# 경쟁 조건
\
[**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks)를 사용하여 세계에서 가장 **고급** 커뮤니티 도구로 구동되는 **워크플로우를 쉽게 구축** 및 **자동화**하세요.\
오늘 바로 액세스하세요:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
htARTE (HackTricks AWS Red Team Expert)로부터 AWS 해킹을 처음부터 전문가까지 배우세요
HackTricks를 지원하는 다른 방법:
* **회사가 HackTricks에 광고되길 원하거나 PDF로 HackTricks를 다운로드하길 원한다면** [**구독 요금제**](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)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를 팔로우**하세요.
* **HackTricks** 및 **HackTricks Cloud** github 저장소로 **PR 제출**하여 해킹 트릭을 **공유**하세요.
{% hint style="warning" %}
이 기술에 대한 심층적인 이해를 얻으려면 원본 보고서 [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)를 확인하세요.
{% endhint %}
## 경쟁 조건 공격 강화
경쟁 조건을 이용하는 주요 장애물은 **여러 요청이 **동시에 처리되도록** 보장하는 것이며, 이때 **처리 시간에 매우 작은 차이가 있어야 합니다—이상적으로는 1ms 미만**이어야 합니다.
여기서 요청 동기화를 위한 몇 가지 기술을 찾을 수 있습니다:
#### HTTP/2 단일 패킷 공격 대 HTTP/1.1 마지막 바이트 동기화
* **HTTP/2**: 하나의 TCP 연결을 통해 두 개의 요청을 보낼 수 있어 네트워크 지연 영향을 줄입니다. 그러나 서버 측 변동으로 인해 두 개의 요청만으로는 일관된 경쟁 조건 공격이 충분하지 않을 수 있습니다.
* **HTTP/1.1 '마지막 바이트 동기화'**: 20-30개의 요청 대부분을 미리 보내고 작은 조각을 보류한 후 함께 보내어 서버에 동시에 도착하도록 합니다.
**마지막 바이트 동기화 준비**는 다음을 포함합니다:
1. 스트림을 종료하지 않고 최종 바이트를 제외한 헤더 및 본문 데이터를 보냅니다.
2. 초기 전송 후 100ms 일시 중지합니다.
3. Nagle의 알고리즘을 사용하기 위해 TCP\_NODELAY를 비활성화하여 최종 프레임을 일괄 처리합니다.
4. 연결을 미리 준비하기 위해 핑을 보냅니다.
보류된 프레임의 후속 전송은 Wireshark를 통해 단일 패킷으로의 도착을 확인해야 합니다. 이 방법은 일반적으로 RC 공격에 관여하지 않는 정적 파일에는 적용되지 않습니다.
### 서버 아키텍처에 적응
대상의 아키텍처를 이해하는 것이 중요합니다. 프론트엔드 서버는 요청 경로를 다르게 라우팅할 수 있어 시간에 영향을 줄 수 있습니다. 무해한 요청을 통해 선행적인 서버 측 연결 준비를 통해 요청 시간을 정규화할 수 있습니다.
#### 세션 기반 잠금 처리
PHP의 세션 핸들러와 같은 프레임워크는 세션별로 요청을 직렬화하여 취약점을 숨길 수 있습니다. 각 요청에 대해 다른 세션 토큰을 사용하면 이 문제를 우회할 수 있습니다.
#### 속도 또는 리소스 제한 극복
연결을 미리 준비하는 것이 효과적이지 않은 경우, 더미 요청의 홍수를 통해 의도적으로 웹 서버의 속도 또는 리소스 제한 지연을 유발하여 경쟁 조건에 유리한 서버 측 지연을 유도할 수 있습니다.
## 공격 예시
* **Tubo Intruder - HTTP2 단일 패킷 공격 (1 엔드포인트)**: 요청을 **Turbo Intruder**에 보낼 수 있습니다 (`Extensions` -> `Turbo Intruder` -> `Send to Turbo Intruder`), 요청에서 **`%s`**와 같이 브루트 포스할 값을 변경할 수 있습니다. `csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s`와 같이 요청을 변경한 후 드롭다운에서 **`examples/race-single-packer-attack.py`**를 선택하세요:
**다른 값**을 보내려면 클립보드에서 워드리스트를 사용하는 이 코드로 수정할 수 있습니다:
```python
passwords = wordlists.clipboard
for password in passwords:
engine.queue(target.req, password, gate='race1')
```
{% hint style="warning" %}
웹이 HTTP2를 지원하지 않는 경우(`HTTP1.1`만 지원하는 경우) `Engine.BURP2` 대신 `Engine.THREADED` 또는 `Engine.BURP`를 사용하십시오.
{% endhint %}
* **Intruder - HTTP2 단일 패킷 공격(여러 엔드포인트)**: RCE를 트리거하기 위해 1개 엔드포인트로 요청을 보내고 다른 엔드포인트로 여러 요청을 보내야 하는 경우, `race-single-packet-attack.py` 스크립트를 다음과 같이 변경할 수 있습니다:
```python
def queueRequests(target, wordlists):
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
'''
# 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)
```
* **리피터**에서도 Burp Suite의 새로운 '**병렬 그룹으로 전송**' 옵션을 통해 사용할 수 있습니다.
* **한도 초과**의 경우, 그룹에 **같은 요청을 50번** 추가하면 됩니다.
* **연결 워밍**의 경우, 웹 서버의 정적이 아닌 부분에 몇 가지 **요청**을 그룹의 **처음에 추가**할 수 있습니다.
* **한 요청 처리와 다른 요청 처리 사이**의 프로세스를 **지연**시키려면, 2개의 하위 상태 단계에서 **두 요청 사이에 추가 요청을 추가**할 수 있습니다.
* **다중 엔드포인트** RC의 경우, **숨겨진 상태로 이동하는 요청**을 보내고 그 후에 **숨겨진 상태를 이용하는 50개의 요청**을 보내면 됩니다.
### Raw BF
이전 연구 이전에 RC를 유발하기 위해 가능한 빠르게 패킷을 보내려고 시도한 일부 사용된 페이로드입니다.
* **리피터:** 이전 섹션의 예제를 확인하십시오.
* **Intruder**: **Intruder**에 **요청**을 보내고, **옵션 메뉴**에서 **스레드 수를 30**으로 설정하고, **페이로드로는 Null 페이로드**를 선택하고 **30개를 생성**합니다.
* **Turbo Intruder**
```python
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
pipeline=False
)
a = ['Session=','Session=','Session=']
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):
table.add(req)
```
* **Python - asyncio**
```python
import asyncio
import httpx
async def use_code(client):
resp = await client.post(f'http://victim.com', cookies={"session": "asdasdasd"}, data={"code": "123123123"})
return resp.text
async def main():
async with httpx.AsyncClient() as client:
tasks = []
for _ in range(20): #20 times
tasks.append(asyncio.ensure_future(use_code(client)))
# Get responses
results = await asyncio.gather(*tasks, return_exceptions=True)
# Print results
for r in results:
print(r)
# Async2sync sleep
await asyncio.sleep(0.5)
print(results)
asyncio.run(main())
```
## **RC 방법론**
### **한계 초과 / TOCTOU**
이것은 **동작을 수행할 수 있는 횟수를 제한하는 위치**에서 발생하는 **취약점** 중 가장 기본적인 종류입니다. 웹 상점에서 동일한 할인 코드를 여러 번 사용하는 것과 같은 예시가 있습니다. 매우 쉬운 예시는 [**이 보고서**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43)나 [**이 버그**](https://hackerone.com/reports/759247)에서 찾을 수 있습니다.
이 종류의 공격에는 다음과 같은 여러 변형이 있습니다:
* 선물 카드를 여러 번 사용하기
* 제품에 여러 번 평가하기
* 계좌 잔액을 초과하여 현금을 인출하거나 이체하기
* 단일 CAPTCHA 솔루션 재사용하기
* 안티 브루트 포스 속도 제한 우회하기
### **숨겨진 하위 상태**
복잡한 경합 조건을 악용하는 것은 종종 숨겨진 또는 **의도하지 않은 기계 하위 상태**와의 짧은 상호 작용 기회를 활용하는 것을 포함합니다. 다음은 이를 접근하는 방법입니다:
1. **잠재적인 숨겨진 하위 상태 식별**
* 사용자 프로필이나 비밀번호 재설정 프로세스와 같은 중요한 데이터를 수정하거나 상호 작용하는 엔드포인트를 정확히 파악하여 시작합니다. 다음에 집중하세요:
* **저장**: 서버 측 영구 데이터를 조작하는 엔드포인트를 선호하고 데이터를 클라이언트 측에서 처리하는 엔드포인트보다 우선합니다.
* **동작**: 기존 데이터를 변경하는 작업을 찾아서, 새 데이터를 추가하는 것보다 취약한 조건을 만들 가능성이 높습니다.
* **키 지정**: 성공적인 공격은 일반적으로 동일한 식별자(예: 사용자 이름 또는 재설정 토큰)를 기반으로 하는 작업을 포함합니다.
2. **초기 탐색 수행**
* 식별된 엔드포인트를 경합 조건 공격으로 테스트하면 예상 결과와 다른 변화를 관찰합니다. 예상치 못한 응답이나 응용 프로그램 동작의 변경은 취약점을 나타낼 수 있습니다.
3. **취약점 증명**
* 취약점을 악용하기 위해 필요한 요청의 최소한의 수로 공격 범위를 좁힙니다. 이 단계는 정확한 타이밍으로 인해 여러 시도나 자동화가 필요할 수 있습니다.
### **시간 민감한 공격**
요청의 정밀한 타이밍은 취약점을 드러낼 수 있습니다, 특히 보안 토큰에 타임스탬프와 같은 예측 가능한 방법이 사용될 때입니다. 예를 들어, 타임스탬프를 기반으로 비밀번호 재설정 토큰을 생성하면 동시 요청에 대해 동일한 토큰을 허용할 수 있습니다.
**악용 방법:**
* 동시에 비밀번호 재설정 요청을 수행하기 위해 정밀한 타이밍(예: 단일 패킷 공격)을 사용합니다. 동일한 토큰은 취약점을 나타냅니다.
**예시:**
* 동시에 두 개의 비밀번호 재설정 토큰을 요청하고 비교합니다. 일치하는 토큰은 토큰 생성에 결함이 있음을 나타냅니다.
**이를 시도해보려면** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities) **를 확인하세요.**
## **숨겨진 하위 상태 사례 연구**
### **결제 및 항목 추가**
**이 [PortSwigger Lab](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation)를 확인하여** 상점에서 **결제**하고 **추가**할 **항목을 추가**하는 방법을 확인하세요.
### **다른 이메일 확인**
**이메일 주소를 확인하고 동시에 다른 이메일 주소로 변경**하여 플랫폼이 새로운 이메일을 확인하는지 확인하세요.
### **이메일을 2개의 이메일 주소로 변경 쿠키 기반**
[**이 연구**](https://portswigger.net/research/smashing-the-state-machine)에 따르면 Gitlab은 다른 이메일로 이메일 확인 토큰을 **보낼 수 있기 때문에** 이 방법으로 인해 취약했습니다.
**이를 시도해보려면** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) **를 확인하세요.**
### **숨겨진 데이터베이스 상태 / 확인 우회**
**데이터베이스에 정보를 추가하기 위해 2개의 다른 쓰기**가 사용되면 **데이터베이스에는 처음 데이터만 기록된 작은 시간**이 있습니다. 예를 들어, 사용자를 생성할 때 **사용자 이름**과 **비밀번호**가 **기록**되고 **그런 다음** 새로 생성된 계정을 확인하는 **토큰**이 기록됩니다. 이는 잠깐의 시간 동안 **계정을 확인하는 토큰이 null**임을 의미합니다.
따라서 **계정을 등록하고 빈 토큰(`token=` 또는 `token[]=` 또는 다른 변형)을 사용하여 계정을 즉시 확인하는 여러 요청을 보내면** 이메일을 제어하지 않는 상태에서 **계정을 확인**할 수 있습니다.
**이를 시도해보려면** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction) **를 확인하세요.**
### **2단계 인증 우회**
다음 의사 코드는 세션을 생성하는 동안 **2단계 인증이 강제되지 않는** 매우 짧은 시간 동안 경합 조건에 취약합니다:
```python
session['userid'] = user.userid
if user.mfa_enabled:
session['enforce_mfa'] = True
# generate and send MFA code to user
# redirect browser to MFA code entry form
```
### OAuth2 영구 지속성
여러 [**OAUth 제공업체**](https://en.wikipedia.org/wiki/List\_of\_OAuth\_providers)가 있습니다. 이러한 서비스는 고객이 등록한 사용자를 인증하고 응용 프로그램을 만들어 사용자가 제공자의 일부 데이터에 액세스할 수 있도록 허용합니다. 따라서 **클라이언트**는 **응용 프로그램에 액세스할 수 있도록 허용**해야 합니다.\
따라서, 여기까지는 구글/링크드인/깃허브 등과 같은 공통 로그인이며, "_응용 프로그램 \이(가) 귀하의 정보에 액세스하려고 합니다. 허용하시겠습니까?_"라는 페이지가 표시됩니다.
#### `authorization_code`에서의 경쟁 조건
**문제**는 **수락**하고 악의적인 응용 프로그램으로 **`authorization_code`**를 자동으로 전송할 때 발생합니다. 그런 다음, 이 **응용 프로그램은 OAUth 서비스 제공업체의 경쟁 조건을 악용하여 귀하의 계정에 대해 **`authorization_code`**로부터 여러 AT/RT** (_인증 토큰/새로 고침 토큰_)을 생성합니다. 기본적으로 귀하가 응용 프로그램이 데이터에 액세스할 수 있도록 허용했다는 사실을 악용하여 **여러 계정을 생성**합니다. 그런 다음, **응용 프로그램에 데이터 액세스를 허용하는 것을 중지하면 한 쌍의 AT/RT가 삭제되지만 다른 것들은 여전히 유효**합니다.
#### `Refresh Token`에서의 경쟁 조건
한 번 **유효한 RT를 획득하면** 여러 AT/RT를 생성하려고 시도할 수 있으며, 심지어 사용자가 악의적인 응용 프로그램이 데이터에 액세스하는 권한을 **취소해도 여러 RT가 여전히 유효**할 수 있습니다.
## **웹소켓에서의 RC**
[**WS\_RaceCondition\_PoC**](https://github.com/redrays-io/WS\_RaceCondition\_PoC)에서 **Java로 웹소켓 메시지를 병렬로 보내는** RC를 악용할 수 있는 PoC를 찾을 수 있습니다.
## 참고 자료
* [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)
htARTE (HackTricks AWS Red Team Expert)를 통해 **제로부터 영웅까지의 AWS 해킹을 배우세요**!
HackTricks를 지원하는 다른 방법:
* **회사를 HackTricks에서 광고**하거나 **PDF로 HackTricks 다운로드**하려면 [**구독 요금제**](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) 컬렉션
* 💬 [**디스코드 그룹**](https://discord.gg/hRep4RUj7f) 또는 [**텔레그램 그룹**](https://t.me/peass)에 **가입**하거나 **트위터** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**를** 팔로우하세요.
* **HackTricks** 및 **HackTricks Cloud** 깃허브 저장소에 PR을 제출하여 **해킹 트릭을 공유**하세요.
\
[**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks)를 사용하여 세계에서 가장 **고급** 커뮤니티 도구를 활용한 **워크플로우를 쉽게 구축하고 자동화**하세요.\
오늘 바로 액세스하세요:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}