\documentclass[12pt,a4paper]{article} \usepackage[cm]{fullpage} \usepackage{amsthm} \usepackage{amsmath} \usepackage{amsfonts} \usepackage{amssymb} \usepackage{xspace} \usepackage[english]{babel} \usepackage{fancyhdr} \usepackage{titling} \usepackage{minted} \usepackage{xcolor} % to access the named colour LightGray \definecolor{LightGray}{gray}{0.9} \renewcommand{\thesection}{Exercise \Alph{section}:} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % This part needs customization from you % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % please enter your group number your names and matriculation numbers here \newcommand{\groupnumber}{04} \newcommand{\name}{Tobias Eidelpes, Mehmet Ege Demirsoy, Nejra Komic} \newcommand{\matriculation}{01527193, 01641187, 11719704} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % End of customization % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\projnumber}{2} \newcommand{\Title}{Smart Contracts} \setlength{\headheight}{15.2pt} \setlength{\headsep}{20pt} \setlength{\textheight}{680pt} \pagestyle{fancy} \fancyhf{} \fancyhead[L]{Cryptocurrencies - Project \projnumber\ - Analysing the Blockchain} \fancyhead[C]{} \fancyhead[R]{\name} \renewcommand{\headrulewidth}{0.4pt} \fancyfoot[C]{\thepage} \begin{document} \thispagestyle{empty} \noindent\framebox[\linewidth]{% \begin{minipage}{\linewidth}% \hspace*{5pt} \textbf{Cryptocurrencies (WS2021/22)} \hfill Prof.~Matteo Maffei \hspace*{5pt}\\ \begin{center} {\bf\Large Project \projnumber~-- \Title} \end{center} \vspace*{5pt}\hspace*{5pt} \hfill TU Wien \hspace*{5pt} \end{minipage}% } \vspace{0.5cm} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section*{Group \groupnumber} Our group consists of the following members: \begin{center} \textbf{\name} \matriculation \end{center} \section{Bad Parity} For this challenge we were given two contracts: \texttt{Wallet} and \texttt{WalletLibrary}. The second contract is used by the \texttt{Wallet} contract to set the owner upon initialization, to get the current owner, to change the owner and to withdraw funds from the wallet. These functions are called from the \texttt{Wallet} contract through the use of the \texttt{delegatecall} function. In contrast to a regular \texttt{call}, \texttt{delegatecall} executes the function in the context of the \emph{calling} smart contract. This means that if there happens to be a variable in both contracts with the same name and a function changes that variable, the \emph{caller's} and not the \emph{callee's} variable is changed. If insufficient care is exercised during programming, the semantics of \texttt{delegatecall} can have serious security implications, as in this case with \texttt{Wallet} and \texttt{WalletLibrary}. The \texttt{fallback} function in \texttt{Wallet} is called when the smart contract receives a transaction with empty call data or call data which does not match any other function. The call data sent with the transaction is then passed to the \texttt{WalletLibrary} contract via \texttt{delegatecall}. The \texttt{WalletLibrary} contract has a function called \texttt{initWallet} which sets the owner of the contract to the given address. Usually this function would be called only upon initialization of the contract (in the constructor for example). We can call this function at any time by supplying the correct call data to the \texttt{fallback} function from the \texttt{Wallet} contract. Since the function is then called via \texttt{delegatecall}, the owner of the \texttt{Wallet} contract is changed to an address of our choosing. To trigger the \texttt{initWallet} function, the call data must contain the signature of the function and all parameters. The function signature is the first four bytes of the keccak hash of the function name and the types of its parameters. Any parameters are added to the signature in a padded form. Creating the call data in python works as follows (where \texttt{address} is the address of the new owner): \begin{minted}[frame=lines,framesep=2mm,bgcolor=LightGray,fontsize=\footnotesize,linenos]{python} sig = w3.keccak(text='initWallet(address)')[:4].hex() + address[2:].rjust(64, '0') # sig = 0x9da8be21000000000000000000000000f9ac06BAeb6597511C22Dc7b03DA447cA893fb4e \end{minted} We can then send this call data to the contract (via the geth console): \begin{minted}[frame=lines,framesep=2mm,bgcolor=LightGray,fontsize=\footnotesize,linenos]{python} eth.sendTransaction({ from: student, to: badparityAddress, data: "0x9da8be21000000000000000000000000f9ac06BAeb6597511C22Dc7b03DA447cA893fb4e", gas: "80000" }); \end{minted} The owner of the \texttt{Wallet} contract is now our own address. Since we are the owner, we can call the \texttt{withdraw} function from the \texttt{Wallet} contract: \begin{minted}[frame=lines,framesep=2mm,bgcolor=LightGray,fontsize=\footnotesize,linenos,breaklines]{python} sig = w3.keccak(text='withdraw(uint256)')[:4].hex() + hex(30000000000000000000)[2:].rjust(64, '0') # sig = 0x2e1a7d4d000000000000000000000000000000000000000000000001a055690d9db80000 eth.sendTransaction({ from: student, to: badparityAddress, data: "0x2e1a7d4d000000000000000000000000000000000000000000000001a055690d9db80000", gas: "80000" }); \end{minted} Our own balance has increased by 30 Ether. To mitigate this vulnerability the contract should use \texttt{call} instead of \texttt{delegatecall}. \section{DAO Down} In this challenge we were given one contract called \texttt{EDao}. It allows investors to fund addresses and those addresses can then withdraw the funding they received. There is a bug in the \texttt{withdraw} function, however, which allows an already funded address to withdraw more than it should be able to. If the funded address is a contract address, the contract can exploit the \texttt{withdraw} function by repeatedly withdrawing their funding. This is possible because the internal balance of how much funds an address can withdraw is only changed \emph{after} the funding is paid out to the receiver. For this to work, a malicious contract has to have a \texttt{fallback} function which calls the \texttt{withdraw} function again. When the \texttt{fallback} function is called, the code execution recurses into the \texttt{withdraw} function and passes all balance checks because the balance has not yet been changed. The payout proceeds a second time and the \texttt{fallback} function is called again until the balance of the \texttt{EDao} contract is zero. This type of attack is called a \emph{reentrancy attack}. In practice the following contract (or a variation thereof) has to be deployed to the blockchain and the address of the deployed contract has to be funded with one Ether in the \texttt{EDao} contract: \inputminted[frame=lines,framesep=2mm,bgcolor=LightGray,fontsize=\footnotesize,linenos,breaklines]{solidity}{daodown/hacker.sol} An attacker can manually call the contract's \texttt{pwn} function and execute the exploit. The malicious contract has successfully siphoned off \texttt{EDao}'s balance. Finally, the attacker calls the \texttt{withdraw} function of the malicious contract and the balance is transferred to the attacker. Mitigating reentrancy attacks is commonly done through two means. Either the contract performs changes to its state \emph{before} executing the call or functions which perform calls to external addresses are wrapped in a modifier with mutex-like functionality. In the former approach a malicious contract will not be able to execute the call to its own \texttt{fallback} function an additional time because the balance checks fail. In the latter approach a boolean variable is set to \texttt{true} when the function is executing the first time. Before the function can be executed a second time, the contract checks whether the variable is set to \texttt{true}. If it is, the transaction is aborted. \section{Fail Dice} % Fill here your answers for exercise C \section{Not A Wallet} % Fill here your answers for exercise D \section*{Work distribution} \begin{description} \item[Tobias Eidelpes] Report for Bad Parity and DAO Down. \end{description} \end{document}