Skip to content

Instantly share code, notes, and snippets.

@leegao
Last active February 26, 2016 23:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leegao/1e7743b0d0e43a5ba2c4 to your computer and use it in GitHub Desktop.
Save leegao/1e7743b0d0e43a5ba2c4 to your computer and use it in GitHub Desktop.
Null-packet protection
// 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);
}
}
@leegao
Copy link
Author

leegao commented Feb 26, 2016

Build this on ubuntu or some other linux system with

gcc -g -L %LUA_DIRECTORY%/lib/ -I%LUA_DIRECTORY%/includes/ -fpermissive -fPIC --shared -m32 -o patch.so patch.cpp -llua

and you can include it in sys/lua/server.lua with

require 'sys.lua.patch'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment