Skip to content

Commit f5fec25

Browse files
committed
KWallet format: Do not decode beyond 64 bytes, support truncation, unify
1 parent 566dbc9 commit f5fec25

File tree

1 file changed

+38
-6
lines changed

1 file changed

+38
-6
lines changed

src/kwallet_fmt_plug.c

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,18 @@ static struct fmt_tests kwallet_tests[] = {
9191
{"$kwallet$88$69fca2d9a5004b6a8c4dc56e27e0046840a5b960121462270caf2d6b39db6e1d87b50d36e1bdfa6468e98c63de980d882af639a71e03438f6263864490a32c5cecb425c30fd216de5aa0af9e4cb8dad3a8ebece09dcf0884$1$56$d12685e20a1e7e9e87f357b78f72f5e059ad7b49295f159aa5af775ef11ec5de14bb978f0e1ab9aa29d365848e4b6f68260408fdfd0f43db$50000", "openwall"},
9292
{"$kwallet$88$d93b084704e76898b1157b9965316e2c1f837d758e63005bf5f8865fcf929051b118cbda3aaffbff86cba4c715fc749c173368be796d0e37b327db7f832e20b7accb3e7ac519c38a13b056ad8ca03240da64deed72293634$1$56$bbe9dd83359eb451fc7759c91d457bbe9c74dab3ed30c10a3a8f0ef1e0bb2cfab32e6e68f6e8c1fb788f22073b76d03c98d52dc9a50a991e$50000", "openwall"},
9393
{"$kwallet$520$d931157b758d2fcd343a9fd5823da60c79dc15b596389d61ac046a2f268f8660a87d1aaa001e66f1a24405f153921b79809043f214446ccfd5fdfd5d50e86efac53e1ce96b450af39062fc101eb1aa463acba15d870552aa3321468fa56c68e7c1b3b4a3f19c44c1ecc7b9c07a09a6e5bf3a41a811914b7f11a0e4afecbefb7621e0bf8ee0b38337c385ae86b92d1604d8824ed94a9bb53621b530463db60d5eff60d21cc79ee6fb2302d069c9a1fccf021dd88a9af299ed166112b162bcd4615dd2f759ab505db916e61b6486c835b4d57c7bd967cb3eaa23e9f8a70b9eff8ae5298318057deb092f3cb48c9e519548a807c894ea6070aedda33e5ae03d423f4b737e27f5f0738da7f25b29581e85fa8011190f3c3419298896c612082accb55b3ba5d280998c54ad1630edae05758a5584288d8c51803935b9f757f945e33f2b351dd8022b9f15d427a96e359e29e7fd569ee774d770baa9720f9717a3d882d693f9d3562428400bc40728a49180430d2d47f1a880ae22a3fd5d696607bf93db00df0d47d6058623a7c7f091c9ff47bb62b9ddaf9df56002cb542350f270d8302351359d68857bf13e5693ba111ffc45227af10572818d785cc115b0b6633371f4ef5baf7870ab33bc98b3bddb5f63d1decf8f85e3732b9b3a95dff93b2398809108ce236c268eeedfa14637b2d73ec507bff15b76d136ac601e8c5a9c3d4e2f94816fd4fcf01e$1$56$6278a23465d8cfc3d6117e97f684c3e13bf3c747b6681649103c373a3703512ee6a76080fd0019bbe4e1554e2397f435bce21b96ac5d27e8$50000", "eel-bronze-aghast-blissful-duh-duration-outrank-shrunk"},
94+
// Pre-truncated
95+
{"$kwallet$88$04ff141f0318b30b950a452514175886a16a64fd61bdc575912ab49fa6784a0ebe049d493c677d51b88f923bcfa4cf371337055215ff7f75b626ee3915b672a073$1$56$5a083da3e6f3917d3af71d1367738b103a296ea2240244c0935f378c49ca92a3002bd87419ea3d1ef18a77d069214e3dc75b0569bddeea11$50000", "openwall"},
96+
{"$kwallet$112$25be8c9cdaa53f5404d7809ff48a37752b325c8ccd296fbd537440dfcef9d66f72940e97141d21702b325c8ccd296fbd537440dfcef9d66fcd953cf1e41904b0c4", "openwall"},
97+
9498
{NULL}
9599
};
96100

97101
static char (*saved_key)[PLAINTEXT_LENGTH + 1];
98102
static int *cracked;
99103

100104
static struct custom_salt {
101-
unsigned char ct[0x10000];
105+
unsigned char ct[64];
102106
unsigned int ctlen;
103107
// following fields are required to support modern KWallet files
104108
int kwallet_minor_version;
@@ -126,7 +130,7 @@ static void done(void)
126130
static int valid(char *ciphertext, struct fmt_main *self)
127131
{
128132
char *ctcopy, *keeptr, *p;
129-
int res, extra;
133+
int res, len, extra;
130134
if (strncmp(ciphertext, FORMAT_TAG, FORMAT_TAG_LEN) != 0)
131135
return 0;
132136

@@ -138,11 +142,12 @@ static int valid(char *ciphertext, struct fmt_main *self)
138142
if (!isdec(p))
139143
goto err;
140144
res = atoi(p);
141-
if (res < 64 || res > sizeof(cur_salt->ct) || (res & 7))
145+
if (res < 64 || res > 0x1000000 || (res & 7))
142146
goto err;
143147
if ((p = strtokm(NULL, "$")) == NULL) /* ct */
144148
goto err;
145-
if (hexlenl(p, &extra) != res*2 || extra)
149+
len = hexlenl(p, &extra);
150+
if ((len != res*2 && len != 130) || extra) /* 130 means truncated */
146151
goto err;
147152

148153
if ((p = strtokm(NULL, "$")) != NULL) {
@@ -173,6 +178,33 @@ static int valid(char *ciphertext, struct fmt_main *self)
173178
return 0;
174179
}
175180

181+
/* Truncate the main ciphertext field to 130 chars (65 bytes) */
182+
static char *split(char *ciphertext, int index, struct fmt_main *self)
183+
{
184+
static char *out;
185+
static size_t have;
186+
size_t need, part1, part2;
187+
char *p, *q;
188+
189+
p = strchr(ciphertext + FORMAT_TAG_LEN, '$') + 1;
190+
q = strchr(p, '$');
191+
if (!q)
192+
q = p + strlen(p);
193+
if (q - p == 130)
194+
return ciphertext;
195+
196+
part1 = p + 130 - ciphertext;
197+
part2 = strlen(q) + 1;
198+
need = part1 + part2;
199+
if (need > have)
200+
out = mem_alloc_tiny(have = need * 2, MEM_ALIGN_NONE);
201+
202+
memcpy(out, ciphertext, part1);
203+
memcpy(out + part1, q, part2);
204+
205+
return out;
206+
}
207+
176208
static void *get_salt(char *ciphertext)
177209
{
178210
char *ctcopy = xstrdup(ciphertext);
@@ -187,7 +219,7 @@ static void *get_salt(char *ciphertext)
187219
p = strtokm(ctcopy, "$");
188220
salt->ctlen = atoi(p);
189221
p = strtokm(NULL, "$");
190-
for (i = 0; i < salt->ctlen; i++)
222+
for (i = 0; i < 64; i++)
191223
salt->ct[i] = atoi16[ARCH_INDEX(p[i * 2])] * 16
192224
+ atoi16[ARCH_INDEX(p[i * 2 + 1])];
193225

@@ -456,7 +488,7 @@ struct fmt_main fmt_kwallet = {
456488
fmt_default_reset,
457489
fmt_default_prepare,
458490
valid,
459-
fmt_default_split,
491+
split,
460492
fmt_default_binary,
461493
get_salt,
462494
{tunable_cost_version, tunable_cost_iterations},

0 commit comments

Comments
 (0)