phpmywind getshell

  • A+
所属分类:漏洞时代
摘要

较鸡肋,就看看而已
phpmywind一直也没有修补漏洞,这里有很多方法,我们这里主要使用一个任意无限制注入得到一个管理员账号,后台进行getshell.先说说 80sec-ids 的绕过吧.做代码审计的时候,遇见ids 这个waf的几率还是很高的,今天我就拿phpmywind cms做分析.我们先看看他的代码

较鸡肋,就看看而已
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('/[^[email protected]/._-]{1,}(union|sleep|benchmark|load_file|outfile)[^[email protected]/.-]{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('/[^[email protected]/._-]{1,}(union|sleep|benchmark|load_file|outfile)[^[email protected]/.-]{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(@`'`) 就可以了。

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: