Codegate CTF 2018 Preliminary - RedVelvet (Rev)

문제 파일 (RedVelvet)

먼저 main함수를 살펴보면 입력한 글자에 대해서 각 함수들이 비교를 하고 해당 함수를 통과하게 되면 HAPPINESS:), 통과하지 못하면 exit(1)를 호출하는 구조로 되어있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
v20 = __readfsqword(0x28u);
strcpy(s2, "0a435f46288bb5a764d13fca6c901d3750cee73fd7689ce79ef6dc0ff8f380e5");
v16 = 0LL;
v17 = 0LL;
v18 = 0LL;
v19 = 0;
printf((const char *)&loc_4016CF + 1, argv, envp);
fgets(s, 27, edata);
func1(s[0], s[1]);
func2(s[1], s[2]);
func3(s[2], s[3]);
func4(s[3], s[4]);
func5(s[4], s[5]);
func6(s[5], s[6], s[7]);
func7(s[7], s[8], s[9]);
func8(s[9], s[10], s[11]);
func9(s[11], s[12], s[13]);
v4 = ptrace(0, 0LL, 1LL, 0LL);
if ( v4 == -1 )
{
v8 = *v5;
v9 = v3 + v5[111] == 0;
v5[111] += v3;
JUMPOUT(!v9, &unk_401746);
MEMORY[0x6C] &= BYTE1(v4);
JUMPOUT(*(_QWORD *)"ag : ");
}
func10(s[13], s[14], s[15]);
func11(s[15], s[16], s[17]);
func12(s[17], s[18], s[19]);
func13(s[19], s[20], s[21]);
func14(s[21], s[22], s[23]);
func15(s[23], s[24], s[25]);
SHA256_Init(&v11);
v6 = strlen(s);
SHA256_Update(&v11, s, v6);
SHA256_Final(v13, &v11);
for ( i = 0; i <= 31; ++i )
sprintf(&s1[2 * i], "%02x", (unsigned __int8)v13[i]);
if ( strcmp(s1, s2) )
exit(1);
printf("flag : {\" %s \"}\n", s);
return 0;

angrflag가 출력되는 부분을 찾고자 했으나 실패하였다. 그래서 HAPPINESS:)가 15번 출력되는 결과를 찾기로 했다.

1
2
3
4
5
6
7
8
9
10
11
import angr

proj = angr.Project("./RedVelvet")
simgr = proj.factory.simgr()

simgr.explore(find=lambda s: "HAPPINESS:)\n"*15 in s.posix.dumps(1))

s = simgr.found[0]
print s.posix.dumps(1)
flag = s.posix.dumps(0)[:26]
print flag

정답으로 What_You_Wanna_Be?:)_lc_la가 나왔지만 마지막 hash비교가 맞지 않았고 What_You_Wanna_Be?:)_la_la로 게싱해보았더니 정답이었다.

Share