The code and data behind xeiaso.net
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

🥺

Signed-off-by: Xe Iaso <me@christine.website>

Xe Iaso a4ba1e20 819567e8

+268
+268
blog/🥺.markdown
··· 1 + --- 2 + title: "🥺: the best sudo replacement" 3 + date: 2023-01-20 4 + tags: 5 + - infosec 6 + - sudo 7 + - rust 8 + --- 9 + 10 + <xeblog-hero ai="Waifu Diffusion" file="aoi-flee" prompt="1girl, fox ears, blue hair, blue eyes, katana, bamboo forest, kimono, long hair, princess, pokemon, fluffy hair, shouting, coffee, chibi, portrait, dialogue, monado, running, fox tail, blue tail"></xeblog-hero> 11 + 12 + <xeblog-conv name="Mara" mood="hmm">I wonder how many people's RSS/JSONFeed 13 + readers we broke with the title...</xeblog-conv> 14 + 15 + <xeblog-conv name="Aoi" mood="cheer">Come on, it couldn't have been _that_ many, 16 + things support Unicode now, right?</xeblog-conv> 17 + 18 + <xeblog-conv name="Numa" mood="delet"><span style="color:green">&gt;implying 19 + things support Unicode properly in the year of our lord two thousand and 20 + twenty-three</span></xeblog-conv> 21 + 22 + <xeblog-conv name="Aoi" mood="facepalm">They do support Unicode though...right? 23 + They have to.</xeblog-conv> 24 + 25 + <xeblog-conv name="Cadey" mood="coffee">We'll find out.</xeblog-conv> 26 + 27 + Security is impossible. We just like to pretend otherwise so that we can 28 + constantly project this aura of impenetrability that will save us from having to 29 + admit the reality that it's impossible. One of the biggest targets in the modern 30 + information security world is [sudo](https://www.sudo.ws/). It is a command that 31 + lets you *s*et *u*ser and then *do* a command. Sudo is one of the most widely 32 + deployed programs on the Internet and is widely regarded as critical 33 + infrastructure. 34 + 35 + <xeblog-conv name="Aoi" mood="grin">Sooo the creators and maintainers of sudo 36 + take things very seriously by using something like 37 + [Rust](https://www.rust-lang.org/), maintain a high quality standard of 38 + malicious inputs by fuzzing all public attack surfaces, and try to minimize the 39 + amount of code involved in order to prevent vulnerabilities from being a 40 + problem?</xeblog-conv> 41 + 42 + <xeblog-conv name="Cadey" mood="coffee">God I wish they did. They wrote the 43 + program in C, (as far as I can tell) have no intention of rewriting it in Rust, and it's had 44 + [many](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-22809) 45 + [viable](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3156) 46 + [attacks](https://www.sudo.ws/security/advisories/sudoedit_selinux) over the 47 + years that allowed attackers to gain root privileges and worse. It's also 48 + debatable if the entire concept of privilege separation as implemented in Linux 49 + and UNIX was a bad idea to begin with but we're stuck with it because of an 50 + endless ball of legacy programs controlled by egotistical open source people 51 + that refuse to change because then [obscure targets that nobody uses won't be 52 + able to leech off of the rest of the ecosystem by holding back any chance to let 53 + us have a modicum of nice things](https://lwn.net/Articles/845535/).</xeblog-conv> 54 + 55 + <xeblog-conv name="Aoi" mood="sus">Oh god...</xeblog-conv> 56 + 57 + I'm tired of this situation and I bet a lot of the ecosystem is too. There's 58 + been talk and ideas, but not enough in the action department. I made a new tool. 59 + A better tool. One that will let all of us proceed towards the future we 60 + deserve. I made a sudo replacement named 🥺. 61 + 62 + ## <span style="font-size:xx-large">🥺</span> 63 + 64 + 🥺 has no pronounceable name in English or any other speakable human language. 65 + It is named 🥺, but it is referred to as `xn--ts9h` (the punycode form of 🥺) in 66 + situations where emoji are not yet supported (such as Debian package names). 67 + 68 + To use 🥺, install it (such as from the Debian package) and then run it in place 69 + of sudo: 70 + 71 + ``` 72 + $ id 73 + uid=1000(xe) gid=1000(xe) groups=1000(xe),102(docker) 74 + 75 + $ 🥺 id 76 + uid=0(root) gid=0(root) groups=0(root),102(docker),1000(xe) 77 + ``` 78 + 79 + <xeblog-conv name="Mara" mood="hmm">Wait, what? That's it? How is this even 80 + secure at all? If it doesn't ask you for your password how can you be sure that 81 + an actual human is making the request and not some malicious 82 + script?</xeblog-conv> 83 + 84 + <xeblog-conv name="Numa" mood="delet">Using this program requires you to be able 85 + to type an emoji. Most attack code is of such poor quality that they are unable 86 + to run commands named with emoji. This makes the program secure.</xeblog-conv> 87 + 88 + <xeblog-conv name="Aoi" mood="coffee">This is not how any of this 89 + works.</xeblog-conv> 90 + 91 + Here it is broken down statement by statement. 92 + 93 + First, I pull in a bunch of imports from the standard library and also the 94 + [syslog](https://docs.rs/syslog/latest/syslog/) to write a message to syslog 95 + about what's going on: 96 + 97 + ```rust 98 + use std::{env, os::unix::process::CommandExt, process::Command}; 99 + use syslog::{unix, Facility::LOG_AUTH, Formatter3164}; 100 + ``` 101 + 102 + Next, I create a main function that returns an 103 + [`io::Result`](https://doc.rust-lang.org/std/io/type.Result.html), this is an 104 + error that is returned by most of the standard library functions that do I/O 105 + operations with the OS. 106 + 107 + ```rust 108 + fn main() -> io::Result<()> { 109 + ``` 110 + 111 + The correct usage of this program is to run it like `🥺 id`, so if the user 112 + doesn't specify a program to run, then it should blow up with an error message 113 + instead of panicking: 114 + 115 + ```rust 116 + if env::args().len() == 1 { 117 + eprintln!("usage: {} <command> [args]", env::args().nth(0).unwrap()); 118 + return Ok(()); 119 + } 120 + ``` 121 + 122 + <xeblog-conv name="Aoi" mood="wut">Wait, what? Why is it returning that 123 + everything is okay if the user is doing it wrong? Shouldn't it return some kind 124 + of error code that the running program or shell can catch?</xeblog-conv> 125 + 126 + <xeblog-conv name="Numa" mood="delet">It's a feature.</xeblog-conv> 127 + 128 + <xeblog-conv name="Aoi" mood="coffee">I really hope I never have to maintain any 129 + of your code.</xeblog-conv> 130 + 131 + Next, we grab the program name and arguments from the command line arguments of 132 + 🥺 and send a message to syslog that it's being run so that there is _some_ 133 + accountability after-the-fact: 134 + 135 + ```rust 136 + let program = env::args().nth(1).unwrap(); 137 + let args = env::args().skip(2).collect::<Vec<String>>(); 138 + let mut writer = unix(Formatter3164 { 139 + facility: LOG_AUTH, 140 + hostname: None, 141 + process: "🥺".into(), 142 + pid: 0, 143 + }) 144 + .unwrap(); 145 + writer 146 + .err(format!("running {:?} {:?}", program, args)) 147 + .unwrap(); 148 + ``` 149 + 150 + <xeblog-conv name="Aoi" mood="wut">Wait so the emoji works there, but it 151 + probably isn't going to work in people's RSS feed readers? How does that make 152 + any sense?</xeblog-conv> 153 + 154 + <xeblog-conv name="Numa" mood="delet">It doesn't, lololol</xeblog-conv> 155 + 156 + <xeblog-conv name="Cadey" mood="coffee">UNIX is mostly devoid of the concept of 157 + character sets. Any character is fine as long as it doesn't have a null 158 + terminator (this ends the string in C). I'd be more amazed if the emoji use 159 + broke something, as there are legitimate uses for putting non-Latin characters 160 + into message buses like that. Also most RSS feed readers have very poor code 161 + quality.</xeblog-conv> 162 + 163 + Finally, the actual command is executed: 164 + 165 + ```rust 166 + Err(Command::new(program).args(args).uid(0).gid(0).exec().into()) 167 + ``` 168 + 169 + This works because I'm using the 170 + [`CommandExt`](https://doc.rust-lang.org/std/os/unix/process/trait.CommandExt.html) 171 + trait implementation of 172 + [`Command`](https://doc.rust-lang.org/std/process/struct.Command.html) that adds 173 + some methods we need: 174 + 175 + - [`uid(&mut self, id: 176 + u32)`](https://doc.rust-lang.org/std/process/struct.Command.html#method.uid) 177 + to set the user ID of the child process 178 + ([`setuid(2)`](https://man7.org/linux/man-pages/man2/setuid.2.html) in C) 179 + - [`gid(&mut self, id: 180 + u32)`](https://doc.rust-lang.org/std/process/struct.Command.html#method.gid) 181 + to set the group ID of the child process 182 + ([`setgid(2)`](https://man7.org/linux/man-pages/man2/setgid.2.html), though 183 + groups are starting to die out due to them not being across multiple machines 184 + without extra effort like configuration managment) 185 + - [`exec(&mut 186 + self)`](https://doc.rust-lang.org/std/os/unix/process/trait.CommandExt.html#tymethod.exec) 187 + which runs the 188 + [`execvp(3)`](https://man7.org/linux/man-pages/man3/exec.3.html) system call 189 + that _replaces_ the current 🥺 with the child process 190 + 191 + The key part is the `exec` call at the end. One of the interesting things about 192 + the `exec`-family of system calls in UNIX is that it _replaces_ the current 193 + process if it succeeds. This means that the function will never return unless 194 + some error happened, so the `exec` method _always_ returns an error. This will 195 + make error handling happen properly and if things fail the process will exit 196 + with a non-zero error code: 197 + 198 + ``` 199 + $ cargo run --release ls 200 + Finished release [optimized] target(s) in 0.06s 201 + Running `target/release/🥺 ls` 202 + Error: Os { code: 1, kind: PermissionDenied, message: "Operation not permitted" } 203 + ``` 204 + 205 + <xeblog-conv name="Numa" mood="delet">Sure, this error message could be better, 206 + but that's a 2.0 feature. This is a disruptive program poised to totally reshape 207 + the security industry so we have to _move fast and break things_!</xeblog-conv> 208 + 209 + I'm fairly sure that this program has no bugs that aren't either a part of the 210 + syslog crate or the Rust standard library. 211 + 212 + ## Installation 213 + 214 + You can install 🥺 by downloading the `.deb` file from [my 215 + fileserver](https://pneuma.shark-harmonic.ts.net/.within/xn--ts9h/) and 216 + installing it with `dpkg -i`. This will give you the `🥺` command that you can 217 + use in place of `sudo`. 218 + 219 + <xeblog-conv name="Numa" mood="delet">This will let you stick it to the man and 220 + let you self-host your own sudo on a $5 a month VPS from a budget host. You 221 + can't have any vulnerabilities if there are no bugs to begin with!</xeblog-conv> 222 + 223 + <xeblog-sticker name="Aoi" mood="facepalm"></xeblog-sticker> 224 + 225 + This is also known to work on Amazon Linux 2, so you can create blursed things 226 + like this: 227 + 228 + ``` 229 + $ ssh -A xe@10.77.131.103 230 + Warning: Permanently added '10.77.131.103' (ED25519) to the list of known hosts. 231 + Last login: Fri Jan 20 04:09:11 2023 from 10.77.131.1 232 + 233 + __| __|_ ) 234 + _| ( / Amazon Linux 2 AMI 235 + ___|\___|___| 236 + 237 + https://aws.amazon.com/amazon-linux-2/ 238 + [xe@inez-rengenne ~]$ 🥺 id 239 + uid=0(root) gid=0(root) groups=0(root),10(wheel),1000(xe) 240 + ``` 241 + 242 + <xeblog-conv name="Mara" mood="hacker">Pro tip! You can apparently pass a URL to 243 + a `.rpm` file to `yum install` and it will just download and install that `.rpm` 244 + file. This is incredibly cursed.</xeblog-conv> 245 + 246 + The `.deb` package was built on Ubuntu 18.04 and the `.rpm` package was built on 247 + Amazon Linux 2, so it should be compatible with enough distributions that you 248 + don't have to care. 249 + 250 + <xeblog-conv name="Mara" mood="hacker">There's even a manpage you can read with 251 + `man 8 🥺`!</xeblog-conv> 252 + 253 + <xeblog-conv name="Numa" mood="delet">And most importantly, [patches 254 + welcome](https://github.com/Xe/xn--ts9h)!</xeblog-conv> 255 + 256 + --- 257 + 258 + <xeblog-conv name="Numa" mood="delet">By the way, there are many more lovely 259 + ways to get root than just by asking nicely with `setuid`. Why doesn't this 260 + program use those?</xeblog-conv> 261 + 262 + <xeblog-conv name="Cadey" mood="coffee">We gotta save _something_ for part 2, 263 + otherwise that would spoil all the _fun_.</xeblog-conv> 264 + 265 + <xeblog-conv name="Aoi" mood="sus">I don't know if I like what you mean by "fun" 266 + there...</xeblog-conv> 267 + 268 +