[CVE ID]
CVE-2024-41631
==================================================================================================================================================================
[Product]
NEUQ_Board
==================================================================================================================================================================
[Version]
1.0
==================================================================================================================================================================
[Exploit Type]
Buffer overflow
==================================================================================================================================================================
[Attack Type]
Remote
==================================================================================================================================================================
[Description]
Buffer Overflow vulnerability in host-host NEUQ_board v.1.0 allows a remote attacker to cause a denial of service via the password.h component.
==================================================================================================================================================================
[Exploit Analysis]
These functions:
memcpy(c + 36, con + i + 5, min(35, n - (i + 5)));
memcpy(c + 36, con + i + 5, min(35, j - (i + 5)));
memcpy(user[x] + 36, con + i + 21, min(35, j - (i + 21)));
uses min() function:
int min(int x, int y)
{
return x < y ? x : y;
}
its return val is int,but memcpy's third element is size_t which is unsigned long long and we can let n-(i+5) equals to -1 (0xffffffffffffffff) ,then we can cause a Buffer overflow
ALSO
You can change the encode of body sothat it doesn't has any '&' and i is very large which can cause buffer overflow by memcpy
==================================================================================================================================================================
[Code Reference]
Danger code in password.h:
void login(int cl, const char *re, const char *con, int n, const char *id)
{
char c[72];
memset(c, 0, 72);
int i = 4;
for (; con[i]; i++)
if (con[i] == '&')
{
if (i - 4 < 1 || i - 4 > 35)
return mysend(cl, "");
memcpy(c, con + 4, i - 4);
if (!users.count((std::string)c))
return mysend(cl, "");
break;
}
memcpy(c + 36, con + i + 5, min(35, n - (i + 5)));
char *w = user[users[(std::string)c]];
for (int j = 36; j < 72; j++)
if (w[j] != c[j])
i = -1;
if (i == -1)
return mysend(cl, "");
char X4[] = "HTTP/1.1 200 OK\r\ncache-control: max-age=0, public\r\nContent-Length:75\r\nSet-Cookie: id= ; Max-Age=604800; Domain=121.36.103.216; Path=/; HttpOnly\r\n\r\n";
memcpy(X4 + 85, w + 72, 10);
write(cl, X4, strlen(X4));
}
void reg(int cl, const char *re, const char *con, int n, const char *id)
{
char c[128];
memset(c, 0, 128);
int i = 4, j;
for (; con[i]; i++)
if (con[i] == '&')
{
if (i - 4 < 1 || i - 4 > 35)
return mysend(cl, "");
memcpy(c, con + 4, i - 4);
if (users.count((std::string)c))
return mysend(cl, "");
break;
}
for (j = i + 5; con[j] && con[j] != '&'; j++)
;
memcpy(c + 36, con + i + 5, min(35, j - (i + 5)));
while (con[j] && con[j] != '=')
j++;
if (con[j])
j++;
while (con[j] && con[j] != '=')
j++;
memcpy(c + 82, con + j, min(46, strlen(con + j)));
for (i = 77; i < 82; i++)
c[i] = rand() % 26 + (rand() % 2 ? 'a' : 'A');
int x = users.size(), tx = x;
users.insert(std::pair(c, x));
for (i = 76; i >= 72; tx /= 26)
c[i--] = 'A' + tx % 26;
memcpy(user[x], c, 128);
mysend(cl, "");
}
void check_cookie_js(int cl, const char *re, const char *con, int n, const char *id)
{
int x = 0, i = 0;
for (; i < 5; i++)
x = x * 26 + id[i] - 'A';
if (0 <= x && x < users.size())
{
for (int j = 5; j < 10; j++)
if (id[j] != user[x][72 + j])
i = 0;
if (i == 5)
return mysend(cl, user[x]);
}
mysend(cl, "Not_Logged_In");
}
void change_password(int cl, const char *re, const char *con, int n, const char *id)
{
if (id[0] == '0')
return mysend(cl, "");
int x = 0, i = 0, j;
for (; i < 5; i++)
x = x * 26 + id[i] - 'A';
if (0 <= x && x < users.size())
{
for (; i < 10; i++)
if (id[i] != user[x][72 + i])
return mysend(cl, "");
for (i = 0; user[x][36 + i]; i++)
if (con[12 + i] != user[x][36 + i])
break;
if (user[x][36 + i] || con[12 + i] != '&')
return mysend(cl, "");
for (j = i + 21; con[j] && con[j] != '&';)
j++;
memset(user[x] + 36, 0, 36);
memcpy(user[x] + 36, con + i + 21, min(35, j - (i + 21)));
for (int i = 77; i < 82; i++)
user[x][i] = rand() % 26 + (rand() % 2 ? 'a' : 'A');
return mysend(cl, "");
}
mysend(cl, "");
}