Loading
0

NetGear R系列多款路由器远程命令注入漏洞分析

这里$IFS是Linux的内部域分隔符,这里可以看做是一个空格。
那么接下来跟入sub_19600。
char *__fastcall sub_19600(const char *a1, const char *a2, int a3)
{
const char *v3; // r6@1
const char *v4; // r4@1
int v5; // r5@1
char *result; // r0@1
v3 = a2;
v4 = a1;
v5 = a3;
result = strstr(a1, "cgi-bin");
if ( result )
{
if ( acosNvramConfig_match((int)"cgi_debug_msg", (int)"1") )
printf("\r\n##########%s(%d)url=%s\r\n", "handle_options", 1293, v4);
result = (char *)sub_36C34(v3, v5, v4, 2);
}
return result;
}
比较简短,这里会打印一个url字符串,而url后面跟的%s就是v4,v4由a1而来,a1就是此函数第一个参数,所以第一个参数的确是url的值,接下来v4会作为第三个参数传入sub_36C34函数,漏洞就是在此函数中发生。
这里我先分段讲解这个函数中产生漏洞的整个过程,最后,我再贴上这个函数的完整伪代码。我们重点关注第三个参数v4。
进入后,首先第三个参数,也就是url会交给v6。
1
v6 = a3;
然后会判断v6中是否包含cgi-bin,如果包含,则进入内部处理,这里根据exp,是存在cgi-bin的,接下来进入处理,在处理的过程中,会判断是否包含?,如果包含?,则会给v47赋值,v47这个值我们要记住,在后面设置QUERY_STRING,我们会用到,但是实际上跟此漏洞没有关系。
这里为什么要用到?,就是QUERY_STRING是CGI接收GET参数的,这里默认GET参数是在?后面,就是由此而来。
v12 = strstr(v6, "cgi-bin");
if ( v12 )
{
if ( acosNvramConfig_match((int)&unk_F0378, (int)"1") )
printf("\r\n##########%s(%d)\r\n", "netgear_commonCgi", 76);
if ( strchr(v12, 63) )
{
if ( acosNvramConfig_match((int)&unk_F0378, (int)"1") )
printf("\r\n##########%s(%d)\r\n", "netgear_commonCgi", 80);
v13 = strchr(v12, 63);
if ( acosNvramConfig_match((int)&unk_F0378, (int)"1") )
printf("\r\n#############%s(%d)tmp1=%s,tmp2=%s\r\n", "netgear_commonCgi", 83, v12, v13 + 1);
strcpy((char *)&v47, v13 + 1);
if ( acosNvramConfig_match((int)&unk_F0378, (int)"2") )
printf("\r\n###############%s(%d)query_string=%s\r\n", "netgear_commonCgi", 86, &v47);
v14 = strchr(v6, 47);
当然,在exp中是不包含?的,因此这个if ( strchr(v12, 63) )
语句不成立,则不进入这个处理,看一下下面的else语句。
在else语句中会进行字符串切割,切割的就是v12,也就是cgi-bin/;killall,这里注释里我写出了切割后地址指针指向的字符串内容。
比较关心的就是v20,v21和v22,其中由于切割后,后面不再包含47,也就是/的ascii码,因此v22为0,之后会对v50进行初始化。
else
{
if ( acosNvramConfig_match((int)&unk_F0378, (int)"2") )
printf("\r\n##########%s(%d)\r\n", "netgear_commonCgi", 99);
v19 = strchr(v12, 47);
v20 = v19 + 1;                          // ;kill
v21 = v19;                              // /;kill
v22 = strchr(v19 + 1, 47);              // v22=NULL
memset(&v50, 0, 0x40u);                 // v50init
v23 = (char)v21;
然后就进入一系列的判断,判断的内容就是切割之后;kill后面还包含不包含/。
if ( v21 )
v23 = 1;
v24 = v22 == 0;
if ( v22 )
v24 = v21 == 0;

分页阅读: 1 2 3 4 5 6 7 8 9
【声明】:8090安全小组门户(https://www.8090-sec.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们:邮箱hack@ddos.kim,我们会在最短的时间内进行处理。