A preserved archive of the Logical Gamers community forums, 2009-2025. The original threads and posts, served read-only. Registration, posting and private messages are gone for good.

[HOWTO] Captcha decodes using the auth API

943 views · started by Artificial ·
#1
[HOWTO] Captcha decodes using the auth API
Ill quickly explain the process of decoding captchas with the auth API. At the time of this post, it doesnt cost LG to decode a captcha (as it's currently only being used for testing purposes), however this will be updated in the future. It currently is only configured for recaptcha.

One final note: I'm not happy with how we keep having to send the user/pass combination to the server, and especially in plaintext. I'm going to rework all of this in the future, however I'll ensure that legacy calls are still properly processed, so it shouldn't be a concern.

--

So, basically the system works like this (I've been drawing diagrams all week for my IS class, thought I would do another :p)



So, like the diagram alludes to, you send the recaptcha key to the server, it sends back a system key, and then you use that system key to check with the server whether or not it has been solved. For instance, on the project I've been working on, I check every 5 seconds until it's solved.

Auth URLs


Send recaptcha key to server:
http://logicalgamers.com/auth/auth.php?user=&pass=&key=&gpc=&do=start&cid=


Breakdown:

  • User - logicalgamers username
  • Pass - logicalgamers password
  • key - your program key (will give you a % of LGG deducted from system)
  • gpc - random integer. Should be reasonably large
  • cid - recaptcha id. The value of the c variable in the following url:


http://api.recaptcha.net/image?c=03AHJ_VutAxHMf8TvDkgfn7to-Uj-JMlI3EkFAludzAL9LOA2QWyCu9jiA8xIJUmmuvXiGe5sr6k80a8QWj0ZjSWAo8RAoQn2Iz5sxSvAxoqZJviofoBqvZgjP2yNurak7XDZlCYy2n01Q3jkMrEt5BpSL6GfVQjq6tw


If you send the request properly it should give you a result similar to:
<return>
<sessionId>3dffff5e51205379d02d4ce88ec5ecca</sessionId>
</return>


The session id is important, so save that. It's a session unique to that individual captcha.

Checking on the captcha status
This is fairly simple once you have the captcha session id. Just send a call to:

http://logicalgamers.com/auth/auth.php?user=&pass=&key=&gpc=&do=status&csession=


All of the variables are same as the previous call, save csession, which is the captcha session id you retrieved in the previous step. If the captcha hasn't been found, it will output something similar to:

<return>
<error>Captcha not found</error>
</return>


The error message may change depending on the error. If the captcha has been found, it will output something similar to:
<return>
<captcha>captcha text</captcha>
</return>


Where the value of the captcha is found within the <captcha> tag.

Reporting an invalid captcha
If the captcha did not work (i.e. it was invalid), send an API call to:

http://logicalgamers.com/auth/auth.php?user=&pass=&key=&gpc=&do=invalid&csession=


Obviously filling out the variables. Our system will send a call back to deathbycaptcha and will ask for our money back.


Sample implementation code:

This is the code I've used in Python:

Class A:
    def initialiseCaptcha( self, captchaId ):
# Captcha API url
captchaApi = 'http://logicalgamers.com/auth/auth.php?user=' + self.lgDetails['username'] + '&pass=' + self.lgDetails['password'] + '&key=' + self.lgDetails['programKey'] + '&gpc=' + str( random.randint( 10000,1000000 ) ) + '&do=start&cid=' + captchaId

# Retrieve the contents of the page
pageHtml = self.openUrl( captchaApi )

# Try to return
try:
captchaApiKey = re.findall( "\<sessionId\>([a-z0-9]{32})\<\/sessionId\>", pageHtml )

# Return the server captcha API key
return captchaApiKey[0]

except:
print "Unable to retrieve captcha session", captchaApiKey, pageHtml
return ""


def retrieveCaptcha( self, captchaSession ):
# Captcha API url
captchaApi = 'http://logicalgamers.com/auth/auth.php?user=' + self.lgDetails['username'] + '&pass=' + self.lgDetails['password'] + '&key=' + self.lgDetails['programKey'] + '&gpc=' + str( random.randint( 10000,1000000 ) ) + '&do=status&csession=' + captchaSession

# Retrieve the contents of the page
pageHtml = self.openUrl( captchaApi )

if pageHtml.find( "<error>" ) >= 0:
return ""
else:
captchaText = re.findall( "\<captcha\>(.*?)\<\/captcha\>", pageHtml )
return captchaText[0]

def reportInvalidCaptcha( self, captchaSession ):
# Captcha API url
captchaApi = 'http://logicalgamers.com/auth/auth.php?user=' + self.lgDetails['username'] + '&pass=' + self.lgDetails['password'] + '&key=' + self.lgDetails['programKey'] + '&gpc=' + str( random.randint( 10000,1000000 ) ) + '&do=invalid&csession=' + captchaSession

# Retrieve the contents of the page
pageHtml = self.openUrl( captchaApi )
print "Invalid captcha", pageHtml
[/0][/0]


Initializing the captcha and retrieving the value:
   
# Let's finish the game by sending our bucket to Gaia
def finishGame(self):

print "finishGame function called"

# Retrieve captcha function
def retrieveCaptcha():
# For debugging purposes
print "Fetching a new captcha"

# Let's do some tests with the captcha
captchaId = self.gaiaClass.getCaptcha()

# Let's connect to the logicalgamers API service
captchaSession = self.gaiaClass.initialiseCaptcha( captchaId )

# Let's try and get the value
captchaText = ""
curCount = 0

# Loop through
while captchaText == "":
# For debugging purposes
print "Waiting 5 seconds while we attempt to decode captcha"

# If we've already tried (x) times, lets just break out and request a new captcha
if curCount >= 6:
return ""

# Increment the count
curCount += 1

# Sleep and then check on the status
time.sleep( 5 )
captchaText = self.gaiaClass.retrieveCaptcha( captchaSession )

# Return the captcha
return captchaText

# Let's loop through and fetch the captcha. If it's blank, we simply request another one
captchaText = ""
while captchaText == "":
captchaText = retrieveCaptcha()


Detecting if the captcha was invalid:
                # Captcha was accepted
if sushi[2] == "OK":
self.sendAttempts = 0
self.fishing = False
self.sendSushi([["19", self.seqID, "G_FISH_PLUGIN", "501", self.g_gameMD5, self.gaiaDetails["sessionId"]]])

# Captcha was not accepted
else:
self.sendAttempts += 1
# It's failed. We've done it enough, let's just start a new game
if self.sendAttempts >= 4:
self.sendAttempts = 0
self.fishing = False
self.sendSushi([["19", self.seqID, "G_FISH_PLUGIN", "501", self.g_gameMD5, self.gaiaDetails["sessionId"]]])

# Otherwise it's failed, let's just try it again
else:
# Try to send again
self.finishGame()
[/2]


That's it. Questions? Just ask.
#2
Thanks alex! We loves you, lol

Im implementing this into the C# Auth code as i edit this
#3
Python makes me happy.

Definitely put some kind of encryption on the passwords when sending them to the server, so no one eavesdrops. :P
#4
I'm probably just going to return a session id and have the server handle the username/password. But I'll still need to write some sort of algorithm to protect the password in the original request. I'm going to hold off working on the auth serverside until I get around to writing the client side verification in C.
#5
Can you make it so if the captcha session is null or something it wont fail the login so we dont have to go through and update all of our programs. Other words if we just want to login with out the captcha crap. Sort of like a bypass.
#6
Fixed. Sorry, that was a bug.
#7
Just use MD5 or other common crypt algorithms. If you need to decrypt in the server side, then use public/private symmetric keys. Just putting that out there. :)
#8
We wouldnt need to decrypt it actually. Because vBulletin uses md5( md5( password ) . salt ) we could just send through the single md5 password.
#9
I almost have it in C#. Its just being stupid and replying that i need to supply a username even though im using the url: (of course i removed my pass though)

http://logicalgamers.com/auth/auth.php?user=MattSmith&pass=&key=cec3872cf3bc25637fab61af5a19ea7c&gpc=621636cd75517e2b5f48de3671239d021e97d62347&do=start&cid=03AHJ_VusOm0vYLYoGWgFsDgTV0JsdoWeasmHI3MOALmODjxIADzU2GgaQ_Dw5PI6kBO9Rq1UXw_EjW1VONaOs6_F4ebVY_4G_oxpCk6aN6aMBcg9FOOG7QMr44ynYRZ5Cn9XeKn2kzSqyF2DMT8bXgTzX9v_gjk_mLA


This is the url that the program generated, i just put a break in and copied the variable. Use in browser its fine. Use on program, doesnt work. Has something to do with wrapper obviously..
#10
MattSmith wrote:
I almost have it in C#. Its just being stupid and replying that i need to supply a username even though im using the url: (of course i removed my pass though)

http://logicalgamers.com/auth/auth.php?user=MattSmith&pass=&key=cec3872cf3bc25637fab61af5a19ea7c&gpc=621636cd75517e2b5f48de3671239d021e97d62347&do=start&cid=03AHJ_VusOm0vYLYoGWgFsDgTV0JsdoWeasmHI3MOALmODjxIADzU2GgaQ_Dw5PI6kBO9Rq1UXw_EjW1VONaOs6_F4ebVY_4G_oxpCk6aN6aMBcg9FOOG7QMr44ynYRZ5Cn9XeKn2kzSqyF2DMT8bXgTzX9v_gjk_mLA


This is the url that the program generated, i just put a break in and copied the variable. Use in browser its fine. Use on program, doesnt work. Has something to do with wrapper obviously..


Get stream .
#11
Nah i got it chad, way before you replied. Only reason i havnt updated the auth thread is because im adding more stuff to it.

I have an event that fires when the captcha is found. Also, you can check manually if you want, and you can disable the event so you dont use the resources and such. Very easily used too