the home site for me: also iteration 3 or 4 of my site
1+++ 2title = "Hilton Tomfoolery" 3date = 2024-10-13 4slug = "hilton-tomfoolery" 5description = "Playing around with mitmproxy and the Hilton Honors app as well as a flipper zero" 6 7[taxonomies] 8tags = ["reverse engineering", "hilton"] 9+++ 10 11I'm at a Hilton at the time of writing this, and I'm decently bored. Currently, I'm downloading the latest version of RogueMaster (0.420.0) to my flipper, as it is currently crashing every time I open the NFC app. My dad tried out the app unlock feature in the Hilton app for the first time today, which, as most new tech things, made me quite curious how it worked and whether I could break it. Based on playing with it, there seems to be a proximity reading (over Bluetooth? Perhaps a BLE beacon?) to detect if you are by your door but for a period of time (~20 sec) after getting that signal it allows you to unlock the door from across the room which I'm guessing means that it controls the locks via a central server. The current plan is to install the root cert (of mitmproxy) on my iPhone and then try and intercept those API calls and see if we can manipulate them in any interesting ways. I'm also planning on live blogging this, which I've never tried before. (I also wrote this whole article in vim ^_^) 12 13<!-- more --> 14 15## Connecting to Mitmproxy 16 17I'm connecting over WireGuard, so I fired up mitmproxy with `mitmweb --mode wireguard` on my laptop. Connecting via WireGuard theoretically is pretty simple; all I need to do is to scan a qr code and connect. Unfortunately, the hotel Wi-Fi seems to be oddly segmented, and I can't access the WireGuard server or ping my laptop from my phone. I'm going to try firing up a hot spot on my dad's phone and see if that allows me to talk to my phone. 18 19![screenshot of the root certificate install process](https://hc-cdn.hel1.your-objectstorage.com/s/v3/29c856921e88c31bfc2e2d73d09d287ce4aa149a_2install_profile.png){caption="You have to dig through several menus to trust it"} 20 21I messed with getting my laptop to connect to my dad's phone, but it kept refusing for some reason. My next idea is to ngrok the WireGuard tunnel, which ended up failing because ngrok doesn't support UDP. Finally, after an embarrassingly long time, I realized that I could simply use `ngrok tcp 8080` and the HTTP proxy server built into mitmproxy instead. After installing the root certificate and trusting it in the iPhone settings, we were good to go! 22 23## Digging around in the Hilton Honors app 24 25First I had to download the app, which required disabling the proxy as iOS seems to ignore certificate trust settings for the app store. Enrollment happened via the `https://m.hilton.io/graphql/customer?operationName=createGuest&type=enroll` endpoint and was as follows: 26 27> POST 28```json 29{ 30 "query": "...", 31 "variables": { 32 "input": { 33 "email": { 34 "emailAddress": "xxxx-xxxx-xxxx@duck.com" 35 }, 36 "preferredLanguage": "EN", 37 "enrollSourceCode": "IOSEW", 38 "phone": { 39 "phoneNumber": "xxxxxxxxxx", 40 "phoneType": "home" 41 }, 42 "subscriptions": { 43 "hhonorsSubscriptions": [], 44 "optOuts": { 45 "survey": false, 46 "marketing": false 47 } 48 }, 49 "name": { 50 "firstName": "Kieran", 51 "lastName": "Klukas" 52 }, 53 "address": { 54 "city": "Washington", 55 "addressType": "home", 56 "addressLine2": null, 57 "postalCode": "20003", 58 "state": "DC", 59 "addressLine1": "1600 Pennsylvania Ave SE Apartments", 60 "country": "US" 61 }, 62 "privacyRequested": false, 63 "password": "xxxxxxxxxxxxxxxxxxxxxxxxxxx" 64 }, 65 "language": "en_US" 66 }, 67 "operationName": "createGuest" 68} 69``` 70```bash 71--- 72mutation createGuest($input: EnrollInput!, $language: String!) { 73 createGuest(language: $language, input: $input) { 74 data { 75 guestId 76 hhonorsNumber 77 } 78 error { 79 code 80 context 81 message 82 notifications { 83 code 84 fields 85 message 86 } 87 } 88 } 89} 90``` 91<br/> 92 93> response 94 95```json 96{ 97 "data": { 98 "createGuest": { 99 "data": { 100 "guestId": 1726240000, 101 "hhonorsNumber": "225782xxxx" 102 }, 103 "error": null 104 } 105 }, 106 "extensions": { 107 "logSearch": "mdc.client_message_id=51da35305bde9b71e7faa2993ebc2a619e50c598-iap71t195vk6jur6eyd83hy9g21w4bzam" 108 } 109} 110``` 111<br/> 112 113> headers 114 115```json 116{ 117 "access_token": "DX.eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00iLCJwaWQiOiJtb2JpbGUiLCJraWQiOiJWTktOaU9WLTZ4c2cyOXQ2dEJUMmR5Nnl1TEJPUG8tb2FycDFpZzZnVWdZIn0.Yfxkp8Jnrwttmrp_QcMTp6HwW2yBzEIROsAjheNVd3LgIWBQVfw5UDstAd7qA3MKZffoKSf7SbkopJhWIr-vreOYQ2BZEf2a9DYm4p-tD9jXEMsuVY9offYqjRzyeWwcjLyWq9ubnUBpQuCHMNUO1025BZkNV3NYG3_LZfJlNc77aMawrfS52zi5I5hSL0zAs3K7kxYuReJEC-RzASt-coPHEmdkmDp1TLqujqe8Opy6z4DC8xFDFkO09J-tN6RwolJ6jtssr0vnFyCv9zw_lbAQppB0jbWZqxiEmNk_krC4laOsChe3bUJc8ECeKltvqgVnSAKAhz-zBfy9EbFeew.Wki3N1rclvnjMfA4.dtWVnkpMJZixW86Q9hiiBY30_Oa1NHPLM_SuuAjtTrY-QZilp5tgu7COJtiVYI51_j6nIOHdX2oI0EoiHaPhzC4YizFxNbZsUfpR0W6wPVWj3LpdTr23GMhoOga5UTFCbaehb5XCsWr9PLfnLc2tSGyi4wZOSGrSidQUCDQ6UssUTxt6vvlp5y623EbvkMEi-ok6IXqUnYgsztcz_i14GKRHdRmJZFACJj3X0zQLarN4b19KEwvqIXfIrpPWpr1f74ozamM6CUEQhqoF61cucKCxKf0hU7kAyMduo4l3OfEkghQUfrlfA1D7eoInyPcOb8a3_LjQhGXwh1XVoElXUriuP7yEOfyksv59_pKCWajzJuyWdEl164OZXAFmMkdQ89flDO3_nRZUliMXapnWkU3WDBGD_gQ49sYbxlAh95l0HiJeKZwf2g4DTlEb6ccauRAbUzD2Fopoe2ldMXL-wBkVg2Grx8SfaCnOCiyfGq2HloJMf-8YRz-tWQoTXFEM30KdJCWY70sUTY9LeWVQrz4dnpZlRk29KyNi20YsdQRK3y9_ZFL0qs4IJwhddtrhzQVKz6oaxDPgQxy2vK1DErers-8-oJ3WgDho9l9D7Z7U9C1spjf1IIBG5hvdtCiExqh78fFsizcvkG9oeHB09Z1oGU3jL_cUFKrrUp9ZXnOKlwU1BjFPrOjVVZi97-rVN3IjvlRjJCBfFCf2CxlbZcib_CWSiD0vtFsloClkmSho2ynnbLQG341SibvaO4TKygttS-NsluDjBtpuJydlNjDAXO6ZvWRiFWcHDrDqiBeo897yUM40kHYFXBpjhbiIDcCnAJu6GDozbacnGsEGOJlauASm3t8TFn1lPd_kQgd3Uy2fDtTCKxxSaXA4RvHwUbBgYWU4SMA7UPYn_RygkxUZ0UL4ZHfN1-bDpkQ16DLm0Q.hh53MImM9BA7Ujib61RUOg", 118 "exp": 1728879203, 119 "expires_in": 3600, 120 "iat": 1728875603, 121 "scope": "am_application_scope default", 122 "token_type": "Bearer" 123} 124``` 125 126At this point I went to bed as it was about 23:30, but I set my alarm for 5:30 (if you know me I never get up before 8:00, so this is rare) and actually managed to wake-up on time. It's always quite curious how excitement and a new place can cause you to wake-up earlier. Unfortunately, while I was sleeping my laptop died which caused me to lose the rest of the signup data. I'm going to invite myself to get the room key and see what API requests that triggers, and then try actually unlocking the door. 127 128# Invitation 129 130> Hi Kieran, 131> I’m sharing my Digital Key so you can use your phone as a room key. 132> If you already have the Hilton Honors app make sure you are on the latest version and click this https://hiltonhonors3.hilton.com/rs/hilton-honors-mobile-app?shareId=b4d6140d311e4c4c935dd653ca00af65 to accept the Digital Key. 133> If you don’t have the Hilton Honors app, download it using the link above and return to this message to accept within 8 hours to get your key. 134> See you soon, 135> xxxx xxxx 136 137I shared the key which asked for a name and then opened the iOS share sheet and I choose to send by text (it sent the above message). I went back to my phone, clicked the link and low and behold we got a hit! `https://hms.hiltonapi.com/hms/v1/digitalkey/invitation/accept`: 138 139> POST 140```json 141{ 142 "shareId": "b4d6140d311e4c4c935dd653ca00af65" 143} 144``` 145 146<br/> 147 148> response 149```json 150{ 151 "arrivalDateTime": "2024-10-13T15:00-04:00", 152 "confirmationNumber": "5448xxxx", 153 "ctyhocn": "GCYPAHX", 154 "departureDateTime": "2024-10-14T11:00-04:00", 155 "hotelName": "Hampton Inn & Suites Grove City", 156 "stayId": "296088xxxx" 157} 158``` 159 160Another interesting request was to `https://m.hilton.io/graphql/customer?operationName=hotel_brand&type=hotelDetails_GCYPAHX` 161 162> POST 163```json 164{ 165 "variables": { 166 "ctyhocn": "GCYPAHX", 167 "language": "en-US" 168 }, 169 "operationName": "hotel_brand", 170 "query": "..." 171} 172``` 173```bash 174--- 175query hotel_brand($language: String!, $ctyhocn: String!) { 176 hotel(language: $language, ctyhocn: $ctyhocn) { 177 address { 178 addressFmt 179 addressLine1 180 addressLine2 181 city 182 country 183 countryName 184 postalCode 185 state 186 } 187 alerts { 188 description 189 type 190 } 191 amenities { 192 id 193 name 194 } 195 attributes { 196 numberOfRestaurants 197 } 198 brand { 199 isPartnerBrand 200 } 201 brandCode 202 campus { 203 type 204 } 205 chainCode 206 checkin { 207 checkinTimeFmt 208 checkinTime 209 checkoutTimeFmt 210 checkoutTime 211 digitalKey 212 } 213 config { 214 checkout { 215 allowDCO 216 } 217 connectedRoom { 218 crEnabled 219 crFullyEnabled 220 emsEnabled 221 } 222 messaging { 223 kipsuEnabled 224 messagingTileEnabled 225 gatewayRoutingEnabled 226 } 227 adjoiningRooms { 228 active 229 } 230 } 231 coordinate { 232 latitude 233 longitude 234 } 235 crsData { 236 adultAge 237 ageBasedPricing 238 acceptedCreditCards 239 } 240 ctyhocn 241 currencyCode 242 display { 243 treatments 244 } 245 gmtHours 246 internetAddress 247 name 248 phoneNumber 249 policyOptions { 250 label 251 value 252 options { 253 label 254 value 255 } 256 } 257 facilityOverview { 258 shortDesc 259 } 260 images { 261 master { 262 altText 263 url(height: 430, width: 612) 264 } 265 gallery { 266 image(variant: searchPropertyImageThumbnail) { 267 altText 268 url(height: 430, width: 612) 269 } 270 masterImage 271 } 272 carousel { 273 altText 274 url(height: 430, width: 612) 275 } 276 } 277 } 278} 279``` 280 281<br/> 282 283> response 284```json 285{ 286 "data": { 287 "hotel": { 288 "address": { 289 "addressFmt": "4 Holiday Blvd., Mercer, Pennsylvania, 16137, USA", 290 "addressLine1": "4 Holiday Blvd.", 291 "addressLine2": null, 292 "city": "Mercer", 293 "country": "US", 294 "countryName": "USA", 295 "postalCode": "16137", 296 "state": "PA" 297 }, 298 "alerts": [ 299 { 300 "description": "The hotel will be undergoing exterior renovations September 03, 2024 - December 31, 2024. The interior and guestrooms will be unaffected. Thank you for your patience and understanding.", 301 "type": "alert" 302 } 303 ], 304 "amenities": [ 305 { 306 "id": "adjoiningRooms", 307 "name": "Connecting Rooms" 308 }, 309 { 310 "id": "freeBreakfast", 311 "name": "Free hot breakfast" 312 }, 313 { 314 "id": "freeParking", 315 "name": "Free parking" 316 }, 317 { 318 "id": "freeWifi", 319 "name": "Free WiFi" 320 }, 321 { 322 "id": "nonSmoking", 323 "name": "Non-smoking rooms" 324 }, 325 { 326 "id": "digitalKey", 327 "name": "Digital Key" 328 }, 329 { 330 "id": "evCharging", 331 "name": "EV charging" 332 }, 333 { 334 "id": "indoorPool", 335 "name": "Indoor pool" 336 }, 337 { 338 "id": "fitnessCenter", 339 "name": "Fitness center" 340 }, 341 { 342 "id": "petsAllowed", 343 "name": "Pet-friendly rooms" 344 }, 345 { 346 "id": "meetingRooms", 347 "name": "Meeting rooms" 348 } 349 ], 350 "attributes": { 351 "numberOfRestaurants": 0 352 }, 353 "brand": { 354 "isPartnerBrand": false 355 }, 356 "brandCode": "HP", 357 "campus": { 358 "type": "enhanced" 359 }, 360 "chainCode": "HH", 361 "checkin": { 362 "checkinTime": "15:00", 363 "checkinTimeFmt": "3:00 PM", 364 "checkoutTime": "11:00", 365 "checkoutTimeFmt": "11:00 AM", 366 "digitalKey": true 367 }, 368 "config": { 369 "adjoiningRooms": { 370 "active": true 371 }, 372 "checkout": { 373 "allowDCO": true 374 }, 375 "connectedRoom": null, 376 "messaging": { 377 "gatewayRoutingEnabled": true, 378 "kipsuEnabled": true, 379 "messagingTileEnabled": true 380 } 381 }, 382 "coordinate": { 383 "latitude": 41.142354, 384 "longitude": -80.164956 385 }, 386 "crsData": { 387 "acceptedCreditCards": [ 388 "CU", 389 "VI", 390 "MC", 391 "AX", 392 "DS", 393 "DC", 394 "CB" 395 ], 396 "adultAge": null, 397 "ageBasedPricing": null 398 }, 399 "ctyhocn": "GCYPAHX", 400 "currencyCode": "USD", 401 "display": { 402 "treatments": [] 403 }, 404 "facilityOverview": { 405 "shortDesc": "We're off I-79, 10 minutes from Grove City. Grove City Premium Outlets and Wendell August Forge, America's oldest and largest working forge, are less than a mile away. Both Grove City College and Slippery Rock University are within 20 minutes of us. Enjoy free hot breakfast, free WiFi, and our indoor pool and hot tub." 406 }, 407 "gmtHours": -4, 408 "images": { 409 "carousel": [ 410 { 411 "altText": "Outdoor Patio", 412 "url": "https://www.hilton.com/im/en/GCYPAHX/2888809/gcypahx-patio.jpg?impolicy=resize&rh=430&rw=612" 413 }, 414 { 415 "altText": "Double Queen", 416 "url": "https://www.hilton.com/im/en/GCYPAHX/4248848/hampton-grove-city-standard-queen-1-preview.jpg?impolicy=resize&rh=430&rw=612" 417 }, 418 { 419 "altText": "King Standard", 420 "url": "https://www.hilton.com/im/en/GCYPAHX/4248016/hampton-grove-city-king-standard-1.jpg?impolicy=resize&rh=430&rw=612" 421 }, 422 { 423 "altText": "Lobby and Dining Area", 424 "url": "https://www.hilton.com/im/en/GCYPAHX/2887422/lobby-1.jpg?impolicy=resize&rh=430&rw=612" 425 }, 426 { 427 "altText": "Lobby", 428 "url": "https://www.hilton.com/im/en/GCYPAHX/2887224/lobby-2.jpg?impolicy=resize&rh=430&rw=612" 429 }, 430 { 431 "altText": "Breakfast Buffet", 432 "url": "https://www.hilton.com/im/en/GCYPAHX/2880542/breakfast-1.jpg?impolicy=resize&rh=430&rw=612" 433 }, 434 { 435 "altText": "Indoor Pool", 436 "url": "https://www.hilton.com/im/en/GCYPAHX/4258295/hampton-new-pics-2008-035.jpg?impolicy=resize&rh=430&rw=612" 437 }, 438 { 439 "altText": "Fitness Center", 440 "url": "https://www.hilton.com/im/en/GCYPAHX/2883297/fitness.jpg?impolicy=resize&rh=430&rw=612" 441 }, 442 { 443 "altText": "Boardroom", 444 "url": "https://www.hilton.com/im/en/GCYPAHX/2879933/board-room.jpg?impolicy=resize&rh=430&rw=612" 445 }, 446 { 447 "altText": "Meeting Room", 448 "url": "https://www.hilton.com/im/en/GCYPAHX/2888194/meeting.jpg?impolicy=resize&rh=430&rw=612" 449 }, 450 { 451 "altText": "Hotel Exterior at Night", 452 "url": "https://www.hilton.com/im/en/GCYPAHX/4251655/exterior-night.jpg?impolicy=resize&rh=430&rw=612" 453 }, 454 { 455 "altText": "Business Center", 456 "url": "https://www.hilton.com/im/en/GCYPAHX/2881016/business-center.jpg?impolicy=resize&rh=430&rw=612" 457 } 458 ], 459 "gallery": [ 460 { 461 "image": { 462 "altText": "Outdoor Patio", 463 "url": "https://www.hilton.com/im/en/GCYPAHX/2888809/gcypahx-patio.jpg?impolicy=resize&rh=430&rw=612" 464 }, 465 "masterImage": true 466 }, 467 { 468 "image": { 469 "altText": "Double Queen", 470 "url": "https://www.hilton.com/im/en/GCYPAHX/4248848/hampton-grove-city-standard-queen-1-preview.jpg?impolicy=resize&rh=430&rw=612" 471 }, 472 "masterImage": false 473 }, 474 { 475 "image": { 476 "altText": "King Standard", 477 "url": "https://www.hilton.com/im/en/GCYPAHX/4248016/hampton-grove-city-king-standard-1.jpg?impolicy=resize&rh=430&rw=612" 478 }, 479 "masterImage": false 480 }, 481 { 482 "image": { 483 "altText": "Lobby and Dining Area", 484 "url": "https://www.hilton.com/im/en/GCYPAHX/2887422/lobby-1.jpg?impolicy=resize&rh=430&rw=612" 485 }, 486 "masterImage": false 487 }, 488 { 489 "image": { 490 "altText": "Lobby", 491 "url": "https://www.hilton.com/im/en/GCYPAHX/2887224/lobby-2.jpg?impolicy=resize&rh=430&rw=612" 492 }, 493 "masterImage": false 494 }, 495 { 496 "image": { 497 "altText": "Breakfast Buffet", 498 "url": "https://www.hilton.com/im/en/GCYPAHX/2880542/breakfast-1.jpg?impolicy=resize&rh=430&rw=612" 499 }, 500 "masterImage": false 501 }, 502 { 503 "image": { 504 "altText": "Indoor Pool", 505 "url": "https://www.hilton.com/im/en/GCYPAHX/4258295/hampton-new-pics-2008-035.jpg?impolicy=resize&rh=430&rw=612" 506 }, 507 "masterImage": false 508 }, 509 { 510 "image": { 511 "altText": "Fitness Center", 512 "url": "https://www.hilton.com/im/en/GCYPAHX/2883297/fitness.jpg?impolicy=resize&rh=430&rw=612" 513 }, 514 "masterImage": false 515 }, 516 { 517 "image": { 518 "altText": "Boardroom", 519 "url": "https://www.hilton.com/im/en/GCYPAHX/2879933/board-room.jpg?impolicy=resize&rh=430&rw=612" 520 }, 521 "masterImage": false 522 }, 523 { 524 "image": { 525 "altText": "Meeting Room", 526 "url": "https://www.hilton.com/im/en/GCYPAHX/2888194/meeting.jpg?impolicy=resize&rh=430&rw=612" 527 }, 528 "masterImage": false 529 }, 530 { 531 "image": { 532 "altText": "Hotel Exterior at Night", 533 "url": "https://www.hilton.com/im/en/GCYPAHX/4251655/exterior-night.jpg?impolicy=resize&rh=430&rw=612" 534 }, 535 "masterImage": false 536 }, 537 { 538 "image": { 539 "altText": "Business Center", 540 "url": "https://www.hilton.com/im/en/GCYPAHX/2881016/business-center.jpg?impolicy=resize&rh=430&rw=612" 541 }, 542 "masterImage": false 543 }, 544 { 545 "image": { 546 "altText": "Indoor Pool / Whirlpool", 547 "url": "https://www.hilton.com/im/en/GCYPAHX/2885342/pool.jpg?impolicy=resize&rh=430&rw=612" 548 }, 549 "masterImage": false 550 }, 551 { 552 "image": { 553 "altText": "Double Queen Studio", 554 "url": "https://www.hilton.com/im/en/GCYPAHX/4250170/hampton-new-pics-2008-020.jpg?impolicy=resize&rh=430&rw=612" 555 }, 556 "masterImage": false 557 }, 558 { 559 "image": { 560 "altText": "Whirlpool Suite", 561 "url": "https://www.hilton.com/im/en/GCYPAHX/4251204/whirlpool-king-suite-one-2-2-.jpg?impolicy=resize&rh=430&rw=612" 562 }, 563 "masterImage": false 564 }, 565 { 566 "image": { 567 "altText": "Breakfast Area", 568 "url": "https://www.hilton.com/im/en/GCYPAHX/2880342/breakfast-2.tif?impolicy=resize&rh=430&rw=612" 569 }, 570 "masterImage": false 571 }, 572 { 573 "image": { 574 "altText": "Suite Shop", 575 "url": "https://www.hilton.com/im/en/GCYPAHX/2890823/gift-shop.jpg?impolicy=resize&rh=430&rw=612" 576 }, 577 "masterImage": false 578 }, 579 { 580 "image": { 581 "altText": "Hotel Exterior", 582 "url": "https://www.hilton.com/im/en/GCYPAHX/390670/gcypahx-hampton-exterior-night-1.jpg?impolicy=resize&rh=430&rw=612" 583 }, 584 "masterImage": false 585 }, 586 { 587 "image": { 588 "altText": "Hotel Exterior", 589 "url": "https://www.hilton.com/im/en/GCYPAHX/4255766/hampton-new-pics-2008-012.jpg?impolicy=resize&rh=430&rw=612" 590 }, 591 "masterImage": false 592 }, 593 { 594 "image": { 595 "altText": "Double Queen Suite", 596 "url": "https://www.hilton.com/im/en/GCYPAHX/4251117/double-queen-standard-2-.jpg?impolicy=resize&rh=430&rw=612" 597 }, 598 "masterImage": false 599 } 600 ], 601 "master": { 602 "altText": "Outdoor Patio", 603 "url": "https://www.hilton.com/im/en/GCYPAHX/2888809/gcypahx-patio.jpg?impolicy=resize&rh=430&rw=612" 604 } 605 }, 606 "internetAddress": "https://www.hilton.com/en/hotels/gcypahx-hampton-suites-grove-city/", 607 "name": "Hampton Inn & Suites Grove City", 608 "phoneNumber": "+1 724-748-5744", 609 "policyOptions": [ 610 { 611 "label": "Cancellation", 612 "options": [ 613 { 614 "label": "Description", 615 "value": "Cancellation policies may vary depending on the rate or dates of your reservation. Please refer to your reservation confirmation to verify your cancellation policy. If you need further assistance, call the hotel directly or contact <a href=https://help.hilton.com/s/>customer service</a>. Alternatively, you can <a href=https://www.hilton.com/en/book/reservation/find/>cancel your reservation online</a>." 616 } 617 ], 618 "value": null 619 }, 620 { 621 "label": "Check-in/Check-out", 622 "options": [ 623 { 624 "label": "Checkin Time", 625 "value": "3:00 PM" 626 }, 627 { 628 "label": "Checkout Time", 629 "value": "11:00 AM" 630 }, 631 { 632 "label": "Early Departure Fee", 633 "value": null 634 }, 635 { 636 "label": "Late Checkout Fee", 637 "value": null 638 }, 639 { 640 "label": "Minimum Age To Register", 641 "value": "21" 642 } 643 ], 644 "value": null 645 }, 646 { 647 "label": "Wi-Fi", 648 "options": [ 649 { 650 "label": "Description", 651 "value": "Standard In-Room and Lobby Wi-Fi - All guests get free standard Wi-Fi in-room and in the lobby." 652 } 653 ], 654 "value": null 655 }, 656 { 657 "label": "Parking", 658 "options": [ 659 { 660 "label": "Covered", 661 "value": "Not Available" 662 }, 663 { 664 "label": "In Out Privileges", 665 "value": "Not Available" 666 }, 667 { 668 "label": "Other Parking Information", 669 "value": "Parking Lot" 670 }, 671 { 672 "label": "Secured", 673 "value": "Not Available" 674 }, 675 { 676 "label": "Self Parking", 677 "value": "$0.00 Complimentary" 678 }, 679 { 680 "label": "Valet Parking", 681 "value": "Not Available" 682 } 683 ], 684 "value": null 685 }, 686 { 687 "label": "Payment", 688 "options": [ 689 { 690 "label": "Hotel Currency", 691 "value": "US Dollar" 692 }, 693 { 694 "label": "Accepted Payment Options", 695 "value": "American Express, Carte Blanche, China Union Pay, Diner's Club, Discover, MasterCard, Visa" 696 } 697 ], 698 "value": null 699 }, 700 { 701 "label": "Pets", 702 "options": [ 703 { 704 "label": "Deposit", 705 "value": "$50.00 Non-Refundable" 706 }, 707 { 708 "label": "Kennel Message", 709 "value": null 710 }, 711 { 712 "label": "Maximum Size", 713 "value": null 714 }, 715 { 716 "label": "Maximum Weight", 717 "value": null 718 }, 719 { 720 "label": "Other Pet Services", 721 "value": "$50(1-4n),$75(5+n) 2petsMax,dog/cat only" 722 }, 723 { 724 "label": "Pets Allowed", 725 "value": "Yes" 726 }, 727 { 728 "label": "Service Animals Allowed", 729 "value": "Yes" 730 } 731 ], 732 "value": null 733 }, 734 { 735 "label": "Smoking", 736 "options": [ 737 { 738 "label": "Indicator", 739 "value": "Non-Smoking" 740 }, 741 { 742 "label": "Description", 743 "value": null 744 } 745 ], 746 "value": null 747 } 748 ] 749 } 750 }, 751 "extensions": { 752 "logSearch": "mdc.client_message_id=51da35305bde9b71e7faa2993ebc2a619e50c598-uauhdwbaydoqbvy3uvuzai20c4takt22" 753 } 754} 755``` 756 757It appears that Hilton relies very heavily on GraphQL, which is interesting. I would be interested in playing with those APIs more. For now, though, onto unlocking stuff! 758 759## Locks 760 761![screenshot of the hotel digital key](https://hc-cdn.hel1.your-objectstorage.com/s/v3/06dcbd4c5166d7f17e31027b687f32539d68aa44_0hotel-key.png){caption="What it looks like in the app"} 762 763When using the unlock button, it made a request to this URL: `https://smetric.hilton.com/b/ss/hiltonglobalprod/10/IOSN030200030900/s65425920` with a payload of a URL encoded form. 764 765> POST 766```yaml 767ndh: 1 768cid.: 769card_no.: 770as: 0 771id: 2257829743 772.card_no: 773hhid.: 774as: 1 775id: 2257829743 776.hhid: 777.cid: 778aamb: j8Odv6LonN4r3an7LhD3WZrU1bUpAkFkkiY1ncBR96t2PTI 779aamlh: 7 780c.: 781a.: 782AppID: HHonors 2024.10.1 (1) 783CarrierName: -- 784DeviceName: iPhone14,4 785OSVersion: iOS 18.1 786Resolution: 1125x2436 787RunMode: Application 788TimeSinceLaunch: 24560 789action: digital key:key:unlock_btn 790.a: 791hm.: 792app.: 793name: HHonors iOS Mobile 794.app: 795digitalkeyflag: Yes 796event.: 797element.: 798click: digital key:key:unlock_btn 799.element: 800key.: 801unlock.: 802initiate: 1 803.unlock: 804.key: 805.event: 806flag.: 807appsettings: N|N|NA|N|Y|Y|Y|Y|Y|NA|UsingApp|N| 808orientation: L 809stay.: 810level.: 811status: In-Stay 812.level: 813.stay: 814timeCaptureAEP: 2024-10-14T09:59:44.676Z 815timeCaptureEpoch: 1728899984 816timeCaptureISO: 2024-10-14T05:59:44-0400 817.flag: 818hotel.: 819brand: HP 820propertycode: GCYPAHX 821.hotel: 822key.: 823gnr: 79125065 824locktype: guest 825lsn: 92044507 826shared.: 827flag: Yes 828.shared: 829.key: 830page.: 831name: 832previous: App:EN:Honors:Digital Key:Key 833.page: 834purchase.: 835booking.: 836dates: 10132024:10142024:1 837.booking: 838bookingid: 54486330 839.purchase: 840site.: 841type: PA 842.site: 843user.: 844aam.: 845segments: 15218869,26458327,19493122,21537957,22516131,17952857,23583601,17952894,19484989,21539153,22889861,21539313,26458383,21881915,15217574 846.aam: 847language: en 848login.: 849status: Logged-in 850.login: 851memberId: 2257829743 852stayid: 2960880196 853tierpoints: Member 854.user: 855.hm: 856.c: 857ce: UTF-8 858cp: foreground 859d.ptfm: ios 860mid: 61621496110939688115558742623055817571 861pageName: HHonors 2024.10.1 (1) 862pe: lnk_o 863pev2: AMACTION:digital key:key:unlock_btn 864products: ;GCYPAHX;;;; 865t: 00/00/0000 00:00:00 0 240 866ts: 1728899984 867``` 868 869<br/> 870 871> response 872```json 873 { 874 "stuff":[ { 875 "cn":"TMS","cv":"web=17836315,Web-app=15217574,Web-app=17952857,Web-app=17952894,web-app=19493122,web-app=19484989,web-app=21539153,web-app=21539313,web-app=21881915,web-app=22516131,web-app=22889861,web-app=23583601,web-app=15218869,web-app=26458327,web-app=26458383,web-app=21537957","ttl":30,"dmn":"" 876 } 877 , { 878 "cn":"fltk","cv":"segID=15218869","ttl":30,"dmn":"" 879 } 880 ],"uuid":"61645808922583835885560882535048239660","dcs_region":7,"tid":"RufgJCfxTjg=" 881} 882``` 883 884About a second afterward, I get a second request to `https://smetric.hilton.com/b/ss/hiltonglobalprod/10/IOSN030200030900/s88785229` with similar form data. Diff shown below. 885 886> POST.diff 887```diff 88823c23 889< action: digital key:key:unlock_btn 890--- 891> action: digital key:key:unlock:unlock_success 89231,33d30 893< element.: 894< click: digital key:key:unlock_btn 895< .element: 89636c33 897< initiate: 1 898--- 899> success: 1 90048,50c45,47 901< timeCaptureAEP: 2024-10-14T09:59:44.676Z 902< timeCaptureEpoch: 1728899984 903< timeCaptureISO: 2024-10-14T05:59:44-0400 904--- 905> timeCaptureAEP: 2024-10-14T09:59:45.537Z 906> timeCaptureEpoch: 1728899985 907> timeCaptureISO: 2024-10-14T05:59:45-0400 90879c76 909< segments: 15218869,26458327,19493122,21537957,22516131,17952857,23583601,17952894,19484989,21539153,22889861,21539313,26458383,21881915,15217574 910--- 911> segments: 21537957,22889861,23583601,15218869,17952857,21881915,21539313,22516131,19484989,26458383,19493122,17952894,15217574,21539153,26458327 91297c94 913< pev2: AMACTION:digital key:key:unlock_btn 914--- 915> pev2: AMACTION:digital key:key:unlock:unlock_success 916100c97,99 917< ts: 1728899984 918--- 919> ts: 1728899985 920> 921> *:8080mitmproxy 10.4.2 922``` 923<br/> 924 925> response.diff 926```diff 927< ],"uuid":"61645808922583835885560882535048239660","dcs_region":7,"tid":"RufgJCfxTjg=" 928--- 929> ],"uuid":"61645808922583835885560882535048239660","dcs_region":7,"tid":"69dMPcWjQD4=" 930``` 931 932Replaying either of the requests does nothing except give a new `tid` value but doesn't unlock the door. The `sxxxxxxx` part of the request URL also changes on every new request and doesn't seem to match any discernible pattern. The `IOSN030200030900` part never changes, however. My guess is that that part is a hotel reference ID. From doing some ducking around online, I couldn't find any references to the `smetric.hilton.com` domain, but it was blocked by uBlock Origin as part of the [EasyPrivacy](https://easylist.to/#easyprivacy) block list. The app also seems to issue requests to this URL. 933 934## Wrap up 935 936{{ img(id="https://hc-cdn.hel1.your-objectstorage.com/s/v3/4e9bfb28c266eb29cea1568cedd3573be2ba1f97_1bluetooth-scan.png" alt="screenshot of bluetooth scan" caption="The bluetooth scan of (what i believe is) the lift") }} 937 938I tried running a Bluetooth scan to see if I could find the locks, but nothing popped out as being a likely culprit. I did however find an interesting set of 3 Bluetooth devices named "clearsky smart fleet" which upon research seems to be scissor lifts / construction equipment made by a company called [JLG](https://smartfleet.jlg.com/) which is quite interesting. That would make sense, however, as I saw several scissor lifts outside the hotel on my way in. 939 940{{ img(id="https://hc-cdn.hel1.your-objectstorage.com/s/v3/993ad810e42289ad3aaefa4093ede271a4ee1d12_0img_2781.jpg" alt="image of JLG lift" caption="The same (probably) JLG lift in the wild!") }} 941 942By the time I'm writing this it's 6:41, and I need to eat breakfast, so I'll probably finish this post in the car this afternoon. Overall this was a fascinating experiment and while I sadly did fail at unlocking doors from my laptop I do feel more confident with reverse engineering app requests now! The next step would probably be to grab the app bundle and try to decompile it looking for the URLs we saw, but I don't have a mac on me, and I've never done that before. Next post? 943 944Taking inspiration from the [LOW←TECH MAGAZINE](https://solar.lowtechmagazine.com/) I will be taking any questions / comments about this article via email and then posting them here to my site! If you have a question or comment, feel free to email me at [me@dunkirk.sh](mailto://me@dunkirk.sh). Now to go eat breakfast :) 945 946![image of my hotel breakfast](https://hc-cdn.hel1.your-objectstorage.com/s/v3/c974178c62fc836657a1c5e61cac90596c13a3bd_3img_2777.jpg){caption="A delicious waffle, mildy warm bacon, and under seasoned potatoes."}