欢迎来到 无奈人生 安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

从pwnable.tw-calc看数组越界造成的任意地址读写

来源: 作者: 时间:2019-02-24 21:17 点击: 我要投稿
广告位API接口通信错误,查看德得广告获取帮助

数组越界访问是c程序常见的错误之一,由于c语言并不向Java等语言对数组下标有严格的检查,一旦出现越界,就有可能造成严重的后果。
数组越界访问
看下边一个例子::
#include
#include
int target = 0xdeadbeef;
int main()
{  
    int a[20] = {0xdeadbeef};
    int index,value;
    printf("%x\n",a);
    scanf("%d%d", &index, &value);
    a[index] = value;
    if (target == 0x27)
        printf("Congratulations!\n");
    else
    {
        printf("try again.\n");
    }
    return 0;
}
以32位为例:
gcc -m32 Array-out-of-bounds.c -g0 -o 32
栈空间:
00:0000│ esp  0xffffcdb0 —▸ 0x8048634 ◂— and    eax, 0x642564 /* '%d%d' */
01:0004│      0xffffcdb4 —▸ 0xffffcdc4 —▸ 0xf7ffd918 ◂— 0x0
02:0008│      0xffffcdb8 —▸ 0xffffcdc8 —▸ 0xffffcde0 ◂— 0x0
03:000c│      0xffffcdbc ◂— 0x0
04:0010│      0xffffcdc0 —▸ 0xf7ffd000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x23f3c
05:0014│ eax  0xffffcdc4 —▸ 0xf7ffd918 ◂— 0x0
06:0018│      0xffffcdc8 —▸ 0xffffcde0 ◂— 0x0
07:001c│      0xffffcdcc ◂— 0xdeadbeef
08:0020│      0xffffcdd0 ◂— 0x0
... ↓
1b:006c│ edi  0xffffce1c ◂— 0xc4907500
1c:0070│      0xffffce20 —▸ 0xffffce40 ◂— 0x1
1d:0074│      0xffffce24 —▸ 0xf7fb3000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x1b1db0
1e:0078│ ebp  0xffffce28 ◂— 0x0
1f:007c│      0xffffce2c —▸ 0xf7e19637 (__libc_start_main+247) ◂— add    esp, 0x10
此时我们可以看到a的地址为0xffffcdcc而内存访问数组的方法是:
   0x8048549 94>     add    esp, 0x10
   0x804854c 97>     mov    eax, dword ptr [ebp - 0x64]
   0x804854f 100>    mov    edx, dword ptr [ebp - 0x60]
   0x8048552 103>    mov    dword ptr [ebp + eax*4 - 0x5c], edx
即 ebp-0x5c为a的地址,再加上eax也就是索引乘4,如果我们要修改target的值:
pwndbg> p/x &target
$3 = 0x804a028
即0xffffcdcc + eax * 4 == 0x804a028解方程。我们因为是32位,所以我们可以把这个方程看成:
(0xffffcdcc + eax * 4) & 0xffffffff  == 0x804a028
因为有很多值,我们就取一个:
In [5]: (0x10804a028-0xffffcdcc)/4
Out[5]: 0x2013497
成功修改:
pwndbg> c
Continuing.
ffffcdcc
33633431 39
...
pwndbg> p $ebp + $eax*4 - 0x5c
$5 = (void *) 0x804a028
pwndbg> n
...
pwndbg> p/x target
$6 = 0x27
修改成功,退出调试环境再试一下。
➜  Array-out-of-bounds ./32         
ffd8e7fc
34270731 39
Congratulations!
接下来通过pwnable.tw的一道calc实战一下
pwnable.tw-calc
nc连上去看看:
➜  ~ nc chall.pwnable.tw 10100
=== Welcome to SECPROG calculator ===
1+3
4
1-3
-2
2+-2
expression error!
-2+2
2
0+0
prevent division by zero
-0+1
prevent division by zero
+1+1
2
+5-7
-7
Merry Christmas!
随便输入点什么,可以看到有些奇怪的输出。打开ida加载分析一下、逻辑很简单:
unsigned int calc()
{
  int result[101]; // [esp+18h] [ebp-5A0h]
  char expr; // [esp+1ACh] [ebp-40Ch]
  unsigned int v3; // [esp+5ACh] [ebp-Ch]
  v3 = __readgsdword(0x14u);
  while ( 1 )
  {
    bzero(&expr, 0x400u);
    if ( !get_expr((int)&expr, 1024) )
      break;
    init_pool(result);
    if ( parse_expr(&expr, result) )
    {
      printf(("%d\n", result[result[0] - 1 + 1]);
      fflush(stdout);
    }
  }
  return __readgsdword(0x14u) ^ v3;
}
主要就是这个calc的函数,可以看到一开始读了canary到栈里,然后从命令行读一行字符串然后调用parse_expr来计算,结果放在result[size - 1]处。get_expr的逻辑就是一个字符一个字符读到s里并过滤掉除[0-9]*+-\%的字符。init_pool这个函数初始化了一段大小为100*4内存空间。暂时不知道干什么用的,不过通过calc的那个printf可以推断出这里边放有计算的结果。parse_expr首先是个for循环对输入的表达式进行遍历。

[1] [2] [3]  下一页

数组越界访问是c程序常见的错误之一,由于c语言并不向Java等语言对数组下标有严格的检查,一旦出现越界,就有可能造成严重的后果。
数组越界访问
看下边一个例子::
#include
#include
int target = 0xdeadbeef;
int main()
{  
    int a[20] = {0xdeadbeef};
    int index,value;
    printf("%x\n",a);
    scanf("%d%d", &index, &value);
    a[index] = value;
    if (target == 0x27)
        printf("Congratulations!\n");
    else
    {
        printf("try again.\n");
    }
    return 0;
}
以32位为例:
gcc -m32 Array-out-of-bounds.c -g0 -o 32
栈空间:
00:0000│ esp  0xffffcdb0 —▸ 0x8048634 ◂— and    eax, 0x642564 /* '%d%d' */ 无奈人生安全网
01:0004│      0xffffcdb4 —▸ 0xffffcdc4 —▸ 0xf7ffd918 ◂— 0x0
02:0008│      0xffffcdb8 —▸ 0xffffcdc8 —▸ 0xffffcde0 ◂— 0x0
03:000c│      0xffffcdbc ◂— 0x0
04:0010│      0xffffcdc0 —▸ 0xf7ffd000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x23f3c
05:0014│ eax  0xffffcdc4 —▸ 0xf7ffd918 ◂— 0x0
06:0018│      0xffffcdc8 —▸ 0xffffcde0 ◂— 0x0
07:001c│      0xffffcdcc ◂— 0xdeadbeef
08:0020│      0xffffcdd0 ◂— 0x0
... ↓
1b:006c│ edi  0xffffce1c ◂— 0xc4907500
1c:0070│      0xffffce20 —▸ 0xffffce40 ◂— 0x1
1d:0074│      0xffffce24 —▸ 0xf7fb3000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x1b1db0

www.wnhack.com


1e:0078│ ebp  0xffffce28 ◂— 0x0
1f:007c│      0xffffce2c —▸ 0xf7e19637 (__libc_start_main+247) ◂— add    esp, 0x10
此时我们可以看到a的地址为0xffffcdcc而内存访问数组的方法是:
   0x8048549 94>     add    esp, 0x10
   0x804854c 97>     mov    eax, dword ptr [ebp - 0x64]
   0x804854f 100>    mov    edx, dword ptr [ebp - 0x60]
   0x8048552 103>    mov    dword ptr [ebp + eax*4 - 0x5c], edx
即 ebp-0x5c为a的地址,再加上eax也就是索引乘4,如果我们要修改target的值:
pwndbg> p/x &target
$3 = 0x804a028
即0xffffcdcc + eax * 4 == 0x804a028解方程。我们因为是32位,所以我们可以把这个方程看成:
(0xffffcdcc + eax * 4) & 0xffffffff  == 0x804a028
因为有很多值,我们就取一个:
In [5]: (0x10804a028-0xffffcdcc)/4 copyright 无奈人生
Out[5]: 0x2013497
成功修改:
pwndbg> c
Continuing.
ffffcdcc
33633431 39
...
pwndbg> p $ebp + $eax*4 - 0x5c
$5 = (void *) 0x804a028
pwndbg> n
...
pwndbg> p/x target
$6 = 0x27
修改成功,退出调试环境再试一下。
➜  Array-out-of-bounds ./32         
ffd8e7fc
34270731 39
Congratulations!
接下来通过pwnable.tw的一道calc实战一下
pwnable.tw-calc
nc连上去看看:
➜  ~ nc chall.pwnable.tw 10100
=== Welcome to SECPROG calculator ===
1+3
4
1-3
-2
2+-2
expression error!
-2+2
2
0+0
prevent division by zero
-0+1
prevent division by zero
+1+1
2
+5-7
-7
Merry Christmas!
随便输入点什么,可以看到有些奇怪的输出。打开ida加载分析一下、逻辑很简单:
unsigned int calc()
{
  int result[101]; // [esp+18h] [ebp-5A0h]
  char expr; // [esp+1ACh] [ebp-40Ch]
本文来自无奈人生安全网

  unsigned int v3; // [esp+5ACh] [ebp-Ch]
  v3 = __readgsdword(0x14u);
  while ( 1 )
  {
    bzero(&expr, 0x400u);
    if ( !get_expr((int)&expr, 1024) )
      break;
    init_pool(result);
    if ( parse_expr(&expr, result) )
    {
      printf(("%d\n", result[result[0] - 1 + 1]);
      fflush(stdout);
    }
  }
  return __readgsdword(0x14u) ^ v3;
}
主要就是这个calc的函数,可以看到一开始读了canary到栈里,然后从命令行读一行字符串然后调用parse_expr来计算,结果放在result[size - 1]处。get_expr的逻辑就是一个字符一个字符读到s里并过滤掉除[0-9]*+-\%的字符。init_pool这个函数初始化了一段大小为100*4内存空间。暂时不知道干什么用的,不过通过calc的那个printf可以推断出这里边放有计算的结果。parse_expr首先是个for循环对输入的表达式进行遍历。
内容来自无奈安全网

[1] [2] [3]  下一页 www.wnhack.com

。 (责任编辑:admin)
【声明】:无奈人生安全网(http://www.wnhack.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱472701013@qq.com,我们会在最短的时间内进行处理。