티스토리 뷰

[출처 : http://blogs.soph-ware.com/?p=14 ]
엄청난 글을 보고 깜짝 놀라고 말았습니다.
SWF는 공개된 포맷이라 보안에 취약한 점이 없지 않아 있습니다.

그런데.....좋은 방법이 나왔군요..
아니 왜 이런 생각을 못했을까..머리속을 탁 스치고 지나갔습니다..
공인인증서도 생명이 다 한듯 하네요 ^^
금융결제감독원?? 인가에서 발행되는 인증서가 4,400인데..쩝..
내년부터 강제라죠.. 그런데 암호화만 할 수 있고 디컴파일을 해도 알 수만 없다면..게임 끝입니다.
그들도 모라 할 수가 없게 되는 거죠..

Why Obfuscate, Encrypt those SWFs!

A little over a month ago, somebody posted this question to the Flexcoders mailing list asking about encrypting SWF’s to prevent them from being “captured” by applications or individuals. The solution is fairly simple, “encrypt the SWF!” But how would the Flash player handle that you might ask? Let’s find out.

Introduction

Here’s the quick summary of how everything is going to work:

  1. Encrypt the real SWF using a standalone application, or integrate encryption into a web service.
  2. Create a wrapper SWF that loads the encrypted SWF from the server using the same symmetric key and initialization vector.
  3. Upload the SWF’s to your server as usual.
  4. Sit relaxed knowing nobody can intercept your SWFs.

Background

As can be seen in the above steps, the wrapper SWF is loaded by the Flash Player, so it doesn’t have to do anything special and everything is basically transparent to the user.

Now let’s go into a bit more background on encryption and how this will work.

Most modern encryption is based on one of two different algorithms, symmetric key algorithms or asymmetric key algorithms.

In symmetric key algorithms, both the sender and the receiver use the same key. In other words, the same key is used to encrypt the message as is used to decrypt the message. Thus, if anybody can figure out what that shared key is, and obtains a copy of the encrypted data, they can then decrypt that data.

Asymmetric key algorithms use a public key and a private key. Both the sender and the receiver usually have different public and private keys. Let’s say that John and Tom decide they want to send encrypted messages back and forth. John then creates a public and a private key and gives his public key to Tom. Similarly, Tom creates a different public key and private key and gives his public key to John. To send an encrypted message to Tom, John only needs to use John’s public key to encrypt his message, after which it can be sent to John. Then John, using his private key (which only he has a copy of), can decrypt the message to see what John had to say about how great a conference they put on.

As it turns out, symmetric keys are better for transmitting a lot of information, so that’s the approach that I’ll take. Specifically, I’ll use the Advanced Encryption Standard (AES) algorithm which is a combination block/stream cipher. I’ll use it to operate on a stream of bits (the SWF we will be encrypting and decrypting), but internally it’s operates on one block at a time, thus requiring a padding algorithm.

Since AES operates on blocks of streaming data, there has to be at least one blocks worth of data to operate on, thus, at the end of the SWF we usually will not have exactly the right number of bits, so we will pad the real bits with a few extra bits using a known padding algorithm. This also means our SWF might end up a few bytes larger.

Encrypt Your SWF

The first thing you’ll need is a “real” SWF that we can encrypt. The one that I’ll use for this example has a red background with the text “Hello Encrypted SWF World!” on it as can be seen below, or you can try it out here:

Now that we have a real application, we need to encrypt it. To try this out yourself, you’ll need this Java Program to encrypt your SWF. You simply give it a few arguments on the command line as follows:

# compile the .java file (only necessary the first time
javac AesEncrypter.java
# NOTE: The following should be on one command line, the backslashes escape
# the newline allowing it to be on multiple lines.
java AesEncrypter 01020304050708090a0b0c0d0e0f0001 \
 01020304050708090a0b0c0d0e0f0001 \
SampleSwf.swf \
SampleSwf.eswf

And the output will look something like the following:

key:01020304050708090a0b0c0d0e0f0001
Bytes:32
iv:01020304050708090a0b0c0d0e0f0001
Bytes:32
Cipher mode: AES/CBC/PKCS5Padding
Name:SampleSwf.eswf and size: 152480

Other tools besides my Java program can be used for the AES encryption, as long as the encryption and padding algorithms match up, it doesn’t matter which program does the encryption. I have a C# program that could easily be adapted to do the same thing. (The AES algorithm is actually the Rijndael algorithm with a few restrictions applied, so it’s more popular than some people think.)

On the ActionScript side, I must note that the EncSwfLoader requires the awesome as3crypto libraries. Without such a good encryption library for Flex/Actionscript, this wouldn’t be possible! I just grabbed the swc of the as3crypto site and everything worked exactly as expected.

Create a Wrapper SWF

Now that are SWF has been encrypted, we need a wrapper that will load the encrypted SWF, decrypt it, and display it. Let’s take a look at some code. First, we want to be able to load a encrypted SWF just as if it were a regular SWF, so I’ll subclass SWFLoader. It’s usage follows:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
    xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:comp="com.sophware.controls.*"
    layout="vertical"
    >
    <comp:EncSwfLoader
        source="http://blogs.soph-ware.com/posted-content/files/sampleswf/SampleSwf.eswf"
        hexKey="01020304050708090a0b0c0d0e0f0001"
        hexIv="01020304050708090a0b0c0d0e0f0001"
        />
</mx:Application>

Now that’s pretty simple. I just generated a not-quite random 32 bytes and placed them (in hex form) in the hexKey and hexIv properties of the EncSwfLoader. As long as nobody finds out what the key is, they won’t be able to break the encryption. The hexIv is the initialization vector, also in hex form. Although this need not be kept secret, at might as well be.

Upload the SWF

For this example, I assume you know how to do that. My examples are here:

Sit back and relax!

Now how safe is the encryption being used above? The default encryption type is AES using a CBC mode. AES is certified for government Top Secret data. In other words, it’s pretty safe. The only danger is that someone downloads the wrapper SWF, decompiles it, discovers the encryption key, intercepts the encrypted SWF being downloaded, and then uses some other program to decrypt the SWF, assuming of course that they grabbed the initialization vector at the same time they were looking at the SWF. Oh, and a couple of other little details, they would have to know it’s using CBC mode and discover the padding algorithm. So, in other words, it’s pretty safe. Yes, it’s still possible for somebody to figure out what was sent, but they would really want to know and it would be non-trivial and require extra tools. Even though I know how… I don’t think I would ever bother!

The end result, will look like a normal SWF application. Here’s a screenshot, or take a look at the real application here:

So what are the downsides of this?

  • You have to encrypt your SWF
  • It takes some processing time to decrypt the SWF
  • The encrypted SWF will usually be larger by up to 31 bytes
  • Nobody can “borrow” your SWF and thereby help make you famous!

A few of you might be thinking, but that’s not good enough — I absolutely can’t have anybody intercept or decrypt my SWF, what do I do? The short answer is — it’s possible. The long answer is — perhaps I’ll discuss it in some other blog post :).

Related Links

For interested parties, here are some relevant links on Wikipedia. Also note that I’ve been a little lax about terminology, so please forgive me if that’s bothered you:

Cryptography
Cipher
Symmetric Key Algorithm
Asymmetric Key Algorithm
Private Key Cryptography
Public Key Cryptography
Block Cipher
Stream Cipher
Padding Algorithms
Advanced Encryption Standard (AES)

NOTE: Following text added Apr 18, 2008 after comments #1 through #3 were posted:

Purpose and Preventative Target

Cédric Tabin and others have asked about the purpose of this. To the question, “Isn’t this completely a waste of time?”, I answer “It depends!”

When Ritesh Yadav posted his original question, I saw the main issue as being that anybody with some reasonable computer or HTML experience could easily figure out how to save the SWF to disk, allowing them to use that SWF in an environment where it wasn’t originally intended. Perhaps that environment is one where no adds are served, and therefore, the author is unable to make money based on the work that they did.

If the purpose is to prevent somebody from saving the SWF to disk, this works great and does exactly what it’s supposed to do. As such, it is not a waste of time.

If, however, the purpose is to prevent somebody determined from getting the code to your SWF, which is basically impossible, then this might be a waste of time and will only slow the a capable hacker down requiring an extra two or three steps. Any determined and capable hacker can decompile or otherwise reverse engineer just about anything, which includes this process.

One way in which a hacker might break this procedure follows:

  1. Decompile the wrapper SWF
  2. Retrieve the shared private key and the initialization vector
  3. Intercept the real SWF as it is downloaded
  4. Use the exact same encryption algorithm and its parameters to decrypt the SWF
  5. Decrypt the real SWF

In private correspondence with Cédric Tabin, he pointed out another possible point of attack:

  1. Debug the wrapper SWF, breakpointing at the location where the decryption has been done.
  2. Grab the stream of bytes that are being sent to the SWFLoader
  3. Write the bytes to disk or otherwise inspect the real SWF

I’m not exactly sure how the latter may work, never having tried to debug a release SWF, but I could certainly do such a thing with C or C++, so it’s definitely a feasable approach. Furthermore, the actual Flex/SWF debugger could by bypassed by using a C/C++ debugger with the Flash Player directly.

Summary

This approach is not intended to make it impossible for somebody to get to the real SWF, only to make it “impossible” for an average or better than average computer user (e.g. not a hacker) to grab the SWF. This approach is also not intended to be complete. By adding TLS and/or random key and iv generation to the mix, which would require a service on the server side, it can be made much more difficult for a hacker to get at the real SWF.

I hope this clarifies. Thanks for your comments and feedback.

신고
댓글
  • 프로필사진 Favicon of http://blog.flashplatform.kr BlogIcon 검쉰 검색할때 플래시파일의 내용도 검색가능하게 할꺼라던거 뭐라던가 하던데, 음.. 2008.07.12 00:53 신고
  • 프로필사진 Favicon of http://lovedev.tistory.com BlogIcon Kevin lovedev 서버사이드에서 SWF를 생성해서 만들어 본적은 있는데 왜 암호화를 해볼 생각은 안했는지..^^;

    그런 검색나와도 소용없을꺼 같아요. 소스코드를 검색하려는 사람이 있다면 몰라도 ㅋㅋ

    근데 오늘 오셨었어요? 캠프 오신다고 이야기는 들었었는데..쩝..
    2008.07.12 22:25 신고
  • 프로필사진 Favicon of http://blog.flashplatform.kr BlogIcon 검쉰 갔었습니다!!!
    저 질문 뽑혀서 책도 받고 제가 있던 팀에서 티셔츠도 받았어요 ㅎㅎ
    오창훈님도 오셨군요! 전화번호라도 알았으면 인사라도 드리는건데... 음;; 완전 아쉽습니다.
    2008.07.13 12:06 신고
  • 프로필사진 Favicon of http://lovedev.tistory.com BlogIcon Kevin lovedev 와...축하 드려요..
    그러게요 완전 아쉽네요.. ^^;

    소통의 시간 때 어이없게 갑작스레.. 추가 보충 설명하라고 발표하게 되었었는데..
    기억하실런쥐 ㅋㅋ ..
    아 생각하면 챙피해 죽겠어요 :)
    "갑자기 일어나서 뭘 말해야 할지 모르겠는데..혹시 질문 있으신분~ 했던.."
    2008.07.14 15:27 신고
  • 프로필사진 Favicon of http://blog.flashplatform.kr BlogIcon 검쉰 아.. 기억납니다. ㅋㅋ
    전 4조에서 발표할때 횡설수설하던 녀석입니다. ㅋ
    2008.07.14 15:52 신고
  • 프로필사진 Favicon of http://blog.jidolstar.com BlogIcon 지돌스타 오셨었군요. ㅎㅎㅎ 2008.07.14 15:15 신고
  • 프로필사진 Favicon of http://lovedev.tistory.com BlogIcon Kevin lovedev ㅋㅋㅋ 넵 갔었습니다 ^^
    만나뵈서 정말 즐거웠습니다.. :)
    초대장도 받았겠다..스타플 가입해보려고요 ㅋㅋ
    나중에 또 뵈요~ ^^
    2008.07.14 15:24 신고
  • 프로필사진 비밀댓글입니다 2009.02.18 22:00
댓글쓰기 폼