Skip to content

Commit

Permalink
changes
Browse files Browse the repository at this point in the history
  • Loading branch information
m-heim committed Feb 16, 2023
1 parent 55c50d0 commit fdbc3a5
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 3 deletions.
13 changes: 13 additions & 0 deletions determinewordcount.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import os
import sys

def determine_word_count(target_program_path: str, buffer_size: int) -> int:
for words in range(1, buffer_size + 64):
if os.system(target_program_path + ' ' + 'AAAA' * words):
return words - 1
return -1

if __name__ == '__main__':
word_count = determine_word_count(sys.argv[1], int(sys.argv[2]))
print('Required words: ' + str(word_count))
print('String: ' + 'AAAA' * word_count)
3 changes: 3 additions & 0 deletions gdbtoomany.gdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
(gdb)
Binary file modified paper.pdf
Binary file not shown.
14 changes: 11 additions & 3 deletions paper.tex
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,18 @@ \subsection{Phases of developing the attack}
\item Insert payload into target using a vulnerability
\end{enumerate}
\paragraph{Goal and abstract payload}
After specifying the goal and possibly simplifying it we have to write a list of instructions and arguments that achieve the goal, for this its favorable to directly use the format of the final payload except for using instructions instead of addresses as this will then allow to simply insert the found gadgets into this abstract payload. For the example in this paper we want to open a shell, for that the simplest way is to execute an execve system call. The following program state has to be achieved so the interrupt \bltInlineVerb{int 0x80} causes a shell to be opened.

After specifying the goal and possibly simplifying it we have to write a list of instructions and arguments that achieve the goal, for this its favorable to directly use the format of the final payload except for using instructions instead of addresses as this will then allow to simply insert the found gadgets into this abstract payload. For the example in this paper we want to open a shell, for that the simplest way is to execute an execve system call. The following program state~\cref{fig:stateforint} has to be achieved so the interrupt \bltInlineVerb{int 0x80} causes a shell to be opened.
\begin{figure}[h]
\centering
\includegraphics[width=0.95\textwidth]{Stateforexecve.png}
\caption{Required program state for the execve syscall}
\label{fig:stateforint}
\end{figure}
\paragraph{Extract and search gadgets}
After extracting the gadgets using one of the above mentioned methods we can search for gadgets
\paragraph{Determining the padding}
Compilers optimize stack alignment and without providing options to change that the simplest way to determine the padding required is to test the program until it crashes with a payload increasing by 1 word in each iteration. This can be automated in a Python script~\cref{code:determinewordcount}. This script applies the method mentioned above with the \bltInlineVerb{os.system} function. The return value of that function is the exit code of the program that has been executed and is either \Verb+0+ when the execution ended without any errors and non \Verb+0+ when an error or exception occured during startup or runtime. This means we can increase the input by \bltInlineVerb{"AAAA"} in each iteration until the return value is non zero. At this point the base pointer \bltInlineVerb{ebp} has been overridden causing the program to crash. Now reducing the padding by 1 word results in the correct amount.
\bltCode{determinewordcount.py}{python}{A Python Script to Determine the Required Words}{code:determinewordcount}
we have overwritten the return instruction pointer with \bltInlineVerb{"BBBB"}. Reducing the amount of \Verb+A+'s by 4 the first gadget overrides the return address of the function call and on \Verb+ret+ the execution gets redirected to the first gadget.
\paragraph{struct.pack}
\Verb+struct.pack+ is a Python function that allows to easily generate our desired payload from the raw bytes. Bash then allows to directly pipe the generated payload into our target. In order to generate the payload we first have to fill the buffer and override the EBP with arbitary values as seen in line 2~\cref{howtopack}. This is usually done using easily recognizable characters, using the letter \Verb+A+ for this is common. It has the hex value \Verb+0x41+, doing this allows then to spot the buffer in a debugger like \Verb+gdb+. So in this example we fill the buffer with 8 \Verb+A+'s and 4 \Verb+B+'s. After that it is time to insert the addresses of the gadgets and the arguments. This is done by calling pack with the double word (64 Bit) while specifying the endianness, converting that to a string and adding it to the string as seen in line 3~\cref{howtopack}. After the whole payload has been generated we can print it and use the output directly for running the buffer overflow attack as mentioned above.
\bltCode{pack.py}{python}{How to use struct.pack}{howtopack}
Expand Down
Binary file modified vuln
Binary file not shown.

0 comments on commit fdbc3a5

Please sign in to comment.