diff --git a/.classpath b/.classpath
deleted file mode 100644
index 149cb3c..0000000
--- a/.classpath
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.fatjar b/.fatjar
deleted file mode 100644
index 5eada3a..0000000
--- a/.fatjar
+++ /dev/null
@@ -1,14 +0,0 @@
-#Fat Jar Configuration File
-#Fri Oct 26 14:20:32 CST 2018
-onejar.license.required=true
-manifest.classpath=
-manifest.removesigners=true
-onejar.checkbox=false
-jarname=D\:\\github\\domain_hunter\\domain_hunter.v1.2.jar
-manifest.mergeall=true
-manifest.mainclass=
-manifest.file=
-jarname.isextern=true
-onejar.expand=
-excludes=~test/
-includes=
diff --git a/.gitignore b/.gitignore
index eea009b..624e8e8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@
.project
/bin/
/target/
+/.settings/
+.fatjar
diff --git a/README.md b/README.md
index 84de272..7003aac 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
**author**
-[bit4](https://github.com/bit4woo)
+[bit4woo](https://github.com/bit4woo)
**domain_hunter**
@@ -46,6 +46,8 @@ Some times similar domain and related domains give you surprise^_^. that's why I
2018-11-01: Add "Add to domain hunter" menu in site map tree.
+2019-07-06: Use multiple thread to improve search speed. Use regex to find more domain in every response.
+
**xmind of domain collection**
![xmind](doc/xmind.png)
diff --git a/domain_hunter-1.3.jar b/domain_hunter-1.3.jar
deleted file mode 100644
index 7e869e2..0000000
Binary files a/domain_hunter-1.3.jar and /dev/null differ
diff --git a/pom.xml b/pom.xml
index 3db1b8d..7cd93e8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,61 +1,69 @@
-
- 4.0.0
- com.bit4woo.burp
- domain_hunter
- 1.3
-
- src
-
-
- maven-compiler-plugin
- 3.7.0
-
-
- 1.8
-
-
-
-
- maven-assembly-plugin
-
-
- jar-with-dependencies
-
-
-
-
- make-assembly
- package
-
- single
-
-
-
-
-
-
-
-
-
-
- net.portswigger.burp.extender
- burp-extender-api
- 1.7.22
-
-
-
-
- com.alibaba
- fastjson
- 1.2.51
-
-
-
-
- com.google.guava
- guava
- 19.0
-
+
+ 4.0.0
+ com.bit4woo.burp
+ domain_hunter
+ 1.4
+
+ src
+
+
+ maven-compiler-plugin
+ 3.7.0
+
+
+ 1.8
+
+
+
+ maven-assembly-plugin
+
+
+ jar-with-dependencies
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
+
+
+
+ net.portswigger.burp.extender
+ burp-extender-api
+ 1.7.22
+
+
+
+
+ com.alibaba
+ fastjson
+ 1.2.51
+
+
+
+
+ com.google.guava
+ guava
+ 19.0
+
+
+
+
+ org.apache.commons
+ commons-text
+ 1.6
+
\ No newline at end of file
diff --git a/src/burp/BurpExtender.java b/src/burp/BurpExtender.java
index 8acfc83..83baba1 100644
--- a/src/burp/BurpExtender.java
+++ b/src/burp/BurpExtender.java
@@ -1,29 +1,24 @@
package burp;
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.PrintWriter;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
import javax.swing.JMenuItem;
import javax.swing.SwingUtilities;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.Component;
-
-import java.io.PrintWriter;
-import java.net.MalformedURLException;
-import java.net.URL;
public class BurpExtender extends GUI implements IBurpExtender, ITab, IExtensionStateListener,IContextMenuFactory{
- private IBurpExtenderCallbacks callbacks;
+ private static IBurpExtenderCallbacks callbacks;
private IExtensionHelpers helpers;
@@ -58,86 +53,11 @@ public void extensionUnloaded() {
@Override
public Map> search(Set rootdomains, Set keywords){
-
- Set httpsURLs = new HashSet();
- Set httpServiceSet = getHttpServiceFromSiteMap();
- for (IHttpService httpservice:httpServiceSet){
-
- String shortURL = httpservice.toString();
- String protocol = httpservice.getProtocol();
- String Host = httpservice.getHost();
-
- //callbacks.printOutput(rootdomains.toString());
- //callbacks.printOutput(keywords.toString());
- int type = domainResult.domainType(Host);
- //callbacks.printOutput(Host+":"+type);
- if (type == DomainObject.SUB_DOMAIN)
- {
- domainResult.subDomainSet.add(Host);
- }else if (type == DomainObject.SIMILAR_DOMAIN) {
- domainResult.similarDomainSet.add(Host);
- }
-
- if (type !=DomainObject.USELESS && protocol.equalsIgnoreCase("https")){
- httpsURLs.add(shortURL);
- }
- }
-
- stdout.println("sub-domains and similar-domains search finished,starting get related-domains");
- //stdout.println(httpsURLs);
-
- //多线程获取
- //Set>> set = new HashSet>>();
- Map>> urlResultmap = new HashMap>>();
- ExecutorService pool = Executors.newFixedThreadPool(10);
-
- for (String url:httpsURLs) {
- Callable> callable = new ThreadCertInfo(url,keywords);
- Future> future = pool.submit(callable);
- //set.add(future);
- urlResultmap.put(url, future);
- }
-
- Set tmpRelatedDomainSet = new HashSet();
- for(String url:urlResultmap.keySet()) {
- Future> future = urlResultmap.get(url);
- //for (Future> future : set) {
- try {
- stdout.println("founded related-domains :"+future.get() +" from "+url);
- if (future.get()!=null) {
- tmpRelatedDomainSet.addAll(future.get());
- }
- } catch (Exception e) {
- //e.printStackTrace(stderr);
- stderr.println(e.getMessage());
- }
- }
- domainResult.relatedDomainSet =tmpRelatedDomainSet;
- /* 单线程获取方式
- Set tmpRelatedDomainSet = new HashSet();
- //begin get related domains
- for(String url:httpsURLs) {
- try {
- tmpRelatedDomainSet.addAll(CertInfo.getSANs(url));
- }catch(UnknownHostException e) {
- stderr.println("UnknownHost "+ url);
- continue;
- }catch(ConnectException e) {
- stderr.println("Connect Failed "+ url);
- continue;
- }
- catch (Exception e) {
- e.printStackTrace(stderr);
- continue;
- }
- }
- */
- //to save domain result to extensionSetting
- String content= domainResult.Save();
- callbacks.saveExtensionSetting("content", content);
-
- return null;
- }
+ IBurpExtenderCallbacks callbacks = BurpExtender.getCallbacks();
+ IHttpRequestResponse[] messages = callbacks.getSiteMap(null);
+ new ThreadSearhDomain(Arrays.asList(messages)).Do();
+ return null;
+ }
@Override
public Map> crawl (Set rootdomains, Set keywords) {
@@ -309,6 +229,11 @@ public void actionPerformed(ActionEvent e)
}
}
}
+
+ public static IBurpExtenderCallbacks getCallbacks() {
+ // TODO Auto-generated method stub
+ return callbacks;
+ }
/* public static void main(String[] args) {
diff --git a/src/burp/GUI.java b/src/burp/GUI.java
index 249bb1e..4d2310d 100644
--- a/src/burp/GUI.java
+++ b/src/burp/GUI.java
@@ -67,10 +67,10 @@
public class GUI extends JFrame {
- public String ExtenderName = "Domain Hunter v1.3 by bit4";
+ public String ExtenderName = "Domain Hunter v1.4 by bit4woo";
public String github = "https://github.com/bit4woo/domain_hunter";
- public DomainObject domainResult = new DomainObject("");
+ public static DomainObject domainResult = new DomainObject("");
public PrintWriter stdout;
public PrintWriter stderr;
@@ -811,4 +811,10 @@ public boolean accept(File file) {
}
}
+
+ public static DomainObject getDomainResult() {
+ // TODO Auto-generated method stub
+ return domainResult;
+ }
+
}
diff --git a/src/burp/Getter.java b/src/burp/Getter.java
new file mode 100644
index 0000000..6932709
--- /dev/null
+++ b/src/burp/Getter.java
@@ -0,0 +1,230 @@
+package burp;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+
+public class Getter {
+ private static IExtensionHelpers helpers;
+ private final static String Header_Spliter = ": ";
+ public Getter(IExtensionHelpers helpers) {
+ this.helpers = helpers;
+ }
+
+ /*
+ * 获取header的字符串数组,是构造burp中请求需要的格式。
+ */
+ public List getHeaderList(boolean messageIsRequest,IHttpRequestResponse messageInfo) {
+ if(messageIsRequest) {
+ IRequestInfo analyzeRequest = helpers.analyzeRequest(messageInfo);
+ List headers = analyzeRequest.getHeaders();
+ return headers;
+ }else {
+ IResponseInfo analyzeResponse = helpers.analyzeResponse(messageInfo.getResponse());
+ List headers = analyzeResponse.getHeaders();
+ return headers;
+ }
+ }
+
+ public List getHeaderList(boolean IsRequest,byte[] requestOrResponse) {
+ if(IsRequest) {
+ IRequestInfo analyzeRequest = helpers.analyzeRequest(requestOrResponse);
+ List headers = analyzeRequest.getHeaders();
+ return headers;
+ }else {
+ IResponseInfo analyzeResponse = helpers.analyzeResponse(requestOrResponse);
+ List headers = analyzeResponse.getHeaders();
+ return headers;
+ }
+ }
+
+ /*
+ * 获取所有headers,当做一个string看待。
+ * 主要用于判断是否包含某个特殊字符串
+ * List getHeaders 调用toString()方法,得到如下格式:[111111, 2222]
+ * 就能满足上面的场景了
+ */
+ public String getHeaderString(boolean messageIsRequest,IHttpRequestResponse messageInfo) {
+ List headers =null;
+ StringBuilder headerString = new StringBuilder();
+ if(messageIsRequest) {
+ IRequestInfo analyzeRequest = helpers.analyzeRequest(messageInfo);
+ headers = analyzeRequest.getHeaders();
+ }else {
+ IResponseInfo analyzeResponse = helpers.analyzeResponse(messageInfo.getResponse());
+ headers = analyzeResponse.getHeaders();
+ }
+
+ for (String header : headers) {
+ headerString.append(header);
+ }
+
+ return headerString.toString();
+ }
+
+ /*
+ * 获取header的map格式,key:value形式
+ * 这种方式可以用put函数轻松实现:如果有则update,如果无则add。
+ * !!!注意:这个方法获取到的map,会少了协议头GET /cps.gec/limit/information.html HTTP/1.1
+ */
+ public HashMap getHeaderHashMap(boolean messageIsRequest,IHttpRequestResponse messageInfo) {
+ List headers=null;
+ HashMap result = new HashMap();
+ if(messageIsRequest) {
+ IRequestInfo analyzeRequest = helpers.analyzeRequest(messageInfo);
+ headers = analyzeRequest.getHeaders();
+ }else {
+ IResponseInfo analyzeResponse = helpers.analyzeResponse(messageInfo.getResponse());
+ headers = analyzeResponse.getHeaders();
+ }
+
+ for (String header : headers) {
+ if(header.contains(Header_Spliter)) {//to void trigger the Exception
+ try {
+ String headerName = header.split(Header_Spliter, 0)[0];
+ String headerValue = header.split(Header_Spliter, 0)[1];
+ //POST /login.pub HTTP/1.1 the first line of header will tirgger error here
+ result.put(headerName, headerValue);
+ } catch (Exception e) {
+ //e.printStackTrace();
+ }
+ }
+ }
+ return result;
+ }
+
+ public List MapToList(HashMap Headers){
+ List result = new ArrayList();
+ for (Entry header:Headers.entrySet()) {
+ String item = header.getKey()+Header_Spliter+header.getValue();
+ result.add(item);
+ }
+ return result;
+ }
+
+ /*
+ * 获取某个header的值,如果没有此header,返回null。
+ */
+ public String getHeaderValueOf(boolean messageIsRequest,IHttpRequestResponse messageInfo, String headerName) {
+ List headers=null;
+ if(messageIsRequest) {
+ if (messageInfo.getRequest() == null) {
+ return null;
+ }
+ IRequestInfo analyzeRequest = helpers.analyzeRequest(messageInfo);
+ headers = analyzeRequest.getHeaders();
+ }else {
+ if (messageInfo.getResponse() == null) {
+ return null;
+ }
+ IResponseInfo analyzeResponse = helpers.analyzeResponse(messageInfo.getResponse());
+ headers = analyzeResponse.getHeaders();
+ }
+
+
+ headerName = headerName.toLowerCase().replace(":", "");
+ for (String header : headers) {
+ if (header.toLowerCase().startsWith(headerName)) {
+ return header.split(Header_Spliter, 2)[1];//分成2部分,Location: https://www.jd.com
+ }
+ }
+ return null;
+ }
+
+
+ public byte[] getBody(boolean messageIsRequest,IHttpRequestResponse messageInfo) {
+ if (messageInfo == null){
+ return null;
+ }
+ if(messageIsRequest) {
+ if (messageInfo.getRequest() ==null) {
+ return null;
+ }
+ IRequestInfo analyzeRequest = helpers.analyzeRequest(messageInfo);
+ int bodyOffset = analyzeRequest.getBodyOffset();
+ byte[] byte_Request = messageInfo.getRequest();
+
+ byte[] byte_body = Arrays.copyOfRange(byte_Request, bodyOffset, byte_Request.length);//not length-1
+ //String body = new String(byte_body); //byte[] to String
+ return byte_body;
+ }else {
+ if (messageInfo.getResponse() ==null) {
+ return null;
+ }
+ IResponseInfo analyzeResponse = helpers.analyzeResponse(messageInfo.getResponse());
+ int bodyOffset = analyzeResponse.getBodyOffset();
+ byte[] byte_Request = messageInfo.getResponse();
+
+ byte[] byte_body = Arrays.copyOfRange(byte_Request, bodyOffset, byte_Request.length);//not length-1
+ return byte_body;
+ }
+ }
+
+ public byte[] getBody(boolean isRequest,byte[] requestOrResponse) {
+ if (requestOrResponse == null){
+ return null;
+ }
+ int bodyOffset = -1;
+ if(isRequest) {
+ IRequestInfo analyzeRequest = helpers.analyzeRequest(requestOrResponse);
+ bodyOffset = analyzeRequest.getBodyOffset();
+ }else {
+ IResponseInfo analyzeResponse = helpers.analyzeResponse(requestOrResponse);
+ bodyOffset = analyzeResponse.getBodyOffset();
+ }
+ byte[] byte_body = Arrays.copyOfRange(requestOrResponse, bodyOffset, requestOrResponse.length);//not length-1
+ //String body = new String(byte_body); //byte[] to String
+ return byte_body;
+ }
+
+
+ public String getShortUrl(IHttpRequestResponse messageInfo) {
+ return messageInfo.getHttpService().toString();
+ }
+
+ public URL getURL(IHttpRequestResponse messageInfo){
+ IRequestInfo analyzeRequest = helpers.analyzeRequest(messageInfo);
+ return analyzeRequest.getUrl();
+
+ //callbacks.getHelpers().analyzeRequest(baseRequestResponse).getUrl();
+ }
+
+ public String getHost(IHttpRequestResponse messageInfo) {
+ return messageInfo.getHttpService().getHost();
+ }
+
+ public short getStatusCode(IHttpRequestResponse messageInfo) {
+ if (messageInfo == null || messageInfo.getResponse() == null) {
+ return -1;
+ }
+ IResponseInfo analyzedResponse = helpers.analyzeResponse(messageInfo.getResponse());
+ return analyzedResponse.getStatusCode();
+ }
+
+ public List getParas(IHttpRequestResponse messageInfo){
+ IRequestInfo analyzeRequest = helpers.analyzeRequest(messageInfo);
+ return analyzeRequest.getParameters();
+ }
+
+
+ public String getHTTPBasicCredentials(IHttpRequestResponse messageInfo) throws Exception{
+ String authHeader = getHeaderValueOf(true, messageInfo, "Authorization").trim();
+ String[] parts = authHeader.split("\\s");
+
+ if (parts.length != 2)
+ throw new Exception("Wrong number of HTTP Authorization header parts");
+
+ if (!parts[0].equalsIgnoreCase("Basic"))
+ throw new Exception("HTTP authentication must be Basic");
+
+ return parts[1];
+ }
+
+ public static void main(String args[]) {
+ String a= "xxxxx%s%bxxxxxxx";
+ System.out.println(String.format(a, "111"));
+ }
+}
diff --git a/src/burp/ThreadSearhDomain.java b/src/burp/ThreadSearhDomain.java
new file mode 100644
index 0000000..cf6dfd6
--- /dev/null
+++ b/src/burp/ThreadSearhDomain.java
@@ -0,0 +1,243 @@
+package burp;
+
+import java.io.PrintWriter;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.text.StringEscapeUtils;
+
+//////////////////ThreadGetTitle block/////////////
+//no need to pass BurpExtender object to these class, IBurpExtenderCallbacks object is enough
+class ThreadSearhDomain{
+ private List messages;
+ private List plist;
+
+ private static IBurpExtenderCallbacks callbacks = BurpExtender.getCallbacks();//静态变量,burp插件的逻辑中,是可以保证它被初始化的。;
+ public PrintWriter stdout = new PrintWriter(callbacks.getStdout(), true);
+ public PrintWriter stderr = new PrintWriter(callbacks.getStderr(), true);
+ public IExtensionHelpers helpers = callbacks.getHelpers();
+
+ public ThreadSearhDomain(List messages) {
+ this.messages = messages;
+ }
+
+ public void Do(){
+ stdout.println("~~~~~~~~~~~~~Start Search Domain~~~~~~~~~~~~~");
+
+ BlockingQueue inputQueue = new LinkedBlockingQueue();//use to store messageInfo
+ BlockingQueue subDomainQueue = new LinkedBlockingQueue();
+ BlockingQueue similarDomainQueue = new LinkedBlockingQueue();
+ BlockingQueue relatedDomainQueue = new LinkedBlockingQueue();
+
+ inputQueue.addAll(messages);
+
+ plist = new ArrayList();
+
+ for (int i=0;i<=50;i++) {
+ DomainProducer p = new DomainProducer(inputQueue,subDomainQueue,
+ similarDomainQueue,relatedDomainQueue,i);
+ p.start();
+ plist.add(p);
+ }
+
+ while(true) {//to wait all threads exit.
+ if (inputQueue.isEmpty() && isAllProductorFinished()) {
+ stdout.println("~~~~~~~~~~~~~Search Domain Done~~~~~~~~~~~~~");
+ break;
+ }else {
+ try {
+ Thread.sleep(1*1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ continue;
+ }
+ }
+ int oldnumber = GUI.getDomainResult().getSubDomainSet().size();
+
+ GUI.getDomainResult().getSubDomainSet().addAll(subDomainQueue);
+ GUI.getDomainResult().getSimilarDomainSet().addAll(similarDomainQueue);
+ GUI.getDomainResult().getRelatedDomainSet().addAll(relatedDomainQueue);
+
+ int newnumber = GUI.getDomainResult().getSubDomainSet().size();
+ stdout.println(String.format("~~~~~~~~~~~~~%s subdomains added!~~~~~~~~~~~~~",newnumber-oldnumber));
+
+ return;
+ }
+
+ boolean isAllProductorFinished(){
+ for (DomainProducer p:plist) {
+ if(p.isAlive()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void stopThreads() {
+ for (DomainProducer p:plist) {
+ p.stopThread();
+ }
+ stdout.println("threads stopped!");
+ }
+
+ public static void main(String args[]) {//test
+ System.out.println(DomainProducer.grepDomain("http://www.jd.com/usr/www.baidu.com/xss.jd.com"));
+ }
+}
+
+/*
+ * do request use method of burp
+ * return IResponseInfo object Set
+ *
+ */
+
+class DomainProducer extends Thread {//Producer do
+ private final BlockingQueue inputQueue;//use to store messageInfo
+ private final BlockingQueue subDomainQueue;
+ private final BlockingQueue similarDomainQueue;
+ private final BlockingQueue relatedDomainQueue;
+ private BlockingQueue httpsQueue = new LinkedBlockingQueue<>();//temp variable to identify checked https
+
+ private int threadNo;
+ private boolean stopflag = false;
+
+ private static IBurpExtenderCallbacks callbacks = BurpExtender.getCallbacks();//静态变量,burp插件的逻辑中,是可以保证它被初始化的。;
+ public PrintWriter stdout = new PrintWriter(callbacks.getStdout(), true);
+ public PrintWriter stderr = new PrintWriter(callbacks.getStderr(), true);
+ public IExtensionHelpers helpers = callbacks.getHelpers();
+
+ public DomainProducer(BlockingQueue inputQueue,
+ BlockingQueue subDomainQueue,
+ BlockingQueue similarDomainQueue,
+ BlockingQueue relatedDomainQueue,
+ int threadNo) {
+ this.threadNo = threadNo;
+ this.inputQueue = inputQueue;
+ this.subDomainQueue = subDomainQueue;
+ this.similarDomainQueue = similarDomainQueue;
+ this.relatedDomainQueue = relatedDomainQueue;
+ stopflag= false;
+ }
+
+ public void stopThread() {
+ stopflag = true;
+ }
+
+ @Override
+ public void run() {
+ while(true){
+ Getter getter = new Getter(helpers);
+ try {
+ if (inputQueue.isEmpty() || stopflag) {
+ //stdout.println("Producer break");
+ break;
+ }
+
+ IHttpRequestResponse messageinfo = inputQueue.take();
+
+ IHttpService httpservice = messageinfo.getHttpService();
+ String urlString = helpers.analyzeRequest(messageinfo).getUrl().toString();
+
+ String shortURL = httpservice.toString();
+ String protocol = httpservice.getProtocol();
+ String Host = httpservice.getHost();
+
+ //callbacks.printOutput(rootdomains.toString());
+ //callbacks.printOutput(keywords.toString());
+ int type = GUI.domainResult.domainType(Host);
+ //callbacks.printOutput(Host+":"+type);
+ if (type == DomainObject.SUB_DOMAIN)
+ {
+ if (!subDomainQueue.contains(Host)) {
+ subDomainQueue.add(Host);
+ }
+ }else if (type == DomainObject.SIMILAR_DOMAIN) {
+ if (!similarDomainQueue.contains(Host)) {
+ similarDomainQueue.add(Host);
+ }
+ }
+
+ if (type !=DomainObject.USELESS && protocol.equalsIgnoreCase("https")){//get related domains
+ if (!httpsQueue.contains(shortURL)) {//httpService checked or not
+ Set tmpDomains = CertInfo.getSANs(shortURL,GUI.domainResult.fetchKeywordSet());
+ for (String domain:tmpDomains) {
+ if (!relatedDomainQueue.contains(domain)) {
+ relatedDomainQueue.add(domain);
+ }
+ }
+ httpsQueue.add(shortURL);
+ }
+ }
+
+ if (type != DomainObject.USELESS) {//grep domains from response and classify
+ if (urlString.endsWith(".gif") ||urlString.endsWith(".jpg")
+ || urlString.endsWith(".png") ||urlString.endsWith(".css")) {
+
+ }else {
+ classifyDomains(messageinfo);
+ //classifyEmails(messageinfo);
+ }
+ }
+ } catch (Throwable error) {//java.lang.RuntimeException can't been catched, why?
+ }
+ }
+ }
+
+ public void classifyDomains(IHttpRequestResponse messageinfo) {
+ byte[] response = messageinfo.getResponse();
+ if (response != null) {
+ Set domains = DomainProducer.grepDomain(new String(response));
+ for (String domain:domains) {
+ int type = GUI.domainResult.domainType(domain);
+ if (type == DomainObject.SUB_DOMAIN)
+ {
+ subDomainQueue.add(domain);
+
+ }else if (type == DomainObject.SIMILAR_DOMAIN) {
+ similarDomainQueue.add(domain);
+ }
+ }
+ }
+ }
+
+ public static Set grepDomain(String httpResponse) {
+ Set domains = new HashSet<>();
+ //"^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$"
+ final String DOMAIN_NAME_PATTERN = "([A-Za-z0-9-]{1,63}(?