Skip to content

Commit

Permalink
CertInfo获取逻辑优化,支持代理
Browse files Browse the repository at this point in the history
  • Loading branch information
bit4woo committed Mar 6, 2024
1 parent 8b6e8cf commit 3d230a1
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 52 deletions.
2 changes: 1 addition & 1 deletion src/Tools/ToolPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ protected void action() {
Iterator<String> it = urls.iterator();
while (it.hasNext()) {
String url = it.next();
Set<String> domains = CertInfo.getAlternativeDomains(url);
Set<String> domains = new CertInfo().getAlternativeDomains(url);
result.add(url + " " + domains.toString());
System.out.println(url + " " + domains.toString());
}
Expand Down
13 changes: 13 additions & 0 deletions src/config/ConfigPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ public class ConfigPanel extends JPanel{

public static JTextField textFieldQuakeAPIKey;
public static JTextField textFieldHunterAPIKey;
public static JTextField textFieldProxyForGetCert;


public LineConfig getLineConfig() {
return lineConfig;
}
Expand Down Expand Up @@ -121,6 +123,7 @@ public void loadConfigToGUI(String projectConfigFile) {
textFieldFofaKey.setText(lineConfig.getFofaKey());
textFieldQuakeAPIKey.setText(lineConfig.getQuakeAPIKey());
textFieldHunterAPIKey.setText(lineConfig.getHunterAPIKey());
textFieldProxyForGetCert.setText(lineConfig.getProxy());

showItemsInOne.setSelected(lineConfig.isShowItemsInOne());
rdbtnSaveTrafficTo.setSelected(lineConfig.isEnableElastic());
Expand All @@ -140,6 +143,7 @@ public LineConfig getConfigFromGUI() {
lineConfig.setFofaKey(textFieldFofaKey.getText());
lineConfig.setQuakeAPIKey(textFieldQuakeAPIKey.getText());
lineConfig.setHunterAPIKey(textFieldHunterAPIKey.getText());
lineConfig.setProxy(textFieldProxyForGetCert.getText());

lineConfig.setToolPanelText(((SuperJTextArea)ToolPanel.inputTextArea).getTextAsDisplay());
lineConfig.setShowItemsInOne(showItemsInOne.isSelected());
Expand Down Expand Up @@ -260,6 +264,12 @@ public void mouseClicked(MouseEvent e) {
textFieldHunterAPIKey.setColumns(30);
textFieldHunterAPIKey.getDocument().addDocumentListener(new textFieldListener());


JLabel lblProxyForGetCert = new JLabel("proxy for get certificates:");

textFieldProxyForGetCert = new JTextField();
textFieldProxyForGetCert.setColumns(30);
textFieldProxyForGetCert.getDocument().addDocumentListener(new textFieldListener());

///////下方是JRadioButton/////

Expand Down Expand Up @@ -413,6 +423,9 @@ public void actionPerformed(ActionEvent e) {
add(lblHunterAPIKey, new MyGridBagLayout(++rowIndex,1));
add(textFieldHunterAPIKey,new MyGridBagLayout(rowIndex,2));

add(lblProxyForGetCert, new MyGridBagLayout(++rowIndex,1));
add(textFieldProxyForGetCert,new MyGridBagLayout(rowIndex,2));

add(DisplayContextMenuOfBurp, new MyGridBagLayout(++rowIndex,2));
add(showItemsInOne, new MyGridBagLayout(++rowIndex,2));
add(ignoreHTTPS, new MyGridBagLayout(++rowIndex,2));
Expand Down
10 changes: 10 additions & 0 deletions src/config/LineConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public class LineConfig {

private String quakeAPIKey = "";
private String hunterAPIKey = "";

private String proxy = "127.0.0.1:7890";

private boolean showItemsInOne = false;
private boolean enableElastic = false;
Expand Down Expand Up @@ -271,6 +273,14 @@ public void setHunterAPIKey(String hunterAPIKey) {
this.hunterAPIKey = hunterAPIKey;
}

public String getProxy() {
return proxy;
}

public void setProxy(String proxy) {
this.proxy = proxy;
}

public boolean isShowItemsInOne() {
return showItemsInOne;
}
Expand Down
142 changes: 94 additions & 48 deletions src/domain/CertInfo.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package domain;

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.Collection;
Expand All @@ -14,71 +16,100 @@
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import base.Commons;
import config.ConfigPanel;

public class CertInfo {
private static TrustManager myX509TrustManager = new X509TrustManager() {

@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}

@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {


private static String proxyHost;
private static Integer proxyPort;

@Deprecated
public CertInfo(String proxyHost, Integer proxyPort) {
CertInfo.proxyHost = proxyHost;
CertInfo.proxyPort = proxyPort;
}

public CertInfo() {
try {
String proxy = ConfigPanel.textFieldProxyForGetCert.getText();
if (proxy != null && !proxy.isEmpty() && proxy.contains(":")) {
String[] parts = proxy.split(":");
if (parts.length==2) {
CertInfo.proxyHost = parts[0];
CertInfo.proxyPort = Integer.parseInt(parts[1]);
}
}
}catch(Exception e) {
e.printStackTrace();
}
}

};


public static Certificate[] getCerts(String aURL) throws Exception {
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
/**
* 核心方法
* @param url
* @param proxyHost
* @param proxyPort
* @return
* @throws Exception
*/
private static Certificate[] getCertificates(String url, String proxyHost, Integer proxyPort) throws Exception {
// 全局忽略主机验证
HostnameVerifier allHostsValid = (hostname, session) -> true;

HttpsURLConnection conn = null;
try {
TrustManager[] tm = new TrustManager[]{myX509TrustManager};
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 初始化 SSL 上下文
TrustManager[] tm = {new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
}};
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, tm, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);//do not check certification
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

URL destinationURL = new URL(aURL);
conn = (HttpsURLConnection) destinationURL.openConnection();
URL urlObject = new URL(url);

// 如果代理相关参数为空,则不设置代理
if (proxyHost != null && proxyPort != null) {
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
conn = (HttpsURLConnection) urlObject.openConnection(proxy);
} else {
conn = (HttpsURLConnection) urlObject.openConnection();
}
conn.connect();
Certificate[] certs = conn.getServerCertificates();
return certs;
}catch (Exception e) {
throw e;
}finally {
if (conn!=null) {

// 获取证书信息
return conn.getServerCertificates();//Certificate[]
} finally {
if (conn != null) {
conn.disconnect();
}
}
}





/**
* get all SANs ---证书中所有的域名信息
* @param url
* @return
*/
public static Set<String> getAlternativeDomains(String url){
public Set<String> getAlternativeDomains(String url){
try {
if (url.toLowerCase().startsWith("https://")){
Certificate[] certs = getCerts(url);
Certificate[] certs = getCertificates(url,proxyHost,proxyPort);
Set<String> domains = getAlternativeDomains(certs);
return domains;
}
Expand Down Expand Up @@ -133,7 +164,7 @@ private static long getDateRange(Certificate[] certs) {
}
return -1;
}

private static String getCertIssuer(Certificate[] certs) {
if (certs == null) return null;
StringBuffer result = new StringBuffer();
Expand All @@ -151,7 +182,7 @@ private static String getCertIssuer(Certificate[] certs) {
public static String getCertIssuer(String url) {
try {
if (url.startsWith("https://")){
Certificate[] certs = getCerts(url);
Certificate[] certs = getCertificates(url,proxyHost,proxyPort);
String info = getCertIssuer(certs);
String org = info.split(",")[1];
org = org.replaceFirst("O=", "");
Expand All @@ -162,11 +193,11 @@ public static String getCertIssuer(String url) {
}
return null;
}

public static String getCertTime(String url) {
try {
if (url.startsWith("https://")){
Certificate[] certs = getCerts(url);
Certificate[] certs = getCertificates(url, proxyHost, proxyPort);
long outtime = getDateRange(certs);//过期时间
return Commons.TimeToString(outtime);
}
Expand All @@ -181,7 +212,7 @@ public static String getCertTime(String url) {
*/
public static Set<String> getSANsbyKeyword(String aURL,Set<String> domainKeywords){//only when domain key word in the Principal,return SANs
try {
Certificate[] certs = getCerts(aURL);
Certificate[] certs = getCertificates(aURL, proxyHost, proxyPort);
for (Certificate cert : certs) {
//System.out.println("Certificate is: " + cert);
if(cert instanceof X509Certificate) {
Expand Down Expand Up @@ -231,12 +262,27 @@ public static void test1() {
e.printStackTrace();
}
}

public static void test2() {
System.out.println("aaaa".contains(""));
}

public static void test3() {
String url = "https://google.com";
String proxyHost = "127.0.0.1";
int proxyPort = 8080;

try {
Certificate[] certs = getCertificates(url, proxyHost, proxyPort);
for (Certificate cert : certs) {
System.out.println(cert);
}
} catch (Exception e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
getCertIssuer("https://shopee.com/index.html");
test3();
}
}
2 changes: 1 addition & 1 deletion src/domain/DomainProducer.java
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ public void run() {
* @return
*/
public boolean isTargetByCertInfoForTarget(String shortURL) throws Exception {
Set<String> certDomains = CertInfo.getAlternativeDomains(shortURL);
Set<String> certDomains = new CertInfo().getAlternativeDomains(shortURL);
for (String domain : certDomains) {
int type = guiMain.getDomainPanel().fetchTargetModel().assetType(domain);
if (type == DomainManager.SUB_DOMAIN || type == DomainManager.TLD_DOMAIN) {
Expand Down
4 changes: 2 additions & 2 deletions src/title/LineEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ public LineEntry firstRequest(GetTitleTempConfig config) {

// 第四步:获取证书域名
if (this.url.toLowerCase().startsWith("https://")) {
this.CertDomainSet = CertInfo.getAlternativeDomains(url);
this.CertDomainSet = new CertInfo().getAlternativeDomains(url);
}
} else {
// 当域名可以解析,但是所有URL请求都失败的情况下。添加一条DNS解析记录
Expand Down Expand Up @@ -319,7 +319,7 @@ public void DoRequestCertInfoAgain() throws MalformedURLException {
try {
String url = this.getUrl();
if (url.toLowerCase().startsWith("https")) {
CertDomainSet = CertInfo.getAlternativeDomains(url);
CertDomainSet = new CertInfo().getAlternativeDomains(url);
}

if (!IPAddressUtils.isValidIP(host)) {// 目标是域名
Expand Down

0 comments on commit 3d230a1

Please sign in to comment.