// to avoid interactive step, without loss of generality p1 = alloc(8); p1[0] = 'a'; p1[1] = NUL;
cryptstate_T结构体:
1 2 3 4 5 6 7 8 9 10
/* The state of encryption, referenced by cryptstate_T. */ typedefstruct { int key; int shift; int step; int orig_size; int size; int cur_idx; char_u *buffer; } perm_state_T;
/* Step 1: Inverse of Multiplication */ i = 4; while (i < len) { if (ps->cur_idx < ps->orig_size) { to[ps->cur_idx+4] = from[i]; i++; } ps->cur_idx = (ps->cur_idx+ps->step)%ps->size; }
/* Step 2: Inverse of Addition */ for (i = 0; i < ps->shift; ++i) ps->buffer[i] = to[i+4]; for (i = 4+ps->shift; i < len; ++i) to[i-ps->shift] = to[i]; for (i = 0; i < ps->shift; ++i) to[len-ps->shift+i] = ps->buffer[i];
/* The state of encryption, referenced by cryptstate_T. */ typedefstruct { int key; int shift; int step; int orig_size; int size; int cur_idx; char_u *buffer; } perm_state_T;
crypt_perm_decode( cryptstate_T *state, char_u *from, size_t len, char_u *to) { // ... /* Step 1: Inverse of Multiplication */ i = 4; while (i < len) { if (ps->cur_idx < ps->orig_size) { to[ps->cur_idx+4] = from[i]; i++; } ps->cur_idx = (ps->cur_idx+ps->step)%ps->size; } // ... }
这里没有检查ps->cur_idx的值,导致可以控制其为负数,造成堆的前向溢出。
from是vim打开的文件。ps->step可以通过
1 2 3 4 5 6 7 8 9 10 11
unsignedint iv; for (i = 0; i < 4; ++i) { to[i] = from[i]; iv = (iv<<8) + from[i]; } // ... ps->step = ps->key ^ iv; if (ps->step % ps->size == 0) ps->step++; ps->cur_idx = 0;
控制。
如果能改写ps->buffer的值,就能进一步利用
1 2 3
/* Step 2: Inverse of Addition */ for (i = 0; i < ps->shift; ++i) ps->buffer[i] = to[i+4];
/* The state of encryption, referenced by cryptstate_T. */ typedefstruct { int key; int shift; int step; int orig_size; int size; int cur_idx; char_u *buffer; } perm_state_T;
crypt_perm_decode( cryptstate_T *state, char_u *from, size_t len, char_u *to) { // ... /* Step 1: Inverse of Multiplication */ i = 4; while (i < len) { if (ps->cur_idx < ps->orig_size) { to[ps->cur_idx+4] = from[i]; i++; } ps->cur_idx = (ps->cur_idx+ps->step)%ps->size; } // ... /* Step 2: Inverse of Addition */ for (i = 0; i < ps->shift; ++i) ps->buffer[i] = to[i+4]; // ... }