7
\$\begingroup\$

I have a new liftmaster (chamberlain) garage door opener that has a wired keypad. The keypad has several buttons on it, but for my purposes I'm only interested in the door open/close and light on/off buttons. I would like to reverse engineer this signal in order to control the door opener and light with an ESP8266.

The keypad is wired with only two wires - meanining the power and signal are sent over the same wire.

Using a scope and an arduino, I have captured the signal which is sent when the door trigger button is pressed. (I used an arduino so I could capture a longer signal than I can with my scope. I used the scope to verify that the arduino is capturing the signal correctly).

My method for capturing the signal is to record the micros() each time the signal goes from LOW to HIGH or vice versa.

I have observed is the following:

  • The minimum pit or peak seems to be ~100 microseconds
  • There are three distinct messages that occur when the button is pressed. Notice the voltage is lower on the middle message. I suspect that this might be some sort of confirmation from the opener, and the first and third messages are from the button. enter image description here
  • The message seems to have the same header, but the content changes slightly. Here are two back to back overlaid enter image description here
  • last but not least, you can have more than one button wired in parallel to control the opener

So my question is - what kind of signal might this be?

EDIT: Building off of the observations of @jasen @icodeplenty, I wrote a parser which converts the measured signal into hex. I made a few assumptions:

  • the messages are 11 bits long
  • the first bit is always low (just a start bit?) and so I ignore it
  • the next eight bits are data?
  • the last two bits are stop

I then captured 8 passes for three different events and converted that signal to hex (see below).

I cannot discern any pattern here, other than that every event message starts with AA 80 00.

Handshake (a message is sent by the button when it is powered on):

AA  80  00  50  3C  6A  D4  B4  6D  FB  BE  25  E8  5C  79  7B  B1  DE  95
AA  80  00  65  98  15  6A  58  B2  6C  C9  10  28  CC  19  20  05  F2  94
AA  80  00  A5  E4  EE  DC  37  69  DA  34  95  14  A3  87  84  4E  61  E8
AA  80  00  21  DC  BA  71  FE  FD  FF  FE  19  30  8E  9E  36  6A  A1  EC
AA  80  00  41  F0  63  C7  D3  26  49  9A  91  10  C5  0A  52  23  31  E4
AA  80  00  98  A0  06  0D  06  00  12  20  94  84  A3  87  04  4A  61  E8
AA  80  00  18  A0  4E  9F  22  49  80  24  58  9C  2A  D6  9F  F9  89  62
AA  80  00  46  F0  AA  47  93  6C  49  96  11  74  0E  98  37  6A  A3  80

Door Button Triggers:

AA  80  00  06  B8  3D  B6  68  93  B6  ED  92  10  D5  0A  53  15  28  40
AA  80  00  80  EC  8F  35  4A  92  24  A9  1A  AC  0A  94  2D  6A  DA  2C
AA  80  00  00  C0  D6  A7  6E  DB  B6  CD  92  50  55  0A  52  15  20  50
AA  80  00  6A  30  E5  85  5B  96  65  A9  15  30  CE  14  20  4E  D3  20
AA  80  00  AA  CC  3A  33  A6  4D  D3  54  99  10  86  0C  32  07  12  30
AA  80  00  24  98  70  E7  7E  FF  FE  9D  11  34  1C  98  36  4E  B2  34
AA  80  00  44  E4  8F  51  13  24  48  E2  96  10  87  0C  32  4E  10  30
AA  80  00  91  F0  F5  E0  08  02  20  E0  18  28  4F  9F  2D  4F  80  2C

Light Button Triggers:

AA  80  00  04  AC  58  AA  7C  DB  B7  6D  10  60  CE  39  60  4C  B0  A0
AA  80  00  A6  D4  A3  9F  B7  25  5B  96  6A  C0  F5  63  52  95  61  E1
AA  80  00  99  40  C6  54  21  01  12  20  A9  84  EB  D5  A4  6A  51  C6
AA  80  00  42  F0  61  8F  9B  34  49  9A  64  CC  31  E3  DF  B5  6E  8D
AA  80  00  65  98  35  31  DA  B2  6C  C9  08  64  DC  BB  44  DD  B0  E5
AA  80  00  0A  CC  98  14  ED  FB  BE  6D  86  5C  1C  28  7B  DC  2C  39
AA  80  00  02  4C  0E  54  2D  CB  B6  6D  06  7C  5C  38  7F  95  BE  3D
AA  80  00  A9  D4  E3  1D  B3  6C  59  96  00  60  CE  39  68  DE  B4  E9
AA  80  00  80  C0  87  19  4B  92  24  09  81  18  57  2E  1B  95  2C  39

EDIT 2

I found a python implementation of Security+ 2.0, which is the wireless rolling code protocol implemented for the remote buttons. I'm not a python expert, so reading the code is a bit of a challenge. I'm hoping that the same protocol is used with the wired buttons and this library might offer some clues on how to read and transmit the necessary signal.

There is also a patent for Security+ 2.0 which explains a bit about how it works.

Edit 3 I found a program called sigrok PulseView which has a uart decoder plugin. I tested a bunch of recorded samples and found some consistencies which leads me to believe that

  1. It is in fact uart 9600 baud as @Jasen originally suggested
  2. I do not know if its LSB or MSB. I left the default LSB decoding in from PulseView
  3. The data is obfuscated or encrypted and this is a dead end for now

pulseview

FINAL EDIT for future readers:

I have succeeded in solving this puzzle. I have released an esp8266 shield and a open source solution for controlling Security+ 2.0 doors.

\$\endgroup\$
6
  • \$\begingroup\$ Is this question helpful? \$\endgroup\$ Commented Dec 9, 2021 at 23:09
  • 2
    \$\begingroup\$ Does it matter what it is? You can already try a replay attack, which for your purposes might be enough.... (interesting to fibd out, though) \$\endgroup\$
    – 2e0byo
    Commented Dec 9, 2021 at 23:49
  • \$\begingroup\$ @2e0by0 I did try a replay attack already, but it failed. I suspect this might be because I'm either not playing back enough of the message, or I'm playing back too much. I'm going to try to play the first message - wait, and then play the third message (guessing the middle message is from the opener since it has a different low voltage). \$\endgroup\$ Commented Dec 10, 2021 at 2:47
  • 1
    \$\begingroup\$ @icodeplenty i saw that post. That's an older model that uses a different signal (it just pulls to ground to open the door, like a normal garage door bell button would). The openers from that generation do not work with the new models. \$\endgroup\$ Commented Dec 10, 2021 at 2:49
  • \$\begingroup\$ I created a message parser in JavaScript (can be copied and pasted into a browser debug console to execute it). Now to capture more samples to test the parser and look for patterns. gist.github.com/PaulWieland/f7018cc016711998cca7fc99d6b8f986 \$\endgroup\$ Commented Dec 14, 2021 at 19:04

2 Answers 2

1
\$\begingroup\$

Apart from the first pulse which is over-length, it looks like asynchronous serial with 8 data bits and two stop bits. The evidence for this this is the regularly spaced two high followed by 1 low. (so 11 bits per symbol)

The baud rate is a little over 9600 baud (I get 9620 but the precise value depends on how good the clock on your Arduino is, in any case it's close enough to 9600 to call it 9600).

Connect it to a UART and you'll see a "break" symbol followed by a brief pause and several data symbols.

I don't know what the actual data bits mean

\$\endgroup\$
3
\$\begingroup\$

I doubt that playback will work. My guess is the protocol uses a similar protection as the rolling code method, and the initial character is identical each time. @Jasen said it is UART protocol, which I agree, from the newly decoded values for Run1. At least the first six characters seem to be error free (break/start/data/stop). Breaks can be any length of time.

enter image description here

Also, I'm guessing the wired protocol that you captured simply mimics the protocol used with the wireless RF (a simple carrier modulation), which most certainly uses a security code for protection. This would explain why the playback doesn't work.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ I'm not yet convinced that the wired button is using a rolling code. I powered on the opener and one wired button. Pressed the button to cycle the opener. Then I plugged in a second wired button - the second button is able to also cycle the opener. I would think if it were using rolling code the button would have to be linked with the opener, and at the very least would not work unless it was plugged in during the power on phase so the opener could sync the key with all wired buttons. \$\endgroup\$ Commented Dec 11, 2021 at 22:49
  • \$\begingroup\$ Rolling codes can be captured and played back as long as the receiver doesn't see it first. This is a known vulnerability with some remotes (RF) but not wired since it would require access to the wire (in house). \$\endgroup\$ Commented Dec 11, 2021 at 23:23
  • \$\begingroup\$ I have to retract my previous comment. I was missing the handshake. When plugging in a second button, there is a delay before the button sends a message and the opener replies. \$\endgroup\$ Commented Dec 14, 2021 at 0:49
  • \$\begingroup\$ The wireless remote uses Security+ 2.0. There is a software python implementation on github: github.com/argilo/secplus \$\endgroup\$ Commented Dec 22, 2021 at 16:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.