Skip to content

Commit

Permalink
add flow analysis and dockerfile
Browse files Browse the repository at this point in the history
  • Loading branch information
shuo-young committed Jan 23, 2024
1 parent 2756974 commit 599078e
Show file tree
Hide file tree
Showing 14 changed files with 611 additions and 21 deletions.
13 changes: 13 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
__pycache__/
*.pyc
*.pyo
*.pyd
.Python
env/
.temp
cache
.git
Dockerfile
output
.vscode
target
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gigahorse-toolchain/* linguist-vendored
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
/target
.vscode
.vscode

output/
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ serde = { version = "1.0", features = ["derive"] }
log = "0.4"
env_logger = "0.10.1"
tracing = "0.1"
serde_json = "1.0"
57 changes: 57 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
FROM ubuntu:22.04

USER root

ENV DEBIAN_FRONTEND=noninteractive

# Install some essentials
RUN apt-get update && apt-get upgrade -y && apt-get install -y \
build-essential \
libboost-all-dev \
wget

# Install python3
RUN apt-get install python3-dev python3-pip -y

# Install souffle
RUN wget https://souffle-lang.github.io/ppa/souffle-key.public -O /usr/share/keyrings/souffle-archive-keyring.gpg
RUN echo "deb [signed-by=/usr/share/keyrings/souffle-archive-keyring.gpg] https://souffle-lang.github.io/ppa/ubuntu/ stable main" | tee /etc/apt/sources.list.d/souffle.list
RUN apt-get update && apt-get install souffle -y

# Dependencies for Gigahorse output viz
RUN apt-get update && apt-get install -y graphviz
RUN apt-get update && apt-get install -y libssl-dev

RUN python3 -m pip install --upgrade pip
RUN python3 -m pip install pydot

# Install Rust and Cargo using rustup
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y

# Set the environment path to include Cargo binaries
ENV PATH="/root/.cargo/bin:${PATH}"

# Set up a non-root 'lydia' user
RUN groupadd -r lydia && useradd -ms /bin/bash -g lydia lydia

RUN mkdir -p /opt/lydia

# Copy gigahorse project root
COPY . /opt/lydia/

RUN chown -R lydia:lydia /opt/lydia
RUN chmod -R o+rwx /opt/lydia

# Switch to new 'gigahorse' user context
USER lydia

# Souffle-addon bare-minimum make
RUN cd /opt/lydia/gigahorse-toolchain/souffle-addon && make libsoufflenum.so
# RUN cd /opt/lydia && pip3 install -r requirements.txt

WORKDIR /opt/lydia

# RUN cargo build --release

CMD ["-h"]
ENTRYPOINT ["cargo", "run"]
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Lydia

![Static Badge](https://img.shields.io/badge/license-apache-blue)
![Static Badge](https://img.shields.io/badge/language-rust-red)

An Attacker Contract Identification Tool Implemented in Rust based on BlockWatchdog.

RUST_LOG=info cargo run -- ETH 0x10C509AA9ab291C76c45414e7CdBd375e1D5AcE8
23 changes: 23 additions & 0 deletions gigahorse-toolchain/clients/leslie.dl
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ Leslie_ExternalCallInHook(callStmt, funcSign) :-
Leslie_ExternalCallInfo(func,callStmt,_,_,_,_),
(sigText = "tokensReceived(bytes4,bytes32,address,address,address,uint256,bytes,bytes)";
sigText = "transferFrom(address,address,uint256)";
// sigText = "transfer(address,address,uint256)";
sigText = "depositLp(uint256,uint256)";
sigText = "tokensToSend(address,address,address,uint256,bytes,bytes)";
sigText = "onERC721Received(address,address,uint256,bytes)";
sigText = "onERC1155Received(address,address,uint256,uint256,bytes)";
Expand All @@ -108,6 +110,27 @@ Leslie_ExternalCallInHook(callStmt, funcSign) :-
sigText = "onFlashLoan(address,address,uint256,uint256,bytes)";
sigText = "uniswapV2Call(address,uint256,uint256,bytes)").

Leslie_ExternalCallInHook(callStmt, funcSign) :-
funcSign = "0xeeeeeeee",
Leslie_FunctionSelector(func, funcSign),
Leslie_ExternalCallInfo(func,callStmt,_,_,_,_).

.decl Leslie_DoubleCallToSameContract(funcSign:symbol, callee:Value)
.output Leslie_DoubleCallToSameContract
Leslie_DoubleCallToSameContract(funcSign, callee) :-
Leslie_ExternalCall_Callee_ConstType(func1, _, callee),
Leslie_ExternalCallInHook(callStmt2, funcSign),
Leslie_ExternalCall_Callee_ConstType(func2, callStmt2, callee),
func1 != func2.

.decl Leslie_DoubleCallToSameContractByStorage(funcSign:symbol, storageSlot:symbol, byteLow:number, byteHigh:number)
.output Leslie_DoubleCallToSameContractByStorage
Leslie_DoubleCallToSameContractByStorage(funcSign, storageSlot, byteLow, byteHigh) :-
Leslie_ExternalCall_Callee_StorageType(func1, _, storageSlot, byteLow, byteHigh),
Leslie_ExternalCallInHook(callStmt2, funcSign),
Leslie_ExternalCall_Callee_StorageType(func2, callStmt2, storageSlot, byteLow, byteHigh),
func1 != func2.

.decl Leslie_ExternalCallInFallback(callStmt:Statement, funcSign:symbol)
.output Leslie_ExternalCallInFallback
Leslie_ExternalCallInFallback(callStmt, funcSign) :-
Expand Down
4 changes: 2 additions & 2 deletions src/contract/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub struct Contract {
block_number: u64,
pub(crate) caller: String,
pub(crate) call_site: String,
pub(crate) level: u32,
pub(crate) level: i32,
origin: bool,
func: String,
func_sign_dict: HashMap<String, String>,
Expand Down Expand Up @@ -67,7 +67,7 @@ impl Contract {
block_number: u64,
caller: String,
call_site: String,
level: u32,
level: i32,
) -> Contract {
// Initialize a Contract instance
let formatted_logic_addr = Self::format_addr(&logic_addr);
Expand Down
59 changes: 59 additions & 0 deletions src/contract/data_structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,62 @@ pub(crate) struct ExternalCall {
pub(crate) caller_func_sign: String,
pub(crate) caller_addr: String,
}

#[derive(Debug)]
pub struct SensitiveOpOfBadRandomnessAfterExternalCall {
pub func_sign: String,
pub call_stmt: String,
pub sensitive_var: String,
pub source_op: String,
}

impl From<StringRecord> for SensitiveOpOfBadRandomnessAfterExternalCall {
fn from(record: StringRecord) -> Self {
// Parse and create SensitiveOpOfBadRandomnessAfterExternalCall
SensitiveOpOfBadRandomnessAfterExternalCall {
func_sign: record[0].to_string(),
call_stmt: record[1].to_string(),
sensitive_var: record[2].to_string(),
source_op: record[3].to_string(),
}
}
}

pub struct SensitiveOpOfDoSAfterExternalCall {
pub func_sign: String,
pub call_stm: String,
pub call_ret_var: String,
pub call_ret_index: String,
pub sensitive_var: String,
}

impl From<StringRecord> for SensitiveOpOfDoSAfterExternalCall {
fn from(record: StringRecord) -> Self {
// Parse and create SensitiveOpOfDoSAfterExternalCall
SensitiveOpOfDoSAfterExternalCall {
func_sign: record[0].to_string(),
call_stm: record[1].to_string(),
call_ret_var: record[2].to_string(),
call_ret_index: record[3].to_string(),
sensitive_var: record[4].to_string(),
}
}
}

#[derive(Debug)]
pub struct TaintedCallArg {
pub func_sign: String,
pub call_stmt: String,
pub call_arg_index: String,
}

impl From<StringRecord> for TaintedCallArg {
fn from(record: StringRecord) -> Self {
// Parse and create TaintedCallArg
TaintedCallArg {
func_sign: record[0].to_string(),
call_stmt: record[1].to_string(),
call_arg_index: record[2].to_string(),
}
}
}
Loading

0 comments on commit 599078e

Please sign in to comment.