PHPMYWIND4.6.6前台Refer头注入+后台另类getshell分析
下载链接
https://share.weiyun.com/b060b59eaa564d729a9347a580b7e4f2
Refer头注入
全局过滤函数如下
function _RunMagicQuotes(&$svar)
{
//PHP5.4已经将此函数移除
if(@!get_magic_quotes_gpc())
{
if(is_array($svar))
{
foreach($svar as $_k => $_v) $svar[$_k] = _RunMagicQuotes($_v);
}
else
{
if(strlen($svar)>0 &&
preg_match('#^(cfg_|GLOBALS|_GET|_POST|_SESSION|_COOKIE)#',$svar))
{
exit('不允许请求的变量值!');
} $svar = addslashes($svar);
}
}
return $svar;
}
在前台注册用户并且添加收藏的地方抓包分析
else if($a == 'savefavorite')
{
//die("test");
$aid = isset($aid) ? $aid : '';
$molds = isset($molds) ? $molds : '';
$link = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; if($aid == '' or $molds == '' or $link == '')
{
header('location:?c=default');
exit();
} $r = $dosql->GetOne("SELECT `id`,`expval`,`integral` FROM `#@__member` WHERE `username`='$c_uname'");
$uid = $r['id'];
$uname = $c_uname;
$time = time();
$ip = GetIP(); $r2 = $dosql->GetOne("SELECT `aid`,`molds` FROM `#@__userfavorite` WHERE `aid`=$aid and `molds`=$molds");
if(!is_array($r2))
{
$dosql->ExecNoneQuery("INSERT INTO `#@__userfavorite` (aid,molds,uid,uname,link,time,ip,isshow) VALUES ('$aid','$molds','$uid','$uname','$link','$time','$ip','1')");
//收藏一条增加1经验值2积分
$dosql->ExecNoneQuery("UPDATE `#@__member` SET expval='".($r['expval'] + 1)."', integral='".($r['integral'] + 2)."' WHERE `username`='$c_uname'");
echo '1';
exit();
}
else
{
echo '2';
exit();
}
}
GetIp()函数不能用
function GetIP()
{
static $ip = NULL;
if($ip !== NULL) return $ip; if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
{
$arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$pos = array_search('unknown',$arr);
if(false !== $pos) unset($arr[$pos]);
$ip = trim($arr[0]);
}
else if(isset($_SERVER['HTTP_CLIENT_IP']))
{
$ip = $_SERVER['HTTP_CLIENT_IP'];
}
else if(isset($_SERVER['REMOTE_ADDR']))
{
$ip = $_SERVER['REMOTE_ADDR'];
} //IP地址合法验证
$ip = (false !== ip2long($ip)) ? $ip : '0.0.0.0';
return $ip;
}
但是
$link = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
HTTP头是不受全局过滤的影响的
跟进ExecNoneQuery函数
function ExecNoneQuery($sql='')
{
global $dosql; if($dosql->isclose)
{
$this->Open();
$dosql->isclose = false;
} if(!empty($sql))
{
$this->SetQuery($sql);
}
else
{
return false;
} //SQL语句安全检查
if($this->safecheck)
{ // die($sql);
$this->CheckSql($this->querystring,'update');
} if(mysqli_query($this->linkid, $this->querystring))
{
return true;
}
else
{
$this->DisplayError(mysqli_error($this->linkid).' Error sql: '.$this->querystring);
exit();
}
}
有个CheckSql函数 跟进一下
function CheckSql($sql, $querytype='select')
{ $clean = '';
$error = '';
$pos = -1;
$old_pos = 0; //如果是普通查询语句,直接过滤一些特殊语法
if($querytype == 'select')
{
if(preg_match('/[^0-9a-z@\._-]{1,}(union|sleep|benchmark|load_file|outfile)[^0-9a-z@\.-]{1,}/', $sql))
{
$this->DisplayError("$sql||SelectBreak",1);
}
} //完整的SQL检查
while(true)
{
$pos = strpos($sql, '\'', $pos + 1);
if($pos === false)
{
break;
}
$clean .= substr($sql, $old_pos, $pos - $old_pos); while(true)
{
$pos1 = strpos($sql, '\'', $pos + 1);
$pos2 = strpos($sql, '\\', $pos + 1);
if($pos1 === false)
{
break;
}
else if($pos2 == false || $pos2 > $pos1)
{
$pos = $pos1;
break;
}
$pos = $pos2 + 1;
} $clean .= '$s$';
$old_pos = $pos + 1;
} $clean .= substr($sql, $old_pos);
$clean = trim(strtolower(preg_replace(array('~\s+~s' ), array(' '), $clean)));
var_dump($clean); //老版本的Mysql并不支持union,常用的程序里也不使用union,但是一些黑客使用它,所以检查它
if(strpos($clean, 'union') !== false && preg_match('~(^|[^a-z])union($|[^[a-z])~s', $clean) != 0)
{
$fail = true;
$error = 'union detect';
} //发布版本的程序可能比较少包括--,#这样的注释,但是黑客经常使用它们
else if(strpos($clean, '/*') > 2 || strpos($clean, '--') !== false || strpos($clean, '#') !== false)
{
$fail = true;
$error = 'comment detect';
} //这些函数不会被使用,但是黑客会用它来操作文件,down掉数据库
else if(strpos($clean, 'sleep') !== false && preg_match('~(^|[^a-z])sleep($|[^[a-z])~s', $clean) != 0)
{
$fail = true;
$error = 'slown down detect';
}
else if(strpos($clean, 'benchmark') !== false && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s', $clean) != 0)
{
$fail = true;
$error = 'slown down detect';
}
else if(strpos($clean, 'load_file') !== false && preg_match('~(^|[^a-z])load_file($|[^[a-z])~s', $clean) != 0)
{
$fail = true;
$error = 'file fun detect';
}
else if(strpos($clean, 'into outfile') !== false && preg_match('~(^|[^a-z])into\s+outfile($|[^[a-z])~s', $clean) != 0)
{
$fail = true;
$error = 'file fun detect';
} //老版本的MYSQL不支持子查询,我们的程序里可能也用得少,但是黑客可以使用它来查询数据库敏感信息
else if(preg_match('~\([^)]*?select~s', $clean) != 0)
{
$fail = true;
$error = 'sub select detect';
} if(!empty($fail))
{
$this->DisplayError("$sql,$error",1);
}
else
{
return $sql;
}
}
这是80sec的防sql注入函数
通过跟踪这段代码发现,它有个特征就是会将两个单引号之间的内容用$s$替换,例如’select’会被替换为$s$,这里用两个@`'`包含敏感字,这样$clean变量中就不会出现敏感字,从而绕过CheckSql()函数检测
这里可以设置title为如下代码,一方面绕过ids防注入代码检测,另一方面加一个#注释掉后面的代码,但是还要做一下变形,就是这个char(@`'`)了。因为#@__feedback的所有字段都被设置为NOT NULL,而@`'`是一个变量,默认为NULL,直接插入@`'`的话会报错,所以需要以char(@`'`)的方法转换一下。
1' and updatexml(1,concat(0x7e,(select concat(0x7e,version(),0x7e)),0x7e),1),1,1,1)#
后台另类getshell
在后台网站配置处 admin/web_config.php
理论上说有全局过滤应该就不能闭合拿shell了
但是仔细读一下他的流程
先把东西存到数据库- 然后在从数据库中都出来构造字符串写进文件
if($action == 'update')
{
foreach($_POST as $k=>$v)
{
//统计代码转义
$v = _RunMagicQuotes($v); if(!$dosql->ExecNoneQuery("UPDATE `#@__webconfig` SET `varvalue`='$v' WHERE varname='$k'"))
{
ShowMsg('更新变量失败,可能有非法字符!', 'web_config.php');
exit();
}
} WriteConfig(); ShowMsg('成功保存变量并更新配置文件!', 'web_config.php');
exit();
}
更新文件的函数
function WriteConfig()
{
global $dosql, $config_cache; //die($config_cache); $str = '<?php if(!defined(\'IN_PHPMYWIND\')) exit(\'Request Error!\');'."\r\n\r\n";
$dosql->Execute("SELECT `varname`,`vartype`,`varvalue`,`vargroup` FROM `#@__webconfig` ORDER BY orderid ASC");
while($row = $dosql->GetArray())
{
//强制去掉 '
//强制去掉最后一位 /
$vartmp = str_replace("'",'',$row['varvalue']); if(substr($vartmp, -1) == '\\')
{
$vartmp = substr($vartmp,1,-1);
} if($row['vartype'] == 'number')
{
if($row['varvalue'] == '')
{
$vartmp = 0;
} $str .= "\${$row['varname']} = ".$vartmp.";\r\n";
}
else
{
$str .= "\${$row['varname']} = '".$vartmp."';\r\n";
}
}
$str .= '?>';
//die($str); if(!Writef($config_cache,$str))
{
ShowMsg("变量成功保存,但由于 config.cache.php 无法写入,因此不能更新配置!", 'web_config.php');
exit();
} RewriteURL();
}
上述代码第13行
$vartmp = str_replace("'",'',$row['varvalue']);
有多少单引号也给过滤了
但是下面一个操作
//强制去掉最后一位
有这样的操作
如果我写两个\\\进去 从数据库出来的时候 还是三个\ 但是
15 if(substr($vartmp, -1) == '\\')找他的最后一数是不是\
16 {
17 $vartmp = substr($vartmp,1,-1);
这里的操作是让变量登入字符串从下标为1开始一直到从后面数第二个的
三个\\\就是 下标1 是\ 倒数第二个跟他一样的
18 }
经过上面的操作就只剩下一个\
意思就是
上面的单引号被转移 就跟下面连起来了
再接着/*多行注释就起作用了
很老的一个洞了 还是很值的学习的。
PHPMYWIND4.6.6前台Refer头注入+后台另类getshell分析的更多相关文章
- AES加密解密——AES在JavaWeb项目中前台JS加密,后台Java解密的使用
一:前言 在软件开发中,经常要对数据进行传输,数据在传输的过程中可能被拦截,被监听,所以在传输数据的时候使用数据的原始内容进行传输的话,安全隐患是非常大的.因此就要对需要传输的数据进行在客户端进行加密 ...
- XSS注入,js脚本注入后台
曾经一度流行sql注入,由于现在技术的更新,已经看不到这问题了,但是又出来新的安全问题,XSS攻击,他的原理就是在前端提交表单的时候,在input标签当中输入js脚本,通过js脚本注入后台,请看下图. ...
- SAP跟踪前台操作导致的后台查询语句
SAP跟踪前台操作导致的后台查询语句,通过这个可以查看前台对应了后台的数据库表,然后可以通过se11查看表内容,也可以删除表内容. 在sap升级的时候,首先需要拷贝正式的sap系统,然后将拷贝的系统中 ...
- SQL注入篇二------利用burp盲注,post注入,http头注入,利用burpsuit找注入点,宽字节注入
1.布尔盲注burpsuit的使用 先自己构造好注入语句,利用burpsuit抓包,设置变量,查出想要的信息. 比如----查数据库名的ascii码得到数据库构造好语句 http://123.206. ...
- form表单提交中文乱码(前台中文到JAVA后台乱码)问题及解决
form表单提交中文乱码(前台中文到JAVA后台乱码)问题及解决 一.问题: 页面输入框中的中文内容,在后台乱码,导致搜索功能失效:(详细可以见后面的重现) 二.原因: 浏览器对于数据的默认编码格式为 ...
- 重新认识被人遗忘的HTTP头注入
前言 注入类漏洞经久不衰,多年保持在owasp Top 10的首位.今天就聊聊那些被人遗忘的http头注入.用简单的实际代码进行演示,让每个人更深刻的去认识该漏洞. HOST注入 在以往http1.0 ...
- 2.HTTP头注入
重新认识被人遗忘的HTTP头注入 前言 注入类漏洞经久不衰,多年保持在owasp Top 10的首位.今天就聊聊那些被人遗忘的http头注入.用简单的实际代码进行演示,让每个人更深刻的去认识该漏洞. ...
- SpringMVC:前台jsp页面和后台传值
前台jsp页面和后台传值的几种方式: 不用SpringMVC自带的标签 前台---->后台,通过表单传递数据(): 1.jsp页面代码如下, modelattribute 有没有都行 < ...
- 解决Ajax前台中文传到后台出现中文乱码
遇到的问题是: 前台利用Ajax, get方式向后台发送中文数据出现乱码. 解决办法是前台两次编码, 后台一次解码即可. 前台jsp文件 1 var text = "张三"; 3 ...
随机推荐
- Codeforces518 D. Ilya and Escalator
传送门:>Here< 题意:有n个人排队做电梯,每个人必须等前面的人全部上了以后才能上.对于每秒钟,有p的概率选择上电梯,(1-p)的概率选择不上电梯.现在问t秒期望多少人上电梯 解题思路 ...
- LOJ2557. 「CTSC2018」组合数问题
LOJ2557. 「CTSC2018」组合数问题 这道题是我第一道自己做完的题答题.考场上面我只拿了41分,完全没有经验.现在才发现其实掌握了大概的思路还是不难. 首先模拟退火,通过了1,2,6,9, ...
- RequestContextHolder 很方便的获取 request
在 Spring boot web 中我们可以通过 RequestContextHolder 很方便的获取 request. ServletRequestAttributes requestAttri ...
- 自适应PC端网页制作使用REM
做一个PC端的网页,设计图是1920X1080的. 要在常见屏上显示正常(比例正确可) 1280X720 1366X768 1440X900 1920X1080 使用了几种办法 1.内容在一屏内显示的 ...
- mysql5.6做单向主从复制Replication
原理场景:MySQL从3.23版本开始提供复制功能.指的是将主数据库的DDL和DML操作通过二进制日志传到从服务器(也叫从库),然后在从库上对这些日志重新执行, 从而使得从库和主库的数据保持同步. 优 ...
- InnoDB,5项最佳实践,知其所以然?
InnoDB,5项最佳实践,知其所以然? 原创: 58沈剑 架构师之路 昨天 缓存讲了一个月<缓存架构,一篇足够>.今天,开始写数据库. 第一篇,说说MySQL两个最常用的存储引擎,MyI ...
- java 遍历方法 及 数组,ArrayList,HashMap,HashSet的遍历
一,遍历方法的实现原理 1.传统的for循环遍历,基于计数器的: 遍历者自己在集合外部维护一个计数器,然后依次读取每一个位置的元素,当读取到最后一个元素后,停止.主要就是需要按元素的位置来读取元素. ...
- QML学习笔记(六)- 简单计时器和定时器
做一个简单的qml计时器和定时器,左键触发计时,右键触发定时 GitHub:八至 作者:狐狸家的鱼 本文链接:QML学习笔记(六)- 简单计时器和定时器 左键点击按钮,触发计时器,中键可以暂停计时,同 ...
- LOJ#2720 你的名字
题意:给定母串s和若干个询问.每个询问是一个串t和两个数l,r,表示求t中有多少个本质不同的子串没有在s[l,r]中出现过. 解:我写的并不是正解......是个毒瘤做法.只在loj上面卡时过了就写l ...
- zabbix3.4 监控网卡流量设置差量
自定义监控项的时候 看里面预设的监控网卡下载流量的key是 net.if.in[if,<mode>]这次可以监控流量了 但是添加监控项的时候 看网上别人的 都是可以设置数值是每秒的差量 出 ...