├── Js-forward.py ├── README.md └── img ├── 0.png ├── 1.png ├── 10.png ├── 11.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── 8.png ├── 9.png ├── 启动.png └── 实现原理.png /Js-forward.py: -------------------------------------------------------------------------------- 1 | from threading import Thread 2 | from http.server import HTTPServer, BaseHTTPRequestHandler 3 | import requests 4 | 5 | 6 | FORWORD_PORT = 28080 7 | ECHO_PORT = 38080 8 | BURP_PORT = 8080 9 | 10 | 11 | class ForwardRequestHandler(BaseHTTPRequestHandler): 12 | def do_POST(self): 13 | content_length = int(self.headers.get('content-length', 0)) 14 | 15 | self.send_response(200) 16 | self.send_header('Access-Control-Allow-Origin','*') 17 | self.end_headers() 18 | data = self.rfile.read(content_length) 19 | if str(self.path) == "/REQUEST": 20 | r = requests.request('REQUEST', 'http://127.0.0.1:{}/'.format(ECHO_PORT), 21 | proxies={'http': 'http://127.0.0.1:{}'.format(BURP_PORT)}, 22 | data=data) 23 | new_data = r.text 24 | self.wfile.write(new_data.encode('utf8')) 25 | else: 26 | try: 27 | r = requests.request('RESPONSE', 'http://127.0.0.1:{}/'.format(ECHO_PORT), 28 | proxies={'http': 'http://127.0.0.1:{}'.format(BURP_PORT)}, 29 | data=data) 30 | new_data = r.text 31 | self.wfile.write(new_data.encode('utf8')) 32 | except: 33 | self.wfile.write(data) 34 | 35 | class RequestHandler(BaseHTTPRequestHandler): 36 | def do_REQUEST(self): 37 | content_length = int(self.headers.get('content-length', 0)) 38 | self.send_response(200) 39 | self.end_headers() 40 | self.wfile.write(self.rfile.read(content_length)) 41 | 42 | do_RESPONSE = do_REQUEST 43 | 44 | def echo_server_thread(): 45 | print('>开始监听镜像服务器,端口:{}'.format(ECHO_PORT)) 46 | server = HTTPServer(('0.0.0.0', ECHO_PORT), RequestHandler) 47 | server.serve_forever() 48 | 49 | def echo_forward_server_thread(): 50 | print('>开始监听转发服务器,端口:{}'.format(FORWORD_PORT)) 51 | server = HTTPServer(('0.0.0.0', FORWORD_PORT), ForwardRequestHandler) 52 | server.serve_forever() 53 | 54 | def get_payload(): 55 | while(1): 56 | print("============================================================================================") 57 | param_name = input(">请输入要forward到Burp的参数名(输入$end结束):") 58 | if param_name == "$end": 59 | return False 60 | data_type = input(">请输入" + param_name + "的数据类型(json/string):") 61 | request_type = input(">请输入请求标识(例如:REQUEST/RESPONSE):") 62 | if data_type == "json": 63 | base_payload = 'var xhr = new XMLHttpRequest();xhr.open(\"post\", \"http://127.0.0.1:' + str(FORWORD_PORT) + '/' + request_type + '\", false);xhr.send(JSON.stringify(' + param_name + '));' + param_name + '=JSON.parse(xhr.responseText);' 64 | elif data_type == "string": 65 | base_payload = 'var xhr = new XMLHttpRequest();xhr.open(\"post\", \"http://127.0.0.1:' + str(FORWORD_PORT) + '/' + request_type + '\", false);xhr.send(' + param_name + ');' + param_name + '=xhr.responseText;' 66 | else: 67 | print(">您的数据类型输入有误") 68 | return True 69 | print('payload生成完毕:\n' + base_payload) 70 | print("============================================================================================") 71 | 72 | 73 | def banner(): 74 | print(''' 75 | _____ ______ ___ __ 76 | |_ _|.' ____ \ .' ..] | ] 77 | | | | (___ \_|______ _| |_ .--. _ .--. _ _ __ ,--. _ .--. .--.| | 78 | _ | | _.____`.|______|'-| |-'/ .'`\ \[ `/'`\][ \ [ \ [ ]`'_\ : [ `/'`\]/ /'`\' | 79 | | |__' | | \____) | | | | \__. | | | \ \/\ \/ / // | |, | | | \__/ | 80 | `.____.' \______.' [___] '.__.' [___] \__/\__/ \'-;__/[___] '.__.;__] 81 | 82 | Version 2.0 By OBG_VSSC_ASC1_Gr33k 83 | ============================================================================================ 84 | 提示: 85 | 本工具生成payload仅限(string/json)类型参数,若参数为其他类型请自行修改payload 86 | ''') 87 | 88 | 89 | 90 | if __name__ == '__main__': 91 | banner() 92 | flag = True 93 | while flag: 94 | flag = get_payload() 95 | t1 = Thread(target=echo_forward_server_thread) 96 | t = Thread(target=echo_server_thread) 97 | t.daemon = True 98 | t.start() 99 | t1.daemon = True 100 | t1.start() 101 | print(">准备就绪 请启动Burp,端口:8080") 102 | for t in [t, t1]: 103 | t.join() 104 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Js-Forward 简介 2 | 3 | Js-Forward是为了解决在渗透测试过程中所遇到的WEB参数加密而开发出的脚本工具 4 | 5 | # Js-Forward 设计背景 6 | 7 | - 随着互联网安全的发展,对重要的业务系统的安全性要求也在逐渐提升,出现了大量用于加密参数的js,实现了客户端浏览器到服务器直接的参数加密。这个时候想要对渗透测试无疑相当于增加了难度,通常我们F12对其进行调试寻找加密过程密钥,解密参数后修改数据包再加密送往服务器,这个过程繁琐且效率低下,遇到轮询密钥交换等不固定密钥算法时还会更加复杂。 8 | - 为此,Js-Forward被开发了出来,通过使用该工具,可以应对几乎所有的前端加密技术对渗透测试造成的困扰。 9 | - 使用便捷。 10 | 11 | # Js-Forward 原理 12 | 13 | - 浏览器在对参数进行加密时,通常会将需要加密的参数传入一个加密函数,返回密文。将服务器密文传入一个解密函数,返回明文,那么不管中间使用的是什么加密方式,总会有两个点可以进行修改,即加密函数入参与解密函数返回,此时加解密问题就变成了如何修改js运行过程参数的问题,到了这里思路逐渐明了。方法大致有两种:1、js hook 2、使用http请求将参数发送出来再外部进行修改,将修改后的返回值再替换原参数。 14 | - 这里选择使用第二种,至于第一种感兴趣的小伙伴可以研究一下看是不是会更方便 15 | 16 | 原理图如下: 17 | 18 | ![image](img/实现原理.png) 19 | 20 | # Js-Forward 使用方法 21 | ``` 22 | python3 Js-forward.py 23 | ``` 24 | - 这里举例的其实已经属于比较复杂的类型,且不包含Js-Forward所需要的jquery,希望大家可以认真看完。 25 | 26 | #### 一、输入手机号,点击发送验证码 27 | ![image](img/0.png) 28 | #### 二、Burp正常抓包,发现参数是加密的,并且有summary、data、encelope三个参数 29 | ![image](img/1.png) 30 | #### 三、通过前端JS的调试,寻找到加密函数点,这里可以发现summary、data、encelope都是由此而来,函数名称setInto 31 | ![image](img/2.png) 32 | #### 四、在Js-Forward中输入要转发出来的参数名称,即data,会生成payload 33 | ![image](img/启动.png) 34 | #### 五、通过chrome浏览器的JS替换功能,将生成payload插入至原JS修改变量处。 35 | #### 六、启动Burp服务,正常触发业务逻辑,可抓到明文数据包。 36 | #### 七、脚本输出请求日志 37 | ![image](img/11.png) 38 | 39 | # 后记 40 | - 遇到需要修改多个参数的,只需要按照上面的方法多生成几条payload插入对应的位置即可。 41 | - 此项目只针对WEB应用,APP解密工具也已完成,由于涉及金融行业APP以及第三方开发框架,暂不公开。 42 | - 有问题请联系 jiaxingl@126.com 43 | -------------------------------------------------------------------------------- /img/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G-Security-Team/JS-Forward/6fff5961e1a89aaaae56e7a86bc806ef681ad60b/img/0.png -------------------------------------------------------------------------------- /img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G-Security-Team/JS-Forward/6fff5961e1a89aaaae56e7a86bc806ef681ad60b/img/1.png -------------------------------------------------------------------------------- /img/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G-Security-Team/JS-Forward/6fff5961e1a89aaaae56e7a86bc806ef681ad60b/img/10.png -------------------------------------------------------------------------------- /img/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G-Security-Team/JS-Forward/6fff5961e1a89aaaae56e7a86bc806ef681ad60b/img/11.png -------------------------------------------------------------------------------- /img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G-Security-Team/JS-Forward/6fff5961e1a89aaaae56e7a86bc806ef681ad60b/img/2.png -------------------------------------------------------------------------------- /img/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G-Security-Team/JS-Forward/6fff5961e1a89aaaae56e7a86bc806ef681ad60b/img/3.png -------------------------------------------------------------------------------- /img/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G-Security-Team/JS-Forward/6fff5961e1a89aaaae56e7a86bc806ef681ad60b/img/4.png -------------------------------------------------------------------------------- /img/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G-Security-Team/JS-Forward/6fff5961e1a89aaaae56e7a86bc806ef681ad60b/img/5.png -------------------------------------------------------------------------------- /img/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G-Security-Team/JS-Forward/6fff5961e1a89aaaae56e7a86bc806ef681ad60b/img/6.png -------------------------------------------------------------------------------- /img/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G-Security-Team/JS-Forward/6fff5961e1a89aaaae56e7a86bc806ef681ad60b/img/7.png -------------------------------------------------------------------------------- /img/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G-Security-Team/JS-Forward/6fff5961e1a89aaaae56e7a86bc806ef681ad60b/img/8.png -------------------------------------------------------------------------------- /img/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G-Security-Team/JS-Forward/6fff5961e1a89aaaae56e7a86bc806ef681ad60b/img/9.png -------------------------------------------------------------------------------- /img/启动.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G-Security-Team/JS-Forward/6fff5961e1a89aaaae56e7a86bc806ef681ad60b/img/启动.png -------------------------------------------------------------------------------- /img/实现原理.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/G-Security-Team/JS-Forward/6fff5961e1a89aaaae56e7a86bc806ef681ad60b/img/实现原理.png --------------------------------------------------------------------------------