Winding down

I knew the conversation wouldn’t be easy when the veterinarian asked if this was a good time to talk.

I still think of her as a puppy, even though she hasn’t been one for many years. People are surprised to find that this tiny little dog is a full-grown adult. Although she’s shaped like a miniature version of the real thing, it’s hard to wrap your brain around something that small being anything other than a baby.

The years don’t care about her appearance, or that she sometimes sleeps on my pillow next to my head, or that I remember how frisky she use to be. Even little bits wear out and start to fail. As her vet translated the numbers from the lab results into things I could understand, I began to realize what they meant: my wife and I will have to make difficult decisions soon.

It’s hard to know what’s best for her, and harder yet to separate that from what’s easiest for us. Those aren’t at all the same things. If I could throw the finite resources available to us at the problem and put it off forever, I would. But that’s not how time works. We can delay things, but only for so long. And the delay has its costs. The analytical part of my brain imagines that she has a fixed amount of happiness left. Do we let her spend it all and then lay down for a last nap, or do we spread it over years (or maybe just months, who can tell) of uncomfortable treatments and procedures? I don’t know. And not deciding is the same as deciding: time won’t give us the luxury of pausing until we can choose what’s right.

My heart knows that this is tougher because of how much we love her. If these sorts of decisions were easy, that would be sad in a different way. Many years ago, we came to care so much about our little puppy that it made the inevitable so painful, but I wouldn’t change that even if I could. And until then, I’m going to make her remaining time as happy as I can.

Surprise eero hardware end-of-life

Amazon is ending software support for 1st generation eero devices at the end of September 2022. That’s fine. You can’t support old hardware forever, and five years is a decent run.

But it’s not OK that I got less than a month’s notice that it was happening, and no email or app notifications. I happened to open the eero app for unrelated reasons and saw a banner telling me my hardware will be obsolete later this month. That’s unacceptably short notice that the hardware is all but dead. Sure, it may keep working for a while, but without security updates or routine bug fixes, it’s not anything I’d want to depend on. If I’d received any other notice whatsoever, I would have been investigating hardware upgrades, reading the various sale emails they’d sent me, and otherwise preparing for the day. Now I have to scramble to fix something that I didn’t know needed fixed, and I don’t appreciate it.

To the folks at eero: this is a managed system. You have my contact information and know what hardware I’m using. This would have been an excellent opportunity for you to let me know about this a few months ago. You could have suggested appropriate hardware upgrades and turned it into a sales opportunity. As your customer, I would have liked that.

eero death notice

Trying (and Failing) to hack the Wall of Sheep

The Wall of Sheep is a popular exhibit at DEF CON. Participants run packet sniffers on an insecure Wi-Fi network and try to catch people logging into unencrypted websites and other services. If they see that happening, they post the person’s username and password on a giant display. It looks something like:

Sample Wall of Sheep

That’s an excellent reminder to be careful when you’re connected to an unknown network, and not to send your login credentials out in the open.

From the first time I saw it, though, I had to wonder: is the wall itself hackable? Could I make it look like this instead?

Snoop onto them, as they snoop onto us.

The idea kept bouncing around the back of my mind until I added it to my to-do list so I could stop thinking about it. I had to at least try it.

To do: hack the wall!

Assumptions

I know nothing about the Wall of Sheep’s internal workings. That’s deliberate. I wanted to test this for the fun of it, and part of the challenge was to see how far I could get without any knowledge of it. I had to make a few assumptions:

  1. If you’re connected to the right Wi-Fi network and submit credentials in plaintext, they’ll be shown on the wall.
  2. The process of getting captured credentials on the wall is automated.
  3. The wall is rendered by a web browser.
  4. The wall’s software has been around for a while and wasn’t written to be particularly secure. After all, it’s on the attacking end, right?
  5. No one’s tried this before, so no one’s fixed it before.

Choosing the attack

If the above assumptions are true, the obvious attack vector is Cross Site Scripting (XSS). The method is to create a snippet of JavaScript and then trick the Wall of Sheep into displaying — and executing — it. This should work:

<script type="text/javascript">alert("I was here.");</script>

But how do I get that onto the board? The password field is usually censored, such as hunter2 being masked to hunt***. That would destroy the payload, so that wouldn’t work. Is there a way to make a DNS hostname that renders correctly? Eh, maybe, but crafting that sounds like work. (Note to self: but boy, wouldn’t that wreak havoc on the web? Huh. I’ve gotta look into that.)

However, look at that lovely login field. It’s just sitting out there in full, uncensored, plaintext glory. Jackpot! That’s where I’ll inject the JavaScript.

Setting up a webserver

This attack requires a webserver to send those faked credentials to. For ease of implementation, I configured HTTP Basic authentication with:

  • Username: Me<script ...
  • Password: lol
Remember how I've wanted to do this for years? Guess who suddenly remembered to do it on the last day of DEF CON. Everything after this was done on my iPhone with Vim in an SSH client. This was not an ideal way to do something technical. Learn from my mistakes: failing to plan is planning to fail.

Getting onto the DefCon-open Wi-Fi

You brought a burner device, right? I didn’t. What could possibly go wrong connecting an off-the-shelf device to an open network at DEF CON! YOLO.

Visiting the web page

I logged into the page on my webserver’s bare IP address, watched the board, and… nothing. I reloaded it; nothing. I looked around to see if any of the participants looked like they might’ve found something; still nothing. Rats.

Enlisting help

Jan and Pat1 were participants sitting near where I was setting this up. I needed their assistance but didn’t want to outright ask for it. I started posing innocent questions to Jan: “Hey, what are you working on? What’s Wireshark?” While they kindly explained in general terms, they were understandably more interested in their own project than tutoring a passerby. Pat was more willing to teach me and I pulled up a chair to sit with them. They patiently answered my questions and pointed to interesting things on their screen. They also noticed fairly quickly that I was regularly reloading a page on my phone as I watched them. “Hey, uh, are you trying to get caught?” “Maaaaybe…” “Why?” I gave them a quick explanation of my project and they instantly bought in:

Pat: Do you think this’ll work?
Me: Probably not, but it’s worth a shot.
Pat: Oh, wow. If it does, this will be legendary!

I had a helper. Soon after, Jan noticed we were up to something, leading to one of my favorite exchanges at DEF CON:

Jan: Are you two trying to get something up there on the board?
Me, grinning: Yeah. It’s a JavaScript injection.
Jan, wide-eyed: Who the hell are you?

Thank you, Jan. I felt like a bona fide Security Researcher after that.

Another random visitor saw us huddled and asked if we were trying to hack something. Jan looked at me, looked at the visitor, said “nope”, and looked back at me. I winked at Jan. Jan nodded back. The visitor squinted at us and walked off. Jan had my back.

Pat and Jan were awesome. When we couldn't capture my phone's request, Pat asked if I happened to be on a VPN. facepalm. Yes, I had iCloud Private Relay turned on globally.

Social engineering a Shepherd

After experimentation, we had usable Wireshark captures of me logging into my website. However, they weren’t being displayed on the Wall of Sheep. It turned out that my assumption was wrong: we had to demonstrate the capture to a “Shepherd” running the contest. Pat called one over. We showed them Pat’s capture, but they weren’t convinced at first. Most website logins are through a form POSTed to the server, not through HTTP Basic authentication. The Shepherd was also skeptical that the login was successful because the server was returning the default “welcome to Nginx!” page and not something personalized for the (obviously fake) username. I leaned very hard into the “innocent observer” role, asking questions like “but isn’t that what a successful capture looks like?” and “golly gee, it looks right to me. Don’t you think?” and “it looks suspicious to me, too, but couldn’t we try it and see what happens?” Our Shepherd seemed almost ready to go along with it — until they burned my plan to the ground.

Defeat

I asked the Shepherd how a login goes from being captured to being shown on the Wall of Sheep. Their reply doomed our fun: “I’d type it in.” Oh no. That’s not good. “Isn’t it automatic?”, I asked. The Shepherd paused to rub the bridge of their nose. “Well,” they sighed, “it was until people started sending a bunch of vile usernames and passwords and kind of ruined it2, so now we have to moderate the process.” I wasn’t giving up, though. “Could you type that username to see what happens?” “It’d just show up like that,” they replied. “Could we try it?”, I pleaded. “I mean, it’s just text. Um, that’s not a web page”, they countered.

What.

And then for the first time ever, I saw a flashing cursor down in the bottom corner of the Wall of Sheep. My heart sunk. “Is that Excel or something?” They grinned: “it’s just some old software we run.”

Disaster.

Regrouping

That’s when I formally gave up on this attempt. If it were ever possible to hack the Wall of Sheep, it wasn’t on that day. That doesn’t mean I’m abandoning this forever, though. Next year, I’m going to make a smarter effort, by:

  • Setting this up in advance. Again, Vim over SSH on a phone sucks. I’ll have the fake login working before I leave home.
  • Getting there earlier. If the Wall of Sheep is ever going to be automated and rendered in a browser, it’ll be at the opening of DEF CON before anyone’s polluted the waters.
  • Using a more common authentication method than HTTP Basic auth, like a typical login form.
  • Making the resulting page look like I’d really logged into a legitimate service.
  • Bringing a burner device, because putting my own personal device on that specific Wi-Fi network was not the best idea I’ve ever had.

And if Jan and Pat are around, I’m recruiting their help again.

To do: hack the wall harder!

  1. I didn’t get anyone’s names, or their permission to describe them. Fake names are all you get. ↩︎

  2. I appreciate the irony that I’m complaining about hackers getting stuff to show up on the Wall of Sheep in a post where I’m talking about getting stuff to show up on the Wall of Sheep. The first rule of a good prank, though, is “don’t be a jackass and ruin it for everyone else”. I was going for something that I hoped the Shepherds would find amusing and wasn’t trying to get racial slurs and other vile junk to show up on a big screen. Don’t be that person. ↩︎

How QBasic jump started my career

When I was an enlisted sailor in the US Navy, I spent an awful lot of time on a deployment hacking away on our ancient laptops to write QBasic programs to automate some of our completely-not-computer-related work. For instance, I wrote a little program to format short text messages in a particular way and write them to a floppy. Then I could hand that floppy to the ship’s radioman, and he’d run a program to load the messages and broadcast them over a packet radio to the MARS radio network. A ham operator in the States would call the recipient, read the message to them, transcribe the reply, then radio it back to our ship. I’d pick up a floppy with those replies, bring them back to the medical department where I worked, and print them out.

At that time, the quickest way to contact home was to buy a calling card for the ship’s on-board satellite phone, which cost something like $5 per minute to use. The alternative was to write a physical letter. If you were lucky and the person wrote back immediately, that would take about one month to get a response. The MARS radio system was free to use and shortened the round trip to about a day. My little program helped people use it, and I can’t exaggerate how happy this made my coworkers and bosses.

One day, a particularly enlightened boss sat me down for a talk. “Why do you lie to yourself that you want to be in medicine?” “Uh, because I want to be a doctor?” “Stop kidding yourself. You want to work with computers. We both know it.” Whoa. It was like a lightning strike. Well, of course I could go to school for that thing which had been my obsessive hobby since I was tiny! Why hadn’t I thought of that?! And so I got out of the Navy, enrolled in a computer science program, and here I am today rattling on about it.

Thank you, QBasic. You weren’t running on my beloved Amiga, but you were in the right place and time to kick off a career that I’ve loved every step of the way.

Slack was broadcasting hashed passwords for 5 years

I received an email from Slack on Thursday, 2022-08-04:

We’re writing to let you know about a bug we recently discovered and fixed in Slack’s Shared Invite Link functionality. This feature allows users with the proper permissions to create a link that will allow anyone to join your Slack workspace; it is an alternative to inviting people one-by-one via email to become workspace members. You are receiving this email because one or more members of your workspace created and/or revoked one of these links for your workspace between April 17th, 2017 and July 17th, 2022. We’ll go into detail about this security issue below.

Important things first, though: We have no reason to believe that anyone was able to obtain plaintext passwords for users in your workspace because of this vulnerability. However, for the sake of caution, we have reset impacted users’ Slack passwords. They will need to set a new Slack password before they can login again. A list of impacted users is below.

[redacted]

Now, for some technical details — feel free to skip the next two paragraphs if that doesn’t interest you. When you’re connected to Slack, we keep your client updated using a piece of technology called a websocket. This is an always-open stream of behind-the-scenes information, specific to just you and your account, that we use to push new information to your Slack client. When a new message is posted, a new file is uploaded, a new emoji reaction is added, or a new teammate joins, all of this information (plus much more!) is sent to you over a websocket. Data streamed from Slack’s servers over the websocket is processed by the Slack client apps, but often hidden from the user’s view.

One of the hidden events we send over the websocket is a notice that a shared invite link was created or revoked. The bug we discovered was in this invite link event: along with the information about the shared invite link, we included the hashed password of the user who created or revoked the link. This information was sent over the websocket to all users of the workspace who were currently connected to Slack. The hash of a password is not the same as the password itself; it is a cryptographic technique to store data in a way that is secure, but not reversible. In other words, it is practically infeasible for your password to be derived from the hash, and no one can use the hash to log in as you. We use a technique called salting to further protect these hashes. Hashed passwords are secure, but not perfect — they are still subject to being reversed via brute force — which is why we’ve chosen to reset the passwords of everyone affected.

When your users reset their passwords we recommend selecting a complex and unique password. This is easiest to do by using a password manager to help generate and store strong, unique passwords for every service.

If you have additional questions, or if you need our help as you investigate this issue, you can reply to this message or email us feedback@slack.com.

We know that the security of your data is important. We deeply regret this issue and its impact on your organization.

Sincerely, The team at Slack

In summary, for 5 years Slack sent your hashed password to everyone on your Slack server every time you invited (or uninvited) someone to it.

This email leaves a few questions unanswered:

  • How can you have a major vulnerability like this for 5 years?
  • What hashing algorithm did they use? Argon2? MD5?
  • Did they use per-user salts or one global one?
  • Where is the open, public notification of the issue?

However, they did get one thing right: use a password manager to generate a strong, random password for every single service you use, and never, ever, under any circumstances, use the same password for more than one service. Because if you’ve invited anyone to Slack in the last 5 years, and you use the same password for Slack and your bank, I hope you’re on friendly terms with all of your coworkers.

Update 2022-08-06

Slack has now posted about this on their blog.

Not Upgrading for Stage Manager

Apple’s iPadOS 16 features a new multitasking mechanism called Stage Manager, but only on very new iPad models equipped with Apple’s M1 CPU. The ludicrous reason Apple gave for this limitation is that the recent M1 chip is the first iPad CPU capable of using swap space.

If you listen quietly, you can hear millions of computer science graduates rolling their eyes at that ridiculous excuse. Far less capable computers have supported swap space for decades, and I won’t bother going into details of how nervy Apple’s claim is. Admit it, gang: you want to give people a reason to buy new hardware to use the shiny new feature. I could respect an honest explanation that doesn’t insult my intelligence.

But because of this dishonesty, I’m holding onto my still-overpowered 2018 iPad Pro until it dies, or until Apple releases a feature I can’t live without. If there were a legitimate technical reason to hold back new features on older hardware, I might use that as a reason to upgrade. Now, though, I don’t trust Apple not to pull the same trick next year. If I bought a 2022 iPad Pro because of this, and next year they released a feature in iPadOS 17 that would only work on 2023 models for another contrived reason, I’d be livid.

Apple’s trick isn’t going to make me upgrade more often, but less often. I’m not risking my hard-earned money until I have to.

How to give compliments

It’s fun to receive compliments. It’s as much fun to give them! That can be intimidating, though. “What if I say the wrong thing? What if they take it wrong? What if they get angry?” Relax! Saying something nice can be easier than you’d think. First, the ground rules:

Don’t be a pest. If someone’s talking to someone, chatting on the phone, reading a book, or otherwise occupied doing something they probably don’t want want to be interrupted from, then don’t.

They don’t owe you a response. If you say something nice to someone, you haven’t obligated them to thank you, to smile, or even to acknowledge your presence. If they don’t, move on.

Examine your motives. Are you saying something nice to get a date? See the previous rule, and stop right there.

Don’t compliment their body. Unless you’re talking to your romantic partner, don’t comment on someone’s body. If they’re a stranger, or a co-worker, or anyone else who isn’t already voluntarily in a relationship with you, don’t say it.

Stick to complimenting choices they make. For extra safety, concentrate on matters of taste that they’re publicly displaying, like “those are great boots!” or “I love the band on your jacket!”

Don’t take forever to do it. If you’re standing there impatiently waiting for them to finishing their conversation, you’re going to come across as creepy.

With those said, here’s how to say something nice to someone:

  1. Turn to them and say, “wow, your hair color is so cool!”
  2. Smile quickly and sincerely.
  3. Go back to what you were doing.

That’s it. This communicates that you’re being sincere and not imposing an obligation on the listener. If they smile and thank you, right on! If they don’t, that’s fine!

It’s fun to compliment strangers, and people should do more of that. Make sure you’re doing it for the right reason — to make the world happier and more pleasant — then make it easy on the recipient. Good luck!

Don't buy a cheap Apple Watch Series 3

Don’t buy an Apple Watch Series 3. Many recent articles enthuse about its current wonderfully low prices, but it’s a trap. The Series 3 is slow, technologically obsolete, and unsupported by the upcoming watchOS 9. Anyone buying it as their first Apple Watch will be disappointed by the awful performance.

I could only recommend it for someone who broke their newer Apple Watch, wants something to tide them over until the new Series 8 is released, and can recycle it or donate it to someone who’d be OK with a dead-end device.

The dynamic range of emotions

“Dynamic range” describes the difference between the softest and loudest bits of a musical recording. If the sound was recorded poorly so that the soft and loud parts are similar, it stops being interesting. Imagine the 1812 Overture where the cannon fire was at the same volume as the brass, or Skrillex without the drop. Without softness to compare it to, you can’t have loudness.

I was thinking about a loved one who passed away, and about the ebb and flow of happy memories mixed with tragic moments. The difficult parts were devastating, but I don’t think I’d forget them if I could. Without the sadness to compare with, could the happiness be as wonderful? I wouldn’t risk foregoing the lows if it meant the highs were less joyous.

Internet Explorer is finally dead

I was working the night shift at a motel while going to school during the day, when my parents saw a help wanted ad for a local ISP. This was in the late 90s when public use of the Internet was starting to take off, and that sounded like a lot more fun than balancing books every night.

It was. Although I technically worked in tech support, at least at first, in a small shop everyone learns how to do everything. Soon I was learning networking, configuring routers, managing Linux systems, and doing full stack web development. At the time, that meant using Gimp to carve up images to shoehorn into HTML table layouts, and using Perl to write CGI scripts to process forms.

That meant having very strong opinions about web browsers, and the preferences tended to fall into two camps:

  • If you used Windows and were new to the Internet, you liked Internet Explorer.
  • Everyone else preferred Netscape Navigator.

Netscape was better in almost every way, except for the most crucial: Windows came with Internet Explorer. And from Microsoft’s point of view, that was just peachy. They were able to leverage their famous “embrace, extend, and extinguish” policy to push ever more Windows-specific functions onto the web. Why struggle with tricky HTML forms when you could embed ActiveX controls right there in the web page? Or why use the industry standard HTML, CSS, and JavaScript definitions when you could use Microsoft’s own proprietary versions that were very slightly more convenient to use (even though it meant the page wouldn’t load in Netscape on Windows or any other OS)?

For the next decade, Microsoft used every trick in their book to make Internet Explorer the standard web browser, even though it was very non-standard. And once they succeeded, they got bored and forgot to improve it further, at least until Google’s Chrome started getting popular.

And through it all, my colleagues and I continued to try to make web pages that looked good and worked well in all browsers. That process looked like:

  • Develop the web page, testing with Firefox or Chrome, until you got it working.
  • Test it on the other browser to make sure it still worked.
  • Find a creaky Windows box to test it with, see what broke because Internet Explorer didn’t process standard HTML correctly, and tweak it until it looked mostly correctly in all 3 browsers.
  • Go home and drink.

The Browser Wars were a real, serious struggle, and it wasn’t at all obvious whether open technologies or proprietary vendors were going to win.

The web’s in much better shape now, with several major desktop and mobile browsers that work more or less the same. Sure, there are still differences that have to be dealt with, but at least they all use basically the same DOM, and the same JavaScript runs on most browsers unless you’re pushing at the edges.

And now, all these years later, Internet Explorer is finally dead. After many long years of fighting against that abomination, I won’t miss it one bit.