1. 首页
  2. 代码审计

php代码审计学习函数缺陷(二)

正则使用不当导致的路径穿越问题

Frost Pattern

  • code
class TokenStorage {
  public function performAction($action, $data) {
    switch ($action) {
      case 'create':
        $this->createToken($data);
        break;
      case 'delete':
        $this->clearToken($data);
        break;
      default:
        throw new Exception('Unknown action');
    }
  }

  public function createToken($seed) {
    $token = md5($seed);
    file_put_contents('/tmp/tokens/' . $token, '...data');
  }

  public function clearToken($token) {
    $file = preg_replace("/[^a-z.-_]/", "", $token);
    unlink('/tmp/tokens/' . $file);
  }
}

$storage = new TokenStorage();
$storage->performAction($_GET['action'], $_GET['data']);
  • preg_replace(函数执行一个正则表达式的搜索和替换)
  • payload

$action = $delete$data = ../../config.php

WeEngine0.8

  • web/source/site/category.ctrl.php:176

file_delete文件删除函数

php代码审计学习函数缺陷(二)
  • framework/function/file.func.php:294

查看file_delete函数

php代码审计学习函数缺陷(二)
  • 追朔$file变量从何而来
if (!empty($navs)) {
        foreach ($navs as $row) {
            file_delete($row['icon']);
        }
  • 追朔$navs从何而来
    $navs = pdo_fetchall("SELECT icon, id FROM ".tablename('site_nav')." WHERE id IN (SELECT nid FROM ".tablename('site_category')." WHERE id = {$id} OR parentid = '$id')", array(), 'id');
  • web/source/site/category.ctrl.php:137

php代码审计学习函数缺陷(二)
  • web/source/site/category.ctrl.php:130

php代码审计学习函数缺陷(二)

$nav[‘icon’] 即为文件删除函数的参

parse_str函数缺陷

  • parse_str
parse_str的作用就是解析字符串并且注册成变量,它在注册变量之前不会验证当前变量是否存在,所以会直接覆盖掉当前作用域中原有的变量。

php代码审计学习函数缺陷(二)

preg_replace函数之命令执行

Candle

  • code
header("Content-Type: text/plain");

function complexStrtolower($regex, $value) {
  return preg_replace(
    '/(' . $regex . ')/ei',
    'strtolower("\\1")',
    $value
  );
}

foreach ($_GET as $regex => $value) {
  echo complexStrtolower($regex, $value) . "\n";
}
  • preg_replace(函数执行一个正则表达式的搜索和替换)
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

$pattern 存在 /e 模式修正符,允许代码执行
/e 模式修正符,是 preg_replace() 将 $replacement 当做php代码来执行

将GET请求传过来的参数通过complexStrtolower函数执行,preg_replace函数存在e修正符

  • payload
S*=${phpinfo()} 

参考

深入研究preg_replace与代码执行

CmsEasy 5.5

  • 环境搭建

php代码审计学习函数缺陷(二)

漏洞分析

  • lib/tool/form.php:90

如果$form[$name][‘default’]内容被匹配到就会执行eval

php代码审计学习函数缺陷(二)
  • cache/template/default/manage/#guestadd.php:175

全局搜索getform,主要注意catid是作为$name的

php代码审计学习函数缺陷(二)
  • lib/table/archive.php:25

追朔catid,寻找到default

php代码审计学习函数缺陷(二)
  • lib/tool/front_class.php:2367

php代码审计学习函数缺陷(二)
  • lib/tool/front_class.php:493

php代码审计学习函数缺陷(二)
  • lib/tool/front_class.php:332

$form[$name][‘default’]可控

php代码审计学习函数缺陷(二)
  • lib/default/manage_act.php:29

php代码审计学习函数缺陷(二)
  • 测试

php代码审计学习函数缺陷(二)

str_replace函数过滤不当

Rabbit

  • code
class LanguageManager {
  public function loadLanguage() {
    $lang = $this->getBrowserLanguage();
    $sanitizedLang = $this->sanitizeLanguage($lang);
    require_once("/lang/$sanitizedLang");
  }

  private function getBrowserLanguage() {
    $lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? 'en';
    return $lang;
  }

  private function sanitizeLanguage($language) {
    return str_replace('../', '', $language);
  }
}

(new LanguageManager())->loadLanguage();
  • str_replace(子字符串替换)
str_replace(字符串1,字符串2,字符串3):将字符串3中出现的所有字符串1换成字符串2。

str_replace(数组1,字符串1,字符串2):将字符串2中出现的所有数组1中的值,换成字符串1。

str_replace(数组1,数组2,字符串1):将字符串1中出现的所有数组1一一对应,替换成数组2的值,多余的替换成空字符串。
  • payload
....// 或者 ..././ 

Metinfo 6.0.0

  • strstr
查找字符串的首次出现到结尾的字符串

php代码审计学习函数缺陷(二)

漏洞分析

  • app/system/include/module/old_thumb.class.php:14

php代码审计学习函数缺陷(二)
  • include/thumb.php:6

全局搜索

php代码审计学习函数缺陷(二)
  • app/system/include/class/load.class.php:113

php代码审计学习函数缺陷(二)
  • payload
http://localhost/metInfo/include/thumb.php?dir=.....///http/.....///最终用户授权许可协议.txt

程序未恰当exit导致的问题

Anticipation

  • code
extract($_POST);

function goAway() {
  error_log("Hacking attempt.");
  header('Location: /error/');
}

if (!isset($pi) || !is_numeric($pi)) {
  goAway();
}

if (!assert("(int)$pi == 3")) {
  echo "This is not pi.";
} else {
  echo "This might be pi.";
}
  • extract
从数组中将变量导入到当前的符号表

php代码审计学习函数缺陷(二)
  • payload
pl=phpinfo()
  • 测试

php代码审计学习函数缺陷(二)

FengCms 1.32

  • install/index.php

如果安装完成会生成INSTALL文件,访问文件如果存在此文件则会弹窗提示退出,但没有及时exit,导致程序逻辑还是往下走,还是会安装

php代码审计学习函数缺陷(二)

Simple-Log1.6网站重装漏洞

  • install/index.php

访问文件如果存在此文件则会弹窗提示退出,但没有及时exit,只是跳转到首页,导致程序逻辑还是往下走,还是会安装

php代码审计学习函数缺陷(二)

Tips整理

  • parse_str
parse_str的作用就是解析字符串并且注册成变量,它在注册变量之前不会验证当前变量是否存在,所以会直接覆盖掉当前作用域中原有的变量
  • preg_replace
$pattern 存在 /e 模式修正符,允许代码执行
/e 模式修正符,是 preg_replace() 将 $replacement 当做php代码来执行
  • extract
从数组中将变量导入到当前的符号表
  • 尾声

本系列是弟弟跟着红日安全产出的代码审计教程系列学习的,原项目地址:[PHP-Audit-Labs]

(https://github.com/hongriSec/PHP-Audit-Labs)

原创文章,作者:syst1m,未经授权禁止转载!如若转载,请联系作者:syst1m

联系我们

在线咨询:点击这里给我发消息

QR code