打开题目环境,显示如下字符:

    1. never never never give up !!!

    右键查看源码,发现注释里存在线索:

    <!--1p.html-->
    never never never give up !!!
    

    访问1p.html,发现跳转至bugku论坛,使用Burp抓包,发现一段可疑JS代码

    BugkuCTF-Web21-作者:御结冰城 - 图1

    内容如下:

    var Words ="%3Cscript%3Ewindow.location.href%3D'http%3A%2F%2Fwww.bugku.com'%3B%3C%2Fscript%3E%20%0A%3C!--JTIyJTNCaWYoISUyNF9HRVQlNUInaWQnJTVEKSUwQSU3QiUwQSUwOWhlYWRlcignTG9jYXRpb24lM0ElMjBoZWxsby5waHAlM0ZpZCUzRDEnKSUzQiUwQSUwOWV4aXQoKSUzQiUwQSU3RCUwQSUyNGlkJTNEJTI0X0dFVCU1QidpZCclNUQlM0IlMEElMjRhJTNEJTI0X0dFVCU1QidhJyU1RCUzQiUwQSUyNGIlM0QlMjRfR0VUJTVCJ2InJTVEJTNCJTBBaWYoc3RyaXBvcyglMjRhJTJDJy4nKSklMEElN0IlMEElMDllY2hvJTIwJ25vJTIwbm8lMjBubyUyMG5vJTIwbm8lMjBubyUyMG5vJyUzQiUwQSUwOXJldHVybiUyMCUzQiUwQSU3RCUwQSUyNGRhdGElMjAlM0QlMjAlNDBmaWxlX2dldF9jb250ZW50cyglMjRhJTJDJ3InKSUzQiUwQWlmKCUyNGRhdGElM0QlM0QlMjJidWdrdSUyMGlzJTIwYSUyMG5pY2UlMjBwbGF0ZWZvcm0hJTIyJTIwYW5kJTIwJTI0aWQlM0QlM0QwJTIwYW5kJTIwc3RybGVuKCUyNGIpJTNFNSUyMGFuZCUyMGVyZWdpKCUyMjExMSUyMi5zdWJzdHIoJTI0YiUyQzAlMkMxKSUyQyUyMjExMTQlMjIpJTIwYW5kJTIwc3Vic3RyKCUyNGIlMkMwJTJDMSkhJTNENCklMEElN0IlMEElMDklMjRmbGFnJTIwJTNEJTIwJTIyZmxhZyU3QioqKioqKioqKioqJTdEJTIyJTBBJTdEJTBBZWxzZSUwQSU3QiUwQSUwOXByaW50JTIwJTIybmV2ZXIlMjBuZXZlciUyMG5ldmVyJTIwZ2l2ZSUyMHVwJTIwISEhJTIyJTNCJTBBJTdEJTBBJTBBJTBBJTNGJTNF--%3E" 
    function OutWord()
    {
    var NewWords;
    NewWords = unescape(Words);
    document.write(NewWords);
    } 
    OutWord();
    

    对中间备注里的可疑代码使用BASE64编码解码:

    %22%3Bif(!%24_GET%5B'id'%5D)%0A%7B%0A%09header('Location%3A%20hello.php%3Fid%3D1')%3B%0A%09exit()%3B%0A%7D%0A%24id%3D%24_GET%5B'id'%5D%3B%0A%24a%3D%24_GET%5B'a'%5D%3B%0A%24b%3D%24_GET%5B'b'%5D%3B%0Aif(stripos(%24a%2C'.'))%0A%7B%0A%09echo%20'no%20no%20no%20no%20no%20no%20no'%3B%0A%09return%20%3B%0A%7D%0A%24data%20%3D%20%40file_get_contents(%24a%2C'r')%3B%0Aif(%24data%3D%3D%22bugku%20is%20a%20nice%20plateform!%22%20and%20%24id%3D%3D0%20and%20strlen(%24b)%3E5%20and%20eregi(%22111%22.substr(%24b%2C0%2C1)%2C%221114%22)%20and%20substr(%24b%2C0%2C1)!%3D4)%0A%7B%0A%09%24flag%20%3D%20%22flag%7B***********%7D%22%0A%7D%0Aelse%0A%7B%0A%09print%20%22never%20never%20never%20give%20up%20!!!%22%3B%0A%7D%0A%0A%0A%3F%3E
    

    再进行ulr编码解码:

    ";if(!$_GET['id'])
    {
        header('Location: hello.php?id=1');
        exit();
    }
    $id=$_GET['id'];
    $a=$_GET['a'];
    $b=$_GET['b'];
    if(stripos($a,'.'))
    {
        echo 'no no no no no no no';
        return ;
    }
    $data = @file_get_contents($a,'r');
    if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
    {
        $flag = "flag{***********}"
    }
    else
    {
        print "never never never give up !!!";
    }
    ?>
    

    对这段php代码进行解读:

    ";if(!$_GET['id'])  //如果无法通过get获得id变量
    {
        header('Location: hello.php?id=1');  ////跳转到hello.php文件设置id=1
        exit();  ////退出脚本。
    }
    $id=$_GET['id'];  //通过get方式获得其他文件的id变量
    $a=$_GET['a'];  //通过get方式获得其他文件的a变量
    $b=$_GET['b'];  ///通过get方式获得其他文件的b变量
    if(stripos($a,'.'))  ////$a文件中不能有.
    {
        echo 'no no no no no no no';
        return ;
    }
    $data = @file_get_contents($a,'r');  //将$a文件读入到data中
    if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
    {
        $flag = "flag{***********}"
    }
    else
    {
        print "never never never give up !!!";
    }
    ?>
    

    满足以下条件才能获得flag。

    • 以a为名字的文件内容要是bugku is a nice plateform!,源码中变量 $data 是由 file_get_contents() 函数读取变量 $a 的值而得,所以 $a 的值必须为数据流。在服务器中自定义一个内容为 bugku is a nice plateform! 文件,再把此文件路径赋值给 $a,显然不太现实。因此这里用伪协议 php:// 来访问输入输出的数据流,其中 php://input 可以访问原始请求数据中的只读流,通俗点说就是可以获取post报文的实体体(body)的内容,这里令 $a = “php://input”,并在请求主体中提交字符串 bugku is a nice plateform!。

    • id = 0;本来感觉很简单,但是后来发现前面有个条件,导致等0的话,!0=1,导致重定向,那么就不能是数字0可以是字符0,也可能是0e123456来绕过。同时,也可使用弱类型比较来绕过,参数id要求不能为0,但其值又必须与0相等
      所以让 id = ‘abc’
      即可满足 !$_GET[‘id’] 为flase
      而id ==0

    • strlen($b)>5,b长度大于5;这个简单

    • eregi(“111”.substr($b,0,1),”1114”),b第一位连起来满足eregi方法;这个简单,b第一位是4就好

    • substr($b,0,1)!=4,b第一位不能4。ereg() 函数或 eregi() 函数存在空字符截断漏洞,即参数中的正则表达式或待匹配字符串遇到空字符则截断丢弃后面的数据,这样就可以用空字符来绕过,他匹配到空字符自动停止,url中的空字符是%00

    经过分析,初步构造payloadhello.php?id=0e123456&a=php://input&b=%0012345,提交获得falg。

    BugkuCTF-Web21-作者:御结冰城 - 图2