Exploit-DB #18214
Description: SMF 2.0.1 - SQL Injection / Privilege Escalation
Type: webapps
Platform: php
Date: 2011-12-07
Author: The:Paradox

Exploit:
#!/usr/bin/python
# -*- coding: iso-8859-15 -*-
#
#
# Exploit Title:		Smf <= 2.0.1 Sql injection Vulnerability
# Author:			The:Paradox
# Disclosure date: 	06/12/2011
# Software Link:	http://download.simplemachines.org/ , http://www.php.net/releases/
#
#
# Smf <= 2.0.1 Sql injection Vulnerability
#	- Priviledge escalation exploit
#
# INTRO:
#
#
# ------- ENGLISH -------
#
# Just disclosing all old/useless stuff on my hard drive.
#
# Nice vulnerability but too much target requirements: PHP5 < 5.1.4 or PHP4 < 4.4.3 (php Zend_Hash_Del_Key_Or_Index vulnerability affected version)
# Successfully tested on PHP versions < 5.1.4
#
# This exploit was written for version 1.1.5, updated to 1.1.11. I checked some sources, I bet it's actually working on all versions (last version is 2.0.1)
# Note: PHP4 calculed hash seems to be wrong, somehow can't get correct Zend_Hash_Del_Key_Or_Index Vulnerability hash, whatever. 
#
#
#
# ------- ITALIANO -------
#
# Pubblicando tutto cio' che Ãš diventato inutile o troppo vecchio che ho sul mio disco rigido.
#
# VulnerabilitÃ  davvero intricata e carina, ma i target possibili effettivi sono davvero pochi visti i requirements:  PHP5 < 5.1.4 or PHP4 < 4.4.3 (php Zend_Hash_Del_Key_Or_Index vulnerability)
#
# Questa vulnerabilitÃ  esiste perchÃš nella realtÃ  dei fatti i programmatori di smf non hanno mai ben compreso la mia precedente advisory, 
# e fixando un po' alla meno peggio hanno mandato in conflitto due filtri di diverso tipo.
# E' davvero divertente vedere come la supponenza dei programmatori di smf sia arrivata a commentare in modo da indicarmi esattamente
# dove cercare la vulnerabilitÃ . Commento testuale: <<Numeric keys in cookies are less of a problem. Just unset those>>, ed Ãš proprio per questo "diverso
# trattamento" (chissÃ  perchÃš poi) che la vulnerabilitÃ  esiste.
#
# L'exploit Ãš stato scritto per 1.1.5 e precedenti, riadattato alla 1.1.11, e, attualmente, dando un'occhiata ai sorgenti, sono pronto a scommettere che funziona su
# tutte le versioni attuali (2.0.1 Ãš l'ultima al momento del rilascio).
#
# Il poc qui sotto Ãš scritto in un inglese cacofonico e altamente comprensibile ad un italiano, credo che fare una traduzione sia davvero superfluo, spero di non creare problemi
# di comprensione perchÃš questo exploit Ãš davvero a solo "Educational Purpose" visto che cercare versioni php cosÃ¬ vecchie che montino smf Ãš come cercare un
# ago in un pagliaio.
#
# Per motivi che non comprendo, l'hash php4 di Zend_Hash_Del_Key_Or_Index Vulnerability non Ãš corretto e non sono riuscito a generarlo, correggetelo nel caso vogliate testare su php4.
# Testata con successo sulle versioni vulnerabili di php5
#
#
""" 
<POC>

Smf <= 1.1.11 Sql injection Vulnerability
	- Priviledge escalation exploit

			// The:Paradox 

I said in my last smf advisory that 1.1.5 version was safe from
sql code injections affecting the previous version.
Now here we are to show how that's not really true.
The "patch code" (File index.php, lines 45-48) is useless in PHP 5 version < 5.1.4
and PHP 4 version < 4.4.3

First, let's see some source code:


File: index.php 
----------------------------------------------------------

45.	// Make sure some things simply do not exist.
46.	foreach (array('db_character_set') as $variable)
47.		if (isset($GLOBALS[$variable]))
48.			unset($GLOBALS[$variable]);
49.	
50.	// Load the settings...
51.	require_once(dirname(__FILE__) . '/Settings.php');
52.	
53.	// And important includes.
54.	require_once($sourcedir . '/QueryString.php');
55.	require_once($sourcedir . '/Subs.php');
56.	require_once($sourcedir . '/Errors.php');
57.	require_once($sourcedir . '/Load.php');
58.	require_once($sourcedir . '/Security.php');
[...]
78.	// Load the settings from the settings table, and perform operations like optimizing.
79.	reloadSettings();
80.	// Clean the request variables, add slashes, etc.
81.	cleanRequest();

----------------------------------------------------------

File: Sources/Load.php
----------------------------------------------------------

138.	function reloadSettings()
139.	{
140.		global $modSettings, $db_prefix, $boarddir, $func, $txt, $db_character_set;
141.		global $mysql_set_mode, $context;
142.	
143.		// This makes it possible to have SMF automatically change the sql_mode and autocommit if needed.
144.		if (isset($mysql_set_mode) && $mysql_set_mode === true)
145.			db_query("SET sql_mode='', AUTOCOMMIT=1", false, false);
146.
147.		// Most database systems have not set UTF-8 as their default input charset.
148.		if (isset($db_character_set) && preg_match('~^\\w+$~', $db_character_set) === 1)
149.			db_query("
150.				SET NAMES $db_character_set", __FILE__, __LINE__);

----------------------------------------------------------

File: Sources/QueryString.php
----------------------------------------------------------

83.	function cleanRequest()
84.	{
85.		global $board, $topic, $boardurl, $scripturl, $modSettings;
86.	
87.		// Makes it easier to refer to things this way.
88.		$scripturl = $boardurl . '/index.php';
89.	
90.		// Save some memory.. (since we don't use these anyway.)
91.		unset($GLOBALS['HTTP_POST_VARS'], $GLOBALS['HTTP_POST_VARS']);
92.		unset($GLOBALS['HTTP_POST_FILES'], $GLOBALS['HTTP_POST_FILES']);
93.	
94.		// These keys shouldn't be set...ever.
95.		if (isset($_REQUEST['GLOBALS']) || isset($_COOKIE['GLOBALS']))
96.			die('Invalid request variable.');
97.	
98.		// Same goes for numeric keys.
99.		foreach (array_merge(array_keys($_POST), array_keys($_GET), array_keys($_FILES)) as $key)
100.			if (is_numeric($key))
101.				die('Invalid request variable.');
102.	
103.		// Numeric keys in cookies are less of a problem. Just unset those.
104.		foreach ($_COOKIE as $key => $value)
105.			if (is_numeric($key))
106.				unset($_COOKIE[$key]);
----------------------------------------------------