annotate test/test_dropbear.py @ 1930:299f4f19ba19

Add /usr/sbin and /sbin to default root PATH When dropbear is used in a very restricted environment (such as in a initrd), the default user shell is often also very restricted and doesn't take care of setting the PATH so the user ends up with the PATH set by dropbear. Unfortunately, dropbear always sets "/usr/bin:/bin" as default PATH even for the root user which should have /usr/sbin and /sbin too. For a concrete instance of this problem, see the "Remote Unlocking" section in this tutorial: https://paxswill.com/blog/2013/11/04/encrypted-raspberry-pi/ It speaks of a bug in the initramfs script because it's written "blkid" instead of "/sbin/blkid"... this is just because the scripts from the initramfs do not expect to have a PATH without the sbin directories and because dropbear is not setting the PATH appropriately for the root user. I'm thus suggesting to use the attached patch to fix this misbehaviour (I did not test it, but it's easy enough). It might seem anecdotic but multiple Kali users have been bitten by this. From https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=903403
author Raphael Hertzog <hertzog@debian.org>
date Mon, 09 Jul 2018 16:27:53 +0200
parents 81991ded740f
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1836
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
1 import subprocess
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
2 import os
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
3 import pty
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
4 import tempfile
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
5 import logging
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
6 import time
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
7 import socketserver
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
8 import threading
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
9 import queue
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
10
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
11 import pytest
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
12
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
13 LOCALADDR="127.0.5.5"
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
14
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
15 @pytest.fixture(scope="module")
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
16 def dropbear(request):
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
17 opt = request.config.option
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
18 if opt.remote:
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
19 yield None
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
20 return
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
21
1870
0dcc5b0d93fa Make re-exec work with "dropbearmulti dropbear"
Matt Johnston <matt@ucc.asn.au>
parents: 1864
diff changeset
22 # split so that "dropbearmulti dropbear" works
0dcc5b0d93fa Make re-exec work with "dropbearmulti dropbear"
Matt Johnston <matt@ucc.asn.au>
parents: 1864
diff changeset
23 args = opt.dropbear.split() + [
1836
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
24 "-p", LOCALADDR, # bind locally only
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
25 "-r", opt.hostkey,
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
26 "-p", opt.port,
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
27 "-F", "-E",
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
28 ]
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
29 p = subprocess.Popen(args, stderr=subprocess.PIPE, text=True)
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
30 # Wait until it has started listening
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
31 for l in p.stderr:
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
32 if "Not backgrounding" in l:
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
33 break
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
34 # Check it's still running
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
35 assert p.poll() is None
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
36 # Ready
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
37 yield p
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
38 p.terminate()
1852
e0c1825c567d Debug pytest password auth failing
Matt Johnston <matt@ucc.asn.au>
parents: 1841
diff changeset
39 print("Terminated dropbear. Flushing output:")
e0c1825c567d Debug pytest password auth failing
Matt Johnston <matt@ucc.asn.au>
parents: 1841
diff changeset
40 for l in p.stderr:
e0c1825c567d Debug pytest password auth failing
Matt Johnston <matt@ucc.asn.au>
parents: 1841
diff changeset
41 print(l.rstrip())
e0c1825c567d Debug pytest password auth failing
Matt Johnston <matt@ucc.asn.au>
parents: 1841
diff changeset
42 print("Done")
1836
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
43
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
44 def dbclient(request, *args, **kwargs):
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
45 opt = request.config.option
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
46 host = opt.remote or LOCALADDR
1870
0dcc5b0d93fa Make re-exec work with "dropbearmulti dropbear"
Matt Johnston <matt@ucc.asn.au>
parents: 1864
diff changeset
47 # split so that "dropbearmulti dbclient" works
0dcc5b0d93fa Make re-exec work with "dropbearmulti dropbear"
Matt Johnston <matt@ucc.asn.au>
parents: 1864
diff changeset
48 base_args = opt.dbclient.split() + ["-y", host, "-p", opt.port]
1836
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
49 if opt.user:
1870
0dcc5b0d93fa Make re-exec work with "dropbearmulti dropbear"
Matt Johnston <matt@ucc.asn.au>
parents: 1864
diff changeset
50 base_args.extend(['-l', opt.user])
1836
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
51 full_args = base_args + list(args)
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
52 bg = kwargs.get("background")
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
53 if "background" in kwargs:
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
54 del kwargs["background"]
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
55 if bg:
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
56 return subprocess.Popen(full_args, **kwargs)
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
57 else:
1841
d757f48ae29f Add a default 10 second timeout for tests
Matt Johnston <matt@ucc.asn.au>
parents: 1836
diff changeset
58 kwargs.setdefault("timeout", 10)
1836
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
59 # wait for response
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
60 return subprocess.run(full_args, **kwargs)
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
61
1863
b550845e500b Use venv for test_aslr
Matt Johnston <matt@ucc.asn.au>
parents: 1852
diff changeset
62 def own_venv_command():
b550845e500b Use venv for test_aslr
Matt Johnston <matt@ucc.asn.au>
parents: 1852
diff changeset
63 """ Returns a command to run as a prefix to get the same venv
b550845e500b Use venv for test_aslr
Matt Johnston <matt@ucc.asn.au>
parents: 1852
diff changeset
64 as the current running Python. Returns '' on not a virtualenv
b550845e500b Use venv for test_aslr
Matt Johnston <matt@ucc.asn.au>
parents: 1852
diff changeset
65 """
b550845e500b Use venv for test_aslr
Matt Johnston <matt@ucc.asn.au>
parents: 1852
diff changeset
66 try:
b550845e500b Use venv for test_aslr
Matt Johnston <matt@ucc.asn.au>
parents: 1852
diff changeset
67 venv = os.environ['VIRTUAL_ENV']
b550845e500b Use venv for test_aslr
Matt Johnston <matt@ucc.asn.au>
parents: 1852
diff changeset
68 except KeyError:
b550845e500b Use venv for test_aslr
Matt Johnston <matt@ucc.asn.au>
parents: 1852
diff changeset
69 return ""
b550845e500b Use venv for test_aslr
Matt Johnston <matt@ucc.asn.au>
parents: 1852
diff changeset
70
b550845e500b Use venv for test_aslr
Matt Johnston <matt@ucc.asn.au>
parents: 1852
diff changeset
71 # note: bash/zsh unix specific
b550845e500b Use venv for test_aslr
Matt Johnston <matt@ucc.asn.au>
parents: 1852
diff changeset
72 return f"source {venv}/bin/activate"
b550845e500b Use venv for test_aslr
Matt Johnston <matt@ucc.asn.au>
parents: 1852
diff changeset
73
1836
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
74 class HandleTcp(socketserver.ThreadingMixIn, socketserver.TCPServer):
1879
81991ded740f test: Set allow_reuse_addr
Matt Johnston <matt@ucc.asn.au>
parents: 1870
diff changeset
75
81991ded740f test: Set allow_reuse_addr
Matt Johnston <matt@ucc.asn.au>
parents: 1870
diff changeset
76 # override TCPServer's default, avoids TIME_WAIT
81991ded740f test: Set allow_reuse_addr
Matt Johnston <matt@ucc.asn.au>
parents: 1870
diff changeset
77 allow_reuse_addr = True
81991ded740f test: Set allow_reuse_addr
Matt Johnston <matt@ucc.asn.au>
parents: 1870
diff changeset
78
1836
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
79 """ Listens for a single incoming request, sends a response if given,
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
80 and returns the inbound data.
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
81 Reponse can be a queue object, in which case each item in the queue will
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
82 be sent as a response, until it receives a None item.
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
83 """
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
84 def __init__(self, port, timeout, response=None):
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
85 super().__init__(('localhost', port), self.Handler)
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
86 self.port = port
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
87 self.timeout = timeout
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
88 self.response = response
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
89 self.sink = None
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
90
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
91 class Handler(socketserver.StreamRequestHandler):
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
92 def handle(self):
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
93 if isinstance(self.server.response, queue.Queue):
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
94 while True:
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
95 i = self.server.response.get()
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
96 if i is None:
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
97 break
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
98 self.wfile.write(i)
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
99 elif self.server.response:
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
100 self.wfile.write(self.server.response)
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
101 assert self.server.sink is None, ">1 request sent to handler"
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
102 self.server.sink = self.rfile.read()
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
103
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
104 def __enter__(self):
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
105 self.server_thread = threading.Thread(target=self.serve_forever)
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
106 self.server_thread.daemon = True
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
107 self.server_thread.start()
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
108 return self
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
109
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
110 def __exit__(self, *exc_stuff):
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
111 self.shutdown()
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
112 self.server_thread.join()
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
113
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
114 def inbound(self):
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
115 """ Returns the data sent to the socket """
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
116 return self.sink
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
117
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
118 def readall_socket(sock):
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
119 b = []
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
120 while True:
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
121 i = sock.recv(4096)
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
122 if not i:
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
123 break
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
124 b.append(i)
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
125 return b''.join(b)
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
126
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
127 # returns a str
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
128 def random_alnum(size):
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
129 r = os.urandom(500 + size*5)
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
130 return bytes(i for i in r if bytes((i,)).isalnum())[:size].decode()
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
131
06c7ddbb9dd6 Add first channel tests
Matt Johnston <matt@codeconstruct.com.au>
parents:
diff changeset
132