Race Condition
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F311514708-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F1ImEu59kE9yiIA7SmB7z%252Fuploads%252Fgit-blob-78abb7891633b1e8147b4e743e4f00af375d3cd6%252Fimage%2520%2848%29.png%3Falt%3Dmedia&width=768&dpr=4&quality=100&sign=bbc817c8&sv=1)
Trickest를 사용하여 세계에서 가장 진보된 커뮤니티 도구로 구동되는 워크플로우를 쉽게 구축하고 자동화하세요. 지금 바로 액세스하세요:
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:
HackTricks Training GCP Red Team Expert (GRTE)
이 기술에 대한 깊은 이해를 얻으려면 https://portswigger.net/research/smashing-the-state-machine에서 원본 보고서를 확인하세요.
레이스 조건 공격 강화
레이스 조건을 이용하는 데 있어 주요 장애물은 여러 요청이 동시에 처리되도록 보장하는 것입니다. 처리 시간의 차이가 매우 적어야 하며, 이상적으로는 1ms 미만이어야 합니다.
여기 요청 동기화를 위한 몇 가지 기술이 있습니다:
HTTP/2 단일 패킷 공격 vs. HTTP/1.1 마지막 바이트 동기화
HTTP/2: 단일 TCP 연결을 통해 두 개의 요청을 전송할 수 있어 네트워크 지터의 영향을 줄입니다. 그러나 서버 측 변동으로 인해 두 개의 요청만으로는 일관된 레이스 조건 공격이 불가능할 수 있습니다.
HTTP/1.1 '마지막 바이트 동기화': 20-30개의 요청의 대부분을 미리 전송하고, 작은 조각을 보류한 후 함께 전송하여 서버에 동시에 도착하도록 합니다.
마지막 바이트 동기화를 위한 준비는 다음과 같습니다:
스트림을 종료하지 않고 마지막 바이트를 제외한 헤더와 본문 데이터를 전송합니다.
초기 전송 후 100ms 동안 일시 중지합니다.
TCP_NODELAY를 비활성화하여 Nagle의 알고리즘을 사용하여 최종 프레임을 배치합니다.
연결을 준비하기 위해 핑을 보냅니다.
보류된 프레임을 이후에 전송하면 단일 패킷으로 도착해야 하며, 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
**를 선택합니다:
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F311514708-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F1ImEu59kE9yiIA7SmB7z%252Fuploads%252Fgit-blob-8cd1f020d1b5cfab09adf86a200587442cd7cd8d%252Fimage%2520%2857%29.png%3Falt%3Dmedia&width=768&dpr=4&quality=100&sign=84a180fd&sv=1)
다른 값을 보내려면, 클립보드에서 단어 목록을 사용하는 이 코드로 수정할 수 있습니다:
웹이 HTTP2를 지원하지 않는 경우(오직 HTTP1.1만 지원) Engine.THREADED
또는 Engine.BURP
를 Engine.BURP2
대신 사용하세요.
Tubo Intruder - HTTP2 단일 패킷 공격 (여러 엔드포인트): RCE를 트리거하기 위해 1개의 엔드포인트에 요청을 보내고 그 후 여러 엔드포인트에 요청을 보내야 하는 경우,
race-single-packet-attack.py
스크립트를 다음과 같이 변경할 수 있습니다:
Burp Suite의 새로운 '병렬로 그룹 전송' 옵션을 통해 Repeater에서도 사용할 수 있습니다.
limit-overrun의 경우, 그룹에 같은 요청을 50번 추가하면 됩니다.
connection warming을 위해, 그룹의 시작 부분에 웹 서버의 비정적 부분에 대한 요청을 추가할 수 있습니다.
지연을 위해 하나의 요청과 다른 요청 간의 처리 사이에 2단계 하위 상태에서 추가 요청을 추가할 수 있습니다.
다중 엔드포인트 RC의 경우, 숨겨진 상태로 가는 요청을 먼저 보내고, 그 뒤에 숨겨진 상태를 악용하는 50개의 요청을 보낼 수 있습니다.
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F311514708-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F1ImEu59kE9yiIA7SmB7z%252Fuploads%252Fgit-blob-b38f1e7c33a457a514f7c74612639d5252f62631%252Fimage%2520%2858%29.png%3Falt%3Dmedia&width=768&dpr=4&quality=100&sign=4bcc10d5&sv=1)
자동화된 파이썬 스크립트: 이 스크립트의 목표는 사용자의 이메일을 변경하면서 새로운 이메일의 확인 토큰이 마지막 이메일로 도착할 때까지 지속적으로 확인하는 것입니다(이는 코드에서 이메일을 수정할 수 있는 RC가 발견되었지만 확인이 이전 이메일로 전송되도록 이미 첫 번째 이메일로 채워진 변수가 있었기 때문입니다). "objetivo"라는 단어가 수신된 이메일에서 발견되면 변경된 이메일의 확인 토큰을 수신한 것이며 공격을 종료합니다.
Improving Single Packet Attack
원래 연구에서는 이 공격이 1,500 바이트의 한계를 가지고 있다고 설명합니다. 그러나 이 게시물에서는 IP 레이어 분할을 사용하여 단일 패킷 공격의 1,500 바이트 제한을 TCP의 65,535 B 윈도우 제한으로 확장하는 방법이 설명되었습니다(단일 패킷을 여러 IP 패킷으로 나누고 서로 다른 순서로 전송하여 모든 조각이 서버에 도달할 때까지 패킷 재조립을 방지함). 이 기술을 통해 연구자는 약 166ms 만에 10,000개의 요청을 보낼 수 있었습니다.
이 개선이 수백/수천 개의 패킷이 동시에 도착해야 하는 RC에서 공격을 더 신뢰할 수 있게 만들지만, 일부 소프트웨어 제한이 있을 수 있다는 점에 유의하십시오. Apache, Nginx 및 Go와 같은 일부 인기 있는 HTTP 서버는 각각 100, 128 및 250으로 설정된 엄격한 SETTINGS_MAX_CONCURRENT_STREAMS
설정을 가지고 있습니다. 그러나 NodeJS 및 nghttp2와 같은 다른 서버는 무제한입니다.
이는 기본적으로 Apache가 단일 TCP 연결에서 100개의 HTTP 연결만 고려한다는 것을 의미합니다(이 RC 공격을 제한함).
이 기술을 사용하는 몇 가지 예는 레포지토리 https://github.com/Ry0taK/first-sequence-sync/tree/main에서 찾을 수 있습니다.
Raw BF
이전 연구 이전에 RC를 유발하기 위해 패킷을 가능한 한 빠르게 전송하려고 시도한 몇 가지 페이로드가 있었습니다.
Repeater: 이전 섹션의 예를 확인하십시오.
Intruder: Intruder에 요청을 보내고, 옵션 메뉴에서 스레드 수를 30으로 설정하고, 페이로드로 Null payloads를 선택하고 30을 생성합니다.
Turbo Intruder
파이썬 - asyncio
RC Methodology
Limit-overrun / TOCTOU
이것은 행동을 수행할 수 있는 횟수를 제한하는 곳에서 발생하는 취약점의 가장 기본적인 유형입니다. 예를 들어, 웹 상점에서 동일한 할인 코드를 여러 번 사용하는 경우입니다. 매우 쉬운 예는 이 보고서 또는 이 버그에서 찾을 수 있습니다.
이러한 종류의 공격에는 여러 가지 변형이 있습니다:
기프트 카드를 여러 번 사용하기
제품에 대해 여러 번 평가하기
계좌 잔액을 초과하여 현금을 인출하거나 이체하기
단일 CAPTCHA 솔루션 재사용하기
반 브루트 포스 속도 제한 우회하기
Hidden substates
복잡한 레이스 조건을 악용하는 것은 종종 숨겨진 또는 의도하지 않은 기계 하위 상태와 상호작용할 수 있는 짧은 기회를 이용하는 것을 포함합니다. 접근 방법은 다음과 같습니다:
잠재적 숨겨진 하위 상태 식별
사용자 프로필이나 비밀번호 재설정 프로세스와 같은 중요한 데이터를 수정하거나 상호작용하는 엔드포인트를 파악하는 것부터 시작합니다. 다음에 집중하세요:
저장소: 클라이언트 측 데이터를 처리하는 것보다 서버 측 지속 데이터를 조작하는 엔드포인트를 선호합니다.
작업: 기존 데이터를 변경하는 작업을 찾습니다. 이는 새로운 데이터를 추가하는 것보다 악용 가능한 조건을 생성할 가능성이 더 높습니다.
키잉: 성공적인 공격은 일반적으로 동일한 식별자(예: 사용자 이름 또는 재설정 토큰)에 키가 지정된 작업을 포함합니다.
초기 탐색 수행
식별된 엔드포인트에 대해 레이스 조건 공격을 테스트하고 예상 결과와의 편차를 관찰합니다. 예상치 못한 응답이나 애플리케이션 동작의 변화는 취약점을 신호할 수 있습니다.
취약점 입증
취약점을 악용하는 데 필요한 최소한의 요청 수로 공격을 좁힙니다. 종종 두 개의 요청만 필요합니다. 이 단계는 정밀한 타이밍이 필요하기 때문에 여러 번의 시도나 자동화가 필요할 수 있습니다.
시간 민감 공격
요청의 타이밍을 정밀하게 조정하면 취약점을 드러낼 수 있습니다. 특히 보안 토큰에 타임스탬프와 같은 예측 가능한 방법이 사용될 때 그렇습니다. 예를 들어, 타임스탬프를 기반으로 비밀번호 재설정 토큰을 생성하면 동시에 요청에 대해 동일한 토큰이 허용될 수 있습니다.
악용 방법:
단일 패킷 공격과 같은 정밀한 타이밍을 사용하여 동시 비밀번호 재설정 요청을 합니다. 동일한 토큰은 취약점을 나타냅니다.
예시:
두 개의 비밀번호 재설정 토큰을 동시에 요청하고 비교합니다. 일치하는 토큰은 토큰 생성의 결함을 나타냅니다.
이것을 확인하세요 PortSwigger Lab 에서 시도해 보세요.
Hidden substates 사례 연구
Pay & add an Item
이 PortSwigger Lab를 확인하여 상점에서 지불하고 추가 아이템을 추가하는 방법을 알아보세요. 지불할 필요가 없습니다.
Confirm other emails
아이디어는 이메일 주소를 확인하고 동시에 다른 이메일로 변경하여 플랫폼이 변경된 새 이메일을 확인하는지 알아보는 것입니다.
Change email to 2 emails addresses Cookie based
이 연구에 따르면 Gitlab은 이 방법으로 인수 공격에 취약했습니다. 왜냐하면 하나의 이메일의 이메일 확인 토큰을 다른 이메일로 보낼 수 있기 때문입니다.
이것을 확인하세요 PortSwigger Lab 에서 시도해 보세요.
Hidden Database states / Confirmation Bypass
데이터베이스에 정보를 추가하기 위해 2개의 서로 다른 쓰기가 사용되면, 첫 번째 데이터만 데이터베이스에 기록된 짧은 시간이 있습니다. 예를 들어, 사용자를 생성할 때 사용자 이름과 비밀번호가 기록되고 새로 생성된 계정을 확인하기 위한 토큰이 기록됩니다. 이는 짧은 시간 동안 계정을 확인하기 위한 토큰이 null임을 의미합니다.
따라서 계정을 등록하고 빈 토큰(token=
또는 token[]=
또는 기타 변형)을 사용하여 즉시 계정을 확인하기 위한 여러 요청을 보내면 이메일을 제어하지 않는 계정을 확인할 수 있습니다.
이것을 확인하세요 PortSwigger Lab 에서 시도해 보세요.
Bypass 2FA
다음 의사 코드는 레이스 조건에 취약합니다. 왜냐하면 세션이 생성되는 동안 2FA가 적용되지 않는 매우 짧은 시간이 있기 때문입니다:
OAuth2 영구 지속성
여러 OAUth 제공자가 있습니다. 이러한 서비스는 애플리케이션을 생성하고 제공자가 등록한 사용자를 인증할 수 있게 해줍니다. 이를 위해 클라이언트는 귀하의 애플리케이션이 OAUth 제공자 내의 일부 데이터에 접근할 수 있도록 허용해야 합니다. 여기까지는 구글/링크드인/깃허브 등으로 로그인하는 일반적인 과정으로, "애플리케이션 <InsertCoolName>이 귀하의 정보에 접근하고자 합니다. 허용하시겠습니까?"라는 페이지가 표시됩니다.
authorization_code
의 경쟁 조건
authorization_code
의 경쟁 조건문제는 귀하가 허용할 때 발생하며, 악의적인 애플리케이션에 **authorization_code
**가 자동으로 전송됩니다. 그런 다음 이 **애플리케이션은 OAUth 서비스 제공자의 경쟁 조건을 악용하여 귀하의 계정에 대해 **authorization_code
로부터 여러 개의 AT/RT (인증 토큰/리프레시 토큰)를 생성합니다. 기본적으로, 애플리케이션이 귀하의 데이터에 접근하도록 허용한 사실을 악용하여 여러 계정을 생성합니다. 그런 다음, 귀하가 애플리케이션이 귀하의 데이터에 접근하는 것을 중지하면 한 쌍의 AT/RT가 삭제되지만, 다른 것들은 여전히 유효합니다.
Refresh Token
의 경쟁 조건
Refresh Token
의 경쟁 조건유효한 RT를 얻은 후, 여러 개의 AT/RT를 생성하기 위해 악용할 수 있으며, 사용자가 악의적인 애플리케이션이 자신의 데이터에 접근하는 권한을 취소하더라도, 여러 RT는 여전히 유효합니다.
웹소켓의 RC
WS_RaceCondition_PoC에서 웹소켓의 경쟁 조건을 악용하기 위해 병렬로 웹소켓 메시지를 전송하는 Java PoC를 찾을 수 있습니다.
참고 문헌
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:
HackTricks Training GCP Red Team Expert (GRTE)
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F311514708-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252F1ImEu59kE9yiIA7SmB7z%252Fuploads%252Fgit-blob-78abb7891633b1e8147b4e743e4f00af375d3cd6%252Fimage%2520%2848%29.png%3Falt%3Dmedia&width=768&dpr=4&quality=100&sign=bbc817c8&sv=1)
Trickest를 사용하여 세계에서 가장 진보된 커뮤니티 도구로 워크플로우를 쉽게 구축하고 자동화하세요. 오늘 바로 접근하세요:
Last updated