Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: Crashing all users in server with error (Exploit) #1073

Open
Maxi605 opened this issue Dec 31, 2024 · 13 comments
Open

[BUG]: Crashing all users in server with error (Exploit) #1073

Maxi605 opened this issue Dec 31, 2024 · 13 comments
Assignees
Labels
Status: 🖐 available Task currently opened. Type: 🐞 bug An error that needs fixing.

Comments

@Maxi605
Copy link

Maxi605 commented Dec 31, 2024

👉👈 Contact Details (optional)

No response

🤔 What happened?

There seems to be a new (or old) exploit that continues to work with the latest ReHLDS release (I haven't tested on the dev actions) that the exploiter connects to the server and every player on the server crashes.

L 12/30/2024 - 02:02:50: "RAX<1614><>" connected, address "IPOFTHEPLAYER"

After he connects, everyone crashes with the error "Host_Error: DispatchUserMsg: User Msg ItemPickup/93 sent too much data (247 bytes), 192 bytes max."

A few weeks before, the user was doing the same or similar exploit, although the console printed the image below.
image

The server itself prints no messages about the error, just the connection of the attacker and the disconnection of everyone on the server.

The server is running with the latest public/official versions of ReHLDS, ReGameDLL, ReAPI and ReUnion.

⚠️ Meta-information

Protocol version 48
Exe version 1.1.2.7/Stdio (cstrike)
ReHLDS version: 3.13.0.798-dev
Build date: 00:41:40 Dec 14 2023 (3533)
Build from: https://github.com/dreamstalker/rehlds/commit/93f5775

ReGameDLL version: 5.26.0.668-dev
Build date: 19:02:48 Dec 31 2023
Build from: https://github.com/s1lentq/ReGameDLL_CS/commit/d3c0ec8

Linux Server.

📄 Relevant log output

No response

@Maxi605 Maxi605 added Status: 🖐 available Task currently opened. Type: 🐞 bug An error that needs fixing. labels Dec 31, 2024
@Maxi605 Maxi605 changed the title [BUG]: Crashing all users in server with error [BUG]: Crashing all users in server with error (Exploit) Dec 31, 2024
@justgo97
Copy link

ItemPickup is related to ReGameDLL, Also it's a message initaited by the server, Maybe it's a bug on the map? is it a custom map?

@Maxi605
Copy link
Author

Maxi605 commented Dec 31, 2024

ItemPickup is related to ReGameDLL, Also it's a message initaited by the server, Maybe it's a bug on the map? is it a custom map?

I was unsure where to post it. The exploit can be used in any map or any server for what i've seen. At the time, the map wasn't a custom map.

@Splatt581
Copy link

It seems that userinfo can contain some characters, after which reading of strings in svc_updateuserinfo breaks for game clients (because in the screenshot the client tries to parse svc_choke (* char), and then TutorText (s char), which looks like \*sid\ key).

A few weeks before, the user was doing the same or similar exploit, although the console printed the image below. image

Could you catch this error with the preset developer 1 cvar in the client console? The client will write a file cstrike/buffer.dat with the last parsed network messages. Attach this file to the post, it will give us more information about the problem.

@UnrealKaraulov
Copy link

UnrealKaraulov commented Jan 9, 2025

@Splatt581 yes

image

@UnrealKaraulov
Copy link

UnrealKaraulov commented Jan 9, 2025

image

svc_userinfo break forced, forced to svc_stufftext, then moved back to svc_userinfo?

@less1556
Copy link

less1556 commented Jan 12, 2025

I'd like to report a recent connection log to our server where the user has the following userinfo: "_cl_autowepswitch\1\bottomcolor\6\cl_dlmax\512\cl_lc\1\cl_lw\1\cl_updaterate\20\model\sas\name\TEST\topcolor\30\rate\20000\team\äÿäÿ#gign_label_+duck;"

When this user joins, it triggers the error described in this post.

@SupremeNTM
Copy link

Something like this?

Image

@less1556
Copy link

less1556 commented Jan 29, 2025

@SupremeNTM No, that's not the problem. In any case, here's a temporary fix

https://dev-cs.ru/resources/1775/

@SupremeNTM
Copy link

Thanks. I've implemented it.

@rndtrash
Copy link

rndtrash commented Feb 1, 2025

Still, it would be nice to have #1074 merged on the main branch 🙏🏻

@UnrealKaraulov
Copy link

Still, it would be nice to have #1074 merged on the main branch 🙏🏻

Latest rehlds release date : 2023-07-12. The patient is more alive than dead, but that’s not certain.

@bulevar20
Copy link

@SupremeNTM No, that's not the problem. In any case, here's a temporary fix

https://dev-cs.ru/resources/1775/

pls drop fix here, dev-cs.ru is down

@Maxi605
Copy link
Author

Maxi605 commented Feb 17, 2025

@SupremeNTM No, that's not the problem. In any case, here's a temporary fix
https://dev-cs.ru/resources/1775/

pls drop fix here, dev-cs.ru is down

#pragma semicolon 1

#include <amxmodx>
#include <reapi>

#define PLUGIN_NAME     "Safe Userinfo"
#define PLUGIN_VERSION  "1.0.4"
#define PLUGIN_AUTHOR   "the_hunter"

public plugin_init()
{
    register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR);
    RegisterHookChain(RH_SV_CheckUserInfo, "OnCheckUserInfo");
    RegisterHookChain(RH_SV_WriteFullClientUpdate, "OnWriteFullClientUpdate");
    RegisterHookChain(RG_CSGameRules_ClientUserInfoChanged, "OnClientUserInfoChanged");
}

public OnCheckUserInfo(address, buffer)
{
    if ((!IsValidUtf8InfoBuffer(buffer))) {
        SetHookChainReturn(ATYPE_INTEGER, false);
        return HC_BREAK;
    }

    return HC_CONTINUE;
}

public OnWriteFullClientUpdate(player, buffer)
{
    if ((!IsValidUtf8InfoBuffer(buffer))) {
        KickForInvalidUserInfo(player);
        return HC_BREAK;
    }

    return HC_CONTINUE;
}

public OnClientUserInfoChanged(player, info[])
{
    if ((!IsValidUtf8InfoString(info))) {
        KickForInvalidUserInfo(player);
        return HC_BREAK;
    }

    return HC_CONTINUE;
}

KickForInvalidUserInfo(player)
{
    rh_drop_client(player, "Invalid userinfo");
}

bool:IsValidUtf8InfoBuffer(buffer)
{
    const MAX_INFO_STRING = 256;

    new info[MAX_INFO_STRING];
    get_key_value_buffer(buffer, info, charsmax(info));

    return IsValidUtf8InfoString(info);
}

bool:IsValidUtf8InfoString(const info[])
{
    new i = 0;
    new bytes, codepoint;

    while (info[i] != EOS) {
        bytes = Utf8Codepoint(info, i, codepoint);

        if (bytes < 1) {
            return false;
        }

        // Reject control characters in the ranges U+0000–U+001F and U+007F–U+009F
        if (((codepoint >= 0x0000) && (codepoint <= 0x001F)) ||
            ((codepoint >= 0x007F) && (codepoint <= 0x009F))) {
            return false;
        }

        // Reject bidirectional text control characters
        if ((codepoint >= 0x202A) && (codepoint <= 0x202E)) {
            return false;
        }

        // Reject deprecated control characters
        if ((codepoint >= 0x206A) && (codepoint <= 0x206F)) {
            return false;
        }

        // Reject Line Separator and Paragraph Separator
        if ((0x2028 == codepoint) || (0x2029 == codepoint)) {
            return false;
        }

        i += bytes;
    }

    return true;
}

stock Utf8Codepoint(const string[], index, &codepoint)
{
    new curByte = string[index];

    if (EOS == curByte) {
        return 0;
    }

    // 4-byte UTF-8 codepoint
    if (0xF0 == (0xF8 & curByte)) {
        if ((EOS == string[(index + 1)]) || (EOS == string[(index + 2)]) || (EOS == string[(index + 3)])) {
            return 0; // Incomplete sequence
        }

        if ((0x80 != (0xC0 & string[(index + 1)])) ||
            (0x80 != (0xC0 & string[(index + 2)])) ||
            (0x80 != (0xC0 & string[(index + 3)]))) {
            return 0; // Invalid continuation byte
        }

        codepoint = (((0x07 & curByte) << 18) | ((0x3F & string[(index + 1)]) << 12) |
                    ((0x3F & string[(index + 2)]) << 6) | (0x3F & string[(index + 3)]));

        if ((codepoint < 0x010000) || (codepoint > 0x10FFFF)) {
            return 0; // Out of valid Unicode range
        }

        return 4;
    }

    // 3-byte UTF-8 codepoint
    if (0xE0 == (0xF0 & curByte)) {
        if ((EOS == string[(index + 1)]) || (EOS == string[(index + 2)])) {
            return 0; // Incomplete sequence
        }

        if ((0x80 != (0xC0 & string[(index + 1)])) || (0x80 != (0xC0 & string[(index + 2)]))) {
            return 0; // Invalid continuation byte
        }

        codepoint = (((0x0F & curByte) << 12) | ((0x3F & string[(index + 1)]) << 6) | (0x3F & string[(index + 2)]));

        if ((codepoint >= 0xD800) && (codepoint <= 0xDFFF)) {
            return 0; // Surrogate pairs are not allowed
        }

        if ((codepoint < 0x0800) || (codepoint > 0xFFFF)) {
            return 0; // Out of valid Unicode range
        }

        return 3;
    }

    // 2-byte UTF-8 codepoint
    if (0xC0 == (0xE0 & curByte)) {
        if (EOS == string[(index + 1)]) {
            return 0; // Incomplete sequence
        }

        if (0x80 != (0xC0 & string[(index + 1)])) {
            return 0; // Invalid continuation byte
        }

        codepoint = (((0x1F & curByte) << 6) | (0x3F & string[(index + 1)]));

        if ((codepoint < 0x0080) || (codepoint > 0x07FF)) {
            return 0; // Out of valid Unicode range
        }

        return 2;
    }

    // 1-byte UTF-8 codepoint
    if ((curByte > 0) && (curByte <= 0x007F)) {
        codepoint = curByte;
        return 1;
    }

    return 0; // Invalid start byte
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: 🖐 available Task currently opened. Type: 🐞 bug An error that needs fixing.
Projects
None yet
Development

No branches or pull requests

9 participants