Skip to content

Commit

Permalink
Merge pull request #15 from quarkslab/refactor/refactor-engines
Browse files Browse the repository at this point in the history
Refactor engines
  • Loading branch information
cnheitman authored Jul 17, 2024
2 parents 288326e + 4c470da commit 44f0507
Show file tree
Hide file tree
Showing 30 changed files with 83 additions and 82 deletions.
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ At the moment it supports the following fuzzing engines:

<p align="center" style="font-size:20px">
<a href="https://quarkslab.github.io/pastis">
[Documentation]
[Documentation]
</a>
</p>

Expand All @@ -30,7 +30,7 @@ At the moment it supports the following fuzzing engines:
</a>
<img src="https://img.shields.io/github/downloads/quarkslab/pastis/total"/>
<img src="https://img.shields.io/pypi/dm/pastis-framework"/>

</p>

---
Expand Down Expand Up @@ -99,7 +99,7 @@ pastis-aflpp online
Or:

```commandline
pastis-triton online
pastis-tritondse online
```

Full documentation is available: [here](https://quarkslab.github.io/pastis/campaign.html)
Expand Down Expand Up @@ -146,14 +146,14 @@ The PASTIS Docker image has already installed all the needed dependencies such a

## Papers and conference

* **Symbolic Execution the Swiss-Knife of the Reverse Engineer Toolbox**
**Venue**: KLEE Workshop, 2022 [[:books:]](https://srg.doc.ic.ac.uk/klee22/talks/David-Reverse-Engineering.pdf) [[:movie_camera:]](https://youtu.be/PNbNtTa5Sp4)
**Authors**: Robin David, Richard Abou Chaaya, Christian Heitman
* **Symbolic Execution the Swiss-Knife of the Reverse Engineer Toolbox**
**Venue**: KLEE Workshop, 2022 [[:books:]](https://srg.doc.ic.ac.uk/klee22/talks/David-Reverse-Engineering.pdf) [[:movie_camera:]](https://youtu.be/PNbNtTa5Sp4)
**Authors**: Robin David, Richard Abou Chaaya, Christian Heitman


* **From source code to crash test-case through software testing automation**
**Venue**: European Cyber Week, C&ESAR Workshop, 2021 [paper](https://ceur-ws.org/Vol-3056/paper-02.pdf) [slides](https://github.com/quarkslab/conf-presentations/blob/main-page/C%26ESAR-2021/CESAR-2021_slides_2-2.pdf)
**Authors**: Robin David, Jonathan Salwan, Justin Bourroux
* **From source code to crash test-case through software testing automation**
**Venue**: European Cyber Week, C&ESAR Workshop, 2021 [paper](https://ceur-ws.org/Vol-3056/paper-02.pdf) [slides](https://github.com/quarkslab/conf-presentations/blob/main-page/C%26ESAR-2021/CESAR-2021_slides_2-2.pdf)
**Authors**: Robin David, Jonathan Salwan, Justin Bourroux


## Cite Pastis
Expand Down
12 changes: 6 additions & 6 deletions bin/pastis-benchmark
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ from pastisbroker.workspace import Workspace
from libpastis.types import CheckMode, SeedInjectLoc

# Engines imports
from pastishf import HonggfuzzDriver, spawn_online_honggfuzz
from pastishonggfuzz import HonggfuzzDriver, spawn_online_honggfuzz
from pastisaflpp import spawn_online_aflpp, check_scaling_frequency
from pastisdse import spawn_online_triton
from pastistritondse import spawn_online_triton

from pastisbenchmark.replayer import ReplayType, Replayer
from pastisbenchmark.plotter import Plotter
Expand Down Expand Up @@ -127,9 +127,9 @@ def clean(workspace: str):
def showmap(bins: str):

MAP = {
"Triton": "pastisttbroker",
"Honggfuzz": "hfbroker",
"AFL++": "aflppbroker"
"Triton": "pastistritondse.addon",
"Honggfuzz": "pastishonggfuzz.addon",
"AFL++": "pastisaflpp.addon"
}
mapping = {k: load_engine_descriptor(v) for k,v in MAP.items()}
for file in iterate_file(bins):
Expand Down Expand Up @@ -245,7 +245,7 @@ def run(workspace: str, bins: str, seeds: str, mode: str, injloc: str, aflpp: bo
if not tt_confs.exists(): # if folder is empty
logging.info(f"{tt_confs} not found fall back current workdir")
tt_confs = Path("triton_confs")
broker.load_engine_addon("pastisttbroker")
broker.load_engine_addon("pastistritondse.addon")
if tt_confs.exists():
for i, conf in enumerate(sorted(tt_confs.iterdir())):
with open(conf, "r+") as fd:
Expand Down
16 changes: 8 additions & 8 deletions bin/pastisd
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ except ImportError:
hfwrapper, Honggfuzz = None, None
HONGGFUZZ_AVAILABLE = False
try:
import pastisdse
from pastisdse import PastisDSE
PASTISDSE_AVAILABLE = True
import pastistritondse
from pastistritondse import TritonDSEDriver
PASTISTRITONDSE_AVAILABLE = True
except ImportError:
pastisdse, PastisDSE = None, None
PASTISDSE_AVAILABLE = False
pastistritondse, TritonDSEDriver = None, None
PASTISTRITONDSE_AVAILABLE = False


PASTIS_MASTER = "pastis.lan"
Expand Down Expand Up @@ -61,7 +61,7 @@ def start_received(*args):
logging.critical("Can't find Honggfuzzz HFUZZ_DATA not set")

elif engine == FuzzingEngine.TRITON:
engine = PastisDSE(agent)
engine = TritonDSEDriver(agent)
configure_logging(logging.DEBUG, "%(asctime)s %(threadName)s [%(levelname)s] %(message)s")
engine.start_received(*args)
engine.start()
Expand All @@ -80,8 +80,8 @@ def main(host=PASTIS_MASTER):
engines.append((FuzzingEngine.HONGGFUZZ, hfwrapper.__version__))
else:
logging.warning("Honggfuzz is not available (cannot import it)")
if PASTISDSE_AVAILABLE:
engines.append((FuzzingEngine.TRITON, pastisdse.__version__))
if PASTISTRITONDSE_AVAILABLE:
engines.append((FuzzingEngine.TRITON, pastistritondse.__version__))
else:
logging.warning("Triton is not available (cannot import it)")

Expand Down
4 changes: 2 additions & 2 deletions doc/adding-fuzzer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,5 @@ There is nothing like examples. Thus one can see existing drivers to see how the
implemented and how they work. They can be used as a basis for other fuzzing engines.

* tiny test clients: `test_client.py <https://github.com/quarkslab/pastis/blob/main/tests/test_client.py>`_
* Honggfuzz driver: `driver.py <https://github.com/quarkslab/pastis/blob/main/engines/pastis-honggfuzz/pastishf/driver.py>`_
* TritonDSE driver: `pastisdse.py <https://github.com/quarkslab/pastis/blob/main/engines/pastis-triton/pastisdse/pastisdse.py>`_
* Honggfuzz driver: `driver.py <https://github.com/quarkslab/pastis/blob/main/engines/pastis-honggfuzz/pastishonggfuzz/driver.py>`_
* TritonDSE driver: `driver.py <https://github.com/quarkslab/pastis/blob/main/engines/pastis-tritondse/pastistritondse/driver.py>`_
2 changes: 1 addition & 1 deletion doc/campaign.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ Engines can be launched with theirs appropriate binary:

* AFL++: ``pastis-aflpp online [IP] [PORT]``
* Honggfuzz: ``pastis-honggfuzz online [IP] [PORT]``
* TritonDSE: ``pastis-triton online [IP] [PORT]``
* TritonDSE: ``pastis-tritondse online [IP] [PORT]``

If no IP or port is provided, they will automatically connect to *localhost:5555*.

Expand Down
10 changes: 5 additions & 5 deletions doc/engines/tritondse.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
TritonDSE
=========

The utility ``pastis-triton`` enables launching a TritonDSE. It can be launched
The utility ``pastis-tritondse`` enables launching a TritonDSE. It can be launched
in an alert driven manner in ``ALERT_ONLY`` or in independent manner with ``CHECK_ALL``.
Also, it can be run in two modes, `online` to interact with a ``pastis-broker`` server or `offline`
to run locally on its own.
Expand All @@ -12,17 +12,17 @@ Online
The online mode only requires an IP and a port to run as all subsequent parameters
will be provided by the broker. The default IP and port are *localhost* on *5555*.

If the broker is running on the same machine ``pastis-triton`` can be launched with:
If the broker is running on the same machine ``pastis-tritondse`` can be launched with:

::

$ pastis-triton online
$ pastis-tritondse online

If the broker runs on a different machine it can then be launched with:

::

$ pastis-triton online -h 8.8.8.8 -p 5555
$ pastis-tritondse online -h 8.8.8.8 -p 5555


The utility will then automatically receive the parameters, the binary to test and
Expand All @@ -39,7 +39,7 @@ on the commande line. The help message is the following:

::

Usage: pastis-triton offline [OPTIONS] PROGRAM [PARGVS]...
Usage: pastis-tritondse offline [OPTIONS] PROGRAM [PARGVS]...

Options:
-r, --sast-report FILE SAST report to use
Expand Down
2 changes: 1 addition & 1 deletion doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ PASTIS in action
..
pastis-aflpp <api/aflpp>
pastis-honggfuzz <api/honggfuzz>
pastis-triton <api/tritondse>
pastis-tritondse <api/tritondse>


Expand Down
4 changes: 2 additions & 2 deletions doc/tutorials/demo-fsm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@ Once ready we can run TritonDSE on the target with:

.. code-block:: bash
pastis-triton online
pastis-tritondse online
It will connect the broker that will send it the *fsm.tt* target with the right
configuration.

.. note:: If you want to run TritonDSE with a specific configuration it has to be
be provided via the broker with ``-e pastisttbroker --tt-config conf.json``.
be provided via the broker with ``-e pastistritondse.addon --tt-config conf.json``.
The ``-e`` preload the tritondse addon in order to be able to load the
configuration file.

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#!/usr/bin/env python3

# To run it offline
# pastis-aflpp offline [OPTS] BINARY PARAMS
#
Expand Down Expand Up @@ -116,5 +114,9 @@ def offline(program: str, sast_report: Optional[str], seed: Tuple[str], exmode,
aflpp.stop()


if __name__ == "__main__":
def main():
cli()


if __name__ == "__main__":
main()
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def init_agent(self, remote: str = "localhost", port: int = 5555):
self._agent.connect(remote, port)
self._agent.start()
# Send initial HELLO message, whick will make the Broker send the START message.
self._agent.send_hello([FuzzingEngineInfo("AFLPP", pastisaflpp.__version__, "aflppbroker")])
self._agent.send_hello([FuzzingEngineInfo("AFLPP", pastisaflpp.__version__, "pastisaflpp.addon")])

def run(self):
self.aflpp.wait()
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#!/usr/bin/env python3

# To run it offline
# pastis-honggfuzz offline [OPTS] BINARY PARAMS
#
Expand All @@ -19,7 +17,7 @@
from libpastis.types import ExecMode, CoverageMode, SeedInjectLoc, CheckMode, FuzzingEngineInfo, FuzzMode

# Local imports
from pastishf import HonggfuzzDriver, __version__
from pastishonggfuzz import HonggfuzzDriver, __version__


coloredlogs.install(level=logging.DEBUG,
Expand Down Expand Up @@ -114,5 +112,9 @@ def offline(program: str, sast_report: Optional[str], seed: Tuple[str], exmode,
honggfuzz.stop()


if __name__ == "__main__":
def main():
cli()


if __name__ == "__main__":
main()
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
LogLevel, AlertData, FuzzMode

# Local imports
import pastishf
from pastishf.replay import Replay
from pastishf.honggfuzz import HonggfuzzProcess
from pastishf.workspace import Workspace
import pastishonggfuzz
from pastishonggfuzz.replay import Replay
from pastishonggfuzz.honggfuzz import HonggfuzzProcess
from pastishonggfuzz.workspace import Workspace


# Inotify logs are very talkative, set them to ERROR
Expand Down Expand Up @@ -121,7 +121,7 @@ def init_agent(self, remote: str = "localhost", port: int = 5555):
self._agent.connect(remote, port)
self._agent.start()
# Send initial HELLO message, whick will make the Broker send the START message.
self._agent.send_hello([FuzzingEngineInfo("HONGGFUZZ", pastishf.__version__, "hfbroker")])
self._agent.send_hello([FuzzingEngineInfo("HONGGFUZZ", pastishonggfuzz.__version__, "pastishonggfuzz.addon")])

def run(self):
self.honggfuzz.wait()
Expand Down Expand Up @@ -238,7 +238,7 @@ def start_received(self, fname: str, binary: bytes, engine: FuzzingEngineInfo, e
logging.error(f"Wrong fuzzing engine received {engine.name} while I am Honggfuzz")
self._agent.send_log(LogLevel.ERROR, f"Invalid fuzzing engine received {engine.name} can't do anything")
return
if engine.version != pastishf.__version__:
if engine.version != pastishonggfuzz.__version__:
logging.error(f"Wrong fuzzing engine version {engine.version} received")
self._agent.send_log(LogLevel.ERROR, f"Invalid fuzzing engine version {engine.version} do nothing")
return
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Tuple
import subprocess

from .pastisdse import PastisDSE
from .driver import TritonDSEDriver

# Expose triton version
import tritondse
Expand All @@ -12,7 +12,7 @@


def spawn_online_triton(port: int = 5555, probe: Tuple[str] = ()):
tt = ["pastis-triton", "online", "-p", f"{port}"]
tt = ["pastis-tritondse", "online", "-p", f"{port}"]
if len(probe) > 0:
tt += ["--probe", f"{probe}"]
subprocess.Popen(tt, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#!/usr/bin/env python3

# PYTHONPATH=. ./bin/fuzz_cyclone.py offline -s out.frames micro_http_server_tt_fuzz_single_with_vuln wlp0s20f3 48:e2:44:f5:9b:01 10.0.13.86 255.255.255.0 10.0.13.254


Expand All @@ -18,7 +16,7 @@
from libpastis.types import ExecMode, CoverageMode, SeedInjectLoc, CheckMode, FuzzingEngineInfo, SeedType, FuzzMode

# Local imports
from pastisdse import PastisDSE, __version__
from pastistritondse import TritonDSEDriver, __version__
from tritondse import CoverageStrategy, ProbeInterface, Config, SmtSolver
from tritondse.probes.basic_trace import BasicDebugTrace
import tritondse.logging
Expand Down Expand Up @@ -62,8 +60,8 @@ def cli():
@click.option('--probe', type=str, help="Probe to load as a python module (should contain a ProbeInterface)", multiple=True)
def online(host: str, port: int, debug: bool, probe: Tuple[str]):
"""
This is the online mode of the pastis-triton exploration. With this mode,
the client (pastis-triton) will try to connect to the broker. Then, the broker
This is the online mode of the pastis-tritondse exploration. With this mode,
the client (pastis-tritondse) will try to connect to the broker. Then, the broker
will send us the binary to explore, the configuration and initiale seeds.
:param host: The remote host to connect
Expand All @@ -78,7 +76,7 @@ def online(host: str, port: int, debug: bool, probe: Tuple[str]):
agent = ClientAgent()

# Instanciate the pastis that will register the appropriate callbacks
pastis = PastisDSE(agent)
pastis = TritonDSEDriver(agent)

for p in list(probe):
probe = load_probe_module(p)
Expand Down Expand Up @@ -129,8 +127,8 @@ def offline(program: str,
debug_pp: bool,
trace: bool):
"""
This is the offline mode of the pastis-triton exploration. With this mode,
the client (pastis-triton) will be able to work without a remote broker. In
This is the offline mode of the pastis-tritondse exploration. With this mode,
the client (pastis-tritondse) will be able to work without a remote broker. In
this mode, we have to provide all information about the configuration via
the command line option.
Expand Down Expand Up @@ -168,7 +166,7 @@ def offline(program: str,
agent = FileAgent()

# Instanciate the pastis that will register the appropriate callbacks
pastis = PastisDSE(agent)
pastis = TritonDSEDriver(agent)

if config:
config = Config.from_file(config)
Expand Down Expand Up @@ -235,8 +233,9 @@ def offline(program: str,
pastis.run(online=False, debug_pp=debug_pp)


if __name__ == "__main__":
def main():
cli()



if __name__ == "__main__":
main()
File renamed without changes.
Loading

0 comments on commit 44f0507

Please sign in to comment.