Compare commits
10
Commits
e0bffaf8fe
...
fccf1b99c2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fccf1b99c2 | ||
|
|
8180295b9f | ||
|
|
c0b2c1a005 | ||
|
|
658bfa32d1 | ||
|
|
84e1fbdce2 | ||
|
|
fa32eeee94 | ||
|
|
ee44cf9d85 | ||
|
|
6a660d3edd | ||
|
|
e8cc0986be | ||
|
|
97b52216cb |
@@ -2,3 +2,8 @@
|
|||||||
*.aux
|
*.aux
|
||||||
*.blg
|
*.blg
|
||||||
*.gz
|
*.gz
|
||||||
|
*.out
|
||||||
|
*.snm
|
||||||
|
*.toc
|
||||||
|
*.vrb
|
||||||
|
*.nav
|
||||||
|
|||||||
+16
-5
@@ -64,9 +64,20 @@
|
|||||||
note = {\url{https://github.com/Arachnid/uscc/tree/master/submissions-2017/doughoyte} [Accessed: Oct. 27th 2023]}
|
note = {\url{https://github.com/Arachnid/uscc/tree/master/submissions-2017/doughoyte} [Accessed: Oct. 27th 2023]}
|
||||||
}
|
}
|
||||||
|
|
||||||
@misc{CiteDrive2022,
|
@article{multilayer,
|
||||||
title = {CiteDrive brings reference management to Overleaf},
|
author = {Duan, Li and Sun, Yangyang and Zhang, Ke-Jia and Ding, Yong},
|
||||||
author = {CiteDrive, Inc},
|
year = {2022},
|
||||||
year = 2022,
|
month = {02},
|
||||||
note = {\url{https://www.citedrive.com/overleaf} [Accessed: (Use the date of access)]}
|
pages = {},
|
||||||
|
title = {Multiple-Layer Security Threats on the Ethereum Blockchain and Their Countermeasures},
|
||||||
|
volume = {2022},
|
||||||
|
journal = {Security and Communication Networks},
|
||||||
|
doi = {10.1155/2022/5307697}
|
||||||
|
}
|
||||||
|
|
||||||
|
@inproceedings{Kalra2018ZEUSAS,
|
||||||
|
title={ZEUS: Analyzing Safety of Smart Contracts},
|
||||||
|
author={Sukrit Kalra and Seep Goel and Mohan Dhawan and Subodh Sharma},
|
||||||
|
booktitle={Network and Distributed System Security Symposium},
|
||||||
|
year={2018},
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,17 @@ doughoyte.
|
|||||||
\url{https://github.com/Arachnid/uscc/tree/master/submissions-2017/doughoyte}
|
\url{https://github.com/Arachnid/uscc/tree/master/submissions-2017/doughoyte}
|
||||||
[Accessed: Oct. 27th 2023].
|
[Accessed: Oct. 27th 2023].
|
||||||
|
|
||||||
|
\bibitem{multilayer}
|
||||||
|
Li~Duan, Yangyang Sun, Ke-Jia Zhang, and Yong Ding.
|
||||||
|
\newblock Multiple-layer security threats on the ethereum blockchain and their
|
||||||
|
countermeasures.
|
||||||
|
\newblock {\em Security and Communication Networks}, 2022, 02 2022.
|
||||||
|
|
||||||
|
\bibitem{Kalra2018ZEUSAS}
|
||||||
|
Sukrit Kalra, Seep Goel, Mohan Dhawan, and Subodh Sharma.
|
||||||
|
\newblock Zeus: Analyzing safety of smart contracts.
|
||||||
|
\newblock In {\em Network and Distributed System Security Symposium}, 2018.
|
||||||
|
|
||||||
\bibitem{teether}
|
\bibitem{teether}
|
||||||
Johannes Krupp and Christian Rossow.
|
Johannes Krupp and Christian Rossow.
|
||||||
\newblock {teEther}: Gnawing at ethereum to automatically exploit smart
|
\newblock {teEther}: Gnawing at ethereum to automatically exploit smart
|
||||||
|
|||||||
Binary file not shown.
+280
-22
@@ -46,6 +46,40 @@
|
|||||||
\definecolor{codegray}{rgb}{0.5,0.5,0.5}
|
\definecolor{codegray}{rgb}{0.5,0.5,0.5}
|
||||||
\definecolor{codepurple}{rgb}{0.58,0,0.82}
|
\definecolor{codepurple}{rgb}{0.58,0,0.82}
|
||||||
\definecolor{backcolour}{rgb}{0.95,0.95,0.92}
|
\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}{
|
\lstdefinestyle{mystyle}{
|
||||||
backgroundcolor=\color{backcolour},
|
backgroundcolor=\color{backcolour},
|
||||||
@@ -73,6 +107,10 @@
|
|||||||
|
|
||||||
\maketitle
|
\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{Weakness and consequences}
|
\section{Weakness and consequences}
|
||||||
|
|
||||||
\subsection{Solidity storage layout}
|
\subsection{Solidity storage layout}
|
||||||
@@ -95,9 +133,9 @@ Any unchecked array write is potentially dangerous, as the storage-location of a
|
|||||||
|
|
||||||
A trivial example of such a vulnerable write operation is shown in Algorithm~\ref{alg:vuln-write}.
|
A trivial example of such a vulnerable write operation is shown in Algorithm~\ref{alg:vuln-write}.
|
||||||
|
|
||||||
\lstset{style=mystyle}
|
|
||||||
\begin{algorithm}[H]
|
\begin{algorithm}[H]
|
||||||
\begin{lstlisting}[language=Octave]
|
\begin{lstlisting}[language=Solidity]
|
||||||
pragma solidity 0.4.25;
|
pragma solidity 0.4.25;
|
||||||
|
|
||||||
contract MyContract {
|
contract MyContract {
|
||||||
@@ -124,9 +162,8 @@ In the following example (Algorithm~\ref{alg:pop-incorrect}) the $pop$ function
|
|||||||
|
|
||||||
\medspace
|
\medspace
|
||||||
|
|
||||||
\lstset{style=mystyle}
|
|
||||||
\begin{algorithm}[H]
|
\begin{algorithm}[H]
|
||||||
\begin{lstlisting}[language=Octave]
|
\begin{lstlisting}[language=Solidity]
|
||||||
pragma solidity 0.4.25;
|
pragma solidity 0.4.25;
|
||||||
|
|
||||||
contract MyContract {
|
contract MyContract {
|
||||||
@@ -158,19 +195,18 @@ In the following example (Algorithm~\ref{alg:pop-incorrect}) the $pop$ function
|
|||||||
\label{alg:pop-incorrect}
|
\label{alg:pop-incorrect}
|
||||||
\end{algorithm}
|
\end{algorithm}
|
||||||
|
|
||||||
Another weakness that allows arbitrary storage access is unchecked assembly code. Assembly is a powerful tool that allows the developers to get as close to the EVM as they can,
|
\medspace
|
||||||
but it may also be very dangerous when not tested correctly. As per the documentation\footnote{\url{https://docs.soliditylang.org/en/latest/assembly.html}}: \textit{"this [inline assembly]
|
|
||||||
|
Another weakness that allows arbitrary storage access is unchecked assembly code. Assembly is a powerful tool that allows the developers to get as close to the EVM as they can, but it may also be very dangerous when not used correctly. As per the documentation\footnote{\url{https://docs.soliditylang.org/en/latest/assembly.html}, accessed: Oct. 30th 2023}: \textit{"this [inline assembly]
|
||||||
bypasses important safety features and checks of Solidity. You should only use it for tasks that need it, and only if you are confident with using it."}
|
bypasses important safety features and checks of Solidity. You should only use it for tasks that need it, and only if you are confident with using it."}
|
||||||
When given access to such lowlevel structures, a programmer can built-in not only weaknesses similar to the ones described previously, but also others, such as overwriting map locations,
|
When given access to such low-level instructions, a programmer can construct not only weaknesses similar to the ones described previously, but also others, such as overwriting map locations, contract variables etc.
|
||||||
contract variables etc.
|
|
||||||
|
|
||||||
An example for such a weakness is given in Algorithm~\ref{alg:unchecked-assembly}.
|
An example for such a weakness is given in Algorithm~\ref{alg:unchecked-assembly}.
|
||||||
|
|
||||||
\medspace
|
\medspace
|
||||||
|
|
||||||
\lstset{style=mystyle}
|
|
||||||
\begin{algorithm}[H]
|
\begin{algorithm}[H]
|
||||||
\begin{lstlisting}[language=Octave]
|
\begin{lstlisting}[language=Solidity]
|
||||||
pragma solidity 0.4.25;
|
pragma solidity 0.4.25;
|
||||||
|
|
||||||
contract MyContract {
|
contract MyContract {
|
||||||
@@ -211,26 +247,111 @@ An example for such a weakness is given in Algorithm~\ref{alg:unchecked-assembly
|
|||||||
\label{alg:unchecked-assembly}
|
\label{alg:unchecked-assembly}
|
||||||
\end{algorithm}
|
\end{algorithm}
|
||||||
|
|
||||||
The contract has a manager mapping, which should be used as a stack.
|
\medspace
|
||||||
|
|
||||||
|
The contract has a manager mapping, which is intended to be used as a stack.
|
||||||
The developer has added the \texttt{setNextManager} function, which should set the top of the stack to the latest user as a manager.
|
The developer has added the \texttt{setNextManager} function, which should set the top of the stack to the latest user as a manager.
|
||||||
The issue is that the function is implemented in such a way, that the stack would not grow, but the first element would always be overwritten - this arises from the fact that the memory slot
|
The issue is that the function is implemented in such a way, that the stack does not grow, but the first element is always overwritten - this arises from the fact that the memory slot
|
||||||
of the managers mapping does not point to the memory address on the top of the stack, but instead to the base of it.
|
of the managers mapping does not point to the memory address on the top of the stack, but instead to the base of it.
|
||||||
The function is then using this slot address directly, without calculating any offset, overwriting the base of the stack. If social engineeering is applied, an attacker can persuade the
|
The function is then using this slot address directly, without calculating any offset, overwriting the base of the stack. If social engineeering is applied, an attacker can persuade the
|
||||||
owner to set them as a manager, which would result in the weakness being exploited directly and the owner giving up their own management rights.
|
owner to set them as a manager, which would result in the weakness being exploited directly and the owner giving up their own management rights.
|
||||||
|
|
||||||
\subsection{Consequences}
|
\subsection{Consequences}
|
||||||
|
|
||||||
The consequences of exploiting an arbitrary storage access weakness can be of different types and severity.
|
The consequences of exploiting an arbitrary storage access weakness can be of different types and severity.
|
||||||
An attacker may gain read-write access to private contract data, which should only be accessible to owners, maintainers etc.
|
An attacker may gain read-write access to private contract data, which should only be accessible to owners, maintainers etc.
|
||||||
They may also exploit the contract to circumvent authorization checks and drain the contract funds.
|
They may also exploit the contract to circumvent authorization checks and drain the contract funds.
|
||||||
%TODO: can we expand this?
|
According to Li Duan et al.~\cite{multilayer}, an attacker may also be able to destroy the contract storage structure and thus cause
|
||||||
|
unexpected program flow, abnormal function execution or contract freeze.
|
||||||
|
|
||||||
|
\subsection{Similar yet safe code example}
|
||||||
|
|
||||||
|
Using dynamic arrays is naturally not inherently dangerous, as long as they're used properly. The following version of Algorithm~\ref{alg:pop-incorrect} correctly checks for array length, and thereby prevents the integer underflow of the length value. This code example is not vulnerable to the techniques shown in this paper.
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
\begin{algorithm}[H]
|
||||||
|
\begin{lstlisting}[language=Solidity]
|
||||||
|
pragma solidity 0.4.25;
|
||||||
|
|
||||||
|
contract MyContract {
|
||||||
|
address private owner;
|
||||||
|
uint[] private arr;
|
||||||
|
|
||||||
|
constructor() public {
|
||||||
|
arr = new uint[](0);
|
||||||
|
owner = msg.sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
function push(value) {
|
||||||
|
arr[arr.length] = value;
|
||||||
|
arr.length++;
|
||||||
|
}
|
||||||
|
|
||||||
|
function pop() {
|
||||||
|
require(arr.length > 0);
|
||||||
|
arr.length--;
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(unit index, uint value) {
|
||||||
|
require(index < arr.length);
|
||||||
|
arr[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\caption{Correctly managed array length}
|
||||||
|
\label{alg:pop-correct}
|
||||||
|
\end{algorithm}
|
||||||
|
|
||||||
\section{Vulnerable contracts in literature}
|
\section{Vulnerable contracts in literature}
|
||||||
|
|
||||||
collect vulnerable contracts used by different papers to motivate/illustrate the weakness
|
One example for vulnerable contracts, which is similar to Algorithm~\ref{alg:pop-incorrect}, is mentioned in the paper by Li Duan et al.~\cite{multilayer}:
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
\begin{algorithm}[H]
|
||||||
|
\begin{lstlisting}[language=Solidity]
|
||||||
|
function PopBonusCode() public {
|
||||||
|
require(0 <= bonusCodes.length);
|
||||||
|
bonusCodes.length--;
|
||||||
|
}
|
||||||
|
|
||||||
|
function UpdateBonusCodeAt(uint idx, uint c) public {
|
||||||
|
require(idx < bonusCodes.length);
|
||||||
|
bonusCodes[idx] = c;
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\caption{Arbitrary write as per Li Duan et al.}
|
||||||
|
\label{alg:multilayer-example}
|
||||||
|
\end{algorithm}
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
We will not go into a detailed explanation, as we already did this in the previous section. A more sophisticated example is presented in the paper by Sukrit Kalra et al.~\cite{Kalra2018ZEUSAS}:
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
\begin{algorithm}[H]
|
||||||
|
\begin{lstlisting}[language=Solidity]
|
||||||
|
uint payout = balance/participants.length;
|
||||||
|
for (var i = 0; i < participants.length; i++)
|
||||||
|
participants[i].send(payout);
|
||||||
|
\end{lstlisting}
|
||||||
|
\caption{Arbitrary read as per Sukrit Kalra et al.}
|
||||||
|
\label{alg:zeus-example}
|
||||||
|
\end{algorithm}
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
The vulnerability here is an integer overflow - as the variable \texttt{i} is dynamically typed, it will get the smallest possible type that will be able to hold the value 0 - that being \texttt{uint8}, which is able to hold positive integers up to 255.
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
Because of this, if the length of the \texttt{participants} arrays is greater than 255, the integer overflows on the 256th iteration and instead of moving on to \texttt{participants[255]}, it reverts back to the first element in the array. As a result, the first 255 participants will split all the balance of the contract, whereas the rest will get nothing.
|
||||||
|
|
||||||
\section{Code properties and automatic detection}
|
\section{Code properties and automatic detection}
|
||||||
|
|
||||||
Automatic detection tools can be broadly categorized into ones employing static analysis and those who use fuzzing, i.e. application of semi-random inputs. Notable static analysis tools include Securify \cite{securify} and teEther \cite{teether} which both function in a similar manner:
|
Automatic detection tools can be broadly categorized into ones employing static analysis and those who use fuzzing, i.e. application of semi-random inputs. Notable static analysis tools include Securify~\cite{securify} and teEther~\cite{teether} which both function in a similar manner:
|
||||||
|
|
||||||
\medspace
|
\medspace
|
||||||
|
|
||||||
@@ -238,28 +359,165 @@ Initially, the given EVM byte-code is disassembled into a control-flow-graph (CF
|
|||||||
|
|
||||||
\medspace
|
\medspace
|
||||||
|
|
||||||
In the case of Securify \cite{securify}, the CFG is translated into what the authors call "semantic facts" to which an elaborate set of so-called security patterns is applied. These patterns consist of building blocks in the form of predicates, which allows the tool to simply generate output based on the (transitively) matched patterns.
|
In the case of Securify~\cite{securify}, the CFG is translated into what the authors call "semantic facts" to which an elaborate set of so-called security patterns is applied. These patterns consist of building blocks in the form of predicates, which allows the tool to simply generate output based on the (transitively) matched patterns.
|
||||||
|
|
||||||
\medspace
|
\medspace
|
||||||
|
|
||||||
teEther \cite{teether} employs a similar approach, but instead the authors opt to build a graph of dependent variables. If the graph arrives at a $sstore(k,v)$ instruction and a path can be found leading to user-controlled inputs, the tool infers a set of constraints which are then used to automatically generate an exploit.
|
teEther~\cite{teether} employs a similar approach, but instead the authors opt to build a graph of dependent variables. If the graph arrives at a $sstore(k,v)$ instruction and a path can be found leading to user-controlled inputs, the tool infers a set of constraints which are then used to automatically generate an exploit.
|
||||||
|
|
||||||
\medspace
|
\medspace
|
||||||
|
|
||||||
The fuzz-driven approach to vulnerability detection is more abstract, as general-purpose fuzzing tools generally don't have knowledge of the analysed program. For the tool SmartFuzzDriverGenerator \cite{fuzzdrivegen}, a multitude of these fuzzing libraries can be used. The problem at hand is, however, that the technique cannot interface with a smart contract out of the box. The "glue" between fuzzer and program is called a driver, hence the name of "driver-generator".
|
The fuzz-driven approach to vulnerability detection is more abstract, as general-purpose fuzzing tools generally don't have knowledge of the analysed program. For the tool SmartFuzzDriverGenerator~\cite{fuzzdrivegen}, a multitude of these fuzzing libraries can be used, although its application is limited to the Hyperledger Fabric permissioned blockchain. The problem at hand is, that the technique cannot interface with a smart contract out of the box. The "glue" between fuzzer and program is called a driver, hence the name of "driver-generator".
|
||||||
|
|
||||||
\medspace
|
\medspace
|
||||||
|
|
||||||
SmartFuzzDriverGenerator aims to automatically generate such a driver by %TODO: I have no idea how it does this actually%
|
SmartFuzzDriverGenerator aims to automatically generate such a driver by inferring the available APIs from the bytecode. There are multiple approaches to decide the order of available fuzzing steps, including a heuristic based on code complexity (i.e. nested conditions, loops, array operations, etc.), random sequences, and user-generated strategies.
|
||||||
|
|
||||||
\medspace
|
\medspace
|
||||||
|
|
||||||
The Smartian tool \cite{smartian} attempts to find a middle-ground between static and dynamic analysis by first transforming the EVM bytecode into control-flow facts. Based on this information, a set of seed-inputs is generated that are expected to have a high probability of yielding useable results. Should no exploit be found, the seed-inputs are then mutated in order to yield a higher code coverage. %TODO: This is probably extemely inprecise and should be re-written%
|
The Smartian tool~\cite{smartian} attempts to find a middle-ground between static and dynamic analysis by first transforming the EVM bytecode into control-flow facts. Based on this information, a set of seed-inputs is generated that are expected to have a high probability of yielding useable results. Should no exploit be found, the seed-inputs are then mutated in order to yield a higher code coverage.
|
||||||
|
|
||||||
\section{Exploit sketch}
|
\section{Exploit sketch}
|
||||||
|
|
||||||
\cite{doughoyte}
|
An exploitation sketch to Algorithm~\ref{alg:pop-incorrect} and to Algorithm~\ref{alg:multilayer-example} is available from Doughoyte~\cite{doughoyte}.
|
||||||
%TODO: just explain what this guy does: https://github.com/Arachnid/uscc/tree/master/submissions-2017/doughoyte%
|
|
||||||
|
\textbf{Checkpoint A}
|
||||||
|
We assume that the following events have occurred:
|
||||||
|
\begin{enumerate}
|
||||||
|
\item the contract MerdeToken\footnote{\url{https://github.com/Arachnid/uscc/blob/master/submissions-2017/doughoyte/MerdeToken.sol}, accessed: Oct. 30th 2023} has been created;
|
||||||
|
\item the investor has set a withdrawal limit of 1 ether, which only they can change;
|
||||||
|
\item an investor has invested 50 ETH;
|
||||||
|
\item the owner is malicious.
|
||||||
|
\end{enumerate}
|
||||||
|
|
||||||
|
At this point, an example storage layout as per Doughoyte would be:
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
\lstset{style=mystyle}
|
||||||
|
\begin{algorithm}[H]
|
||||||
|
\begin{lstlisting}
|
||||||
|
"storage": {
|
||||||
|
// The address of the contract owner:
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000": "94b898c1a30adcff67208fd79b9e5a4d339f3cc6d2",
|
||||||
|
// The address of the trusted third party:
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000001": "948bc7317ad44d6f34f0f0b6e3c8c7bf739ba666fa",
|
||||||
|
// The amount deposited (50 ETH):
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000003": "8902b5e3af16b1880000",
|
||||||
|
// The withdrawal limit (1 ETH):
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000004": "880de0b6b3a7640000",
|
||||||
|
// the legth of the array would normaly stay here, if it was not zero at init time
|
||||||
|
// balanceOf[investorAddress] (50 MDT):
|
||||||
|
"dd87d7653af8fba540ea9ebd2d914ba190d975fcfa4d8d2927126a5decdbff9e": "8902b5e3af16b1880000"
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\caption{Exploit - Memory at Checkpoint A}
|
||||||
|
\label{alg:exploit-checkpoint-a}
|
||||||
|
\end{algorithm}
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
\textbf{Checkpoint B}
|
||||||
|
Afterwards, the malicious owner calls the vulnerable function \texttt{popBonusCode()} and the length of the array is set to the max value. This happened, because prior to the underflow, the array length was zero and, to save space, it was omitted from the memory:
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
\lstset{style=mystyle}
|
||||||
|
\begin{algorithm}[H]
|
||||||
|
\begin{lstlisting}
|
||||||
|
"storage": {
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000": "94b898c1a30adcff67208fd79b9e5a4d339f3cc6d2",
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000001": "948bc7317ad44d6f34f0f0b6e3c8c7bf739ba666fa",
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000003": "8902b5e3af16b1880000",
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000004": "880de0b6b3a7640000",
|
||||||
|
// The array length has underflowed:
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000005": "a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
"dd87d7653af8fba540ea9ebd2d914ba190d975fcfa4d8d2927126a5decdbff9e": "8902b5e3af16b1880000"
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\caption{Exploit - Memory at Checkpoint B}
|
||||||
|
\label{alg:exploit-checkpoint-b}
|
||||||
|
\end{algorithm}
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
Increasing the length of the array to the maximum allowed by \texttt{uint256} was important, as this will now allow the owner to pass the requirement set in \texttt{modifyBonusCode} and still
|
||||||
|
use the function for storage modification.
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
\textbf{Checkpoint C} The owner is then able to use \texttt{modifyBonusCode} to increase the fixed withdraw limit to the max \texttt{uint256} value. Had the contract not have this vulnerability,
|
||||||
|
this action should only have been possible through the \texttt{setWithdrawLimit}, which is only available to the investor.
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
In order to overwrite the withdrawal limit, the owner must calculate the hex value to use as a first argument (index) to the function.
|
||||||
|
Since the array \texttt{bonusCodes} underflow is defined in the sixth place in the contract storage, its length is in the fifth storage slot (counting from zero)
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
The limit is defined at the fourth storage slot. Then, in order to manipulate the withdrawal limit, the owner must convert the address of the length to hexadecimal:
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
\lstset{style=mystyle}
|
||||||
|
\begin{algorithm}[H]
|
||||||
|
\begin{lstlisting}
|
||||||
|
$ web3.sha3("0x0000000000000000000000000000000000000000000000000000000000000005", { encoding: 'hex' })
|
||||||
|
> "0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0"
|
||||||
|
\end{lstlisting}
|
||||||
|
\caption{Exploit - Convert length address to hex}
|
||||||
|
\label{alg:exploit-convert-address}
|
||||||
|
\end{algorithm}
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
and then just calculate the array index that will wrap around using the formula $2^{256} - H + 4$, where $2^{256}$ is the max \texttt{uint256} value, H is the hex obtained from the previous command and 4 is the offset of the withdrawal limit storage slot from the base of the contract. This, converted to hex, will give the owner the address to use with \texttt{modifyBonusCode}. The Perl snippet below does that:
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
\lstset{style=mystyle}
|
||||||
|
\begin{algorithm}[H]
|
||||||
|
\begin{lstlisting}[language=Octave]
|
||||||
|
$ perl -Mbigint -E 'say ((2**256 - 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0 + 4)->as_hex)'
|
||||||
|
> 0xfc949c7b4a13586e39d89eead2f38644f9fb3efb5a0490b14f8fc0ceab44c254
|
||||||
|
\end{lstlisting}
|
||||||
|
\caption{Exploit - Convert limit offset to address}
|
||||||
|
\label{alg:exploit-convert-offset}
|
||||||
|
\end{algorithm}
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
As a result, the memory now looks like this:
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
\lstset{style=mystyle}
|
||||||
|
\begin{algorithm}[H]
|
||||||
|
\begin{lstlisting}
|
||||||
|
"storage": {
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000": "94b898c1a30adcff67208fd79b9e5a4d339f3cc6d2",
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000001": "948bc7317ad44d6f34f0f0b6e3c8c7bf739ba666fa",
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000003": "8902b5e3af16b1880000",
|
||||||
|
// The withdrawal limit is now really high:
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000004": "a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000005": "a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
"dd87d7653af8fba540ea9ebd2d914ba190d975fcfa4d8d2927126a5decdbff9e": "8902b5e3af16b1880000"
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\caption{Exploit - Memory at Checkpoint C}
|
||||||
|
\label{alg:exploit-checkpoint-c}
|
||||||
|
\end{algorithm}
|
||||||
|
|
||||||
|
\medspace
|
||||||
|
|
||||||
|
\textbf{Checkpoint D} The owner can now call \texttt{withdraw()} with the full amount of ether in the contract and drain it. The investor has not increased the limit at any point.
|
||||||
|
|
||||||
|
\section{Conclusion}
|
||||||
|
|
||||||
|
We presented different forms of the common weakness SWC-124: Write to Arbitrary Storage Location and how they might be detected using automated tools. We have shown how a possible exploit may be constructed, and how this can lead to the complete compromise of a smart contract's storage and control flow. We have given multiple attackable and benign code examples to illustrate this weakness. We believe this weakness to be of particular practical relevance, as it is very easy to introduce by accident, and hard to for a developer to spot without advanced knowledge of the underlying mechanisms that cause it.
|
||||||
|
|
||||||
|
As for preventative measures, we would recommend developers not to interact with low-level building blocks like an array's length value or inline assembly instructions if possible, and instead to employ standard library functions when ever available.
|
||||||
|
|
||||||
|
|
||||||
\bibliography{exercise.bib}
|
\bibliography{exercise.bib}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,305 @@
|
|||||||
|
%%
|
||||||
|
% @file beamerthemeTUW.sty
|
||||||
|
% @date 2016-08-30
|
||||||
|
% @author Wolfgang Puffitsch, Denise Ratasich
|
||||||
|
%
|
||||||
|
% @brief Beamer LaTeX template matching the corporate design of TU Wien.
|
||||||
|
%%
|
||||||
|
|
||||||
|
\NeedsTeXFormat{LaTeX2e}
|
||||||
|
\ProvidesPackage{beamerthemeTUW}[2016/08/30 Beamer template that fits the TU Wien corporate design (adopted styles from powerpoint presentation template in CD manual)]
|
||||||
|
|
||||||
|
\RequirePackage{graphicx}
|
||||||
|
\RequirePackage{tikz}
|
||||||
|
|
||||||
|
\def\beamer@tuwDefault{default}
|
||||||
|
\def\beamer@tuwPlain{plain}
|
||||||
|
\def\beamer@tuwSidebar{sidebar}
|
||||||
|
\def\beamer@tuwHelvetica{helvetica}
|
||||||
|
\def\beamer@tuwNoImage{none}
|
||||||
|
\def\beamer@tuwLogo{TU_Logo}
|
||||||
|
\def\beamer@tuwLogoWhite{TU_Logo_white}
|
||||||
|
|
||||||
|
%%% options
|
||||||
|
% The user may choose other fonts (TU Wien CD says to use helvetica).
|
||||||
|
\DeclareOptionBeamer{font}{\def\beamer@tuwFont{#1}}
|
||||||
|
% Another outer theme may be chosen, however it may not fit the TU Wien colors.
|
||||||
|
\DeclareOptionBeamer{outer}{\def\beamer@tuwOuter{#1}}
|
||||||
|
% Width of the sidebar.
|
||||||
|
\DeclareOptionBeamer{width}{\def\beamer@tuwWidth{#1}}
|
||||||
|
% Background image of TU Wien building on title page.
|
||||||
|
\newif\ifbeamer@tuwBackground
|
||||||
|
\DeclareOptionBeamer{tuw_background}{\beamer@tuwBackgroundtrue}
|
||||||
|
% Individual background image on title page.
|
||||||
|
\DeclareOptionBeamer{tuw_image}{\def\beamer@tuwImage{#1}}
|
||||||
|
% White logo (if tuw_image is dark the logo should be set to be white).
|
||||||
|
\newif\ifbeamer@tuwWhiteLogo
|
||||||
|
\DeclareOptionBeamer{tuw_whitelogo}{\beamer@tuwWhiteLogotrue}
|
||||||
|
% Print frame title beside the logo to save space.
|
||||||
|
\newif\ifbeamer@tuwFrametitleToTop
|
||||||
|
\DeclareOptionBeamer{tuw_frametitletotop}{\beamer@tuwFrametitleToToptrue}
|
||||||
|
|
||||||
|
% defaults
|
||||||
|
\ExecuteOptionsBeamer{outer=default}
|
||||||
|
\ExecuteOptionsBeamer{width=1.6cm}
|
||||||
|
\ExecuteOptionsBeamer{font=\familydefault}
|
||||||
|
\beamer@tuwBackgroundfalse
|
||||||
|
\ExecuteOptionsBeamer{tuw_image=none}
|
||||||
|
\beamer@tuwWhiteLogofalse
|
||||||
|
\beamer@tuwFrametitleToTopfalse
|
||||||
|
|
||||||
|
\ProcessOptionsBeamer
|
||||||
|
|
||||||
|
\ifx\beamer@tuwFont\beamer@tuwHelvetica
|
||||||
|
\RequirePackage{helvet}
|
||||||
|
\fi
|
||||||
|
|
||||||
|
\mode<presentation>
|
||||||
|
|
||||||
|
%%% colors
|
||||||
|
% For some reason the logo is not in TU-blue (0,102,153). The powerpoint
|
||||||
|
% presentation has TU-blue as background and the logo with a different color
|
||||||
|
% (doesn't look nice). We align the TU-blue to the logo, like in the CD manual.
|
||||||
|
\definecolor{tuwBlue}{RGB}{0,116,178}
|
||||||
|
\definecolor{tuwGray}{RGB}{102,102,102}
|
||||||
|
\definecolor{iceBlue}{RGB}{222,231,236}
|
||||||
|
|
||||||
|
\def\tuwBlue{tuwBlue}
|
||||||
|
\def\tuwGray{tuwGray}
|
||||||
|
\def\iceBlue{iceBlue}
|
||||||
|
\def\tuwLightBlue{tuwBlue!20!white}
|
||||||
|
\def\tuwMediumBlue{tuwBlue!45!white}
|
||||||
|
\def\tuwDarkBlue{tuwBlue!70!black}
|
||||||
|
\def\alertred{red!50!black}
|
||||||
|
|
||||||
|
% content page
|
||||||
|
\setbeamercolor{normal text}{fg=black,bg=white}
|
||||||
|
\setbeamercolor{alerted text}{fg=\alertred}
|
||||||
|
\setbeamercolor{structure}{fg=\tuwBlue}
|
||||||
|
\setbeamercolor{frametitle}{fg=black}
|
||||||
|
|
||||||
|
\setbeamercolor{palette primary}{fg=\tuwDarkBlue,bg=\tuwLightBlue}
|
||||||
|
\setbeamercolor{palette secondary}{fg=\tuwBlue!50!black,bg=\tuwMediumBlue}
|
||||||
|
\setbeamercolor{palette tertiary}{fg=white,bg=\tuwBlue}
|
||||||
|
|
||||||
|
\setbeamercolor{section in toc}{parent=normal text}
|
||||||
|
\setbeamercolor{subsection in toc}{parent=section in toc}
|
||||||
|
|
||||||
|
\setbeamercolor{block title}{fg=white, bg=\tuwBlue}
|
||||||
|
\setbeamercolor{block title example}{fg=white, bg=\tuwBlue}
|
||||||
|
\setbeamercolor{block title alerted}{fg=white, bg=\alertred}
|
||||||
|
\setbeamercolor{block body}{bg=\iceBlue}
|
||||||
|
\setbeamercolor{block body example}{parent=block body}
|
||||||
|
\setbeamercolor{block body alerted}{parent=block body, fg=\alertred}
|
||||||
|
|
||||||
|
\setbeamercolor{title in head/foot}{fg=\tuwBlue}
|
||||||
|
\setbeamercolor{page number in head/foot}{fg=\tuwBlue}
|
||||||
|
\setbeamercolor{footline}{fg=\tuwBlue}
|
||||||
|
|
||||||
|
% color difference of default and other outer styles
|
||||||
|
\ifx\beamer@tuwOuter\beamer@tuwDefault
|
||||||
|
% default style - this is the CD of TU Wien
|
||||||
|
% title page
|
||||||
|
\setbeamercolor{title}{fg=white}
|
||||||
|
\setbeamercolor{subtitle}{fg=white}
|
||||||
|
\setbeamercolor{author}{fg=white}
|
||||||
|
\setbeamercolor{institute}{fg=white}
|
||||||
|
\setbeamercolor{date}{fg=white}
|
||||||
|
% content page
|
||||||
|
% keep defaults (black)
|
||||||
|
\else
|
||||||
|
% other outer styles (e.g., sidebar)
|
||||||
|
% title page
|
||||||
|
\setbeamercolor{title}{fg=\tuwGray}
|
||||||
|
\setbeamercolor{subtitle}{fg=\tuwGray}
|
||||||
|
\setbeamercolor{author}{fg=black}
|
||||||
|
\setbeamercolor{institute}{fg=black}
|
||||||
|
\setbeamercolor{date}{fg=black}
|
||||||
|
% content page
|
||||||
|
\setbeamercolor{frametitle}{fg=\tuwGray}
|
||||||
|
\setbeamercolor{headline}{fg=\tuwGray}
|
||||||
|
\setbeamercolor{footline}{fg=\tuwGray}
|
||||||
|
\fi
|
||||||
|
|
||||||
|
% sidebar
|
||||||
|
\setbeamercolor{sidebar}{bg=\tuwBlue,fg=white}
|
||||||
|
\setbeamercolor{palette sidebar primary}{fg=\tuwDarkBlue,bg=\tuwLightBlue}
|
||||||
|
\setbeamercolor{palette sidebar secondary}{fg=\tuwDarkBlue,bg=\tuwLightBlue}
|
||||||
|
\setbeamercolor{palette sidebar tertiary}{fg=white,bg=\tuwBlue}
|
||||||
|
\setbeamercolor{title in sidebar}{fg=white,bg=\tuwBlue}
|
||||||
|
\setbeamercolor{section in sidebar}{fg=\tuwDarkBlue}
|
||||||
|
\setbeamercolor{section in sidebar shaded}{fg=white,bg=\tuwBlue}
|
||||||
|
\setbeamercolor{subsection in sidebar}{fg=\tuwDarkBlue}
|
||||||
|
\setbeamercolor{subsection in sidebar shaded}{fg=white,bg=\tuwBlue}
|
||||||
|
|
||||||
|
%%% fonts
|
||||||
|
|
||||||
|
% font weight
|
||||||
|
\setbeamerfont{title}{series=\bfseries}
|
||||||
|
\setbeamerfont{author}{series=\mdseries}
|
||||||
|
\setbeamerfont{institute}{series=\mdseries}
|
||||||
|
\setbeamerfont{date}{series=\mdseries}
|
||||||
|
\setbeamerfont{frametitle}{series=\mdseries}
|
||||||
|
\setbeamerfont{headline}{series=\mdseries}
|
||||||
|
\setbeamerfont{footline}{series=\mdseries}
|
||||||
|
|
||||||
|
% font size difference of default and other outer styles
|
||||||
|
\ifx\beamer@tuwOuter\beamer@tuwDefault
|
||||||
|
% default style - this is the CD of TU Wien
|
||||||
|
\setbeamerfont{title}{size=\huge}
|
||||||
|
\setbeamerfont{author}{size=\normalsize}
|
||||||
|
\setbeamerfont{institute}{size=\normalsize}
|
||||||
|
\setbeamerfont{date}{size=\normalsize}
|
||||||
|
\setbeamerfont{frametitle}{size=\Large}
|
||||||
|
\setbeamerfont{framesubtitle}{size=\large}
|
||||||
|
\setbeamerfont{headline}{size=\scriptsize}
|
||||||
|
\setbeamerfont{footline}{size=\scriptsize}
|
||||||
|
\else
|
||||||
|
% other outer styles (e.g., sidebar)
|
||||||
|
% keep defaults
|
||||||
|
\fi
|
||||||
|
|
||||||
|
\setbeamerfont{section in toc}{parent=normal text}
|
||||||
|
\setbeamerfont{subsection in toc}{parent=section in toc}
|
||||||
|
|
||||||
|
% sidebar
|
||||||
|
\setbeamerfont{title in sidebar}{series=\bfseries}
|
||||||
|
\setbeamerfont{section in sidebar}{series=\bfseries,size=\tiny}
|
||||||
|
\setbeamerfont{subsection in sidebar}{size=\tiny}
|
||||||
|
|
||||||
|
%%% outer
|
||||||
|
\setbeamersize{text margin left=1.2cm}
|
||||||
|
\setbeamersize{text margin right=1.5cm}
|
||||||
|
\beamertemplatenavigationsymbolsempty
|
||||||
|
|
||||||
|
|
||||||
|
\ifx\beamer@tuwOuter\beamer@tuwDefault
|
||||||
|
% default outher theme - this is the CD of TU Wien
|
||||||
|
|
||||||
|
% background
|
||||||
|
\setbeamertemplate{background}{
|
||||||
|
\begin{tikzpicture}
|
||||||
|
\useasboundingbox (0,0) rectangle(\the\paperwidth,\the\paperheight);
|
||||||
|
% title page
|
||||||
|
\ifbeamer@tuwBackground % tu building background selected
|
||||||
|
\node[anchor=south west] (background) at (-0.15cm,-0.15cm) {\includegraphics[width=1.01\paperwidth]{TU_Background}};
|
||||||
|
\else\ifx\beamer@tuwImage\beamer@tuwNoImage % no background image specified
|
||||||
|
\fill[white] (0,0) rectangle (\the\paperwidth,\the\paperheight);
|
||||||
|
\else % individual background image
|
||||||
|
\node[anchor=north west] (background) at (-0.15cm,-0.15cm) {\includegraphics[width=1.01\paperwidth]{\beamer@tuwImage}};
|
||||||
|
\fi\fi
|
||||||
|
\fill[\tuwBlue, rounded corners=0.5cm] (-1cm,-1cm) rectangle (\paperwidth-0.5cm,\paperheight-3cm);
|
||||||
|
\ifbeamer@tuwWhiteLogo % white logo option specified
|
||||||
|
\node[anchor=north west] (logo) at (0.3cm,\paperheight-0.1cm) {\includegraphics[height=2cm]{\beamer@tuwLogoWhite}};
|
||||||
|
\else
|
||||||
|
\node[anchor=north west] (logo) at (0.2cm,\paperheight-0.2cm) {\includegraphics[height=2cm]{\beamer@tuwLogo}};
|
||||||
|
\fi
|
||||||
|
% content page
|
||||||
|
\ifnum\thepage>1\relax%
|
||||||
|
\fill[\iceBlue] (0,0) rectangle (\the\paperwidth,\the\paperheight);
|
||||||
|
\fill[white, rounded corners=0.5cm] (-1cm,-1cm) rectangle(\paperwidth-0.4cm,\paperheight-0.8cm);
|
||||||
|
\node[anchor=west] (logo) at (0.3cm,\paperheight-0.4cm) {\includegraphics[height=0.5cm]{TU_Signet}};
|
||||||
|
\fi
|
||||||
|
\end{tikzpicture}
|
||||||
|
}
|
||||||
|
|
||||||
|
% title page
|
||||||
|
\def\beamer@titlepageLeft{1.6cm}
|
||||||
|
\setbeamertemplate{title page}{
|
||||||
|
\vskip 4cm%
|
||||||
|
\begin{beamercolorbox}[leftskip=\beamer@titlepageLeft]{title}%
|
||||||
|
\usebeamerfont{title}\inserttitle%
|
||||||
|
\end{beamercolorbox}%
|
||||||
|
\vskip 0.5cm%
|
||||||
|
\begin{beamercolorbox}[leftskip=\beamer@titlepageLeft]{subtitle}
|
||||||
|
\usebeamerfont{subtitle}\insertsubtitle%
|
||||||
|
\end{beamercolorbox}
|
||||||
|
\vskip 0.25cm%
|
||||||
|
\vfill%
|
||||||
|
\begin{beamercolorbox}[leftskip=\beamer@titlepageLeft]{author}
|
||||||
|
\usebeamerfont{author}\insertauthor%
|
||||||
|
\end{beamercolorbox}
|
||||||
|
\begin{beamercolorbox}[leftskip=\beamer@titlepageLeft]{date}
|
||||||
|
\usebeamerfont{date}\insertdate%
|
||||||
|
\end{beamercolorbox}
|
||||||
|
}
|
||||||
|
|
||||||
|
% frametitle
|
||||||
|
\setbeamertemplate{frametitle}
|
||||||
|
{%
|
||||||
|
\ifbeamer@tuwFrametitleToTop % frametitle should be printed beside the logo
|
||||||
|
% vbox to keep the baseline
|
||||||
|
\vbox{}\vskip -0.43cm%
|
||||||
|
\else
|
||||||
|
\vbox{}\vskip 0.7cm%
|
||||||
|
\fi
|
||||||
|
\begin{beamercolorbox}[leftskip=0cm]{frametitle}
|
||||||
|
\usebeamerfont{frametitle}\insertframetitle%
|
||||||
|
\ifbeamer@tuwFrametitleToTop
|
||||||
|
\vbox{}\vskip 0.3cm%
|
||||||
|
\else
|
||||||
|
\vbox{}\vskip 0.2cm%
|
||||||
|
\fi
|
||||||
|
\usebeamerfont{framesubtitle}\insertframesubtitle%
|
||||||
|
\end{beamercolorbox}
|
||||||
|
}
|
||||||
|
|
||||||
|
% footline
|
||||||
|
\setbeamertemplate{footline}{%
|
||||||
|
\vspace{0.1cm}
|
||||||
|
\ifnum\thepage>1
|
||||||
|
\begin{beamercolorbox}[wd=\paperwidth,ht=2.25ex,dp=1ex]{footline}
|
||||||
|
\hskip 1.2cm%
|
||||||
|
\usebeamerfont{footline}\insertshortdate%
|
||||||
|
\hfill%
|
||||||
|
\insertshorttitle, \insertshortauthor%
|
||||||
|
\hfill%
|
||||||
|
\insertframenumber\:/\:\inserttotalframenumber%
|
||||||
|
\hspace*{1.5cm}%
|
||||||
|
\end{beamercolorbox}
|
||||||
|
\else
|
||||||
|
\begin{beamercolorbox}[wd=\paperwidth,ht=2.25ex,dp=1ex,center]{}%
|
||||||
|
% empty environment to raise height
|
||||||
|
\end{beamercolorbox}
|
||||||
|
\fi
|
||||||
|
\vspace{0.1cm}
|
||||||
|
}
|
||||||
|
|
||||||
|
\else\ifx\beamer@tuwOuter\beamer@tuwSidebar
|
||||||
|
% sidebar outer theme
|
||||||
|
\useoutertheme[width=\beamer@tuwWidth,height=0pt]{\beamer@tuwOuter}
|
||||||
|
|
||||||
|
% footline
|
||||||
|
\setbeamertemplate{footline}{
|
||||||
|
\ifnum\thepage>1
|
||||||
|
\vspace{-1cm}
|
||||||
|
\hfill{\scriptsize\insertframenumber\:/\:\inserttotalframenumber~~}
|
||||||
|
\vspace{0.1cm}
|
||||||
|
\fi
|
||||||
|
}
|
||||||
|
\else
|
||||||
|
\useoutertheme{\beamer@tuwOuter}
|
||||||
|
\fi\fi % if outer=default or outer=sidebar
|
||||||
|
|
||||||
|
|
||||||
|
%%% inner
|
||||||
|
\ifx\beamer@tuwOuter\beamer@tuwDefault
|
||||||
|
\setbeamertemplate{itemize items}[circle]
|
||||||
|
\else
|
||||||
|
% defaults
|
||||||
|
\fi % if outer=default
|
||||||
|
|
||||||
|
\setlength{\parskip}{6pt}
|
||||||
|
|
||||||
|
% blocks
|
||||||
|
\setbeamertemplate{blocks}[rounded]
|
||||||
|
\pgfdeclareverticalshading{bmb@transition}{\the\paperwidth}{color(0pt)=(\iceBlue); color(3.0pt)=(\iceBlue)}
|
||||||
|
|
||||||
|
\setbeamercovered{invisible}
|
||||||
|
|
||||||
|
% emphasize
|
||||||
|
\renewcommand<>{\emph}[1]{{\only#2{\color{\tuwBlue}}#1}}
|
||||||
|
|
||||||
|
\hypersetup{colorlinks=true,linkcolor=fg,citecolor=\tuwGray,urlcolor=\tuwGray}
|
||||||
|
|
||||||
|
\mode<all>
|
||||||
Binary file not shown.
@@ -0,0 +1,280 @@
|
|||||||
|
\documentclass{beamer}
|
||||||
|
%\documentclass[aspectratio=169]{beamer}
|
||||||
|
|
||||||
|
% You have to install the theme first!
|
||||||
|
|
||||||
|
% corporate design of TU Wien
|
||||||
|
\usetheme[font=helvetica]{tuw}
|
||||||
|
% background "TU main building" on title page
|
||||||
|
%\usetheme[tuw_background]{tuw}
|
||||||
|
% individual background on title page
|
||||||
|
%\usetheme[tuw_image=TU_Background]{tuw}
|
||||||
|
% white logo if you have a dark background image
|
||||||
|
%\usetheme[tuw_image=TU_Background,tuw_whitelogo]{tuw}
|
||||||
|
% sidebar (not in TU Wien CD! but nice for long presentations)
|
||||||
|
% width of the sidebar can be changed with option: "width=2cm"
|
||||||
|
%\usetheme[outer=sidebar]{tuw}
|
||||||
|
% move frametitle up (beside logo)
|
||||||
|
%\usetheme[tuw_frametitletotop]{tuw}
|
||||||
|
|
||||||
|
% if you use german umlaute use T1 encoding:
|
||||||
|
%\usepackage[T1]{fontenc}
|
||||||
|
% default Latex fonts are not T1 supported -> bitmaps used, this is not nice on
|
||||||
|
% screen; you can use the lmodern package instead
|
||||||
|
%\usepackage{lmodern}
|
||||||
|
\usepackage[utf8]{inputenc}
|
||||||
|
\usepackage{listings}
|
||||||
|
\usepackage{booktabs}
|
||||||
|
\usepackage{url}
|
||||||
|
\usepackage{xcolor}
|
||||||
|
\usepackage{graphicx}
|
||||||
|
\graphicspath{ {./} }
|
||||||
|
|
||||||
|
\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
|
||||||
|
}
|
||||||
|
|
||||||
|
%%% title page settings
|
||||||
|
\title[SWC-124]{%
|
||||||
|
SWC-124: Write to Arbitrary Storage Location
|
||||||
|
}
|
||||||
|
\subtitle{192.127 Seminar in Software Engineering (Smart Contracts)}
|
||||||
|
\author{Ivaylo Ivanov \& Peter Millauer}
|
||||||
|
\date{\today}
|
||||||
|
|
||||||
|
%%% slides start here
|
||||||
|
\begin{document}
|
||||||
|
|
||||||
|
% first frame must include the title page!
|
||||||
|
\begin{frame}
|
||||||
|
\titlepage
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
% table of contents if you have a long presentation (uses 'part' and 'section'
|
||||||
|
% elements)
|
||||||
|
\begin{frame}{Outline}
|
||||||
|
\tableofcontents
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\section{Introduction}
|
||||||
|
|
||||||
|
\subsection[SWC-124: Weakness Outline]{SWC-124: Weakness Outline}
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{SWC-124: Weakness Outline}
|
||||||
|
SWC-124 is a weakness that allows attackers to write to places in the storage where they should not be able to.
|
||||||
|
It can be used to gain unauthorized access, overwrite data, steal funds etc.
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{SWC-124: Weakness Outline}
|
||||||
|
We generally differentiate three types of SWC-124:
|
||||||
|
\begin{itemize}
|
||||||
|
\item unchecked array write
|
||||||
|
\item incorrect array length check
|
||||||
|
\item unchecked assembly code
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
Examples follow, use in production at your own risk ;)
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Why this works}
|
||||||
|
A dynamic array in storage slot $p$ stores its data at continuous addresses starting at $keccak(p)$.
|
||||||
|
|
||||||
|
For example, if the variable $x$ is a dynamic array occupying storage slot 3, $x[o]$ can be found at $keccak(0x3)+o$.
|
||||||
|
|
||||||
|
An attacker can use this information to overwrite any storage slot by finding an appropriate offset value.
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Why this works}
|
||||||
|
|
||||||
|
\includegraphics[width=\textwidth]{storage}
|
||||||
|
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\subsection[Examples]{Examples}
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Unchecked Array Write}
|
||||||
|
\begin{lstlisting}[language=Solidity]
|
||||||
|
pragma solidity 0.4.25;
|
||||||
|
|
||||||
|
contract MyContract {
|
||||||
|
address private owner;
|
||||||
|
uint[] private arr;
|
||||||
|
|
||||||
|
constructor() public {
|
||||||
|
arr = new uint[](0);
|
||||||
|
owner = msg.sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
function write(unit index, uint value) {
|
||||||
|
arr[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Incorrect Array Length Check}
|
||||||
|
\begin{lstlisting}[language=Solidity, basicstyle=\tiny\ttfamily, numberstyle=\tiny]
|
||||||
|
pragma solidity 0.4.25;
|
||||||
|
|
||||||
|
contract MyContract {
|
||||||
|
uint[] private arr;
|
||||||
|
|
||||||
|
constructor() public {
|
||||||
|
arr = new uint[](0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function push(value) {
|
||||||
|
arr[arr.length] = value;
|
||||||
|
arr.length++;
|
||||||
|
}
|
||||||
|
|
||||||
|
function pop() {
|
||||||
|
require(arr.length >= 0);
|
||||||
|
arr.length--;
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(unit index, uint value) {
|
||||||
|
require(index < arr.length);
|
||||||
|
arr[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Unchecked Assembly}
|
||||||
|
\begin{lstlisting}[language=Solidity, basicstyle=\tiny\ttfamily, numberstyle=\tiny, breaklines=true]
|
||||||
|
pragma solidity 0.4.25;
|
||||||
|
|
||||||
|
contract MyContract {
|
||||||
|
address private owner;
|
||||||
|
mapping(address => bool) public managers;
|
||||||
|
|
||||||
|
constructor() public {
|
||||||
|
owner = msg.sender;
|
||||||
|
setNextUserRole(msg.sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setNextManager(address next) internal {
|
||||||
|
uint256 slot;
|
||||||
|
assembly {
|
||||||
|
slot := managers.slot
|
||||||
|
sstore(slot, next)
|
||||||
|
}
|
||||||
|
bytes32 location = keccak256(abi.encode(160, uint256(slot)));
|
||||||
|
assembly {
|
||||||
|
sstore(location, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerUser(address user) {
|
||||||
|
require(msg.sender == owner);
|
||||||
|
setNextManager(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\section{Detecting and Exploiting}
|
||||||
|
\subsection[Detecting SWC-124]{Detecting SWC-124}
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{SWC-124: Detection Heuristics 1}
|
||||||
|
Any contract without dynamic arrays (or mappings with integer keys) or raw assembly including a SSTORE instruction can immediately be considered non-vulnerable.
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{SWC-124: Detection Heuristics 2}
|
||||||
|
If heuristic 1 does not hold, we can then apply a second heuristic: 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.
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{SWC-124: Detection Heuristics 2.1}
|
||||||
|
If the version of the contract is higher than 0.8.0, we examine whether 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.
|
||||||
|
|
||||||
|
\begin{block}{Note on assembly}
|
||||||
|
Due to the nature of the examples given, we could not find reliable heuristics for unchecked assembly.
|
||||||
|
\end{block}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{SWC-124: Detection Tools}
|
||||||
|
\begin{itemize}
|
||||||
|
\item existing static analysis tools were useless - most of them had no support for SWC-124
|
||||||
|
\item \texttt{solc-select} - for changing solidity compiler versions
|
||||||
|
\item \texttt{slither} - for printing contract variable layout
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\texttt{\$ slither Bethorde.sol --print variable-order}
|
||||||
|
|
||||||
|
\includegraphics[width=\textwidth]{slither}
|
||||||
|
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\subsection[Exploiting SWC-124]{Exploiting SWC-124}
|
||||||
|
|
||||||
|
% TODO: Exploitation is trivial, should we just go back and explain or should we go into memory layout? Can we handle it in time?
|
||||||
|
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Vulnerable Examples}
|
||||||
|
Using the previously mentioned heuristics, we could not find a vulnerable contract from the dataset.
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
\section{Future Work}
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
\frametitle{Future Work}
|
||||||
|
\begin{itemize}
|
||||||
|
\item add heuristics to static analysis tool like \texttt{slither} or \texttt{mythril}
|
||||||
|
\item develop additional vulnerable and non-vulnerable contracts and test against heuristics
|
||||||
|
\item train a model against the resulting dataset
|
||||||
|
\item fine-tune heuristics
|
||||||
|
\end{itemize}
|
||||||
|
\end{frame}
|
||||||
|
\section{Conclusion}
|
||||||
|
\begin{frame}[fragile]
|
||||||
|
Questions?
|
||||||
|
\end{frame}
|
||||||
|
|
||||||
|
|
||||||
|
\end{document}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -0,0 +1,249 @@
|
|||||||
|
\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}
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
Reference in New Issue
Block a user