首页
社区
课程
招聘
[原创]GOAhead CVE-2017-17562深入分析
发表于: 2018-1-5 20:21 8178

[原创]GOAhead CVE-2017-17562深入分析

2018-1-5 20:21
8178

GOAhead CVE-2017-17562深入分析

         GOAhead是一个嵌入式的webserver,前几周被爆出一个远程命令执行的漏洞,受漏洞影响版本:2.5-3.6.4。本文进行该漏洞的深入分析,漏洞调试环境:Ubuntu 16.04 64bit,GOAhead版本3.6.4,下载地址:78fK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6W2L8h3u0W2k6s2c8Z5K9i4y4Q4x3V1k6Y4L8$3q4Z5k6h3q4V1i4K6u0r3M7X3g2D9k6h3q4K6k6i4y4Q4c8e0y4Q4z5o6m8Q4z5o6t1`.

GOAhead安装和cgi扩展启用参考:048K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3u0D9L8$3N6Q4x3X3g2U0M7$3c8F1i4K6u0W2L8X3g2@1i4K6u0r3P5h3q4F1k6$3N6#2K9h3S2S2L8#2)9J5c8X3q4J5N6r3W2U0L8r3g2Q4x3V1k6V1k6i4c8S2K9h3I4K6i4K6u0r3y4o6V1^5x3U0l9%4y4U0g2Q4c8e0y4Q4z5o6m8Q4z5o6t1`.

GOAhead要启用CGI时,记的是修改要修改/etc/goahead中的route.txt。


dir是cgi的存放目录,其目录下存放一个cgi_test,里面内容随便写,然后gcc编译即可。


输入cgi的url:9f5K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8U0p5%4x3W2)9J5k6e0t1H3i4K6u0W2z5e0c8Q4x3X3f1&6z5q4)9K6b7e0R3^5z5o6S2Q4x3V1k6U0k6$3W2Q4x3X3c8T1K9h3&6Q4x3V1k6U0k6$3W2Q4y4h3k6@1k6i4y4@1

LD_PRELOAD是Linux系统的一个环境变量,用于动态库的加载执行,动态库加载的优先级最高,一般情况下,其加载顺序为:LD_PRELOAD>LD_LIBRARY>/etc/ld.so.cache >/lib>/usr/lib.它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态库,甚至覆盖正常的函数库。

LA_PRELOAD替换前:

 

LA_PRELOAD替换后:

        

演示程序:

a.主程序(login.c)

#include <stdio.h>

#include <string.h>

#include "myverify.h"

void main(int argc, char const *argv[])

{

         char pwd[] = "123456";

         if(argc < 2)

         {

                   printf("usage: %s <your password>\n", argv[0]);

                   return;

         }

         if(!verify(pwd, argv[1]))

         {

                   printf("login success\n");

         }

         else

         {

                   printf("login fail\n");

         }

}

b.调用库(myverify.h和myverify.c)

#include <stdio.h>

int verify(const char *s1, const char *s2);

#include <stdio.h>

#include <string.h>

#include "myverify.h"

int verify(const char *s1, const char *s2)

{

         return strcmp(s1, s2);

}

c.编译运行效果如下:


相关命令解释如下:

gcc myverify.c -fPIC -shared -o libmyverify.so #编译动态链接库

gcc login.c -L. -lmyverify -o mylogin #编译主程序

export LD_LIBRARY_PATH=/home/daizy/workplace/CDemo/LinuxAPI/ #指定动态链接库所在目录位置

ldd myverifypasswd #显示、确认依赖关系

d.替换代码如下:(myhack.c)

#include <stdio.h>

#include <string.h>

int verify(const char *s1, const char *s2)

{

         printf("hack function invoked.\n");

         return 0;

}

e.编译设置环境变量LD_PRELOAD,运行替换代码效果如下:


export LD_PRELOAD="./myhack.so" #设置LD_PRELOAD环境变量,库中的同名函数在程序运行时优先调用

ps:替换结束,要还原函数调用关系,用命令unset LD_PRELOAD 解除

以GOAhead 3.6.4版本为例进行漏洞分析:

当用户post提交数据时,goahead最终会调用http.c中readEvent(Webs *wp)进行数据读取的处理,其中结构体Webs后续会常看到,此处先给出该结构体大致定义,在goahead.h中可以查找到:

typedef struct Webs {

    WebsBuf         rxbuf;              /**< Raw receive buffer */

    WebsBuf         input;              /**< Receive buffer after de-chunking */

    WebsBuf         output;             /**< Transmit buffer after chunking */

    WebsBuf         chunkbuf;           /**< Pre-chunking data buffer */

    WebsBuf         *txbuf;

    WebsHash        vars;               /**< CGI standard variables */

    int             rxChunkState;       /**< Rx chunk encoding state */

    ssize           rxChunkSize;        /**< Rx chunk size */

    char            *rxEndp;            /**< Pointer to end of raw data in input beyond endp */

    ssize           lastRead;           /**< Number of bytes last read from the socket */

    ssize           txChunkPrefixLen;   /**< Length of prefix */

    ssize           txChunkLen;         /**< Length of the chunk */

    int             txChunkState;       /**< Transmit chunk state */

    char            *filename;          /**< Document path name */

    char            *path;             /**< Path name without query. This is decoded. */ 

    int             sid;                /**< Socket id (handler) */

    int             routeCount;         /**< Route count limiter */

    ssize           rxLen;              /**< Rx content length */

    ssize           rxRemaining;        /**< Remaining content to read from client */

    ssize           txLen;              /**< Tx content length header value */

    int             wid;                /**< Index into webs */

#if ME_GOAHEAD_CGI

    char            *cgiStdin;          /**< Filename for CGI program input */

    int             cgifd;              /**< File handle for CGI program input */

#endif

    struct WebsRoute *route;            /**< Request route */

    struct WebsUser *user;              /**< User auth record */

    WebsWriteProc   writeData;      /**< Handler write I/O event callback. Used by fileHandler */

} Webs;


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 1
支持
分享
最新回复 (4)
雪    币: 6637
活跃值: (2416)
能力值: ( LV7,RANK:150 )
在线值:
发帖
回帖
粉丝
2
给你点赞,经过测试,你的poc可以用。
2018-1-11 22:53
0
雪    币: 207
活跃值: (462)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
如果实际环境中的cgi程序需要验证怎么办,这个能运行吗?
2018-1-15 14:39
0
雪    币: 506
活跃值: (185)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
4
这个不影响的,cgi验证意思是cgi需要执行起来才能验证,所以只要goahead调用了execve函数执行cgi程序,就会触发远程该漏洞。
2018-1-15 19:12
0
雪    币: 506
活跃值: (185)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
5
fighter 如果实际环境中的cgi程序需要验证怎么办,这个能运行吗?
这个不影响的,cgi验证意思是cgi需要执行起来才能验证,所以只要goahead调用了execve函数执行cgi程序,就会触发远程该漏洞。
2018-1-15 19:12
0
游客
登录 | 注册 方可回帖
返回