---
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

第二道题我觉得是这五道题里面最难的，因为攻击方法并不明显。整个日志看起来都非常正常，我为了让日志看起来更整洁还隐藏了签名验证的部分，日志里实现的操作都是用户正常使用会用到的，管理员创建了几个商品，删了两个商品，用户读了一次商品列表，然后买了一件，感觉没有哪里不对。

![[image_2023-11-18_23-47-54.png|非常正常的日志]]

看了超级超级久还没发现问题，但是把签名打出来发现了不同请求的签名长度不一样，所以猜猜可能是签名验证的问题就去检查了一下签名验证的代码，然后发现了这堆鬼东西：

![[2023-11-18 23-01.png|他们自己实现了一个 ASN 验证，后面是五百行的我都看不懂的纯正密码学]]

不懂就不要随便自己实现加密算法啊啊啊 (╯’ – ‘)╯︵ ┻━┻

密码学真的有太多我看不懂的理论数学，所以我也看不出他们的实现有没有 Bug，但是总之先试试让 GPT4 用标准库重写一遍 VerifyASN 吧... 重写完重跑一遍居然就真的就过了 🌚

## 总结

总之五道 Defense 题全都解出来啦，然后看时间不够快赶不上 One Among Us 的手工活动就赶快走了。感觉很开心！这是我参加的第一个有 Defense 题型的 CTF，感觉是和 Web 题完全反过来的题型。Defense 少见可能是因为这种题比较难封沙盒吧，不过第一次知道原来像我这样的平凡全栈技能也能在 CTF 上起到作用。

原本登记了这次比赛只是因为 UofTCTF 他们组缺人，去之前还觉得自己一年没打过 CTF 了说不定一道题都做不出来呢，结果发现并没有全都忘掉也很开心。居然比同组的那些 UofTCTF 活跃队员分还高一些（不过也是因为 Defense 题更简单啦）总之虽然已经退坑了但是偶尔打打 CTF 还是很好玩的！