在渗透测试过程中,扫描敏感目录文件是一件非常重要的事情,那么接下来,我们就用Java来做一个目录扫描的Demo。同样,对于网络编程一样要用到以下几个类:
1、java.net.HttpUrlConnection 2、java.net.Url
接下来对Http UrlConnection类进行了分装,按照http请求分为了request与response,这样一来直接对HTTP协议进行操作,就方便多了。
request 类如下:
package com.xxser.http; import java.io.IOException; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.Proxy; import java.net.URL; public class Request { privateURL url; privateHttpURLConnection con; privateProxy proxy = null; /** * 构造方法 * * @param url * Url信息 */ publicRequest(String url) { try{ this.url= new URL(url); this.init(); } catch(MalformedURLException e) { e.printStackTrace(); } } /** * * @param url * URL 信息 * @param proxy * 代理 */ publicRequest(String url, Proxy proxy) { try{ this.url= new URL(url); this.proxy= proxy; this.init(); } catch(MalformedURLException e) { e.printStackTrace(); } } publicRequest(URL url) { this.url= url; this.init(); } publicURL getUrl() { returnurl; } publicHttpURLConnection getCon() { returncon; } /** * 初始化 HTTP 信息 */ privatevoid init() { try{ if(this.proxy == null) { this.con= (HttpURLConnection) url.openConnection(); } else { this.con= (HttpURLConnection) this.url .openConnection(this.proxy); } }catch (IOException e) { e.printStackTrace(); } } /** * 得到Response * * @return */ publicResponse getResponse() { try{ this.con.getInputStream();// 发起请求 } catch (IOException e) { e.printStackTrace(); } Responseres = new Response(this.con); returnres; } /** * 设置请求方法 * * @param method */ publicvoid setMethod(String method) { try{ this.con.setRequestMethod(method); } catch (ProtocolException e){ e.printStackTrace(); } } /** * 设置请求头 * * @param h * 头 * @param v * 值 */ publicRequest setHeader(String h, String v) { this.con.addRequestProperty(h,v); returnthis; } /** *设置请求头内容 * * @param data */ publicvoid setData(String data) { this.con.setDoOutput(true); OutputStreamos = null; try{ os= this.con.getOutputStream(); os.write(data.getBytes()); os.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 设置是否执行302跳转 * @param set */ @SuppressWarnings("static-access") public void setInstanceFollowRedirects (booleanflag) { this.con.setInstanceFollowRedirects (flag); } }
response 类如下:
package com.xxser.http; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; public class Response { private HttpURLConnection con; public Response(HttpURLConnection con) { this.con = con; } /** * * @return 获取原始请求 */ public HttpURLConnection getCon() { return con; } /** * 获取请求头 * @param key * @return */ public String getHeader(String key) { return this.con.getHeaderField(key); } /** * * @return获取内容,默认编码为GBK */ public String getBody() { return this.getBody("GBK"); } /** * * @param charset字符编码 * @return获取内容 */ public String getBody(String charset) { BufferedReader buf = null; try { buf = new BufferedReader(new InputStreamReader(this.con .getInputStream(), charset)); } catch (IOException e) { e.printStackTrace(); } StringBuilder sb = new StringBuilder(); try { for (String temp = buf.readLine(); temp != null; temp = buf .readLine()) { sb.append(temp); sb.append(System.getProperty("line.separator")); } } catch (IOException e) { e.printStackTrace(); } return sb.toString(); } /** * * @return HTTP 状态码 */ public int getResponseCode() { int temp = -1 ; try { temp = this.con.getResponseCode() ; } catch (IOException e) { e.printStackTrace(); } return temp ; } }
两个类都有了,那么接下来步入正题,在扫描中,一般使用HEAD方法是最快的,因为不用等待取得HTTP body,也就是HTML、JS、CSS等数据。
进行测试,代码如下:
package com.xxser.test; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.Proxy.Type; import com.xxser.http.Request; import com.xxser.http.Response; public class Main { public static void main(String[] args) throws Exception { Proxy p = new Proxy(Type.HTTP,new InetSocketAddress("127.0.0.1",8888)); Request r = new Request("http://www.moonsos.com"+"/index.html", p); r.setHeader("User-Agent", "HelloWorld").setMethod("HEAD"); Response ps = r.getResponse(); System.out.println(ps.getResponseCode()); } }
这里使用了代理,用BurpSuite抓了包,来查看是否正确,果然,一些都没问题。
ps:如果你不懂的如何使用代理,请看另外一篇文章Java编写代理服务器(Burp拦截Demo)
但有一点需要注意,那就是禁止302跳转,比如我们访问:
http://www.baidu.com/xxx.html,这个"xxx.html"页面是不存在的,那么服务器为了避免404错误,会直接重定向到另外一个页面,一般都是“error”页面,如下图所示:
这个页面是不存在的,但如果不禁止302跳转,依然会返回状态码200!,如下图所示。
所以我们可以调用request. setInstanceFollowRedirects(false) 来禁止302自动跳转,如下图所示,就没问题了。
接下来,你可以做一个多线程,进行扫描了。我就不在一一的说了。无法就是IO与状态吗判断的问题了。