BattlEye communication hook

栏目: IT技术 · 发布时间: 4年前

内容简介:To combat masses of video game hackers, anti cheat systems need to collect and process a lot of information from clients. This is usually usually done by sending everything to the servers for further analysis, which allows the attackers to circumvent these

To combat masses of video game hackers, anti cheat systems need to collect and process a lot of information from clients. This is usually usually done by sending everything to the servers for further analysis, which allows the attackers to circumvent these systems through interesting means, one of them being hijack of the communication routine.

If an anti cheat is trying to detect a certain cheat by, for example, the name of the process that hosts the cheat code, it will usually parse the entire process list and send it to the server. This way of outsourcing the processing prevents cheaters from reverse engineering the blacklisted process names, as all they can see is that the *entire* process list is sent to the anti cheat server. This is actually becoming more and more prevalent in the anti cheat community, which raises some serious privacy concerns, simply due to the sheer amount of information being sent to a foreign server.

BattlEye, one of the world’s most installed anti cheats, uses such a routine to send data to their master server over UDP. This function is usually referred to as battleye::send or battleye::report (as in my previous articles). It takes two parameters: buffer and size. Every single piece of information sent to the BattlEye servers is passed through this function, making it very lucrative for hackers to intercept, possibly circumventing every single protection as the game can’t report the anomalies if a hacker is the middleman of communcations. Few cheat developers are actively using this method, as most of them lack the technical skills to reverse engineer and deobfuscate the dynamically streamed modules that BattlEye heavily relies on, but in this post i will shed some light on how this communication routine is being actively exploited, and how BattlEye has tried to mitigate it.

Abuse

BattlEye’s communication routine resides in the module BEClient, which is loaded dynamically by the protected game process. This routine takes “packets” with a two byte header and varying content length, encrypts and afterwards transmits them to the BattlEye server over UDP. Detection routines such asthe timing detection orthe single stepper rely on this communication, as the results of these tests are sent unfiltered to the BattlEye server for processing. What would happen if you were to hook this function, and simply modify the raw data being sent to prevent the server from banning you? Absolutely nothing, for many years up until last year, when BattlEye added integrity checks of battleye::report to the obfuscated module BEClient2. This integrity check is described in the following section.

Mitigation

It seems to have been desperate times for the BattlEye developers, as they discovered the prevalence of battleye::report hooking in private, highly exclusive cheats in games such as Rainbow Six: Siege and PUBG . Ideally, you would run complete integrity checks of the respective module to ensure fair play, but BattlEye has a very long history of low effort, band-aid fixes , and this is no exception. If you are willing to spend hours on end to devirtualize the module BEClient2, you will notice this integrity check:

*(std::uint64_t*)&report_table[0x3A] = battleye::report;
if ( *(std::uint32_t*)(battleye::report + 5) == 0xCCCCCCCC && 
	 *(std::uint32_t*)(battleye::report + 0x1506CA) == 0xFFF3BF25 &&
    (*(std::uint32_t*)(battleye::report + 1) != 0x1506C9 || *((std::uint8_t*)battleye::report + 0x1506CE) != 0x68) )
{
	report_table[0x43] = 1;
}

Instead of doing a full integrity check by, for example running hash comparisons of the module’s code, they’ve decided to simply test certain portions of the function and set a boolean if the conditions are met. If we ignore the poor attempt at integrity checks for a second, how is report_table transmitted to BattlEye’s servers?

battleye::report(report_table, sizeof(report_table));
return;

Holy shit!Not only are the integrity checks very primitive, it relies on its own integrity! This means that any hacker that is already hooking the communication routine and triggering the integrity check, can control the result of the same exact check *facepalm*. This is actually really trivial to bypass:

Circumvention

As you can see from the integrity check, the result is stored in the report data array + 0x43. With a hook, this can be trivially bypassed as nothing stops you from setting the integrity check result to fit the bill:

void battleye_report_hook(const std::uint8_t* buffer, const std::size_t size)
{
	// ? BECLIENT2 PACKET ?
	if (buffer[1] == PACKET_BECLIENT2) // 0x39
	{
		// SET INTEGRITY CHECK RESULT
		buffer[0x43] = true;
	}

	// SEND THE INFORMATION TO BATTLEYE SERVERS
	original_fn(buffer, size);
}

Exercise for the reader: the buffer is actually encrypted with a simple xor key (literally the tick count of when the packet was generated, it’s stored in plaintext at (std::uint32_t)report_table[0x1FC]


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web Development Recipes

Web Development Recipes

Brian P. Hogan、Chris Warren、Mike Weber、Chris Johnson、Aaron Godin / Pragmatic Bookshelf / 2012-1-22 / USD 35.00

You'll see a full spectrum of cutting-edge web development techniques, from UI and eye candy recipes to solutions for data analysis, testing, and web hosting. Make buttons and content stand out with s......一起来看看 《Web Development Recipes》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试