Exploiting simple network services in CTF’s
For those of you that enjoy CTF’s here are a few tips on how you can go about testing non HTTP network services.
There are plenty of different services out there to test with, and this is by no means an exhaustive tutorial, but gives you a few tips to get started testing non HTTP based services.
So how could we approach attacking these services?
In CTF challenges where you are given the binary it can make like alot easier as you can decompile the software to understand its structure and how the binary operates.
Initially you may start with:
- running
stringsto identify readable text within the binary. - Extracting the binary (depending on its format) using tools such as
objdump, NSA's Ghindra framework, OllyDbg etc.
Then use the insights you gain from debugging the code locally to understand how the software is operating.
Typically in the case of CTF’s these binaries won’t contain the flag you want to capture, but have the same program structure so that you can build a network based attack.
Once you have an initial understanding run the binary and debug with GDB. ExploitDB has a quick primer
- Examine the behaviour with different inputs
- Walk through the logical functionality of the program
If you don’t have access to the binary you may need to start with the socket service and develop your knowledge in a more automated way. You can use the same approach with a local binary or network service.
Using python to test the service
Python provides the socket to interact directly with TCP sockets.
It is also possible to treat the socket as a file like object. This can be useful if you have a copy of a binary to decompile and examine and a webservice that you are testing such as in HackTheBox.eu Little_Tommy challenge where you are provided with a binary that you can reverse and a webservice to attack that is running said binary.
With this knowledge you can quickly start to test the service and fuzz for vulnerabilities.
In line with the code of conduct on HackTheBox the solution isn’t here for the challenge, but the tools and techniques apply.
First off setup your python environment. Since this is a simple task using pipenv may be an overkill, but i’d recommend using a virtualenv at the very least.
Once you have your environment setup you can connect to the webservice. E.g.
import socketdef connect(server, port):
# open a connection to vulnserver
s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
s.connect ((server, port))
return sdef read_until(s, delim=b':'):
buf = b''
while not buf.endswith(delim):
buf += s.recv(1)
return bufif __name__ == "__main__":
PORT = 12345
SERVER = '<THE HOSTNAME OR IP>' s = connect(SERVER, PORT)
print(read_until(s))In the code above it assumes we are using a network service as we are communicating directly with the socket. You could also interact with a file like object that can make it easier to work with the local binary if you have it. Then you can interact with the socket in the same way you would reading and writing to a file in python.
In the code above all we are doing first off is establishing a connection to the server then reading from the socket byte by byte until we reach the delimiter character, which I have defaulted to :.
To Run the code copy and paste into a file and run e.g. python readuntil.py
The response from the server will be printed.
From here you can start to develop functions to fuzz the service with different inputs in an exploratory manner to understand how the service works and try out different inputs in a consistent and repeatable manner.
For example if you wanted to test for a buffer overflow a simple for loop could suffice. E.g. if the service returns a prompt for input then awaits your input and requires a newline to accept the input.
def overflow_input(num_chars=128):
for i in range(1, num_chars):
try:
s = connect(SERVER,PORT)
read_until(s)
data = 'A' * i + '\n'
data = bytes(data, encoding='utf-8')
s.send(data)
except:
print(f"Server crashed with input size {i}")
finally:
s.close()The code will simply loop and feed larger and larger input seeking a crash of the server which can give you an intial starting point to exploit the service.
By using building blocks such as these you can quickly start to test out network services and local binaries.






