[+] CyberSci 2023

This commit is contained in:
2023-11-18 23:37:40 -05:00
parent 99629c47c2
commit 52eee41127
7 changed files with 73 additions and 0 deletions
@@ -0,0 +1,73 @@
---
title: CyberSci 2023 CTF 网安比赛 Writeup
subtitle: 你是来打网安还是修 Bug 的?🌚
tags: [ctf]
---
我解的五道题都是 Defense 分类的,Defense 规则是修好一个服务器端让攻击方的 PoC 脚本失效就能拿分(这不是我维护服务器日常做的事情吗 ;-;
前三道题「CFP」是一套 PhP + Nginx 写的用来上传作业文档的服务器,后两道题「Swag Shop」是一套 Go GIN 写的购物服务器,全都跑在 docker compose 容器里(然而这两个语言我都没用过呜呜呜)
知道问题的时候修一个 bug 很容易,但是 PoC 机并不会告诉你 bug 在哪里,所以解题的第一步是去查 HTTP log 找到被攻击的方法。
## 前三道题 - Call for Presentations
### Attack 1
前三道题的部署结构我真的太熟悉了,因为我自己的所有服务器都是 Nginx + Docker,直接 `tail -f /var/log/nginx/access.log` 读出所有的请求,整理出一个攻击从开始到结束的所有请求,再 `cat /tmp/nginx-req-body/{n}/` 来读出每个请求内容。看一下请求过程如下:
1. 注册一个帐号
2. 登录这个帐号
3. 换一个不同的密码登录这个帐号还登进去了??
啊所以难道给我的这套代码登录甚至没有验证密码的吗 (╯’ – ‘)╯︵ ┻━┻
![[2023-11-18 22-02 2.png|欣赏一下屎山代码]]
看看源代码 lib.php 确实数据库密码验证逻辑写得乱七八糟,数据库直接 string concat,密码甚至没 hash... 好直接让 GPT4 重写了一遍登录和注册这两个函数,然后 PoC 就失效了,拿分拿分 🌚
![[2023-11-18 22-03.png|GPT4 帮我修好了!]]
(不过我至今没弄懂 PhP 要怎样把 log 打到能看到的地方... 打比赛的时候试了几个不同的方法都看不到 log 就算了算了直接把 curl hydev.org/say 写进去了,发到 /say 的东西会转发到我的 Telegram 上hhhh
### Attack 2
第一个好简单。第二个攻击的请求乍一看好像没什么问题,但是仔细看看就会发现 PoC 机注册的帐号的名字和请求提交的 JWT Token 名字不一样然后还莫名过签证验证了... 为什么呢?
![[image_2023-11-18_21-58-35 1.png|第二个攻击的 Log]]
看一眼代码确实,签名居然不是密码学签名,而是直接把请求 JWT 里面的东西 hash 了一遍,验证签名和 hash 相等???🫠 这种客户端能生成的东西还算签名吗?算了交给 GPT4 去改,果然改完就过了。
### Attack 3
第三个攻击感觉是最简单的,看日志内容发现用户上传了五个不同的文件,但是看请求内容那一步就马上发现不对劲了——五个文件中有一个是 PhP 文件,里面是攻击代码,居然直接以 .php 结尾被传进代码旁边的子目录了。泰经典辣,甚至没有用 GPT4,直接给 portal.php 上传文件的代码加一个文件结尾检查就过了(虽然如果是现实中真的遇到这种情况的话肯定要检测文件内容的)
## 后二道题 - Swag Shop
上一道题因为是 PhP,改完代码直接 `compose up --build -d` 重新跑容器也只要几秒。但是这两道题是用 Go 写的,而 Go 是需要编译的语言,所以发现的第一件事情是 `docker build` 居然要两分钟 (╯’ – ‘)╯︵ ┻━┻
磨刀不误砍柴工,先把本地 Go 环境和依赖装上,把 SSL cert 挪到该放的地方,带缓存的编译重跑就只需要不到一秒了。
![[2023-11-18 22-52.png]]
## Attack 1
第一道题非常非常简单,跑起来之后看 HTTP 访问日志马上就看到了一条野生 SQL 语句 👀 原来要修的是 SQL 注入。看看代码,main 里面定义了这个 `/shop/items/:item` 节点的函数是 DescribeItem(),把整个函数拷给 GPT4 重写拿分()
![[2023-11-18 22-56.png|GPT4 不知道今天帮了我多少忙]]
### Attack 2
第二道题我觉得是这五道题里面最难的,因为攻击方法并不明显。整个日志看起来都非常正常,我为了让日志看起来更整洁还隐藏了签名验证的部分,日志里实现的操作都是用户正常使用会用到的。看了超级超级久还没发现问题,但是把签名打出来发现了不同请求的签名长度不一样,所以猜猜可能是签名验证的问题就去检查了一下签名验证的代码,然后发现了这堆鬼东西:
![[2023-11-18 23-01.png|他们自己实现了一个 ASN 验证,后面是五百行的我都看不懂的纯正密码学]]
不懂就不要随便自己实现加密算法啊啊啊 (╯’ – ‘)╯︵ ┻━┻
密码学真的有太多我看不懂的理论数学,所以我也看不出他们的实现有没有 Bug,但是总之先试试让 GPT4 用标准库重写一遍 VerifyASN 吧... 重写完重跑一遍居然就真的就过了 🌚
## 总结
总之五道 Defense 题全都解出来啦,然后看时间不够快赶不上 One Among Us 的手工活动就赶快走了。感觉很开心!这是我参加的第一个有 Defense 题型的 CTF,感觉是和 Web 题完全反过来的题型。Defense 少见可能是因为这种题比较难封沙盒吧,不过第一次知道原来像我这样的平凡全栈技能也能在 CTF 上起到作用。
原本登记了这次比赛只是因为 UofTCTF 他们组缺人,去之前还觉得自己一年没打过 CTF 了说不定一道题都做不出来呢,结果发现并没有全都忘掉也很开心。居然比同组的那些 UofTCTF 活跃队员分还高一些(不过也是因为 Defense 题更简单啦)总之虽然已经退坑了但是偶尔打打 CTF 还是很好玩的!
Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB