diff --git a/docs/commands/index.md b/docs/commands/index.md index 8f7e68a03..9f3748923 100644 --- a/docs/commands/index.md +++ b/docs/commands/index.md @@ -115,6 +115,7 @@ - [libcinfo](linux_libc_elf/libcinfo.md) - Show libc version and link to its sources - [linkmap](linux_libc_elf/linkmap.md) - Show the state of the Link Map - [onegadget](linux_libc_elf/onegadget.md) - Find gadgets which single-handedly give code execution. +- [parse-seccomp](linux_libc_elf/parse-seccomp.md) - Parse a struct sock_fprog from memory and dump its filter - [piebase](linux_libc_elf/piebase.md) - Calculate VA of RVA from PIE base. - [plt](linux_libc_elf/plt.md) - Prints any symbols found in Procedure Linkage Table sections if any exist. - [strings](linux_libc_elf/strings.md) - Extracts and displays ASCII strings from readable memory pages of the debugged process. diff --git a/docs/commands/linux_libc_elf/parse-seccomp.md b/docs/commands/linux_libc_elf/parse-seccomp.md new file mode 100644 index 000000000..b6d57fcba --- /dev/null +++ b/docs/commands/linux_libc_elf/parse-seccomp.md @@ -0,0 +1,23 @@ + +# parse-seccomp + +```text +usage: parse-seccomp [-h] addr + +``` + +Parse a struct sock_fprog from memory and dump its filter +### Positional arguments + +|Positional Argument|Help| +| :--- | :--- | +|addr|Address of sock_fprog structure in target process memory (e.g. 0xdeadbeef)| + +### Optional arguments + +|Short|Long|Help| +| :--- | :--- | :--- | +|-h|--help|show this help message and exit| + + + diff --git a/pwndbg/commands/__init__.py b/pwndbg/commands/__init__.py index 2f764f044..436deabe5 100644 --- a/pwndbg/commands/__init__.py +++ b/pwndbg/commands/__init__.py @@ -944,6 +944,7 @@ def load_commands() -> None: import pwndbg.commands.onegadget import pwndbg.commands.p2p import pwndbg.commands.paging + import pwndbg.commands.parse_seccomp import pwndbg.commands.patch import pwndbg.commands.pie import pwndbg.commands.plist diff --git a/pwndbg/commands/parse_seccomp.py b/pwndbg/commands/parse_seccomp.py new file mode 100644 index 000000000..586a35042 --- /dev/null +++ b/pwndbg/commands/parse_seccomp.py @@ -0,0 +1,50 @@ +from __future__ import annotations + +import argparse +import shutil +import subprocess + +import pwndbg.aglib.memory +import pwndbg.aglib.typeinfo +import pwndbg.commands +from pwndbg.color import message +from pwndbg.commands import CommandCategory + +parser = argparse.ArgumentParser( + description="Parse a struct sock_fprog from memory and dump its filter" +) +parser.add_argument( + "addr", + type=int, + help="Address of sock_fprog structure in target process memory (e.g. 0xdeadbeef)", +) + + +@pwndbg.commands.Command(parser, command_name="parse-seccomp", category=CommandCategory.LINUX) +@pwndbg.commands.OnlyWhenRunning +def parse_seccomp(addr: int) -> None: + """Parse a struct sock_fprog at a given address and pass filter to external tool.""" + + # addr = int(addr) & pwndbg.aglib.arch.ptrmask + filter_len = pwndbg.aglib.memory.u16(addr) + filter_addr = pwndbg.aglib.memory.u(addr + pwndbg.aglib.typeinfo.ptrsize) + + print(message.success(f"sock_fprog @ {addr:#x}")) + print(f" len = {filter_len}") + print(f" filter_addr = {filter_addr:#x}") + + filter_size = filter_len * 8 + filter_bytes = pwndbg.aglib.memory.read(filter_addr, filter_size, partial=False) + + if shutil.which("ceccomp"): + proc = subprocess.run( + ["ceccomp", "disasm", "--color", "always"], input=filter_bytes, capture_output=True + ) + print(proc.stdout.decode()) + elif shutil.which("seccomp-tools"): + proc = subprocess.run( + ["seccomp-tools", "disasm", "-"], input=filter_bytes, capture_output=True + ) + print(proc.stdout.decode()) + else: + print("install ceccomp or seccomp-tools to parse seccomp")