Exchange ActiveSync Building Blocks – Remote Wipe

Index for the series:
Exchange ActiveSync Building Blocks – Intro

Background reading (not a pre-requisite):
[MS-ASCMD] Common Status Codes
[MS-ASPROV] Directing a Client to Execute a Remote Wipe
[MSDN] Provisioning, Policies, Remote Wipe, and ABQ in Exchange ActiveSync

In the previous installment in this series we looked at how security policies are pushed down to our Exchange ActiveSync clients, and how to deal with them, or for that matter circumvent them. Thus I thought that it would be suitable to cover a topic highly related to implementation of security policies – how to handle remote wipe 🙂

When dealing with the "wipe" concept there are two kinds of wipes we need to be aware of; local wipe and remote wipe.

A local wipe is one that is triggered on the device, usually without any contact with any servers or networks. The most common triggering mechanism would probably be that there’s a security policy in place stating that a failed password x number of times will result in the device hard resetting itself. This policy does not necessarily have to be enforced from Exchange, but in an enterprise scenario users usually aren’t configuring these settings themselves. (Many users don’t enable this setting on their device, and this makes no sense to me; I have content on my device that I don’t want everyone to read even though we’re not talking government level secrets.) Technically it would be a local wipe if you were to choose "reset" in the settings/configuration part of your device as well, but we can probably agree that that’s not relevant to this discussion 🙂

A remote wipe is one that is triggered from a central location/server, without any user interaction. For the sake of this article we assume that this server is an Exchange Server, but there are plenty of Mobile Device Management products that also implement this feature either through their own client or employing supporting features in the operating system of the device. A wipe could be triggered both by an SMS message or IP-level notification, but Exchange prefers IP. (There are scenarios where an SMS could trigger a wipe from Exchange as well, but we’re keeping that out of scope as it is not the default to use SMS.) Note that the implementation of this wipe comes in different forms – some ActiveSync clients might interpret the wipe to only remove the data related to the Exchange synchronization partnership, while others will do a full reset of the device. (The latter being the more common.)

Since the Exchange ActiveSync protocol is not the triggering factor in a local wipe, (even if EAS was responsible for deploying the policy), we will concern ourselves only with the remote wipe option.

As with most things ActiveSync there is a process a device has to go through after the end-user or administrator has selected a device for wiping:
– A status of “140” is returned to the device when it tries to synchronize. This status code informs the device that a remote wipe has been issued server side.
– The device performs a provision request (just like it does when pulling down security policies).
– The Exchange Server returns a wipe WBXML response. In "plain xml format" it looks like this:

<?xml version="1.0" encoding="utf-8"?>
<Provision>
<Status>1</Status>
<RemoteWipe />
</Provision>

– The device acknowledges (ACKs) this response basically saying "yes, I am now initiating a wipe of myself”.

– The Exchange Server ACKs that is has received the client ACK.

– The Exchange Server fires off a mail from the user, to the user, informing that the wipe was successful.

This means that the device ACKs the wipe before it has actually wiped itself, but if it had wiped itself first then it wouldn’t have any means to ACK it either so that would be by design. The client should preferably have mechanisms included that ensures it will perform the wipe even if it loses connectivity, or someone pulls out the battery in the middle of the process. (This is not the responsibility of the Exchange Server.)

You’ll also note that the wipe itself isn’t sent directly as a response to the initial sync attempt; the device specifically has to request to be wiped. By this we also see that a wipe can only be initiated on a device which has indicated itself as provisionable. If it isn’t provisionable it isn’t wipeable.

When the device requests the wipe it can use a PolicyKey equal to 0 (just to confirm it’s provisionable), but when ACKing the wipe it is not necessary to use the new PolicyKey that was provided to it with the wipe WBXML. I have however included parsing and outputting of the key in my diagnostic tool even if we don’t have to do so.

A funny thing I noted is that since the wipe is handled through the "standard" provisioning mechanism I was informed that I would not be allowed to wipe myself before providing full details about the device when I used EAS version 14.1 (I find this to be rather strict, and not really necessary either I suppose).

After the device has been wiped you will have to remove the synchronization partnership, (from OWA for instance), before the same device is allowed to sync again. If you recover your device, or it was wiped by mistake you can easily get it up and running again. However if it is reconnected with a different user account it seems to be able to sync again, so it’s not a permanent ban.

Anyways; let’s take a walk through of how this affects us on a coding and testing level:

– Make sure that you have a fake device synced up to your Exchange. You could use the test app in Part 5 of this series to do so.

Status for the device should be “OK”.

image

Select "Wipe Device", and notice how the status changes to "Wipe Pending".

image

The UI this time around is pretty similar to the previous test apps:

image

The status should also reflect the ACK:

image

And you’ve got mail:

image

Coding is pretty similar to the previous walkthrough of provisioning, so I’ll only include parts of it below (the rest is downloadable as per usual).

Notice that I am using ASVersion 14.0 to avoid having to provide device information as mentioned earlier.

//WBXML for requesting wipe
byte[] postReqWipe = new byte[41] {
0x03,0x01,0x6a,0x00,0x00,0x0e,0x45,0x46,0x47,0x48,0x03,0x4d,
0x53,0x2d,0x45,0x41,0x53,0x2d,0x50,0x72,0x6f,0x76,0x69,0x73,
0x69,0x6f,0x6e,0x69,0x6e,0x67,0x2d,0x57,0x42,0x58,0x4d,0x4c,
0x00,0x01,0x01,0x01,0x01
};

//WBXML for ACKing wipe
byte[] postAckWipe = new byte[67] {
0x03,0x01,0x6a,0x00,0x00,0x0e,0x45,0x46,0x47,0x48,0x03,0x4d,
0x53,0x2d,0x45,0x41,0x53,0x2d,0x50,0x72,0x6f,0x76,0x69,0x73,
0x69,0x6f,0x6e,0x69,0x6e,0x67,0x2d,0x57,0x42,0x58,0x4d,0x4c,
0x00,0x01,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x01,0x4b,0x03,0x31,0x00,0x01,0x01,0x01,0x4c,
0x4b,0x03,0x31,0x00,0x01,0x01,0x01
};

(...)

string uri = 
strServerAddress + "/Microsoft-Server-ActiveSync" + "?Cmd=Provision&User="
+ strUsername + "&DeviceId=" + strDeviceId + "&DeviceType=" + strDeviceType;

HttpWebRequest webRequestWipe = (HttpWebRequest)WebRequest.Create(uri);
webRequestWipe.ContentType = "application/vnd.ms-sync.wbxml";

webRequestWipe.Method = "POST";
webRequestWipe.Headers.Add("Authorization", "Basic " + strEncCredentials);
webRequestWipe.Headers.Add("MS-ASProtocolVersion", strASVersion);
webRequestWipe.UserAgent = strUserAgent;
webRequestWipe.Headers.Add("X-MS-PolicyKey", "0");          

webRequestWipe.ContentLength = postReqWipe.Length;
try
{
Stream sw = webRequestWipe.GetRequestStream();
sw.Write(postReqWipe, 0, postReqWipe.Length);
sw.Close();
txtOutput.Text += "Requesting wipe " + "\r\n";
WebResponse webResponseWipe = webRequestWipe.GetResponse();
if (webResponseWipe == null)
{
}

(...)

//ACK the wipe
HttpWebRequest webAckWipe = (HttpWebRequest)WebRequest.Create(uri);
webAckWipe.ContentType = "application/vnd.ms-sync.wbxml";

webAckWipe.Method = "POST";
webAckWipe.Headers.Add("Authorization", "Basic " + strEncCredentials);
webAckWipe.Headers.Add("MS-ASProtocolVersion", strASVersion);
webAckWipe.UserAgent = strUserAgent;                      

webAckWipe.ContentLength = postAckWipe.Length;
try
{
Stream sw = webAckWipe.GetRequestStream();
sw.Write(postAckWipe, 0, postAckWipe.Length);
sw.Close();
txtOutput.Text += "ACKing wipe " + "\r\n";
WebResponse webResponseAckWipe = webAckWipe.GetResponse();
if (webResponseAckWipe == null)
{
}

System.Text.UTF8Encoding utf8Encoding = new System.Text.UTF8Encoding();
StreamReader sr = new StreamReader(webResponseAckWipe.GetResponseStream());
                
string responseBody = sr.ReadToEnd().Trim();
Byte[] byteResp = utf8Encoding.GetBytes(responseBody);
txtOutput.Text += "Device has been wiped (emulated).\r\n";
}
catch (WebException)
{
}

That’s all there is to it really. You will now have a fresh and clean device either in your own hands, or in the hands of someone who just happened to find your device. If you’re feeling really creative you can code up a service/client for a Windows computer and have it reformat itself when instructed to do so by your Exchange Server Smile

Downloads:

C# Source – RemoteWipe.cs

C# Source – EAS_BB_Part-06_01.zip

One thought on “Exchange ActiveSync Building Blocks – Remote Wipe”

Leave a Reply

Your email address will not be published. Required fields are marked *

*