[WMCTF2020]Make PHP Great Again 2.0

require_once 表达式和 require 表达式完全相同,唯一区别是 PHP 会检查该文件是否已经被包含过,如果是则不会再次包含。

由于 require_once 包含的软链接层数较多时 once 的 hash 匹配会直接失效造成重复包含。

php特性

[SWPU2019]Web4

打开页面发现一个登录框,输入账号和密码后没有反应

我们f12打开页面源码,发现js代码

image-20240908201027925

js主要功能是将username和password以json格式然后发给index.php?r=Login/Login。

我们进行抓包

sql注入json

[GWCTF 2019]mypassword(xss)

打开题目,后先查看源码有没有什么有用的东西,发现了login.php、register.php以及login.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//login.js
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split('; ');
var cookie = {};
for (var i = 0; i < cookies.length; i++) {
var arr = cookies[i].split('=');
var key = arr[0];
cookie[key] = arr[1];
}
if(typeof(cookie['user']) != "undefined" && typeof(cookie['psw']) != "undefined"){
document.getElementsByName("username")[0].value = cookie['user'];
document.getElementsByName("password")[0].value = cookie['psw'];
}
}

代码会把cookie中的username和password填进当前表单

注册登录,根据题目提示这应该不是sql注入题目

xss

[RoarCTF 2019]Online Proxy

http://t.csdnimg.cn/hrdF4

我们f12看到页面源码

image-20240906200203907

我们测试一下,先输入 1’ or ‘1 此时我们的current IP就等于它,让后我们再随便换一个其他的东西,只要和刚才那个不一样就可以,比如111,那么我们的current IP就成了:111,而last IP就是1’ or ‘1,此时1’ or ‘1已经写入了数据库 .因为第一次和第二次传输的IP不一样,所以服务器并不会从数据库找last IP,它会把上次的IP(1’or ‘1)直接显示为last IP,让后存入数据库。那么我们再传一次111,因为和currnet IP相同,那么last IP就会从数据库里寻找,也就是会执行1’or‘1,结果为一。

题解sql注入

[EIS 2019]EzPOP

我们查看源码

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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?php
error_reporting(0);

class A {

protected $store;

protected $key;

protected $expire;

public function __construct($store, $key = 'flysystem', $expire = null) {
$this->key = $key;
$this->store = $store;
$this->expire = $expire;
}

public function cleanContents(array $contents) {
$cachedProperties = array_flip([
'path', 'dirname', 'basename', 'extension', 'filename',
'size', 'mimetype', 'visibility', 'timestamp', 'type',
]);

foreach ($contents as $path => $object) {
if (is_array($object)) {
$contents[$path] = array_intersect_key($object, $cachedProperties);
}
}

return $contents;
}

public function getForStorage() {
$cleaned = $this->cleanContents($this->cache);

return json_encode([$cleaned, $this->complete]);
}

public function save() {
$contents = $this->getForStorage();

$this->store->set($this->key, $contents, $this->expire);
}

public function __destruct() {
if (!$this->autosave) {
$this->save();
}
}
}

class B {

protected function getExpireTime($expire): int {
return (int) $expire;
}

public function getCacheKey(string $name): string {
return $this->options['prefix'] . $name;
}

protected function serialize($data): string {
if (is_numeric($data)) {
return (string) $data;
}

$serialize = $this->options['serialize'];

return $serialize($data);
}

public function set($name, $value, $expire = null): bool{
$this->writeTimes++;

if (is_null($expire)) {
$expire = $this->options['expire'];
}

$expire = $this->getExpireTime($expire);
$filename = $this->getCacheKey($name);

$dir = dirname($filename);

if (!is_dir($dir)) {
try {
mkdir($dir, 0755, true);
} catch (\Exception $e) {
// 创建失败
}
}

$data = $this->serialize($value);

if ($this->options['data_compress'] && function_exists('gzcompress')) {
//数据压缩
$data = gzcompress($data, 3);
}

$data = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
$result = file_put_contents($filename, $data);

if ($result) {
return true;
}

return false;
}

}

if (isset($_GET['src']))
{
highlight_file(__FILE__);
}

$dir = "uploads/";

if (!is_dir($dir))
{
mkdir($dir);
}
unserialize($_GET["data"]);

进行代码审计,我们发现A类的调用关系为__destruct->save()->getForStorage->cleanContents
然后再进行到save()中的$this->store->set($this->key, $contents, $this->expire);

题解反序列化

http://t.csdnimg.cn/21MYs

web351

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
//初始化一个cURL会话
$ch=curl_init($url);
//设定返回信息中包含响应信息头
curl_setopt($ch, CURLOPT_HEADER, 0);
//启用时会将头文件的信息作为数据流输出。
//参数为1表示输出信息头,为0表示不输出

//设定curl_exec()函数将响应结果返回,而不是直接输出
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//参数为1表示$result,为0表示echo $result

//执行一个cURL会话
$result=curl_exec($ch);
//关闭一个curl会话
curl_close($ch);
//输出返回信息 如果CURLOPT_RETURNTRANSFER参数为fasle可省略
echo ($result);
?>
ssrfctfshow