2019年美国国家安全局(NSA)免费向公众开放其逆向工程框架,集成出工具ghidra并在当年3月登陆github。最近碰到一题risc-v架构(*ctf2021 favourite architecture),需要用ghidra反编译辅助分析,以其为例记录动态与静态调试环境搭建。
1
2
3
4
5
6
7
8
9
|
$ checksec ./main
[*] '/mnt/hgfs/linux_share/starctf/favourite_architecture/share/main'
Arch: em_riscv-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x10000)
RWX: Has RWX segments
|
静态调试
下载与使用ghidra
下载略
快捷键见[3]
- L 重命名函数
- G 跳转到
- ctrl+shift+E 查找
- ……
踩坑记录
反编译(decompiling)窗口显示unknown error,无法反编译除entry以外的函数
见参考资料[1],需要设置手动gp(全局寄存器)
在entrypoint最后(0x00101ec)能计算出或者直接在entry的反编译窗口看到gp的正确值为0x6f178
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
|
*************************************************************
* FUNCTION
*************************************************************
undefined entry ()
assume gp = 0x6f178
undefined a0:1 <RETURN>
entry XREF[3]: Entry Point (*) , 00010018 (*) ,
00067e94 (*)
000101c0 ef 00 c0 02 jal ra,FUN_000101ec undefined FUN_000101ec()
000101c4 aa 87 c.mv a5,a0
000101c6 17 05 00 00 auipc a0,0x0
000101ca 13 05 a5 23 addi a0=>LAB_00010400 ,a0,0x23a
000101ce 82 65 c.ldsp a1,0x0 =>Stack [0x0 ](sp)
000101d0 30 00 c.addi4s a2,sp,0x8
000101d2 13 71 01 ff andi sp,sp,-0x10
000101d6 97 16 00 00 auipc a3,0x1
000101da 93 86 a6 54 addi a3=>LAB_00011720 ,a3,0x54a
000101de 17 17 00 00 auipc a4,0x1
000101e2 13 07 27 5d addi a4=>LAB_000117b0 ,a4,0x5d2
000101e6 0a 88 c.mv a6,sp
000101e8 6f 10 40 0a j FUN_0001128c undefined FUN_0001128c()
-- Flow Override: CALL_RETURN (CALL_TERMINATOR)
*************************************************************
* FUNCTION
*************************************************************
undefined FUN_000101ec ()
assume gp = 0x6f178
undefined a0:1 <RETURN>
FUN_000101ec XREF[3]: entry:000101c0 (c) , 00011762 (c) ,
0006cb80 (*)
000101ec 97 f1 05 00 auipc gp,0x5f
000101f0 93 81 c1 f8 addi gp,gp,-0x74
000101f4 82 80 ret
|
全选以后ctrl-R
,将gp改对即可。
动态调试
qemu+gdb调试
先去掉~/.gdbinit的pwndbg等启动命令,使用原生gdb(如果pwn环境安装在py3中,可以使用gef)
1
2
|
source ~/pwndbg/gdbinit.py
source ~/GdbPlugins/gef/gef.py
|
调试脚本,gdb连本地23333端口来连
1
2
3
4
5
6
7
8
9
|
#!/bin/sh
gdb-multiarch -q \
-ex 'set architecture riscv:rv64' \
-ex 'file main' \
-ex 'target remote localhost:23333' \
-ex 'break *0x0010582'\
-ex continue \
;
|
攻击脚本,用qemu在23333端口开一个程序并进行攻击(这里题目给了qemu,也可以用自己的)
1
|
io = process(["./qemu-riscv64" , "-g", "23333" ,"./main"], aslr=False)
|
原生gdb比较简陋,并且功能不够强大,暂时只能凑合着用了
重新学一下gdb指令…
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
|
Breakpoint 1, 0x0000000000010452 in ?? ()
(gdb) x/10xi 0x10452
=> 0x10452: jal ra,0x204e4
0x10456: mv a3,a0
0x10458: lw a4,-1952(gp)
0x1045c: lw a5,-1948(gp)
0x10460: addw a5,a5,a4
0x10462: sext.w a5,a5
0x10464: slli a5,a5,0x20
0x10466: srli a5,a5,0x20
0x10468: bne a3,a5,0x10570
0x1046c: lw a5,-1952(gp)
(gdb) info registers
ra 0x1044c 0x1044c
sp 0x40007ffff0 0x40007ffff0
gp 0x6f178 0x6f178
tp 0x71700 0x71700
t0 0x0 0
t1 0x1a3f2 107506
t2 0x71f93 466835
fp 0x40008001f0 0x40008001f0
s1 0x117b0 71600
a0 0x40008000c8 274886295752
a1 0x6d523 447779
a2 0x1 1
a3 0x0 0
a4 0x1 1
a5 0x40008000c8 274886295752
a6 0xfffffffffbad208b -72540021
a7 0x3f 63
s2 0x0 0
s3 0x0 0
s4 0x0 0
s5 0x0 0
s6 0x0 0
s7 0x0 0
s8 0x0 0
s9 0x0 0
s10 0x0 0
s11 0x0 0
t3 0x8101010101010100 -9151031864016699136
t4 0x2f 47
t5 0x1 1
t6 0x0 0
pc 0x10452 0x10452
(gdb)
|
gef可以通过gdb-multiarch -p pid号来使用,但是寄存器等却无法正确识别,原因不明
可以看到能正确解析risc-v的指令与寄存器。如果不行也许得先安装一下gcc-riscv64-linux-gnu
1
|
sudo apt-get install git build-essential gdb-multiarch qemu-system-misc gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu
|
具体见参考资料[2]
经过测试,以下常用工具都不支持risc-v…
1
2
3
|
(pwn) pwn@ubuntu:~/share/starctf/favourite_architecture/share$ ROPgadget --binary ./main --only "ldsp"
[Error] ELF.getArch() - Architecture not supported
[Error] ELF.getArch() - Architecture not supported
|
gef/pwndbg/peda/gdbinit均出现以下类似的exception (个人问题,貌似是py3的锅)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
(pwn) pwn@ubuntu:~/share/starctf/favourite_architecture/share$ gdb-multiarch -q ./main
GEF for linux ready, type `gef' to start, `gef config' to configure
50 commands loaded for GDB 9.2 using Python engine 3.8
[*] 4 commands could not be loaded, run `gef missing` to know why.
Reading symbols from ./main...
(No debugging symbols found in ./main)
Python Exception <class '__main__.GefUnsupportedOS'> 'CPU type is currently not supported: riscv:rv64':
gef➤ set architecture riscv:rv64
The target architecture is assumed to be riscv:rv64
gef➤ r
Starting program: /mnt/hgfs/linux_share/starctf/favourite_architecture/share/main
/build/gdb-OxeNvS/gdb-9.2/gdb/i387-tdep.c:592: internal-error: void i387_supply_fxsave(regcache*, int, const void*): Assertion `tdep->st0_regnum >= I386_ST0_REGNUM' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
This is a bug, please report it. For instructions, see:
<http://www.gnu.org/software/gdb/bugs/>.
Aborted (core dumped)
(pwn) pwn@ubuntu:~/share/starctf/favourite_architecture/share$ Input the flag: You are wrong ._.
(pwn) pwn@ubuntu:~/share/starctf/favourite_architecture/share$
|
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
|
$ seccomp-tools dump ./main
./main: 12: ./main: �����>�"tEa��"���#0��#&��������7�#������ׇ��7��w�#���������7��w�#������ׇ��7��w�#��bda��9q�"��#<��#8��#4���7������5�>��1I�7�����1F�5��>���G�����#4��5����?몇��7��#��7���>����骇��7��#��7���>����窇��7��#��7���>���_檇��7��#�5����䪇��7��#��7��>���_㪇��7��#��7��>����᪇��7��#��7��>���ઇ��7��#��7��>���ު���7��#��
�7��>����ܪ���7��#��
�7��>���?۪���7��#��
�7��>����٪���7��#��
�7��#�
5�����ת���7��#��
�7���>���֪���7��#��
�7���>���Ԫ���7��#��
�7�����1F�5��>���-�pBt!a���"�#4��#0���7���7��#��
�7�����>�������7��������7��#��: File name too long
./main: 1: ./main: Syntax error: Unterminated quoted string
./main: 3: ./main: ���7������������ُ#: not found./main: 3: ./main: ���7�������������ُ#: not found
./main: 3: ./main: ���7�������������ُ#: not found
./main: 3: ./main: �����7�����k�������`f�G)�!��������``d�G>��p^t ��"���.�#&����#$��������������@���W�Տ�>�bda��yq"�#<��#&��7��������ُ#: not found
./main: 3: ./main: cannot create ��7�: Directory nonexistent
./main: 3: ./main: ��������7�: not found
./main: 3: ./main: cannot create ����p��#0����������������:���N������������6���: Directory nonexistent
./main: 3: ./main: �������G���������D����6����������W������6��������#$�����#: not found
./main: 3: ./main: ���7���C#$��#���7�����#.���7��C#,���7��C#*���7��G#(���7��G#&��# �}�'D��'����#�������G����������D����6����������W�D����6��������#: not found
./main: 1: ./main: �: not found
./main: 1: ./main: ���5XXXDD: not found
./main: 1: ./main: �: not found
./main: 1: ./main:R�td: not found
./main: 1: ./main: �: not found
./main: 1: ./main: dA������Gz��7�A�������cP�: not found
./main: 1: ./main: cannot open ��#8���7���C#: No such file
./main: 1: ./main: ELF��@��@8@t�t����: not found
$
|
以下常用工具可用
参考资料
[1] https://github.com/NationalSecurityAgency/ghidra/issues/2466
[2] https://pdos.csail.mit.edu/6.828/2019/tools.html
[3] https://www.cnblogs.com/iBinary/p/13852204.html