> When we try and decrypt the on and off packets we get:
> 05 54 55 52 4E 01 00 00 00 00 00 00 00 00 00 00
> 05 54 55 52 4E 00 00 00 00 00 00 00 00 00 00 00
> 05 54 55 52 4E 01 00 00 00 00 00 00 00 00 00 00
> 05 54 55 52 4E 00 00 00 00 00 00 00 00 00 00 00
> 05 54 55 52 4E 01 00 00 00 00 00 00 00 00 00 00
> 05 54 55 52 4E 00 00 00 00 00 00 00 00 00 00 00
> Success! This is a lot more sensible. A fixed header, byte 5 switching between a 1 and a 0 for on and off, and a bunch of zeros.
I would guess that’s not a ‘fixed header’, but a length byte (“command is 5 bytes long”), a command (“TURN”) and an argument (zero or one), padded with zeroes to 16 bytes.
That "54 55 52 4E" jumped right out to my eye as the uppercase alphabet. Knowing that numbers start at 0x30, uppercase letters start at 0x41, and lowercase letters start at 0x61 makes alphanumeric patterns in hex dumps easy to spot.
That knowledge is good for short strings, but the canonical hexdump format is a the best way to look at packet and memory dumps.
That’s pretty typical of binary formats. That and offsets or addresses. And type tags. Assuming the payload isn’t compressed or encrypted, you can get pretty far assuming you’ll run into one of those eventually.
Anecdotally, earlier today I was trying to decipher Encarta data and came across the “Mind Maze” data and it’s mostly that - fixed 32-but header, question size, (answer size, answer, correct flag, something I haven’t figure out yet){4}. Then a separate file with an index value and an offset into the first file as well as a header I haven’t figured out yet.
It is padding. It was encrypted with AES, which has a block size of 128 bits. Its input needs to be padded to that amount, unless you use it in some stream modes of operation (e.g. CTR).
Eugh I hope not the padding should be at block level not at content level if this was the standard zero padding from a crypto lib you'd have 0x80 before the padding bytes (and you'd get the unpadded message when decoding it correctly)
Well, they're encrypting with a statically-built-in key shared across all of their devices (and even with others). I hardly think they care about properly implementing padding!
Power supply failure? The WS281x things can go really bright, and, in bulk, suck an awful lot of current. A 12V, 3A power supply on a strip of 100 is just about enough to drive them all to full bright white, and dazzlingly bright it is. So I'd look for a blown fuse. The fact that the firmware only drives them to 31 out of a possible maximum brightness of 255 offers a clue.
That was my first intuition as well, seeing the brigthness limited to 0x1f. With any luck, the power supply might have a fuse, and it's just the fuse that blew up.
Anyway, if you can't salvage it, standard WS281x LED strings can be hooked up to a Raspberry Pi and you could use my open source addressable LED controller :) https://github.com/mbevand/ledthemfight It comes with built-in effects. I made it very modular so for the DIY crowd, in 2 lines of Python, you can create simple custom LED effect modules. See a demo here: https://youtu.be/qpd2rILsnM4
These don't appear to be WS2812. Look at the Ali link he posted. There is a pic of the wires that show four conductors on the strip: 12V, red, green, and blue. I think this is an analog RGB strip where are the lights in the strip are the same color vs. individually addressible.
Anybody wanting to do anything with LED lighting owes it to themselves to look at WLED. Lots of built in effects, web gui, super cheap ESP32 (or ESP 8266!) as the controller, sound-reactive, etc etc etc. WLED is running my indoor Christmas lights right now and they look great.
There are individually addressable leds that have their ‘address’ burned into them and use a ws2812-style protocol, it could be that. There will only be one continuous data wire, which is cheaper to assemble and resistant to single LED failures.
Nice writeup! It reminded me of trying to reverse engineer some lights I have, only to discover they’re encrypted. One is an amaran 60d and then the rest are a handful of SmallRig RM75 battery LED lights, and I wanted to make a script to turn them all on/off instead of fiddling with 2 separate apps.
I spent a bunch of time trying to reverse engineer the apps and the protocol, and it turns out both of these lights seem to use the same negotiation process but use different libraries to do it. I tried to mimic the Diffie-Hellman key exchange process they do on connection, and then kinda gave up. IIRC there was another step or 2 after that, one where it sent a random-looking number (another key? After sending the first key??) and I couldn’t figure out what it wanted there.
Your writeup makes me think I should just go try that hardcoded key and see if it works…
Oh, I would so love to see you succeed with the Amaran lights, which presumably would lead to all of the Aputure stuff being reverse engineered? I think if there was an open-source integration for them with say the Elgato Stream Deck or Home Assistant, it would be a major, major success story. For all those YouTube folks that do talking head at their desk this would be sooo much better than controlling them via an app on the phone.
Not sure what you did with it, but I found that some of this SmartTrash does a hard reset when you do some magic sequence such as quickly turning if off/on 5 times in a row.
If you want a more GUI-oriented way of doing BLE packet sniffing, try the nRF Connect app. Not sure about iPhone, but if you let it sit in the background on Android, you can pick up BLE activity from a nice little GUI on your phone. I use it every day.
I bought a big spool of addressable lights from Aliexpress and hooked them up to an ESP32. Took some soldering and other hacking, but they’re really, really, nice.
Even though it's way more powerful than my first computer, it uses only a fraction of the energy. So yes, in a way maybe you're abusing a pretty powerful computer to do some silly gadget thing, but there's no real negative impact. I know what you mean though. I've only recently gotten into microcontrollers, and because of the time of year I've been thinking of Christmas lights too, and felt the same thing. Then again: I'm also using my M1 Macbook to write a comment on HN, which is only a fraction of what it can do.
Reminds me somewhat of certain keyboard MCUs that would also brick when fed certain lighting commands.
OpenRGB ended up having to disable the particular module from running automatically on that hardware. (Although the vendor software would also trigger said bug, on occassion.)
Unfortunately, the usual way for triggering the in-system programming mode required sending a usb hid report, but affected devices wouldn't even enumerate anymore. (Assuming it was even firmware corruption and not some other undefined behaviour causing hardware damage)
Tuya is so hilarious in this regard. The protocol is just TLS over TCP, but the app happily sprays your Wi-Fi password to every STA in the area every time you add a new device.
(It's how pairing is done - the app blindly broadcasts packets to 255.255.255.255 and the target device (lightbulb, power outlet, et al) just sits in promiscuous mode. The packet contents are protected by WPA2 et al, but the packet lengths aren't, so the protocol sends a bajillion tiny packets with each packet's length set to the ASCII byte value of the next character in the setup handshake. I believe it sends it multiple times in a row. This is why pairing takes 2 minutes then always abruptly stops before the counter reaches zero.)
IoT pairing is a tricky problem because phone/laptop devices give a very limited API for communicating with a new WiFi device that isn't yet on your WiFi network.
All of the decent WiFi-only IoT devices I've seen bootstrap the process by acting as an access point of their own until they're configured. There are some opportunities for securing that initial connection better, like ensuring that the WPA2 key for the temporary AP mode is complex and unique to each device, but I haven't come across a fundamental flaw in the approach. Are you aware of any?
I'd prefer an out-of-band option, like "physically connect the new device to the IoT hub's 'new device' port to configure it automatically before moving it to its permanent location", or "scan the QR code on the new device, which contains a public key that the IoT hub will use to broadcast the WiFi credentials over RF", but I understand that at least for mass-market residential products, that's unlikely because it generally involves more components on each device.
I've seen an iot app do it via multicast - the destination MAC isn't encrypted in the wifi frames, and the last one or two bytes of them are controlled by the sending app.
I figured this out when I tried to debug why the pairing didn't work from my phone, but did from an old Samsung A2: the iot device only had a 2.4ghz module, my new phone was on 5ghz...
This is what I was really afraid of when I reverse engineered my fireplace BLE controller last year. Especially since the "Set password" command accepts raw bytes for input but the OEM app only ever sends length-limited numeric data.
Luckily, it seems to completely forget anything that happened to it after a brief power loss.
Which is probably why most of the BLE controllers of the same brand simply stay at the default password of "0000". A power outage will eventually get you back to that. If you're really bored that'd probably make for some great BLE wardriving.
I'm looking for some flexible, robust lights for my car's roof rack. I'm wondering if anyone knows a set that will fit these requirements:
- Battery powered and outdoor / all weather compatible
- Easy to attach the battery box to surfaces using ties
- Ideally "mini" form factor ("T5") [1]
- Ideally RGB and programmable. I'd like to use them for
Christmas (red/green), Halloween (purple/orange), and
other seasons.
Does anyone know of anything that fits this bill? I've had trouble finding anything that fits the last criterion. Walmart and Home Depot will sell the first three.
Your direction depends (I guess) on how much DIY effort you're willing to put in?
For example, you can get 12v LED strips which are IP67 (waterproof inside a silicon tube) pretty easily [0] and which would probably give a much more impressive effect than a string of Christmas-style lights, due to having lots more LEDs to play with.
However, you'd need to do the leg-work of also buying and programming a micro-controller (something like an Arduino, ESP32, or ESP8266 [1]) and figuring out how to power them from your car battery. You could probably house all of the electronics inside the car and just run wires out of the boot, relying on the existing boot seal to keep everything waterproof.
You can check out "bullet string" style WS2811s. They're 12v native if you're tying back to your car's 12v, usually come waterproof with xConnect pigtails, and are very attachable/flexible. They're easy to resolder with extensions and chain too:
12V is used more often than 5V for outdoor shows. This vendor is very popular, and also has a discussion about 12V vs. 5V: https://www.holidaycoro.com/kb_results.asp?ID=126
Also, the xConnect pigtails are great for wiring up large shows and for adding longer run extension cables.
Join the WLED Discord and look in the #projects and #showcase channels. There are lots of projects with people outfitting their vehicle with RGB LED lights. Just beware that it is really easy to get hooked on this stuff!
Nice, so they can get my money monthly. Where do I sign up? Can I also rent custom lighting schemes? I would love one to light up on the notes of Twinkle, Twinkle Little Star.
It might be worth looking at the decompiled app code some more and seeing if it contains any clues as to the type of command you may have sent, just in case it happens to be some command used for updating the firmware or something. It probably isn't, but you never know.
That said, I suspect you're right and the order of operations was probably something like this, assuming the light controller uses a microprocessor:
1. Controller receives valid command to switch to light pattern 12.
2. Light pattern 12 is saved as user's preference (so it can be restored on power-on).
3. Controller attempts to find light pattern 12 and hits a bounds overflow in the pattern lookup table.
4. There's probably no error checking for this because this "can't happen"[0], so it tries to use the data it finds, which is garbage.
(The next steps depend on how the lookup table is formed, but for the sake of example, let's say the lookup table is an array of pointers to callback routines for each pattern.)
5. The controller remembers whatever garbage it found, treating it as a pointer.
6. The next time the controller wants to update the lights, it tries to call this garbage pointer (which is possibly just a null pointer).
7. Microprocessor tries to execute code there, but whatever it finds causes it instead to infinitely loop.
8. Dimming LEDs typically require a PWM signal, which they're no longer getting, so they go dark.
9. It's dead, Jim.
When you switch off and on again, the process restarts at step 3.
In other words, there may be a possibility for unbricking if you can factory reset, or find out how it stored your light pattern. (Though the latter will probably require at least opening it up and hoping you find a JTAG header, and a lot of patience and Zen. Don't do things willy-nilly!)
In any case, that's my best guess as to what happened here, based purely on the story and without any knowledge of the architecture or home integration ecosystem. If you attempt to fix it, good luck!
Beginners question, is there a reason we can’t reverse engineer something similar for lights made by Govee? Is it because it’s WiFi and harder to MITM?
I have a couple of Govee light bulbs in my garage I control with an M5StickC using BLE: https://github.com/stevenjohnstone/reversing-tools/blob/main... . Looking at the decompiled Govee android app, there are many products with similar control over BLE in addition to wifi.
There may be an easier way, but another HN thread pointed out that you can use tailscale to make it easier to tcpdump phone apps (because you can send all of the phone traffic through an endpoint you control.) (Presumably raw wireguard is enough? I haven't tried (or seen tutorials for) either approach, it was just a "that sounds clever, save it for my next sniffer project" idea)
I like the form factor of some of the Govee string lights. I’ve thrown out their controller and hooked them to ESP32’s with WLED. Best of both worlds that way.
There are a few projects on github for govee lights. On windows I have used https://github.com/ib0b/RGB-PC to connect to mine by bluetooth but the problem is that govee lights can only be connected to one bluetooth device at a time
Nice writeup! It could be that it wrote the last value to some flash memory but since it is invalid and overflows something, it panics and will never finish booting.
And to be fair it wasn't their 'smartness' that killed them anyway, it was hacker mindset!
Christmas tree lights had different pattern modes etc. even before they were LED, for decades. I honestly think swapping button on the controller/power supply brick for a Bluetooth remote is a reasonable level of smart in this day and age. It's not like they wanted to connect to WiFi and be app-controlled via their servers or something.
> When we try and decrypt the on and off packets we get:
> 05 54 55 52 4E 01 00 00 00 00 00 00 00 00 00 00
> 05 54 55 52 4E 00 00 00 00 00 00 00 00 00 00 00
> 05 54 55 52 4E 01 00 00 00 00 00 00 00 00 00 00
> 05 54 55 52 4E 00 00 00 00 00 00 00 00 00 00 00
> 05 54 55 52 4E 01 00 00 00 00 00 00 00 00 00 00
> 05 54 55 52 4E 00 00 00 00 00 00 00 00 00 00 00
> Success! This is a lot more sensible. A fixed header, byte 5 switching between a 1 and a 0 for on and off, and a bunch of zeros.
I would guess that’s not a ‘fixed header’, but a length byte (“command is 5 bytes long”), a command (“TURN”) and an argument (zero or one), padded with zeroes to 16 bytes.