Parameter Pollution | JSON Injection
Reading time: 8 minutes
Parameter Pollution
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
HTTP Parameter Pollution (HPP) 개요
HTTP Parameter Pollution (HPP)는 공격자가 HTTP 매개변수를 조작하여 웹 애플리케이션의 동작을 의도하지 않은 방식으로 변경하는 기술입니다. 이 조작은 HTTP 매개변수를 추가, 수정 또는 복제함으로써 이루어집니다. 이러한 조작의 효과는 사용자에게 직접적으로 보이지 않지만, 서버 측에서 애플리케이션의 기능을 상당히 변경할 수 있으며, 클라이언트 측에서 관찰 가능한 영향을 미칠 수 있습니다.
HTTP Parameter Pollution (HPP) 예시
은행 애플리케이션 거래 URL:
- 원본 URL:
https://www.victim.com/send/?from=accountA&to=accountB&amount=10000
추가 from
매개변수를 삽입함으로써:
- 조작된 URL:
https://www.victim.com/send/?from=accountA&to=accountB&amount=10000&from=accountC
거래가 accountA
대신 accountC
에 잘못 청구될 수 있으며, 이는 HPP가 거래 또는 비밀번호 재설정, 2FA 설정, API 키 요청과 같은 다른 기능을 조작할 수 있는 가능성을 보여줍니다.
기술별 매개변수 파싱
- 매개변수가 파싱되고 우선순위가 매겨지는 방식은 기본 웹 기술에 따라 다르며, HPP가 어떻게 악용될 수 있는지에 영향을 미칩니다.
- Wappalyzer와 같은 도구는 이러한 기술과 그 파싱 동작을 식별하는 데 도움을 줍니다.
PHP와 HPP 악용
OTP 조작 사례:
- 맥락: 일회용 비밀번호(OTP)를 요구하는 로그인 메커니즘이 악용되었습니다.
- 방법: Burp Suite와 같은 도구를 사용하여 OTP 요청을 가로채고, 공격자는 HTTP 요청에서
email
매개변수를 복제했습니다. - 결과: 초기 이메일을 위한 OTP가 조작된 요청에서 지정된 두 번째 이메일 주소로 전송되었습니다. 이 결함은 의도된 보안 조치를 우회하여 무단 접근을 허용했습니다.
이 시나리오는 OTP 생성을 위해 첫 번째 email
매개변수를 처리했지만, 전달을 위해 마지막 매개변수를 사용한 애플리케이션의 백엔드에서의 중요한 간과를 강조합니다.
API 키 조작 사례:
- 시나리오: 애플리케이션이 사용자가 프로필 설정 페이지를 통해 API 키를 업데이트할 수 있도록 허용합니다.
- 공격 벡터: 공격자는 POST 요청에 추가
api_key
매개변수를 추가함으로써 API 키 업데이트 기능의 결과를 조작할 수 있음을 발견합니다. - 기술: Burp Suite와 같은 도구를 사용하여 공격자는 하나의 합법적인
api_key
매개변수와 하나의 악의적인api_key
매개변수를 포함하는 요청을 작성합니다. 서버는 마지막 발생만 처리하여 공격자가 제공한 값으로 API 키를 업데이트합니다. - 결과: 공격자는 피해자의 API 기능을 제어하게 되어, 무단으로 개인 데이터에 접근하거나 수정할 수 있습니다.
이 예시는 API 키 관리와 같은 중요한 기능에서 안전한 매개변수 처리가 필요함을 더욱 강조합니다.
매개변수 파싱: Flask vs. PHP
웹 기술이 중복 HTTP 매개변수를 처리하는 방식은 다르며, HPP 공격에 대한 취약성에 영향을 미칩니다:
- Flask: 쿼리 문자열
a=1&a=2
에서a=1
과 같은 첫 번째 매개변수 값을 채택하며, 초기 인스턴스를 후속 중복보다 우선시합니다. - PHP (Apache HTTP Server에서): 반대로, 마지막 매개변수 값을 우선시하여 주어진 예에서
a=2
를 선택합니다. 이 동작은 공격자가 조작한 매개변수를 원본보다 우선시함으로써 HPP 악용을 무심코 촉진할 수 있습니다.
기술별 매개변수 오염
결과는 https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89에서 가져왔습니다.
PHP 8.3.11 및 Apache 2.4.62
- 매개변수 이름의 %00 이후는 무시합니다.
- name[]를 배열로 처리합니다.
- _GET은 GET 메서드를 의미하지 않습니다.
- 마지막 매개변수를 선호합니다.
Ruby 3.3.5 및 WEBrick 1.8.2
- & 및 ; 구분자를 사용하여 매개변수를 분리합니다.
- name[]를 인식하지 않습니다.
- 첫 번째 매개변수를 선호합니다.
Spring MVC 6.0.23 및 Apache Tomcat 10.1.30
- POST RequestMapping == PostMapping & GET RequestMapping == GetMapping.
- POST RequestMapping & PostMapping에서 name[]를 인식합니다.
- name과 name[]가 모두 존재할 경우 name을 선호합니다.
- 매개변수를 연결합니다. 예: first,last.
- POST RequestMapping & PostMapping에서 Content-Type으로 쿼리 매개변수를 인식합니다.
NodeJS 20.17.0 및 Express 4.21.0
- name[]를 인식합니다.
- 매개변수를 연결합니다. 예: first,last.
GO 1.22.7
- name[]를 인식하지 않습니다.
- 첫 번째 매개변수를 선호합니다.
Python 3.12.6 및 Werkzeug 3.0.4 및 Flask 3.0.3
- name[]를 인식하지 않습니다.
- 첫 번째 매개변수를 선호합니다.
Python 3.12.6 및 Django 4.2.15
- name[]를 인식하지 않습니다.
- 마지막 매개변수를 선호합니다.
Python 3.12.6 및 Tornado 6.4.1
- name[]를 인식하지 않습니다.
- 마지막 매개변수를 선호합니다.
JSON Injection
중복 키
obj = {"test": "user", "test": "admin"}
프론트엔드는 첫 번째 발생을 믿을 수 있지만 백엔드는 두 번째 발생의 키를 사용할 수 있습니다.
키 충돌: 문자 잘림 및 주석
특정 문자는 프론트엔드에서 올바르게 해석되지 않지만 백엔드는 이를 해석하고 해당 키를 사용할 수 있습니다. 이는 특정 제한을 우회하는 데 유용할 수 있습니다:
{"test": 1, "test\[raw \x0d byte]": 2}
{"test": 1, "test\ud800": 2}
{"test": 1, "test"": 2}
{"test": 1, "te\st": 2}
이 경우 프론트 엔드는 test == 1
이라고 생각할 수 있고 백엔드는 test == 2
라고 생각할 수 있습니다.
이것은 다음과 같은 값 제한을 우회하는 데에도 사용될 수 있습니다:
{"role": "administrator\[raw \x0d byte]"}
{"role":"administrator\ud800"}
{"role": "administrator""}
{"role": "admini\strator"}
주석 잘라내기 사용
obj = {"description": "Duplicate with comments", "test": 2, "extra": /*, "test": 1, "extra2": */}
여기에서는 각 파서의 직렬 변환기를 사용하여 해당 출력을 볼 것입니다.
Serializer 1 (예: GoLang의 GoJay 라이브러리)은 다음을 생성합니다:
description = "Duplicate with comments"
test = 2
extra = ""
Serializer 2 (예: Java의 JSON-iterator 라이브러리)는 다음을 생성합니다:
description = "Duplicate with comments"
extra = "/*"
extra2 = "*/"
test = 1
또는, 주석을 간단히 사용하는 것도 효과적일 수 있습니다:
obj = {"description": "Comment support", "test": 1, "extra": "a"/*, "test": 2, "extra2": "b"*/}
Java의 GSON 라이브러리:
{ "description": "Comment support", "test": 1, "extra": "a" }
Ruby의 simdjson 라이브러리:
{ "description": "Comment support", "test": 2, "extra": "a", "extra2": "b" }
일관되지 않은 우선순위: 역직렬화 대 직렬화
obj = {"test": 1, "test": 2}
obj["test"] // 1
obj.toString() // {"test": 2}
Float and Integer
숫자
999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
여러 표현으로 디코딩될 수 있습니다. 다음을 포함하여:
999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
9.999999999999999e95
1E+96
0
9223372036854775807
어떤 불일치를 초래할 수 있습니다
References
- https://medium.com/@shahjerry33/http-parameter-pollution-its-contaminated-85edc0805654
- https://github.com/google/google-ctf/tree/master/2023/web-under-construction/solution
- https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89
- https://bishopfox.com/blog/json-interoperability-vulnerabilities
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.