`
xiaobian
  • 浏览: 581135 次
  • 来自: 北京
社区版块
存档分类
最新评论

使用Java HttpClient 库自动注册Tom在线邮箱

    博客分类:
  • Java
阅读更多

用到的工具和技术,排名不分先后:

1.HttpClient  Apache项目组开发的在Java中模拟浏览器行为的代码库。

2.Live Http Headers 插件 此插架是FireFox下查看Http协议头的数据。

 

备注: 使用WireShark也可以拦截Http协议的数据,具体使用方法和下载地址请自行搜索下载。

 

为防止程序的自动注册,现在不管是注册还是留言一般都需要使用验证码。 而我们要完成自动注册就需要分析验证码的生成和解析验证码这两个步骤。 解析验证码这个步骤很复杂,这个程序也没有实现这个功能,需要用户根据弹出的页面自己输入验证码。

 

开始分析:

 

Tom在线,注册页面:http://bjcgi.tom.com/cgi-bin/tom_reg.cgi。 通过对此页面源代码的查看可以发现验证码生成的地址。

<td>
<script src="http://login.tom.com/captcha/drawme.php?type=6"> </script>
<script> var d =new Date();d.setTime(d.getTime()+60*60*1000);document.cookie='post_key=dcf5e3a556853ef44529e00a09c7284c;expires='+d.toGMTString()+';domain='+_gg_dm();document.write("<img title='看不清?点击更换验证码!' alt='看不清?点击更换验证码!' id='v_i_0980t' onclick=\"rewriteimg();\" src=http://login.tom.com/captcha/draw.php?post_key=dcf5e3a556853ef44529e00a09c7284c&type=6>"); </script>
  <img title="看不清?点击更换验证码!" alt="看不清?点击更换验证码!" id="v_i_0980t" onclick="rewriteimg();" src="http://login.tom.com/captcha/draw.php?post_key=dcf5e3a556853ef44529e00a09c7284c&amp;type=6"> &nbsp;&nbsp;
<a href="javascript:rewriteimg();" style="color: rgb(255, 0, 0); font-weight: bold;"> 看不清楚,换一张图片 </a>
</td>

这个地址既是Tom在线生成验证码的页面【如果你现在浏览可以看不到验证码】,其右两个参数: post_key  和 type 。其中Type应该是指生成验证码。而post_key是一个32位的Hash值。具体是如何Hash的不清楚,因为是写在draw.php文件中的。 post_key 是验证码之外的另一层验证系统,如果你想获得正确的验证码必须要有一个post_key分析网易,Google的注册行为也是同样的原理。

 

那么既然post_key是在draw.php页面中,那有如何找到这个key呢。答案在

http://login.tom.com/captcha/drawme.php?type=6

打开上面的连接【function rewriteimg() { var a=document.createElement('script'); document.body.appendChild(a); a.src='http://login.tom.com/captcha/reset.php?type=6'+'&'+Math.random(); } function _gg_dm() { var a = document.domain.split('.'); if(a.length>=2) { return a[a.length-2]+'.'+a[a.length-1]; } else { return document.domain; } } document.write(" <script>var d =new Date();d.setTime(d.getTime()+60*60*1000);document.cookie='post_key=f377fd6144b1aab847f416aa77741055;expires='+d.toGMTString()+';domain='+_gg_dm();document.write(\&quot;&lt;img title='¿´²»Çå?µã»÷¸ü»»ÑéÖ¤Âë!' alt='¿´²»Ç壿µã»÷¸ü»»ÑéÖ¤Âë!' id='v_i_0980t' onclick=\\\&quot;rewriteimg();\\\&quot; src=http://login.tom.com/captcha/draw.php?post_key=f377fd6144b1aab847f416aa77741055&amp;type=6&gt;\&quot;);</script> ");】

 

在上面的代码中有这个链接

http://login.tom.com/captcha/reset.php?type=6

 

打开上面的连接【var d =new Date();d.setTime(d.getTime()+60*60*1000);document.cookie='post_key=25630b8e96724532038103efb761b57e;expires='+d.toGMTString()+';domain='+_gg_dm(); document.getElementById("v_i_0980t").src='http://login.tom.com/captcha/draw.php?post_key=25630b8e96724532038103efb761b57e&type=6';】

 

在上面的内容中看到 【post_key=25630b8e96724532038103efb761b57e;】这一句了吧,对了这个就是我们要找的key。 只要我们分析这个页面【http://login.tom.com/captcha/reset.php?type=6】就可以找到这个key。

 

然后就可以通过下边这个链接来生成验证码,供用户输入。因为post_key与时间有关所以如果超过一定时间下边的连接就生成不了验证码。 就像这样。

http://login.tom.com/captcha/draw.php?post_key=dcf5e3a556853ef44529e00a09c7284c&type=6

 

至此Tom在线的验证码生成系统分析就完成了。

 

网易的邮箱系统与Google的邮箱系统与此都类似:

// 网易获取验证码的地址:
    // http://reg.163.com/services/getid 获取ID的
    // http://divs.reg.163.com/services/crtimg?id=4c3fd8fdc6c2eea1126077566f91876c95fdbc35 根据上边的ID生成验证码的。

 

 

 

 

HttpClient的使用方式请参照附件中的HttpClient的说明文档。

 

至于程序里边用到的HTTP Header 信息。请使用Live Http Header 插件在进行模拟注册的时候进行拦截,并记录。

 

完整的代码;

 

package com.cache.http;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Random;
import java.util.Scanner;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;

/**
 * 
 * #xiaobian.iteye.com
 * 
 * @author phoenix_bian
 */
public class TomMail {
	public static void main(String[] args) throws IOException {
		HttpClient client = new HttpClient();
		client.getHostConfiguration().setHost("bjcgi.tom.com", 80, "http");
		client.getHostConfiguration().setProxy("63.208.180.6", 3128);
		int i = 0;
		while (i < 100) {
			i++;
			String userName = createUserName();
			HttpMethod method = getPostMethod(userName); // 使用 POST 方式提交数据
			// HttpMethod method = getGetMethod(); // 使用 Get 方式提交数据
			client.executeMethod(method); // 打印服务器返回的状态
			String response = new String(method.getResponseBodyAsString()
					.getBytes("ISO-8859-1"));
			// 打印返回的信息
			// System.out.println(response);
			if (response.indexOf("" + userName + ",恭喜您成功注册TOM免费邮箱!") != -1) {
				System.out.println(userName + " 注册成功");
				appendToFile("c:\\user.txt", userName + " " + "12345678\n");
			}
			method.releaseConnection();
			try {
				Thread.sleep(1000 * 60);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 使用 POST 方式提交数据
	 * 
	 * @return
	 * @throws IOException
	 * @throws HttpException
	 */
	private static HttpMethod getPostMethod(String userName)
			throws HttpException, IOException {
		// 要POST的URL
		PostMethod post = new PostMethod("/cgi-bin/tom_reg.cgi");
		// 要POST的参数
		NameValuePair[] values = new NameValuePair[15];
		values[0] = new NameValuePair("funcid", "reguser");
		values[1] = new NameValuePair("refer", "http://mail.tom.com/");
		values[2] = new NameValuePair("year", "1980");
		values[3] = new NameValuePair("month", "1");
		values[4] = new NameValuePair("day", "1");
		values[5] = new NameValuePair("argee", "1");
		values[6] = new NameValuePair("idnum", "4401");

		values[7] = new NameValuePair("uid", userName);
		values[8] = new NameValuePair("password", "12345678");
		values[9] = new NameValuePair("confirm_password", "12345678");
		values[10] = new NameValuePair("safemail", "abc@gmail.com");
		values[11] = new NameValuePair("question", "My Mom's birthday");
		values[12] = new NameValuePair("answer", "1951-11-11");
		values[13] = new NameValuePair("argee_c", "on");
		String post_key = getPostKey();
		String address = "http://login.tom.com/captcha/draw.php?post_key="
				+ post_key + "&type=6";
		open(address);
		Scanner scanner = new Scanner(System.in);
		System.out.print("请您输入验证码:");
		String verifyCode = scanner.next();

		values[14] = new NameValuePair("authcode", verifyCode);

		post.setRequestBody(values);

		post.setRequestHeader("Host", "bjcgi.tom.com");
		post
				.setRequestHeader("User-Agent",
						"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; CIBA)");
		post
				.setRequestHeader(
						"Accept",
						"image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash");
		post.setRequestHeader("Accept-Language", "zh-cn");
		post.setRequestHeader("Accept-Encoding", "gzip,deflate");
		post.setRequestHeader("Referer",
				"http://bjcgi.tom.com/cgi-bin/tom_reg.cgi");

		post.setRequestHeader("Cookie", "post_key=" + post_key + "");

		post.setRequestHeader("Content-Type",
				"application/x-www-form-urlencoded");
		// 注册成功 <div
		// class="RegSuc_Info"><span>bianbian0202,恭喜您成功注册TOM免费邮箱!</span></div>
		return post;
	}

	private static String createUserName() {
		return "phoenix_" + String.valueOf(new Random().nextInt());
	}

	public static final String randomString(int length) {
		Random randGen = null;
		char[] numbersAndLetters = null;
		Object initLock = new Object();
		if (length < 1) {
			return null;
		}
		if (randGen == null) {
			synchronized (initLock) {
				if (randGen == null) {
					randGen = new Random();
					numbersAndLetters = ("0123456789abcdefghijklmnopqrstuvwxyz")
							.toCharArray();
				}
			}
		}
		char[] randBuffer = new char[length];
		for (int i = 0; i < randBuffer.length; i++) {
			randBuffer[i] = numbersAndLetters[randGen.nextInt(20)];
			// randBuffer[i] = numbersAndLetters[randGen.nextInt(35)];
		}
		return new String(randBuffer);
	}

	private static void open(String address) {
		Runtime rt = Runtime.getRuntime();
		try {
			rt.exec("C:\\Program Files\\Internet Explorer\\iexplore.exe   "
					+ address);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			rt.gc();// 强制回收
		}

	}

	// 获取Tom网的Post_Key
	private static String getPostKey() throws HttpException, IOException {
		HttpClient client = new HttpClient();
		// 设置代理服务器地址和端口
		// client.getHostConfiguration().setProxy("63.208.180.6", 3128);

		// 使用 GET 方法 ,如果服务器需要通过 HTTPS 连接,那只需要将下面 URL 中的 http 换成 https
		HttpMethod method = new GetMethod(
				"http://login.tom.com/captcha/reset.php?type=6");
		// 使用POST方法
		// HttpMethod method = new PostMethod("http://www.7y8.com/V/ip.asp");
		client.executeMethod(method);
		// 打印服务器返回的状态
		System.out.println(method.getStatusLine());
		// 打印返回的信息
		String result = method.getResponseBodyAsString();
		// 释放连接
		method.releaseConnection();
		int beginIndex = result.indexOf("post_key=") + "post_key=".length();
		int endIndex = result.indexOf(";expires");

		String post_key = result.substring(beginIndex, endIndex);
		return post_key;
	}

	/**
	 * 
	 * 
	 * @param fileName
	 * @param content
	 */
	public static void appendToFile(String fileName, String content) {
		try {
			File f = new File(fileName);
			if (!f.exists()) {
				if (!new File(f.getParentFile().toString()).exists())
					new File(f.getParentFile().toString()).mkdirs();
				f.createNewFile();
			}
			FileWriter writer = new FileWriter(fileName, true);
			writer.write(content);
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}
 

 

 

 

 

 

 

分享到:
评论
1 楼 zlb824 2011-10-12  
您好,首先非常感谢您的分享,对您的这段代码我也运行了一下,结果令人兴奋不已。但是还是有几个问题我不是很懂:
①client.getHostConfiguration().setHost("bjcgi.tom.com", 80, "http");中所设置的地址我可以如下设置:
PostMethod post = new PostMethod("http://bjcgi.tom.com/cgi-bin/tom_reg.cgi"); 我想问下它们到底有什么区别?一般情况下下用哪一种比较好些。
②“post.setRequestHeader”的目的是干嘛?是不是一定要对其进行设置,为什么有些我不设置它也能进行访问呢?
③我们知道点击“注册”之后都会进入一个访问后台的地址,为什么我们在不知道这个地址的情况下也能注册成功?

不好意思,由于本人是个初学者,还望您能替我解答这几个疑问,本人在此非常感谢!

相关推荐

Global site tag (gtag.js) - Google Analytics