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

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

2018-1-5 20:21
7902

GOAhead CVE-2017-17562深入分析

         GOAhead是一个嵌入式的webserver,前几周被爆出一个远程命令执行的漏洞,受漏洞影响版本:2.5-3.6.4。本文进行该漏洞的深入分析,漏洞调试环境:Ubuntu 16.04 64bit,GOAhead版本3.6.4,下载地址:https://github.com/embedthis/goahead/releases。

GOAhead安装和cgi扩展启用参考:http://blog.csdn.net/yangguihao/article/details/49820765。

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


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


输入cgi的url:http://172.20.94.98:8888/cgi-bin/cgi_test

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;


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 1
支持
分享
最新回复 (4)
雪    币: 6303
活跃值: (2051)
能力值: ( LV7,RANK:150 )
在线值:
发帖
回帖
粉丝
2
给你点赞,经过测试,你的poc可以用。
2018-1-11 22:53
0
雪    币: 207
活跃值: (356)
能力值: ( 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
游客
登录 | 注册 方可回帖
返回
//