Guest User

Untitled

a guest
Aug 22nd, 2018
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.64 KB | None | 0 0
  1. #! /usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. import socket, struct, random, time, re, os, datetime
  5. from hashlib import md5
  6.  
  7. ########## Configuration ###############
  8.  
  9. ### Required ###
  10. username='USERNAME' #用户名
  11. password='PASSWORD' #密码
  12. host_ip = 'IP_ADDR' #ip地址
  13. mac = 0x010203040506 #mac地址 echo 0x`ifconfig eth | egrep -io "([0-9a-f]{2}:){5}[0-9a-f]{2}" | tr -d ":"`
  14.  
  15. ### Optional ###
  16. host_name = '++++++++' #计算机名
  17. host_os = 'Windows XP' #操作系统
  18. bind_ip = '0.0.0.0' #must be listed in your `ip a` results
  19. LOG_PATH = '/var/log/drcom.log'
  20. RETRY = False
  21.  
  22. ### for Development ###
  23. IS_DEBUG=False
  24.  
  25. server = '10.100.61.3'
  26.  
  27. #used in mkpkt()
  28. CONTROLCHECKSTATUS = '\x20'
  29. ADAPTERNUM = '\x03'
  30. IPDOG = '\x01'
  31. PRIMARY_DNS = '10.10.10.10'
  32. dhcp_server = '0.0.0.0'
  33. AUTH_VERSION = '\x68\x00'
  34.  
  35. # used in keep_alive
  36. KEEP_ALIVE_VERSION = '\xdc\x02'
  37. ############## END #####################
  38.  
  39. class LoginException (Exception):
  40. def __init__(self):
  41. pass
  42.  
  43. def setup_socket(bind_ip):
  44. log('DEBUG', 'setup_socket()')
  45. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  46. # s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  47. s.bind((bind_ip, 61440))
  48. s.settimeout(3)
  49. return s
  50.  
  51.  
  52. def do_login(user, pwd, salt, mac, svr, socket):
  53. log('DEBUG', 'do_login()')
  54. packet = mkpkt(salt, user, pwd, mac)
  55. log('DEBUG', '[login] send:' + packet.encode('hex'))
  56. socket.sendto(packet, (svr, 61440))
  57. data, address = socket.recvfrom(1024)
  58. log('DEBUG', '[login] recv:' + data.encode('hex'))
  59. if address == (svr, 61440):
  60. if data[0] == '\x04':
  61. log('INFO', 'auth success.')
  62. else:
  63. log('WARN', 'auth failed.')
  64. raise LoginException
  65. else:
  66. log('WARN', 'exception occured. address not match')
  67. raise Exception
  68.  
  69. #0.8 changed:
  70. return data[23:39]
  71. #return data[-22:-6]
  72.  
  73.  
  74. def get_salt(socket, svr, rand):
  75. log('DEBUG', 'get_salt()')
  76. t = struct.pack("<H", int(rand)%(0xFFFF))
  77. socket.sendto("\x01\x02"+t+"\x09"+"\x00"*15, (svr, 61440))
  78. log('DEBUG', 'send: blabla ')
  79. data, address = socket.recvfrom(1024)
  80. log('DEBUG', 'sending:' + data.encode('hex'))
  81. if data[0] != '\x02':
  82. raise Exception
  83. return data[4:8]
  84.  
  85.  
  86. def mkpkt(salt, usr, pwd, mac):
  87. log('DEBUG', 'mkpkt()')
  88. data = '\x03\x01\x00'+chr(len(usr)+20)
  89. data += md5sum('\x03\x01'+salt+pwd)
  90. data += usr.ljust(36, '\x00')
  91. data += CONTROLCHECKSTATUS
  92. data += ADAPTERNUM
  93. data += dump(int(data[4:10].encode('hex'),16)^mac).rjust(6,'\x00') #mac xor md51
  94. data += md5sum("\x01" + pwd + salt + '\x00'*4) #md52
  95. data += '\x01' # number of ip
  96. #data += '\x0a\x1e\x16\x11' #your ip address1, 10.30.22.17
  97. data += ''.join([chr(int(i)) for i in host_ip.split('.')]) #x.x.x.x ->
  98. data += '\00'*4 #your ipaddress 2
  99. data += '\00'*4 #your ipaddress 3
  100. data += '\00'*4 #your ipaddress 4
  101. data += md5sum(data + '\x14\x00\x07\x0b')[:8] #md53
  102. data += IPDOG
  103. data += '\x00'*4 #delimeter
  104. data += host_name.ljust(32, '\x00')
  105. data += ''.join([chr(int(i)) for i in PRIMARY_DNS.split('.')]) #primary dns
  106. data += ''.join([chr(int(i)) for i in dhcp_server.split('.')]) #DHCP server
  107. data += '\x00\x00\x00\x00' #secondary dns:0.0.0.0
  108. data += '\x00' * 8 #delimeter
  109. data += '\x94\x00\x00\x00' # unknow
  110. data += '\x06\x00\x00\x00' # os major
  111. data += '\x02\x00\x00\x00' # os minor
  112. data += '\xf0\x23\x00\x00' # OS build
  113. data += '\x02\x00\x00\x00' #os unknown
  114. data += '\x44\x72\x43\x4f\x4d\x00\xcf\x07\x68'
  115. data += '\x00' * 55#unknown string
  116. data += '\x33\x64\x63\x37\x39\x66\x35\x32\x31\x32\x65\x38\x31\x37\x30\x61\x63\x66\x61\x39\x65\x63\x39\x35\x66\x31\x64\x37\x34\x39\x31\x36\x35\x34\x32\x62\x65\x37\x62\x31'
  117. data += '\x00' * 24
  118. data += AUTH_VERSION
  119. data += '\x00' + chr(len(pwd))
  120. data += ror(md5sum('\x03\x01'+salt+pwd), pwd)
  121. data += '\x02\x0c'
  122. data += checksum(data+'\x01\x26\x07\x11\x00\x00'+dump(mac))
  123. data += '\x00\x00' #delimeter
  124. data += dump(mac)
  125. if (len(pwd) / 4) != 4:
  126. data += '\x00' * (len(pwd) / 4)#strange。。。
  127. data += '\x60\xa2' #unknown, filled numbers randomly =w=
  128. data += '\x00' * 28
  129. return data
  130.  
  131.  
  132. def md5sum(str):
  133. log('DEBUG', 'md5sum()')
  134. m = md5()
  135. m.update(str)
  136. return m.digest()
  137.  
  138.  
  139. def dump(n):
  140. log('DEBUG', 'dump()')
  141. s = '%x' % n
  142. if len(s) & 1:
  143. s = '0' + s
  144. return s.decode('hex')
  145.  
  146.  
  147. def ror(md5, pwd):
  148. log('DEBUG', 'ror()')
  149. ret = ''
  150. for i in range(len(pwd)):
  151. x = ord(md5[i]) ^ ord(pwd[i])
  152. ret += chr(((x<<3)&0xFF) + (x>>5))
  153. return ret
  154.  
  155.  
  156. def checksum(s):
  157. log('DEBUG', 'checksum()')
  158. ret = 1234
  159. for i in re.findall('....', s):
  160. ret ^= int(i[::-1].encode('hex'), 16)
  161. ret = (1968 * ret) & 0xffffffff
  162. return struct.pack('<I', ret)
  163.  
  164.  
  165. def keep_alive(pwd, salt, cookie, svr, socket):
  166. log('DEBUG', 'keep_alive')
  167. old_cookie = cookie
  168. keep_alive1(salt, old_cookie, pwd, svr, socket)
  169.  
  170. svr_num = 0
  171.  
  172. svr_num, cookie = keep_alive_pre_1(svr_num, cookie, svr, socket)
  173. svr_num, cookie = keep_alive_pre_2(svr_num, cookie, svr, socket)
  174. svr_num, cookie = keep_alive_pre_3(svr_num, cookie, svr, socket)
  175.  
  176. i = svr_num
  177. while True:
  178. packet = keep_alive_package_builder(i, cookie, 1, False)
  179. socket.sendto(packet, (svr, 61440))
  180. data, address = socket.recvfrom(1024)
  181. cookie = data[16:20]
  182.  
  183. packet = keep_alive_package_builder(i+1, cookie, 3, False)
  184. socket.sendto(packet, (svr, 61440))
  185. data, address = socket.recvfrom(1024)
  186. cookie = data[16:20]
  187.  
  188. i = (i+2) % 0xFF
  189. time.sleep(20)
  190. keep_alive1(salt, old_cookie, pwd, svr, socket)
  191.  
  192.  
  193. def keep_alive1(salt, cookie, pwd, svr, socket):
  194. log('DEBUG', 'keep_alive1()')
  195. foo = struct.pack('!H',int(time.time())%0xFFFF)
  196. data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00'
  197. data += cookie
  198. data += foo + '\x00\x00\x00\x00'
  199. log('DEBUG', 'send:'+data.encode('hex'))
  200. socket.sendto(data, (svr, 61440))
  201. while True:
  202. data, address = socket.recvfrom(1024)
  203. log('DEBUG', 'recv:'+data.encode('hex'))
  204. if data[0] == '\x07':
  205. break
  206. else:
  207. log('WARN', 'unexpected recv:'+data.encode('hex'))
  208.  
  209.  
  210. def keep_alive_pre_1(svr_num, cookie, svr, socket):
  211. log('DEBUG', 'keep_alive_pre_1()')
  212. packet = keep_alive_package_builder(svr_num, '\x00'*4, 1, True)
  213. log('DEBUG', 'send:'+packet.encode('hex'))
  214. while True:
  215. socket.sendto(packet, (svr, 61440))
  216. data, address = socket.recvfrom(1024)
  217. log('DEBUG', 'recv:'+data.encode('hex'))
  218. if data.startswith('\x07\x00\x28\x00') or data.startswith('\x07' + chr(svr_num) + '\x28\x00'):
  219. break
  220. # 2014/10/15 add by latyas, maybe svr sends back a file packet
  221. elif data[0] == '\x07' and data[2] == '\x10':
  222. svr_num = svr_num + 1
  223. packet = keep_alive_package_builder(svr_num, '\x00'*4, 1, False)
  224. else:
  225. log('WARN', 'unexpected recv:'+data.encode('hex'))
  226. return svr_num, None
  227.  
  228. def keep_alive_pre_2(svr_num, cookie, svr, socket):
  229. log('DEBUG', 'keep_alive_pre_2()')
  230. packet = keep_alive_package_builder(svr_num, '\x00'*4, 1, False)
  231. log('DEBUG', 'send:'+packet.encode('hex'))
  232. socket.sendto(packet, (svr, 61440))
  233. while True:
  234. data, address = socket.recvfrom(1024)
  235. log('DEBUG', 'recv:'+data.encode('hex'))
  236. if data[0] == '\x07':
  237. svr_num = svr_num + 1
  238. break
  239. else:
  240. log('WARN', 'unexpected recv:'+data.encode('hex'))
  241. cookie = data[16:20]
  242. return svr_num, cookie
  243.  
  244. def keep_alive_pre_3(svr_num, cookie, svr, socket):
  245. log('DEBUG', 'keep_alive_pre_3')
  246. packet = keep_alive_package_builder(svr_num, cookie, 3, False)
  247. log('DEBUG', 'send:'+packet.encode('hex'))
  248. socket.sendto(packet, (svr, 61440))
  249. while True:
  250. data, address = socket.recvfrom(1024)
  251. log('DEBUG', 'recv:'+data.encode('hex'))
  252. if data[0] == '\x07':
  253. svr_num = svr_num + 1
  254. break
  255. else:
  256. log('WARN', 'unexpected recv:'+data.encode('hex'))
  257. cookie = data[16:20]
  258. return svr_num, cookie
  259.  
  260.  
  261. def keep_alive_package_builder(svr_number, cookie, type=1, first=False):
  262. log('DEBUG', 'keep_alive_package_builder()')
  263. data = '\x07'+ chr(svr_number) + '\x28\x00\x0b' + chr(type)
  264. if first :
  265. data += '\x0f\x27'
  266. else:
  267. data += KEEP_ALIVE_VERSION
  268. data += '\x2f\x12' + '\x00' * 6
  269. data += cookie
  270. data += '\x00' * 4
  271. if type == 3:
  272. foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip
  273. crc = '\x00' * 4
  274. data += crc + foo + '\x00' * 8
  275. else: #packet type = 1
  276. data += '\x00' * 16
  277. return data
  278.  
  279.  
  280. def empty_socket_buffer(socket):
  281. #empty buffer for some fucking schools
  282. log('DEBUG', 'starting to empty socket buffer')
  283. try:
  284. while True:
  285. data, address = socket.recvfrom(1024)
  286. log('DEBUG', 'recived sth unexpected'+data.encode('hex'))
  287. if socket == '':
  288. break
  289. except:
  290. # get exception means it has done.
  291. log('DEBUG', 'exception in empty_socket_buffer')
  292. log('DEBUG', 'emptyed')
  293.  
  294.  
  295. def log(level, msg):
  296. log_msg = '[%s]: %s (%s)' % (level, msg, datetime.datetime.now() )
  297. if IS_DEBUG:
  298. print log_msg
  299. return
  300. if level == 'DEBUG':
  301. return
  302. try:
  303. with open(LOG_PATH, 'a') as f:
  304. f.write(log_msg+'\n')
  305. except Exception as e:
  306. print "Unable to log, %s" % e
  307.  
  308. def main():
  309. os.environ["TZ"] = 'Asia/Shanghai'
  310. time.tzset()
  311. log('INFO', 'starting...')
  312. is_first_time = True
  313. while RETRY or is_first_time:
  314. is_first_time = False
  315. try:
  316. socket = setup_socket(bind_ip)
  317. salt = get_salt(socket, server, random.randint(0xF,0xFF))
  318. cookie = do_login(username, password, salt, mac, server, socket)
  319. empty_socket_buffer(socket)
  320. keep_alive(password, salt, cookie, server, socket)
  321. except LoginException as e:
  322. pass
  323. except Exception as e: #normal exception is timeout, which mostly caused by multiplace login and this session is ticked out
  324. log('WARN', e)
  325. socket.close()
  326. log('INFO', 'release socket')
  327. time.sleep(15)
  328. log('INFO', 'process quit')
  329.  
  330. if __name__ == "__main__":
  331. main()
Add Comment
Please, Sign In to add comment