So... a hack was released that made a highlight of a very important Ebenezer flaw.
Basically, it was able to send GM commands through the chat packet - without having to even be logged in.
But how does the exploit actually work?
Well...
As the hack doesn't login, the character also hasn't been selected, and well, the character's Authority hasn't been set in Ebenezer.
This means that the Authority stays as it is - 0. We all should know that the 0 Authority indicates that a user is a Game Master!
So, because of this, when the hack sends the chat packet, Ebenezer goes "hey, they have the Authority 0 - that means I can pass it on to my dear friend CEbenezerDlg::OperationMessage, where they'll (hopefully!) handle it with care". CEbenezerDlg::OperationMessage then handles the command itself, and does whatever it needs to do.
With that said, the question then is how do we fix the problem?
Quite simply, we need to set the default Authority to something other than 0. I use 1, but you could also use 2 (muted) or 255 (banned). Either way, they don't have access to execute any GM commands.
Now, another big flaw is that Ebenezer does not at all check if a user is logged in throughout the many packet handlers it has.
This means that if you send a packet to Ebenezer, if you are logged in or not, it will heed the request, and carry it out (depending on the packet) - even though you're not actually logged in!
This is just a problem waiting to happen - if we checked to see if the user was logged in before going ahead with handling packets (that is, all except the first two - version & login request), the Authority issue for one would be nearly completely removed. The released hack would not work any longer, however if you hooked the client's send function and sent the GM command/s at the character selection screen, the hack would still be effective, as the login check would say you've logged in - but the Authority has yet to be set (it is set when you select a character).
So, instead of doing one or the other, I have combined the two into one relatively large-sized patch which I really have to thank mgame for.
I suppose you could say this patch also patches the kill-switch exploit... I decided to use the kill-switch's check (before the packet handler), and also its function for my code-cave.
Well, here's the patch - each line is commented, so you know what's going on).
; Above the packet handler- 00490995 . E9 16400300 JMP Ebenezer.004C49B0; Replace the kill-switch checks with a jump to our code-cave
- 0049099A 90 NOP; Rest of it is nopped out.
- 0049099B 90 NOP
- 0049099C 90 NOP
- 0049099D 90 NOP
- 0049099E 90 NOP
- 0049099F 90 NOP
- 004909A0 90 NOP
- 004909A1 90 NOP
- 004909A2 90 NOP
- 004909A3 90 NOP
- ; In our code-cave
- 004C49B0 > 83FA 2B CMP EDX,2B ; Check for version packet
- 004C49B3 . 74 17 JE SHORT Ebenezer.004C49CC ; If version packet, jump back to switch (no account ID set yet)
- 004C49B5 . 83FA 01 CMP EDX,1 ; Check for login packet
- 004C49B8 74 17 JE SHORT Ebenezer.004C49D1 ; If login packet, set the Authority to 1 [default before it's retrieved from the database] and jump back to switch (it's set in this packet's handler)
- 004C49BA . 52 PUSH EDX ; Push EDX/opcode onto the stack
- 004C49BB . 8A96 9C800000 MOV DL,BYTE PTR DS:[ESI+809C] ; Store first byte of account name in DL
- 004C49C1 . 80FA 00 CMP DL,0 ; Compare first byte of account name to 0x00/NULL
- 004C49C4 . 5A POP EDX ; Pop EDX/opcode off the stack
- 004C49C5 . 75 05 JNZ SHORT Ebenezer.004C49CC ; Byte isn't NULL, jump to packet handler!
- 004C49C7 . BA FFFFFFFF MOV EDX,-1 ; Byte is NULL, set the opcode to -1 (so it's not handled)
- 004C49CC >^E9 D3BFFCFF JMP Ebenezer.004909A4 ; Back to the packet handler we go!
- 004C49D1 50 PUSH EAX ; Push EAX (used in the CUser::Parsing func we jumped from for something [not relevant]) onto the stack
- 004C49D2 8B86 98800000 MOV EAX,DWORD PTR DS:[ESI+8098] ; Store the pointer to the user's struct in eax
- 004C49D8 C640 71 01 MOV BYTE PTR DS:[EAX+71],1 ; Set the user's Authority to 1
- 004C49DC 58 POP EAX ; Pop eax off the stack
- 004C49DD ^EB ED JMP SHORT Ebenezer.004C49CC ; Jump back to CUser::Parsing
复制代码 You can use OllyDbg to patch this one up, or just use my updated version of the Ebenezer/Client Editor - which will be released very soon. ;) |