Advertisement
Guest User

Untitled

a guest
Sep 13th, 2016
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.07 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import socket, struct, time
  4. from hashlib import md5
  5. import sys
  6. import os
  7. import random
  8.  
  9. # CONFIG
  10. server = "192.168.100.150"
  11. username = ""
  12. password = ""
  13. host_name = "LIYUANYUAN"
  14. host_os = "8089D"
  15. host_ip = "10.30.22.17"
  16. PRIMARY_DNS = "114.114.114.114"
  17. dhcp_server = "0.0.0.0"
  18. mac = 0xb888e3051680
  19. CONTROLCHECKSTATUS = '\x20'
  20. ADAPTERNUM = '\x01'
  21. KEEP_ALIVE_VERSION = '\xdc\x02'
  22. AUTH_VERSION = '\x0a\x00'
  23. IPDOG = '\x01'
  24. # CONFIG_END
  25.  
  26. nic_name = '' #Indicate your nic, e.g. 'eth0.2'.nic_name
  27. bind_ip = '0.0.0.0'
  28.  
  29. class ChallengeException (Exception):
  30. def __init__(self):
  31. pass
  32.  
  33. class LoginException (Exception):
  34. def __init__(self):
  35. pass
  36.  
  37. def bind_nic():
  38. try:
  39. import fcntl
  40. def get_ip_address(ifname):
  41. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  42. return socket.inet_ntoa(fcntl.ioctl(
  43. s.fileno(),
  44. 0x8915, # SIOCGIFADDR
  45. struct.pack('256s', ifname[:15])
  46. )[20:24])
  47. return get_ip_address(nic_name)
  48. except ImportError as e:
  49. print('Indicate nic feature need to be run under Unix based system.')
  50. return '0.0.0.0'
  51. except IOError as e:
  52. print(nic_name + 'is unacceptable !')
  53. return '0.0.0.0'
  54. finally:
  55. return '0.0.0.0'
  56.  
  57. if nic_name != '':
  58. bind_ip = bind_nic()
  59.  
  60. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  61. # s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  62. s.bind((bind_ip, 61440))
  63.  
  64. s.settimeout(3)
  65. SALT = ''
  66. IS_TEST = True
  67. # specified fields based on version
  68. CONF = "/etc/drcom.conf"
  69. UNLIMITED_RETRY = True
  70. EXCEPTION = False
  71. DEBUG = False #log saves to file
  72. LOG_PATH = '/var/log/drcom_client.log'
  73. if IS_TEST:
  74. DEBUG = True
  75. LOG_PATH = 'drcom_client.log'
  76.  
  77.  
  78. def log(*args, **kwargs):
  79. s = ' '.join(args)
  80. print s
  81. if DEBUG:
  82. with open(LOG_PATH,'a') as f:
  83. f.write(s + '\n')
  84.  
  85. def challenge(svr,ran):
  86. while True:
  87. t = struct.pack("<H", int(ran)%(0xFFFF))
  88. s.sendto("\x01\x02"+t+"\x09"+"\x00"*15, (svr, 61440))
  89. try:
  90. data, address = s.recvfrom(1024)
  91. log('[challenge] recv',data.encode('hex'))
  92. except:
  93. log('[challenge] timeout, retrying...')
  94. continue
  95.  
  96. if address == (svr, 61440):
  97. break
  98. else:
  99. continue
  100. log('[DEBUG] challenge:\n' + data.encode('hex'))
  101. if data[0] != '\x02':
  102. raise ChallengeException
  103. log('[challenge] challenge packet sent.')
  104. return data[4:8]
  105.  
  106. def md5sum(s):
  107. m = md5()
  108. m.update(s)
  109. return m.digest()
  110.  
  111. def dump(n):
  112. s = '%x' % n
  113. if len(s) & 1:
  114. s = '0' + s
  115. return s.decode('hex')
  116.  
  117. def ror(md5, pwd):
  118. ret = ''
  119. for i in range(len(pwd)):
  120. x = ord(md5[i]) ^ ord(pwd[i])
  121. ret += chr(((x<<3)&0xFF) + (x>>5))
  122. return ret
  123.  
  124. def keep_alive_package_builder(number,random,tail,type=1,first=False):
  125. data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type)
  126. if first :
  127. data += '\x0f\x27'
  128. else:
  129. data += KEEP_ALIVE_VERSION
  130. data += '\x2f\x12' + '\x00' * 6
  131. data += tail
  132. data += '\x00' * 4
  133. #data += struct.pack("!H",0xdc02)
  134. if type == 3:
  135. foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip
  136. #CRC
  137. # edited on 2014/5/12, filled zeros to checksum
  138. # crc = packet_CRC(data+foo)
  139. crc = '\x00' * 4
  140. #data += struct.pack("!I",crc) + foo + '\x00' * 8
  141. data += crc + foo + '\x00' * 8
  142. else: #packet type = 1
  143. data += '\x00' * 16
  144. return data
  145.  
  146. # def packet_CRC(s):
  147. # ret = 0
  148. # for i in re.findall('..', s):
  149. # ret ^= struct.unpack('>h', i)[0]
  150. # ret &= 0xFFFF
  151. # ret = ret * 0x2c7
  152. # return ret
  153.  
  154. def keep_alive2(*args):
  155. #first keep_alive:
  156. #number = number (mod 7)
  157. #status = 1: first packet user sended
  158. # 2: first packet user recieved
  159. # 3: 2nd packet user sended
  160. # 4: 2nd packet user recieved
  161. # Codes for test
  162. tail = ''
  163. packet = ''
  164. svr = server
  165. ran = random.randint(0,0xFFFF)
  166. ran += random.randint(1,10)
  167. # 2014/10/15 add by latyas, maybe svr sends back a file packet
  168. svr_num = 0
  169. packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1,True)
  170. while True:
  171. log('[keep-alive2] send1',packet.encode('hex'))
  172. s.sendto(packet, (svr, 61440))
  173. data, address = s.recvfrom(1024)
  174. log('[keep-alive2] recv1',data.encode('hex'))
  175. if data.startswith('\x07\x00\x28\x00') or data.startswith('\x07' + chr(svr_num) + '\x28\x00'):
  176. break
  177. elif data[0] == '\x07' and data[2] == '\x10':
  178. log('[keep-alive2] recv file, resending..')
  179. svr_num = svr_num + 1
  180. packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1, False)
  181. else:
  182. log('[keep-alive2] recv1/unexpected',data.encode('hex'))
  183. #log('[keep-alive2] recv1',data.encode('hex'))
  184.  
  185. ran += random.randint(1,10)
  186. packet = keep_alive_package_builder(svr_num, dump(ran),'\x00'*4,1,False)
  187. log('[keep-alive2] send2',packet.encode('hex'))
  188. s.sendto(packet, (svr, 61440))
  189. while True:
  190. data, address = s.recvfrom(1024)
  191. if data[0] == '\x07':
  192. svr_num = svr_num + 1
  193. break
  194. else:
  195. log('[keep-alive2] recv2/unexpected',data.encode('hex'))
  196. log('[keep-alive2] recv2',data.encode('hex'))
  197. tail = data[16:20]
  198.  
  199.  
  200. ran += random.randint(1,10)
  201. packet = keep_alive_package_builder(svr_num,dump(ran),tail,3,False)
  202. log('[keep-alive2] send3',packet.encode('hex'))
  203. s.sendto(packet, (svr, 61440))
  204. while True:
  205. data, address = s.recvfrom(1024)
  206. if data[0] == '\x07':
  207. svr_num = svr_num + 1
  208. break
  209. else:
  210. log('[keep-alive2] recv3/unexpected',data.encode('hex'))
  211. log('[keep-alive2] recv3',data.encode('hex'))
  212. tail = data[16:20]
  213. log("[keep-alive2] keep-alive2 loop was in daemon.")
  214.  
  215. i = svr_num
  216. while True:
  217. try:
  218. ran += random.randint(1,10)
  219. packet = keep_alive_package_builder(i,dump(ran),tail,1,False)
  220. #log('DEBUG: keep_alive2,packet 4\n',packet.encode('hex'))
  221. log('[keep_alive2] send',str(i),packet.encode('hex'))
  222. s.sendto(packet, (svr, 61440))
  223. data, address = s.recvfrom(1024)
  224. log('[keep_alive2] recv',data.encode('hex'))
  225. tail = data[16:20]
  226. #log('DEBUG: keep_alive2,packet 4 return\n',data.encode('hex'))
  227.  
  228. ran += random.randint(1,10)
  229. packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False)
  230. #log('DEBUG: keep_alive2,packet 5\n',packet.encode('hex'))
  231. s.sendto(packet, (svr, 61440))
  232. log('[keep_alive2] send',str(i+1),packet.encode('hex'))
  233. data, address = s.recvfrom(1024)
  234. log('[keep_alive2] recv',data.encode('hex'))
  235. tail = data[16:20]
  236. #log('DEBUG: keep_alive2,packet 5 return\n',data.encode('hex'))
  237. i = (i+2) % 0xFF
  238. time.sleep(20)
  239. keep_alive1(*args)
  240. except:
  241. pass
  242.  
  243.  
  244. import re
  245. def checksum(s):
  246. ret = 1234
  247. for i in re.findall('....', s):
  248. ret ^= int(i[::-1].encode('hex'), 16)
  249. ret = (1968 * ret) & 0xffffffff
  250. return struct.pack('<I', ret)
  251.  
  252. def mkpkt(salt, usr, pwd, mac):
  253. data = '\x03\x01\x00'+chr(len(usr)+20)
  254. data += md5sum('\x03\x01'+salt+pwd)
  255. data += usr.ljust(36, '\x00')
  256. data += CONTROLCHECKSTATUS
  257. data += ADAPTERNUM
  258. data += dump(int(data[4:10].encode('hex'),16)^mac).rjust(6,'\x00') #mac xor md51
  259. data += md5sum("\x01" + pwd + salt + '\x00'*4) #md52
  260. data += '\x01' # number of ip
  261. data += ''.join([chr(int(i)) for i in host_ip.split('.')]) # x.x.x.x ->
  262. data += ''.join([chr(int(i)) for i in '192.168.211.1'.split('.')]) # your ipaddress 2
  263. data += ''.join([chr(int(i)) for i in '192.168.191.1'.split('.')]) # your ipaddress 3
  264. data += ''.join([chr(int(i)) for i in '192.168.92.1'.split('.')]) # your ipaddress 4
  265. data += md5sum(data + '\x14\x00\x07\x0b')[:8] #md53
  266. data += IPDOG
  267. data += '\x00'*4 # delimeter
  268. data += host_name.ljust(32, '\x00')
  269. data += ''.join([chr(int(i)) for i in PRIMARY_DNS.split('.')]) # primary dns
  270. data += ''.join([chr(int(i)) for i in dhcp_server.split('.')]) # DHCP server
  271. data += ''.join([chr(int(i)) for i in '202.100.192.68'.split('.')]) # secondary dns:0.0.0.0
  272. data += '\x00' * 8 # delimeter
  273. data += '\x94\x00\x00\x00' # OS Version InfoSize
  274. data += '\x06\x00\x00\x00' # OS major
  275. data += '\x02\x00\x00\x00' # OS minor
  276. data += '\xf0\x23\x00\x00' # OS build
  277. data += '\x02\x00\x00\x00' # Platform ID
  278. data += '\x44\x72\x43\x4f\x4d\x00\xcf\x07\x26'
  279. data += '\x00' * 55
  280. data += '\x64\x63\x35\x65\x66\x32\x30\x37\x61\x62\x65\x65\x65\x65\x30\x33\x30\x35\x36\x31\x32\x38\x30\x63\x61\x31\x66\x31\x35\x61\x39\x62\x39\x38\x30\x37\x35\x63\x39\x63'
  281. data += '\x00' * 24
  282. data += AUTH_VERSION
  283. data += '\x00' + chr(len(pwd))
  284. data += ror(md5sum('\x03\x01' + salt + pwd), pwd)
  285. data += '\x02\x0c'
  286. data += checksum(data + '\x01\x26\x07\x11\x00\x00' + dump(mac))
  287. data += '\x00\x00' # delimeter
  288. data += dump(mac)
  289. data += '\x00' # auto logout / default: False
  290. data += '\x00' # broadcast mode / default : False
  291. data += '\xe4\xc7' # unknown, filled numbers randomly =w=
  292.  
  293. log('[mkpkt]',data.encode('hex'))
  294. return data
  295.  
  296. def login(usr, pwd, svr):
  297. import random
  298. global SALT
  299.  
  300. i = 0
  301. while True:
  302. salt = challenge(svr,time.time()+random.randint(0xF,0xFF))
  303. SALT = salt
  304. packet = mkpkt(salt, usr, pwd, mac)
  305. log('[login] send',packet.encode('hex'))
  306. s.sendto(packet, (svr, 61440))
  307. data, address = s.recvfrom(1024)
  308. log('[login] recv',data.encode('hex'))
  309. log('[login] packet sent.')
  310. if address == (svr, 61440):
  311. if data[0] == '\x04':
  312. log('[login] loged in')
  313. break
  314. else:
  315. log('[login] login failed.')
  316. if IS_TEST:
  317. time.sleep(3)
  318. else:
  319. time.sleep(30)
  320. continue
  321. else:
  322. if i >= 5 and UNLIMITED_RETRY == False :
  323. log('[login] exception occured.')
  324. sys.exit(1)
  325. else:
  326. continue
  327.  
  328. log('[login] login sent')
  329. #0.8 changed:
  330. return data[23:39]
  331. #return data[-22:-6]
  332.  
  333. def keep_alive1(salt,tail,pwd,svr):
  334. foo = struct.pack('!H',int(time.time())%0xFFFF)
  335. data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00'
  336. data += tail
  337. data += foo + '\x00\x00\x00\x00'
  338. log('[keep_alive1] send',data.encode('hex'))
  339.  
  340. s.sendto(data, (svr, 61440))
  341. while True:
  342. data, address = s.recvfrom(1024)
  343. if data[0] == '\x07':
  344. break
  345. else:
  346. log('[keep-alive1]recv/not expected',data.encode('hex'))
  347. log('[keep-alive1] recv',data.encode('hex'))
  348.  
  349. def empty_socket_buffer():
  350. #empty buffer for some fucking schools
  351. log('starting to empty socket buffer')
  352. try:
  353. while True:
  354. data, address = s.recvfrom(1024)
  355. log('recived sth unexpected',data.encode('hex'))
  356. if s == '':
  357. break
  358. except:
  359. # get exception means it has done.
  360. log('exception in empty_socket_buffer')
  361. pass
  362. log('emptyed')
  363. def daemon():
  364. with open('/var/run/jludrcom.pid','w') as f:
  365. f.write(str(os.getpid()))
  366.  
  367. def main():
  368. if not IS_TEST:
  369. daemon()
  370. execfile(CONF, globals())
  371. log("auth svr:"+server+"\nusername:"+username+"\npassword:"+password+"\nmac:"+str(hex(mac)))
  372. log(bind_ip)
  373. while True:
  374. try:
  375. package_tail = login(username, password, server)
  376. except LoginException:
  377. continue
  378. log('package_tail',package_tail.encode('hex'))
  379. #keep_alive1 is fucking bullshit!
  380. empty_socket_buffer()
  381. keep_alive1(SALT,package_tail,password,server)
  382. keep_alive2(SALT,package_tail,password,server)
  383. if __name__ == "__main__":
  384. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement