[하루한줄] CVE-2021-44790: Apache에서 발견된 integer underflow 코드 실행 취약점

URL

CVE-2021-44790: CODE EXECUTION ON APACHE VIA AN INTEGER UNDERFLOW

Target

  • Apache HTTP Server 2.4.52 미만 버전

Explain

Apache httpd의 mod_lua 모듈에서 integer underflow 취약점이 발견되었습니다. 해당 취약점은 Lua 스크립트의 r:parsebody() 함수를 통해 호출되는 모듈의 multipart parser request body에 대한 부적절한 유효성 검사를 통해 발생합니다.

Apache HTTP 서버의 공식 플러그인 모듈 중 하나인 mod_lua 모듈은 HTTP 서버의 extension으로 Lua 스크립트를 사용할 수 있게 만들어줍니다. mod_lua 모듈의 함수 중 하나인 r:parsebody()는 Lua 스크립트가 서버로 보낸 HTTP POST request의 body를 파싱합니다. 해당 함수를 사용하면 body에서 파싱된 매개 변수의 이름과 값을 두 개의 Lua 테이블로 return 합니다.

r:parsebody()가 파싱된 Lua 스크립트 내에서 호출되면 req_parsebody()가 호출됩니다. 해당 함수는 multipart/form-data; boundary=" 문자열로 시작하는 Content-Type 헤더를 확인하여 request body가 multipart/form-data로 인코딩 되어 있는지 확인합니다. 해당 문자열이 존재하면 ContentType 헤더에 정의된 boundary string을 검색한 후 multipart variable에 저장합니다. multipart string을 각각 매치한 후 두 번 연속으로 CRFL squence가 발생하는 첫 지점을 찾아 CRLF variable에 저장합니다. CRLF squence를 찾아 값을 저장한 경우 다른 multipart variable 발생 지점을 찾아 form element data의 끝을 나타내는 end variable을 저장합니다.

그 후 end variable의 값에서 CRLF variable과 8을 빼서 form element data를 계산한 다음 size_t 타입의 vlen 변수에 저장하여 memcpy()를 통해 vlen 만큼 버퍼에 복사합니다. 하지만 이 때 form element의 잘못된 포맷으로 인해 두 개의 CRLF 시퀀스 이후 글자의 수가 8개 미만일 경우 값이 음수 값이 되어 integer overflow가 발생합니다. 계산 값이 -1일 경우 szie_t의 최대 크기 + 1의 힙이 할당되어 integer overflow를 통해 크기가 0인 버퍼가 할당됩니다.

해당 취약점을 통해 multipart/form-data content-type으로 인코딩한 조작된 HTTP POST request를 전송하여 서버 프로세스 보안 컨텍스트에서의 원격 코드 실행이 가능하며 RCE에 실패할 경우 DoS가 발생할 수 있습니다.

POST /example.lua HTTP/1.1 
Accept-Encoding: identity 
Content-Length: 1082 
Host: apache.local:80 
Content-Type: multipart/form-data; boundary=TMSR 
Connection: close 
User-Agent: Python-urllib/2.7 
 
--TMSR 
Content-Disposition: form-data; name="foo"; filename="TMSR.txt" 
 
123TMSRAAAAAA