you're reading...
Source Code

Solving Captchas PHP script

A lot of time one comes across a captcha protection from automation. This is relatively easy to bypass now due to services being put up in 3rd world countries offering food for captchas (literally) and wages. It is a rather interesting that the void is being filled this way by exploiting this relatively large and cheap labor force. Captchas are generally solved for approximately 2 cents USD and even cheaper in bulk for some of these services. They use a relatively simple API that that pings a server, it forwards it to one of the dedicated captcha solvers, and it returns back often within 10 seconds or less depending on load. On a side note people may object to the morality of using such a service but at least these otherwise poor people can get a little cash and a bite to eat oppose to nothing and dangerous job conditions.

Of course this is not the only way it’s possible to use human captcha solvers. A while back a program that users download had a dancing striping girl and if you solved the captcha right she would take more clothes off. I think you can guess it was being used for spam and pinging a central server with captchas/answers. It is rather ingenious using horny men for free to send spam. I have to give credit to the Russians for their originality and the genius of it.

Now onto the code part of this. I linked an example below of a captcha solving class in PHP using Decaptcher’s captcha solving service. Example below of simple usage instructions.

$decaptcha = Decaptcher_recaptcha("username", "password");
$response = $decaptcha->solve("decaptcha public key");
$post_data = array( "recaptcha_callenge_field" => $response["response"], "recaptcha_response_field" => "manual_challenge");
 * Copyright 2011 SkullWare Inc.
 * http://www.skullwareinc.com
 * This code is placed in public domain.

class Decaptcher_recaptcha {
	private $proxy_host = "";
	private $proxy_type = "";
	private $cookies = "";
	private $username, $password, $pict_type, $pict_to;
	public $user_agent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)";
	public $last_solve = array( "ResultCode" => "",
				    "MajorID" => "",
				    "MinorID" => "",
				    "Type" => "",
				    "Timeout" => "",
				    "Text" => "" );
	public function set_proxy($p, $t=CURLPROXY_HTTP) {
		$this->proxy_host = $p;
		$this->proxy_type = $t;
	private function parse($s) {
		if($matches = explode("|", $s)) {
			$this->last_solve["ResultCode"] = $matches[0];
			$this->last_solve["MajorID"] = $matches[1];
			$this->last_solve["MinorID"] = $matches[2];
			$this->last_solve["Type"] = $matches[3];
			$this->last_solve["Timeout"] = $matches[4];
			$this->last_solve["Text"] = $matches[5];
		return $good;
	private function curl_get($url, $ref="", $post="") {
		$ch = curl_init();
		curl_setopt ($ch, CURLOPT_URL, $url);
		curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 30);
		curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);
		if($ref != "") {
			curl_setopt ($ch, CURLOPT_REFERER, $ref);
		curl_setopt ($ch, CURLOPT_COOKIEJAR, $this->cookies);
		curl_setopt ($ch, CURLOPT_COOKIEFILE, $this->cookies);
		curl_setopt ($ch, CURLOPT_USERAGENT, $this->user_agent);
		if($post != "") {
			curl_setopt ($ch, CURLOPT_POST, true);
			curl_setopt ($ch, CURLOPT_POSTFIELDS, $post);
		if($this->proxy_host != "") {
			curl_setopt ($ch, CURLOPT_PROXYTYPE, $this->proxy_type);
			curl_setopt ($ch, CURLOPT_PROXY, $this->proxy_host);
		$page = curl_exec($ch);
		return $page;
	private function get_between($string, $start, $end) {
                $string = " ".$string;
                $ini = strpos($string,$start);
                if ($ini == 0) return "";
                $ini += strlen($start);
                $len = strpos($string,$end,$ini) - $ini;
                return substr($string,$ini,$len);
	private function recaptcha_fetch_image($key) {
		$p = $this->curl_get("http://www.google.com/recaptcha/api/noscript?k=".$key);
		$image = $this->get_between($p, '<img width="300" height="57" alt="" src="', '"');
		$image = "http://www.google.com/recaptcha/api/".$image;
		$challenge = $this->get_between($p, 'id="recaptcha_challenge_field" value="', '"');
		$ret = array('image' => $image,
			'challenge' => $challenge);
		return $ret;
	public function __construct($username, $password, $pict_type=0, $pict_to=0) {
		$this->username = $username;
		$this->password = $password;
		$this->pict_type = $pict_type;
		$this->pict_to = $pict_to;
	public function solve($key) {
		$i = $this->recaptcha_fetch_image($key);
		$image = $this->curl_get($i["image"]);
		$temp = tempnam("/tmp/", "cap-");
		file_put_contents($temp, $image);
		$post_fields = array( "function" => "picture2",
				      "username" => $this->username,
				      "password" => $this->password,
				      "pict_to" => $this->pict_to,
				      "pict_type" => $this->pict_type,
				      "pict" => "@".$temp );
		$this->parse($this->curl_get("http://poster.decaptcher.com/", "", $post_fields));
		$p = $this->curl_get("http://www.google.com/recaptcha/api/noscript?k=$key", "", array("recaptcha_challenge_field" => $i["challenge"], "recaptcha_response_field" => $this->last_solve["Text"]));
		$ret = array( "Text" => $this->last_solve["Text"],
			      "challenge" => $i["challenge"],
			      "response" => $this->get_between($p, '<textarea rows="5" cols="100">', '</textarea>'));
		return $ret;
	public function __destruct() {


About Pythorian

Exploration and Production oriented security consultant for securing IT infrastructures relating to natural resources.


No comments yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: