\documentclass [10pt]{article}


\usepackage{latexsym}
\usepackage{amssymb}
\usepackage{epsfig}
\usepackage{fullpage}
\usepackage{enumerate}
\usepackage{enumitem}
\usepackage{xspace}
\usepackage{todonotes}
\usepackage{listings}
\usepackage{url}
\usepackage[ruled,linesnumbered]{algorithm2e} % Enables the writing of pseudo code.
\usepackage{float}% http://ctan.org/pkg/float

\newcommand{\true}{true}
\newcommand{\false}{false}
\pagestyle{plain}
\bibliographystyle{plain}


\title{192.127 Seminar in Software Engineering (Smart Contracts) \\
 SWC-124: Write to Arbitrary Storage Location \\
 Report Exploits }
\author{Exercises}

\date{WT 2023/24}

\author{\textbf{Ivanov, Ivaylo (11777707) \& Millauer, Peter (01350868)}}

\newtheorem{theorem}{Theorem}
\newtheorem{lemma}[theorem]{Lemma}
\newtheorem{corollary}[theorem]{Corollary}
\newtheorem{proposition}[theorem]{Proposition}
\newtheorem{conjecture}[theorem]{Conjecture}
\newtheorem{definition}[theorem]{Definition}
\newtheorem{example}[theorem]{Example}
\newtheorem{remark}[theorem]{Remark}
\newtheorem{exercise}[theorem]{Exercise}


\renewcommand{\labelenumi}{(\alph{enumi})}

\usepackage{xcolor}

\definecolor{codegreen}{rgb}{0,0.6,0}
\definecolor{codegray}{rgb}{0.5,0.5,0.5}
\definecolor{codepurple}{rgb}{0.58,0,0.82}
\definecolor{backcolour}{rgb}{0.95,0.95,0.92}
\definecolor{verylightgray}{rgb}{.97,.97,.97}

\lstdefinelanguage{Solidity}{
	keywords=[1]{anonymous, assembly, assert, balance, break, call, callcode, case, catch, class, constant, continue, constructor, contract, debugger, default, delegatecall, delete, do, else, emit, event, experimental, export, external, false, finally, for, function, gas, if, implements, import, in, indexed, instanceof, interface, internal, is, length, library, log0, log1, log2, log3, log4, memory, modifier, new, payable, pragma, private, protected, public, pure, push, require, return, returns, revert, selfdestruct, send, solidity, storage, struct, suicide, super, switch, then, this, throw, transfer, true, try, typeof, using, value, view, while, with, addmod, ecrecover, keccak256, mulmod, ripemd160, sha256, sha3}, % generic keywords including crypto operations
	keywordstyle=[1]\color{blue}\bfseries,
	keywords=[2]{address, bool, byte, bytes, bytes1, bytes2, bytes3, bytes4, bytes5, bytes6, bytes7, bytes8, bytes9, bytes10, bytes11, bytes12, bytes13, bytes14, bytes15, bytes16, bytes17, bytes18, bytes19, bytes20, bytes21, bytes22, bytes23, bytes24, bytes25, bytes26, bytes27, bytes28, bytes29, bytes30, bytes31, bytes32, enum, int, int8, int16, int24, int32, int40, int48, int56, int64, int72, int80, int88, int96, int104, int112, int120, int128, int136, int144, int152, int160, int168, int176, int184, int192, int200, int208, int216, int224, int232, int240, int248, int256, mapping, string, uint, uint8, uint16, uint24, uint32, uint40, uint48, uint56, uint64, uint72, uint80, uint88, uint96, uint104, uint112, uint120, uint128, uint136, uint144, uint152, uint160, uint168, uint176, uint184, uint192, uint200, uint208, uint216, uint224, uint232, uint240, uint248, uint256, var, void, ether, finney, szabo, wei, days, hours, minutes, seconds, weeks, years},	% types; money and time units
	keywordstyle=[2]\color{teal}\bfseries,
	keywords=[3]{block, blockhash, coinbase, difficulty, gaslimit, number, timestamp, msg, data, gas, sender, sig, value, now, tx, gasprice, origin},	% environment variables
	keywordstyle=[3]\color{violet}\bfseries,
	identifierstyle=\color{black},
	sensitive=true,
	comment=[l]{//},
	morecomment=[s]{/*}{*/},
	commentstyle=\color{gray}\ttfamily,
	stringstyle=\color{red}\ttfamily,
	morestring=[b]',
	morestring=[b]"
}

\lstset{
	language=Solidity,
	backgroundcolor=\color{verylightgray},
	extendedchars=true,
	basicstyle=\footnotesize\ttfamily,
	showstringspaces=false,
	showspaces=false,
	numbers=left,
	numberstyle=\footnotesize,
	numbersep=9pt,
	tabsize=2,
	breaklines=true,
	showtabs=false,
	captionpos=b
}

\lstdefinestyle{mystyle}{
	backgroundcolor=\color{backcolour},
	commentstyle=\color{codegreen},
	keywordstyle=\color{magenta},
	numberstyle=\tiny\color{codegray},
	stringstyle=\color{codepurple},
	basicstyle=\ttfamily\footnotesize,
	breakatwhitespace=false,
	breaklines=true,
	captionpos=b,
	keepspaces=true,
	numbers=left,
	numbersep=5pt,
	showspaces=false,
	showstringspaces=false,
	showtabs=false,
	tabsize=2
}



\begin{document}


\maketitle


%\begin{abstract}
%	This paper outlines different forms of the common smart contract weakness with the SWC number 124, commonly referred to as "Write to Arbitrary Storage Location". While this paper focuses on applications within the context of Ethereum's EVM and higher-level language Solidity, we will also briefly touch on other research that deals with the Hyperledger Fabric environment. We will begin with a gentle introduction to the Solidity storage layout design that allows this weakness to occur, followed by common forms of exploit, alongside their associated consequences. Finally, we will outline the code characteristics that are detectable by automated tools as well as an exploit sketch.
%\end{abstract}

\section{Introduction}

\subsection{Paper introduction}

The aim of this report is to present an analysis of the SWC-124 weakness and its detection. First, we will decribe the setup we did for performing the analysis.
Then, in section~\ref{sec:exploit-creation} we will give a brief overview of the weakness and present heuristics for detecting it. Afterwards, in section~\ref{sec:results} we will present the results
of the security analysis of the assigned contracts\footnote{\url{https://git.logic.at/ethereum/vulnerabilities_23w/-/tree/swc-124?ref_type=heads}}
and finally, in section~\ref{sec:discussion} we will wrap up, give an overview about what we learned and provide future research questions.

\subsection{Setup}

We attempted to implement an automatic weakness detection pipeline by using a multitude of tools. The software used includes:

\begin{itemize}
	\item \textbf{solc}: Using \textbf{solc-select} we select the correct solc version and compile the associated *.sol file. This way we gather compiler hints and warnings.
  \item \textbf{Mythril}: A tool used for analysis of EVM bytecode, one of the de-facto standards for such work. It is unfortunately not able to detect SWC-124, but there is an existing feature request\footnote{\url{https://github.com/Consensys/mythril/issues/861}} for support available.
	\item \textbf{teEther}: A tool we found in the last research step of this seminar, teether is a dynamic analysis tool for smart contracts. It is unfortunately hardly documented and has been unmaintained for several years. We were unable to generate usable results with it.
  \item \textbf{Securify v2.0}: Another tool we found that could theoretically detect SWC-124. Unfortunately, it works only with old solidity versions and we were not able to start it.
	\item \textbf{Slither}: A highly useful tool that offers a large static analysis toolkit for solidity, it not only allows the extraction of contract data like storage layouts but also automatic scanning for common weaknesses. Although it did not seem to be able to detect SWC-124, the storage layout functionality was used extensively by our team.
\end{itemize}

\section{Exploit Creation}\label{sec:exploit-creation}

\subsection{Short recap of weakness definitions}

SWC-124 attempts to use the underlying mechanisms that govern dynamic array allocation to deterministically overwrite arbitrary data in smart contracts. An analogous weakness can be created by employing unchecked assembly instructions, although this is a less common attack vector due to its unusual structure.

\subsection{Exploit heuristics}

The workflow of determining the vulnerability of a given contract is straightforward and follows the general approach of automatic detection mechanisms from our last paper. Since SWC-124 requires the presence of very specific code, it is relatively easy to develop heuristics to exclude non-vulnerable contracts:
\begin{enumerate}[label=\arabic*.]
  \item any contract without dynamic arrays (or mappings with integer keys) or raw assembly including a SSTORE instruction can immediately be considered non-vulnerable;
  \item if heuristic 1 does not hold and there is a dynamic array or mapping with an integer key available, we can then apply a second heuristic and namely: checking the solidity compiler version, specified at the top of the contract. Solidity version 0.8.0+ introduced integer under- and overflow protection, which are enabled per default and require extra work to be disabled. As such, we have the following "sub-heuristic":
    \begin{enumerate}
      \item if the version of the contract is higher than 0.8.0, we examine whether unchecked arithmetic\footnote{\url{https://docs.soliditylang.org/en/v0.8.0/control-structures.html#checked-or-unchecked-arithmetic}} has been used for modifying the arrays. If this is not the case, which it is not most of the time, we can then determine that the contract is non-vulnerable. Applying this heuristic, we found a contract that could have been vulnerable had it been compiled with a lower solidity version.
    \end{enumerate}
\end{enumerate}
The presence of dynamic arrays can be determined using \textbf{slither --print variable-order}. A sample output looks as follows:

\begin{verbatim}
$slither cans.sol --print variable-order

Cans:
+----------------------------+----------------------------------------------+------+--------+
| Name                       |                                         Type | Slot | Offset |
+----------------------------+----------------------------------------------+------+--------+
| ERC1155._balances          |                mapping(address => uint32[7]) |    0 |      0 |
| ERC1155.tokens             |                                    uint256[] |    1 |      0 |
| ERC1155._operatorApprovals | mapping(address => mapping(address => bool)) |    2 |      0 |
| ERC1155._uri               |                                       string |    3 |      0 |
| Ownable._owner             |                                      address |    4 |      0 |
| Functional._reentryKey     |                                         bool |    4 |     20 |
| Cans.START_TIME            |                                      uint256 |    5 |      0 |
| Cans.END_TIME              |                                      uint256 |    6 |      0 |
| Cans.amountClaimed         |                                  uint8[9998] |    7 |      0 |
| Cans.CLAIM_ENABLED         |                                         bool |  320 |      0 |
| Cans.soda                  |                                 SODAContract |  320 |      1 |
| Cans.SODA_CONTRACT         |                                      address |  321 |      0 |
| Cans.baseURI               |                                       string |  322 |      0 |
+----------------------------+----------------------------------------------+------+--------+

\end{verbatim}

In this example the \textbf{ERC1155.tokens} array is the only potential weakess present. We would then look for the presence of what-where writes to this array in order to confirm the potential presence of SWC-124. What-where writes are of the form

\begin{verbatim}
	someArray[where] = what;
\end{verbatim}

\noindent and are a necessary code snippet for SWC-124. If such an instruction is present, we then attempt to reverse engineer a sequence of inputs to trigger the exploit, or formulate a reason why we believe this not to be possible.


\section{Results}\label{sec:results}

Applying the heuristics, mentioned in the previous section, we gathered the following data about the contracts.

\subsection{Vulnerable contracts}

Using the heuristics above, we were not able to find a contract that is vulnerable to SWC-124.

\subsection{Non-exploitable contracts}

\noindent Solidity files that contained no contracts, just libraries, that would not introduce SWC-124 to the contracts using them as per the heuristics:

\begin{itemize}
	\item AuctionLib.sol
	\item LibRegion.sol
	\item LToken.sol

\end{itemize}

\noindent Contracts that were discarded due to the heuristics holding:

\begin{itemize}
	\item DCU.sol
	\item ERC20\_Asset\_Pool.sol
	\item FacelessNFT.sol
	\item GElasticTokenManager.sol
	\item GoldToken.sol
	\item GovernmentAlpha.sol
	\item HedgeSwap.sol
	\item HermesImplementation.sol
	\item IMETACoin223Token\_13.sol - had this contract been compiled with solidity under 0.8.0, it would have been vulnerable.
	\item UniswapV3PoolAdapter.sol
	\item UserDeposit.sol
	\item WPCMainnetBridge.sol
\end{itemize}

\section{Discussion}\label{sec:discussion}

\subsection{Conclusions}

We have proposed initial heuristics which can show us whether a contract is vulnerable to SWC-124. They are easy to understand and apply even in large contracts.
We have demonstrated an example workflow that uses the tool Slither as a data-gathering aid and applies the heuristics. As a result of this workflow, we were unable to find
vulnerable specimen from the examples provided.

\subsection{Lessons learned: what works, what doesn't}

During the analysis that we performed, we were able to learn that none of the state-of-the-art tools have support for SWC-124 as of the time of writing.
Because of this, currently the only way of detecting this vulnerability is the application of the heuristics from section~\ref{sec:exploit-creation}.
The easiest way to protect yourself from this vulnerability is to use solidity 0.8.0+ and its built-in under- and overflow protection whenever using dynamic arrays (and in general),
to avoid using assembly for trivial tasks and, if the need arises, to make sure that the assembly calls that modify the storage are formally correct and non-exploitable.

\subsection{Open challenges}

The initial heuristics are easy to add to a static code analysis tool, such as Slither.
Afterwards, it can be used to develop a dataset of vulnerable or non-vulnerable samples, which, alongside with manually verified contracts, can be used to improve or expand the heuristics.

\bibliography{exercise.bib}

\end{document}


