- 오래된 힙 취약점 중 하나인 Unsafe Unlink에 대해서 알아보자. Unsafe Unlink - 단일 연결리스트로 구성된 bin을 제외하고 freelist에서 병합이 일어날때 unlink과정이 수행된다. - glibc 2.23버전까지는 이러한 unlink과정이 매크로로 정의되어 수행되었으며 검사를 제대로 진행하지 않았다. - 또한 이 기법이 발표된 2000년 초반에는 nx같은 보안기법도 기본적으로 적용되지 않아 쉘코드등을 heap에 적어놓고 실행해버리는 무시무시한 짓도 가능했다. FD = P->fd; BK = P->bk; FD->bk = BK; BK->fd = FD; - unlink란 어렵게 생각할 것 없이 위 코드의 역할이다. - P는 unlink될 청크를 가리키는 포인터이다. - 따라서 un..
Pwn
- 리눅스 커널 익스플로잇에는 return to shellcode와 유사한 공격 기법으로 return to user(ret2usr)가 있다. - ret2usr는 사용자 메모리 영역에 있는 코드를 실행하는 공격 기법이다. - 공격자가 커널의 코드 영역에 악의적인 코드를 넣는 것은 거의 불가능하지만, 프로세스의 코드는 사용자가 임의로 작성할 수 있으므로 사용자 메모리에 악의적인 코드를 넣는 것은 비교적 쉽다. - 공격자는 이러한 특징을 이용해서 커널에서 스택 버퍼 오버플로우를 발생시키고, 미리 컴파일해둔 악의적인 함수로 실행 흐름을 옮겨서 root권한을 획득할 수 있다. ret2usr - ret2usr는 커널 권한의 흐름을 획득할 수 있을 때, 이를 공격자가 작성한 악의적인 함수로 옮겨서 권한을 획득하는 공..
직접 릭 - 커널 코드의 주소를 릭할 수 있는 가장 간단한 방법은 바로 주소를 직접 릭 시키는 취약점을 찾아 익스플로잇 하는 것이다. - 한 예로, 2.6.29이하 버전의 커널에서는 /proc/[PID]/stat 또는 /proc/[PID]/wchan 가상 파일을 통해 커널 주소를 손쉽게 획득할 수 있었다. - wchan필드는 본래 태스크가 대기상태에 있을 때 마지막으로 실행한 커널 함수의 주소를 출력하여 태스크의 대기 사유를 알 수 있도록 한 것인데, KASLR이 도입되면서 사용자 공간에서 알지 못해야 할 베이스 주소가 릭되는 문제가 생긴 것이다. - 최신 버전 커널의 경우 관리자 권한을 가지고 있어야만 wchan필드에 접근할 수 있으며, 커널 주소 대신 항상 함수명 심볼 또는 0을 출력하도록 변경되었다..
KASLR? - KASLR은 커널 메모리 주소의 예측을 어렵게 하기 위해 고안된 보호 기법이다. - 윈도우, 맥, iOS, 리눅스, FreeBSD, OpenBSD등 상당수의 운영체제에서 KASLR을 지원한다. - 리눅스 커널의 경우 3.14버전에서 최초로 KASLR을 옵션으로 지원하였고, 4.12버전에서는 KASLR이 기본으로 적용되게 하였다. - 따라서 현재 존재하는 대부분의 리눅스 배포판이 KASLR을 기본적으로 적용시켜 비활성화하려면 커널 명령줄에 nokaslr옵션을 사용해야 한다. - KASLR이 적용되면 부팅 시에 커널 코드 및 데이터가 임의 주소에 적재된다. - 따라서 공격자는 기존의 ASLR과 PIE를 우회하듯이 다양한 방법으로 코드나 데이터 섹션의 주소를 구하고, 이를 활용해서 커널이 로드..
- Background: Task에서 실습을 통해 cred구조체를 조작하면 권한이 변경될 수 있음을 알았다. - 실제로도 커널의 취약점을 이용하여 커널 메모리의 cred 구조체를 조작하면 다른 유저의 권한을 획득할 수 있다. - 하지만 이 방법은 다음과 같은 제약 조건이 존재한다. 커널 메모리 상의 현재 task_struct 혹은 cred구조체의 주소를 알아야한다. 임의 읽기 및 쓰기가 가능해야 한다. cred 구조체는 다른 태스크와 공유되는 자원이므로, 임의로 변경 시 레이스 컨디션이 발생할 수 있으며, 이는 익스플로잇의 안전성을 떨어뜨리는 요인이 된다. 실제 커널에서 태스크의 신원 정보를 변경할 때는 cred 구조체를 직접 변경하는 것이 아닌 기존의 구조체를 복사하고 이를 수정한 뒤, 태스크가 복사된..
Task? - 리눅스의 태스크는 프로그램의 실행단위를 나타낸다. - 사용자가 어떤 프로그램을 실행하면, 태스크가 생성되고 프로그램의 코드가 실행된다. - 리눅스에서는 하나의 프로세스 및 스레드가 각각의 태스크로 구성된다. - 많은 현대 운영체제는 여러개의 태스크를 생성해두고, 각각에 실행 시간을 배분하는 방식으로 태스크를 관리한다. - 여기서 다수의 태스크를 관리하는 것을 멀티 태스킹, 실행시간을 배분하는 것을 스케줄링이라 한다..! - 각 태스크는 커널 메모리에 task_struct구조체로 표현되는데, 여기에 태스크의 여러 정보가 저장되어 있다. - 그 중에는 사용자 신원 및 권한과 관련된 정보도 있어서, 이를 조작하는 것이 커널 익스플로잇의 주된 목표가 되기도 한다. 리눅스 권한 - 리눅스는 운영체제..