From efa3572d52512719971c012538757d95f990eccd Mon Sep 17 00:00:00 2001 From: Szymon Marczak <36894700+szmarczak@users.noreply.github.com> Date: Mon, 3 Aug 2020 17:57:33 +0200 Subject: [PATCH] sv_pure_bypass_3 (#17) * sv_pure_bypass_3 --- README.md | 7 +- model_bug/README.md | 5 +- sv_pure_bypass/README.md | 5 + sv_pure_bypass_2-electric_boogaloo/README.md | 2 + sv_pure_bypass_3/README.md | 49 +++++++++ sv_pure_bypass_3/generateWallhack.js | 101 +++++++++++++++++++ 6 files changed, 164 insertions(+), 5 deletions(-) create mode 100644 sv_pure_bypass_3/README.md create mode 100644 sv_pure_bypass_3/generateWallhack.js diff --git a/README.md b/README.md index b0b7725..68fe6fa 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ I post bugs, tricks, exploits and other stuff here when I feel like it. -Why post stuff like this in public? Valve doesn't care anymore, see the model_bug. +Why post stuff like this in public? Valve doesn't care anymore, see the [model_bug](model_bug). ### Status @@ -8,7 +8,8 @@ Why post stuff like this in public? Valve doesn't care anymore, see the model_bu |--------------------|----------|------------|-------------| | model_bug | No | ??-10-2018 | Never | | panora_mitm_xss | Yes | 04-05-2019 | 07-05-2019 | -| sv_pure_bypass | No | ??-05-2019 | | -| sv_pure_bypass_2 | Yes | ??-10-2019 | 05-04-2020 | +| sv_pure_bypass | Yes | ??-05-2019 | 29-07-2020 | +| sv_pure_bypass_2 | Yes | ??-10-2019 | 05-04-2020 | +| sv_pure_bypass_3 | No | ??-06-2020 | | | con_logfile_tricks | Somewhat | ??-??-2018 | | | netcon_stuff | No | ??-03-2020 | | diff --git a/model_bug/README.md b/model_bug/README.md index 7c07f17..d1f87f6 100644 --- a/model_bug/README.md +++ b/model_bug/README.md @@ -1,8 +1,9 @@ -Original Issue: https://github.com/ValveSoftware/csgo-osx-linux/issues/1888 +Original issue: https://github.com/ValveSoftware/csgo-osx-linux/issues/1888 -First reported in october 2018, reported multiple times since. Never received any response. +First reported in October 2018, reported multiple times since. Never received any response. ## Original issue text below + The engine seems to cache loaded props (between map change) for maps with packed textures, which allows you to bug the loading of models and allow the player to see through props on the map, granting an undetectable wallhack. I will be using the official map de_cache as an example in this issue. diff --git a/sv_pure_bypass/README.md b/sv_pure_bypass/README.md index 2ebdfb7..beb6a51 100644 --- a/sv_pure_bypass/README.md +++ b/sv_pure_bypass/README.md @@ -1,12 +1,17 @@ ## sv\_pure bypass (for some files) + +*Fixed 7/29/2020* + Official valve servers, and most community servers, run with `sv_pure 1`. This causes the client to send crc hashes of the files defined in `pure_server_whitelist.txt` to the server. The server then matches the hashes and kicks the player if there is a mismatch. It seems that this is implemented poorly and for some files it's possible to bypass this check. If the file is loaded on game launch, and then again on map load, the CRC is generated on game launch, but not regenerated on map load. This makes it possible to load the game, then replace the file and not be kicked on sv_pure 1 servers. ### Caveats + I didn't do a lot of testing of this, so I pretty much just focused on the easiest file to exploit (soundmixers.txt). There are other files that are loaded on map load, like a bunch of shaders, and some other files in the script folder, but nothing really stood out as interesting or easy to test. It might be possible that the pak files can be modified after load, but it seemed like too much work to verify. Someone should check it out. ### soundmixers.txt example + In the soundmixer folder is a fully automated script, for using a custom soundmixers.txt file on sv_pure 1 servers. The manual process is very easy though: diff --git a/sv_pure_bypass_2-electric_boogaloo/README.md b/sv_pure_bypass_2-electric_boogaloo/README.md index 78b21ec..8196e28 100644 --- a/sv_pure_bypass_2-electric_boogaloo/README.md +++ b/sv_pure_bypass_2-electric_boogaloo/README.md @@ -7,9 +7,11 @@ Official valve servers, and most community servers, run with `sv_pure 1`. This c When loading some game files, the engine tries to load from the platform folder, before trying to load from the csgo folder. The platform folder is however not checked by sv_pure at all, thus giving us yet another sv_pure bypass. ### Caveats + I didn't do a lot of testing of this, so I pretty much just focused on the easiest file to exploit (soundmixers.txt). There are other files that are loaded on map load, like a bunch of shaders, and some other files in the script folder, but nothing really stood out as interesting or easy to test. It might be possible that the pak files can be modified after load, but it seemed like too much work to verify. Someone should check it out. ### soundmixers.txt example + The file soundmixers.txt contains an example of a modified soundmixers file. It mutes own footsteps, doubles the volume of enemy footsteps, lowers own gun sounds, raises other gun sounds. To utilize this feature, download the soundmixers.txt file and put it in: [STEAM PATH]\steamapps\common\Counter-Strike Global Offensive\platform\scripts\ diff --git a/sv_pure_bypass_3/README.md b/sv_pure_bypass_3/README.md new file mode 100644 index 0000000..e417bea --- /dev/null +++ b/sv_pure_bypass_3/README.md @@ -0,0 +1,49 @@ +## sv\_pure bypass \#3 + +Official valve servers, and most community servers, run with `sv_pure 1`. This causes the client to send crc hashes of the files defined in `pure_server_whitelist.txt` to the server. The server then matches the hashes and kicks the player if there is a mismatch. + +It seems that this is implemented poorly and for some `pak01_###.vpk` files it's possible to bypass this check. As `sv_pure_allow_missing_files ` defaults to `1`, you can join the server without `pak01_008.vpk`. It contains some [VMT](https://developer.valvesoftware.com/wiki/Material) definitions, and when they are missing, the textures of agents will be black because of missing skins. + +### Caveats + +1. Some VPK files are required to be present at the game startup, e.g. `pak01_006.vpk`, otherwise the game will crash. +2. Sometimes you may end up getting a [file mismatch](https://support.steampowered.com/kb_article.php?ref=8285-YOAZ-6049) error. If you rejoin the server and aren't kicked immediately, you can keep playing indefinitely. + +### Steps + +0. Download this [`pak01_008.vpk_`](https://gofile.io/d/CkZmXs) or generate one using the instructions below. +1. Make sure CS:GO is closed. +2. Rename the original `pak01_008.vpk` to `pak01_008.vpk.bak`. +3. Copy `pak01_008.vpk_` into the `csgo` folder. Do not delete the trailing `_` yet! +4. Run CS:GO. +5. Connect to any `sv_pure 1` server and wait till you spawn. +6. Disconnect from the server. +7. Rename `pak01_008.vpk_` to `pak01_008.vpk`. +8. Change shader settings to high / low. +9. Reconnect. +10. Profit! VAC-proof wallhack. + +If you run `sv_pure_listfiles`, you can see that all files are verified. Although, you may get: + +``` +File c:\program files (x86)\steam\steamapps\common\counter-strike global offensive\csgo\pak01_008.vpk offset 2500000 hash 5455e4ec6e85785e16057104a706b2b5 does not match ( should be bf8792d18d795a2cf3f8ec268be2eb2b ) +``` + +It is unsure whether it will get you kicked or not. More feedback needed. + +#### Generating `pak01_008.vpk` with wallhacks + +It's pretty simple. You just need [Node.js](https://nodejs.org/en/download/current/) to be able to run the script. All it does it creates a copy of `pak01_008.vpk` file named `pak01_008.vpkwh`. It replaces `"$ambientreflectionboost" "someValueHere"`, `"$phongalbedoboost" "someValueHere"` and `"$rimlightalbedo" "someValueHere"` with `"$ignorez" "1"` and keeps the file size the same. + +1. Copy the `generateWallhack.js` file to `C:\Program Files (x86)\Steam\steamapps\common\Counter-Strike Global Offensive\csgo`. +2. Open Windows Command Prompt. Execute +``` +cd "C:\Program Files (x86)\Steam\steamapps\common\Counter-Strike Global Offensive\csgo" +``` +3. Run `node generateWallhack.js`. + +### Credits + +* [DepoSit](https://www.youtube.com/watch?v=aL2rQzhFTn4) for discovering the bug on Danger Zone servers. +* [@mbhound](https://github.com/mbhound) for further testing on matchmaking servers. +* [@szmarczak](https://github.com/szmarczak) for preparing the `pak01_008.vpk_` file. diff --git a/sv_pure_bypass_3/generateWallhack.js b/sv_pure_bypass_3/generateWallhack.js new file mode 100644 index 0000000..67856b0 --- /dev/null +++ b/sv_pure_bypass_3/generateWallhack.js @@ -0,0 +1,101 @@ +const fs = require('fs'); + +const addMissingZeros = i => { + if (i < 10) { + return `00${i}`; + } + + if (i < 100) { + return `0${i}`; + } + + return i; +}; + +const keys = [ + 'rimlightalbedo', + 'phongalbedoboost', + 'ambientreflectionboost' +]; + +const allowedCharacters = '0123456789.'.split('').map(x => x.charCodeAt(0)); + +let entry = 1; + +const next = (vpk = 0) => { + if (vpk > 130) { + console.log('Done!'); + return; + } + + const filename = `pak01_${addMissingZeros(vpk)}.vpk`; + + const buffer = fs.readFileSync(filename); + + const prevEntry = entry; + + for (const key of keys) { + const search = `${key}" `; + + let start = 0; + let indexOf; + + while (true) { + indexOf = buffer.indexOf(search, start); + + if (indexOf === -1) { + break; + } + + let i = indexOf + search.length; + while (buffer[i] === 32) { // space + i++; + } + + let numberBuffer = ''; + if (buffer[i] === 34) { // " + i++; + + let iterated = 0; + while (true) { + if (allowedCharacters.includes(buffer[i]) && iterated < 4) { + numberBuffer += String.fromCharCode(buffer[i]); + i++; + iterated++; + } else { + break; + } + } + + if (Number.isNaN(Number(numberBuffer)) || buffer[i] !== 34) { // " + start = i; + continue; + } + + console.log(`Found ${entry++}!`, buffer.slice(indexOf, i + 1).toString()); + + const str = 'ignorez" "1"'; + const wanted = `${str}${Buffer.alloc((i - indexOf) - str.length + 1).fill(' ')}`; + buffer.write(wanted, indexOf); + // console.log('Written!', buffer.slice(indexOf, i + 1).toString()); + + start = i; + } else { + break; + } + } + } + + if (entry === prevEntry) { + console.log(`[${filename}] No matches.`); + // next(vpk + 1); + } else { + fs.createWriteStream(`${filename}wh`).end(buffer, error => { + console.log(`[${filename}] Write successful: `, !error, error); + + // next(vpk + 1); + }); + } +}; + +next(8);