XCTF华为鸿蒙专场 HARMOFS01

更新中…

修改固件

  • 解包工具:jefferson
  • 解包用法:jefferson rootfs.img -d ./xxx
  • 固件打包: mkfs.jffs2 -d ./xxx -o rootfs.img

尝试修改出一个可以进入shell然后执行题目的固件,主要是修改了/etc/init.cfg。故尝试使用这种方式上传一个静态编译的gdbserver企图进行用户态的gdb调试,但启动时失败,提如下:

OHOS # ./gdbserver
OHOS # [ERR]OsDoMmapFile 427, Failed to map a valid addr
[ERR]OsLoadELFSegment[947]
execve: Out of memory

接下来使用修改的后的固件进行说明:

操作相关

进入系统之后可以使用telnet on命令开启telnet,使用提供带网络的配置启动qemu,官方手册,鸿蒙的ip地址为192.168.1.10:

OHOS # telnet on
'start telnet server successfully, waiting for connection.

然后在宿主机上telnet即可

➜  telnet 192.168.1.10
Trying 192.168.1.10...
Connected to 192.168.1.10.
Escape character is '^]'.

OHOS # 

这样即可以一个窗口启动目标程序,一个窗口有shell进行操作

地址相关

鸿蒙做了用户态和内核态的隔离,故也做了用户空间地址的隔离,可以在shell中使用vmm命令来看到程序的虚拟地址布局,首先启动目标程序:

OHOS # cd /bin
OHOS # ./harmofs
OHOS # Loading..........
Gift: 0x1ff06eb8
Gift: 0x26812d8

然后在另一个窗口中使用vmm命令即可看到程序的内存布局,可以看到跟漏洞程序打印的内存布局是相同的,main函数地址和libc的puts函数地址:

OHOS # vmm

 PID    aspace     name       base       size     pages 
 ----   ------     ----       ----       -----     ----
 10   0x403e674c harmofs    0x01000000 0x3e000000     180

	 region      name                base       size       mmu_flags      pages   pg/ref
	 ------      ----                ----       ----       ---------      -----   -----
	 0x403e6220  /bin/harmofs                     0x02680000 0x00001000  CH US RD          1       1
	 0x403e6908  /bin/harmofs                     0x02681000 0x00001000  CH US RD EX       1       1
	 0x403e310c  /bin/harmofs                     0x02682000 0x00001000  CH US RD          1       1
	 0x403e5a30                                   0x02683000 0x00001000  CH US RD WR       1       1
	 0x403fd42c  HEAP                             0x10280000 0x00020000  CH US RD WR      32      32
	 0x403ed494  /lib/libc.so                     0x1fe80000 0x00045000  CH US RD         23       5
	 0x403e3228  /lib/libc.so                     0x1fec5000 0x0005e000  CH US RD EX      38       8
	 0x403e3278  /lib/libc.so                     0x1ff23000 0x00001000  CH US RD WR       1       1
	 0x403e32c8                                   0x1ff24000 0x00001000  CH US RD WR       1       1
	 0x403e3318  MMAP                             0x1ff25000 0x00004000  CH US RD WR       4       4
	 0x403e3368  VDSO                             0x1ff29000 0x00002000  CH US RD EX       2       2
	 0x403d0804  /lib/libc++.so                   0x1ff2b000 0x00045000  CH US RD         49      10
	 0x403d0878  /lib/libc++.so                   0x1ff70000 0x00098000  CH US RD EX      18       4
	 0x403e6060  /lib/libc++.so                   0x20008000 0x00005000  CH US RD          5       5
	 0x403e60b0  /lib/libc++.so                   0x2000d000 0x00001000  CH US RD WR       1       1
	 0x403e6100  MMAP                             0x2000e000 0x00001000  CH US RD WR       1       1
	 0x403e33b8  MMAP                             0x3e880000 0x000ff000  CH US RD WR       0       0
	 0x40325a7c  STACK                            0x3e97f000 0x00001000  CH US RD WR       1       1

调试相关

估计用户态gdbserver是没戏了,目前看来只能qemu-system级别调试,修改start_qemu.sh,在启动qemu时加入-S -s参数

sudo ./qemu-system-arm -S -s  -M hi3518  -kernel liteos.bin -nographic -net nic,vlan=0 -net tap,vlan=0,ifname=tap100

然后启动后qemu会卡住,本质是开了本机的tcp:1234等待gdb调试器连入,然后在开一个窗口,启动gdb-multiarch,设置如下指令即可进入调试:

➜  gdb-multiarch 
pwndbg> set architecture arm
The target architecture is assumed to be arm
pwndbg> set endian little 
The target is assumed to be little endian
pwndbg> target remote :1234

断在入口:

───────────────────────────────────[ DISASM ]───────────────────────────────────
 ► 0x40000000    b      #0x40000020
    ↓
   0x40000020    mrc    p15, #0, r0, c1, c0, #0
   0x40000024    bic    r0, r0, #0x1000
   0x40000028    bic    r0, r0, #5
   0x4000002c    mcr    p15, #0, r0, c1, c0, #0
   0x40000030    add    fp, pc, #0x338
   0x40000034    ldr    r0, [fp]
   0x40000038    sub    fp, fp, r0
   0x4000003c    sub    r4, pc, #0x44
   0x40000040    mov    r5, #0x40000000
   0x40000044    subs   ip, r4, r5
───────────────────────────────────[ STACK ]────────────────────────────────────
00:0000│ r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 sp  0 ◂— 0
... ↓
─────────────────────────────────[ BACKTRACE ]──────────────────────────────────
 ► f 0 40000000
────────────────────────────────────────────────────────────────────────────────
pwndbg> 

c继续执行,等待qemu起来,然后开telnet,在开一个窗口连进去。于是现在有三个窗口,俩shell,一个gdb。所以

  • 一个shell窗口起程序
  • 一个shell看vmm
  • gdb窗口control+c即可把程序打断

等待程序输出后:

OHOS # ./harmofs
OHOS # Loading..........
Gift: 0x2480feb8
Gift: 0x6f8a2d8

即可根据程序输出或者vmm结果对程序进行断点调试,比如我要断到每次打印提示符的时候:

.text:0000143C F3 00 00 EB                 BL              printf

此时基址是vmm结果:

 PID    aspace     name       base       size     pages 
 ----   ------     ----       ----       -----     ----
 10   0x403ee528 harmofs    0x01000000 0x3e000000     178

	 region      name                base       size       mmu_flags      pages   pg/ref
	 ------      ----                ----       ----       ---------      -----   -----
	 0x403ed39c  /bin/harmofs                     0x06f89000 0x00001000  CH US RD          1       1
	 0x403ed3ec  /bin/harmofs                     0x06f8a000 0x00001000  CH US RD EX       1       1
	 0x403ed43c  /bin/harmofs                     0x06f8b000 0x00001000  CH US RD          1       1
	 0x403dba18                                   0x06f8c000 0x00001000  CH US RD WR       1       1

即可打断,先control+c,然后设置断点:

pwndbg> b * 0x06f89000+0x0000143C
Breakpoint 2 at 0x6f8a43c
pwndbg> c

然后在程序窗口按回车即可断到:

Breakpoint 2, 0x06f8a43c in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────[ REGISTERS ]──────────────────────────────────
 R0   0x6f8972a ◂— mcrlo  p8, #1, r6, c0, c3, #2 /* 0x3e206853; 'Sh > ' */
 R1   0x763a65c
 R2   0xe
 R3   0x0
 R4   0x6f8971e —▸ 0x74666947 ◂— 0
 R5   0x3a07699c —▸ 0x3a07680a ◂— 0x52483
 R6   0x6f8a2d8 ◂— push   {r4, r5, fp, lr} /* 0xe92d4830 */
 R7   0x6f89757 —▸ 0x63756f74 ◂— 0
 R8   0x3a076f44 —▸ 0x3a076fec —▸ 0x6d726168 ◂— 0
 R9   0x6f8c030 ◂— 0
 R10  0x6f8972a ◂— mcrlo  p8, #1, r6, c0, c3, #2 /* 0x3e206853; 'Sh > ' */
 R11  0x3a076da8 ◂— 0x0
 R12  0x3a076828 ◂— 0xe
 SP   0x3a076998 ◂— 0x0
 PC   0x6f8a43c ◂— bl     #0x6f8a810 /* 0xeb0000f3 */
───────────────────────────────────[ DISASM ]───────────────────────────────────
 ► 0x6f8a43c    bl     #0x6f8a810
 
   0x6f8a440    mov    r0, r5
   0x6f8a444    mov    r1, #0
   0x6f8a448    mov    r2, #0x10
   0x6f8a44c    bl     #0x6f8a850
 
   0x6f8a450    mov    r0, #0
   0x6f8a454    mov    r1, r5
   0x6f8a458    mov    r2, #0xf
   0x6f8a45c    bl     #0x6f8a830
 
   0x6f8a460    mov    r0, r5
   0x6f8a464    mov    r1, r7
───────────────────────────────────[ STACK ]────────────────────────────────────
00:0000│ sp  0x3a076998 ◂— 0x0
01:0004│ r5  0x3a07699c —▸ 0x3a07680a ◂— 0x52483
02:0008│     0x3a0769a0 ◂— 0x5
03:000c│     0x3a0769a4 ◂— 0x0
... ↓
05:0014│     0x3a0769ac —▸ 0x24917e90 —▸ 0x2482d880 ◂— 0
06:0018│     0x3a0769b0 —▸ 0x2482c8c0 —▸ 0x2482d990 ◂— 0
07:001c│     0x3a0769b4 —▸ 0x2482cc40 —▸ 0x2482d950 ◂— 0
─────────────────────────────────[ BACKTRACE ]──────────────────────────────────
 ► f 0  6f8a43c
────────────────────────────────────────────────────────────────────────────────
Breakpoint * 0x06f89000+0x0000143C
pwndbg> 

程序相关

在000015EC地址处,有一段switch,patch后如下:

.text:000015EC 03 00 51 E3                 CMP             R1, #3
.text:000015F0 0A 00 00 8A                 BHI             loc_1620
.text:000015F4 33 00 00 0A                 BEQ             loc_16C8 ; Keypatch modified this from:
.text:000015F4                                                     ;   ADR R0, byte_1600
.text:000015F8 00 00 51 E3                 CMP             R1, #0  ; Keypatch modified this from:
.text:000015F8                                                     ;   LDR R1, [R0,R1,LSL#2]
.text:000015FC 03 00 00 0A                 BEQ             loc_1610 ; Keypatch modified this from:
.text:000015FC                                                     ;   ADD PC, R0, R1
.text:000015FC                                                     ; Keypatch modified this from:
.text:000015FC                                                     ;   BEQ dword_160
.text:00001600 01 00 51 E3                 CMP             R1, #1  ; Keypatch modified this from:
.text:00001600                                                     ;   DCB 0x10
.text:00001600                                                     ;   DCB 0, 0, 0
.text:00001604 16 00 00 0A                 BEQ             loc_1664 ; Keypatch modified this from:
.text:00001604                                                     ;   DCB 0x64
.text:00001604                                                     ;   DCB 0, 0, 0
.text:00001608 02 00 51 E3                 CMP             R1, #2  ; Keypatch modified this from:
.text:00001608                                                     ;   DCB 0x74
.text:00001608                                                     ;   DCB 0, 0, 0
.text:0000160C 18 00 00 0A                 BEQ             loc_1674 ; Keypatch modified this from:
.text:0000160C                                                     ;   DCB 0xC8
.text:0000160C                                                     ;   DCB 0, 0, 0
.text:00001610
.text:00001610             loc_1610                                ; CODE XREF: main+324j