较鸡肋,就看看而已
phpmywind一直也没有修补漏洞,这里有很多方法,我们这里主要使用一个任意无限制注入得到一个管理员账号,后台进行getshell.先说说 80sec-ids 的绕过吧.做代码审计的时候,遇见ids 这个waf的几率还是很高的,今天我就拿phpmywind cms做分析.我们先看看他的代码
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); } } 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))); 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'; } 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'; } 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; } } }
我们来分析.首先我们看传入的 $sql 变量,这一步是我们sql语句进入mysql的最后一步,我们下面看最核心的代码,
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); } } 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; }
这里通过匹配 '/ 确定 最开始 ‘ 两个 单引号的内容(即 通过转义是 '/ 的内容)并且将其中的内容通过 substr()函数 截断下来,再将剩下来的语句进行匹配,所以只要我们将我们需要的语句藏在 两个单引号之间就OK了
藏在两个单引号之间虽然绕过了这个waf,但是我们需要sql语句的正确性, 我们通过资料知道 在mysql 里面,可以用@引入变量,如 @'xxx',@"xxx",@`xxx`等等,大家可以自己写一个脚本 fuzz,其中的xxx为任意字符 ,引入变量初始值都为 NULL,so @`'` @`/'` 变量的默认值是 null ,所以我们 用包含单引号的 @`'` 去包含我们的语句就可以了。有些时候插入 @`'` 会报错,我们用 char(@`'`) 就可以了。
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论