
10개의 스테이지를 해결해야 flag를 얻을 수 있다.
스테이지 클리어 여부는 sub_1407에서 결정한다. (check로 수정)
_BOOL8 __fastcall check(__int64 a1, __int64 a2)
{
int v2; // eax
int v4; // [rsp+1Ch] [rbp-14h]
int v5; // [rsp+20h] [rbp-10h]
int i; // [rsp+24h] [rbp-Ch]
__int64 v7; // [rsp+28h] [rbp-8h]
v7 = 0LL;
v4 = 0;
v5 = 0;
for ( i = 0; *(_BYTE *)(i + a1); ++i )
{
v2 = *(char *)(i + a1);
if ( v2 == 65 )
{
v5 = 1;
++v7;
if ( v4 )
{
puts("A button stucked! Retreat...");
exit(-1);
}
v4 = 1;
}
else
{
if ( v2 != 66 )
{
puts("Invalid button!");
exit(-1);
}
if ( !v5 )
{
puts("Lore says the spell should start with A...");
exit(-1);
}
v7 *= 2LL;
v4 = 0;
}
}
return v7 == a2;
}

저 INFO 값이 ptr의 값이다.
int __fastcall sub_138D(__int64 a1)
{
return printf(
"[INFO] HP: %5hu, STR: %5hhu, AGI: %5hhu, VIT: %5hhu, INT: %5hhu, END: %5hhu, DEX: %5hhu\n",
HIWORD(a1),
(unsigned __int8)a1,
BYTE1(a1),
BYTE2(a1),
BYTE3(a1),
BYTE4(a1),
BYTE5(a1));
}
이 함수에서 ptr이 쪼개진다.
찾아보면 (little-endian 기준)
byte1: 뒤에서 2번째 바이트 (하위 2번째 1바이트)
byte2: 뒤에서 3번째 바이트 (하위 3번째 1바이트)
hiword: 상위 2바이트
unsigned __int8: 하위 1바이트 (little endian 기준으로 마지막 1바이트가 제일 앞에 저장되기 때문
hp << 48 | dex << 40 | end << 32 | iint << 24 | vit << 16 | agi << 8 | sstr
내가 입력한 A, B 배열로 위의 값을 만들 수 있으면 된다.
while num:
if num%2==1:
s += 'A'
num -= 1
else:
s += 'B'
num //= 2
from pwn import *
p = remote('host1.dreamhack.games', 24538)
for i in range(10):
p.recvuntil(b'HP: ')
hp = int(p.recvuntil(b',')[:-1])
print(hp)
p.recvuntil(b'STR: ')
sstr = int(p.recvuntil(b',')[:-1])
print(sstr)
p.recvuntil(b'AGI: ')
agi = int(p.recvuntil(b',')[:-1])
print(agi)
p.recvuntil(b'VIT: ')
vit = int(p.recvuntil(b',')[:-1])
print(vit)
p.recvuntil(b'INT: ')
iint = int(p.recvuntil(b',')[:-1])
print(iint)
p.recvuntil(b'END: ')
end = int(p.recvuntil(b',')[:-1])
print(end)
p.recvuntil(b'DEX: ')
dex = int(p.recvline()[:-1])
print(dex)
num = hp << 48 | dex << 40 | end << 32 | iint << 24 | vit << 16 | agi << 8 | sstr
s = ''
while num:
if num%2==1:
s += 'A'
num -= 1
else:
s += 'B'
num //= 2
#p.interactive()
print(s[::-1])
p.sendlineafter(b'Cast your spell!: ', s[::-1])
p.interactive()