[Source] Decaptcher - idb. - Jun 8, 2011
I see a lot of people on HF needing ways to defeat captcha. In my personal experience Decaptcher beats the shit out of every other method (OCR's included) as far as success rate goes. The only down side is that you have to pay for the service (although the fee is so minute that unless you live on the streets you should have no trouble coughing up the dough).
That being said, I have written a Decaptcher wrapper (which uses my HttpWebRequest wrapper) and I figured I would share it with you guys. Since you'll need my HttpWebRequest wrapper as well, I'll post that too.
First the WR wrapper...
Code Imports System.IO
Imports System.Net
Imports System.Text
Namespace Utility
Public Class Http
#Region "Properties"
Private _Cookies As CookieContainer = New CookieContainer
Public Property Cookies() As CookieContainer
Get
Return _Cookies
End Get
Set(ByVal value As CookieContainer)
_Cookies = value
End Set
End Property
Private _Proxy As String = String.Empty
Public Property Proxy() As String
Get
Return _Proxy
End Get
Set(ByVal value As String)
_Proxy = value
End Set
End Property
Private _Useragent As String = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16"
Public Property Useragent() As String
Get
Return _Useragent
End Get
Set(ByVal value As String)
_Useragent = value
End Set
End Property
Private _Referer As String = String.Empty
Public Property Referer() As String
Get
Return _Referer
End Get
Set(ByVal value As String)
_Referer = value
End Set
End Property
Private _AutoRedirect As Boolean = True
Public Property AutoRedirect() As Boolean
Get
Return _AutoRedirect
End Get
Set(ByVal value As Boolean)
_AutoRedirect = value
End Set
End Property
Private _TimeOut As Integer = 15000
Public Property TimeOut() As Integer
Get
Return _TimeOut
End Get
Set(ByVal value As Integer)
_TimeOut = value
End Set
End Property
Public _StoreCookies As Boolean = True
Public Property StoreCookies() As Boolean
Get
Return _StoreCookies
End Get
Set(ByVal value As Boolean)
_StoreCookies = value
End Set
End Property
Public _SendCookies As Boolean = True
Public Property SendCookies() As Boolean
Get
Return _SendCookies
End Get
Set(ByVal value As Boolean)
_SendCookies = value
End Set
End Property
#End Region
#Region "Structures"
Public Upload As New UploadData
Structure UploadData
Private uContents As Byte()
Private uFileName As String
Private uFieldName As String
Public Property Contents() As Byte()
Get
Return uContents
End Get
Set(ByVal value As Byte())
uContents = value
End Set
End Property
Public Property FileName() As String
Get
Return uFileName
End Get
Set(ByVal value As String)
uFileName = value
End Set
End Property
Public Property FieldName() As String
Get
Return uFieldName
End Get
Set(ByVal value As String)
uFieldName = value
End Set
End Property
End Structure
#End Region
#Region "Objects and Variables"
Private Request As HttpWebRequest = Nothing
Private Requesting As Boolean = False
Private Const newLine As String = vbCr & vbLf
Private Accept As String = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
Private AcceptLanguage As String = "en-us,en;q=0.5"
Private _AutoDecompress As DecompressionMethods = DecompressionMethods.Deflate Or DecompressionMethods.GZip
#End Region
#Region "Constructor"
Public Sub New()
System.Net.ServicePointManager.Expect100Continue = False
System.Net.ServicePointManager.DefaultConnectionLimit = 150
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
End Sub
#End Region
#Region "Methods"
Public Sub CancelRequest()
If Not Requesting Then Exit Sub
Try
Request.Abort()
Catch ex As Exception
End Try
End Sub
Public Function GetResponse(ByVal Uri As String, Optional ByVal PostData As String = "") As Object
Try
Requesting = True
Request = DirectCast(WebRequest.Create(New Uri(Uri)), HttpWebRequest)
With Request
If Not String.IsNullOrEmpty(Proxy) Then
Dim pData() As String = Split(Proxy, ":")
Dim myProxy As New WebProxy(pData(0), Convert.ToInt32(pData(1)))
If pData.Count > 2 Then myProxy.Credentials = New NetworkCredential(pData(2), pData(3))
.Proxy = myProxy
Else
.Proxy = Nothing
End If
If SendCookies = True Then .CookieContainer = Cookies
.Timeout = TimeOut * 1000
.AllowAutoRedirect = AutoRedirect
.Method = IIf(String.IsNullOrEmpty(PostData), "GET", "POST")
.UserAgent = Useragent
.Referer = Referer
.Accept = Accept
.KeepAlive = True
.AutomaticDecompression = _AutoDecompress
.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7")
.Headers.Add("Accept-Language: " & AcceptLanguage)
If Not String.IsNullOrEmpty(PostData) Then
Dim PostDataBytes As Byte() = Encoding.UTF8.GetBytes(PostData)
.ContentType = "application/x-www-form-urlencoded"
.ContentLength = PostDataBytes.Length
Dim RequestStream As Stream = .GetRequestStream()
RequestStream.Write(PostDataBytes, 0, PostDataBytes.Length)
End If
Dim Response As HttpWebResponse = .GetResponse
If StoreCookies = True Then Cookies.Add(Response.Cookies)
Return Response
End With
Catch we As WebException
Return we
Catch ex As Exception
Return ex
Finally
Requesting = False
End Try
End Function
Public Function GetResponse(ByVal Uri As String, ByVal formFields As List(Of DictionaryEntry), ByVal ParamArray objects As UploadData()) As Object
Dim Boundary As String = Guid.NewGuid().ToString().Replace("-", "")
Try
Request = DirectCast(WebRequest.Create(New Uri(Uri)), HttpWebRequest)
With Request
If Not String.IsNullOrEmpty(Proxy) Then
Dim pData() As String = Split(Proxy, ":")
Dim myProxy As New WebProxy(pData(0), Convert.ToInt32(pData(1)))
If pData.Count > 2 Then myProxy.Credentials = New NetworkCredential(pData(2), pData(3))
.Proxy = myProxy
Else
.Proxy = Nothing
End If
.UserAgent = Useragent
.AllowAutoRedirect = False
.Timeout = TimeOut * 1000
.KeepAlive = True
.AutomaticDecompression = DecompressionMethods.GZip And DecompressionMethods.Deflate
.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
If Not String.IsNullOrEmpty(Referer) Then .Referer = Referer
.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-us,en;q=0.5")
.Headers.Add(HttpRequestHeader.AcceptCharset, "ISO-8859-1,utf-8;q=0.7,*;q=0.7")
If StoreCookies = True Then .CookieContainer = Cookies
.Method = "POST"
.ContentType = "multipart/form-data; boundary=" & Boundary
Dim PostData As New MemoryStream()
Dim Writer As New StreamWriter(PostData)
With Writer
If formFields IsNot Nothing Then
For Each de As DictionaryEntry In formFields
.Write(("--" & Boundary) & newLine)
.Write("Content-Disposition: form-data; name=""{0}""{1}{1}{2}{1}", de.Key, newLine, de.Value)
Next
End If
If Not (objects Is Nothing) Then
For Each us As UploadData In objects
.Write(("--" & Boundary) & newLine)
.Write("Content-Disposition: form-data; name=""{0}""; filename=""{1}""{2}", us.FieldName, us.FileName, newLine)
.Write(("Content-Type: application/octet-stream" & newLine) & newLine)
.Flush()
If Not (us.Contents Is Nothing) Then PostData.Write(us.Contents, 0, us.Contents.Length)
.Write(newLine)
Next
End If
.Write("--{0}--{1}", Boundary, newLine)
.Flush()
End With
.ContentLength = PostData.Length
Using s As Stream = .GetRequestStream()
PostData.WriteTo(s)
End Using
PostData.Close()
Dim Response As HttpWebResponse = .GetResponse
If SendCookies = True Then Cookies.Add(Response.Cookies)
Referer = String.Empty
Return Response
End With
Catch we As WebException
Return we
Catch ex As Exception
Return ex
End Try
End Function
Public Function ProcessResponse(ByVal Response As System.Net.HttpWebResponse, Optional ByVal AddHeaders As Boolean = True) As String
Dim DataLog As New StringBuilder
With Response
Dim Reader As New StreamReader(.GetResponseStream())
If AddHeaders = True Then
Dim Headers As WebHeaderCollection = .Headers
DataLog.AppendLine(Headers.ToString())
End If
DataLog.AppendLine(Reader.ReadToEnd())
.Close()
End With
Return DataLog.ToString
End Function
Public Function ParseBetween(ByVal Source As String, ByVal Before As String, ByVal After As String, ByVal Offset As Integer) As String
If String.IsNullOrEmpty(Source) Then Return String.Empty
If Source.Contains(Before) = True Then
Dim Result As String = Source.Substring(Source.IndexOf(Before) + Offset)
If Result.Contains(After) = True Then
If Not String.IsNullOrEmpty(After) Then Result = Result.Substring(0, Result.IndexOf(After))
End If
Return Result
Else
Return String.Empty
End If
End Function
Public Function ParseForms(ByVal Source As String, Optional ByVal ValueRequired As Boolean = False) As String
If Not String.IsNullOrEmpty(Source) Then Return String.Empty
Dim sb As New StringBuilder()
Dim tmp As String = Source
Dim Part As String = String.Empty : Dim Key As String = String.Empty : Dim Value As String = String.Empty
While tmp.Contains("<input ")
Part = ParseBetween(tmp, "name=""", ">", 0)
Key = ParseBetween(Part, "name=""", """", 6)
Value = ParseBetween(Part, "value=""", """", 7)
If ValueRequired Then
If Not String.IsNullOrEmpty(Value) Then sb.Append(Key & "=" & Value & "&")
Else
sb.Append(Key & "=" & Value & "&")
End If
tmp = tmp.Substring(tmp.IndexOf("name=") + 6)
End While
If sb.Length > 1 Then sb.Remove(sb.Length - 1, 1)
Return sb.ToString()
End Function
Public Function GetFormIdText(ByVal Source As String, ByVal Id As String) As String
Dim tmp As String = Source
Dim value As String = String.Empty
Try
tmp = tmp.Substring(tmp.IndexOf("id=""" & Id & """") + 5)
value = ParseBetween(tmp, "value=""", """", 7)
Catch
End Try
Return value
End Function
Public Function GetFormNameText(ByVal Source As String, ByVal Name As String) As String
Dim tmp As String = Source
Dim value As String = String.Empty
Try
tmp = tmp.Substring(tmp.IndexOf("name=""" & Name & """") + 7)
value = ParseBetween(tmp, "value=""", """", 7)
Catch
End Try
Return value
End Function
Public Function UrlEncode(ByVal Data As String) As String
Return Web.HttpUtility.UrlEncode(Data)
End Function
Public Function UrlDecode(ByVal Data As String) As String
Return Web.HttpUtility.UrlDecode(Data)
End Function
Public Function HtmlEncode(ByVal Data As String) As String
Return Web.HttpUtility.HtmlEncode(Data)
End Function
Public Function HtmlDecode(ByVal Data As String) As String
Return Web.HttpUtility.HtmlDecode(Data)
End Function
Public Sub ClearCookies()
Me.Cookies = Nothing
Me.Cookies = New CookieContainer
End Sub
#End Region
End Class
End Namespace
and now the Decaptcher class...
Code Namespace Utility
Public Class Decaptcher
Private http As New Utility.Http
Public Sub CancelRequest()
http.CancelRequest()
End Sub
Public Function SubmitImage(ByVal Path As String) As Object
Try
With http
.TimeOut = My.Settings.DecaptcherTimeout
.SendCookies = False : .StoreCookies = False
Dim dictionary As New List(Of DictionaryEntry)
Dim uploadSpecs As New Http.UploadData
dictionary.Add(New DictionaryEntry("function", "picture2"))
dictionary.Add(New DictionaryEntry("username", My.Settings.Decaptcher.Split(":")(0)))
dictionary.Add(New DictionaryEntry("password", My.Settings.Decaptcher.Split(":")(1)))
dictionary.Add(New DictionaryEntry("pict_to", "0"))
dictionary.Add(New DictionaryEntry("pict_type", "0"))
uploadSpecs.Contents = IO.File.ReadAllBytes(Path)
uploadSpecs.FileName = Path
uploadSpecs.FieldName = "pict"
Return .GetResponse("http://poster.decaptcher.com", dictionary, uploadSpecs)
End With
Catch ex As Exception
Return String.Empty
End Try
End Function
Public Function SubmitBadCaptcha(ByVal Major As String, ByVal Minor As String) As Object
Try
With http
.TimeOut = My.Settings.DecaptcherTimeout
.SendCookies = False : .StoreCookies = False
Dim dictionary As New List(Of DictionaryEntry)
Dim uploadSpecs As New Http.UploadData
dictionary.Add(New DictionaryEntry("function", "picture_bad2"))
dictionary.Add(New DictionaryEntry("username", My.Settings.Decaptcher.Split(":")(0)))
dictionary.Add(New DictionaryEntry("password", My.Settings.Decaptcher.Split(":")(1)))
dictionary.Add(New DictionaryEntry("major_id", Major))
dictionary.Add(New DictionaryEntry("minor_id", Minor))
Return .GetResponse("http://poster.decaptcher.com", dictionary, uploadSpecs)
End With
Catch ex As Exception
Debug.Print(ex.ToString)
Return String.Empty
End Try
End Function
End Class
End Namespace
I assume that most of you will be able to figure out how this works but just incase you don't here is a brief explanation of how to use both classes.
GET Request
Code Dim Http As New Utility.Http
With Http
Dim Request As Object = .GetResponse("http://www.yoursite.com/")
If Not TypeOf Request Is HttpWebResponse Then
Dim [error] As String = String.Empty
If TypeOf Request Is WebException Then
Dim we As WebException = DirectCast(Request, WebException)
' Handle the WebException here
ElseIf TypeOf Request Is Exception Then
Dim ex As Exception = DirectCast(Request, Exception)
' Handle the Exception here
End If
Exit Try
End If
Dim Html As String = .ProcessResponse(Request)
End With
POST Request
Code Dim Http As New Utility.Http
With Http
Dim sb As New StringBuilder
sb.Append("Parameter1_Key=" & .URLEncode("Parameter1_Value"))
sb.Append("&Parameter2_Key=" & .URLEncode("Parameter2_Value"))
Dim Request As Object = .GetResponse("http://www.yoursite.com/", sb.ToString)
If Not TypeOf Request Is HttpWebResponse Then
Dim [error] As String = String.Empty
If TypeOf Request Is WebException Then
Dim we As WebException = DirectCast(Request, WebException)
' Handle the WebException here
ElseIf TypeOf Request Is Exception Then
Dim ex As Exception = DirectCast(Request, Exception)
' Handle the Exception here
End If
Exit Try
End If
Dim Html As String = .ProcessResponse(Request)
End With
* - Perplexity - Jun 8, 2011
Damn idb, this looks hawt :3
* - tflo - Jun 8, 2011
This looks very interesting and well written, so now I would like to see if this can defeat one of my generated CAPCHAs (it would be nice if someone wanted to test this for me :P).
* - idb. - Jun 8, 2011
And this is how you utilize the Decaptcher class
Submit image
Code Dim Solution As String = String.Empty
Dim Major As String = String.Empty
Dim Minor As String = String.Empty
With decaptcher
Dim Request As Object = .SubmitImage("Path of captcha on disk") ' Image must be downloaded to harddrive. Do not use the URL of the image here.
If Not TypeOf Request Is HttpWebResponse Then
Dim [error] As String = String.Empty
If TypeOf Request Is WebException Then
Dim we As WebException = DirectCast(Request, WebException)
' Handle the WebException here
ElseIf TypeOf Request Is Exception Then
Dim ex As Exception = DirectCast(Request, Exception)
' Handle the Exception here
End If
Exit Try
End If
Dim Html As String = .ProcessResponse(Request)
If (Html Is Nothing) Then Exit Sub
If Not Html.Split("|").Count = 6 Then
Dim [error] As String = String.Empty
Select Case Html
Case "-1"
[error] = "Server side error."
Case "-2"
[error] = "Local error."
Case "-3"
[error] = "Network troubles."
Case "-4"
[error] = "Size of the text returned is too big."
Case "-5"
[error] = "Server overload."
Case "-6"
[error] = "No credits on decaptcher account."
Case "-7"
[error] = "Picture has been timed out on server."
Case "-200"
[error] = "Unknown server error."
Case "-201"
[error] = "Incorrect decaptcher login."
Case "-202"
[error] = "Incorrect picture size."
Case Else
[error] = "No valid response."
End Select
RaiseEvent Notify(Me, New Object(1) {"VoteError", [error] & " (Decaptcher)"})
Exit Sub
Else
Solution = Html.Split("|")(5)
Major = Html.Split("|")(1)
Minor = Html.Split("|")(2)
End If
Submit invalid decaptcher credit
Code With decaptcher
Dim Request As Object = .SubmitBadCaptcha(Major, Minor)
If Not TypeOf Request Is HttpWebResponse Then
If TypeOf Request Is WebException Then
Dim we As WebException = DirectCast(Request, WebException)
' Handle the WebException here
ElseIf TypeOf Request Is Exception Then
Dim ex As Exception = DirectCast(Request, Exception)
' Handle the Exception here
End If
Exit Try
End If
Dim Html As String = Http.ProcessResponse(Request)
End With
Hope everyone can follow this code. If you can follow all this, you should have absolutely no problem with mastering HTTP requests. Also, Decaptcher uses multi-part upload ContentType... that means that if you edit the code a little bit you should be able to write your own image/video uploader/etc etc.
Good luck guys/gals :)
(Jun 8, 2011 09:26 PM)TylerFlo Wrote: This looks very interesting and well written, so now I would like to see if this can defeat one of my generated CAPCHAs (it would be nice if someone wanted to test this for me :P).
I can already tell you that it 100% can defeat your captcha and any other captcha out there. The reason being is because Decaptchers method of defeating captchas isn't OCR. It's human interaction. They hire people to sit there and type in captchas all day long who get paid based on the amount of correct captchas they type. Humans will be able to break captchas more effectively than any OCR ever written. Anyone who disagrees is a complete retard.
By the way, I have no delusion that people will not C&P the code as is... but if you're going to be a scumbag who steals peoples work and doesn't bother learning from it atleast give some credit where it is due.
I just noticed that I left some stuff in there from my own project that you'll want to fix. Namely the My.Settings.DecaptcherTimeOut / My.Settings.TimeOut stuff. Instead of that, just change it to 30000 or whatever timeout variable youd like it set to.
Just noticed this thread got 5 stars as well. Thank you to whoever rated this 5 stars :)
OK... I'm done posting in here now. That's about 6 posts in a row that just got consolidated into 1. lol. Sorry to the admins.
* - TLF-KoBE - Jun 8, 2011
Wow, yet another interesting thread from you. I've never used Decaptcher but I can tell this code looks really nice.
* - tflo - Jun 8, 2011
(Jun 8, 2011 09:27 PM)idb Wrote: I can already tell you that it 100% can defeat your captcha and any other captcha out there. The reason being is because Decaptchers method of defeating captchas isn't OCR. It's human interaction. They hire people to sit there and type in captchas all day long who get paid based on the amount of correct captchas they type. Humans will be able to break captchas more effectively than any OCR ever written. Anyone who disagrees is a complete retard.
By the way, I have no delusion that people will not C&P the code as is... but if you're going to be a scumbag who steals peoples work and doesn't bother learning from it atleast give some credit where it is due.
I just noticed that I left some stuff in there from my own project that you'll want to fix. Namely the My.Settings.DecaptcherTimeOut / My.Settings.TimeOut stuff. Instead of that, just change it to 30000 or whatever timeout variable youd like it set to.
Just noticed this thread got 5 stars as well. Thank you to whoever rated this 5 stars :)
OK... I'm done posting in here now. That's about 6 posts in a row that just got consolidated into 1. lol. Sorry to the admins.
Sounds like the worst job ever LOL.
Great release BTW.
* - DragQueen - Jun 8, 2011
what execly this class should do.
get an image and pharse it ?
i really dont understand.
* - idb. - Jun 8, 2011
(Jun 8, 2011 09:44 PM)DragQueen Wrote: what execly this class should do.
get an image and pharse it ?
i really dont understand.
Theres 2 seperate classes. 1 is for HttpWebRequest and the other uses that class to handle Decaptcher.
What Decaptcher will do is allow you to upload the captcha image you are attempting to defeat and they will return a response containing the captchas text. It's to aid people in defeating captchas so they don't need to type them out themselves.
* - H3x0S - Jun 8, 2011
There is already a Decaptcher API.
* - idb. - Jun 8, 2011
(Jun 8, 2011 10:20 PM)H3x0S Wrote: There is already a Decaptcher API.
Well aware, but the POST method works faster than their piece of shit library and the last time I checked they didn't have a wrapper for the POST method. Not to mention, using this will save you the trouble of having to deploy another useless DLL with your project. This also has proxy support if you need it. Theirs does not. Just saying.
* - Coleak - Jun 9, 2011
Wow, this is sexy. Looks like a lot of hardwork, although it wont benefit me, this should benefit a ton of people trying to make accouts makers. This is reallly nice.
* - theonetrueace - Jun 9, 2011
I think you will find a few other services just like decap out there...in my experience they all have their problems from time to time, so the best implementation would monitor and use multiple services....personally I've got 6 and a rating system to determine which to use for various requests....so keep that in mind, decap is not the be-all-end-all of cap service providers ;)
* - Yui Hirasawa - Jun 9, 2011
Look's great, nice share to the VB.NET Section :-)
Thanks.
* - pr3fix - Jun 9, 2011
Damn you little, you never stop to amaze me.
* - DeathStarâ„¢ - Jun 9, 2011
This is truly amazing, may I ask how long it took you to code this?
|