VNCTF 2023 - Web 象棋王子|电子木鱼|BabyGo Writeups

象棋王子

签到题,jsfuck解密

丢到console得到flag

电子木鱼

后面两道都是代码审计,这题是rust,题目给出了源码,下载下来看

关键代码:

VNCTF 2023 - Web 象棋王子|电子木鱼|BabyGo Writeups_第1张图片

由于限制,quantity只能为正数

功德也只能是正数(负数的话无法执行到这里)

关键代码:

cost *= body.quantity;

cost变量由 cost原始值 乘 quantity 得到

由于cost是int32类型变量,这里可以试着溢出

GONGDE.set(GONGDE.get() - cost as i32);

其实我也不太清楚这里底层原理,但是我觉得整个代码里面就是这里是有机会的

虽然我不知道溢出后的结果是什么,我还是尝试了一下

VNCTF 2023 - Web 象棋王子|电子木鱼|BabyGo Writeups_第2张图片

当尝试int32最大值的时候,很明显,减变加了

简单分析

name: Cost的默认cost值是10

事实上只要 cost * quantity >= int32_max值 即可达到溢出

至于溢出之后内存中究竟是cost变负数了还是发生了其他问题我也不太清楚,但至少我们的目的达到了

VNCTF 2023 - Web 象棋王子|电子木鱼|BabyGo Writeups_第3张图片

BabyGo

go的代码审计题

思路:通过文件上传功能上传zip,利用unzip功能可以将zip解压到任意路径,做到文件覆盖的效果,然后获得backdoor的访问权限,backdoor允许自定义模块,通过文件覆盖,令后端代码使用我们编写的恶意go模块并同时获得RCE

首先是文件上传,禁止上传go、gob文件

我看到代码有unzip功能,果断将go文件压缩成zip并上传

文件路径:

/tmp/xxx/uploads/

通过unzip进行解压,也会解压到/tmp/xxx/uploads/

VNCTF 2023 - Web 象棋王子|电子木鱼|BabyGo Writeups_第4张图片

查看unzip的实现代码,能够看出zip解压路径由 固定的/tmp/xxx/uploads/ + 我们可控的path http参数

那就简单了直接设置get参数path为../ 就能解压到任意路径

在看看最后一个功能 backdoor

VNCTF 2023 - Web 象棋王子|电子木鱼|BabyGo Writeups_第5张图片

这里判断用户是否admin,而用户信息从/tmp/xxx/中的user.gob读取的

而关于user.gob的初始化关键代码:

VNCTF 2023 - Web 象棋王子|电子木鱼|BabyGo Writeups_第6张图片

很明显,struct和序列化代码都给我们了,直接照着抄过来,吧Power改admin就可以了

VNCTF 2023 - Web 象棋王子|电子木鱼|BabyGo Writeups_第7张图片

这段代码生成一个新的user.gob

利用刚刚的任意路径解压文件功能,将我们的user.gob上传到/tmp/xxx/

达到覆盖掉原始的user.gob文件目的

这样我们就有权限使用backdoor了

RCE

关键代码:

在这里插入图片描述
有了backdoor访问权限之后,新的问题又来了

这里Eval()函数执行的命令我们居然不可控,什么奇葩后门。

不过还好,它使用的模块我们可控:

http Get参数pkg,默认值为:fmt

我们可以想办法调用我们编写的fmt模块,并调用我们编写的Println()函数

由于这里禁止了使用相对路径模块调用,所以我们只能将我们编写的模块上传到:

/usr/local/go/src/

这里是存放go模块的地方,我们可以通过刚刚的漏洞将文件上传到那里并且调用它

创建一个hackerM的文件夹打开cmd输入:

go mod init fmt

这样我们将得到一个go.mod文件,在文件中添加以下内容:

require hackerM/fmt v0.0.0
replace hackerM/fmt v0.0.0 => ../fmt

在hackerM目录下创建fmt.go文件,内容如下:

package fmt

import "os/exec"
import "fmt"

func Println(cmd string) {
    // out, _ := exec.Command("cat", "/ffflllaaaggg").Output()
    out, _ := exec.Command("whoami").Output()
    fmt.Println(string(out))
}

// /usr/local/go/src/

现在hackerM结构应该是这样:

VNCTF 2023 - Web 象棋王子|电子木鱼|BabyGo Writeups_第8张图片

将hackerM文件夹压缩为zip,上传

解压到 /usr/local/go/src/ :

VNCTF 2023 - Web 象棋王子|电子木鱼|BabyGo Writeups_第9张图片

转到/backdoor页面,添加pkg参数:

?pkg=hackerM/fmt

这样我们编写的fmt模块代码将会被执行,flag在根目录

VNCTF 2023 - Web 象棋王子|电子木鱼|BabyGo Writeups_第10张图片


最后一道题有点难度,也是代码审计吧,只不过要审计cms最新版本,得自己审计出漏洞,我php能力有限,等大佬wp

你可能感兴趣的:(rust,Golang,代码审计,VNCTF,Web安全)