[網絡安全自學篇] 八十九.PE文件解析之經過Python獲取時間戳判斷軟件來源地區

這是做者網絡安全自學教程系列,主要是關於安全工具和實踐操做的在線筆記,特分享出來與博友們學習,但願您喜歡,一塊兒進步。前文分享了基於機器學習的惡意代碼檢測技術,包括機器學習概述與算法舉例、基於機器學習方法的惡意代碼檢測、機器學習算法在工業界的應用。這篇文章將嘗試軟件來源分析,結合APT攻擊中常見的判斷方法,利用Python調用擴展包進行溯源,但也存在侷限性。文章同時也普及了PE文件分析和APT溯源相關基礎,基礎性文章,但願對您有所幫助~php

你是否想過如何判斷PE軟件或APP來源哪一個國家或地區呢?你又想過印度是如何確保一鍵正確卸載中國APP呢?使用黑白名單嗎?本文嘗試進行軟件來源溯源,目前想到的方法包括:html

  • 經過PE文件分析抓取建立文件時間戳,而後UTC定位國家地區,但受樣本數量較少,活動規律不穩定影響很大
  • 經過靜態分析獲取非英文字符串,軟件中通常有供該國使用的文字,而後進行編碼比對溯源地區
  • 某些APP或軟件存在流量反饋或IP定位,嘗試進行流量抓取分析
  • 利用深度學習進行分類,而後提取不一樣國家的特徵完成溯源

歡迎你們討論和留言,咱們一塊兒進行更深刻的嘗試和安全測試 O(∩_∩)Opython


做者做爲網絡安全的小白,分享一些自學基礎教程給你們,主要是關於安全工具和實踐操做的在線筆記,但願您們喜歡。同時,更但願您能與我一塊兒操做和進步,後續將深刻學習網絡安全和系統安全知識並分享相關實驗。總之,但願該系列文章對博友有所幫助,寫文不易,大神們不喜勿噴,謝謝!若是文章對您有幫助,將是我創做的最大動力,點贊、評論、私聊都可,一塊兒加油喔~git


做者的github資源:
軟件安全:https://github.com/eastmountyxz/Software-Security-Course
其餘工具:https://github.com/eastmountyxz/NetworkSecuritySelf-study
Windows-Hacker:https://github.com/eastmountyxz/Windows-Hacker-Exp程序員


聲明:本人堅定反對利用教學方法進行犯罪的行爲,一切犯罪行爲必將受到嚴懲,綠色網絡須要咱們共同維護,更推薦你們瞭解它們背後的原理,更好地進行防禦。github

前文學習:
[網絡安全自學篇] 一.入門筆記之看雪Web安全學習及異或解密示例
[網絡安全自學篇] 二.Chrome瀏覽器保留密碼功能滲透解析及登陸加密入門筆記
[網絡安全自學篇] 三.Burp Suite工具安裝配置、Proxy基礎用法及暴庫示例
[網絡安全自學篇] 四.實驗吧CTF實戰之WEB滲透和隱寫術解密
[網絡安全自學篇] 五.IDA Pro反彙編工具初識及逆向工程解密實戰
[網絡安全自學篇] 六.OllyDbg動態分析工具基礎用法及Crakeme逆向
[網絡安全自學篇] 七.快手視頻下載之Chrome瀏覽器Network分析及Python爬蟲探討
[網絡安全自學篇] 八.Web漏洞及端口掃描之Nmap、ThreatScan和DirBuster工具
[網絡安全自學篇] 九.社會工程學之基礎概念、IP獲取、IP物理定位、文件屬性
[網絡安全自學篇] 十.論文之基於機器學習算法的主機惡意代碼
[網絡安全自學篇] 十一.虛擬機VMware+Kali安裝入門及Sqlmap基本用法
[網絡安全自學篇] 十二.Wireshark安裝入門及抓取網站用戶名密碼(一)
[網絡安全自學篇] 十三.Wireshark抓包原理(ARP劫持、MAC泛洪)及數據流追蹤和圖像抓取(二)
[網絡安全自學篇] 十四.Python攻防之基礎常識、正則表達式、Web編程和套接字通訊(一)
[網絡安全自學篇] 十五.Python攻防之多線程、C段掃描和數據庫編程(二)
[網絡安全自學篇] 十六.Python攻防之弱口令、自定義字典生成及網站暴庫防禦
[網絡安全自學篇] 十七.Python攻防之構建Web目錄掃描器及ip代理池(四)
[網絡安全自學篇] 十八.XSS跨站腳本攻擊原理及代碼攻防演示(一)
[網絡安全自學篇] 十九.Powershell基礎入門及常見用法(一)
[網絡安全自學篇] 二十.Powershell基礎入門及常見用法(二)
[網絡安全自學篇] 二十一.GeekPwn極客大賽之安全攻防技術總結及ShowTime
[網絡安全自學篇] 二十二.Web滲透之網站信息、域名信息、端口信息、敏感信息及指紋信息收集
[網絡安全自學篇] 二十三.基於機器學習的惡意請求識別及安全領域中的機器學習
[網絡安全自學篇] 二十四.基於機器學習的惡意代碼識別及人工智能中的惡意代碼檢測
[網絡安全自學篇] 二十五.Web安全學習路線及木馬、病毒和防護初探
[網絡安全自學篇] 二十六.Shodan搜索引擎詳解及Python命令行調用
[網絡安全自學篇] 二十七.Sqlmap基礎用法、CTF實戰及請求參數設置(一)
[網絡安全自學篇] 二十八.文件上傳漏洞和Caidao入門及防護原理(一)
[網絡安全自學篇] 二十九.文件上傳漏洞和IIS6.0解析漏洞及防護原理(二)
[網絡安全自學篇] 三十.文件上傳漏洞、編輯器漏洞和IIS高版本漏洞及防護(三)
[網絡安全自學篇] 三十一.文件上傳漏洞之Upload-labs靶場及CTF題目01-10(四)
[網絡安全自學篇] 三十二.文件上傳漏洞之Upload-labs靶場及CTF題目11-20(五)
[網絡安全自學篇] 三十三.文件上傳漏洞之繞狗一句話原理和繞過安全狗(六)
[網絡安全自學篇] 三十四.Windows系統漏洞之5次Shift漏洞啓動計算機
[網絡安全自學篇] 三十五.惡意代碼攻擊溯源及惡意樣本分析
[網絡安全自學篇] 三十六.WinRAR漏洞復現(CVE-2018-20250)及惡意軟件自啓動劫持
[網絡安全自學篇] 三十七.Web滲透提升班之hack the box在線靶場註冊及入門知識(一)
[網絡安全自學篇] 三十八.hack the box滲透之BurpSuite和Hydra密碼爆破及Python加密Post請求(二)
[網絡安全自學篇] 三十九.hack the box滲透之DirBuster掃描路徑及Sqlmap高級注入用法(三)
[網絡安全自學篇] 四十.phpMyAdmin 4.8.1後臺文件包含漏洞復現及詳解(CVE-2018-12613)
[網絡安全自學篇] 四十一.中間人攻擊和ARP欺騙原理詳解及漏洞還原
[網絡安全自學篇] 四十二.DNS欺騙和釣魚網站原理詳解及漏洞還原
[網絡安全自學篇] 四十三.木馬原理詳解、遠程服務器IPC$漏洞及木馬植入實驗
[網絡安全自學篇] 四十四.Windows遠程桌面服務漏洞(CVE-2019-0708)復現及詳解
[網絡安全自學篇] 四十五.病毒詳解及批處理病毒製做(自啓動、修改密碼、定時關機、藍屏、進程關閉)
[網絡安全自學篇] 四十六.微軟證書漏洞CVE-2020-0601 (上)Windows驗證機制及可執行文件簽名復現
[網絡安全自學篇] 四十七.微軟證書漏洞CVE-2020-0601 (下)Windows證書籤名及HTTPS網站劫持
[網絡安全自學篇] 四十八.Cracer第八期——(1)安全術語、Web滲透流程、Windows基礎、註冊表及黑客經常使用DOS命令
[網絡安全自學篇] 四十九.Procmon軟件基本用法及文件進程、註冊表查看
[網絡安全自學篇] 五十.虛擬機基礎之安裝XP系統、文件共享、網絡快照設置及Wireshark抓取BBS密碼
[網絡安全自學篇] 五十一.惡意樣本分析及HGZ木馬控制目標服務器
[網絡安全自學篇] 五十二.Windows漏洞利用之棧溢出原理和棧保護GS機制
[網絡安全自學篇] 五十三.Windows漏洞利用之Metasploit實現棧溢出攻擊及反彈shell
[網絡安全自學篇] 五十四.Windows漏洞利用之基於SEH異常處理機制的棧溢出攻擊及shell提取
[網絡安全自學篇] 五十五.Windows漏洞利用之構建ROP鏈繞過DEP並獲取Shell
[網絡安全自學篇] 五十六.i春秋老師分享小白滲透之路及Web滲透技術總結
[網絡安全自學篇] 五十七.PE文件逆向之什麼是數字簽名及Signtool簽名工具詳解(一)
[網絡安全自學篇] 五十八.Windows漏洞利用之再看CVE-2019-0708及Metasploit反彈shell
[網絡安全自學篇] 五十九.Windows漏洞利用之MS08-067遠程代碼執行漏洞復現及shell深度提權
[網絡安全自學篇] 六十.Cracer第八期——(2)五萬字總結Linux基礎知識和經常使用滲透命令
[網絡安全自學篇] 六十一.PE文件逆向之數字簽名詳細解析及Signcode、PEView、010Editor、Asn1View等工具用法(二)
[網絡安全自學篇] 六十二.PE文件逆向之PE文件解析、PE編輯工具使用和PE結構修改(三)
[網絡安全自學篇] 六十三.hack the box滲透之OpenAdmin題目及蟻劍管理員提權(四)
[網絡安全自學篇] 六十四.Windows漏洞利用之SMBv3服務遠程代碼執行漏洞(CVE-2020-0796)復現及詳解
[網絡安全自學篇] 六十五.Vulnhub靶機滲透之環境搭建及JIS-CTF入門和蟻劍提權示例(一)
[網絡安全自學篇] 六十六.Vulnhub靶機滲透之DC-1提權和Drupal漏洞利用(二)
[網絡安全自學篇] 六十七.WannaCry勒索病毒復現及分析(一)Python利用永恆之藍及Win7勒索加密
[網絡安全自學篇] 六十八.WannaCry勒索病毒復現及分析(二)MS17-010利用及病毒解析
[網絡安全自學篇] 六十九.宏病毒之入門基礎、防護措施、自發郵件及APT28樣本分析
[網絡安全自學篇] 七十.WannaCry勒索病毒復現及分析(三)蠕蟲傳播機制分析及IDA和OD逆向
[網絡安全自學篇] 七十一.深信服分享以外部威脅防禦和勒索病毒對抗
[網絡安全自學篇] 七十二.逆向分析之OllyDbg動態調試工具(一)基礎入門及TraceMe案例分析
[網絡安全自學篇] 七十三.WannaCry勒索病毒復現及分析(四)蠕蟲傳播機制全網源碼詳細解讀
[網絡安全自學篇] 七十四.APT攻擊檢測溯源與常見APT組織的攻擊案例
[網絡安全自學篇] 七十五.Vulnhub靶機滲透之bulldog信息收集和nc反彈shell(三)
[網絡安全自學篇] 七十六.逆向分析之OllyDbg動態調試工具(二)INT3斷點、反調試、硬件斷點與內存斷點
[網絡安全自學篇] 七十七.惡意代碼與APT攻擊中的武器(強推Seak老師)
[網絡安全自學篇] 七十八.XSS跨站腳本攻擊案例分享及總結(二)
[網絡安全自學篇] 七十九.Windows PE病毒原理、分類及感染方式詳解
[網絡安全自學篇] 八十.WHUCTF之WEB類解題思路WP(代碼審計、文件包含、過濾繞過、SQL注入)
[網絡安全自學篇] 八十一.WHUCTF之WEB類解題思路WP(文件上傳漏洞、冰蠍蟻劍、反序列化phar)
[網絡安全自學篇] 八十二.WHUCTF之隱寫和逆向類解題思路WP(文字解密、圖片解密、佛語解碼、冰蠍流量分析、逆向分析)
[網絡安全自學篇] 八十三.WHUCTF之CSS注入、越權、csrf-token竊取及XSS總結
[網絡安全自學篇] 八十四.《Windows黑客編程技術詳解》之VS環境配置、基礎知識及DLL延遲加載詳解
[網絡安全自學篇] 八十五.《Windows黑客編程技術詳解》之注入技術詳解(全局鉤子、遠線程鉤子、突破Session 0注入、APC注入)
[網絡安全自學篇] 八十六.威脅情報分析之Python抓取FreeBuf網站APT文章(上)
[網絡安全自學篇] 八十七.惡意代碼檢測技術詳解及總結
[網絡安全自學篇] 八十八.基於機器學習的惡意代碼檢測技術詳解web


前文欣賞:
[滲透&攻防] 一.從數據庫原理學習網絡攻防及防止SQL注入
[滲透&攻防] 二.SQL MAP工具從零解讀數據庫及基礎用法
[滲透&攻防] 三.數據庫之差別備份及Caidao利器
[滲透&攻防] 四.詳解MySQL數據庫攻防及Fiddler神器分析數據包正則表達式



一.PE文件格式

什麼是PE文件?
PE文件的全稱是Portable Executable,意爲可移植的可執行的文件,常見的EXE、DLL、OCX、SYS、COM都是PE文件,PE文件是微軟Windows操做系統上的程序文件(多是間接被執行,如DLL)。算法

EXE文件格式:shell

  • DOS:MZ格式
  • WIndows 3.0/3.1:NE(New Executable)、16位Windows可執行文件格式

爲何要重點學習這種文件格式呢?

  • PE文件是可移植、可執行、跨Win32平臺的文件格式
  • 全部Win32執行體(exe、dll、kernel mode drivers)
  • 知道PE文件本質後,能更好進行惡意樣本分析、APT攻擊分析、勒索病毒分析
  • 瞭解軟件加密和加殼的思想,可以PJ相關的PE文件
  • 它是您熟悉Windows操做系統的第一步,包括EXE程序怎麼映射到內存,DLL怎麼導入等
  • 軟件逆向工程的基本思想與PE文件格式息息相關
  • 若是您想成爲一名黑客、系統安全工程師,那麼精通PE文件是很是必要的

可執行程序是具備不一樣的形態的,好比用戶眼中的QQ以下圖所示。

在這裏插入圖片描述

在這裏插入圖片描述

本質上,QQ以下圖所示。

在這裏插入圖片描述


PE文件格式整體結構
接着讓咱們來欣賞下PE文件格式整體結構圖,包括:MZ頭部、DOS stub、PE文件頭、可選文件頭、節表、節等。

在這裏插入圖片描述

本文的第二部分咱們將對PE文件格式進行詳細解析。好比,MZ頭文件是定位PE文件頭開始位置,用於PE文件合法性檢測。DOS下運行該程序時,會提示用戶「This Program cannot be run in DOS mode」。

在這裏插入圖片描述

PE文件格式與惡意軟件的關係

  • 何爲文件感染或控制權獲取?
    使目標PE文件具有或啓動病毒功能(或目標程序)
    不破壞目標PE文件原有功能和外在形態(如圖標)等
  • 病毒代碼如何與目標PE文件融爲一體呢?
    代碼植入
    控制權獲取
    圖標更改
    Hook

PE文件解析經常使用工具包括:

  • PEView:可按照PE文件格式對目標文件的各字段進行詳細解析。
  • Stud_PE:可按照PE文件格式對目標文件的各字段進行詳細解析。
  • Ollydbg:可跟蹤目標程序的執行過程,屬於用戶態調試工具。
  • UltraEdit \ 010Editor:可對目標文件進行16進制查看和修改。


二.PE文件格式解析

該部分實驗內容:

  • 使用010Editor觀察PE文件例子程序hello-2.5.exe的16進制數據
  • 使用Ollydbg對該程序進行初步調試,瞭解該程序功能結構,在內存中觀察該程序的完整結構
  • 使用010Editor修改該程序,使得該程序僅彈出第二個對話框

1.010Editor解析PE文件

PE文件結構以下圖所示,我推薦你們使用010Editor工具及其模板來進行PE文件分析。
MZ頭部+DOS stub+PE文件頭+可選文件頭+節表+節

在這裏插入圖片描述


(1) 使用010Editor工具打開PE文件,並運行模板。
該PE文件可分爲若干結構,以下圖所示。

在這裏插入圖片描述


(2) MZ文件頭(000h-03fh)。
下圖爲hello-2.5.exe的MZ文件頭,該部分固定大小爲40H個字節。偏移3cH處字段Offset to New EXE Header,指示「NT映象頭的偏移地址」,其中000000B0是NT映象頭的文件偏移地址,定位PE文件頭開始位置,用於PE文件合法性檢驗。

在這裏插入圖片描述

000000B0指向PE文件頭開始位置。

在這裏插入圖片描述


(3) DOS插樁程序(040h-0afh)
DOS Stub部分大小不固定,位於MZ文件頭和NT映象頭之間,可由MZ文件頭中的Offset to New EXE Header字段肯定。下圖爲hello-2.5.exe中的該部份內容。

在這裏插入圖片描述


(4) PE文件頭(0b0h-1a7h)
該部分包括PE標識、映像文件頭、可選文件頭。

  • Signature:字串「PE\0\0」,4個字節(0b0H~0b4H)
  • 映象文件頭File Header:14H個字節(0b5H~0c7H)
    偏移2H處,字段Number of Section 給出節的個數(2個字節):0003
    偏移10H處,字段Size of Optional Header 給出可選映象頭的大小(2個字節):00E0
  • 可選映象頭Optional Header:0c8H~1a7H

在這裏插入圖片描述

對應解析以下圖所示,包括PE標識、X86架構、3個節、文件生成時間、COFF便宜、可選頭大小、文件信息標記等。

在這裏插入圖片描述

010Editor使用模板定位PE文件各節點信息。

在這裏插入圖片描述

PE文件可選文件頭224字節,其對應的字段信息以下所示:

typedef struct _IMAGE_OPTIONAL_HEADER {

    WORD    Magic;                  /*機器型號,判斷是PE是32位仍是64位*/
    BYTE    MajorLinkerVersion;          /*鏈接器版本號高版本*/
    BYTE    MinorLinkerVersion;          /*鏈接器版本號低版本,組合起來就是 5.12 其中5是高版本,C是低版本*/
    DWORD   SizeOfCode;               /*代碼節的總大小(512爲一個磁盤扇區)*/
    DWORD   SizeOfInitializedData;        /*初始化數據的節的總大小,也就是.data*/
    DWORD   SizeOfUninitializedData;       /*未初始化數據的節的大小,也就是 .data ? */
    DWORD   AddressOfEntryPoint;          /*程序執行入口(OEP) RVA(相對偏移)*/
    DWORD   BaseOfCode;               /*代碼的節的起始RVA(相對偏移)也就是代碼區的偏移,偏移+模塊首地址定位代碼區*/
    DWORD   BaseOfData;               /*數據結的起始偏移(RVA),同上*/
    DWORD   ImageBase;               /*程序的建議模塊基址(意思就是說做參考用的,模塊地址在哪裏)*/

    DWORD   SectionAlignment;           /*內存中的節對齊*/
    DWORD   FileAlignment;             /*文件中的節對齊*/
    WORD    MajorOperatingSystemVersion;    /*操做系統版本號高位*/
    WORD    MinorOperatingSystemVersion;    /*操做系統版本號低位*/
    WORD    MajorImageVersion;          /*PE版本號高位*/
    WORD    MinorImageVersion;          /*PE版本號低位*/
    WORD    MajorSubsystemVersion;        /*子系統版本號高位*/
    WORD    MinorSubsystemVersion;        /*子系統版本號低位*/
    DWORD   Win32VersionValue;          /*32位系統版本號值,注意只能修改成4 5 6表示操做系統支持nt4.0 以上,5的話依次類推*/
    DWORD   SizeOfImage;               /*整個程序在內存中佔用的空間(PE映尺寸)*/
    DWORD   SizeOfHeaders;            /*全部頭(頭的結構體大小)+節表的大小*/
    DWORD   CheckSum;               /*校驗和,對於驅動程序,可能會使用*/
    WORD    Subsystem;              /*文件的子系統 :重要*/
    WORD    DllCharacteristics;         /*DLL文件屬性,也能夠成爲特性,可能DLL文件能夠當作驅動程序使用*/
    DWORD   SizeOfStackReserve;         /*預留的棧的大小*/
    DWORD   SizeOfStackCommit;          /*當即申請的棧的大小(分頁爲單位)*/
    DWORD   SizeOfHeapReserve;          /*預留的堆空間大小*/
    DWORD   SizeOfHeapCommit;           /*當即申請的堆的空間的大小*/
    DWORD   LoaderFlags;             /*與調試有關*/
    DWORD   NumberOfRvaAndSizes;         /*下面的成員,數據目錄結構的項目數量*/
    IMAGE_DATA_DIRECTORY DataDirectory[16];  /*數據目錄,默認16個,16是宏,這裏方便直接寫成16*/
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

(5) 節表(1a8h-21fh)

  • 表項大小固定,28H個字節;表項個數由映象文件頭的字段Number of Section 給出。
  • 每一個表項的起始位置起(8個字節),字段Name給出對應節的名稱。
  • 每一個表項的偏移14H處(4個字節),字段Offset to Raw Data給出對應節的起始文件偏移。

在這裏插入圖片描述

該結構包括3個節,對應上圖的3個struct IMAGE_SECTION_HEADER,即「.test」、「.rdata」、「.data」節,其偏移地址對應下圖紫色區域,分別是400、600、800的位置。

在這裏插入圖片描述


(6) 3個節

  • 400H-5ffH:代碼節
  • 600H-7ffH:引入函數節
  • 800H-9ffH:數據節

在這裏插入圖片描述

注意,代碼節「.text」前46H爲數據,後面全是0位填充值,爲了實現文件的200H對齊,因此代碼節是400H到5ffH。

在這裏插入圖片描述


(7) 引入函數節
⽤來從其餘DLL中引⼊函數,引入了kernel32.dll和user32.dll,這個節通常名爲「.rdata」。引入函數是被某模塊調用的但又不在調用者模塊中的函數,用來從其餘(系統或第三方寫的)DLL中引入函數,例如kernel32.dll、gdi32.dll等。

在這裏插入圖片描述

010Editor打開以下圖所示:

在這裏插入圖片描述

詳細標註信息以下圖所示:(圖引自HYQ同窗,再此感謝)

在這裏插入圖片描述


(8) 數據節
數據節實際大小58h,對齊後大小200h,地址爲800h-9ffh,包括對話框彈出的具體內容。

在這裏插入圖片描述



2.Ollydbg動態調試程序

使用Ollydbg對該程序進行初步調試,瞭解該程序功能結構,在內存中觀察該程序的完整結構。注意,內存對齊單位和文件對齊單位的不一樣,內容和文件中IAT表內容的不一樣。

第一步,打開OD加載PE文件。
OD是一款PE文件動態調試器,此時程序斷點自動中止在程序入口點00401000H位置。

在這裏插入圖片描述

在010Editor中,咱們能夠看到,該PE程序基地址是400000h,程序入口地址是1000h,兩個相加爲加載至內存中的地址,即401000h。

在這裏插入圖片描述


第二步,動態調試程序。
當咱們雙擊地址位置,則能夠下斷點且變紅,好比0040100Fh。

在這裏插入圖片描述

接着查看對應調試快捷鍵,F7是單步步入,F8是單步步過。

在這裏插入圖片描述

咱們直接按F8單步步過,此時的位置會CALL一個MessageBoxA函數。

在這裏插入圖片描述

直接單步步過,此時會彈出第一個對話框,點擊「肯定」按鈕。

在這裏插入圖片描述


第三步,動態調試程序之數據跟隨。
接着咱們看左下角部分的內存數據,在該區域按下「Ctrl+G」在數據窗口中跟隨,輸入基地址400000。

在這裏插入圖片描述

此時能夠看到加載到內存中的數據,能夠看到該數據與010Editor打開的PE文件數據一致的。

在這裏插入圖片描述

接着繼續按F8單步步過彈出第二個窗口。

在這裏插入圖片描述

右上角是它寄存器的值,包括各個寄存器中的數據,咱們實驗中主要使用的寄存器包括EAX、ECX、EDX、EBX等。

在這裏插入圖片描述

接着步過0040102E,它是退出進程ExitProcess的位置,此時進程已經終止,以下圖所示。

在這裏插入圖片描述

實驗講到這裏,使用OD動態調試的PE文件的基礎流程就講解完畢,後續隨着實驗深刻,咱們還會使用該工具。



三.Python獲取時間戳

接着咱們嘗試經過Python來獲取時間戳,python的PE庫是pefile,它是用來專門解析PE文件的,可靜態分析PE文件。pefile能完成的任務包括:

  • 檢查頭
  • 分析部分數據
  • 檢索嵌入式數據
  • 從資源中讀取字符串
  • 警告值可疑和格式錯誤
  • PE的基本分析,喜歡寫一些領域和其餘部分的PE的
  • 帶有PEiD簽名的打包程序檢測
  • PEiD簽名 生成

推薦你們學習官方資料和github文檔。

安裝擴展包的方法以下:

  • pip install pefile

在這裏插入圖片描述


假設安裝成功以後,咱們須要對下圖所示的軟件進行分析,該軟件是我在第85篇博客中生成的,你們直接使用便可(文章開頭的github連接能下載)。

在這裏插入圖片描述


第一步,咱們經過010Editor分析PE文件。
其時間戳的輸出結果以下:

  • 06/19/2020 10:46:21

咱們但願經過Python寫代碼實現自動化提取,爲後續自動化溯源提供幫助。


在這裏插入圖片描述


第二步,撰寫Python代碼實現簡單分析。

import pefile
import os,string,shutil,re

PEfile_Path = "MFCApplication.exe"
 
pe = pefile.PE(PEfile_Path)
print(type(pe))
print(pe)

輸出以下圖所示結果,這是Python包自定義的PE結構。

在這裏插入圖片描述

squeezed text表示python的一種編程規範要求,簡稱pep8,你只須要將鼠標放到Squeezed上,右鍵Copy便可查看內容,顯示的是該PE文件的基本結構,以下所示:

----------Parsing Warnings----------

Byte 0xcc makes up 17.8750% of the file's contents. This may indicate truncation / malformation.

Suspicious flags set for section 0. Both IMAGE_SCN_MEM_WRITE and IMAGE_SCN_MEM_EXECUTE are set. This might indicate a packed executable.

----------DOS_HEADER----------

[IMAGE_DOS_HEADER]
0x0        0x0   e_magic:                       0x5A4D    
0x2        0x2   e_cblp:                        0x90      
0x4        0x4   e_cp:                          0x3       
0x6        0x6   e_crlc:                        0x0       
0x8        0x8   e_cparhdr:                     0x4       
0xA        0xA   e_minalloc:                    0x0       
0xC        0xC   e_maxalloc:                    0xFFFF    
0xE        0xE   e_ss:                          0x0       
0x10       0x10  e_sp:                          0xB8      
0x12       0x12  e_csum:                        0x0       
0x14       0x14  e_ip:                          0x0       
0x16       0x16  e_cs:                          0x0       
0x18       0x18  e_lfarlc:                      0x40      
0x1A       0x1A  e_ovno:                        0x0       
0x1C       0x1C  e_res:                         
0x24       0x24  e_oemid:                       0x0       
0x26       0x26  e_oeminfo:                     0x0       
0x28       0x28  e_res2:                        
0x3C       0x3C  e_lfanew:                      0x108     

----------NT_HEADERS----------

[IMAGE_NT_HEADERS]
0x108      0x0   Signature:                     0x4550    

----------FILE_HEADER----------

[IMAGE_FILE_HEADER]
0x10C      0x0   Machine:                       0x14C     
0x10E      0x2   NumberOfSections:              0xA       
0x110      0x4   TimeDateStamp:                 0x5EEC977D [Fri Jun 19 10:46:21 2020 UTC]
0x114      0x8   PointerToSymbolTable:          0x0       
0x118      0xC   NumberOfSymbols:               0x0       
0x11C      0x10  SizeOfOptionalHeader:          0xE0      
0x11E      0x12  Characteristics:               0x102     
Flags: IMAGE_FILE_32BIT_MACHINE, IMAGE_FILE_EXECUTABLE_IMAGE

----------OPTIONAL_HEADER----------

[IMAGE_OPTIONAL_HEADER]
0x120      0x0   Magic:                         0x10B     
0x122      0x2   MajorLinkerVersion:            0xE       
0x123      0x3   MinorLinkerVersion:            0x1A      
0x124      0x4   SizeOfCode:                    0x700C00  
0x128      0x8   SizeOfInitializedData:         0x2F1E00  
0x12C      0xC   SizeOfUninitializedData:       0x0       
0x130      0x10  AddressOfEntryPoint:           0x36CE65  
0x134      0x14  BaseOfCode:                    0x1000    
0x138      0x18  BaseOfData:                    0x1000    
0x13C      0x1C  ImageBase:                     0x400000  
0x140      0x20  SectionAlignment:              0x1000    
0x144      0x24  FileAlignment:                 0x200     
0x148      0x28  MajorOperatingSystemVersion:   0x6       
0x14A      0x2A  MinorOperatingSystemVersion:   0x0       
0x14C      0x2C  MajorImageVersion:             0x0       
0x14E      0x2E  MinorImageVersion:             0x0       
0x150      0x30  MajorSubsystemVersion:         0x6       
0x152      0x32  MinorSubsystemVersion:         0x0       
0x154      0x34  Reserved1:                     0x0       
0x158      0x38  SizeOfImage:                   0xD54000  
0x15C      0x3C  SizeOfHeaders:                 0x400     
0x160      0x40  CheckSum:                      0x0       
0x164      0x44  Subsystem:                     0x2       
0x166      0x46  DllCharacteristics:            0x8140    
0x168      0x48  SizeOfStackReserve:            0x100000  
0x16C      0x4C  SizeOfStackCommit:             0x1000    
0x170      0x50  SizeOfHeapReserve:             0x100000  
0x174      0x54  SizeOfHeapCommit:              0x1000    
0x178      0x58  LoaderFlags:                   0x0       
0x17C      0x5C  NumberOfRvaAndSizes:           0x10      
DllCharacteristics: IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLLCHARACTERISTICS_NX_COMPAT, IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE

----------PE Sections----------

[IMAGE_SECTION_HEADER]
0x200      0x0   Name:                          .textbss
0x208      0x8   Misc:                          0x35B30B  
0x208      0x8   Misc_PhysicalAddress:          0x35B30B  
0x208      0x8   Misc_VirtualSize:              0x35B30B  
0x20C      0xC   VirtualAddress:                0x1000    
0x210      0x10  SizeOfRawData:                 0x0       
0x214      0x14  PointerToRawData:              0x0       
0x218      0x18  PointerToRelocations:          0x0       
0x21C      0x1C  PointerToLinenumbers:          0x0       
0x220      0x20  NumberOfRelocations:           0x0       
0x222      0x22  NumberOfLinenumbers:           0x0       
0x224      0x24  Characteristics:               0xE00000A0
Flags: IMAGE_SCN_CNT_CODE, IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE
Entropy: 0.000000 (Min=0.0, Max=8.0)
MD5     hash: d41d8cd98f00b204e9800998ecf8427e
SHA-1   hash: da39a3ee5e6b4b0d3255bfef95601890afd80709
SHA-256 hash: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
SHA-512 hash: cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
....

對應於010Editor分析的結果,先後是一致的。

在這裏插入圖片描述

同時,咱們能夠輸入help(pefile.PE) 查看幫助信息,它定義了pefile包的一些函數和屬性。

Help on class PE in module pefile:

class PE(builtins.object)
 |  PE(name=None, data=None, fast_load=None)
 |  
 |  A Portable Executable representation.
 |  
 |  This class provides access to most of the information in a PE file.
 |  
 |  It expects to be supplied the name of the file to load or PE data
 |  to process and an optional argument 'fast_load' (False by default)
 |  which controls whether to load all the directories information,
 |  which can be quite time consuming.
 |  
 |  pe = pefile.PE('module.dll')
 |  pe = pefile.PE(name='module.dll')
 |  
 |  would load 'module.dll' and process it. If the data is already
 |  available in a buffer the same can be achieved with:
 |  
 |  pe = pefile.PE(data=module_dll_data)
 |  
 |  The "fast_load" can be set to a default by setting its value in the
 |  module itself by means, for instance, of a "pefile.fast_load = True".
 |  That will make all the subsequent instances not to load the
 |  whole PE structure. The "full_load" method can be used to parse
 |  the missing data at a later stage.
 |  
 |  Basic headers information will be available in the attributes:
 |  
 |  DOS_HEADER
 |  NT_HEADERS
 |  FILE_HEADER
 |  OPTIONAL_HEADER
 |  
 |  All of them will contain among their attributes the members of the
 |  corresponding structures as defined in WINNT.H
 |  
 |  The raw data corresponding to the header (from the beginning of the
 |  file up to the start of the first section) will be available in the
 |  instance's attribute 'header' as a string.
 |  
 |  The sections will be available as a list in the 'sections' attribute.
 |  Each entry will contain as attributes all the structure's members.
 |  
 |  Directory entries will be available as attributes (if they exist):
 |  (no other entries are processed at this point)
 |  
 |  DIRECTORY_ENTRY_IMPORT (list of ImportDescData instances)
 |  DIRECTORY_ENTRY_EXPORT (ExportDirData instance)
 |  DIRECTORY_ENTRY_RESOURCE (ResourceDirData instance)
 |  DIRECTORY_ENTRY_DEBUG (list of DebugData instances)
 |  DIRECTORY_ENTRY_BASERELOC (list of BaseRelocationData instances)
 |  DIRECTORY_ENTRY_TLS
 |  DIRECTORY_ENTRY_BOUND_IMPORT (list of BoundImportData instances)
 |  
 |  The following dictionary attributes provide ways of mapping different
 |  constants. They will accept the numeric value and return the string
 |  representation and the opposite, feed in the string and get the
 |  numeric constant:
 |  
 |  DIRECTORY_ENTRY
 |  IMAGE_CHARACTERISTICS
 |  SECTION_CHARACTERISTICS
 |  DEBUG_TYPE
 |  SUBSYSTEM_TYPE
 |  MACHINE_TYPE
 |  RELOCATION_TYPE
 |  RESOURCE_TYPE
 |  LANG
 |  SUBLANG
......

第三步,撰寫代碼獲取PE文件的方法和屬性,好比section。

import pefile
import os,string,shutil,re

PEfile_Path = "MFCApplication.exe"

#解析PE文件
pe = pefile.PE(PEfile_Path)
print(type(pe))
print(pe)

#查看方法和屬性
print(dir(pefile.PE))
for section in pe.sections:
    print(section)

輸出以下結果:

在這裏插入圖片描述

獲取導入表信息代碼以下:

import pefile
import os,string,shutil,re

PEfile_Path = "MFCApplication.exe"

#解析PE文件
pe = pefile.PE(PEfile_Path)
print(type(pe))
print(pe)

#獲取導入表信息
for item in pe.DIRECTORY_ENTRY_IMPORT:
    print(item.dll)
    for con in item.imports:
        print(con.name)
    print("") #換行

輸出以下所示的結果,包括KERNEL32.dll、USER32.dll等。

b'KERNEL32.dll'
b'RtlUnwind'
b'GetModuleHandleExW'
b'GetCommandLineA'
b'GetSystemInfo'
b'CreateThread'
...

b'USER32.dll'
b'DlgDirSelectExA'
b'FindWindowExA'
b'FindWindowA'
b'SetParent'
b'ChildWindowFromPointEx'
...

b'GDI32.dll'
b'CreateEllipticRgn'
b'CreateFontIndirectA'
b'CreateHatchBrush'
b'CreateICA'
b'CreatePalette'
b'CreatePen'
...

b'MSIMG32.dll'
b'AlphaBlend'
b'GradientFill'
b'TransparentBlt'

b'ADVAPI32.dll'
b'RegCloseKey'
b'RegQueryValueExA'
b'RegCreateKeyExA'
b'RegDeleteKeyA'
...

b'SHELL32.dll'
b'SHGetPathFromIDListA'
b'SHGetSpecialFolderLocation'
b'SHBrowseForFolderA'
b'SHGetDesktopFolder'
b'DragAcceptFiles'
...

b'COMCTL32.dll'
b'InitCommonControlsEx'

...

對應010editor的PE軟件分析結果以下:

在這裏插入圖片描述


第四步,分析文件結構及時間戳位置。
一樣,咱們可使用stud_PE查看文件屬性,該軟件用於顯示頭部、DOs、區段、函數等信息,包括導入表、導出表等,顯示該EXE程序加載的DLL文件及函數。

在這裏插入圖片描述

這裏咱們最關心的內容是「TimeDateStamp」,接下來想辦法獲取它便可。

typedef     struct _IMAGE_FILE_HEADER 
{ 
 
  
	+04h    WORD        Machine;              // 運行平臺
	+06h    WORD        NumberOfSections;     // 文件的區塊數目
	+08h    DWORD       TimeDateStamp;        // 文件建立日期和時間
	+0Ch    DWORD       PointerToSymbolTable; // 指向符號表(主要用於調試)
	+10h    DWORD       NumberOfSymbols;      // 符號表中符號個數(同上)
	+14h    WORD        SizeOfOptionalHeader; // IMAGE_OPTIONAL_HEADER32 結構大小
	+16h    WORD        Characteristics;      // 文件屬性
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

對應的Python包返回的值以下所示:

在這裏插入圖片描述


第五步,接着咱們經過pe.DOS_HEADER、pe.FILE_HEADER等方法獲取對應的內容。

import pefile
import os,string,shutil,re

PEfile_Path = "MFCApplication.exe"

#解析PE文件
pe = pefile.PE(PEfile_Path, fast_load=True)
print(type(pe))
print(pe)

#顯示DOS_HEADER
print(pe.DOS_HEADER,"\n")

#顯示NT_HEADERS
print(pe.NT_HEADERS,"\n")

#顯示FILE_HEADER
print(pe.FILE_HEADER,"\n")

#顯示OPTIONAL_HEADER
print(pe.OPTIONAL_HEADER,"\n")

輸出以下圖所示的結構,其中時間戳也在其中。

在這裏插入圖片描述

做者本想經過它指定的方法提取對應的值,但一直失敗,但做爲長期從事NLP和數據挖掘的程序員,這都不是事,咱們經過正則表達式便可提取所需知識。

import pefile
import os,string,shutil,re

PEfile_Path = "MFCApplication.exe"

#解析PE文件
pe = pefile.PE(PEfile_Path, fast_load=True)
print(type(pe))
print(pe)
print(pe.get_imphash())

#顯示DOS_HEADER
dh = pe.DOS_HEADER

#顯示NT_HEADERS
nh = pe.NT_HEADERS

#顯示FILE_HEADER
fh = pe.FILE_HEADER

#顯示OPTIONAL_HEADER
oh = pe.OPTIONAL_HEADER

print(type(fh)) #<class 'pefile.Structure'>
print(str(fh))

#經過正則表達式獲取時間
p = re.compile(r'[[](.*?)[]]', re.I|re.S|re.M)   #最小匹配
res = re.findall(p, str(fh))
print(res[1])                                    #第一個值是IMAGE_FILE_HEADER
# Fri Jun 19 10:46:21 2020 UTC

最終輸出結果以下所示,這樣咱們就完成了Python自動化提取PE軟件的時間戳過程。任何一個PE軟件都能進行提取,該時間戳也記錄了軟件的編譯時間。

<class 'pefile.PE'>
Squeezed text(347 lines).

<class 'pefile.Structure'>
[IMAGE_FILE_HEADER]
0x10C      0x0   Machine:                       0x14C     
0x10E      0x2   NumberOfSections:              0xA       
0x110      0x4   TimeDateStamp:                 0x5EEC977D [Fri Jun 19 10:46:21 2020 UTC]
0x114      0x8   PointerToSymbolTable:          0x0       
0x118      0xC   NumberOfSymbols:               0x0       
0x11C      0x10  SizeOfOptionalHeader:          0xE0      
0x11E      0x12  Characteristics:               0x102     

Fri Jun 19 10:46:21 2020 UTC


四.時間戳判斷來源地區

1.UTC時間轉換

協調世界時,又稱世界統一時間、世界標準時間、國際協調時間。因爲英文(CUT)和法文(TUC)的縮寫不一樣,做爲妥協,簡稱UTC。協調世界時是以原子時秒長爲基礎,在時刻上儘可能接近於世界時的一種時間計量系統。Python時間解析代碼以下:

import pefile
import time
import datetime
import os,string,shutil,re

PEfile_Path = "MFCApplication.exe"

#----------------------------------第一步 解析PE文件-------------------------------
pe = pefile.PE(PEfile_Path, fast_load=True)
print(type(pe))
print(pe)
print(pe.get_imphash())

#顯示DOS_HEADER
dh = pe.DOS_HEADER

#顯示NT_HEADERS
nh = pe.NT_HEADERS

#顯示FILE_HEADER
fh = pe.FILE_HEADER

#顯示OPTIONAL_HEADER
oh = pe.OPTIONAL_HEADER

print(type(fh)) #<class 'pefile.Structure'>
print(str(fh))

#----------------------------------第二步 獲取UTC時間-------------------------------
#經過正則表達式獲取時間
p = re.compile(r'[[](.*?)[]]', re.I|re.S|re.M)   #最小匹配
res = re.findall(p, str(fh))
print(res[1])                                    #第一個值是IMAGE_FILE_HEADER
res_time = res[1].replace(" UTC","")
# Fri Jun 19 10:46:21 2020 UTC

#獲取當前時間
t = time.ctime()
print(t)                                         # Thu Jul 16 20:42:18 2020
final_time = datetime.datetime.strptime(res_time, '%a %b %d %H:%M:%S %Y')
print(final_time)
# 2020-06-19 10:46:21

輸出結果以下,能夠看到該EXE的建立時間。若是想轉換成時間戳能夠進一步處理。

  • Fri Jun 19 10:46:21 2020 UTC
  • 2020-06-19 10:46:21

接下來咱們須要進一步分析,根據時間戳判斷所在區域。



2.時區APT溯源案例(白象)

做者在「七十四.APT攻擊檢測溯源與常見APT組織的攻擊案例」文章中普及過,安天公司經過時區溯源白象APT來自南亞地區,這裏再進行回顧下。

在過去的四年中,安天的工程師們關注到了中國的機構和用戶反覆遭遇來自「西南方向」的網絡入侵嘗試。這些攻擊雖進行了一些掩蓋和假裝,咱們依然能夠將其推理回原點——來自南亞次大陸的某個國家。

安天在2014年4月相關文章中披露的針對中國兩所大學被攻擊的事件,涉及如下六個樣本。其中五個樣本投放至同一個目標,這些樣本間呈現出模塊組合做業的特色。

  • 4號樣本是初始投放樣本,其具備下載其餘樣本功能
  • 3號樣本提取主機相關信息生成日誌文件
  • 5號樣本負責上傳
  • 6號樣本採集相關文檔文件信息
  • 2號樣本則是一個鍵盤記錄器

在這裏插入圖片描述

那麼,如何溯源該組織所來自的區域呢?
安天經過對樣本集的時間戳、時區分析進行分析,發現其來自南亞。樣本時間戳是一個十六進制的數據,存儲在PE文件頭裏,該值通常由編譯器在開發者建立可執行文件時自動生成,時間單位細化到秒,一般能夠認爲該值爲樣本生成時間(GMT時間)。

在這裏插入圖片描述

時間戳的分析須要收集全部可用的可執行文件時間戳,並剔除過早的和明顯人爲修改的時間,再將其根據特定標準分組統計,如每週的天或小時,並以圖形的形式體現,下圖是經過小時分組統計結果:

在這裏插入圖片描述

從上圖的統計結果來看,若是假設攻擊者的工做時間是早上八九點至下午五六點的話,那麼將工做時間匹配到一個來自UTC+4或UTC+5時區的攻擊者的工做時間。根據咱們匹配的攻擊者所在時區(UTC+4 或UTC+5),再對照世界時區分佈圖,就能夠來推斷攻擊者所在的區域或國家。

在這裏插入圖片描述

接着對該攻擊組織進行更深刻的分析。對這一攻擊組織繼續綜合線索,基於互聯網公開信息,進行了畫像分析,認爲這是一個由10~16人的組成的攻擊小組。其中六人的用戶ID是cr01nk 、neeru rana、andrew、Yash、Ita nagar、Naga。

在這裏插入圖片描述

在安天的跟蹤分析中,發現該組織的部分C&C地址是一些正常的網站,通過分析咱們認爲,有可能該組織入侵了這些網站,將本身的C&C服務控制代碼放到它們的服務器上,以此來隱藏本身的IP信息。同時這種方式還會使安全軟件認爲鏈接的是正常的網站,而不會觸發安全警報。

基於現有資源能夠分析出,「白象二代」組織一名開發人員的ID爲「Kanishk」,經過維基百科查詢到一個相似單詞「Kanishka」,這是一個是梵文譯音,中文翻譯爲「迦膩色迦」,迦膩色伽是貴霜帝國(Kushan Empire)的君主,貴霜帝國主要控制範圍在印度河流域。至此推測該APT組織來自南亞某國。

在這裏插入圖片描述

經過這個案例,咱們能夠經過時區、公開信息、黑客ID、C&C域名進行溯源,並一步步遞進。



3.時間戳分析

好比當前北京時間是2020年7月16日晚上9點3分,而UTC時間是13點3分。

在這裏插入圖片描述

但這裏存在一個問題,當有不少惡意樣本的時候,咱們基於多個樣本時間戳並結合正常做息時間進行分析,才能判斷其來源。可是,若是僅從一個樣本進行分析,其準確率仍是會有影響,有的惡意軟件是深夜發佈,也影響了該方法的準確性,同時混淆、加殼、對抗樣本也能影響咱們的實驗效果,但做者僅是提供了一種方法,更深刻的研究還在繼續,若是您有好的方法也歡迎和我討論。

在這裏插入圖片描述

這裏咱們PE軟件獲取的時間是「2020-06-19 10:46:21」,對應北京時間是19點46分。由於做者習慣晚上寫代碼,但若是是軟件或惡意樣本,大公司一般會有正常的做息,從而能夠結合海量數據分析來肯定最終的軟件來源地區或國家。

  • Fri Jun 19 10:46:21 2020 UTC
  • 2020-06-19 10:46:21

此時的Python代碼以下:

import pefile
import time
import warnings
import datetime
import os,string,shutil,re

#忽略警告
warnings.filterwarnings("ignore")

PEfile_Path = "MFCApplication.exe"

#----------------------------------第一步 解析PE文件-------------------------------
pe = pefile.PE(PEfile_Path, fast_load=True)
print(type(pe))
print(pe)
print(pe.get_imphash())

#顯示DOS_HEADER
dh = pe.DOS_HEADER

#顯示NT_HEADERS
nh = pe.NT_HEADERS

#顯示FILE_HEADER
fh = pe.FILE_HEADER

#顯示OPTIONAL_HEADER
oh = pe.OPTIONAL_HEADER

print(type(fh)) #<class 'pefile.Structure'>
print(str(fh))

#----------------------------------第二步 獲取UTC時間-------------------------------
#經過正則表達式獲取時間
p = re.compile(r'[[](.*?)[]]', re.I|re.S|re.M)   #最小匹配
res = re.findall(p, str(fh))
print(res[1])                                    #第一個值是IMAGE_FILE_HEADER
res_time = res[1].replace(" UTC","")
# Fri Jun 19 10:46:21 2020 UTC

#獲取當前時間
t = time.ctime()
print(t,"\n")                                    # Thu Jul 16 20:42:18 2020
utc_time = datetime.datetime.strptime(res_time, '%a %b %d %H:%M:%S %Y')
print("UTC Time:", utc_time)
# 2020-06-19 10:46:21

#----------------------------------第三步 全球時區轉換-------------------------------
#http://zh.thetimenow.com/india
#UTC時間比北京時間晚八個小時 故用timedelta方法加上八個小時
china_time = datetime.datetime.strptime(res_time, '%a %b %d %H:%M:%S %Y') + datetime.timedelta(hours=8)
print("China Time:",china_time)

#美國 UTC-5
america_time = datetime.datetime.strptime(res_time, '%a %b %d %H:%M:%S %Y') - datetime.timedelta(hours=5)
print("America Time:",america_time)

#印度 UTC+5
india_time = datetime.datetime.strptime(res_time, '%a %b %d %H:%M:%S %Y') + datetime.timedelta(hours=5)
print("India Time:",india_time)

#澳大利亞 UTC+10
australia_time = datetime.datetime.strptime(res_time, '%a %b %d %H:%M:%S %Y') + datetime.timedelta(hours=10)
print("Australia Time",australia_time)

#俄羅斯 UTC+3
russia_time = datetime.datetime.strptime(res_time, '%a %b %d %H:%M:%S %Y') + datetime.timedelta(hours=3)
print("Russia Time",russia_time)

#英國 UTC+0
england_time = datetime.datetime.strptime(res_time, '%a %b %d %H:%M:%S %Y')
print("England Time",england_time)

#日本 UTC+9
japan_time = datetime.datetime.strptime(res_time, '%a %b %d %H:%M:%S %Y') + datetime.timedelta(hours=9)
print("Japan Time",england_time)

#德國 UTC+1
germany_time = datetime.datetime.strptime(res_time, '%a %b %d %H:%M:%S %Y') + datetime.timedelta(hours=1)
print("Germany Time",germany_time)

#法國 UTC+1
france_time = datetime.datetime.strptime(res_time, '%a %b %d %H:%M:%S %Y') + datetime.timedelta(hours=1)
print("France Time",france_time)

#加拿大 UTC-5
canada_time = datetime.datetime.strptime(res_time, '%a %b %d %H:%M:%S %Y') - datetime.timedelta(hours=5)
print("Canada Time:",canada_time)

#越南 UTC+7 
vietnam_time = datetime.datetime.strptime(res_time, '%a %b %d %H:%M:%S %Y') + datetime.timedelta(hours=7)
print("Vietnam Time:",vietnam_time)

輸出結果以下圖所示,不一樣地區有對應的時間分佈,若是正常做息是早上9點到12點、下午2點到5點,從結果看更像是來自India、England、Japan等地區。固然,只有惡意樣本不少的時候,咱們才能進行更好的溯源,哈哈~

在這裏插入圖片描述



五.總結

寫到這裏,這篇文章就介紹完畢,但願對您有所幫助,最後進行簡單的總結下做者的猜測。

  • 經過PE文件分析抓取建立文件時間戳,而後UTC定位國家地區,但受樣本數量較少,活動規律不穩定影響很大
  • 經過靜態分析獲取非英文字符串,軟件中通常有供該國使用的文字,而後進行編碼比對溯源地區
  • 某些APP或軟件存在流量反饋或IP定位,嘗試進行流量抓取分析
  • 利用深度學習進行分類,而後提取不一樣國家的特徵完成溯源

本文嘗試的是最簡單的方法,因此也存在不少問題,好比當有不少惡意樣本的時候,咱們才能基於多個樣本時間戳並結合正常做息時間進行分析,才能判斷其來源。若是僅從一個樣本進行分析,其準確率仍是會有影響,有的惡意軟件是深夜發佈,也影響了該方法的準確性,同時混淆、加殼、對抗樣本也能影響咱們的實驗效果,但做者僅是提供了一種方法,更深刻的研究還在繼續,若是您有好的方法也歡迎和我討論。

最後歡迎你們討論如何判斷PE軟件或APP來源哪一個國家或地區呢?印度又是如何確保一鍵正確卸載中國APP呢?哈哈,未知攻,焉知防。加油~

學安全一年,認識了不少安全大佬和朋友,但願你們一塊兒進步。這篇文章中若是存在一些不足,還請海涵。做者做爲網絡安全初學者的慢慢成長路吧!但願將來能更透徹撰寫相關文章。同時很是感謝參考文獻中的安全大佬們的文章分享,深知本身很菜,得努力前行。

(By:Eastmount 2020-07-23 星期日 下午5點寫於武漢 http://blog.csdn.net/eastmount/ )



參考文獻:
[1] [網絡安全自學篇] 六十二.PE文件逆向之PE文件解析、PE編輯工具使用和PE結構修改(三)
[2] 白象的舞步——來自南亞次大陸的網絡攻擊
[3] https://xz.aliyun.com/t/2688
[4] [原創]利用python+pefile庫作PE格式文件的快速開發 - jmpjerryy
[5] python 時間類型和相互轉換 - shhnwangjian