Java RASP是基於Java Agent技術實現的,而Java Agent程式碼無法獨立啟動,必須依賴於一個Java執行時程式才能執行。 如何偵錯一個Java Agent可以參考之前的一篇推文:如何 debug JRASP Agent程式碼
在RASP開發的中後期,則需要在真實的Web伺服器上測試。通常這些Java應用程式都執行在遠端裝置上,開發者本地不具備這樣的環境。所以我們需要遠端偵錯一個真實的Java應用,來解決bug或者驗證RASP的防護效果。下面將以tomcat為例,介紹如何偵錯一個應用於遠端Java應用的RASP程式。
tomcat啟動指令碼目錄:${tomcat安裝目錄}/bin
${tomcat安裝目錄}/bin/catalina.sh
${tomcat安裝目錄}/bin/catalina.bat
/usr/web/apache-tomcat-9.0.0.M1/bin/catalina.sh
修改tomcat啟動指令碼,新增啟動引數。將剛剛複製的JVM啟動引數以如下的方式新增至catalina.sh的最前面:
Linux:
export JAVA_OPTS='-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005'
windows
set JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
e.g
儲存修改後的指令碼
選擇剛剛新建的遠端JVM偵錯設定並啟動
如果顯示連線成功,則表示雙機偵錯通道已經建立。
如果顯示連線失敗或者連線超時,則需要排查原因:
檢查雙機是否可以ping通。
檢查遠端機器上的目標Java應用是否正確地監聽在偵錯埠號上。可以使用如下命令:
lsof -i:埠號
通常遠端伺服器都設定了防火牆或者安全組,此時需要放開該偵錯埠號。
檢視所有Java應用程式pid:
jps
進入到jrasp安裝目錄
cd /usr/local/jrasp/bin
手動注入jrasp
./jrasp.sh -p pid
斷點觸發與否主要是基於所要測試的程式碼和斷點位置。一般來說,如果斷點設定在AgentMain入口處,則jrasp注入的時候,IDEA即可捕獲斷點。
如果需要偵錯的程式碼和AgentMain函數不在一個模組中,則需要針對性的觸發。雙機偵錯建立之後,可能IDEA並未捕獲斷點,這是因為目前偵錯的RASP模組還未被執行。
此時需要針對性的觸發斷點。舉兩個例子:
RASP是依賴目標Java程序的,所以RASP的遠端偵錯也是基於Java應用的遠端偵錯。比如說偵錯Tomcat上的RASP,要先在Tomcat的JVM啟動引數中新增遠端偵錯的設定,RASP注入後,RASP的程式碼將作為Tomcat的一部分被JVM執行,可遠端偵錯Tomcat即可遠端偵錯RASP。補充一點,偵錯時無需Tomcat原始碼,在RASP的程式碼中設定斷點,IDEA將自動捕獲。但是,RASP大多時候需要hook Tomcat的API,如果無法精準地知道API及其函數描述,可以利用maven中新增對應的tomcat版本的依賴包,上述的遠端偵錯技巧也可以定位到相關的tomcat原始碼中,這樣子在偵錯堆疊中,既可以看RASP的程式碼,也可以看JDK原始碼和tomcat原始碼,偵錯過程更加清晰。