diff --git a/.gitignore b/.gitignore index 5a160f0..1703860 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ debian-binary # lg binaries _ipk-* _downloaded +*extracted* # temp files diff --git a/cujo/README.md b/cujo/README.md index 198b94b..d44435d 100644 --- a/cujo/README.md +++ b/cujo/README.md @@ -8,14 +8,13 @@ - [phone home](#phone-home) ## TV -name|value -----|----- -model|TODO -product|`TODO` -firmware|`TODO` -features|TODO -vulnerabilities|all phone-home calls are done over `HTTP` - +name | value +----------------|----- +model | `TODO` +product | `TODO` +firmware | `TODO` +features | TODO +vulnerabilities | all phone-home calls are done over `HTTP` ## digging @@ -37,8 +36,8 @@ so.. no open ports. let's try something different watching the network activity of the device (`192.168.1.108`), noticed it tried to resolve: - * agent.cujo.io - * jenkins.getcujo.com + * `agent.cujo.io` + * `jenkins.getcujo.com` but since the network isn't allowing external traffic, the DNS resolution fails. diff --git a/lg_webOS/README.md b/lg_webOS/README.md index dd9563a..694665e 100644 --- a/lg_webOS/README.md +++ b/lg_webOS/README.md @@ -362,12 +362,120 @@ key | value since the `update_minor_ver` specified is greater than the existing value (`30.40`), the TV prompts the user that an upgrade is available. -the traffic after the user chooses to upgrade: +the traffic after the user chooses to upgrade starts with a `GET` of the `image_url`: ``` +GET /fizzbuzz HTTP/1.1 +Accept: */* +Host: snu.lge.com +Range: bytes=0-1715 +Connection: Closed ``` - +followed by 5 retries, since they all received 404 as we're not sure what the format of the update actually is (yet), but assume it will be an `.ipk` as well. + +then some base64 encoded data with a log : + +``` +POST /SWDownloadStartLog.laf HTTP/1.1 +Accept: */* +User-Agent: User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) +Host: snu.lge.com:80 +Connection: Keep-Alive +Content-type: application/x-www-form-urlencoded +Content-Length: 268 + +PFJFUVVFU1Q+CjxSRVFfSUQ+MDAwMDAwMDAwMDg2MTMyNDQ2NjA8L1JFUV9JRD4KPFBST0RVQ1RfTk0+d2ViT1NUViAzLjA8L1BST0RVQ1RfTk0+CjxNT0RFTF9OTT5IRV9EVFZfVzE2UF9BRkFEQVRBQTwvTU9ERUxfTk0+CjxTV19UWVBFPkZJUk1XQVJFPC9TV19UWVBFPgo8SU1BR0VfTkFNRT5maXp6YnV6ejwvSU1BR0VfTkFNRT4KPC9SRVFVRVNUPgo= +``` + +decoded: + +```xml + + 00000000008613244660 + webOSTV 3.0 + HE_DTV_W16P_AFADATAA + FIRMWARE + fizzbuzz + +``` + +and then some similar data to a different endpoint: + +``` +POST /DownloadResult.laf HTTP/1.1 +Accept: */* +User-Agent: User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) +Host: snu.lge.com:80 +Connection: Keep-Alive +Content-type: application/x-www-form-urlencoded +Content-Length: 308 + +PFJFUVVFU1Q+CjxSRVFfSUQ+MDAwMDAwMDAwMDg2MTMyNDQ2NjA8L1JFUV9JRD4KPFBST0RVQ1RfTk0+d2ViT1NUViAzLjA8L1BST0RVQ1RfTk0+CjxNT0RFTF9OTT5IRV9EVFZfVzE2UF9BRkFEQVRBQTwvTU9ERUxfTk0+CjxTV19UWVBFPkZJUk1XQVJFPC9TV19UWVBFPgo8VVBEQVRFX1JFU1VMVD43MjI8L1VQREFURV9SRVNVTFQ+CjxSRVRSWV9DT1VOVD4wPC9SRVRSWV9DT1VOVD4KPC9SRVFVRVNUPgo= +``` + +decoded: + +```xml + + 00000000008613244660 + webOSTV 3.0 + HE_DTV_W16P_AFADATAA + FIRMWARE + 722 + 0 + +``` + +so, now we know what the process is, just need to determine what the format/contents of the OS update is. + +after shutting down `impersonate-lge.com.rb`, the real `snu.lge.com` responds to `/CheckSWAutoUpdate.laf` with: + +``` +GET /GlobalSWDownloadCdn.laf?IMG=/-prodkey_nsu_V3_SECURED.epk HTTP/1.1 +Accept: */* +Host: su.lge.com:80 +Range: bytes=0-1715 +Connection: Closed +``` + +taking a look at the (850mb) file: + +``` +$ binwalk -v --dd='.*' -prodkey_nsu_V3_SECURED.epk + +Scan Time: 2016-12-28 22:41:37 +Target File: -prodkey_nsu_V3_SECURED.epk +MD5 Checksum: eadf4625c8033f286f7459766558d43b +Signatures: 344 + +DECIMAL HEXADECIMAL DESCRIPTION +-------------------------------------------------------------------------------- +1437257 0x15EE49 HPACK archive data +88501492 0x5466CF4 StuffIt Deluxe Segment (data): f +116751487 0x6F57C7F VMware4 disk image +151796947 0x90C3CD3 LANCOM OEM file +184522619 0xAFF977B MySQL ISAM compressed data file Version 4 +188949815 0xB432537 QEMU QCOW Image +202964337 0xC18FD71 MySQL ISAM compressed data file Version 8 +360991579 0x15844B5B MySQL ISAM compressed data file Version 9 +403720767 0x18104A3F MySQL ISAM compressed data file Version 5 +438498638 0x1A22F54E Cisco IOS experimental microcode, for "" +558916980 0x21506574 QEMU QCOW Image +652690023 0x26E74267 COBALT boot rom data (Flat boot rom or file system) +673373671 0x2822DDE7 StuffIt Deluxe Segment (data): f +752461107 0x2CD9A533 MySQL ISAM index file Version 11 +798709823 0x2F9B583F LANCOM OEM file +828143551 0x315C77BF MySQL ISAM index file Version 11 +828353910 0x315FAD76 MySQL ISAM compressed data file Version 4 +``` + +however, given the 'encrypted' portion of the filename and the fact that none of the files are actually usable as the type indicated here +- the encryption is throwing off `binwalk` file type detection + +attempting to find an unencrypted version of the file by fuzzing the original URL has, so far, proved unsuccessful. + +# TODO how would we determine the type of encryption in order to start attacking it? ## channel guide diff --git a/lg_webOS/impersonate-lge.com.rb b/lg_webOS/impersonate-lge.com.rb index b6229f5..cddbd5b 100644 --- a/lg_webOS/impersonate-lge.com.rb +++ b/lg_webOS/impersonate-lge.com.rb @@ -28,9 +28,15 @@ get '/fts/:file' do |file| hash = params['hash'] # 6Vsai7Ky71UPgetV mtime = params['mtime'] # 1479098823000 - fake_ipk_name = '16881482.ipk' + fake_ipk_name = sprintf('%s.ipk', key) real_ipk_file = File.join(settings.public_folder, '/gfts/base-files.ipk') + if mtime + mtime_int = Time.at(mtime.to_i / 1000).to_i + mtime_args = Time.at(mtime_int).strftime('%Y%m%d%H%M') + `touch -t #{mtime_args} #{real_ipk_file}` + end + headers( 'Content-Disposition' => sprintf('attachment; filename="%s"', fake_ipk_name), 'Content-Transfer-Encoding' => 'binary', @@ -38,7 +44,7 @@ get '/fts/:file' do |file| 'Server' => 'Apache', ) - send_file real_ipk_file + send_file(real_ipk_file) elsif target_host.match(/ngfts/) ## channel searching -- images / thumbnails diff --git a/mifi/reverse-adpassword.rb b/mifi/reverse-adpassword.rb index 05f7213..742917e 100644 --- a/mifi/reverse-adpassword.rb +++ b/mifi/reverse-adpassword.rb @@ -35,7 +35,5 @@ end # TODO first we mimic the encoding, then we can decode encoded = rstr2hex(rstr_sha1(str2rstr_utf8(password))) -puts sprintf('%s %s', decoded, "\n") - - - +puts sprintf('%s', encoded) +puts sprintf('%s', decoded)