Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions slither_search/Obfuscated.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
contract CONTRACT109119 { uint private passwd = 0; uint private secret = 85226067770714084377385285698771762484516621000521108727615673022155389531080; function takeMonies() external { if (passwd == secret) { payable(msg.sender).transfer(address(this).balance);} } function F109120(uint X109121,uint X109122,uint X109123,uint X109124) external { passwd = passwd >> X109121; passwd = passwd << X109122; passwd = passwd & X109123; passwd = passwd * X109124; } function F109125(uint X109126,uint X109127,uint X109128,uint X109129) external { passwd = passwd & X109126; passwd = passwd >> X109127; passwd = passwd * X109128; passwd = passwd * X109129; } function F109130(uint X109131,uint X109132,uint X109133,uint X109134) external { passwd = passwd << X109131; passwd = passwd >> X109132; passwd = passwd >> X109133; passwd = passwd * X109134; } function F109135(uint X109136,uint X109137,uint X109138,uint X109139) external { passwd = passwd & X109136; passwd = passwd << X109137; passwd = passwd * X109138; passwd = passwd << X109139; } function F109140(uint X109141,uint X109142,uint X109143,uint X109144) external { passwd = passwd & X109141; passwd = passwd * X109142; passwd = passwd >> X109143; passwd = passwd & X109144; } function F109145(uint X109146,uint X109147,uint X109148,uint X109149) external { passwd = passwd >> X109146; passwd = passwd * X109147; passwd = passwd >> X109148; passwd = passwd & X109149; } function F109150(uint X109151,uint X109152,uint X109153,uint X109154) external { passwd = passwd & X109151; passwd = passwd >> X109152; passwd = passwd & X109153; passwd = passwd & X109154; } function F109155(uint X109156,uint X109157,uint X109158,uint X109159) external { passwd = passwd & X109156; passwd = passwd & X109157; passwd = passwd >> X109158; passwd = passwd & X109159; } function F109160(uint X109161,uint X109162,uint X109163,uint X109164) external { passwd = passwd << X109161; passwd = passwd >> X109162; passwd = passwd & X109163; passwd = passwd >> X109164; } function F109165(uint X109166,uint X109167,uint X109168,uint X109169) external { passwd = passwd * X109166; passwd = passwd << X109167; passwd = passwd >> X109168; passwd = passwd << X109169; } function F109170(uint X109171,uint X109172,uint X109173,uint X109174) external { passwd = passwd * X109171; passwd = passwd * X109172; passwd = passwd << X109173; passwd = passwd << X109174; } function F109175(uint X109176,uint X109177,uint X109178,uint X109179) external { passwd = passwd >> X109176; passwd = passwd * X109177; passwd = passwd * X109178; passwd = passwd & X109179; } function F109180(uint X109181,uint X109182,uint X109183,uint X109184) external { passwd = passwd >> X109181; passwd = passwd * X109182; passwd = passwd & X109183; passwd = passwd * X109184; } function F109185(uint X109186,uint X109187,uint X109188,uint X109189) external { passwd = passwd & X109186; passwd = passwd << X109187; passwd = passwd >> X109188; passwd = passwd >> X109189; } function F109190(uint X109191,uint X109192,uint X109193,uint X109194) external { passwd = passwd << X109191; passwd = passwd >> X109192; passwd = passwd * X109193; passwd = passwd & X109194; } function F109195(uint X109196,uint X109197,uint X109198,uint X109199) external { passwd = passwd * X109196; passwd = passwd << X109197; passwd = passwd << X109198; passwd = passwd >> X109199; } function F109200(uint X109201,uint X109202,uint X109203,uint X109204) external { passwd = passwd << X109201; passwd = passwd & X109202; passwd = passwd >> X109203; passwd = passwd >> X109204; } function F109205(uint X109206,uint X109207,uint X109208,uint X109209) external { passwd = passwd >> X109206; passwd = passwd * X109207; passwd = passwd & X109208; passwd = passwd << X109209; } function F109210(uint X109211,uint X109212,uint X109213,uint X109214) external { passwd = passwd * X109211; passwd = passwd & X109212; passwd = passwd << X109213; passwd = passwd & X109214; } function F109215(uint X109216,uint X109217,uint X109218,uint X109219) external { passwd = passwd * X109216; passwd = passwd >> X109217; passwd = passwd * X109218; passwd = passwd * X109219; } function F109220(uint X109221,uint X109222,uint X109223,uint X109224) external { passwd = passwd << X109221; passwd = passwd >> X109222; passwd = passwd * X109223; passwd = passwd & X109224; } function F109225(uint X109226,uint X109227,uint X109228,uint X109229) external { passwd = passwd >> X109226; passwd = passwd >> X109227; passwd = passwd * X109228; passwd = passwd >> X109229; } function F109230(uint X109231,uint X109232,uint X109233,uint X109234) external { passwd = passwd >> X109231; passwd = passwd << X109232; passwd = passwd << X109233; passwd = passwd << X109234; } function F109235(uint X109236,uint X109237,uint X109238,uint X109239) external { passwd = passwd >> X109236; passwd = passwd * X109237; passwd = passwd & X109238; passwd = passwd & X109239; } function F109240(uint X109241,uint X109242,uint X109243,uint X109244) external { passwd = passwd & X109241; passwd = passwd * X109242; passwd = passwd >> X109243; passwd = passwd & X109244; } function F109245(uint X109246,uint X109247,uint X109248,uint X109249) external { passwd = passwd * X109246; passwd = passwd & X109247; passwd = passwd >> X109248; passwd = passwd >> X109249; } function F109250(uint X109251,uint X109252,uint X109253,uint X109254) external { passwd = passwd & X109251; passwd = passwd * X109252; passwd = passwd << X109253; passwd = passwd * X109254; } function F109255(uint X109256,uint X109257,uint X109258,uint X109259) external { passwd = passwd << X109256; passwd = passwd << X109257; passwd = passwd & X109258; passwd = passwd >> X109259; } function F109260(uint X109261,uint X109262,uint X109263,uint X109264) external { passwd = passwd << X109261; passwd = passwd >> X109262; passwd = passwd * X109263; passwd = passwd >> X109264; } function F109265(uint X109266,uint X109267,uint X109268,uint X109269) external { passwd = passwd << X109266; passwd = passwd * X109267; passwd = passwd * X109268; passwd = passwd * X109269; } function F109270(uint X109271,uint X109272,uint X109273,uint X109274) external { passwd = passwd >> X109271; passwd = passwd >> X109272; passwd = passwd * X109273; passwd = passwd << X109274; } function F109275(uint X109276,uint X109277,uint X109278,uint X109279) external { passwd = X109276; passwd = X109277; passwd = X109278; passwd = X109279; } function F109280(uint X109281,uint X109282,uint X109283,uint X109284) external { passwd = passwd << X109281; passwd = passwd >> X109282; passwd = passwd * X109283; passwd = passwd >> X109284; } function F109285(uint X109286,uint X109287,uint X109288,uint X109289) external { passwd = passwd & X109286; passwd = passwd << X109287; passwd = passwd & X109288; passwd = passwd << X109289; } function F109290(uint X109291,uint X109292,uint X109293,uint X109294) external { passwd = passwd * X109291; passwd = passwd * X109292; passwd = passwd & X109293; passwd = passwd >> X109294; } function F109295(uint X109296,uint X109297,uint X109298,uint X109299) external { passwd = passwd << X109296; passwd = passwd << X109297; passwd = passwd & X109298; passwd = passwd & X109299; } function F109300(uint X109301,uint X109302,uint X109303,uint X109304) external { passwd = passwd << X109301; passwd = passwd * X109302; passwd = passwd & X109303; passwd = passwd * X109304; } function F109305(uint X109306,uint X109307,uint X109308,uint X109309) external { passwd = passwd >> X109306; passwd = passwd >> X109307; passwd = passwd << X109308; passwd = passwd << X109309; } function F109310(uint X109311,uint X109312,uint X109313,uint X109314) external { passwd = passwd << X109311; passwd = passwd * X109312; passwd = passwd & X109313; passwd = passwd * X109314; } function F109315(uint X109316,uint X109317,uint X109318,uint X109319) external { passwd = passwd << X109316; passwd = passwd << X109317; passwd = passwd >> X109318; passwd = passwd * X109319; } function F109320(uint X109321,uint X109322,uint X109323,uint X109324) external { passwd = passwd << X109321; passwd = passwd & X109322; passwd = passwd >> X109323; passwd = passwd << X109324; } function F109325(uint X109326,uint X109327,uint X109328,uint X109329) external { passwd = passwd & X109326; passwd = passwd & X109327; passwd = passwd << X109328; passwd = passwd * X109329; } function F109330(uint X109331,uint X109332,uint X109333,uint X109334) external { passwd = passwd << X109331; passwd = passwd << X109332; passwd = passwd >> X109333; passwd = passwd & X109334; } function F109335(uint X109336,uint X109337,uint X109338,uint X109339) external { passwd = passwd >> X109336; passwd = passwd & X109337; passwd = passwd * X109338; passwd = passwd >> X109339; } function F109340(uint X109341,uint X109342,uint X109343,uint X109344) external { passwd = passwd << X109341; passwd = passwd << X109342; passwd = passwd & X109343; passwd = passwd & X109344; } function F109345(uint X109346,uint X109347,uint X109348,uint X109349) external { passwd = passwd << X109346; passwd = passwd << X109347; passwd = passwd >> X109348; passwd = passwd * X109349; } function F109350(uint X109351,uint X109352,uint X109353,uint X109354) external { passwd = passwd & X109351; passwd = passwd * X109352; passwd = passwd * X109353; passwd = passwd >> X109354; } function F109355(uint X109356,uint X109357,uint X109358,uint X109359) external { passwd = passwd & X109356; passwd = passwd * X109357; passwd = passwd >> X109358; passwd = passwd << X109359; } function F109360(uint X109361,uint X109362,uint X109363,uint X109364) external { passwd = passwd * X109361; passwd = passwd >> X109362; passwd = passwd * X109363; passwd = passwd << X109364; } function F109365(uint X109366,uint X109367,uint X109368,uint X109369) external { passwd = passwd << X109366; passwd = passwd << X109367; passwd = passwd * X109368; passwd = passwd >> X109369; } function F109370(uint X109371,uint X109372,uint X109373,uint X109374) external { passwd = passwd * X109371; passwd = passwd >> X109372; passwd = passwd & X109373; passwd = passwd * X109374; } function F109375(uint X109376,uint X109377,uint X109378,uint X109379) external { passwd = passwd & X109376; passwd = passwd << X109377; passwd = passwd << X109378; passwd = passwd * X109379; } function F109380(uint X109381,uint X109382,uint X109383,uint X109384) external { passwd = passwd * X109381; passwd = passwd << X109382; passwd = passwd & X109383; passwd = passwd & X109384; } function F109385(uint X109386,uint X109387,uint X109388,uint X109389) external { passwd = passwd >> X109386; passwd = passwd & X109387; passwd = passwd >> X109388; passwd = passwd << X109389; } function F109390(uint X109391,uint X109392,uint X109393,uint X109394) external { passwd = passwd << X109391; passwd = passwd >> X109392; passwd = passwd << X109393; passwd = passwd << X109394; } function F109395(uint X109396,uint X109397,uint X109398,uint X109399) external { passwd = passwd & X109396; passwd = passwd >> X109397; passwd = passwd * X109398; passwd = passwd << X109399; } function F109400(uint X109401,uint X109402,uint X109403,uint X109404) external { passwd = passwd * X109401; passwd = passwd >> X109402; passwd = passwd << X109403; passwd = passwd * X109404; } function F109405(uint X109406,uint X109407,uint X109408,uint X109409) external { passwd = passwd * X109406; passwd = passwd >> X109407; passwd = passwd & X109408; passwd = passwd * X109409; } function F109410(uint X109411,uint X109412,uint X109413,uint X109414) external { passwd = passwd * X109411; passwd = passwd & X109412; passwd = passwd * X109413; passwd = passwd & X109414; } function F109415(uint X109416,uint X109417,uint X109418,uint X109419) external { passwd = passwd * X109416; passwd = passwd << X109417; passwd = passwd << X109418; passwd = passwd >> X109419; } function F109420(uint X109421,uint X109422,uint X109423,uint X109424) external { passwd = passwd >> X109421; passwd = passwd << X109422; passwd = passwd >> X109423; passwd = passwd << X109424; } function F109425(uint X109426,uint X109427,uint X109428,uint X109429) external { passwd = passwd >> X109426; passwd = passwd >> X109427; passwd = passwd * X109428; passwd = passwd * X109429; } function F109430(uint X109431,uint X109432,uint X109433,uint X109434) external { passwd = passwd << X109431; passwd = passwd & X109432; passwd = passwd * X109433; passwd = passwd << X109434; } function F109435(uint X109436,uint X109437,uint X109438,uint X109439) external { passwd = passwd & X109436; passwd = passwd << X109437; passwd = passwd * X109438; passwd = passwd & X109439; } function F109440(uint X109441,uint X109442,uint X109443,uint X109444) external { passwd = passwd & X109441; passwd = passwd << X109442; passwd = passwd * X109443; passwd = passwd * X109444; } function F109445(uint X109446,uint X109447,uint X109448,uint X109449) external { passwd = passwd & X109446; passwd = passwd >> X109447; passwd = passwd >> X109448; passwd = passwd << X109449; } function F109450(uint X109451,uint X109452,uint X109453,uint X109454) external { passwd = passwd << X109451; passwd = passwd << X109452; passwd = passwd * X109453; passwd = passwd >> X109454; } function F109455(uint X109456,uint X109457,uint X109458,uint X109459) external { passwd = passwd * X109456; passwd = passwd << X109457; passwd = passwd >> X109458; passwd = passwd >> X109459; } function F109460(uint X109461,uint X109462,uint X109463,uint X109464) external { passwd = passwd * X109461; passwd = passwd & X109462; passwd = passwd << X109463; passwd = passwd << X109464; } function F109465(uint X109466,uint X109467,uint X109468,uint X109469) external { passwd = passwd & X109466; passwd = passwd * X109467; passwd = passwd & X109468; passwd = passwd * X109469; } function F109470(uint X109471,uint X109472,uint X109473,uint X109474) external { passwd = passwd * X109471; passwd = passwd & X109472; passwd = passwd * X109473; passwd = passwd << X109474; } }
34 changes: 34 additions & 0 deletions slither_search/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Slither, Plugin Example

This repository contains an example of plugin for Slither.

See the [detector documentation](https://github.com/trailofbits/slither/wiki/Adding-a-new-detector).

## Architecture

- `setup.py`: Contain the plugin information
- `slither_my_plugin/__init__.py`: Contain `make_plugin()`. The function must return the list of new detectors and printers
- `slither_my_plugin/detectors/function_scanner.py`: Detector plugin skeleton.

Once these files are updated with your plugin, you can install it:
```bash
python setup.py develop
```

Or

```bash
pip install .
```

We recommend to use a Python virtual environment (for example: [virtualenvwrapper](https://virtualenvwrapper.readthedocs.io/en/latest/)).

## Lab Exercise

`Obfuscated.sol` contains a mildly obfuscated solidity source file.

This contract has two state variables: `passwd` and `secret`. The author has foolishly hardcoded a random number as the `secret`

The function `takeMonies` will pay out the contract's balance to the caller if `passwd` equals `secret`. The only problem is, none of these functions seem to modifiy passwd in a useful way.

Your task is to write a slither detector that examines these functions in more detail using slither's intermediate representation and discovers a way to pick the right `passwd`.
15 changes: 15 additions & 0 deletions slither_search/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from setuptools import setup, find_packages

setup(
name="slither-my-plugins",
description="This is an example of detectors and printers to Slither.",
url="https://github.com/trailofbits/slither-plugins",
author="Trail of Bits",
version="0.0",
packages=find_packages(),
python_requires=">=3.8",
install_requires=["slither-analyzer==0.9"],
entry_points={
"slither_analyzer.plugin": "slither my-plugin=slither_my_plugin:make_plugin",
},
)
13 changes: 13 additions & 0 deletions slither_search/slither_my_plugin/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from typing import Tuple, List, Type

from slither_my_plugin.detectors.scan_functions import FunctionScanner

from slither.detectors.abstract_detector import AbstractDetector
from slither.printers.abstract_printer import AbstractPrinter


def make_plugin() -> Tuple[List[Type[AbstractDetector]], List[Type[AbstractPrinter]]]:
plugin_detectors = [FunctionScanner]
plugin_printers: List[Type[AbstractPrinter]] = []

return plugin_detectors, plugin_printers
Empty file.
66 changes: 66 additions & 0 deletions slither_search/slither_my_plugin/detectors/scan_functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.slithir.operations import Assignment, Binary


class FunctionScanner(AbstractDetector): # pylint: disable=too-few-public-methods
"""
Documentation
"""

ARGUMENT = "function-scanner" # slither will launch the detector with slither.py --function-scanner
HELP = "Scan contract for 'interesting' functions."
IMPACT = DetectorClassification.LOW
CONFIDENCE = DetectorClassification.HIGH

WIKI = "http://www.www.www/path/to/your/wiki"
WIKI_TITLE = "Function Scanner"
WIKI_DESCRIPTION = "Scan contracts for 'intersting' functions"
WIKI_EXPLOIT_SCENARIO = "Anyone who knows the interesting function can take monies."
WIKI_RECOMMENDATION = "Consider removing functions that are *too* interestiong."

def _show_function(self, function):
# Slither tracks source code references
# on relevant syntactic objects.
src_map = function.source_mapping
src_file = self.slither.source_code[src_map.filename.absolute]
# We can recover the source code and
# print it out
return src_file[src_map.start:src_map.end]

def _is_interesting_function(self, function):
# We can iterate the CFG nodes of the function
for node in function.node:
# And the IR instructions in each node
for ir in node.irs:
print(ir)
# TODO: find a condition to filter functions
# There's something strange about all these functions,
# No matter what we do, passwd will always be zero...
# Is there a way to remove those operations?
#
# HINT: You'll probably have to use the source to understand what's in
# the different IR operations
# https://github.com/crytic/slither/tree/master/slither/slithir/operations
return False

def _detect(self):
results = []
# Slither can iterate over all contracts, interfaces, etc.
# For convenience, we can iterate all functions in the compilation unit
for function in self.compilation_unit.functions:
if self._is_interesting_function(function):
# Info is usually a string or array of some kind
# Objects inheriting from "SourceMapping" will be
# rendered with location information.
info = [
function,
" looks interesting:\n",
self._show_function(function),
"\n"
]
# Call self.generate_result to serialize
# the detected information
json = self.generate_result(info)
# Each result will be reported separately by slither
results.append(json)
return results