|is[dZddlmZdZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z e j e j e j eZe j e j edZeej vrej deddlmZddlmZmZmZmZmZmZddlmZdd l m!Z!ej"d Z#Gd d e$Z%e%j&d e%j'de%j(de%j)de%j*de%j+de%j,diZ-dZ.Gdde$Z/Gdde$Z0dZ1e2dkr e1dSdS)aT oleid.py oleid is a script to analyze OLE files such as MS Office documents (e.g. Word, Excel), to detect specific characteristics that could potentially indicate that the file is suspicious or malicious, in terms of security (e.g. malware). For example it can detect VBA macros, embedded Flash objects, fragmentation. The results is displayed as ascii table (but could be returned or printed in other formats like CSV, XML or JSON in future). oleid project website: http://www.decalage.info/python/oleid oleid is part of the python-oletools package: http://www.decalage.info/python/oletools )print_functionz0.60.1Nz..) tablestream)cryptoftguessolevbamraptoroleobjooxml) log_helper)get_codepage_nameoleidc.eZdZdZdZdZdZdZdZdZ dZ d S) RISKz# Constants for risk levels HIGHMediumlownoneinfoUnknownErrorN) __name__ __module__ __qualname____doc__rMEDIUMLOWNONEINFOUNKNOWNERROR> D  D c0eZdZdZdeddejdfdZdS) Indicatorz Piece of information of an :py:class:`OleID` object. Contains an ID, value, type, name and description. No other functionality. NTc||_||_||_||_|dkr||_||_||_||_dS)N)idvaluetypename descriptionrisk hide_if_false)self_idrF_typerHrIrJrKs r#__init__zIndicator.__init__sK   4<<DI& *r")rrrrboolrrrOr!r"r#rCrCsD #'d! D + + + + + +r"rCcJeZdZdZd dZdZdZdZdZdZ d Z d Z d Z dS) OleIDz Summary of information about an OLE file (and a few other MS Office formats) Call :py:meth:`OleID.check` to gather all info on a given file or run one of the `check_` functions to just get a specific piece of info. Nc||tdd|_|Id|_t|d5}||_dddn #1swxYwYn||_t j|j|_t|tj r||_ d|_ n||_ d|_ g|_ d|_dS)a! Create an OleID object This does not run any checks yet nor open the file. Can either give just a filename (as str), so OleID will check whether that is a valid OLE file and create a :py:class:`olefile.OleFileIO` object for it. Or you can give an already opened :py:class:`olefile.OleFileIO` as argument to avoid re-opening (e.g. if called from other oletools). If filename is given, only :py:meth:`OleID.check` opens the file. Other functions will return None Nz7OleID requires either a file path or file data, or bothFTrb) ValueError file_on_diskopenreadr8ioBytesIO data_bytesio isinstanceolefile OleFileIOolefilename indicators suminfo_data)rLr`r8fs r#rOzOleID.__init__s    VWW W! < $D h%% %FFHH  % % % % % % % % % % % % % % %DIJty11 h 1 2 2 DH DMM$DMDH sAA!AcBfd|jD}|r|dSdS)z:Helper function: returns an indicator if present (or None)c*g|]}|jk |Sr!)rE).0 indicator indicator_ids r# z'OleID.get_indicator..s/333 \\11111r"rN)ra)rLrhresults ` r# get_indicatorzOleID.get_indicatorsC3333T_333  !9 4r"ctj|j|j|_|jj}|jjtjjkr+d |jj |jj }nd}td|j tdtj|}|j|td|jtdtjd }|j||jjtjjkr|jj|_|||||||j|j|jS) zs Open file and run all checks on it. :returns: list of all :py:class:`Indicator`s created )filepathr8z*Unrecognized OLE file. Root CLSID: {} - {}ftypez File format)rFrNrHrJrI containerzContainer formatzContainer type)rFileTypeGuesserr`r8ftgrofiletypeFTYPE GENERIC_OLEformat root_clsidroot_clsid_namerClongnamestrrrrar7rp CONTAINEROLEr]r_check_propertiescheck_encrypted check_macroscheck_external_relationshipscheck_object_pool check_flashclose)rLrorIftcts r#checkz OleID.checks *DM RRR 8  9 9 9FMM#TX%=??KKK wenCmZ^Zc#.000 r""" {%/K]dhdm#3555 r""" 8 !2!6 6 6x'DH    ))+++      8  HNN   r"cD|jsdS|j}td|jtddt j}|j|d}|j -d |j t|j }td|tdd t j}|j|td |j td d t j}|j||||fS) z Read summary information required for other check_* functions :returns: 2 :py:class:`Indicator`s (for presence of summary info and application name) or None if file was not opened NappnamezApplication namez'Application name declared in propertiesrNrHrIrJz{}: {}codepagezProperties code pagezCode page used for propertiesauthorAuthorzAuthor declared in properties) r_ get_metadatarCcreating_applicationrzrrrar7rrvr r)rLmetar codepage_namerrs r#r}zOleID.check_properties3sx 4x$$&&It'@!3Aj!%,,, w''' = $$OODM;LT];[;[\\MZc1?^9&&& x(((8T[#1P9&&& v&&&&((r"ctdddtjdd}|j||jsdS t j|jrd|_tj |_ d|_ nI#t$r<}d |_tj |_ d ||_ Yd}~nd}~wwxYw|S) z Check whether this file is encrypted. :returns: :py:class:`Indicator` for encryption or None if file was not opened encryptedF EncryptedzThe file is not encrypted)rHrJrIrKNTz@The file is encrypted. It may be decrypted with msoffcrypto-toolrzKmsoffcrypto-tool raised an error when checking if the file is encrypted: {})rCrrrar7r_r is_encryptedrFrrJrIr6r rv)rLr exceptions r#r~zOleID.check_encryptedNsk5{#'9*E,1333  y)))x 4 D"48,, k"& !% (j % D D D%IO!ZIN$q$x$xzC%D%DI ! ! ! ! ! !  D s8A== C2B>>Cc ttdddttjdd}|j||js|St}tj |j }tj |D]X\}}td|||||xjdz c_Y|jdkr>d d ||_tj|_|S) z Check whether this file has external relationships (remote template, OLE object, etc). :returns: :py:class:`Indicator` ext_relsrzExternal RelationshipszHExternal relationships such as remote templates, remote OLE objects, etcF)rHrNrJrIrKz(External relationship: type={} target={}z9External relationships found: {} - use oleobj for detailsz, )rCintrrrar7rr is_openxmlsetr XmlParserr[r find_external_relationshipslogdebugrvaddrFjoinrIrrJ)rLr rel_types xmlparserrel_typetargets r#rz"OleID.check_external_relationshipsjs$ Z1IQT#'9*t,1333 x(((x""$$ OEE OD$566 & B9 M M  Hf II@GGRXYY Z Z Z MM( # # # NNa NNN >A  #^#e#e )$$$&$&H  IHMr"ctddddtj}|j||jsdS|jdrd|_tj|_ |S)a  Check whether this file contains an ObjectPool stream. Such a stream would be a strong indicator for embedded objects or files. :returns: :py:class:`Indicator` for ObjectPool stream or None if file was not opened ObjectPoolFzlContains an ObjectPool stream, very likely to contain embedded OLE objects or files. Use oleobj to check it.)rHrIrJNT) rCrrrar7r_existsrFrrJ)rLobjpools r#rzOleID.check_object_pools~ %lQ  w'''x 4 8??< ( ( $ GM8GLr"c tddtddtjd}|j|tddtdd tjd}|j||jjtj j krd |_ d |_ ||fSd } tj |j|j }|rd|_tj|_d|_ |}t+j|}||jrd|_tj|_d|_ nF#t4$r9}tj|_d|_dt|z|_ Yd }~nd }~wwxYw||d }n#||d }wxYw|jr|jr tj |j}|rd|_tj|_d|_ nF#t4$r9}tj|_d|_dt|z|_ Yd }~nd }~wwxYw||n;#||wwxYwtj |_d|_d|_ ||fS)zy Check whether this file contains macros (VBA and XLM/Excel 4). :returns: :py:class:`Indicator` vbaNoz VBA Macrosz&This file does not contain VBA macros.F)rMrFrNrHrIrJrKxlmz XLM Macrosz.This file does not contain Excel 4/XLM macros.z#RTF files cannot contain VBA macrosz#RTF files cannot contain XLM macrosN)r`r8YeszeThis file contains VBA macros. No suspicious keyword was found. Use olevba and mraptor for more info.zYes, suspiciouszdThis file contains VBA macros. Suspicious keywords were found. Use olevba and mraptor for more info.rz#Error while checking VBA macros: %s)r`z:This file contains XLM macros. Use olevba to analyse them.z#Error while checking XLM macros: %srzIFor now, XLM macros can only be detected for files on disk, not in memory)!rCrzrrrar7rrrsrrtRTFrIr VBA_Parserr`r8detect_vba_macrosrFrrJget_vba_code_all_modulesr MacroRaptorscan suspiciousrr6r ris_excelrVdetect_xlm_macrosr)rL vba_indicator xlm_indicator vba_parservba_codemes r#rzOleID.check_macross< "e4s.V'+yGGG  }---!e4s.^'+yGGG  }--- 8  1 1 1(MM %(MM % -/ /  *DM RRRJ++-- W&+ #%)[ "-T )%>>@@'11<W*;M')-M&1WM- W W W!%M ")M (MPSTUPVPV(VM % % % % % % W %  """JJ%  """J     8     x  x +!'!2DM!J!J!JJ!3355q.3 +-1[ *4p 1 ___)-M&*1M'0UX[\]X^X^0^M------_ "-"((***"-"((****.&*\ "&/ #,w )m++sb3B5E)(G) F,3/F'"G'F,,GG"A IJ1 J/J J1JJ11K ctddtddtj}|j||jsdS|jD]Z}|j| }t|}|xj t|z c_ [|j dkrtj |_|S)z Check whether this file contains flash objects :returns: :py:class:`Indicator` for count of flash objects or None if file was not opened flashrz Flash objectszvNumber of embedded Flash objects (SWF files) detected in OLE streams. Not 100% accurate, there may be false positives.rN)rCrrrrar7r_listdir openstreamrXrArFr1rrJ)rLrstreamr8r9s r#rzOleID.check_flashs Qc%  u%%%x 4h&&(( & &F8&&v..3355D &&E KK3u:: %KKK ;??EJ r")NN) rrrrrOrkrr}r~rrrrr!r"r#rRrRs ! ! ! !D...`)))6882A,A,A,Fr"rRc btdtztdtdtdtjt}|dt ddd |}t|j d kr| d Stj |j D]}td |t|}|}tjgdgdtj}|D]c}|jr|jrSt(|jd }||j|j|j|jf|||d fd|d S)zFCalled when running this file as script. Shows all info on input file.z(oleid %s - http://decalage.info/oletoolsz3THIS IS WORK IN PROGRESS - Check updates regularly!zGPlease report any issue at https://github.com/decalage2/oletools/issuesrn)rIinput*FILEzName of files to process)rGnargsmetavarhelprNz Filename:)r-r- )rCValueRisk Description) header_rowstyle)colors)print __version__argparseArgumentParserr add_argumentrz parse_argsr1r print_helpr enable_loggingrRrr TableStreamTableStyleSlimSeprKrF risk_colorgetrJ write_rowrHrIr)parserargsr`r ratablergcolors r#mainrs 4{ BCCC ?@@@  9::: "III  $ 9 9 9F cf7999     D 4:!J k8$$$h[[]] '(8(8(83`3`3`.9.KMMM$ D DI+ DIO D"y~t<<).R[Rg h(-ueT'B DDD r"__main__)3r __future__rrrsysr.r4r2osrYr]pathnormpathabspathdirname__file___thismodule_dirr _parent_dirinsertoletools.thirdparty.tablestreamroletoolsrrrrr r oletools.common.log_helperr oletools.common.codepagesr get_or_create_silent_loggerrobjectrrrrrrrr rrArCrRrrr!r"r#rsV&%%%%%$ */...........................'""27??27??83L3L#M#MNNgrw||OTBBCC chHOOA{###777777DDDDDDDDDDDDDDDD111111777777-j,W55     6    IuKHgIwIvL$J 000j++++++++(kkkkkFkkk` '''R zDFFFFFr"