Home Upgrade Search Memberlist Extras Hacker Tools Award Goals Help Wiki Contact

.NET 

[Source] Decaptcher

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
Need a custom software? Check out my freelance service here! 6+ years and counting, never a complaint :)

STOP STEALING CODE.

FREE NATHAN

People who report posts are lamers.
Damn idb, this looks hawt :3
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).
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)tflo 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.
Need a custom software? Check out my freelance service here! 6+ years and counting, never a complaint :)

STOP STEALING CODE.

FREE NATHAN

People who report posts are lamers.
Wow, yet another interesting thread from you. I've never used Decaptcher but I can tell this code looks really nice.
(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.
what execly this class should do.
get an image and pharse it ?
i really dont understand.
(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.
Need a custom software? Check out my freelance service here! 6+ years and counting, never a complaint :)

STOP STEALING CODE.

FREE NATHAN

People who report posts are lamers.
There is already a Decaptcher API.
(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.
Need a custom software? Check out my freelance service here! 6+ years and counting, never a complaint :)

STOP STEALING CODE.

FREE NATHAN

People who report posts are lamers.
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.
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 ;)
Look's great, nice share to the VB.NET Section :-)

Thanks.
Damn you little, you never stop to amaze me.
This is truly amazing, may I ask how long it took you to code this?


Possibly Related Threads...
Thread / Author Replies Views Last Post
[.NET] by spartanier7777Jan 24, 2013 03:23 PM 64 9,723 Jan 24, 2013 03:23 PM
Last Post: wοrlockt
[.NET] by 1700blockDec 14, 2012 05:59 PM 34 3,578 Dec 14, 2012 05:59 PM
Last Post: iCorb0
[.NET] by idb.Nov 27, 2012 02:28 PM 19 1,080 Nov 27, 2012 02:28 PM
Last Post: MeSriNeHC