diff -r abc45724b267 -r 5a5729358afc handouts/ho03.tex --- a/handouts/ho03.tex Fri Oct 10 12:17:49 2014 +0100 +++ b/handouts/ho03.tex Fri Oct 10 12:38:48 2014 +0100 @@ -473,6 +473,40 @@ \lstinputlisting[language=C]{../progs/C4.c} +\noindent The intention is to print out the first argument +given on the command line. The ``secret string'' is never to +be printed. The problem is that the C function \pcode{printf} +normally expects a format string---a schema that directs how a +string should be printed. This would be for example a proper +invocation of this function: + +\begin{lstlisting}[numbers=none,language=C] +long n = 123456789; +printf("This is a long %lu!", n); +\end{lstlisting} + +\noindent In the program above, instead, the format string +has been forgotten and only \pcode{argv[1]} is printed. +Now if we give on the command line a string such as + +\begin{center} +\code{"foo \%s"} +\end{center} + +\noindent then \pcode{printf} expects a string to +follow. But there is no string that follows, and how +the argument resolution works in C will in fact print out +the secret string! This can be handily exploited by +using the format string \code{"\%x"}, which reads out the +stack. So \code{"\%x....\%x"} will give you as much +information from the stack as you need and over the +Internet. + +While the program above contains clearly a programming +mistake (forgotten format string), things are not as simple +when the application reads data from the user and prompts +responses containing the user input. + \subsubsection*{Caveats} \bigskip\bigskip