250517_BYUCTF learning record
250517_BYUCTF learning record
cvestone【全栈ctfer计划中,会持续复现学习与更新该文章】
赛事信息
战队排名情况
排名:23
题目附件
web
Red This
考察知识点:redis的基本认识
比赛时的临时笔记
页面初探
查看名言的功能对应POST请求。
分析架构
可以知道web应用是用flask框架搭建的,以及数据库采用redis
分析路由
尝试注册并登录,除了多了一个session外,其他没什么变化:
且注意到token是以JWT的格式展示:
头部只有用户名字段,且需要key来验证签名。在
main.py
中似乎可以发现这个key:
分析admin相关条件
反复出现了adminOptions
关键词,重点关注:
如果用户名是admin,可以返回admin相关选项信息,被存储在redis中。且注意到username是来自于session中的字段。
分析数据库
大致看一下redis都做了什么:
接着定位到redis存储的数据:
set后是键值对形式来存储数据,且发现真正的flag藏在这里,且与管理员选项有关。
分析flag相关条件
person来自于页面列表中选择的作者,如果其中包含“flag”,且用户名如果是admin,就会调用
getData
返回对应的键值对。
尝试修改jwt中的username,但由于没有密钥,发现无法对它进行编辑,且被提示payload字段不符合规则,那就只能想其他办法成为admin。可以继续尝试redis数据库中的其他键值对,因为根据以上代码分析,我们可以知道传递给
getData
的值是可控的,如果不包含“flag”是否也能返回对应的值?
显然这就是漏洞存在的地方,成功拿到了管理员密码。接下来只要登录它就可以拿到flag。
getflag
发现admin用户的列表选项多了flag。
Willy Wonka Web
考察知识点:apache反向代理、http头注入
比赛时的临时笔记
页面初探
纯静态,没有robots,源代码也没有隐藏信息。
分析架构
采用node-js作为后端,且bookworm和express值得关注,可能是采用的框架、组件。
分析express请求处理
如果请求头中的a字段为admin,则后端返回给前端的请求包含打开flag.txt操作;否则查询请求中的name字段,并过滤一些标签,看着是用来防范xss的。
尝试:
没有成功。
分析apache配置文件
注意到前端有个apache的配置文件:
第一个功能是作为反向代理(规则中定义的
[P]
),将客户端的请求转发到后端服务器,这样做的目的是隐藏后端真实端点,比如访问https://fronthost.com/name/admin
时,相当于向后端端点发送请求https://backend.com:3000/?name=admin
;第二个功能则是将请求头中特定请求过滤了,所以上面尝试注入a
请求头没有效果。到这里就没有思路了。
Solved by 0xfun-dr.kasbr
1 | curl -g "https://wonka.chal.cyberjousting.com/name/foo%0d%0aA:%20admin%0d%0aX-Ignore:%20yes" |
forensics
Are You Looking Me Up?
考察知识点:原始网络日志分析、dns协议过滤特征
赛后学习
过滤协议特征
这是一个原始的网络日志,题目要求我们定位的条目是DNS协议,从结构来看,首先需要过滤协议名,注意同时考虑协议号(比如某些条目可能未标注协议名而只有协议号,如果只考虑过滤其中一种,可能导致遗漏关键条目),也别忘了过滤UDP(DNS传输大多情况下基于此),协议号没办法直接用
grep
,因为同样的数字能代表多个含义,会引入其他不相关的条目,而每个条目的各项几乎都是对应的位置,所以通过awk
,以逗号分隔来筛选协议号那一列。当然,还要考虑dns的端口号。(总之就是尽可能把dns协议相关的特征都考虑好,作为日志的过滤条件)
最后,dns服务器是负责接收dns请求的,所以最终需要的数据是目标IP,即第20列,所以:
1 | cat logs.txt | grep udp | awk -F ',' '$16 == 17 && $22 == 53 {print $20}' |
数据排序与统计
1 | cat logs.txt | grep udp | awk -F ',' '$16 == 17 && $22 == 53 {print $20}' | sort | uniq -c |
第一列是每个IP出现的总次数,根据题目显然需要出现最多的,也就是172.16.0.1
。
如果需要更完美一点,可以进一步排序让次数最多的在最上方:
1 | cat logs.txt | grep udp | awk -F ',' '$16 == 17 && $22 == 53 {print $20}' | sort | uniq -c | sort -nr | head |
-n
:按数值大小排序-r
:降序排列
Mine Over Matter
赛后学习
思路总结
先确认矿工(src)连接了哪些矿池(dest),获取其域名IP映射信息,再到原日志中根据映射信息表与目标IP比对,相同的则为挖矿相关流量,通过逆向思维的方式找到对应的连接矿工(src)。
确定数据存储方案
日志内容如下:
首先,要寻找受加密挖矿病毒影响的主机,我们需要知道它的源IP和目标IP,不需要统计所以需要对所有IP进行查重,所以集合用来存储ip最为合适,集合可以实现自动过滤重复元素。接着,由于挖矿病毒必须连接矿池才能开始工作,因此会频繁与矿池的域名/IP通信,因此也需要为其分配存储,由于IP和域名数据类型有差异,且除了知道矿池域名还要知道对应的IP,需要建立映射关系,显然字典最合适,字典支持不同的数据类型且可变。所以:
1 | inputFile = "logs.txt" |
提取目标IP
接着打开日志文件,以逗号分隔:
发现返回是列表类型,索引从0开始,所以
fields[19]
是目标IP所在的列,而所有条目中不一定都含有目标IP,因此要对条目的长度先进行判断,必须至少大于20,才能提取出fields[19]
。
反向解析筛选出潜在矿池
接下来,需要从获取到的目标IP列表中,通过IP反向查找域名(可以通过工具nslookup
来实现,需要新建一个子进程运行它),查看是否存在可能与挖矿相关的域名,比如关键词mine
、pool
、xmr
、crypto
等。
首先通过subprocess
模块为nslookup
创建子进程,并获取执行结果的标准输出与标准错误:
text
可以让输出结果以字符串返回而不是字节序列,因为还需要进一步对返回结果做提取,字节序列不支持,然后check
用来捕获异常。
在进一步筛选之前,先看看nslookup返回的结果:
解决clash TUN带来的DNS污染问题
发现指向了一个内网ip的服务器,猜测是本地环境中开启了clash代理导致的,查看clash创建的TUN网卡发现其dns服务器IP正好就是这个:
解决方案很简单,将其改为谷歌dns
8.8.8.8
,然后ip选择自动获取即可:
重新反向解析发现解析到了许多域名:
包括本地中NAT的kali虚拟机此时也能正常用nslookup了:
筛选矿池域名
找到了一个矿池域名,尝试访问:
当然标准输出的显示更整洁些:
显然,我们需要提取的是域名相关的项,满足一定规则,可以用正则匹配。先判断这里的冒号是否为中文字符,复制后放在notepad++:
是英文字符。所以匹配如下:
注意如果在linux中运行nslookup且系统语言为英文,结果中域名的末尾可能还会有
.
符号,显示格式有些不同,需要修改正则匹配为name\s*=\s*(.+)\.
接着将获取到的矿池域名和IP分别放入字典做映射:
定位矿工
最后,根据获取到的矿池IP域名映射信息,重新打开日志,检索出目标IP符合映射中的IP的条目,即挖矿流量部分,此时的src就是受害者miner机器了:
exp
1 | import re |
Wimdows 1
pwn
Minecraft YouTuber
比赛时的临时笔记
检查保护
全保护。
这是一道UAF的堆利用题,待学习。