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[extra] 11has_toc = true 12+++ 13 14I'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 ^_^) 15 16## Connecting to Mitmproxy 17 18I'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. 19 20{{ img(id="https://cloud-ryjlxhb9r-hack-club-bot.vercel.app/2install_profile.png" alt="screenshot of the root certificate install process" caption="You have to dig through several menus to trust it") }} 21 22I 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! 23 24## Digging around in the Hilton Honors app 25 26First 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: 27 28> POST 29```json 30{ 31 "query": "...", 32 "variables": { 33 "input": { 34 "email": { 35 "emailAddress": "xxxx-xxxx-xxxx@duck.com" 36 }, 37 "preferredLanguage": "EN", 38 "enrollSourceCode": "IOSEW", 39 "phone": { 40 "phoneNumber": "xxxxxxxxxx", 41 "phoneType": "home" 42 }, 43 "subscriptions": { 44 "hhonorsSubscriptions": [], 45 "optOuts": { 46 "survey": false, 47 "marketing": false 48 } 49 }, 50 "name": { 51 "firstName": "Kieran", 52 "lastName": "Klukas" 53 }, 54 "address": { 55 "city": "Washington", 56 "addressType": "home", 57 "addressLine2": null, 58 "postalCode": "20003", 59 "state": "DC", 60 "addressLine1": "1600 Pennsylvania Ave SE Apartments", 61 "country": "US" 62 }, 63 "privacyRequested": false, 64 "password": "xxxxxxxxxxxxxxxxxxxxxxxxxxx" 65 }, 66 "language": "en_US" 67 }, 68 "operationName": "createGuest" 69} 70``` 71```bash 72--- 73mutation createGuest($input: EnrollInput!, $language: String!) { 74 createGuest(language: $language, input: $input) { 75 data { 76 guestId 77 hhonorsNumber 78 } 79 error { 80 code 81 context 82 message 83 notifications { 84 code 85 fields 86 message 87 } 88 } 89 } 90} 91``` 92<br/> 93 94> response 95 96```json 97{ 98 "data": { 99 "createGuest": { 100 "data": { 101 "guestId": 1726240000, 102 "hhonorsNumber": "225782xxxx" 103 }, 104 "error": null 105 } 106 }, 107 "extensions": { 108 "logSearch": "mdc.client_message_id=51da35305bde9b71e7faa2993ebc2a619e50c598-iap71t195vk6jur6eyd83hy9g21w4bzam" 109 } 110} 111``` 112<br/> 113 114> headers 115 116```json 117{ 118 "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", 119 "exp": 1728879203, 120 "expires_in": 3600, 121 "iat": 1728875603, 122 "scope": "am_application_scope default", 123 "token_type": "Bearer" 124} 125``` 126 127At 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. 128 129# Invitation 130 131> Hi Kieran, 132> I’m sharing my Digital Key so you can use your phone as a room key. 133> 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. 134> 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. 135> See you soon, 136> xxxx xxxx 137 138I 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`: 139 140> POST 141```json 142{ 143 "shareId": "b4d6140d311e4c4c935dd653ca00af65" 144} 145``` 146 147<br/> 148 149> response 150```json 151{ 152 "arrivalDateTime": "2024-10-13T15:00-04:00", 153 "confirmationNumber": "5448xxxx", 154 "ctyhocn": "GCYPAHX", 155 "departureDateTime": "2024-10-14T11:00-04:00", 156 "hotelName": "Hampton Inn & Suites Grove City", 157 "stayId": "296088xxxx" 158} 159``` 160 161Another interesting request was to `https://m.hilton.io/graphql/customer?operationName=hotel_brand&type=hotelDetails_GCYPAHX` 162 163> POST 164```json 165{ 166 "variables": { 167 "ctyhocn": "GCYPAHX", 168 "language": "en-US" 169 }, 170 "operationName": "hotel_brand", 171 "query": "..." 172} 173``` 174```bash 175--- 176query hotel_brand($language: String!, $ctyhocn: String!) { 177 hotel(language: $language, ctyhocn: $ctyhocn) { 178 address { 179 addressFmt 180 addressLine1 181 addressLine2 182 city 183 country 184 countryName 185 postalCode 186 state 187 } 188 alerts { 189 description 190 type 191 } 192 amenities { 193 id 194 name 195 } 196 attributes { 197 numberOfRestaurants 198 } 199 brand { 200 isPartnerBrand 201 } 202 brandCode 203 campus { 204 type 205 } 206 chainCode 207 checkin { 208 checkinTimeFmt 209 checkinTime 210 checkoutTimeFmt 211 checkoutTime 212 digitalKey 213 } 214 config { 215 checkout { 216 allowDCO 217 } 218 connectedRoom { 219 crEnabled 220 crFullyEnabled 221 emsEnabled 222 } 223 messaging { 224 kipsuEnabled 225 messagingTileEnabled 226 gatewayRoutingEnabled 227 } 228 adjoiningRooms { 229 active 230 } 231 } 232 coordinate { 233 latitude 234 longitude 235 } 236 crsData { 237 adultAge 238 ageBasedPricing 239 acceptedCreditCards 240 } 241 ctyhocn 242 currencyCode 243 display { 244 treatments 245 } 246 gmtHours 247 internetAddress 248 name 249 phoneNumber 250 policyOptions { 251 label 252 value 253 options { 254 label 255 value 256 } 257 } 258 facilityOverview { 259 shortDesc 260 } 261 images { 262 master { 263 altText 264 url(height: 430, width: 612) 265 } 266 gallery { 267 image(variant: searchPropertyImageThumbnail) { 268 altText 269 url(height: 430, width: 612) 270 } 271 masterImage 272 } 273 carousel { 274 altText 275 url(height: 430, width: 612) 276 } 277 } 278 } 279} 280``` 281 282<br/> 283 284> response 285```json 286{ 287 "data": { 288 "hotel": { 289 "address": { 290 "addressFmt": "4 Holiday Blvd., Mercer, Pennsylvania, 16137, USA", 291 "addressLine1": "4 Holiday Blvd.", 292 "addressLine2": null, 293 "city": "Mercer", 294 "country": "US", 295 "countryName": "USA", 296 "postalCode": "16137", 297 "state": "PA" 298 }, 299 "alerts": [ 300 { 301 "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.", 302 "type": "alert" 303 } 304 ], 305 "amenities": [ 306 { 307 "id": "adjoiningRooms", 308 "name": "Connecting Rooms" 309 }, 310 { 311 "id": "freeBreakfast", 312 "name": "Free hot breakfast" 313 }, 314 { 315 "id": "freeParking", 316 "name": "Free parking" 317 }, 318 { 319 "id": "freeWifi", 320 "name": "Free WiFi" 321 }, 322 { 323 "id": "nonSmoking", 324 "name": "Non-smoking rooms" 325 }, 326 { 327 "id": "digitalKey", 328 "name": "Digital Key" 329 }, 330 { 331 "id": "evCharging", 332 "name": "EV charging" 333 }, 334 { 335 "id": "indoorPool", 336 "name": "Indoor pool" 337 }, 338 { 339 "id": "fitnessCenter", 340 "name": "Fitness center" 341 }, 342 { 343 "id": "petsAllowed", 344 "name": "Pet-friendly rooms" 345 }, 346 { 347 "id": "meetingRooms", 348 "name": "Meeting rooms" 349 } 350 ], 351 "attributes": { 352 "numberOfRestaurants": 0 353 }, 354 "brand": { 355 "isPartnerBrand": false 356 }, 357 "brandCode": "HP", 358 "campus": { 359 "type": "enhanced" 360 }, 361 "chainCode": "HH", 362 "checkin": { 363 "checkinTime": "15:00", 364 "checkinTimeFmt": "3:00 PM", 365 "checkoutTime": "11:00", 366 "checkoutTimeFmt": "11:00 AM", 367 "digitalKey": true 368 }, 369 "config": { 370 "adjoiningRooms": { 371 "active": true 372 }, 373 "checkout": { 374 "allowDCO": true 375 }, 376 "connectedRoom": null, 377 "messaging": { 378 "gatewayRoutingEnabled": true, 379 "kipsuEnabled": true, 380 "messagingTileEnabled": true 381 } 382 }, 383 "coordinate": { 384 "latitude": 41.142354, 385 "longitude": -80.164956 386 }, 387 "crsData": { 388 "acceptedCreditCards": [ 389 "CU", 390 "VI", 391 "MC", 392 "AX", 393 "DS", 394 "DC", 395 "CB" 396 ], 397 "adultAge": null, 398 "ageBasedPricing": null 399 }, 400 "ctyhocn": "GCYPAHX", 401 "currencyCode": "USD", 402 "display": { 403 "treatments": [] 404 }, 405 "facilityOverview": { 406 "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." 407 }, 408 "gmtHours": -4, 409 "images": { 410 "carousel": [ 411 { 412 "altText": "Outdoor Patio", 413 "url": "https://www.hilton.com/im/en/GCYPAHX/2888809/gcypahx-patio.jpg?impolicy=resize&rh=430&rw=612" 414 }, 415 { 416 "altText": "Double Queen", 417 "url": "https://www.hilton.com/im/en/GCYPAHX/4248848/hampton-grove-city-standard-queen-1-preview.jpg?impolicy=resize&rh=430&rw=612" 418 }, 419 { 420 "altText": "King Standard", 421 "url": "https://www.hilton.com/im/en/GCYPAHX/4248016/hampton-grove-city-king-standard-1.jpg?impolicy=resize&rh=430&rw=612" 422 }, 423 { 424 "altText": "Lobby and Dining Area", 425 "url": "https://www.hilton.com/im/en/GCYPAHX/2887422/lobby-1.jpg?impolicy=resize&rh=430&rw=612" 426 }, 427 { 428 "altText": "Lobby", 429 "url": "https://www.hilton.com/im/en/GCYPAHX/2887224/lobby-2.jpg?impolicy=resize&rh=430&rw=612" 430 }, 431 { 432 "altText": "Breakfast Buffet", 433 "url": "https://www.hilton.com/im/en/GCYPAHX/2880542/breakfast-1.jpg?impolicy=resize&rh=430&rw=612" 434 }, 435 { 436 "altText": "Indoor Pool", 437 "url": "https://www.hilton.com/im/en/GCYPAHX/4258295/hampton-new-pics-2008-035.jpg?impolicy=resize&rh=430&rw=612" 438 }, 439 { 440 "altText": "Fitness Center", 441 "url": "https://www.hilton.com/im/en/GCYPAHX/2883297/fitness.jpg?impolicy=resize&rh=430&rw=612" 442 }, 443 { 444 "altText": "Boardroom", 445 "url": "https://www.hilton.com/im/en/GCYPAHX/2879933/board-room.jpg?impolicy=resize&rh=430&rw=612" 446 }, 447 { 448 "altText": "Meeting Room", 449 "url": "https://www.hilton.com/im/en/GCYPAHX/2888194/meeting.jpg?impolicy=resize&rh=430&rw=612" 450 }, 451 { 452 "altText": "Hotel Exterior at Night", 453 "url": "https://www.hilton.com/im/en/GCYPAHX/4251655/exterior-night.jpg?impolicy=resize&rh=430&rw=612" 454 }, 455 { 456 "altText": "Business Center", 457 "url": "https://www.hilton.com/im/en/GCYPAHX/2881016/business-center.jpg?impolicy=resize&rh=430&rw=612" 458 } 459 ], 460 "gallery": [ 461 { 462 "image": { 463 "altText": "Outdoor Patio", 464 "url": "https://www.hilton.com/im/en/GCYPAHX/2888809/gcypahx-patio.jpg?impolicy=resize&rh=430&rw=612" 465 }, 466 "masterImage": true 467 }, 468 { 469 "image": { 470 "altText": "Double Queen", 471 "url": "https://www.hilton.com/im/en/GCYPAHX/4248848/hampton-grove-city-standard-queen-1-preview.jpg?impolicy=resize&rh=430&rw=612" 472 }, 473 "masterImage": false 474 }, 475 { 476 "image": { 477 "altText": "King Standard", 478 "url": "https://www.hilton.com/im/en/GCYPAHX/4248016/hampton-grove-city-king-standard-1.jpg?impolicy=resize&rh=430&rw=612" 479 }, 480 "masterImage": false 481 }, 482 { 483 "image": { 484 "altText": "Lobby and Dining Area", 485 "url": "https://www.hilton.com/im/en/GCYPAHX/2887422/lobby-1.jpg?impolicy=resize&rh=430&rw=612" 486 }, 487 "masterImage": false 488 }, 489 { 490 "image": { 491 "altText": "Lobby", 492 "url": "https://www.hilton.com/im/en/GCYPAHX/2887224/lobby-2.jpg?impolicy=resize&rh=430&rw=612" 493 }, 494 "masterImage": false 495 }, 496 { 497 "image": { 498 "altText": "Breakfast Buffet", 499 "url": "https://www.hilton.com/im/en/GCYPAHX/2880542/breakfast-1.jpg?impolicy=resize&rh=430&rw=612" 500 }, 501 "masterImage": false 502 }, 503 { 504 "image": { 505 "altText": "Indoor Pool", 506 "url": "https://www.hilton.com/im/en/GCYPAHX/4258295/hampton-new-pics-2008-035.jpg?impolicy=resize&rh=430&rw=612" 507 }, 508 "masterImage": false 509 }, 510 { 511 "image": { 512 "altText": "Fitness Center", 513 "url": "https://www.hilton.com/im/en/GCYPAHX/2883297/fitness.jpg?impolicy=resize&rh=430&rw=612" 514 }, 515 "masterImage": false 516 }, 517 { 518 "image": { 519 "altText": "Boardroom", 520 "url": "https://www.hilton.com/im/en/GCYPAHX/2879933/board-room.jpg?impolicy=resize&rh=430&rw=612" 521 }, 522 "masterImage": false 523 }, 524 { 525 "image": { 526 "altText": "Meeting Room", 527 "url": "https://www.hilton.com/im/en/GCYPAHX/2888194/meeting.jpg?impolicy=resize&rh=430&rw=612" 528 }, 529 "masterImage": false 530 }, 531 { 532 "image": { 533 "altText": "Hotel Exterior at Night", 534 "url": "https://www.hilton.com/im/en/GCYPAHX/4251655/exterior-night.jpg?impolicy=resize&rh=430&rw=612" 535 }, 536 "masterImage": false 537 }, 538 { 539 "image": { 540 "altText": "Business Center", 541 "url": "https://www.hilton.com/im/en/GCYPAHX/2881016/business-center.jpg?impolicy=resize&rh=430&rw=612" 542 }, 543 "masterImage": false 544 }, 545 { 546 "image": { 547 "altText": "Indoor Pool / Whirlpool", 548 "url": "https://www.hilton.com/im/en/GCYPAHX/2885342/pool.jpg?impolicy=resize&rh=430&rw=612" 549 }, 550 "masterImage": false 551 }, 552 { 553 "image": { 554 "altText": "Double Queen Studio", 555 "url": "https://www.hilton.com/im/en/GCYPAHX/4250170/hampton-new-pics-2008-020.jpg?impolicy=resize&rh=430&rw=612" 556 }, 557 "masterImage": false 558 }, 559 { 560 "image": { 561 "altText": "Whirlpool Suite", 562 "url": "https://www.hilton.com/im/en/GCYPAHX/4251204/whirlpool-king-suite-one-2-2-.jpg?impolicy=resize&rh=430&rw=612" 563 }, 564 "masterImage": false 565 }, 566 { 567 "image": { 568 "altText": "Breakfast Area", 569 "url": "https://www.hilton.com/im/en/GCYPAHX/2880342/breakfast-2.tif?impolicy=resize&rh=430&rw=612" 570 }, 571 "masterImage": false 572 }, 573 { 574 "image": { 575 "altText": "Suite Shop", 576 "url": "https://www.hilton.com/im/en/GCYPAHX/2890823/gift-shop.jpg?impolicy=resize&rh=430&rw=612" 577 }, 578 "masterImage": false 579 }, 580 { 581 "image": { 582 "altText": "Hotel Exterior", 583 "url": "https://www.hilton.com/im/en/GCYPAHX/390670/gcypahx-hampton-exterior-night-1.jpg?impolicy=resize&rh=430&rw=612" 584 }, 585 "masterImage": false 586 }, 587 { 588 "image": { 589 "altText": "Hotel Exterior", 590 "url": "https://www.hilton.com/im/en/GCYPAHX/4255766/hampton-new-pics-2008-012.jpg?impolicy=resize&rh=430&rw=612" 591 }, 592 "masterImage": false 593 }, 594 { 595 "image": { 596 "altText": "Double Queen Suite", 597 "url": "https://www.hilton.com/im/en/GCYPAHX/4251117/double-queen-standard-2-.jpg?impolicy=resize&rh=430&rw=612" 598 }, 599 "masterImage": false 600 } 601 ], 602 "master": { 603 "altText": "Outdoor Patio", 604 "url": "https://www.hilton.com/im/en/GCYPAHX/2888809/gcypahx-patio.jpg?impolicy=resize&rh=430&rw=612" 605 } 606 }, 607 "internetAddress": "https://www.hilton.com/en/hotels/gcypahx-hampton-suites-grove-city/", 608 "name": "Hampton Inn & Suites Grove City", 609 "phoneNumber": "+1 724-748-5744", 610 "policyOptions": [ 611 { 612 "label": "Cancellation", 613 "options": [ 614 { 615 "label": "Description", 616 "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>." 617 } 618 ], 619 "value": null 620 }, 621 { 622 "label": "Check-in/Check-out", 623 "options": [ 624 { 625 "label": "Checkin Time", 626 "value": "3:00 PM" 627 }, 628 { 629 "label": "Checkout Time", 630 "value": "11:00 AM" 631 }, 632 { 633 "label": "Early Departure Fee", 634 "value": null 635 }, 636 { 637 "label": "Late Checkout Fee", 638 "value": null 639 }, 640 { 641 "label": "Minimum Age To Register", 642 "value": "21" 643 } 644 ], 645 "value": null 646 }, 647 { 648 "label": "Wi-Fi", 649 "options": [ 650 { 651 "label": "Description", 652 "value": "Standard In-Room and Lobby Wi-Fi - All guests get free standard Wi-Fi in-room and in the lobby." 653 } 654 ], 655 "value": null 656 }, 657 { 658 "label": "Parking", 659 "options": [ 660 { 661 "label": "Covered", 662 "value": "Not Available" 663 }, 664 { 665 "label": "In Out Privileges", 666 "value": "Not Available" 667 }, 668 { 669 "label": "Other Parking Information", 670 "value": "Parking Lot" 671 }, 672 { 673 "label": "Secured", 674 "value": "Not Available" 675 }, 676 { 677 "label": "Self Parking", 678 "value": "$0.00 Complimentary" 679 }, 680 { 681 "label": "Valet Parking", 682 "value": "Not Available" 683 } 684 ], 685 "value": null 686 }, 687 { 688 "label": "Payment", 689 "options": [ 690 { 691 "label": "Hotel Currency", 692 "value": "US Dollar" 693 }, 694 { 695 "label": "Accepted Payment Options", 696 "value": "American Express, Carte Blanche, China Union Pay, Diner's Club, Discover, MasterCard, Visa" 697 } 698 ], 699 "value": null 700 }, 701 { 702 "label": "Pets", 703 "options": [ 704 { 705 "label": "Deposit", 706 "value": "$50.00 Non-Refundable" 707 }, 708 { 709 "label": "Kennel Message", 710 "value": null 711 }, 712 { 713 "label": "Maximum Size", 714 "value": null 715 }, 716 { 717 "label": "Maximum Weight", 718 "value": null 719 }, 720 { 721 "label": "Other Pet Services", 722 "value": "$50(1-4n),$75(5+n) 2petsMax,dog/cat only" 723 }, 724 { 725 "label": "Pets Allowed", 726 "value": "Yes" 727 }, 728 { 729 "label": "Service Animals Allowed", 730 "value": "Yes" 731 } 732 ], 733 "value": null 734 }, 735 { 736 "label": "Smoking", 737 "options": [ 738 { 739 "label": "Indicator", 740 "value": "Non-Smoking" 741 }, 742 { 743 "label": "Description", 744 "value": null 745 } 746 ], 747 "value": null 748 } 749 ] 750 } 751 }, 752 "extensions": { 753 "logSearch": "mdc.client_message_id=51da35305bde9b71e7faa2993ebc2a619e50c598-uauhdwbaydoqbvy3uvuzai20c4takt22" 754 } 755} 756``` 757 758It 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! 759 760## Locks 761 762{{ img(id="https://cloud-ryjlxhb9r-hack-club-bot.vercel.app/0hotel-key.png" alt="screenshot of the hotel digital key" caption="What it looks like in the app") }} 763 764When 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. 765 766> POST 767```yaml 768ndh: 1 769cid.: 770card_no.: 771as: 0 772id: 2257829743 773.card_no: 774hhid.: 775as: 1 776id: 2257829743 777.hhid: 778.cid: 779aamb: j8Odv6LonN4r3an7LhD3WZrU1bUpAkFkkiY1ncBR96t2PTI 780aamlh: 7 781c.: 782a.: 783AppID: HHonors 2024.10.1 (1) 784CarrierName: -- 785DeviceName: iPhone14,4 786OSVersion: iOS 18.1 787Resolution: 1125x2436 788RunMode: Application 789TimeSinceLaunch: 24560 790action: digital key:key:unlock_btn 791.a: 792hm.: 793app.: 794name: HHonors iOS Mobile 795.app: 796digitalkeyflag: Yes 797event.: 798element.: 799click: digital key:key:unlock_btn 800.element: 801key.: 802unlock.: 803initiate: 1 804.unlock: 805.key: 806.event: 807flag.: 808appsettings: N|N|NA|N|Y|Y|Y|Y|Y|NA|UsingApp|N| 809orientation: L 810stay.: 811level.: 812status: In-Stay 813.level: 814.stay: 815timeCaptureAEP: 2024-10-14T09:59:44.676Z 816timeCaptureEpoch: 1728899984 817timeCaptureISO: 2024-10-14T05:59:44-0400 818.flag: 819hotel.: 820brand: HP 821propertycode: GCYPAHX 822.hotel: 823key.: 824gnr: 79125065 825locktype: guest 826lsn: 92044507 827shared.: 828flag: Yes 829.shared: 830.key: 831page.: 832name: 833previous: App:EN:Honors:Digital Key:Key 834.page: 835purchase.: 836booking.: 837dates: 10132024:10142024:1 838.booking: 839bookingid: 54486330 840.purchase: 841site.: 842type: PA 843.site: 844user.: 845aam.: 846segments: 15218869,26458327,19493122,21537957,22516131,17952857,23583601,17952894,19484989,21539153,22889861,21539313,26458383,21881915,15217574 847.aam: 848language: en 849login.: 850status: Logged-in 851.login: 852memberId: 2257829743 853stayid: 2960880196 854tierpoints: Member 855.user: 856.hm: 857.c: 858ce: UTF-8 859cp: foreground 860d.ptfm: ios 861mid: 61621496110939688115558742623055817571 862pageName: HHonors 2024.10.1 (1) 863pe: lnk_o 864pev2: AMACTION:digital key:key:unlock_btn 865products: ;GCYPAHX;;;; 866t: 00/00/0000 00:00:00 0 240 867ts: 1728899984 868``` 869 870<br/> 871 872> response 873```json 874 { 875 "stuff":[ { 876 "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":"" 877 } 878 , { 879 "cn":"fltk","cv":"segID=15218869","ttl":30,"dmn":"" 880 } 881 ],"uuid":"61645808922583835885560882535048239660","dcs_region":7,"tid":"RufgJCfxTjg=" 882} 883``` 884 885About 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. 886 887> POST.diff 888```diff 88923c23 890< action: digital key:key:unlock_btn 891--- 892> action: digital key:key:unlock:unlock_success 89331,33d30 894< element.: 895< click: digital key:key:unlock_btn 896< .element: 89736c33 898< initiate: 1 899--- 900> success: 1 90148,50c45,47 902< timeCaptureAEP: 2024-10-14T09:59:44.676Z 903< timeCaptureEpoch: 1728899984 904< timeCaptureISO: 2024-10-14T05:59:44-0400 905--- 906> timeCaptureAEP: 2024-10-14T09:59:45.537Z 907> timeCaptureEpoch: 1728899985 908> timeCaptureISO: 2024-10-14T05:59:45-0400 90979c76 910< segments: 15218869,26458327,19493122,21537957,22516131,17952857,23583601,17952894,19484989,21539153,22889861,21539313,26458383,21881915,15217574 911--- 912> segments: 21537957,22889861,23583601,15218869,17952857,21881915,21539313,22516131,19484989,26458383,19493122,17952894,15217574,21539153,26458327 91397c94 914< pev2: AMACTION:digital key:key:unlock_btn 915--- 916> pev2: AMACTION:digital key:key:unlock:unlock_success 917100c97,99 918< ts: 1728899984 919--- 920> ts: 1728899985 921> 922> *:8080mitmproxy 10.4.2 923``` 924<br/> 925 926> response.diff 927```diff 928< ],"uuid":"61645808922583835885560882535048239660","dcs_region":7,"tid":"RufgJCfxTjg=" 929--- 930> ],"uuid":"61645808922583835885560882535048239660","dcs_region":7,"tid":"69dMPcWjQD4=" 931``` 932 933Replaying 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. 934 935## Wrap up 936 937{{ img(id="https://cloud-ryjlxhb9r-hack-club-bot.vercel.app/1bluetooth-scan.png" alt="screenshot of bluetooth scan" caption="The bluetooth scan of (what i belive is) the lift") }} 938 939I 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. 940 941{{ img(id="https://cloud-1asinv8kn-hack-club-bot.vercel.app/0img_2781.jpg" alt="image of JLG lift" caption="The same (probably) JLG lift in the wild!") }} 942 943By 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? 944 945Taking 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 :) 946 947{{ img(id="https://cloud-1asinv8kn-hack-club-bot.vercel.app/3img_2777.jpg" alt="image of my hotel breakfast" caption="A delicious waffle, mildy warm bacon, and under seasoned potatoes.") }}