Skip to content

Commit

Permalink
examples: add new phone2overflow real-life example
Browse files Browse the repository at this point in the history
This requires some additions to enter_namespace to make it usable also
for other examples.
  • Loading branch information
mgerstner committed Jul 16, 2024
1 parent c32b566 commit 85923a8
Show file tree
Hide file tree
Showing 6 changed files with 366 additions and 9 deletions.
10 changes: 10 additions & 0 deletions bo_training.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,16 @@ found in Gnome's 'libsoup', an http protocol parsing library, some years ago.
* *Hands-on*: In the example folder `doc2exploit` further instructions and
helpers can be found.
[role="incremental"]
=== sngrep (2024)
* `sngrep` is a textual SIP VoIP call monitoring tool.
* It is an example of badly implemented parsing of untrusted network data.
* It is at the same time a good example of unexpected obstacles to exploiting
stack buffer overflows.
* *Hands-on*: In the example folder `phone2overflow` further instructions and
helpers can be found.
[[stack-overread]]
Stack Buffer Overread
---------------------
Expand Down
38 changes: 29 additions & 9 deletions examples/connman_dns/enter_namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,23 @@ def eprint(*args, **kwargs):
print(*args, **kwargs)


parser = argparse.ArgumentParser(description="Manages execution of a split-off network namespace for safely running connmand and exploiting it.")
parser.add_argument("--reexec", action='store_true')
example_root = Path(__file__).parent
need_preload_lib = (example_root / "geteuid-preload").exists()

CONFIG = {
"connman_dns": ("connmand", "sbin/connmand"),
"phone2overflow": ("sngrep", "usr/local/bin/sngrep")
}

config = CONFIG.get(example_root.name)
if not config:
eprint("unsupport exploit example", example_root.name, "encountered!")
sys.exit(1)
exploit_target = config[0]
exploit_subpath = config[1]

parser = argparse.ArgumentParser(description=f"Manages execution of a split-off network namespace for safely running {exploit_target} and exploiting it.")
parser.add_argument("--reexec", action='store_true', help='internal switch used to transparently join an existing namespace')
parser.add_argument("--join", action='store_true')

args = parser.parse_args()
Expand All @@ -26,25 +41,25 @@ def eprint(*args, **kwargs):
# Running D-Bus in a separate user namespace doesn't work out, because the
# user ID doesn't match the user ID in the root namespace. Lie to D-Bus about
# our real and effective user IDs using an ld-preload library.
preload = script_dir / "geteuid-preload/libgeteuid_preload.so"
preload_lib = script_dir / "geteuid-preload/libgeteuid_preload.so"
instdir_conf = script_dir / "instdir.conf"

if not instdir_conf.exists():
eprint(f"Expected location of connmand $INSTDIR in {str(instdir_conf)}")
eprint(f"Expected location of {exploit_target} $INSTDIR in {str(instdir_conf)}")
sys.exit(1)

instdir = Path(open(instdir_conf).read().strip())
connmand = instdir / "sbin/connmand"
exploit_bin = instdir / exploit_subpath

if not instdir.is_dir() or not connmand.exists():
eprint(f"{instdir} or {connmand} do not exist")
if not instdir.is_dir() or not exploit_bin.exists():
eprint(f"{instdir} or {exploit_bin} do not exist")
sys.exit(1)

# export it into the environment to make example command lines from the
# README.md work as expected
os.environ["INSTDIR"] = str(instdir)

if not preload.exists():
if need_preload_lib and not preload_lib.exists():
print("Building LD_PRELOAD helper lib\n")
subprocess.check_call(["make"], cwd=script_dir)
print()
Expand All @@ -54,10 +69,15 @@ def eprint(*args, **kwargs):
if args.reexec:
child_env = os.environ.copy()
child_env["IN_NS_NAMESPACE"] = "1"
child_env["LD_PRELOAD"] = str(preload)
if need_preload_lib:
child_env["LD_PRELOAD"] = str(preload_lib)
shell = os.environ["SHELL"]
child_env["PS1"] = r"(network-ns) \u@\h:\w> "
if not args.join:
try:
os.makedirs(ns_pidfile.parent)
except FileExistsError:
pass
with open(ns_pidfile, 'w') as ns_fd:
ns_fd.write(str(os.getpid()))
# we need to mount our forked-off sysfs to reflect our network
Expand Down
1 change: 1 addition & 0 deletions examples/phone2overflow/Makefile
Loading

0 comments on commit 85923a8

Please sign in to comment.