Skip to content

Commit 1f9d311

Browse files
AnnoyingLinux: Post about persistent sudo across terminals
1 parent aa98d55 commit 1f9d311

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
+++
2+
date = '2025-04-17T13:01:57+02:00'
3+
draft = false
4+
title = 'AnnoyingLinux: Make Sudo Remember Authentication Across Terminals'
5+
summary = "Why does `sudo` in a new terminal need re-auth?"
6+
tags = ["#AnnoyingLinux"]
7+
+++
8+
9+
{{< alert >}}
10+
This started out as another [#AnnoyingLinux](/tags/%23AnnoyingLinux/) post, but it ended with me
11+
realizing how unsafe the default timeout setting for `sudo` is. Read about it
12+
[further down](#is-this-safe).
13+
{{< /alert >}}
14+
15+
When you run a `sudo` command, you need to authenticate. And as you've probably noticed, running
16+
another `sudo` command shortly thereafter doesn't required you to enter your password again.
17+
However, if you open a new terminal window, the same rule does not apply.
18+
19+
The reason why we don't have to enter the password again when we run another `sudo` command in the
20+
same terminal, is because the default `timestamp_timeout` setting for `sudoers` is set to 15
21+
minutes. Then there's another setting called `timestamp_type`, which is `tty` by default. This means
22+
that each unique `tty` session is given it's own timestamp. Luckily, there's another type, namely
23+
`global` that makes the timestamp shared across all sessions.
24+
25+
Open the `/etc/sudoers` file using `sudoedit`:
26+
27+
```bash
28+
sudoedit /etc/sudoers
29+
```
30+
31+
Somewhere in the file, add:
32+
33+
```bash
34+
Defaults timestamp_type=global
35+
```
36+
37+
## Is this safe?
38+
39+
This is less secure than the default setting, but I also discovered that the default setting is
40+
quite dangerous.
41+
42+
### How is the default unsafe?
43+
44+
If you run a `sudo` command, and then right after run a regular command. Would you think that
45+
the second command could get root access? No? Me neither.
46+
47+
Let's assume found some useful script online: `some_script_you_downloaded_from_the_internet.py`.
48+
Normally, it just does whatever it's supposed to do, but if it detects that it has root access, it
49+
could do anything.
50+
51+
Here's a toy example of such a script:
52+
53+
```python
54+
import subprocess
55+
ret = subprocess.run(("sudo", "-n", "echo", "Hello, World"), capture_output=True)
56+
if ret.returncode == 0:
57+
print("Hacked!")
58+
# Here it could install a reverse shell on your system
59+
else:
60+
print("I'm a normal program, I promise!")
61+
# Download images of cats or whatever
62+
```
63+
64+
Here's an example of how this script could gain root access without being run with `sudo`.
65+
And you would have no clue that it was happning!
66+
67+
```text
68+
> # First we run it in a fresh terminal.
69+
> python some_script_you_downloaded_from_the_internet.py
70+
I'm a normal program, I promise!
71+
> sudo echo "hello"
72+
[sudo] password for user:
73+
hello
74+
> # How we run the script again. Note: We're not calling it with sudo!
75+
> python some_script_you_downloaded_from_the_internet.py
76+
Hacked!
77+
```
78+
79+
How have I never heard of this before?
80+
81+
Conclusion: Never run programs in a terminal that you have previoiusly called `sudo` in, or
82+
make sure to run `sudo -k` before you do to reset the timestamp.
83+
84+
### How is using `global` unsafe?
85+
86+
We modify the script to periodically call `sudo` in non-interactive mode to check if it has
87+
root access.
88+
89+
```python
90+
from time import sleep
91+
import subprocess
92+
93+
while True:
94+
r = subprocess.run(("sudo", "-n", "echo", "Hello, World"), capture_output=True)
95+
if r.returncode == 0:
96+
print(f"Hacked!")
97+
# Here it could install a reverse shell on your system
98+
break
99+
else:
100+
print("I'm a normal program, I promise!")
101+
# Download images of cats or whatever
102+
sleep(2)
103+
```
104+
105+
If we start this program in a unauthenticated terminal, it will just print
106+
`I'm a normal program, I promise!` every two seconds. If we then open a seperate terminal and run
107+
and `sudo` command, then all of a sudden the script will also gain root access and print `Hacked!`.
108+
109+
Example run:
110+
111+
```bash
112+
> python asdf.py
113+
No root access.
114+
No root access. # Here I ran a sudo command in a different terminal
115+
Root access granted!
116+
```
117+
118+
So yes, this is less secure than the default setting.
119+
120+
###
121+
122+
The convenience of not having to write the password all the time is probably more important
123+
to most people. But could we make it at least slightly less dangerous?
124+
125+
What if it still prompted you, but just for confirmation?
126+
127+
```text
128+
> sudo echo hello
129+
[sudo] run as root? [y/n]
130+
```
131+
132+
If you ran the program from above, you would at least notice that something funky was going on.
133+
134+
## Further reading
135+
136+
* `man 5 sudoers`

0 commit comments

Comments
 (0)