攻击房东的锅炉
Attacking My Landlord's Boiler

原始链接: https://blog.videah.net/attacking-my-landlords-boiler/

2025年4月,有人详细描述了他们如何入侵公寓的无线电遥控恒温器,以更好地控制供暖系统,绕过房东设置的限制。目标是在无需房东干预或电工操作的情况下,将供暖系统集成到Home Assistant自动化系统中。 其方法涉及重放攻击,克隆恒温器和锅炉之间的信号。最初尝试逆向工程通信协议过于复杂。他们使用了一款经济型RTL-SDR来可视化868MHz无线电信号。在尝试使用868MHz开发板广播信号失败后,他们改用HackRF One克隆设备来录制和重放“开”和“关”命令。 HackRF通过USB集线器连接到Home Assistant服务器。他们创建了一个基本的Web服务器来执行发送命令,这些命令随后由Home Assistant的平均传感器插件和YAML配置进行控制。此设置成功地实现了供暖自动化,可以通过智能手机和预设时间表进行控制。尽管使用功能强大的SDR有些大材小用,但这名用户还是找到了一个能够满足其供暖需求的实用解决方案。

一篇Hacker News帖子标题为“攻击房东的锅炉”,引发了关于替代方法的简短讨论。原发帖人ericvolp12详细描述了一种基于射频的攻击。评论者willvarfar建议通过将恒温器封闭在一个温度可控的盒子中来机械地控制它,这反映了他们自身的技能。其他人很快提出了不同的技术方案:kbuck建议将ESP32连接到锅炉的控制板以闭合干触点电路,unsnap_biceps也赞同这种方法。这场对话突出了不同的背景和“工具箱”如何导致针对同一问题产生不同的解决方案。

原文

Please do your due diligence and check local laws before attempting anything I do in this post. Transmitting radio signals can become legally problematic very quickly, and the band I specifically transmit on here (868Mhz) is illegal in the United States without a license. I'd rather you didn't have men in suits knocking on your door on my account. You've been warned!

A little while ago I moved into an apartment to live on my own for the first time. This has given me a decent amount of newfound freedom to sculpt my living environment to my liking, but not enough where I could start knocking down walls. I have a landlord (and a deposit!) to think about, after all. 🙂

While it isn't near the level of knocking down walls, I was finding heating my apartment rather frustrating. The boiler's thermostat installed by my landlord is a single radio-controlled unit that uses a built-in temperature sensor to modulate the heating on and off to meet a target temperature. This presents a few first-world problems:

  • The temperature sensor can only sample a single room in the apartment, which heats unevenly.
  • That room is dependent on the physical proximity of the thermostat's controls, which can be annoying to use if I might be in bed and the controls are in the living room or vice versa.
  • If I forget to turn the heating off before I leave the apartment, I'm wasting a lot of costly energy.

I automate things around my apartment with Home Assistant, and I wanted to be able to do the same here. There are a lot of off-the-shelf solutions for this, obviously, but to get back to the knocking-down-walls comparison, they would require my landlord's cooperation and likely a visit from an electrician. I don't want that!

Instead, here's how I figured out how to control my apartment's heating in a way that leaves no trace using the existing thermostat already fitted by my landlord, and maybe learn a bit about radios along the way.

Where Do We Start?

I knew that the thermostat communicated with the boiler through some kind of radio protocol. We could try to reverse-engineer the protocol from scratch, but as I'll get into later, that turns out to be very involved and way beyond my minimal radio skills.

I eventually decided it was a lot easier to attempt something called a Replay Attack. This involves cloning the signals sent between the boiler and the thermostat, and then pretending we are the thermostat by re-broadcasting the signals. This way we don't need to understand the protocol, just replay it.

This approach requires some degree of luck and crossing your fingers. Replay attacks can be pretty easily thwarted by using an incrementing counter in the communications to nullify previous signals, ignoring signals with a counter value you've already seen. I was lucky the thermostat does not do this—your mileage may vary!

Initial Reconnaissance

The first thing I did was check to see if there was any information online about my specific thermostat. I came across a listing for the exact model I had, along with a datasheet in the attachments section. The section on RF Communication is exactly what I was looking for:

From this, we know the thermostat communicates around the 868Mhz range. The Protocol: Encrypted part was initially a bit concerning, but it turned out to not be a problem.

The first issue I'm running into here is that there are shockingly few resources on cloning a 868Mhz signal online. Most beefy resources were about using LoRa/Meshtastic. I would come across a lot of Reddit posts of people trying to do the same thing as me for things like ceiling fans and garage doors, but nobody seemed to have any answers... 😭

I suspect this is because unlicensed 868Mhz transmission is illegal in the US and nobody cares about Europe, but who really knows. My life would be so much easier if it were 433Mhz instead, as there is a plethora of consumer-facing tools for communicating on that band.

Seeing Signals

So without much to go on, I thought the first thing to do would be to actually see the radio packets and inspect them. I'd read about Software-Defined Radios in the past and guessed it'd be my best bet. Most SDRs are really expensive, so I went with the budget RTL-SDR V4 off of AliExpress. (This actually ended up being somewhat unnecessary for reasons we'll eventually get to!)

You might have heard of the infamous Flipper Zero and its ability to clone and replay signals. Maybe you're like me and consider using it in this situation, but be warned that the Flipper is NOT an SDR. The Flipper is very stingy about what frequencies it can operate on. I found this out the hard way when I borrowed one and assumed all was hopeless when it wouldn't work.

After it arrived, I hooked it up to my laptop with the SDR++ software just to see if it worked and get an initial glimpse of my thermostat yapping. After pressing the thermostat's buttons a few times, I managed to see the waterfall light up!

The "waterfall" at 868Mhz showing long horizontal blips.

Ignore the solid vertical line on the waterfall—this is just a common byproduct of using a really cheap SDR, and for me it appears nearby to any frequency I'm inspecting.

This step isn't super important, but we can then try to use the rtl_433 tool (it works on other frequencies despite the name) to see if the thermostat is speaking a known protocol. More obscure devices might not work here!

It seems like this thermostat speaks the same protocol as another Honeywell one. The demand attribute sets whether the boiler is on (1) or off (0), and then the boiler responds with an acknowledgement (presumably so the thermostat can determine if it's out of range).

Trying To Yell Back

Now that we've actually seen the back-and-forth communication, we want to be able to send some packets ourselves and puppeteer the boiler as if we were the thermostat.

Using a 868Mhz Challenger Dev Board, first failed attempt...

This was the step I got stuck on for months. I was trying the "smart" route of attempting to reverse-engineer and reconstruct the packets by hand using URH and then broadcasting them with very cheap 868Mhz microcontroller boards. I can safely say this was all wayyy outside of my skill set. None of the boards were really designed to talk to anything other than the exact same board, and going any further than that required poking at radio registers in ways I wasn't comfortable doing.

The HackRF

The official HackRF One board, going on to spawn many AliExpress clones.

I decided to then go for the sledgehammer approach: use a full-blown SDR to just replay the exact same signal without a care for what the signal actually contains. But the cheap RTL-SDR I got earlier only supports receiving, not broadcasting. SDRs that can broadcast are usually hundreds of dollars.

I say usuallyyy because one of the most common broadcast-capable SDRs, the HackRF One (usually upwards of $400), had numerous clones available on AliExpress for a fraction of the price—just $40.

And then I say haddd because, writing this months later, AliExpress has removed pretty much every listing you could find just searching "HackRF". From my understanding, they were getting nabbed at customs in a lot of countries that were getting pissy about importing a scawy hacking tool, so they just decided to nuke all the listings rather than deal with it. Newer clones can be bought from here, but they aren't nearly as cheap as they used to be... 😭

There are some obvious ethical (and probably a few technical) problems with cheap clones of what is meant to be open-source hardware, but I figured it'd be fine for my small use case. Please support the original hardware project if it's within your means to!

As I kinda alluded to earlier, this makes the need for the RTL-SDR sort of redundant? But I guess it's always good to have another SDR just to confirm that we're not polluting other frequencies.

Actually Yelling Back

With the HackRF in hand, we can use the hackrf_transfer tool to record signals and, most importantly, replay signals. I perform these commands and then press the appropriate controls on the thermostat to write the signals to individual files:

# We set the frequency to 868.3Mhz and the sample rate to 2000000.
hackrf_transfer -r turn_off.raw -f 868300000 -s 2000000
hackrf_transfer -r turn_on.raw -f 868300000 -s 2000000

And then we can try and turn the boiler off and on from CLI like this:

# We use -a to turn on the amplifier and -x to increase the gain a tad.
hackrf_transfer -t turn_off.raw -f 868300000 -s 2000000 -a 1 -x 23
hackrf_transfer -t turn_on.raw -f 868300000 -s 2000000 -a 1 -x 23

After doing this, I could hear the physical relay inside of my boiler turning on and off!

Automating The Whole Thing

My HackRF clone in a 3D printed case, plugged into the server.

I have the HackRF plugged into a powered USB hub connected to my Home Assistant server. I wrote a very basic web server that simply shells out to the transmit commands above in a Docker container.

Then with an Average Sensor Plugin and the config YAML below:

command_line:
  - switch:
    name: Boiler
    command_on: "curl http://docker-vm:1111/api/on"
    command_off: "curl http://docker-vm:1111/api/off"

sensor:
  - platform: average
    name: "Average Temperature"
    entities:
      - sensor.bedroom_thermostat_temperature
      - sensor.kitchen_thermostat_temperature

climate:
  - platform: generic_thermostat
  name: Boiler Thermostat
  heater: switch.boiler
  target_sensor: sensor.average_temperature

We have a working controllable thermostat! 🤯

At this point I was just happy to have the thing working after so many months, so I'll be the first to admit this setup with Home Assistant is a bit slapdash and could use some cleanup. It'd be better to write a proper plugin and control the radio directly instead of shelling out to the CLI. Relying on curl to heat my apartment is maybe a bit cursed?

Was It Worth It?

Grafana graph showing the temperatures following the target one.

I've been using this setup to control the heating of my apartment since the beginning of December and haven't had any issues since! It's super convenient to dial in the temperature from my phone, and the automations I have make me feel like this project was really worth the work.

I have some basic automations like having the temperature go down when I'm sleeping and then up in the morning in time for me waking up, but I also have it so the heating turns off when I go into town and turns back on when I'm just a few train stops away so my place is nice and toasty for me getting home!

The only thing I'm not happy with is needing to use a very powerful and versatile radio like the HackRF for something as simple as a boiler on/off switch. But I'd rather use something overkill and have it work than spend ages trying to force smaller radios to do my bidding.

The important thing is I'm not as cold as I used to be! 🐺


There was a comment section here. It's gone now.

As of March 16th, 2025 the United Kingdom's Online Safety Act has gone into full effect. The law presents a lot of challenges for hobbyist websites like this one to present any user-to-user content (like y'know, blog comments) and comes with some pretty serious repercussions for non-compliance.

The odds of Ofcom (the regulator who's job is to enforce this) kicking my door down over this blog are low if we are being honest with ourselves. But the odds are at least somewhere above zero and the punishment is a life ruining £18 million fine(!!) so it's just not worth the risk. taking the risk.

A kind lawyer has written up the implications of this law for self-run blogs like this one and the only way to guarantee that I am not in-scope would be to manually review all comments made before being available to the public. Not to be a big baby about it all but I don't really want to do this! I liked my current setup!

So I guess as a little act of protest and to hedge against any risk I've removed the comment section entirely. Sorry about that!

If you want more information on this and how much this sucks for the hobbyist internet please read this writeup.

联系我们 contact @ memedata.com