tinypad-house of einherjar

本文最后更新于:2024年4月2日 晚上

本题出自2016 seccon。基于GLIBC 2.23-0ubuntu11。

checksec

1
2
3
4
5
Arch:     amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

主逻辑函数

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
int main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rsi
char *v4; // rdi
__int64 v5; // rdx
size_t v6; // rax
int v7; // eax
int v8; // eax
size_t v9; // rax
unsigned __int64 v10; // rax
char *c; // [rsp+4h] [rbp-1Ch] BYREF
int v13; // [rsp+Ch] [rbp-14h]
int v14; // [rsp+10h] [rbp-10h]
int v15; // [rsp+14h] [rbp-Ch]

v14 = 0;
v3 = 1LL;
v4 = "\n";
write_n((__int64)"\n", 1LL);
do
{
HIDWORD(c) = 0;
while ( SHIDWORD(c) <= 3 )
{
LOBYTE(c) = BYTE4(c) + 49;
write_n((__int64)" # INDEX: ", 12LL);
writeln(&c, 1LL);
write_n((__int64)" # CONTENT: ", 12LL);
if ( tinypad[2 * SHIDWORD(c) + 33] )
{
v6 = strlen(tinypad[2 * SHIDWORD(c) + 33]);
writeln(tinypad[2 * SHIDWORD(c) + 33], v6);
}
v3 = 1LL;
v4 = "\n";
writeln("\n", 1LL);
++HIDWORD(c);
}
v13 = 0;
v7 = getcmd(v4, v3, v5);
v14 = v7;
if ( v7 == 'D' ) // Delete
{
write_n((__int64)"(INDEX)>>> ", 11LL);
v13 = read_int();
if ( v13 <= 0 || v13 > 4 )
{
LABEL_29:
v3 = 13LL;
v4 = "Invalid index";
writeln("Invalid index", 13LL);
continue;
}
if ( !tinypad[2 * v13 + 30] )
{
LABEL_31:
v3 = 8LL;
v4 = "Not used";
writeln("Not used", 8LL);
continue;
}
free(tinypad[2 * v13 + 31]); // Delete
tinypad[2 * v13 + 30] = 0LL;
v3 = 9LL;
v4 = "\nDeleted.";
writeln("\nDeleted.", 9LL);
}
else if ( v7 > 'D' )
{
if ( v7 != 'E' )
{
if ( v7 == 'Q' )
continue;
LABEL_41:
v3 = 17LL;
v4 = "No such a command";
writeln("No such a command", 17LL);
continue;
}
write_n((__int64)"(INDEX)>>> ", 11LL);
v13 = read_int();
if ( v13 <= 0 || v13 > 4 )
goto LABEL_29;
if ( !tinypad[2 * v13 + 30] )
goto LABEL_31;
LODWORD(c) = 48;
strcpy((char *)tinypad, tinypad[2 * v13 + 31]);
while ( toupper((int)c) != 'Y' ) // Edit
{
write_n((__int64)"CONTENT: ", 9LL);
v9 = strlen((const char *)tinypad);
writeln(tinypad, v9);
write_n((__int64)"(CONTENT)>>> ", 13LL);
v10 = strlen(tinypad[2 * v13 + 31]);
read_until((char *)tinypad, v10, 0xAu); // off by --
writeln("Is it OK?", 9LL);
write_n((__int64)"(Y/n)>>> ", 9LL);
read_until((char *)&c, 1uLL, 0xAu);
}
strcpy(tinypad[2 * v13 + 31], (const char *)tinypad);
v3 = 8LL;
v4 = "\nEdited.";
writeln("\nEdited.", 8LL);
}
else
{
if ( v7 != 'A' )
goto LABEL_41;
while ( v13 <= 3 && tinypad[2 * v13 + 32] )
++v13;
if ( v13 == 4 )
{
v3 = 17LL;
v4 = "No space is left.";
writeln("No space is left.", 17LL);
}
else // Add
{
v15 = -1;
write_n((__int64)"(SIZE)>>> ", 10LL);
v15 = read_int();
if ( v15 <= 0 )
{
v8 = 1;
}
else
{
v8 = v15;
if ( (unsigned __int64)v15 > 0x100 )
v8 = 256;
}
v15 = v8;
tinypad[2 * v13 + 32] = (char *)v8;
tinypad[2 * v13 + 33] = (char *)malloc(v15);
if ( !tinypad[2 * v13 + 33] )
{
writerrln("[!] No memory is available.", 27LL);
exit(-1);
}
write_n((__int64)"(CONTENT)>>> ", 13LL);
read_until(tinypad[2 * v13 + 33], v15, 0xAu);
v3 = 7LL;
v4 = "\nAdded.";
writeln("\nAdded.", 7LL);
}
}
}
while ( v14 != 'Q' );
return 0;
}

read_until

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void __fastcall read_until(char *a1, unsigned __int64 a2, unsigned int a3)
{
unsigned __int64 i; // [rsp+28h] [rbp-18h]
__int64 n; // [rsp+30h] [rbp-10h]

for ( i = 0LL; i < a2; ++i )
{
n = read_n(0LL, &a1[i], 1LL);
if ( n < 0 )
return;
if ( !n || a1[i] == a3 )
break;
}
a1[i] = 0; // off by --
if ( i == a2 && a1[a2 - 1] != 10 )
dummyinput(a3);
}

有off by one,prev_inuse位基本可控,可以实现向前合并合成一个top chunk,以及控制prev_size来实现fake chunk。


tinypad-house of einherjar
http://example.com/2024/03/06/tinypad-house-of-einherjar/
作者
OSLike
发布于
2024年3月6日
许可协议