攻防世界官网:https://adworld.xctf.org.cn/ 。
源程序下载: http://file.eonew.cn/ctf/re/simple2 。
一道简单的逆向题,虽然不知道什么壳,但是手脱后分析还是很简单的。
目录
观察
拖进IDA分析,并不知道是什么壳,所以直接用gdb,把相对应的内存dump下来。
ex@Ex:~/Downloads$ gdb ./simple2
pwndbg: loaded 175 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
Reading symbols from ./simple2...(no debugging symbols found)...done.
pwndbg> r
Starting program: /home/ex/Downloads/simple2
^C
Program received signal SIGINT, Interrupt.
0x000000000043f590 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────[ REGISTERS ]──────────────────────────────────
RAX 0xfffffffffffffe00
RBX 0x6ca540 ◂— 0xfbad2288
RCX 0x43f590 ◂— cmp rax, -0xfff
RDX 0x400
RDI 0x0
RSI 0x6cf880 ◂— 0x0
R8 0x6cc5e0 ◂— 0x0
R9 0x6ce880 ◂— 0x6ce880
R10 0x4a12c4 ◂— and eax, 0x733639 /* '%96s' */
R11 0x246
R12 0x0
R13 0xffffffffffffffd0
R14 0x6cb9e0 —▸ 0x4a6e20 —▸ 0x4b554d ◂— add byte ptr [r15 + 0x4d], al /* 'C' */
R15 0x6ca540 ◂— 0xfbad2288
RBP 0x6ca320 ◂— 0xfbad2084
RSP 0x7fffffffc298 —▸ 0x411f98 ◂— cmp rax, 0
RIP 0x43f590 ◂— cmp rax, -0xfff
───────────────────────────────────[ DISASM ]───────────────────────────────────
► 0x43f590 cmp rax, -0xfff
0x43f596 jae 0x444560
↓
0x444560 neg rax
0x444563 mov dword ptr fs:[0xffffffffffffffd0], eax
0x44456b or rax, 0xffffffffffffffff
0x44456f ret
0x444570 push rbp
0x444571 mov rbp, rsp
0x444574 push r15
0x444576 push r14
0x444578 push r13
───────────────────────────────────[ STACK ]────────────────────────────────────
00:0000│ rsp 0x7fffffffc298 —▸ 0x411f98 ◂— cmp rax, 0
01:0008│ 0x7fffffffc2a0 ◂— 0x84f4dc
02:0010│ 0x7fffffffc2a8 —▸ 0x6ca540 ◂— 0xfbad2288
03:0018│ 0x7fffffffc2b0 —▸ 0x7fffffffc990 —▸ 0x7fffffffcaf0 —▸ 0x6ca018 —▸ 0x43b130 ◂— ...
04:0020│ 0x7fffffffc2b8 —▸ 0x4152ae ◂— cmp eax, -1
05:0028│ 0x7fffffffc2c0 ◂— 0x0
06:0030│ 0x7fffffffc2c8 —▸ 0x4629f0 ◂— cmp eax, -1
07:0038│ 0x7fffffffc2d0 ◂— 0xeb8
─────────────────────────────────[ BACKTRACE ]──────────────────────────────────
► f 0 43f590
f 1 411f98
f 2 84f4dc
f 3 6ca540
f 4 7fffffffc990
f 5 4152ae
f 6 0
Program received signal SIGINT
pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
0x400000 0x4ca000 r-xp ca000 0
0x4ca000 0x6c9000 ---p 1ff000 0
0x6c9000 0x6f1000 rwxp 28000 0 [heap]
0x800000 0x801000 rwxp 1000 0
0x7ffff7ffa000 0x7ffff7ffd000 r--p 3000 0 [vvar]
0x7ffff7ffd000 0x7ffff7fff000 r-xp 2000 0 [vdso]
0x7ffffffdd000 0x7ffffffff000 rwxp 22000 0 [stack]
0xffffffffff600000 0xffffffffff601000 r-xp 1000 0 [vsyscall]
pwndbg> dump memory bin 0x400000 0x6c9000
分析
将dump下来的文件拖进IDA进行分析。
LOAD:00000000004009AE ; int __cdecl main(int argc, const char **argv, const char **envp)
LOAD:00000000004009AE main proc near ; DATA XREF: start+1D↑o
LOAD:00000000004009AE
LOAD:00000000004009AE var_70 = byte ptr -70h
LOAD:00000000004009AE var_8 = qword ptr -8
LOAD:00000000004009AE
LOAD:00000000004009AE push rbp
LOAD:00000000004009AF mov rbp, rsp
LOAD:00000000004009B2 sub rsp, 112
LOAD:00000000004009B6 mov rax, fs:28h
LOAD:00000000004009BF mov [rbp+var_8], rax
LOAD:00000000004009C3 xor eax, eax
LOAD:00000000004009C5 lea rax, [rbp+var_70]
LOAD:00000000004009C9 mov rsi, rax
LOAD:00000000004009CC mov edi, offset a96s ; "%96s"
LOAD:00000000004009D1 mov eax, 0
LOAD:00000000004009D6 call scanf
LOAD:00000000004009DB lea rax, [rbp+var_70]
LOAD:00000000004009DF mov esi, offset unk_6CA0A0
LOAD:00000000004009E4 mov rdi, rax
LOAD:00000000004009E7 call strcpy
LOAD:00000000004009EC test eax, eax
LOAD:00000000004009EE jnz short loc_4009FC
LOAD:00000000004009F0 mov edi, offset aCongratulation ; "Congratulations!"
LOAD:00000000004009F5 call printf
LOAD:00000000004009FA jmp short loc_400A06
LOAD:00000000004009FC ; ---------------------------------------------------------------------------
LOAD:00000000004009FC
LOAD:00000000004009FC loc_4009FC: ; CODE XREF: main+40↑j
LOAD:00000000004009FC mov edi, offset aTryAgain ; "Try again!"
LOAD:0000000000400A01 call printf
LOAD:0000000000400A06
LOAD:0000000000400A06 loc_400A06: ; CODE XREF: main+4C↑j
LOAD:0000000000400A06 mov eax, 0
LOAD:0000000000400A0B mov rdx, [rbp+var_8]
LOAD:0000000000400A0F xor rdx, fs:28h
LOAD:0000000000400A18 jz short locret_400A1F
LOAD:0000000000400A1A call sub_442EC0
LOAD:0000000000400A1F ; ---------------------------------------------------------------------------
LOAD:0000000000400A1F
LOAD:0000000000400A1F locret_400A1F: ; CODE XREF: main+6A↑j
LOAD:0000000000400A1F leave
LOAD:0000000000400A20 retn
LOAD:0000000000400A20 main endp
调试
发现main函数就是字符串比较,所以在0x4009E7
下断点。
ex@Ex:~/Downloads$ gdb ./simple2
pwndbg: loaded 175 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
Reading symbols from ./simple2...(no debugging symbols found)...done.
pwndbg> r
Starting program: /home/ex/Downloads/simple2
^C
Program received signal SIGINT, Interrupt.
0x000000000043f590 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────[ REGISTERS ]──────────────────────────────────
RAX 0xfffffffffffffe00
RBX 0x6ca540 ◂— 0xfbad2288
RCX 0x43f590 ◂— cmp rax, -0xfff
RDX 0x400
RDI 0x0
RSI 0x6cf880 ◂— 0x0
R8 0x6cc5e0 ◂— 0x0
R9 0x6ce880 ◂— 0x6ce880
R10 0x4a12c4 ◂— and eax, 0x733639 /* '%96s' */
R11 0x246
R12 0x0
R13 0xffffffffffffffd0
R14 0x6cb9e0 —▸ 0x4a6e20 —▸ 0x4b554d ◂— add byte ptr [r15 + 0x4d], al /* 'C' */
R15 0x6ca540 ◂— 0xfbad2288
RBP 0x6ca320 ◂— 0xfbad2084
RSP 0x7fffffffc298 —▸ 0x411f98 ◂— cmp rax, 0
RIP 0x43f590 ◂— cmp rax, -0xfff
───────────────────────────────────[ DISASM ]───────────────────────────────────
► 0x43f590 cmp rax, -0xfff
0x43f596 jae 0x444560
↓
0x444560 neg rax
0x444563 mov dword ptr fs:[0xffffffffffffffd0], eax
0x44456b or rax, 0xffffffffffffffff
0x44456f ret
0x444570 push rbp
0x444571 mov rbp, rsp
0x444574 push r15
0x444576 push r14
0x444578 push r13
───────────────────────────────────[ STACK ]────────────────────────────────────
00:0000│ rsp 0x7fffffffc298 —▸ 0x411f98 ◂— cmp rax, 0
01:0008│ 0x7fffffffc2a0 ◂— 0x84f4dc
02:0010│ 0x7fffffffc2a8 —▸ 0x6ca540 ◂— 0xfbad2288
03:0018│ 0x7fffffffc2b0 —▸ 0x7fffffffc990 —▸ 0x7fffffffcaf0 —▸ 0x6ca018 —▸ 0x43b130 ◂— ...
04:0020│ 0x7fffffffc2b8 —▸ 0x4152ae ◂— cmp eax, -1
05:0028│ 0x7fffffffc2c0 ◂— 0x0
06:0030│ 0x7fffffffc2c8 —▸ 0x4629f0 ◂— cmp eax, -1
07:0038│ 0x7fffffffc2d0 ◂— 0xeb8
─────────────────────────────────[ BACKTRACE ]──────────────────────────────────
► f 0 43f590
f 1 411f98
f 2 84f4dc
f 3 6ca540
f 4 7fffffffc990
f 5 4152ae
f 6 0
Program received signal SIGINT
pwndbg> b *0x04009E7
Breakpoint 1 at 0x4009e7
pwndbg> c
Continuing.
12
Breakpoint 1, 0x00000000004009e7 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────[ REGISTERS ]──────────────────────────────────
RAX 0x7fffffffca80 ◂— 0x3231 /* '12' */
RBX 0x4002c8 ◂— sub rsp, 8
RCX 0xa
RDX 0x6cc5f0 ◂— 0x0
RDI 0x7fffffffca80 ◂— 0x3231 /* '12' */
RSI 0x6ca0a0 ◂— 'flag{Upx_1s_n0t_a_d3liv3r_c0mp4ny}'
R8 0x0
R9 0x6ce880 ◂— 0x6ce880
R10 0x4a12c4 ◂— and eax, 0x733639 /* '%96s' */
R11 0x246
R12 0x401590 ◂— push r14
R13 0x401620 ◂— push rbx
R14 0x0
R15 0x7fffffffcfb8 —▸ 0x40000c ◂— syscall
RBP 0x7fffffffcaf0 —▸ 0x6ca018 —▸ 0x43b130 ◂— mov rcx, rsi
RSP 0x7fffffffca80 ◂— 0x3231 /* '12' */
RIP 0x4009e7 ◂— call 0x400360
───────────────────────────────────[ DISASM ]───────────────────────────────────
► 0x4009e7 call 0x400360
0x4009ec test eax, eax
0x4009ee jne 0x4009fc
0x4009f0 mov edi, 0x4a12c9
0x4009f5 call 0x40fcc0
0x4009fa jmp 0x400a06
0x4009fc mov edi, 0x4a12da
0x400a01 call 0x40fcc0
0x400a06 mov eax, 0
0x400a0b mov rdx, qword ptr [rbp - 8]
0x400a0f xor rdx, qword ptr fs:[0x28]
───────────────────────────────────[ STACK ]────────────────────────────────────
00:0000│ rax rdi rsp 0x7fffffffca80 ◂— 0x3231 /* '12' */
01:0008│ 0x7fffffffca88 ◂— 0x8000
02:0010│ 0x7fffffffca90 —▸ 0x7fffffffcc48 —▸ 0x7fffffffcfc0 ◂— ' =/home/ex/Downloads/simple2'
03:0018│ 0x7fffffffca98 ◂— 0x2
04:0020│ 0x7fffffffcaa0 —▸ 0x7fffffffcfb8 —▸ 0x40000c ◂— syscall
05:0028│ 0x7fffffffcaa8 —▸ 0x400630 ◂— test rax, rax
06:0030│ 0x7fffffffcab0 ◂— 0x1
... ↓
─────────────────────────────────[ BACKTRACE ]──────────────────────────────────
► f 0 4009e7
f 1 3231
f 2 8000
f 3 7fffffffcc48
f 4 2
f 5 7fffffffcfb8
f 6 400630
f 7 1
f 8 1
f 9 7fffffffcc38
f 10 401607
Breakpoint *0x04009E7
由上面的调试代码看出,flag就在rsi指向的内存中,也就是flag{Upx_1s_n0t_a_d3liv3r_c0mp4ny}
。
总结
虽然Linux上的脱壳题目做的少,但是原理和Windows的差不多。