We’re all familiar with CAPTCHA right? That impenetrable fortress of crazy squiggly characters that only a real human can decipher. Whilst they tend to drive us a bit nuts, they do actually provide a valuable function in that they prevent the automation of requests against online services. For example, you can’t get yourself a Google account without first wrapping your head around what on earth this one says:

Why does Google do this? Well, once you create yourself a Google account you’ve now got GMail and G+ and all sorts of other platforms which could be used to perform such nefarious activities as generating spam, distributing malware or creating false identities. Once you can automate this, these activities can be performed en masse.
It’s a similar deal with Western Union:

It’s easy to imagine that being able to automatically create accounts at a financial institution might open the gateway to all sorts of monetary shenanigans. And if you’ve already been able to create a GMail account, you’ve got everything you need to begin batching the creation of identities at Western Union.
So CAPTCHA prevents all this, right? Only humans can break the code and complete these signup processes, right? But what if we could automate the humans; I mean what if we could take CAPTCHAs and solve them at such a rate that these registration processes could be easily automated? Well it turns out you can and it will only cost you a couple of bucks.
Commoditised CAPTCHA solving with Antigate
The inspiration for this post goes back to a piece I read recently from renowned security writer Brian Krebs about Virtual Sweatshops Defeating Bot-or-Not Tests. In the article, Brian talks about how CAPTCHA solving is being outsourced by spammers to services in low cost markets which use real people to churn through large numbers of the obfuscated text for a fraction of a cent each time; we’re talking up to $1 for 1,000 CAPTCHAs. That’s right, one tenth of one cent to solve a CAPTCHA. The service is consumable via an API which conceivably means the spammers’ automated scripts can simply pass the CAPTCHA off and get a speedy response containing the actual text which can then be used in their spamming efforts.
The article talks about KolotiBablo.com which caters to those wishing to join the team of elite CAPTCHA crackers. They’re an impressive looking team too:

Personally, if I was a spammer, I’d be comforted by the knowledge that my CAPTCHA crackers were adorned in jacket and tie and overseen by an attractive supervisor in a pants suit. But I digress.
I thought it would be interesting to actually take up this service and see just how efficient outsourced CAPTCHA cracking can be. Whilst KolotiBablo.com might be the coalface for would be CAPTCHA crackers, if we want to consume the cracking service we need to sign up with Antigate over at antigate.com (they both run off the same subnet):

Antigate offers a very attractive pricing structure with payment posible in a number of different popular formats. However, it’s important to note that the service cannot be used for spam operations lest it generate “butthurt”. I wasn’t entirely sure what this meant, but after Googling it I decided I was probably best not to participate in the butthurting and it would be safer just to build my own little test app instead.
Registration is pretty much like registering for any old service:

In fact it’s so much like many common registration services that there’s no SSL. And it doesn’t like strong passwords. And it sends me back my nice 1Password generated crazy string of characters:

Password toned down a bit, everything seems to be ok, I think:

Once logged in, everything looks pretty straight forward with nice quick start options. What I really wanted to do was write my own code which is fortunately one of the options:

Wow, they’ve even got a marketplace! Maybe another time, for now I just want to start solving CAPTCHAs. Looking at the API, the process basically goes like this:
- Send the CAPTCHA and API key via an HTTP POST request
- A response is returned with an ID
- Wait 10 seconds then send the ID back in another request
- A response with either the resolved text or a “not ready” status is sent back
- If it’s not ready, wait 5 seconds then ask for the status again (rinse, lather, repeat)
It seems like a very good use case for long polling. Never mind, the API is straight forward, the interesting bit will be the success rate achieved.
Before we move onto the crux of this post – actually “breaking” CAPTCHA – there’s one more useful service provided by Antigate and that’s the ability to get a quick health check on the status of the operators. Actually, you can load this yourself without authenticating and you should see something similar to this:

It makes a whole lot more sense when you see the underlying XML in the source:
<RESPONSE> <waiting>50</waiting> <load>86.53</load> <minbid>0.001</minbid> <averageRecognitionTime>16.175225206526</averageRecognitionTime> </RESPONSE>
This makes it very convenient to work out when to load up the service with requests to solve CAPTCHAs. More on that later.
Building a CAPTCHA enabled site to break
Of course none of this is going to be very interesting if we don’t have a CAPTCHA enabled site to start breaking. To avoid the butthurting, I created an ASP.NET MCV 3 website and grabbed the Web Helpers Library from Microsoft. The web helpers make it very simple to drop a CAPTCHA into any page and then validate it on submission.
Actually, it’s a reCAPTCHA implementation and the distinction is important; acquired by Google a few years back, reCAPTCHA is designed to assist in the digitisation of text books so this exercise is going to make the world a slightly better place by hopefully making more information available to more people. Plus there’s the fact that Google serves about 200 million of them every day so it’s a good high-profile implementation and reflective of what Antigate’s service is probably being used to solve already.
Moving on, I built a typical registration form as follows:

What’s really important here is how the CAPTCHA renders to HTML; we need to understand this in order to actually download the image from Google, send it to Antigate then submit the correct form values with the registration. Keep in mind that everything we’re about to look at is easily available in the HTML source of any site implementing CAPTCHA.
Taking the registration form from above, the CAPTCHA is embedded via the following markup:
<script type="text/javascript"> var RecaptchaOptions = { "theme": "Red", "lang": "en", "tabindex": 0 }; </script> <script src="http://www.google.com/recaptcha/api/challenge?
k=6Le2hMwSAAAAAPhhj00SFHjaniz3zLnV0nDLThq9"
type="text/javascript"></script> <noscript> <iframe frameborder="0" height="300px"
src="http://www.google.com/recaptcha/api/noscript?
k=6Le2hMwSAAAAAPhhj00SFHjaniz3zLnV0nDLThq9" width="500px"></iframe> <br /> <br /> <textarea cols="40" name="recaptcha_challenge_field" rows="3"></textarea> <input name="recaptcha_response_field" type="hidden"
value="manual_challenge" /> </noscript>
The simplest way to look at this is to focus on the content in the <noscript> tag which is what’s going to be parsed if the browser doesn’t support JavaScript (or has it turned off). This saves us from dealing with all the logic in the external script files which is otherwise used to embed the CAPTCHA image in most browsers.
The important bit is the iframe source which is where the image will be embedded. In this case, you can see the path is http://www.google.com/recaptcha/api/noscript?k=6Le2hMwSAAAAAPhhj00SFHjaniz3zLnV0nDLThq9
This page will render a very basic CAPTCHA implementation – remember that this is the one intended for folks without JavaScript:

The CAPTCHA image is different from the earlier one in the form as we’ve loaded the iframe twice which has caused it to refresh; once when we loaded the registration page it then again when I loaded the iframe separately for the screen grab above. When I automate this in the next section it will only be loaded once.
Inspecting the source of the iframe page, we can easily find the CAPTCHA image embedded in the markup:
<img width="300" height="57" alt="" src="image?
c=03AHJ_VusH0z9XlyEjm8c2Qm6sl9DhDD_fWq7R-tpRlwhF0KeLy2m8nZBM-
T7AOpGn6UCLd0M7fITJZ2RJ0pgHVt2PrchJwp3VoaKwcJMAK7_BhQdxIPidUT5-
nAUIF7GRDD3vrjs2CXLfw7byQMJa9gDNy9CSvhiSuw">
And of course we can then extract the actual URL of the image itself. This is the whole point of the exercise as this is the guy we need to send off to Antigate:
The last thing we need to know is how to construct the form submission to the target site. Obviously this will include values such as the name and address along with the solved CAPTCHA, but there’s a little bit more to it than that. Let’s take a look at what gets submitted by watching the HTTP request with Fiddler:

What we see here is a bunch of form fields into which I’ve just entered “aaa” then two CAPTCHA related fields: a challenge and a response. The challenge is simply the query string parameter from the CAPTCHA image above and the response is obviously the solved CAPTCHA. We now know everything we need to build the CAPTCHA cracker.
Building the CAPTCHA cracker
Antigate try to be helpful here and provide a little C# sample to get you started. I ended up rewriting it myself for both brevity and to ensure I understood exactly what was going on. Plus, of course, it actually needs to automate the form submission in our CAPTCHA enabled app which is naturally a bespoke requirement.
I ended up with a console app which does this:

In short:
- Request the registration page from the target site
- Request the iframe source used to embed the CAPTCHA image
- Request the CAPTCHA image used in the site and save it locally
- Send the CAPTCHA to the Antigate service
- Antigate assigns the CAPTCHA to a human operator who then solves it and sends it back to them
- Wait 10 seconds, then check back with Antigate for the CAPTCHA text (repeat every 5 seconds until solved)
- Send a registration to the target site with the fields filled out (I’ve just defined a static set of sample data) plus the CAPTCHA challenge and solved text
After all this is complete, I’ve also added some logging because I want to track things like throughput and success rate plus the duration of each stage of the process. The success of the process is determined by the response from the form submission; obviously if you get the CAPTCHA right you’re going to receive a very different response body to if you get it wrong.
That’s it – it’s really that simple. But this isn’t a free service so we’ll need some credit before proceeding.
Topping up the Antigate account
The last thing we need to do before the serious CAPTCHA cracking begins is to put some money into the Antigate account. They make things rather easy by delegating the financial bits off to Avangate who sell refill codes for various values:

Avangate is a pretty renowned e-retailer of software products which usually means you’re purchasing license numbers. Over on their site, the (currently) strong Aussie dollar means we’re looking at 96 cents to break 1,000 CAPTCHAS. Nice:

Payment is via PayPal and I went through the usual steps to authorise it after which I was sent back to Avangate:

A short while later and the code is conveniently delivered via email:

And… we’re up and running:

Right, now the really interesting bit begins.
Breaking CAPTCHA
Let’s run it up! I’ve added quite a bit of output verbosity which was very useful during the build process:

Here we can see the iframe source path followed by the CAPTCHA image path and then the query string extracted from it (remember, this is the challenge we need to submit with the form). The image is then saved locally, submitted to Antigate and a response with the ID returned which in this case is 42244161. You can see the process then sleeping for 10 seconds followed by a total of three more requests, each five seconds apart, until a response is returned with the text “mungo odatesp”. This is the first “Wow!” moment; a human somewhere has actually solved this and sent it back to me!
But of course the real proof of success is once the form is submitted. The second last line of text shows this has returned “Ok” so the form has actually returned a response body consistent with a successful registration. Lastly, the entire process took just over 27 seconds and the CAPTCHA cracker also logged the process successfully:
![]()
In this case here, because I also control the website we submitted the registration to I can do a sanity check and make sure the registration was actually submitted:
![]()
Yep, looks right! This has all the sample data I configured the CAPTCHA cracker to post and the CreateDate on the record falls just after the CaptchaCompleteDate in the log. So there you have it – successful programmatic CAPTCHA circumvention using an automated human. Problem is, 27 seconds is not exactly blistering. But there’s a better way to eke out performance and it’s something programmers have known about for a long time: multithreading.
Employing the multithreaded humans pattern
What if we start multithreading the humans? I mean rather than just running up a single instance of the CAPTCHA cracker, how about, say, 30 simultaneous instances? Of course the success of this model depends on having 30 operators who are able to simultaneously work on what is in essence, a sequential process (one operator can only solve one CAPTCHA at a time). But as we saw earlier on, it’s not uncommon to have 50 operators on hand.
So I implemented a “poor man’s multithreading” and fired up 30 separate instances of the CAPTCHA cracker console:

I let this run for 20 minutes then analysed the results which as we’d expect, show a much higher throughput:

A total of 1,230 CAPTCHAs were sent off to Antigate and only 77 were not solved correctly hence causing the registration process to fail. That’s a 94% success rate:

But even though multithreaded, the process of solving the CAPTCHAs was still a huge bottleneck in automating registrations:

In fact the numbers broke down to 420ms from start to where the CAPTCHA image was ready for sending off then 26 seconds to actually get a response back with the solved CAPTCHA followed by 199ms to submit it to the registration form along with the other fields. Clearly CAPTCHA still puts a significant dent in the overall duration of the process; that’s nearly 98% of the total submission process it’s chewing up there.
But of course you can run almost limitless threads (depending on the available humans) and the bottom line is that I was able to break through the CAPTCHA process and automate registrations at a rate of one per every 0.98 seconds and with a 94% success rate. This has well and truly demonstrated that the intent of CAPTCHA can indeed be defeated by simply automating the humans.
Summary
I must admit, I do feel a bit sorry for the folks sitting there endlessly solving a never ending stream of CAPTCHAs; frankly, just one drives me a bit nuts! But what must have been even worse – and I need to take some blame here – is that while testing I kept submitting the same CAPTCHA over and over and over again. I can picture the poor operator sitting there thinking “WTF is this guy doing already?!” Then again, maybe they made some quick bucks because recognising the same pattern time and again becomes more efficient.
When I first got the script running, I just couldn’t help but fire it up over and over again. Frankly, I found it a bit mindboggling to think that each time I ran it, that painfully obtuse little CAPTCHA was flying around the world and being solved by someone for whom $0.001 was a worthwhile effort and the result efficiently delivered back to me within a matter of seconds. There’s something beautiful about the efficiency with which that happens.
Of course the other question all this raises is the legality of a service such as Antigate. On the one hand, they’re just converting random bitmaps to text which in and of itself, is probably no big deal. But it may also be no big deal in the same way that Napster and Megaupload made it possible to share files; it could well come down to the implied (or assumed) intent of the service. At the end of the day, antigate.com resolves to an IP in Florida so assumedly if they were coming foul enough of the law, action such as we saw with Megaupload last week would not be too difficult, I mean it’s not like they’re secreted away in deepest darkest Eastern Europe or anything.
The other thing worth noting is that Antigate aren't the only guys out there providing this service; Death By CAPTCHA offers a very similar service as do Bypass CAPTCHA and Beat CAPTCHAs; this isn’t exactly ground breaking territory. Then availability of all these services could make it very easy to stand up a “clustered humans” model whereby the process I went through above is repeated simultaneously across multiple services hence dramatically increasing the throughput.
Now of course none of this is actually breaking the CAPTCHA implementation; the sanctity of the squiggly words has been retained and indeed it has taken real live humans to resolve them into plain text. But what this exercise does show is that the assertion that CAPTCHA prevents automation is just plain wrong, all it takes is for part of the automation to be moved from computers to humans. Consider this against Wikipedia’s definition and it would be fair to say that this exercise has undermined the very security premise on which CAPTACH is built:
The basis of the CAPTCHA system is to prevent automated access to a system by computer programs or "bots"
It’s an odd position to wrap the post up on; I mean we’re so accustomed to putting our emotionless, highly efficient PCs to work to save us humans from labour intensive exercises. But what this post shows us is that sometimes we need to invert the process and instead automate the humans to the extent where they can perform at high levels of efficiency. It just takes some clever orchestration and enough humans that are willing to do the work cheaply enough to make the exercise financially viable.






Software architect and Microsoft MVP, you’ll usually find me writing about security concepts and process improvement in software delivery.





38 comments:
Nice post!
One thing that occurred to me while reading it... Those numbers you blurred for your order number and "activation key"? They immediately made me think of these:
http://dheera.net/projects/blur.php
http://tlrobinson.net/blog/2008/10/08/recovering-censored-text-using-adobe-photoshop-cs3/
I don't suppose those number are confidential enough for it to matter, but still...
That's right - they're not confidential enough to matter too much, I've already cashed them in. You'll have to go and find $1 somewhere instead :)
Another excellent article Troy.
I always wondered about the usefulness of these systems as well, it seems that if you are determined enough then you can easily get around CAPTCHA as things stand now.Perhaps what is needed is a system that asks questions that require a more human understanding of the content of the page you are currently on that cannot be simply sent to a human data input factory without lots of complications. Something like what is the colour of the title text or how many paragraphs are there on this page. Of course the CAPTCHA API would need to be more complex requiring submission of these values in the first place, they could even combine the values submitted with a value coming back from the CAPTCHA e.g. what is the sum of the number in this image plus the number of paragraphs on this page.This could of course be incredibly frustrating to genuine users so it would have to be done cleverly however clearly something must be done to combat these type of operations.
Incidentally I had noticed that you had been getting SPAM as comments on some of these posts and was going to suggest you add a CAPTCHA!! Maybe I will reconsider now!
Great article - I'm trying to think how I would detect and block this kind of operation. Apart from detecting the IP requesting the captcha I'm drawing a blank!
I wonder if we will end up in a position where e-mail providers give "credit ratings" for accounts! (I.e. how long has it been open, does the user send a lot of spam, does the user receive e-mail on this). You could then ask the provider for the rating when they register an account.
fun times ahead!
Ess
A few things crossed my mind when reading this post:
-
Do they in any way detail how they identify spammers? If not, I'm so reporting them to paypal.
Interesting post (and service). However I would like to point out another explanation of who's doing the work. (This suggestion I read long ago somewhere on the web.) The service could trick humans in solving the captcha's for you.
They set up a site that attracts people willing to register or solve a captcha to access (say: pr0n). The people visiting then are presented your captcha's to solve, instead of genuine ones. So there are no operational expenses, other than setting up an attractive website..
I read on some black hat forum that these "captcha solving providers" use OCR libraries to automate or double check captchas solved by humans. There are also captcha solving DLLs (libraries) that you can integrate in your spamming tool, but success rate with this setup is around 50%.
This service has a higher success rate than I do in getting past captchas.
I agree on the double-checking; if I were to run it, I'd display the same image to X people, and require some percentage of those (Y) to give the same response before marking it as a "success" - and probably putting a ding on the record of those (X-Y) folks who failed to solve it correctly.
Presumably, if a solver's success percentage drops below a certain point, they're fired, or perhaps they're only paid for submissions that agree with others.
Hi Carl, the problem will always remain that whilst deliberately increasing the barrier to entry you're also causing a lot of UX pain! The likes of Google and Western Union need to find a happy balance somewhere and for now, that appears to be CAPTCHA. I guess if they see enough exploitation of the service then things might change.
I use Disqus for my comments and I actually find their spam filtering is very good. I probably get one message a week which I need to delete and a couple of of false positives which get caught and need to be flagged as genuine. I'm happy with that balance in so far as I want to encourage comments and the small amount of spam that currently gets through is easy to deal with.
This is a great writeup. There are actually really solid tools out there that can break most CAPTCHAs automatically with OCR.
XRumer breaks over 5000 different types of them. Including ReCAPTCHA.
Blocking by IP address is a bit flakey. Firstly, you can have many legitimate users on the same publicly facing address (i.e. corporate networks). Secondly, spammers often use botnets of compromised PCs which are spread out all over the place with their own legitimate IPs.
Other mitigations could include looking at submission patterns such as form data and request headers (both things that should vary) or randomising form fields names per session. I'm sure there are other options too, I think it's really a matter of how attractive your service is to exploitation and what effort it's worth in protecting it from automation.
- The imagery of people in suits is obviously nothing more than a stock photo. Take my comments as a humorous observation :)
- The crackers absolutely, positively work from home and have CAPTCHAs automatically assigned to them.
- That 27 seconds includes sending the CAPTCHA to Antigate, them assigning it to an operator, the operator picking it up from their queue, solving it, sending the text back to Antigate then finally, my script pikcing it up from Antigate on one of the 5 second interval polls. I suspect the time to actually solve the CAPTCHA is closer to 5 seconds.
- I suspect the rate of solving CAPTCHAs is closer to 3,000 over 8 hours (9.6 seconds each), but yes, this could be a decent earn for some people in certain locations around the world. Certainly they could exceed minimum wage in a number of locations.
They don't say and I doubt there is (or could be) any automation around that. There's also the argument that it probably wouldn't be in their best financial interest to do so...
There have been lots of algorithmic solutions, but the success rates suck compared to human solvers:
17.5% - http://www.allspammedup.com/2011/01/google-recaptcha-cracked/
30% - http://www.teleread.com/chris-meadows/recaptcha-now-vulnerable-to-computer-cracking/
But of course you could achieve a much greater throughput not relying on humans. Then again, the high failure rate may raise other flags in the target system. But with all these (including humans), CAPTCHAs remain pervasive so obviously they're still of some use.
You've done a great job of breaking down the process. I have heard from SEO/SEM indies that a lot of these CAPTCHAs are placed on high volume web sites like free porn web sites and the people have to figure out the CAPTCHA for the free content.
Admittedly a great career move, but as we all know: stay away from the dark side! ;-)
What you could do is .. use their own service to automate new registrations at http://kolotibablo.com/bablo.php .. Yes, they require you to work out a captcha!
See also: http://en.wikipedia.org/wiki/CAPTCHA#Human_solvers
It mentions the 'employ uninformed nobodies' to do the job for free idea (and other ideas) as well.
Captchas are the worst thing that happened to the Internet. Many times it's impossible to read the captcha, and you need to refresh several times just so you can see an image that you (a human) can read.
I wonder if it's a good job getting $1 for a 1000 captchas - if each captcha takes 3 seconds to break (which is a very optimistic estimate - some can take 10 seconds), that's like $1/hour.
Isn't it the point of the Captcha that it can be shown to one recipient only?
This is software I mentioned in parent comment:
http://www.captchasniper.com/
Looks like they don't currently support ReCAPTCHA (it's "under development"):
http://www.blackhatworld.com/blackhat-seo/buy-sell-trade/363104-captcha-sniper-your-auto-captcha-solving-software-4.html
Yes, if loading it normally via a web page, but of course if you save the CAPTCHA image offline you can send it around to many different people.
In some countries, yes, earning $1/h is a good (average) job:
http://en.wikipedia.org/wiki/List_of_countries_by_GDP_(PPP)_per_capita
If the company has large number of employees working for them, they can build on the accuracy and gradually increase efficiency by applying automation.
Simple approach would be to store hash of the CAPTCHA and solution in the database which is already solved.
If the incoming request file's hash matches with stored inputs then return the stored value if not pass it to a human.
I really like how, upon trying to share this page on Facebook, I was presented the Facebook captcha :)
I find if ironic that 'pro' captcha solvers are getting paid to break recaptcha, which is essentially Google using innocent users to recognize texts for Google Books, for free and by force (e.g. you can't register to sites without helping Google).
So apart from the poor lads solving stupid captchas all day, I'd say Justice is served ;-)
Oh and btw, they should consider targeting consumers directly; I believe lots of people are willing to pay $1 for not having to solve another CAPTCHA ever, especially on mobile.
Soon on the Android Market and Cydia? ;-)
I sometimes wonder whether I'm unwittingly participating in such a system when solving a captcha on a site that doesn't seem to need one.
I suppose it's easier, though, to hire workers than to build a service compelling enough to act as a front. But it's fun to imagine there's only one bank actually using ReCAPTCHA, and everything else is just republishing them in order to hack it.
Excellent post
Why doesn't recaptcha invalidate the image url after 1 request? Or serve a different image? Your program would have to be a little more advanced and actually pass over the image bytes for recognition. It'll increase the load on both ends 10 fold.
The image is only requested once - I downloaded it locally then sent it over to Antigate.
Troy, there was an even cheaper way (once you have set it up) years ago. Put up a site with pictures people want to see (people with very little clothing on OR something) and put a Captcha to keep going every 7th image or so. I'm guessing your paying someone who has setup a site like this.
Interesting you say that, a number of people have said the same thing in the comments. Frankly, I'm doubtful on a number of fronts, not least of which is the sheer volume of users that would be required to make that model realistic. Plus, I don't know about you, but there's no way I could achieve a 94% success rate on reCAPTCHA no matter how badly I wanted to look at the content behind it. I'm inclined to take KolotiBablo proposition at face value; a high conglomerate of high-powered CAPTCHA crackers is behind it (probably not wearing ties or pants suits though).
Just for your information, Russian speakers would recognize the name they are using for the site KolotiBablo.com as "MakeMoney.com".
On the success rate, if they follow the "wait until two people say the same thing" model suggested above, then the success rate for an individual would be relatively unimportant.
Post a Comment