在渗透测试过程中,扫描敏感目录文件是一件非常重要的事情,那么接下来,我们就用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与状态吗判断的问题了。