Last active
February 26, 2016 23:32
-
-
Save leegao/1e7743b0d0e43a5ba2c4 to your computer and use it in GitHub Desktop.
Null-packet protection
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Let's not mangle these names | |
extern "C" { | |
#include "lua.h" | |
#include "lauxlib.h" | |
#include <sys/mman.h> | |
#include <stdio.h> | |
#include <sys/types.h> | |
#include <sys/ioctl.h> | |
#include <sys/socket.h> | |
#ifndef PAGESIZE | |
#define PAGESIZE 4096 | |
#endif | |
#define w [_i++] = | |
#define W(bb, x) bb[_i++] = (x) & 0xff; bb[_i++] = ((x) & 0xff00)>>8; \ | |
bb[_i++] = ((x) & 0xff0000)>>16; bb[_i++] = ((x) & 0xff000000)>>24 | |
int mine(int fd, int eax) { | |
static int first = 0; | |
if (!first) { | |
first = 1; | |
int opt = 1; | |
ioctl(fd, FIONBIO, &opt); | |
} | |
if (!eax) { | |
// Let's go ahead and waste the fd | |
char buf[1]; | |
int ret = recv(fd, buf, 1, MSG_PEEK); | |
if (ret == 0) { | |
recv(fd, buf, 0, 0); | |
printf("Caught a null packet!\n"); | |
} | |
} | |
return 0; | |
} | |
extern void shellcode_asm() { | |
asm("mov 0x8(%ebp), %edx\n" | |
"push 0x8(%edx)\n" | |
"mov $0x1234, %eax\n" | |
"call *%eax\n" | |
"pop %eax\n" | |
"cmp $-1, %eax\n" | |
"jnz next\n" | |
"mov $-1, %eax\n" | |
"mov $0x819ec7e, %edx\n" | |
"jmp *%edx\n" | |
"next:\n" | |
"mov $0x819ec79, %edx\n" | |
"jmp *%edx" | |
); | |
} | |
extern int prepare(void* from) { | |
void* page_start = (void*) (((unsigned long) from) & (~(PAGESIZE - 1))); | |
if (mprotect( | |
page_start, PAGESIZE, PROT_WRITE | PROT_READ | PROT_EXEC)) { | |
printf("Couldn’t mprotect"); | |
return -1; | |
} | |
return 0; | |
} | |
int redirect(void* from, void* to) { | |
char* bb = (char*) from; | |
int _i = 0; | |
unsigned long target = (unsigned long) to; | |
bb w 0x8d; bb w 0x45; bb w 0xfc; | |
bb w 0xb8; W(bb, target); | |
bb w 0xff; bb w 0xe0; // jmp *%rax | |
return 0; | |
} | |
int checksum() { | |
unsigned long start = 0x0819ec3c; | |
unsigned long end = 0x0819ec80; | |
unsigned long len = (end - start)/4; | |
unsigned int* buffer = (unsigned int*) start; | |
unsigned int checksum = 0; | |
for (int i = 0; i < len; i++) { | |
checksum = checksum ^ buffer[i]; | |
} | |
return checksum; | |
} | |
const char* shellcode = ((char*) shellcode_asm + 3); | |
// "\x8b\x55\x08" | |
// "\xff\x72\x08" | |
// "\xb8\x00\x00\x00\x00\xff\xd0" | |
// "\x58\x83\xf8\xff\x75\x0c\xb8\xff\xff\xff\xff\xba\x7e\xec" | |
// "\x19\x08\xff\xe2\xba\x79\xec\x19\x08\xff\xe2"; | |
int LUA_API luaopen_patch(lua_State *L) { | |
int check = checksum(); | |
printf("Checking server integrity: %x... \n", check); | |
if (check != 0x9cbfca47) { | |
printf("\tBad CS2D Server, are you sure you are on 1.0.0.1?\n"); | |
return 1; | |
} | |
if (prepare((void*) shellcode)) { | |
printf("\tCannot mutate code cave, aborting!\n"); | |
return 1; | |
} | |
char* call_loc = (char*) (shellcode + 7); | |
int _i = 0; | |
unsigned long target = (unsigned long) mine; | |
W(call_loc, target); | |
if (prepare((void*) 0x0819ec6d)) { | |
printf("\tCannot mutate buggy code, aborting!\n"); | |
return 1; | |
} | |
if (redirect((void*) 0x0819ec6d, (void*) shellcode)) { | |
printf("\tCannot redirect functions\n"); | |
return 1; | |
} | |
printf("Null-packet protection initialized successfully!\n"); | |
return 0; | |
} | |
int LUA_API luaopen_sys_lua_patch(lua_State *L) { | |
return luaopen_patch(L); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Build this on ubuntu or some other linux system with
and you can include it in sys/lua/server.lua with