PHPMYWIND4.6.6前台Refer头注入+后台另类getshell分析
2017-08-16 16:14
1126 查看
下载链接
https://share.weiyun.com/b060b59eaa564d729a9347a580b7e4f2
Refer头注入
全局过滤函数如下
在前台注册用户并且添加收藏的地方抓包分析
GetIp()函数不能用
View Code
这是80sec的防sql注入函数
通过跟踪这段代码发现,它有个特征就是会将两个单引号之间的内容用$s$替换,例如’select’会被替换为$s$,这里用两个@`'`包含敏感字,这样$clean变量中就不会出现敏感字,从而绕过CheckSql()函数检测
这里可以设置title为如下代码,一方面绕过ids防注入代码检测,另一方面加一个#注释掉后面的代码,但是还要做一下变形,就是这个char(@`'`)了。因为#@__feedback的所有字段都被设置为NOT NULL,而@`'`是一个变量,默认为NULL,直接插入@`'`的话会报错,所以需要以char(@`'`)的方法转换一下。
后台另类getshell
在后台网站配置处 admin/web_config.php
理论上说有全局过滤应该就不能闭合拿shell了
但是仔细读一下他的流程
先把东西存到数据库- 然后在从数据库中都出来构造字符串写进文件
更新文件的函数
上述代码第13行
有多少单引号也给过滤了
但是下面一个操作
有这样的操作
如果我写两个\\\进去 从数据库出来的时候 还是三个\ 但是
经过上面的操作就只剩下一个\
意思就是
上面的单引号被转移 就跟下面连起来了
再接着/*多行注释就起作用了
很老的一个洞了 还是很值的学习的。
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()函数不能用
1 function CheckSql($sql, $querytype='select') 2 { 3 4 $clean = ''; 5 $error = ''; 6 $pos = -1; 7 $old_pos = 0; 8 9 10 //如果是普通查询语句,直接过滤一些特殊语法 11 if($querytype == 'select') 12 { 13 if(preg_match('/[^0-9a-z@\._-]{1,}(union|sleep|benchmark|load_file|outfile)[^0-9a-z@\.-]{1,}/', $sql)) 14 { 15 $this->DisplayError("$sql||SelectBreak",1); 16 } 17 } 18 19 //完整的SQL检查 20 while(true) 21 { 22 $pos = strpos($sql, '\'', $pos + 1); 23 if($pos === false) 24 { 25 break; 26 } 27 $clean .= substr($sql, $old_pos, $pos - $old_pos); 28 29 while(true) 30 { 31 $pos1 = strpos($sql, '\'', $pos + 1); 32 $pos2 = strpos($sql, '\\', $pos + 1); 33 if($pos1 === false) 34 { 35 break; 36 } 37 else if($pos2 == false || $pos2 > $pos1) 38 { 39 $pos = $pos1; 40 break; 41 } 42 $pos = $pos2 + 1; 43 } 44 45 $clean .= '$s$'; 46 $old_pos = $pos + 1; 47 } 48 49 $clean .= substr($sql, $old_pos); 50 $clean = trim(strtolower(preg_replace(array('~\s+~s' ), array(' '), $clean))); 51 var_dump($clean); 52 53 54 //老版本的Mysql并不支持union,常用的程序里也不使用union,但是一些黑客使用它,所以检查它 55 if(strpos($clean, 'union') !== false && preg_match('~(^|[^a-z])union($|[^[a-z])~s', $clean) != 0) 56 { 57 $fail = true; 58 $error = 'union detect'; 59 } 60 61 //发布版本的程序可能比较少包括--,#这样的注释,但是黑客经常使用它们 62 else if(strpos($clean, '/*') > 2 || strpos($clean, '--') !== false || strpos($clean, '#') !== false) 63 { 64 $fail = true; 65 $error = 'comment detect'; 66 } 67 68 //这些函数不会被使用,但是黑客会用它来操作文件,down掉数据库 69 else if(strpos($clean, 'sleep') !== false && preg_match('~(^|[^a-z])sleep($|[^[a-z])~s', $clean) != 0) 70 { 71 $fail = true; 72 $error = 'slown down detect'; 73 } 74 else if(strpos($clean, 'benchmark') !== false && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s', $clean) != 0) 75 { 76 $fail = true; 77 $error = 'slown down detect'; 78 } 79 else if(strpos($clean, 'load_file') !== false && preg_match('~(^|[^a-z])load_file($|[^[a-z])~s', $clean) != 0) 80 { 81 $fail = true; 82 $error = 'file fun detect'; 83 } 84 else if(strpos($clean, 'into outfile') !== false && preg_match('~(^|[^a-z])into\s+outfile($|[^[a-z])~s', $clean) != 0) 85 { 86 $fail = true; 87 $error = 'file fun detect'; 88 } 89 90 //老版本的MYSQL不支持子查询,我们的程序里可能也用得少,但是黑客可以使用它来查询数据库敏感信息 91 else if(preg_match('~\([^)]*?select~s', $clean) != 0) 92 { 93 $fail = true; 94 $error = 'sub select detect'; 95 } 96 97 if(!empty($fail)) 98 { 99 $this->DisplayError("$sql,$error",1); 100 } 101 else 102 { 103 return $sql; 104 } 105 }
View Code
这是80sec的防sql注入函数
通过跟踪这段代码发现,它有个特征就是会将两个单引号之间的内容用$s$替换,例如’select’会被替换为$s$,这里用两个@`'`包含敏感字,这样$clean变量中就不会出现敏感字,从而绕过CheckSql()函数检测
这里可以设置title为如下代码,一方面绕过ids防注入代码检测,另一方面加一个#注释掉后面的代码,但是还要做一下变形,就是这个char(@`'`)了。因为#@__feedback的所有字段都被设置为NOT NULL,而@`'`是一个变量,默认为NULL,直接插入@`'`的话会报错,所以需要以char(@`'`)的方法转换一下。
后台另类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(); }
更新文件的函数
1 function WriteConfig() 2 { 3 global $dosql, $config_cache; 4 5 //die($config_cache); 6 7 $str = '<?php if(!defined(\'IN_PHPMYWIND\')) exit(\'Request Error!\');'."\r\n\r\n"; 8 $dosql->Execute("SELECT `varname`,`vartype`,`varvalue`,`vargroup` FROM `#@__webconfig` ORDER BY orderid ASC"); 9 while($row = $dosql->GetArray()) 10 { 11 //强制去掉 ' 12 //强制去掉最后一位 / 13 $vartmp = str_replace("'",'',$row['varvalue']); 14 15 if(substr($vartmp, -1) == '\\') 16 { 17 $vartmp = substr($vartmp,1,-1); 18 } 19 20 21 if($row['vartype'] == 'number') 22 { 23 if($row['varvalue'] == '') 24 { 25 $vartmp = 0; 26 } 27 28 $str .= "\${$row['varname']} = ".$vartmp.";\r\n"; 29 } 30 else 31 { 32 $str .= "\${$row['varname']} = '".$vartmp."';\r\n"; 33 } 34 } 35 $str .= '?>'; 36 //die($str); 37 38 if(!Writef($config_cache,$str)) 39 { 40 ShowMsg("变量成功保存,但由于 config.cache.php 无法写入,因此不能更新配置!", 'web_config.php'); 41 exit(); 42 } 43 44 RewriteURL(); 45 }
上述代码第13行
$vartmp = str_replace("'",'',$row['varvalue']);
有多少单引号也给过滤了
但是下面一个操作
//强制去掉最后一位
有这样的操作
如果我写两个\\\进去 从数据库出来的时候 还是三个\ 但是
15 if(substr($vartmp, -1) == '\\')找他的最后一数是不是\ 16 { 17 $vartmp = substr($vartmp,1,-1); 这里的操作是让变量登入字符串从下标为1开始一直到从后面数第二个的 三个\\\就是 下标1 是\ 倒数第二个跟他一样的 18 }
经过上面的操作就只剩下一个\
意思就是
上面的单引号被转移 就跟下面连起来了
再接着/*多行注释就起作用了
很老的一个洞了 还是很值的学习的。
相关文章推荐
- [代码审计]青云客Cms前台有条件注入至getshell,后台xss至getshell、至弹你一脸计算器
- PHPCMS9.6.0最新版SQL注入和前台GETSHELL漏洞分析 (实验新课)
- ThinkSNS2.5前台getshell+后台任意文件删除
- Fresco 源码分析(四) 后台数据返回到前台的处理 - Drawable体系的介绍(3) 遗留任务预览
- 【sql注入教程】mysql注入直接getshell
- dz2.5 后台getweshell
- Typecho反序列化导致前台 getshell 漏洞复现
- Fresco 源码分析(四) 后台数据返回到前台的处理
- UIApplicationDelegateDemo--应用程序前台、后台分析
- Redis (REmote DIctionary Server):初步学习(3)-- 前台与后台打开Redis/简单操作(set/get)
- 说一下linux中shell的后台进程与前台进程
- 【Web】前台传送JSON格式数据到后台Shell处理
- Javaweb架构分析安全之万户ezoffice全版本通杀上传GETSHELL
- SQL另类注入之绕过后台登陆验证
- JQuery ($.get()) 前台传值到后台并调用后台方法
- Discuz!X升级/转换程序GETSHELL漏洞分析
- WP 前台或后台显示ShellToast
- Shell 进程前台与后台转换方法
- Dedecms 后台getshell 5.7 SP2
- 典型电子商务系统前台后台功能分析