You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
3.5 KiB

4 years ago
# BadEye
4 years ago
4 years ago
BattlEye proxies NtReadVirtualMemory and NtWriteVirtualMemory in lsass.exe/csrss.exe but doesnt bother to check the handle privilage....
4 years ago
<img src="https://imgur.com/5MjFoHg.png"/>
4 years ago
4 years ago
you cannot use this to read/write the process that battleye is protecting but you can use
this to read/write any other process you can open a simple handle too. `Rust`, `Valorant`, you name it, just open a `PROCESS_QUERY_LIMITED_INFORMATION` handle and pass it to `BEDaisy`. The reason
this works is two fold, firstly BattlEye assumes that the handle already has this access, secondly BattlEye only uses the handle to get the `EPROCESS` so they can call `MmCopyVirtualMemory`. You can see
this in my runtime logs of `BEDaisy`.
4 years ago
# lsass.exe/csrss.exe
4 years ago
```
01450790 126.99650574 [GoodEye]MmCopyVirtualMemory called from: 0xFFFFF804DEFE2E12
01450791 126.99652100 [GoodEye] - SourceProcess: upc.exe
01450792 126.99652100 [GoodEye] - SourceAddress: 0x00000000078EFBEC
01450793 126.99652100 [GoodEye] - TargetProcess: lsass.exe
01450794 126.99652100 [GoodEye] - TargetAddress: 0x000000B470EFE1F0
01450795 126.99652100 [GoodEye] - BufferSize: 0x000000000000001C
01450796 126.99662018 [GoodEye]IofCompleteRequest called from: 0xFFFFF804DEFE2E3D
01450797 126.99662018 [GoodEye] - Request Called From: lsass.exe
01450798 126.99662018 [GoodEye] - IRP_MJ_DEVICE_CONTROL!
01450799 126.99663544 [GoodEye] - IoControlCode: 0x0000000000222000 // ioctl read
01450800 126.99663544 [GoodEye] - InputBufferLength: 0x0000000000000030
01450801 126.99663544 [GoodEye] - OutputBufferLength: 0x0000000000000000
01450802 126.99663544 [GoodEye] - UserBuffer: 0x0000000000000000
01450803 126.99663544 [GoodEye] - MdlAddress: 0x0000000000000000
01450804 126.99663544 [GoodEye] - SystemBuffer: 0xFFFFB78765A0ECC0
```
4 years ago
This section will go into detail about what exactly is going on here. csrss.exe/lsass.exe have handles to all processes and since battleye strips the R/W access of the handle that these processes have
4 years ago
to the game it can cause system instability. Thus bedaisy writes two pages of shellcode to both processes and inline hooks `NtReadVirtualMemory` and `NtWriteVirtualMemory`.
4 years ago
If you run a battleye protected game, open cheat engine, attach to `lsass.exe`, and navigate to `NtReadVirtualMemory`/`NtWriteVirtualMemory` you will see this inline hook...
<img src="https://imgur.com/E7KAeoV.png"/>
This inline hook jumps to shellcode that packages all of the parameter values passed to `NtReadVirtualMemory` into the stack and then jumps to `DeviceIoControl`...
4 years ago
<img src="https://imgur.com/DpFyC9p.png"/>
Now that you have a basic understanding of how this system works (and sorta why it is), lets look at what we can do!
4 years ago
To begin we need to extract the driver handle at runtime, this can be done simply by extracting the address of the shellcode out of the inline hook of `NtReadVirtualMemory`. Now that we have
4 years ago
the handle to the driver we can start sending IOCTL's to BattlEye. The IOCTL data is not encrypted nor complicated... this is what it looks like:
4 years ago
```cpp
4 years ago
struct beioctl
{
void* ret_addr;
HANDLE handle;
void* base_addr;
void* buffer;
size_t buffer_size;
size_t* bytes_read;
};
4 years ago
```
4 years ago
4 years ago
In order to use this ioctl/functionality of bedaisy you need to put a valid return address into this structure. You can do that by sig scanning `lsasrv.dll` with this signature:
`0f 1f 44 00 ? 8b f0 48 8b 0d ? ? ? ? 49 3b cd` the address of this instruction is what you want to be your return address.
4 years ago
4 years ago