반응형
풀이
__int64 __usercall main@<rax>(char **a1@<rsi>, char **a2@<rdx>, __int64 a3@<rbp>)
{
puts_0("General Angerforge, the Dark Iron responsible for stealing my computer.", a1, a2);
puts_0("But I'm just a programmer.. so Call me my best warrior friend.", a1, v3);
puts_0("If you call my friend, I will give you a good reward.", a1, v4);
fgets_0(&v11, 57LL, stdin);
sub_3A48((__int64)&v20, (__int64)&v11);
v5 = (const char *)&v11;
if ( (unsigned int)sub_39F7((__int64)&v11) == 1 )
{
puts_0("OMG, Thank you for your good works :)");
}
else
{
sub_39D9(v6, (__int64)&v20, 57LL);
}
return result;
}
우선 main 함수를 보면 입력 값 57을 받고, 함수로 부터 리턴 값이 1이면 풀리고 아니면 실패하는 구조이다.
__int64 __usercall sub_3A48@<rax>(__int64 a1@<rbp>, __int64 a2@<rdi>)
{
if ( sub_10A0(a2) >= (unsigned __int64)((dword_6010 | dword_6014) + 5) )
{
sub_11C9(a2);
sub_1396(a2);
sub_1563(a2);
sub_1730(a2);
sub_18FD(a2);
sub_1ABF(a2);
sub_1BBF(a2);
sub_1CCE(a2);
sub_1DCE(a2);
sub_1EEE(a2);
sub_22CB(a2);
sub_2589(a2);
sub_2847(a2);
sub_2B05(a2);
sub_2DC3(a2);
sub_2EF9(a2);
sub_3035(a2);
sub_3171(a2);
result = sub_32AD(a2);
}
else
{
sub_33E9(a2);
sub_3481(a2);
sub_3519(a2);
sub_35B1(a2);
sub_3649(a2);
sub_36E1(a2);
sub_3779(a2);
sub_3811(a2);
sub_38A9(a2);
result = sub_3941(a2);
}
return result;
}
signed __int64 __fastcall sub_39F7(__int64 a1)
{
__int64 v2; // [rsp-8h] [rbp-8h]
__asm { endbr64 }
*(&v2 - 3) = a1;
for ( *((_DWORD *)&v2 - 1) = 0; *((_DWORD *)&v2 - 1) <= 55; ++*((_DWORD *)&v2 - 1) )
{
if ( *(_BYTE *)(*((signed int *)&v2 - 1) + *(&v2 - 3)) != byte_4080[*((signed int *)&v2 - 1)] )
return 0LL;
}
return 1LL;
}
우선 첫 번째 연산에는 너무 많은 연산을 한다. 그리고 두 번째 함수는 연산한 결과를 56byte를 어떤 값과 비교한다.
만약 하나라도 틀리면 0을 아니면 1을 반환한다. 연산하는게 너무 많아서 실질적으로 사람이 계산하면 오래걸리는 문제여서 angr 또는 z3같은 것으로 푸는 문제 같다.
solve
import angr
import claripy
p = angr.Project('./angrforge')
flag_chars = [claripy.BVS('flag_%d' % i, 8) for i in range(56)]
flag = claripy.Concat(*flag_chars + [claripy.BVV(b'\n')])
st = p.factory.full_init_state(
stdin = flag,
add_options = angr.options.unicorn,
)
for i in flag_chars:
st.solver.add(i != 0)
st.solver.add(i != 10)
sm = p.factory.simulation_manager(st)
sm.run()
for i in sm.deadended:
if b'OMG' in i.posix.dumps(1):
print(i.posix.dumps(0))
Flag
XMAS{h3_1s_b1o0d3lf_d3athkni9ht_wh0_will_kill_4ngrf0rge}
반응형
'CTF(Capture The Flag) > XMAS 2020' 카테고리의 다른 글
Match Maker (Christmas CTF 2020) (0) | 2020.12.30 |
---|