diyhue / diyHue

Main diyHue software repo
https://diyhue.org/
Other
1.52k stars 274 forks source link

Security fix: RCE for ikea_tradfri calls #105 #888

Closed 7FM closed 1 year ago

7FM commented 1 year ago

(The PR is currently based on https://github.com/diyhue/diyHue/pull/887, but I could rebase it to master in case https://github.com/diyhue/diyHue/pull/887 won't be merged.)

Small PoC:

  1. open diyhue in the browser & log in
  2. go to the tradfri tab
  3. enter into the Security Code field: "; >&2 echo "PWNED" ; false && "
  4. push the pair button

A vulnerable host will produce approximately the following logs:

diyHue  | {'identity': '32',
diyHue  |  'tradfriCode': '"; >&2 echo "PWNED" ; false && "',
diyHue  |  'tradfriGwIp': '192.168.x.x'}
diyHue  | coap-client-gnutls v4.2.1 -- a small CoAP implementation
diyHue  | Copyright (C) 2010-2019 Olaf Bergmann <bergmann@tzi.org> and others
diyHue  |
diyHue  | TLS Library: GnuTLS - runtime 3.7.1, libcoap built for 3.6.10
diyHue  |
diyHue  | Usage: coap-client-gnutls [-a addr] [-b [num,]size] [-e text] [-f file] [-l loss]
diyHue  |       [-m method] [-o file] [-p port] [-r] [-s duration] [-t type]
diyHue  |       [-v num] [-A type] [-B seconds] [-K interval] [-N] [-O num,text]
diyHue  |       [-P addr[:port]] [-T token] [-U]
diyHue  |       [[-k key] [-u user]]
diyHue  |       [[-c certfile] [-C cafile] [-R root_cafile]] URI
diyHue  |
diyHue  |   URI can be an absolute URI or a URI prefixed with scheme and host
diyHue  |
diyHue  | General Options
diyHue  |   -a addr     The local interface address to use
diyHue  |   -b [num,]size   Block size to be used in GET/PUT/POST requests
diyHue  |               (value must be a multiple of 16 not larger than 1024)
diyHue  |               If num is present, the request chain will start at
diyHue  |               block num
diyHue  |   -e text     Include text as payload (use percent-encoding for
diyHue  |               non-ASCII characters)
diyHue  |   -f file     File to send with PUT/POST (use '-' for STDIN)
diyHue  |   -l list     Fail to send some datagrams specified by a comma
diyHue  |               separated list of numbers or number ranges
diyHue  |               (for debugging only)
diyHue  |   -l loss%    Randomly fail to send datagrams with the specified
diyHue  |               probability - 100% all datagrams, 0% no datagrams
diyHue  |   -m method   Request method (get|put|post|delete|fetch|patch|ipatch),
diyHue  |               default is 'get'
diyHue  |   -o file     Output received data to this file (use '-' for STDOUT)
diyHue  |   -p port     Listen on specified port
diyHue  |   -r          Use reliable protocol (TCP or TLS)
diyHue  |   -s duration Subscribe to / Observe resource for given duration
diyHue  |               in seconds
diyHue  |   -t type     Content format for given resource for PUT/POST
diyHue  |   -v num      Verbosity level (default 3, maximum is 9). Above 7,
diyHue  |               there is increased verbosity in GnuTLS logging
diyHue  |   -A type     Accepted media type
diyHue  |   -B seconds  Break operation after waiting given seconds
diyHue  |               (default is 90)
diyHue  |   -K interval send a ping after interval seconds of inactivity
diyHue  |   -N          Send NON-confirmable message
diyHue  |   -O num,text Add option num with contents text to request. If the
diyHue  |               text begins with 0x, then the hex text is converted to
diyHue  |               binary data
diyHue  |   -P addr[:port]  Use proxy (automatically adds Proxy-Uri option to
diyHue  |               request)
diyHue  |   -T token    Include specified token
diyHue  |   -U          Never include Uri-Host or Uri-Port options
diyHue  | PSK Options (if supported by underlying (D)TLS library)
diyHue  |   -k key      Pre-shared key for the specified user
diyHue  |   -u user     User identity for pre-shared key mode
diyHue  | PKI Options (if supported by underlying (D)TLS library)
diyHue  |   -c certfile PEM file containing both CERTIFICATE and PRIVATE KEY
diyHue  |               This argument requires (D)TLS with PKI to be available
diyHue  |   -C cafile   PEM file containing the CA Certificate that was used to
diyHue  |               sign the certfile. This will trigger the validation of
diyHue  |               the server certificate.  If certfile is self-signed (as
diyHue  |               defined by '-c certfile'), then you need to have on the
diyHue  |               command line the same filename for both the certfile and
diyHue  |               cafile (as in '-c certfile -C certfile') to trigger
diyHue  |               validation
diyHue  |   -R root_cafile  PEM file containing the set of trusted root CAs that
diyHue  |               are to be used to validate the server certificate.
diyHue  |               The '-C cafile' does not have to be in this list and is
diyHue  |               'trusted' for the verification.
diyHue  |               Alternatively, this can point to a directory containing
diyHue  |               a set of CA PEM files
diyHue  |
diyHue  | Examples:
diyHue  |   coap-client -m get coap://[::1]/
diyHue  |   coap-client -m get coap://[::1]/.well-known/core
diyHue  |   coap-client -m get coap+tcp://[::1]/.well-known/core
diyHue  |   coap-client -m get coaps://[::1]/.well-known/core
diyHue  |   coap-client -m get coaps+tcp://[::1]/.well-known/core
diyHue  |   coap-client -m get -T cafe coap://[::1]/time
diyHue  |   echo -n 1000 | coap-client -m put -T cafe coap://[::1]/time -f -
diyHue  | PWNED

Note the last line! The echo command got executed. Here is the log of a patched host:

diyHue  | {'identity': '32',
diyHue  |  'tradfriCode': '"; >&2 echo "PWNED" ; false && "',
diyHue  |  'tradfriGwIp': '192.168.x.x'}
diyHue  | getaddrinfo: Name or service not known
diyHue  | failed to resolve address
Mevel commented 1 year ago

Let's implement the rce fix first and then have a look into the other pr.

Thank you very much for that fix!

7FM commented 1 year ago

Let's implement the rce fix first and then have a look into the other pr.

Done, it is based on master now :)

mariusmotea commented 1 year ago

I trust your tests since I cannot test