allow use of other tap interfaces
This commit is contained in:
+30
-16
@@ -2,11 +2,12 @@
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
import pwd
|
||||||
|
import re
|
||||||
|
import stat
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import stat
|
|
||||||
import pwd
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
|
|
||||||
def change_user(username):
|
def change_user(username):
|
||||||
@@ -35,6 +36,13 @@ def main(argv):
|
|||||||
default="memwatch",
|
default="memwatch",
|
||||||
help="Path to memwatch executable. Defaults to memwatch (assumes it's installed somewhere on $PATH).",
|
help="Path to memwatch executable. Defaults to memwatch (assumes it's installed somewhere on $PATH).",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--tap-interface", "-I",
|
||||||
|
action="store",
|
||||||
|
dest="tap_interface",
|
||||||
|
default="/dev/tap0",
|
||||||
|
help="Tap interface to use. Defaults to /dev/tap0.",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--tap-ip", "-i",
|
"--tap-ip", "-i",
|
||||||
action="store",
|
action="store",
|
||||||
@@ -51,20 +59,27 @@ def main(argv):
|
|||||||
print('$SUDO_USER not set; use `sudo -E`')
|
print('$SUDO_USER not set; use `sudo -E`')
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
# 1. open tap0 and configure it
|
tap_match = re.match(r'^/dev/tap([0-9]+)$', args.tap_interface)
|
||||||
print("starting and configuring tap0")
|
if tap_match is None:
|
||||||
tap0_fd = os.open('/dev/tap0', os.O_RDWR)
|
print('tap interface name must begin with /dev/tap')
|
||||||
os.set_inheritable(tap0_fd, True)
|
return 1
|
||||||
subprocess.check_call(['ifconfig', 'tap0', args.tap_ip], stderr=subprocess.DEVNULL)
|
tap_interface_number = int(tap_match.group(1))
|
||||||
subprocess.check_call(['ifconfig', 'tap0', 'up'], stderr=subprocess.DEVNULL)
|
tap_name = 'tap%d' % (tap_interface_number,)
|
||||||
|
|
||||||
|
# 1. open tap and configure it
|
||||||
|
print("starting and configuring " + tap_name)
|
||||||
|
tap_fd = os.open(args.tap_interface, os.O_RDWR)
|
||||||
|
os.set_inheritable(tap_fd, True)
|
||||||
|
subprocess.check_call(['ifconfig', tap_name, args.tap_ip], stderr=subprocess.DEVNULL)
|
||||||
|
subprocess.check_call(['ifconfig', tap_name, 'up'], stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
# 2. fork a Dolphin process, dropping privileges first
|
# 2. fork a Dolphin process, dropping privileges first
|
||||||
print("starting dolphin")
|
print("starting dolphin")
|
||||||
dolphin_proc = subprocess.Popen([args.dolphin_path],
|
dolphin_proc = subprocess.Popen([args.dolphin_path],
|
||||||
preexec_fn=lambda: change_user(username), pass_fds=(tap0_fd,))
|
preexec_fn=lambda: change_user(username), pass_fds=(tap_fd,))
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
# 3. create a temp file for dolphin to open instead of /dev/tap0
|
# 3. create a temp file for dolphin to open instead of /dev/tapN
|
||||||
print("creating temp file")
|
print("creating temp file")
|
||||||
tmpfile_fd = os.open("/tmp/dnet", os.O_CREAT | os.O_RDWR, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
|
tmpfile_fd = os.open("/tmp/dnet", os.O_CREAT | os.O_RDWR, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
|
||||||
os.close(tmpfile_fd)
|
os.close(tmpfile_fd)
|
||||||
@@ -96,9 +111,9 @@ def main(argv):
|
|||||||
dolphin_tap0_fd = int(fd_str[0:-len(fd_str.lstrip(b'0123456789'))])
|
dolphin_tap0_fd = int(fd_str[0:-len(fd_str.lstrip(b'0123456789'))])
|
||||||
print("found open tap fd %d in dolphin" % (dolphin_tap0_fd,))
|
print("found open tap fd %d in dolphin" % (dolphin_tap0_fd,))
|
||||||
|
|
||||||
# step 6: use memwatch to move the tap0 fd into place
|
# step 6: use memwatch to move the tap fd into place
|
||||||
print("replacing temp fd %d with tap fd %d in dolphin" % (dolphin_tap0_fd,
|
print("replacing temp fd %d with tap fd %d in dolphin" % (dolphin_tap0_fd,
|
||||||
tap0_fd))
|
tap_fd))
|
||||||
assembly_contents = b"""start:
|
assembly_contents = b"""start:
|
||||||
mov rax, 0x000000000200005A # dup2(from_fd, to_fd)
|
mov rax, 0x000000000200005A # dup2(from_fd, to_fd)
|
||||||
mov rdi, %d
|
mov rdi, %d
|
||||||
@@ -111,11 +126,10 @@ def main(argv):
|
|||||||
syscall
|
syscall
|
||||||
|
|
||||||
ret
|
ret
|
||||||
""" % (tap0_fd, dolphin_tap0_fd)
|
""" % (tap_fd, dolphin_tap0_fd)
|
||||||
subprocess.run([args.memwatch_path, str(dolphin_proc.pid), "--", "run", "-"], input=assembly_contents, stderr=subprocess.DEVNULL)
|
subprocess.run([args.memwatch_path, str(dolphin_proc.pid), "--", "run", "-"], input=assembly_contents, stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
# ok we're done - dolphin is running as a non-privileged user with tap0 open
|
# ok we're done; dolphin is running as a non-privileged user with the tap open
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user