Summary of Evidence Against I Sea App

Yesterday evening the twitter account SwiftOnSecurity began raising concerns that the I Sea App might be a fake.

The app claims to assign users random slices of the ocean to review and flag possible refugee boats that might need rescue.

The app had been getting a lot of international news attention, but something struck her as off and she asked for confirmation.

Not having anything better to do, I thought I might look into it.

I wired my phone up to Fiddler and installed the app to see what sort of network requests it made to operate. I hoped this would show me if it really did download satellite imagery from somewhere.

Imagery

(JSON Formatted for Clarity)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
POST http://www.iseaapp.com/api/maps/get HTTP/1.1
Host: www.iseaapp.com
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Connection: keep-alive
Accept: */*
User-Agent: I%20SEA/1.11 CFNetwork/758.4.3 Darwin/15.5.0
Accept-Language: en-us
Content-Length: 9
Accept-Encoding: gzip, deflate
isApp=yes
HTTP/1.1 200 OK
Date: Mon, 20 Jun 2016 01:00:23 GMT
Server: Apache/2.2.15 (CentOS)
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT
Access-Control-Allow-Origin: *
Content-Length: 332
Connection: close
Content-Type: text/html; charset=UTF-8
{
"res":"success",
"u_latitude":33.864370597442,
"u_longitude":15.296639353037,
"zLevel":13,
"maps": {
"id":"1",
"area":"Mediterranean Sea",
"start_latitude":"33.59826334",
"start_longitude":"15.15001293",
"end_latitude":"34.16464287",
"end_longitude":"15.43188585",
"image_file":"http:\/\/www.iseaapp.com\/images\/newimg.png",
"received_on":""
}
}

Initial load POSTs to /api/maps/get and receives instructions to download the image http://www.iseaapp.com/images/newimg.png.

Other twitter users indicated that this was the exact same image they were shown.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
GET http://www.iseaapp.com/images/newimg.png HTTP/1.1
Host: www.iseaapp.com
Connection: keep-alive
Accept: */*
User-Agent: I%20SEA/1.11 CFNetwork/758.4.3 Darwin/15.5.0
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: keep-alive
HTTP/1.1 200 OK
Date: Mon, 20 Jun 2016 01:00:24 GMT
Server: Apache/2.2.15 (CentOS)
Last-Modified: Fri, 10 Jun 2016 15:27:59 GMT
ETag: "181792-335030-534ee2f0d124b"
Accept-Ranges: bytes
Content-Length: 3362864
Connection: close
Content-Type: image/png
*** Binary Data Omitted ***

There is nothing in the request or response that indicates this image is unique to me. It appears to be a static image hosted on their server.

Fiddler shows metadata for images, and extracted the following from the downloaded image:

Fiddler Metadata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
Format: PNG
3,362,864 bytes
958w x 1,725h
2.03 bytes/px
72 dpi
Color: RGB+Alpha 8bits/sample
COMMENTS (15,259 bytes)
-----------
iCOMMENT [Plain ]: 'XML:com.adobe.xmp/'='<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.5-c021 79.154911, 2013/10/29-11:47:16 ">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
xmlns:tiff="http://ns.adobe.com/tiff/1.0/"
xmlns:exif="http://ns.adobe.com/exif/1.0/">
<xmp:CreatorTool>Adobe Photoshop CC (Macintosh)</xmp:CreatorTool>
<xmp:CreateDate>2016-06-09T20:43:40+08:00</xmp:CreateDate>
<xmp:ModifyDate>2016-06-10T20:36:45+08:00</xmp:ModifyDate>
<xmp:MetadataDate>2016-06-10T20:36:45+08:00</xmp:MetadataDate>
<dc:format>image/png</dc:format>
<photoshop:ColorMode>3</photoshop:ColorMode>
<xmpMM:InstanceID>xmp.iid:15f381de-bd16-4117-b1a2-80a30e0c15c5</xmpMM:InstanceID>
<xmpMM:DocumentID>xmp.did:33aa7175-f9a2-47d3-8ab2-b829e2822d12</xmpMM:DocumentID>
<xmpMM:OriginalDocumentID>xmp.did:33aa7175-f9a2-47d3-8ab2-b829e2822d12</xmpMM:OriginalDocumentID>
<xmpMM:History>
<rdf:Seq>
<rdf:li rdf:parseType="Resource">
<stEvt:action>created</stEvt:action>
<stEvt:instanceID>xmp.iid:33aa7175-f9a2-47d3-8ab2-b829e2822d12</stEvt:instanceID>
<stEvt:when>2016-06-09T20:43:40+08:00</stEvt:when>
<stEvt:softwareAgent>Adobe Photoshop CC (Macintosh)</stEvt:softwareAgent>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<stEvt:action>saved</stEvt:action>
<stEvt:instanceID>xmp.iid:cbe8695e-440f-4744-92f8-19c61e3a012e</stEvt:instanceID>
<stEvt:when>2016-06-09T21:05:58+08:00</stEvt:when>
<stEvt:softwareAgent>Adobe Photoshop CC (Macintosh)</stEvt:softwareAgent>
<stEvt:changed>/</stEvt:changed>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<stEvt:action>saved</stEvt:action>
<stEvt:instanceID>xmp.iid:15f381de-bd16-4117-b1a2-80a30e0c15c5</stEvt:instanceID>
<stEvt:when>2016-06-10T20:36:45+08:00</stEvt:when>
<stEvt:softwareAgent>Adobe Photoshop CC (Macintosh)</stEvt:softwareAgent>
<stEvt:changed>/</stEvt:changed>
</rdf:li>
</rdf:Seq>
</xmpMM:History>
<tiff:Orientation>1</tiff:Orientation>
<tiff:XResolution>720000/10000</tiff:XResolution>
<tiff:YResolution>720000/10000</tiff:YResolution>
<tiff:ResolutionUnit>2</tiff:ResolutionUnit>
<exif:ColorSpace>65535</exif:ColorSpace>
<exif:PixelXDimension>958</exif:PixelXDimension>
<exif:PixelYDimension>1725</exif:PixelYDimension>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>'

The image was at least processed (if not completely created) by Photoshop.

All of this strongly points towards the app not being wired up to a real satellite image system.

Google Maps Integration

As you scroll around, the app fires off multiple requests to a Google maps API. The need for this is unknown, as Google maps could only return imagery from months or even years ago.

Goggle Maps Request
1
2
3
4
5
6
7
8
9
10
11
12
POST https://clients4.google.com/glm/mmap HTTP/1.1
Host: clients4.google.com
Content-Type: application/binary
Transfer-Encoding: Chunked
Proxy-Connection: keep-alive
Accept: */*
User-Agent: com.grey.isea/1.0.11 GMS-SDK/1.11.21919.0 iPhone/9.3.2 hw/iPhone7_2 (gzip)
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: keep-alive
*** Binary data omitted ***

I suspect there was a drop-in maps widget the developers used so they wouldn’t have to implement any logic to translate scrolling and zooming to a bounded rectangle of latitude and longitude.

Submitting a Report

To submit a report, I had to give my first and last name, my email address and my “Passport”. Nothing was explained about what this “passport” field represented: a passport number? A country from which I have a passport? It seems like a very unusual, and highly personal piece of information to collect.

Luckily the lack of validations accepted "eh" and I was able to submit a test report

Create User
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
POST http://www.iseaapp.com/api/user/save HTTP/1.1
Host: www.iseaapp.com
Content-Type: application/json
Connection: keep-alive
Connection: keep-alive
Accept: application/json
User-Agent: I%20SEA/1.11 CFNetwork/758.4.3 Darwin/15.5.0
Content-Length: 128
Accept-Language: en-us
Accept-Encoding: gzip, deflate
{
"lastname":"smith",
"uuid":"BE4D6A15-****-67A83DB43EF4",
"passport":"eh",
"firstname":"John",
"email":"m@mailinator.com"
}
HTTP/1.1 200 OK
Date: Mon, 20 Jun 2016 01:13:23 GMT
Server: Apache/2.2.15 (CentOS)
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT
Access-Control-Allow-Origin: *
Content-Length: 94
Connection: close
Content-Type: text/html; charset=UTF-8
{
"res":"success",
"user_id":"330",
"firstname":"John",
"lastname":"smith",
"message":"Registered"
}
Save Report
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
POST http://www.iseaapp.com/api/reports/set HTTP/1.1
Host: www.iseaapp.com
Content-Type: application/json
Connection: keep-alive
Connection: keep-alive
Accept: application/json
User-Agent: I%20SEA/1.11 CFNetwork/758.4.3 Darwin/15.5.0
Content-Length: 1734919
Accept-Language: en-us
Accept-Encoding: gzip, deflate
{
"comments":"test",
"user_id":"330",
"screenshot":" *** LONG STRING OMMITTED ***",
"latitude":34.135643,
"longitude":15.307302,
"user_id":"330"
}
HTTP/1.1 200 OK
Date: Mon, 20 Jun 2016 01:13:24 GMT
Server: Apache/2.2.15 (CentOS)
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT
Access-Control-Allow-Origin: *
Content-Length: 126
Connection: close
Content-Type: text/html; charset=UTF-8
{
"res":"success",
"report_id":"560",
"message":"Registered",
"userMailAck":{
"res":"success"
},
"acknowledgement":{
"res":"success"
}
}

The submission did include the latitude and longitude of the area in which I clicked, along with a text encoded “screenshot”. The screenshot is encoded in a format I’m not familiar with and haven’t yet decoded.

The first few lines of it look like this:

Screenshot Encoding (replaced escaped "\r\n" with real newlines)
1
2
3
4
5
iVBORw0KGgoAAAANSUhEUgAAAu4AAAM0CAYAAADkz6c3AAAAAXNSR0IArs4c6QAA
AAlwSFlzAAAWJQAAFiUBSVIk8AAAABxpRE9UAAAAAgAAAAAAAAGaAAAAKAAAAZoA
AAGaAAkG68VuZEsAAEAASURBVHgB7L3Zk23XcZ+JV7ffbIdt0RLureHUqVNz3amq
7jzP92KeORMiQRKcwQEkAILETMzzxJkiLVmi3B66ZVu2o21FdDgUHWFbTy13v\/ip
+7\/Y\/X2\/3PucU4V7LwCClNRhPGTsM+y9Vq7MXGv9Mleuta\/6n\/7DXza\/Lvrb\/\/G\/
If anyone recognizes this encoding (its not base64) please let me know and I’ll see about decoding the whole string.

Update: It is base64 after-all, but the JSON encoding did some escaping. I deleted \r\n characters and turned \/ into literal / and was then able to base64 decode the string into a png file. HT: @joe_h_punk

Email

Finally, the mailinator account I used to sign up received an email

Dear John

Thank you for helping us test out this application. We will not be able to give individual details to you due to the high volume of responses but we will be informing our users of the effects their efforts have had after the testing period is over. Your efforts will help transform ours.

Thanks, I SEA Team

It’s interesting that they are calling it a test. I didn’t read all the news coverage, but I’m not aware of any indicating it was anything other than a real app.

Conclusions

None of the technical discovery really points to a motivation and I don’t care to speculate on that front.

From the app level, all the infrastructure they would need to actually work is there: the API could point different users to different images, and it does appear to accept all the data you might expect for a given report.

It just seems its not actually hooked up to anything, and in fact, would likely be prohibitively expensive to do so.