Sunday, August 30, 2015

Account Break-in and the eMail Weak Link

Last week, a relative's bank account was drained. In this case a person presented some checks, in person, to a teller at the bank. The teller performed a fraud check by calling the telephone number on record for the account. The person who answered the telephone confirmed the checks were valid. Then the bank cashed the checks. Disturbing? Commonplace!

I spend a lot of time working on computer security for my day job. We spend great amounts of time on threat analysis, process control, fault detection. The world isn't very far along with respect to full protection.

So, let's dig into a particular sequence of events that likely happened here:
  • Someone was able to gain access to the eMail account for the relative
  • Next, they examined the eMail history (e.g for bank account #)
  • Next, they requested a password reset for the bank account (sent to the email)
  • Now, with access to the bank account, they:
    • Examined signature on some of the online facsimiles of recently cashed checks
    • Altered the contact telephone number for the bank account
    • Deleted any account-changed evidence that was emailed to the relative
  • Next, they prepared a counter check (readily available) and went to the bank
  • The banker called the fake number and approved the transaction
Yes, the bank will accept liability and will (eventually) return the money. However, this scenario isn't quite like credit-card fraud. Here is a case where your real bank account has no money, you are stuck until the bank restores the funds (after their additional check to make sure you aren't part of the ring!)

Mobile phone eMail Weak Link

The break-in got me to re-visiting my assumptions about eMail and if there is any way to improve eMail password recovery plumbing. How good are eMail provider's MFA solutions? How big is the risk when MFA tokens and email might be on the same phone? How easy is it to social engineer a password recovery? Two cases in point:

Yahoo eMail

  • Has a multi-factor solution that binds a special code to a particular system
  • However, allows for a single password that binds to a mobile device
  • Allows for SMS or alternate eMail address for password recovery
The problem here is that if a phone is stolen, both the SMS target AND the email address are on the same system (always have your phone go to lock mode). Also, if the password recovery email is compromised, then it is likely possible to recover a password for Yahoo (this is exceptionally easy these days as emails correlation databases are readily available).

So, one solution is to not have an SMS recovery for Yahoo and then to have the recovery email to another service (say gmail).

Note, even though SMS target can be removed for Yahoo, they really want an SMS target, they will re-ask for one during recovery even if you only want to use recovery email. So, be careful letting an SMS recovery leak back in to your configuration.

Google eMail

  • Has a time based token option for 2nd factor
  • This does NOT work when using an embedded email system (like on a phone)
  • Has a fancy password recovery mechanism that may be a little too fancy
  • Seems to ignore registered SMS as recovery option
Even if you remove the email recovery email, and only have SMS, google sort of forces you through the social password recovery scheme. I was able to get a recovery password sent to an old email address. I guess this isn't really a scientific test as I didn't try this from different IP addresses, etc. Still this seems a little to fancy (read: tries to reduce the number of support calls google gets...)

Also, here again, if both Yahoo and gmail are on the same phone, it is possible to recover both (again, hope your phone's lock system is robust)

What Next?

I'll discuss malware proxy risks in a future posting. In the mean time, need to investigate which financial institutions allow for:
  • Requiring token based MFA
  • Have non-email based password recovery schemes
  • Optionally, restrict remote financial transactions to non-internet
  • Or, allow for voice confirmed shared secrets ("what is the answer to question 2?")
Yes, the convenience of just typing in a password should be a thing of the past. But, even an MFA solution, or alternate channel password recovery doesn't seem to close all the gaps.





CMSensorRecorder data reliably flowing to Kinesis

I've refactored the iPhone side of the code a bit to better represent background processing of the sensor data. The good thing is that WCSession:sendMessage handles iPhone background processing properly. This is at the expense of having to handle reachability errors in code. The checkpoint of code is here.

Now the flow is roughly:
  • On Watch
    • CMSensorRecorder is activated and is recording records locally regardless of the application state of the Watch
    • When the sensor application is in the foreground, a thread attempts to dequeue data form the recorder
    • And when this data is received a WCSession:sendMessage is used to send the data to the iPhone in the background
    • Iff a valid reply comes back from this message, the CMSensorRecorder fetch position is updated to fetch the next unprocessed sensor data
  • On iPhone
    • A background thread is always ready to receive messages from the Watch
    • Those messages are saved to a local Kinesis queue
    • A timer based flush will submit this Kinesis queue to AWS
    • AWS credentials from Cognito are now manually refreshed by checking the credentials expire time
    • The send and submit kinesis calls are now asynchronous tasks
So this is pretty close to continuous feed on the iPhone side.

Some areas of durability to re-explore next:
  • How to build a Watch dequeue that can run when the application isn't in foreground?
  • Is there another way for WCSession to send to a background task other than sendMessage?
  • How reliable is the sendMessage call?
    • When the iPhone is out of range
    • When the iPhone is locked
    • When it is busy running another application
    • I do see some transient 'not paired' exceptions when sending volume
  • While this does allow for automatic background processing, is there a simpler way of transferring data that doesn't require the application handling reachability errors?
  • How reliable is the Kinesis send-retry when the iPhone can't reach AWS?
I will next be building more quantitative checks of the actual data sent through the system to understand where data get sent more than once, or where it is lost.

Wednesday, August 26, 2015

Xcode 7 beta6: Bitcode issues between WatchOS and iPhone solved!

Getting there!  A quick upgrade to Xcode 7 beta6 fixed this issue.  We now have data transfer from Watch Accelerometer to CMSensorRecorder to Watch app to iPhone to Kinesis -- yes data is flowing, mostly resiliently too; with intermittent focus, connectivity, etc.  Here is the code.

And some screen dumps (explained below):


The Watch screen dump is pretty much as before.  You will see the Cognito integration (using Amazon as an identity provider).  The first 4 lines are the identity details.  The next 4 lines are information regarding the Kinesis storage, the STS token expire time, the amount of local storage consumed, how many flushes to Kinesis have occurred, and when.

Of course the current code still relies on these transfer operations being in focus, an ongoing area of research as to how to make this a background operation on both the Watch and on the iPhone.  But still, real data is finally in Kinesis.

TODO: build an auto-refreshing STS token, as this appears to be a known problem.

Next up, write an AWS Lambda function to read from Kinesis, parse the records and then put them into DynamoDB.  Once that is there, a visualization example both on iOS and on a Server-less web service...


Sunday, August 23, 2015

Marketing: make something look like what is intended, not what it is

Well, this has been a depressing past couple of days. This was the time to re-integrate the AWS SDK back into the application in preparation for sending data to Kinesis. I had basic Cognito and Kinesis hello world working back in June on WatchOS 1.0. I'd mistakenly assumed that some sort of compatibility over time would be in order. Not to be the case. Summary:
Yes, it is possible to disable the enforcement of the TLS1.2 requirement. And this I did, I am able to get a set of temporary keys for calls to AWS services. How many applications are going to have to do this? All of them?

Worse, it doesn't look possible to use the current AWS SDK with a Watch application. This looks like a pretty ugly show stopper:
  • 3rd party library doesn't have bitcode support. While you can disable this on the iPhone,
  • Watch and iPhone have to have the same bitcode support level. And the Watch requires bitcode enabled.
Think about what this means!  7-8 years worth of iPhone 3rd party library support out there and probably used by a few applications. And these libraries will NOT work with any application that wants to bundle with WatchOS 2.0. The proverbial 'what were they thinking?' comes to mind.

So, I'm stuck: can't integrate with 3rd party library until rebuilt...

The calendar looks rough for Apple:
  • September 9th announcements; WatchOS2 and some new hardware
  • Then they turn on the holiday season marketing; "buy our watch, it has apps"
  • In the mean time, a mountain of developers are trying to figure out how to ship anything on the Watch
  • New message "trust us, our developers will eventually catch up"


Tuesday, August 18, 2015

WatchOS 2.0 beta5: development productivity increases!

I've been trying to characterize a beta5 issue where the CMSensorRecorder system doesn't reliably dequeue. There is some combination of being on the charger and then off and then starting a new debug session where the thing just works. For now, juggling with the Watch on and off the charger along with the occasional restart of debugger and I've managed to get 10 or more debug sessions. Ridiculous productivity tonight! The result is some progress on understanding how the system works.

As of now, the sample program:
  • Can kick off the CMSensorRecorder for a defined number of minutes
  • When the Watch application is in foreground, it will dequeue whatever records are found and then send them to the iPhone
  • The iPhone will dequeue the records and test them for consistency by looking for gaps in the sensor record date stamps.
Here is what the displays look like now:


Above, you will see the new gapError count. This is a consistency of data check; a quick check to ensure that all data is sequential and updating at 50Hz (the count of 1 is expected; the first element since program launch).

Updated code is here.

Next up is to plumb AWS back into the rig to send this data to Kinesis...

Monday, August 17, 2015

A visit to the Computer History Museum

I spent an afternoon at the Computer History Museum the other day; a place I haven't visited since their remodel. The presentation is definitely an improved exhibit style tour. Also, a much larger collection with improved descriptions of the various artifacts.

I have to admit, I probably should have worn suspenders and a scruffy beard. That I knew the details of, and in fact worked with, so many of the artifacts in the building was a little scary. Yes, get off of my lawn...

This visit did remind me of another project I have in the backlog:
This is a Polaroid photograph of my desk, circa 1976. A picture of my first digital computer. A hand made Intel 8008 based computer.

This machine (video game) connected to a television for display and had various input and output devices:

  • cassette tape
  • joysticks
  • address and data switches
  • address and data lights
  • and video output
It turns out I have a bundle of design and code papers for this machine (e.g. the blueprint on the world map at the back of the photo). And a few years ago, from those drawings and machine code, I re-animated the programs in a cycle-accurate machine emulator. Actually, a more accurate description would be to reverse-engineer some partial drawings and code to try to figure out what was intended and then to make an emulation. It was quite an experience to see the programs alive again.

I did the original emulation as a java/swing application. It is now time to port this over to javascript so anyone can run it in their browsers.

I'll scan a few of the drawings and post an update with the details and architecture of this machine. Makes for a good experiment at least.


Sunday, August 16, 2015

WatchOS beta5: CMSensorRecorder working again (almost)

The Journey of Instability is alive and well.

I have been working the last 4 days to get around this error when attempting to dequeue CMSensorRecorder messages (filed as bug 22300167):
Aug 16 18:23:43 Gregs-AppleWatch sensor WatchKit Extension[174] <Error>: CoreLocation: Error occurred while trying to retrieve accelerometer records!
During a couple dozen debug attempts I was able to see data flowing only once.

Again, it is fun to be on the pre-release train with Apple. Yes, they work hard to improve features at the expense of stability. The balance between getting things working and presenting a stable interface is a tough one to manage. I know this looks better inside the company, where folks can know in advance to not use experimental interfaces. From the outside, the every-two-week, do it a different approach way is tiring. This will slow the adoption of novel features I'm sure.

Here's what the workflow was like to get to this point:
  • beta5 upgrade of XCode, iOS9, WatchOS2 (~ 5 hours)
  • discover that the metadata in the existing sensor project is somehow incompatible
  • manually copy over the code to a newly generated project, now simulator and hardware are working (~ 8 hours)
  • port the sensor recorder using the new protocol (a mere 20 minutes)
  • after numerous sessions to real hardware (simulator doesn't support accelerometer) realize that I don't know how to work around the above bug (~ 8 hours)
As many of you have lived; the repeated reboots, hard starts, 'disconnect and reconnect', yet another restart because the iPhone screen is wedged, restart debug session because it times out, etc. isn't the most productive development environment. But I persist.

Code is updated here. Works most of the time now. Working on additional tests around restart, etc.


Wednesday, August 12, 2015

Whoops! beta5 has a new protocol for CMSensorRecorder...

I guess my earlier post noting that the batch based fetch could use an inclusive/exclusive flag is moot. Apple have removed that method call in beta5. Here are the sensor interfaces in beta5:
  • public func accelerometerDataFromDate(fromDate: NSDate, toDate: NSDate) -> CMSensorDataList?
  • public func recordAccelerometerForDuration(duration: NSTimeInterval)
Lovely. This means now, in addition to dealing with the 'up to 3 minutes' delay in retrieving data, we now need to keep NSDate fences for iterative queries. The documentation is a little ambiguous as to what data values should be used. I'll guess they are actual sample dates (document hints at 'wall time'). We'll see.

Anyway the beta5 upgrade is going ok, I'll port to a new style next (to also see if fromDate is inclusive or exclusive for returned samples). I'll also check to see if the CMSensorDataList needs to be extended to include generate().

Monday, August 10, 2015

Cleaner approach to distributing CMSensorRecorder data

I've taken another path for handling accelerometer data.  Recall:
  • CMSensorRecorder does continuous sampling, but the data visibility is slightly delayed
  • WCSession.sendMessage requires both watch and iPhone apps to be active and in focus
  • A Watch application's threads pretty much will not be scheduled when the watch is quiescent or another application is running
  • The goal is to have an application running on the Watch that does not require continuous access to the iPhone -- instead, enqueuing data for later delivery
  • Don't forget NSDate still can't be sent through WCSession... (until beta5?)
All of the above make it difficult to have continuous distribution of accelerometer data off the Watch. There still may be some technique for having a system level background thread using complications, notifications, etc. I haven't found it yet. So, for now, I will simply distribute the data when the application is running on the Watch.

Let's try WCSession.transferUserInfo() as the transfer mechanism. The flow on the Watch is roughly:
  • CMSensorRecorder starts recording as before
  • An independent dequeue enable switch will start a timer loop on Watch
  • When the timer fires it will look for and enqueue any new batches of sensor data from the recorder
This works pretty well. Sensor data is recorded, a polling loop is fetching data from the recorder and queueing the data for send to the iPhone. Then, when the iPhone is reachable, the data gets sent and handled by the phone app.

Code is here.  Some screen shot examples are here:




The astute reader will notice the difference between batchNum and lastBatch above (835 vs 836). batchNum is the next batch we are looking for and lastBatch is the last batch handled.  I think this is a problem in the api -- basically my code needs to know that batch numbers monotonically increase so it can inclusively search for the next batch after what has been handled.  This seems to be a bit too much knowledge to expose to the user.  I suggest that the call to CMSensorRecorder.accelerometerDataSince(batchNum) should be exclusive of the batch number provided.  Or, add an optional parameter (inclusive, exclusive) to keep the API more or less compatible.

Next up:
  • Getting on beta5 s/w stack (Xcode, iOS9, WatchOS2)
  • Going back to attempt native object transfer from Watch to iPhone
  • Moving the iPhone data receiver to a first class background thread
  • Adding the AWS Cognito and Kinesis support for receiving sensor data

Saturday, August 1, 2015

Relabelling cans: an afternoon at SF/Marin Food Bank

Family is back in town and we found ourselves at the SF/Marin Food Bank today.  This session turned into quite an assembly line.  Our shift wound up re-labelling and packaging 17,000 cans of Chicken Broth:


Was a nice afternoon, and we can skip the YMCA for today.

Sign up!  It is easy.