Write-ups/pwnable.xyz
GrownUp - pwnable.xyz
dolphinlmg
2020. 2. 11. 23:13
Prob Info
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *src; // ST08_8
__int64 buf; // [rsp+10h] [rbp-20h]
__int64 v6; // [rsp+18h] [rbp-18h]
unsigned __int64 v7; // [rsp+28h] [rbp-8h]
v7 = __readfsqword(0x28u);
setup();
buf = 0LL;
v6 = 0LL;
printf("Are you 18 years or older? [y/N]: ", argv);
*((_BYTE *)&buf + (signed int)((unsigned __int64)read(0, &buf, 0x10uLL) - 1)) = 0;
if ( (_BYTE)buf != 'y' && (_BYTE)buf != 'Y' )
return 0;
src = (char *)malloc(0x84uLL);
printf("Name: ", &buf);
read(0, src, 0x80uLL);
strcpy(usr, src);
printf("Welcome ", src);
printf(qword_601160, usr);
return 0;
}
맨 마지막 printf가 조금 이상한데 0x601160를 찾아 들어가보면 setup 함수에서 0x601168이란 값으로 초기화 해주고 0x601168에는 "%s\n"를 저장한다. 결국 printf("%s\n", usr) 와 같은 의미이다.
src = (char *)malloc(0x84uLL);
printf("Name: ", &buf);
read(0, src, 0x80uLL);
strcpy(usr, src);
이 부분을 잘 보면 힙 영역에 0x80 만큼 값을 입력받고 그 값을 다시 전역변수 usr에 strcpy를 통해 복사한다. 이 때 strcpy는 문자열을 다루는 함수이기 때문에 처리 후 맨 끝에 널바이트를 붙여준다. usr의 사이즈는 0x80이고 그 뒤에 qword_601160 변수가 존재하는데, strcpy 함수로 인해 최대 0x81 바이트를 복사할 수 있고 off-by-one이 발생한다. 이를 통해 qword_601160의 값이 0x601168에서 0x601100으로 바뀌게 되고 이는 usr의 중간부분이므로 fsb가 가능하다.
.data:0000000000601080 public flag
.data:0000000000601080 flag db 'FLAG{_the_real_flag_will_be_here_}',0
.data:0000000000601080 _data ends
바이너리 내부에 플래그가 있으므로 fsb를 통해 이 문자열을 출력해주면 된다.