출처 : CERTCC 메일링
작성자 : 홍석범

한달여전에 발견된 리눅스 커널의 메모리 관리 코드인 mremap 에서의 취약성에 이어
이번에는 같은 코드에서 return value 를 체크하지 않는 문제로 인하여 일반유저 권한으로
local 에서 root 권한을 획득할 수 있는 심각한 취약성이 발견되었습니다.

이로써 금번까지 3달 연속 약 한 달을 주기로 심각한
리눅스 커널 취약성이 발견되고 있습니다.

12월초순 : do_brk() 함수에서의 취약성 (2.4.22 이하 버전 취약)
1월 중순 : mremap 에서 bound 체킹 취약성 (2.4.23 이하 버전 취약)
2월중순 : mremap 에서 return value 취약성 (2.4.24 이하 버전 취약)

이번 취약성 역시 현존하는 모든 리눅스 커널에 해당하며
취약한 버전과 안전한 버전은 각각 다음과 같습니다.

-------------------------------------------------------------
취약한 버전 | 패치버전
-------------------------------------------------------------
* 커널 2.2.25 를 포함한 2.2.25 이전 버전 --> 패치버전 미제공
* 커널 2.4.24 를 포함한 2.4.24 이전 버전 --> 2.4.25
* 커널 2.6.2 를 포함한 2.6.2 버전 --> 2.6.3
--------------------------------------------------------------

참고로 금번 취약성과 관련된 패치는 아래와 같습니다.

--- linux-2.4.20/mm/mremap.c~ 2004-02-05 00:17:20.000000000 +0000
+++ linux-2.4.20/mm/mremap.c 2004-02-05 00:22:32.000000000 +0000
@@ -305,7 +305,9 @@
if ((addr <= new_addr) && (addr+old_len) > new_addr)
goto out;

- do_munmap(current->mm, new_addr, new_len);
+ ret = do_munmap(current->mm, new_addr, new_len);
+ if (ret && new_len)
+ goto out;
}

/*
@@ -313,9 +315,11 @@
* the unnecessary pages..
* do_munmap does all the needed commit accounting
*/
- ret = addr;
if (old_len >= new_len) {
- do_munmap(current->mm, addr+new_len, old_len - new_len);
+ ret = do_munmap(current->mm, addr+new_len, old_len - new_len);
+ if (ret && old_len != new_len)
+ goto out;
+ ret = addr;
if (!(flags & MREMAP_FIXED) || (new_addr == addr))
goto out;
old_len = new_len;

커널소스 다운로드 : ftp://ftp.kr.kernel.org/pub/linux/kernel/

만약 rpm 으로 커널을 패치하시려면 각각 아래의 URL 을 참고하시기 바랍니다.

* 레드햇 9.0
https://rhn.redhat.com/errata/RHSA-2004-065.html

* 레드햇 7.2 / 7.3/ 8.0 (곧 제공될 예정)
http://download.fedoralegacy.org/

참고로, 아래 URL 에서는 레드햇 7.2/7.3/8.0 에 대해 유료로 rpm 패치를 제공하고 있군요.
http://transition.progeny.com/

패치가 종료된 후 시스템이 취약한 지 여부는 다음과 같이 확인 가능합니다.
(단지, Proof Of Concept 일 뿐 시스템에 영향을 주지는 않습니다.)

소스코드 다운로드 : http://www.security.nnov.ru/files/mremap_poc_2.c

$ gcc -o mremap_poc_2 mremap_poc_2.c //컴파일

## 취약한 커널 버전(2.4.24)의 경우

$ ./mremap_poc_2
mmap: Cannot allocate memory
created ~65530 VMAs
now mremapping 0x3FFE5000 at 0x3FFE1000Segmentation fault

이후 dmesg 또는 /var/log/messages 파일을 확인하면 다음과 같은
로그가 보이게 됩니다.

$ dmesg | tail -n 15 또는 tail -15 /var/log/messages

kernel BUG at mmap.c:1188!
invalid operand: 0000
CPU: 0
EIP: 0010:[<c0123201>] Not tainted
EFLAGS: 00010287
eax: 3ffe2000 ebx: cead2140 ecx: cead3ec0 edx: cead3f60
esi: cead2124 edi: cead20e0 ebp: cead2140 esp: cf6b1f48
ds: 0018 es: 0018 ss: 0018
Process mremap_poc_2 (pid: 24785, stackpage=cf6b1000)
Stack: cead2140 cead2124 cead20e0 00000002 00000002 c0127f84 ce3be780 c0127ff4
ce3be780 cead2140 cf6b0000 00001000 3ffe5000 ce3be79c ce3be780 3ffe2000
cf6b0000 cead20e0 cead3f00 c01280ab 3ffe5000 00001000 00001000 00000003
Call Trace: [<c0127f84>] [<c0127ff4>] [<c01280ab>] [<c01086e7>]

Code: 0f 0b a4 04 01 e7 1e c0 8b 7c 24 10 8b 74 24 14 8b 5c 24 18

## 취약하지 않은 커널 버전(2.4.25)의 경우

$ ./mremap_poc_2
mmap: Cannot allocate memory
created ~65530 VMAs
now mremapping 0x3FFE5000 at 0x3FFE1000
kernel may not be vulnerable

dmesg 에 아무런 로그가 남지 않음.

본 취약성에 대한 자세한 내용은 아래의 URL 을 참고하시기 바랍니다.

http://www.isec.pl/vulnerabilities/isec-0014-mremap-unmap.txt
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0077

+ Recent posts