BLOG main image
분류 전체보기 (13)
reverse engineering (2)
troubleshooting (5)
영화감성 (4)
책감성 (2)
2,959 Visitors up to today!
Today 1 hit, Yesterday 5 hit
daisy rss
tistory 티스토리 가입하기!
2015.06.03 17:02



허즈번드 시크릿

저자
리안 모리아티 지음
출판사
마시멜로 | 2015-03-20 출간
카테고리
소설
책소개
전 세계를 강타한 베스트셀러 《허즈번드 시크릿》 국내 출간 13...
가격비교 글쓴이 평점  


아........................................

나에게 간만에 블로그에 글을 쓸 수 있도록 인도하여 준 바로 그 책....

허즈번드 시크릿.....

평점.... 별 하나.


아마존 ‘최고의 책’ 

아마존 종합 베스트셀러 1위 

[뉴욕타임스] 베스트셀러 1위 

[USA투데이]가 뽑은 필독 도서 TOP 30 

영국 최고 서평단이 뽑은 반드시 읽어야 할 도서 

2013년 미국에서 가장 많이 팔린 책 4위 

전 세계 40개국 번역 출간 

헐리우드 영화 판권 계약, 영화화 결정


오.... 뭔가 특별한게 있나 보다 싶어, 서점에서 내 눈에 콕콕 박혔었는대....


진부한 소재에 지루한 이야기 진행. 게다가 뻔한 결말.


세명의 주요인물의 시점으로 이야기는 진행된다.

초반부터 남편(허즈번드)의 비밀은 뻔해 보였고....

그 뻔한 이야기는 이야기 중반까지 나오지 않는다.

비밀이 계속 숨겨지기에 혹시 다른 반전이 있나 싶었지만.... 예상했던 그대로.....

초반에 나왔던 복선도 마지막 장면에서 어떠한 극적인 장치 없이 그대로 재사용 된다.

갈등 해결 또한 너무 뻔했고.....

주인공들의 케릭터는 빡치게 하였고....

이토록 성의 없는 책은 처음 봤다.


아오 빡쳐..

'책감성' 카테고리의 다른 글

허즈번드 시크릿  (0) 2015.06.03
흔들리며 흔들거리며  (0) 2013.10.27
Name
Password
Homepage
Secret
2015.01.14 17:55

Scapy란?


Scapy 는 인터렉티브하게 패킷을 조작할 수 있는 강력한 기능을 제공하며, 수 많은 프로토콜의 디코딩 기능과 수정된 패킷을 전송할 수 있는 기능등을 포함하고 있다.

이 도구의 큰 장점은 다양한 기능을 수행할 수 있는 것인데, 우리가 흔히 스캐닝을 하거나, 패킷덤프를 하거나, 원격 시스템의 Alive 유무를 점검 또는 공격 패킷등을 만들고자 할때 사용하는 도구들이 다 달라진다. 예를 들면, hping, nmap, arpsoof, tcpdump, tshark, p0f 등의 여러 도구의 능들 말이다. 하지만 Scapy 는 이 도구 하나로 가능하다. 너무 강력한 도구인양 소개한 것일까?

사용용도에 따라 달라지겠지만 무척이나 편리한 기능을 갖고 있는 것은 사실이다. 다만 사용하는데 있어서는 일반적인 도구에 비해서는 사용방법이 처음에는 힘들 수도 있다. Scapy 는 파이썬을 기반으로 작성되어 있는데, 사용형태가 파이썬에서 코드를 사용하는 것과 같이 사용할 수 있으므로 파이썬에 익숙해져 있는 사용자라면 더 없이 편할 것이다. 또한, Scapy 모듈을 이용하여, 파이썬에서 패킷을 핸들링 하는 프로그램을 작성한다면 간단하게 그 기능을 이용할 수 있어 개발자 관점에서도 유용하다.


출처 :  http://www.packetinside.com/2010/10/강력한-패킷-조작-프로그램-scapy-를-소개한다-첫번째.html


Ubuntu에 Scapy 설치


$ sudo apt-get install python-scapy


패킷 복호화


악성코드가 간단한 연산을 이용하여 패킷을 암호화 하고 있는 것을 발견. 통신 내용 확인을 위해 패킷 복호화.

조건 1. HTTP를 이용하여 통신

조건 2. HTTP 헤더를 이용하며, HTTP payload 부분만 암호화

조건 3. 암호 알고리즘 : 1byte 암호화로 간단한 연산을 이용함. ((EncryptionData[index] - 0x3F) ^ 0x3F)


#-*- coding: utf-8 -*-

#!/usr/bin/python

 

import sys

from scapy.all import *

import time

 

def run(target) :

    try :

        #pkt = rdpcap(target, 500)

        pkt = rdpcap(target)

    except MemoryError:

        print "Sorry - Memory Error"

        sys.exit()

    numPkt = len(pkt)

     

    print "[*] Analyzing : " + target

    print "[*] Total Packets : %d\n" % numPkt #전체 패킷의 Count를 출력, rdpcap()에서 count를 사용하지 않을시는 전체 패킷 건수를 표시

     

    packetNum = 0

     

    # 패킷을 하나씩 꺼내 온다.

    for packet in pkt:

        packetNum = packetNum + 1

         

        # 패킷안의 layer를 하나씩 꺼내 온다.

        layer = packet.payload

        while layer :

            layerName = layer.name

             

            # 해당 패킷이 IP 통신일 경우

            if layerName == "IP" :

                tcplayer = layer.payload

                 

                # TCP 통신일 경우

                if tcplayer.name != "TCP" :

                    break

                

                # HTTP Payload를 확인

                httplayer = tcplayer.payload

                if httplayer.name == "Raw" :

                    printTime =  time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(packet.time))

                    # 시간 정보와 IP.ADDR, TCP.PORT를 출력

                    print "[%s] %s:%s ---> %s:%s" %(printTime, layer.src, tcplayer.sport, layer.dst, tcplayer.dport)

                     

                    stream = httplayer.load

                    stream_len = len(stream)

                    #decode = ""

                    # 통신 내용이 4byte보다 작을 경우, HTTP 헤더 무시

                    if stream_len < 4 :

                        hexdump("".join(chr(((ord(c) - 0x3F) & 0xFF) ^ 0x3F) for c in stream))

                    else :

                        # HTTP 헤더 체크를 하여, HTTP Payload 부분만 복호화

                        if stream.startswith('POST') or stream.startswith('HTTP') :

                            decStartIndex = stream.find('\x0d\x0a\x0d\x0a') + 4

                            decode = []

                            index = 0

                            for c in stream :

                                if index < decStartIndex :

                                    decode.append(c)

                                else :

                                    decode.append(chr(((ord(c) - 0x3F) & 0xFF ) ^ 0x3F))

                                index = index +1

                            hexdump("".join(decode))

                        else :

                            # HTTP 헤더가 없을 경우, 모든 내용을 복호하

                            hexdump("".join(chr(((ord(c) - 0x3F) & 0xFF ) ^ 0x3F) for c in stream))

                break

            # 다음 레이어를 읽어온다.

            layer = layer.playload

 

# call run

run("data.pcap")




'reverse engineering' 카테고리의 다른 글

Scapy를 이용한 통신 패킷 복호화  (0) 2015.01.14
VirusTotal for IDA plugin  (0) 2014.10.15
Name
Password
Homepage
Secret
2014.10.15 22:33

소개

 

분석 도중 새로 생성하는 파일들 또는 발견되는 url과 hash 들의 VirusTotal 결과를 쉽게 확인 할 수 있는 플러그인.
Hex Blog에 공개 된 소스코드를 좀 수정 하였다. VirusTotal에서 제공하는 API 2.0으로 변경을 하였으며, UI 부분에서 약간의 변화를 주었다. 또한 파일과 url, hash를 자동으로 판별해서 정보를 요청한다.

 

 

사용 환경

  1. IDA와 python이 설치 되어 있어야 한다.
    개발 환경은 IDA 6.5, python 2.7.8
  2. python에서 simplejson 패키지를 설치한다.
    VirusTotal API 2.0이 json으로 구성되어 있다.
  3. VirusTotal 가입하여 개인 API를 발급 받어야 한다.
    발급 받은 개인 API Key는 소스의 KEY(line number 18) 부분에 넣는다.
  4. 아래 작성된 소스 파일(v4ida.py)를 플러그인 폴더에 복사한다.
    IDA plug인 폴더 = C:\Program Files\IDA 6.5\plugins (자신의 설치 환경에 따라 달라질 수 있다.)

사용법

  1. IDA 실행 후, 분석도중 alt+F8을 누르면 virustotal 검색 창을 열 수 있다. 또는 "Edit - Plugins - VirusTotal report" 를 선택한다.
    단축키는 소스코드의 wanted_hotkey 부분을 수정하여 변경 가능.
  2. Search Item 필드에 검색어를 넣은 후 Report 버튼을 누른다. 제공되는 검색 명령어는 다음과 같다.
    1. 파일 절대 경로 : 드라이브명을 포함한 풀 경로를 넣어준다. MD5 hash값을 계산하여 검색 결과를 보여준다.


    2. MD5, SHA1, SHA256 : VirusTotal에서 지원 가능한 hash 값들.


    3. URL : URL에 대한 스캔 결과를 보여준다.


  3. 검색 결과 출력
    1. 검색 결과가 있을 경우 Results 창에 출력
    2. 검색 결과 전부 정상일 경우 "All Clean" 메세지 출력
    3. 검색 결과가 없을 경우 "Signature Not Found" 메세지 출력
  4. 검색 결과가 있을 경우 해당 필드를 더블클릭하면, 웹브라우져 실행 후 구글 검색 결과를 보여준다.

    (AntiVirus 업체명 + 진단명) 을 기준으로 검색.

소스코드 (vt4ida.py)

'''
Created on 2014. 10. 14.
@author: YoungSoo Yi
@version: 1.1.0
'''
import idaapi
import idc
from idaapi import Choose2, plugin_t, Form
import webbrowser
import urllib
import urllib2
import simplejson
import re
import hashlib
import os
 
PLUGIN_TEST = 0
KEY = "    Insert your API key"
 
# -----------------------------------------------------------------------
# VirusTotal Icon in PNG format
VT_ICON = (
    "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52"
    "\x00\x00\x00\x10\x00\x00\x00\x10\x04\x03\x00\x00\x00\xED\xDD\xE2"
    "\x52\x00\x00\x00\x30\x50\x4C\x54\x45\x03\x8B\xD3\x5C\xB4\xE3\x9C"
    "\xD1\xED\xF7\xFB\xFD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD3\xF2\x42\x61\x00\x00\x00"
    "\x4B\x49\x44\x41\x54\x78\x9C\x2D\xCA\xC1\x0D\x80\x30\x0C\x43\x51"
    "\x27\x2C\x50\x89\x05\x40\x2C\x40\xEB\xFD\x77\xC3\x76\xC9\xE9\xEB"
    "\xC5\x20\x5F\xE8\x1A\x0F\x97\xA3\xD0\xE4\x1D\xF9\x49\xD1\x59\x29"
    "\x4C\x43\x9B\xD0\x15\x01\xB5\x4A\x9C\xE4\x70\x14\x39\xB3\x31\xF8"
    "\x15\x70\x04\xF4\xDA\x20\x39\x02\x8A\x0D\xA8\x0F\x94\xA7\x09\x0E"
    "\xC5\x16\x2D\x54\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82")
 
# -----------------------------------------------------------------------
class VirusTotalOpenAPI():
    API_KEY = KEY
   
    FLAG_INVALID = 0
    FLAG_FILE_SCAN = 1
    FLAG_HASH_SCAN = 2
    FLAG_URL_SCAN = 3
   
    def get_file_md5_hash(self, filename):
        f = open(filename, 'rb')
        r = hashlib.md5(f.read()).hexdigest()
        f.close()
       
        return r    
   
    def getScanType(self, rsrc):
        length = len(rsrc)
       
        if length == 0 :
            return self.FLAG_INVALID
        elif os.path.exists(rsrc) :
            return self.FLAG_FILE_SCAN
        elif len(re.findall(r"([.])", rsrc)) >= 1 :
            return self.FLAG_URL_SCAN
        elif length == len(re.findall(r"([a-fA-F\d])", rsrc)) :
            if length == 32 or length == 40 or length == 64 :
                return self.FLAG_HASH_SCAN
       
        return self.FLAG_INVALID
   
    def getScanReport(self, rsrc):
        # parameter validation check
        scan_type = self.getScanType(rsrc)
        if scan_type == self.FLAG_INVALID :
            return (False, "Invalid parameter")
        elif scan_type == self.FLAG_FILE_SCAN :
            rsrc = self.get_file_md5_hash(rsrc)
       
        # call VT API
        parameters = {"resource": rsrc,
                      "apikey": self.API_KEY}
        data = urllib.urlencode(parameters)
        if scan_type == self.FLAG_FILE_SCAN or scan_type == self.FLAG_HASH_SCAN :
            req = urllib2.Request(self.API_FILE_SCAN_REPORT, data)
        else :
            req = urllib2.Request(self.API_URL_SCAN_REPORT, data)
        response = urllib2.urlopen(req)
        json = response.read()
        response_dict = simplejson.loads(json)
       
        if int(response_dict.get("response_code")) != 1 :
            return (False, "Signature Not Found")
         
        diclist = []
        if scan_type == self.FLAG_FILE_SCAN or scan_type == self.FLAG_HASH_SCAN :
            for key, value in response_dict['scans'].iteritems():
                if str(response_dict.get("scans", {}).get(key, {}).get("detected")) == 'True' :
                    temp = [str(key),
                            str(response_dict.get("scans", {}).get(key, {}).get("result")),
                            str(response_dict.get("scans", {}).get(key, {}).get("version")),
                            str(response_dict.get("scans", {}).get(key, {}).get("update"))
                            ]
                    diclist.append(temp)
        else :
            for key, value in response_dict['scans'].iteritems():
                if str(response_dict.get("scans", {}).get(key, {}).get("result")) == True :
                    temp = [str(key),
                            str(response_dict.get("scans", {}).get(key, {}).get("result")),
                            "",
                            ""
                            ]
                    diclist.append(temp)
       
        if len(diclist) == 0 :
            return (False, "All Clean")
       
        return (True, diclist)
 
# -----------------------------------------------------------------------
class VirusTotalChooser(Choose2):
    """
    Chooser class to display results from VT
    """
    def __init__(self, title, items, icon, embedded=False):
        Choose2.__init__(self,
                         title,
                         [ ["AntiVirus", 100], ["result", 100], ["version", 100], ["update", 100] ],
                         embedded=embedded)
        self.items = items
        self.icon = icon
   
    def GetItems(self):
        return self.items
   
    def SetItems(self, items):
        self.items = [] if items is None else items
       
    def OnClose(self):
        pass
   
    def OnGetLine(self, n):
        return self.items[n]
   
    def OnGetSize(self):
        return len(self.items)
   
    def OnSelectLine(self, n):
        # Google search for the malware name and the antivirus name
        #s = urllib.urlencode({"q" : " ".join(self.items[n])})
        s = urllib.urlencode({"q" : " " + self.items[n][0] + " " + self.items[n][1]})
        webbrowser.open_new_tab("http://www.google.com/search?%s" % s)
 
# -----------------------------------------------------------------------
class VirusTotalForm(Form):
    def __init__(self, icon):
        self.EChooser = VirusTotalChooser("E1", [], icon, embedded=True)
        Form.__init__(self, r"""
VirusTotal - IDAPython plugin v1.1.0 by Style.efi
 
{FormChangeCb}
<#Search Item#~S~earch Item:{txtSearchItem}> <#Get reports from VT#~R~eport:{btnReport}>
 
<Results:{cEChooser}>
""", {
            'FormChangeCb'  : Form.FormChangeCb(self.OnFormChange),
            'txtSearchItem' : Form.StringInput(swidth=80),
            'btnReport'     : Form.ButtonInput(self.OnReportClick),
            'cEChooser'     : Form.EmbeddedChooserControl(self.EChooser, swidth=100)
        })
       
    def OnReportClick(self, code=0):
        pass
   
    def OnFormChange(self, fid):
       
        #
        # Report Button
        #
        if fid == self.btnReport.id:
            searchItem = self.GetControlValue(self.txtSearchItem)
           
            vt = VirusTotalOpenAPI()
            ok, r = vt.getScanReport(searchItem)
           
            # Error?
            if not ok :
                idc.Warning(r)
                return 1
           
            # Pass the result
            self.EChooser.SetItems(r)
           
            # Refresh the embedded chooser control
            # (Could also clear previous results if not were retrieved during this run)
            self.RefreshField(self.cEChooser)
           
        return 1
       
    def Show(self):
        # Compile the form once
        if not self.Compile() :
            _, args = self.Compile()
           
        ok = self.Execute()
       
        return ok
 
'''
'''
class VirusTotalPlugin_t(plugin_t):
    flags = idaapi.PLUGIN_UNL
    comment = "VirusTotal plugin for IDA"
    help = ""
    wanted_name = "VirusTotal report"
    wanted_hotkey = "Alt-F8"
   
    def init(self):
        # Some initialization
        self.icon_id = 0
        return idaapi.PLUGIN_OK
   
    def run(self, arg=0):
        # Load icon from the memory and save its id
        self.icon_id = idaapi.load_custom_icon(data=VT_ICON, format="png")
        if self.icon_id == 0 :
            raise RuntimeError("Failed to load icon data!")
       
        # Create form
        f = VirusTotalForm(self.icon_id)
         
        # Show the form
        ok = f.Show()
        if ok == 0:               
            f.Free()
            return
               
        # Spawn a non-model chooser w/ the results if any
        if ok == 2 and f.EChooser.GetItems() :
            VirusTotalChooser(
                "VirusTotal results [1111]",
                f.EChooser.GetItems(),
                self.icon_id).Show()
               
        f.Free()
        return
   
    def term(self):
        # Free the custom icon
        if self.icon_id != 0 :
            idaapi.free_custom_icon(self.icon_id)
 
def PLUGIN_ENTRY():
    return VirusTotalPlugin_t()
 
if PLUGIN_TEST:
    # Create form
    f = PLUGIN_ENTRY()
    f.init()
    f.run()
    f.term()

 


Related articles

 

http://www.hexblog.com/?p=324

http://www.hexblog.com/?p=120

 

'reverse engineering' 카테고리의 다른 글

Scapy를 이용한 통신 패킷 복호화  (0) 2015.01.14
VirusTotal for IDA plugin  (0) 2014.10.15
Name
Password
Homepage
Secret