Skip to content
Georg Lukas edited this page Dec 1, 2023 · 5 revisions

When uploading images from the NX300 to social media, it will try to talk unencrypted to snsgw.samsungmobile.com, using different API endpoints.

HTTP API

Update: detailed reverse engineering in Samsung NX 2009 Crypto Fail: Social Media Uploads.

Example for a Facebook login (don't bother, those credentials are fake) from the NX300:

POST http://snsgw.samsungmobile.com/facebook/auth HTTP/1.1

<?xml version="1.0" encoding="UTF-8"?>
<Request Method="login" Timeout="3000" CameraCryptKey="844e7f0fadf4ba1cf5b6de9edb06ac9a448c0d3031b73db65a308cecb570428a44dea69bddd94403829e5c06efee9a4d555590f75a8c1313c3b935a0a03684d463733b30d3a34fe11b0da9d7f230366221ceec509419d89fd9b0cc36adc7258fbc904b497173d1f154202727c402b2a25d58dd0ecc6d576294880226cfb46151">
<UserName Value="7xKPwb19QdFKzsjsrQx62g%3D%3D"/>
<Password Value="U%2BK0X1QnWUv4tkvrrtQ0aQ%3D%3D"/>
<PersistKey Use="true"/>
4p4uaaq422af3"/>
<SessionKey Type="APIF"/>
<CryptSessionKey Use="true" Type="SHA1" Value="/////xAAwKRSAQAAAPAHtv////8QAMCkUgEAAADwB7Y="/>
<ApplicationKey Value="6a563c3967f147d3adfa454ef913535d0d109ba4b4584914"/>
</Request>

Yes, it's unencrypted. Yes, the XML is invalid.

The CameraCryptKey is different in each request, all the other fields remain the same. It looks like UserName and Password are encrypted in ECB or some other simple, IV-less mode.

As the service is down, I don't know (yet) the expected response format, so there is no way yet to mimic the service.

There is an accidental header file from libwifi-sns in the NX300 source code dump, containing those strings, under TIZEN/project/NX300/imagedev/usr/include/libwifi-sns/client_predefined.h, but there is no source code :(

Encryption

XML variables:

  • CameraCryptKey (right-aligned hex number, 128 bit): RSA-encrypted keyspec (32 bytes binary, not base64-encoded)
  • UserName (url-encoded base64): AES-encrypted(?) username / email
  • Password (url-encoded base64): AES-encrypted(?) password
  • CryptSessionKey (base64-encoded): the unencrypted keyspec (Ooops!)
  • ApplicationKey (hex): 24-byte static key that depends on the geographic API endpoint

Internally, libwifi-sns is using AES encryption with a per-session generated AES key (or maybe key + IV? gWeb.keyspec, 32 bytes, base64-encoded).

The key is created from calling _secureRandom() twice and concatenating the results:

char * _secureRandom(int *result)
{
  srand(time(0x0));
  char *target = String_new(20,result);
  if (*result == 0) {
    String_format(target,20,"%d",rand());
    target = _sha1_byte(target,result); /* WARNING: this is not actually SHA1, it's "return some 20 bytes from local stack" */
  }
  else {
    *result = *result;
    target = (char *)0x0;
  }
  return target;
}

Excellent engineering!

The keyspec is RSA encrypted by Web_Get_Camera_CryptKey() using a static key, which returns a zero-filled 256 byte hex string (stored in gWeb.encrypted_session_key):

_rsaEncrypt(keyspec_raw,keyspec_raw_len,
    "0x8ae4efdc724da51da5a5a023357ea25799144b1e6efbe8506fed1ef12abe7d3c11995f15
     dd5bf20f46741fa7c269c7f4dc5774ce6be8fc09635fe12c9a5b4104a890062b9987a6b6d69
     c85cf60e619674a0b48130bb63f4cf7995da9f797e2236a293ebc66ee3143c221b2ddf239b4
     de39466f768a6da7b11eb7f4d16387b4d7",
    "0x10001",&err);