smb.py 148 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099
  1. # Copyright (c) 2003-2016 CORE Security Technologies
  2. #
  3. # This software is provided under under a slightly modified version
  4. # of the Apache Software License. See the accompanying LICENSE file
  5. # for more information.
  6. #
  7. # Copyright (C) 2001 Michael Teo <michaelteo@bigfoot.com>
  8. # smb.py - SMB/CIFS library
  9. #
  10. # This software is provided 'as-is', without any express or implied warranty.
  11. # In no event will the author be held liable for any damages arising from the
  12. # use of this software.
  13. #
  14. # Permission is granted to anyone to use this software for any purpose,
  15. # including commercial applications, and to alter it and redistribute it
  16. # freely, subject to the following restrictions:
  17. #
  18. # 1. The origin of this software must not be misrepresented; you must not
  19. # claim that you wrote the original software. If you use this software
  20. # in a product, an acknowledgment in the product documentation would be
  21. # appreciated but is not required.
  22. #
  23. # 2. Altered source versions must be plainly marked as such, and must not be
  24. # misrepresented as being the original software.
  25. #
  26. # 3. This notice cannot be removed or altered from any source distribution.
  27. #
  28. # Altered source done by Alberto Solino (@agsolino)
  29. # Todo:
  30. # [ ] Try [SMB]transport fragmentation using Transact requests
  31. # [ ] Try other methods of doing write (write_raw, transact2, write, write_and_unlock, write_and_close, write_mpx)
  32. # [-] Try replacements for SMB_COM_NT_CREATE_ANDX (CREATE, T_TRANSACT_CREATE, OPEN_ANDX works
  33. # [x] Fix forceWriteAndx, which needs to send a RecvRequest, because recv() will not send it
  34. # [x] Fix Recv() when using RecvAndx and the answer comes splet in several packets
  35. # [ ] Try [SMB]transport fragmentation with overlaping segments
  36. # [ ] Try [SMB]transport fragmentation with out of order segments
  37. # [x] Do chained AndX requests
  38. # [ ] Transform the rest of the calls to structure
  39. # [X] Implement TRANS/TRANS2 reassembly for list_path
  40. import os
  41. import socket
  42. import string
  43. from binascii import a2b_hex
  44. import datetime
  45. from struct import pack, unpack
  46. from contextlib import contextmanager
  47. from impacket import nmb, ntlm, nt_errors, LOG
  48. from impacket.structure import Structure
  49. from impacket.spnego import SPNEGO_NegTokenInit, TypesMech, SPNEGO_NegTokenResp
  50. # For signing
  51. import hashlib
  52. unicode_support = 0
  53. unicode_convert = 1
  54. try:
  55. from cStringIO import StringIO
  56. except ImportError:
  57. from StringIO import StringIO
  58. # Dialect for SMB1
  59. SMB_DIALECT = 'NT LM 0.12'
  60. # Shared Device Type
  61. SHARED_DISK = 0x00
  62. SHARED_DISK_HIDDEN = 0x80000000
  63. SHARED_PRINT_QUEUE = 0x01
  64. SHARED_DEVICE = 0x02
  65. SHARED_IPC = 0x03
  66. # Extended attributes mask
  67. ATTR_ARCHIVE = 0x020
  68. ATTR_COMPRESSED = 0x800
  69. ATTR_NORMAL = 0x080
  70. ATTR_HIDDEN = 0x002
  71. ATTR_READONLY = 0x001
  72. ATTR_TEMPORARY = 0x100
  73. ATTR_DIRECTORY = 0x010
  74. ATTR_SYSTEM = 0x004
  75. # Service Type
  76. SERVICE_DISK = 'A:'
  77. SERVICE_PRINTER = 'LPT1:'
  78. SERVICE_IPC = 'IPC'
  79. SERVICE_COMM = 'COMM'
  80. SERVICE_ANY = '?????'
  81. # Server Type (Can be used to mask with SMBMachine.get_type() or SMBDomain.get_type())
  82. SV_TYPE_WORKSTATION = 0x00000001
  83. SV_TYPE_SERVER = 0x00000002
  84. SV_TYPE_SQLSERVER = 0x00000004
  85. SV_TYPE_DOMAIN_CTRL = 0x00000008
  86. SV_TYPE_DOMAIN_BAKCTRL = 0x00000010
  87. SV_TYPE_TIME_SOURCE = 0x00000020
  88. SV_TYPE_AFP = 0x00000040
  89. SV_TYPE_NOVELL = 0x00000080
  90. SV_TYPE_DOMAIN_MEMBER = 0x00000100
  91. SV_TYPE_PRINTQ_SERVER = 0x00000200
  92. SV_TYPE_DIALIN_SERVER = 0x00000400
  93. SV_TYPE_XENIX_SERVER = 0x00000800
  94. SV_TYPE_NT = 0x00001000
  95. SV_TYPE_WFW = 0x00002000
  96. SV_TYPE_SERVER_NT = 0x00004000
  97. SV_TYPE_POTENTIAL_BROWSER = 0x00010000
  98. SV_TYPE_BACKUP_BROWSER = 0x00020000
  99. SV_TYPE_MASTER_BROWSER = 0x00040000
  100. SV_TYPE_DOMAIN_MASTER = 0x00080000
  101. SV_TYPE_LOCAL_LIST_ONLY = 0x40000000
  102. SV_TYPE_DOMAIN_ENUM = 0x80000000
  103. # Options values for SMB.stor_file and SMB.retr_file
  104. SMB_O_CREAT = 0x10 # Create the file if file does not exists. Otherwise, operation fails.
  105. SMB_O_EXCL = 0x00 # When used with SMB_O_CREAT, operation fails if file exists. Cannot be used with SMB_O_OPEN.
  106. SMB_O_OPEN = 0x01 # Open the file if the file exists
  107. SMB_O_TRUNC = 0x02 # Truncate the file if the file exists
  108. # Share Access Mode
  109. SMB_SHARE_COMPAT = 0x00
  110. SMB_SHARE_DENY_EXCL = 0x10
  111. SMB_SHARE_DENY_WRITE = 0x20
  112. SMB_SHARE_DENY_READEXEC = 0x30
  113. SMB_SHARE_DENY_NONE = 0x40
  114. SMB_ACCESS_READ = 0x00
  115. SMB_ACCESS_WRITE = 0x01
  116. SMB_ACCESS_READWRITE = 0x02
  117. SMB_ACCESS_EXEC = 0x03
  118. TRANS_DISCONNECT_TID = 1
  119. TRANS_NO_RESPONSE = 2
  120. STATUS_SUCCESS = 0x00000000
  121. STATUS_LOGON_FAILURE = 0xC000006D
  122. STATUS_LOGON_TYPE_NOT_GRANTED = 0xC000015B
  123. MAX_TFRAG_SIZE = 5840
  124. EVASION_NONE = 0
  125. EVASION_LOW = 1
  126. EVASION_HIGH = 2
  127. EVASION_MAX = 3
  128. RPC_X_BAD_STUB_DATA = 0x6F7
  129. # SMB_FILE_ATTRIBUTES
  130. SMB_FILE_ATTRIBUTE_NORMAL = 0x0000
  131. SMB_FILE_ATTRIBUTE_READONLY = 0x0001
  132. SMB_FILE_ATTRIBUTE_HIDDEN = 0x0002
  133. SMB_FILE_ATTRIBUTE_SYSTEM = 0x0004
  134. SMB_FILE_ATTRIBUTE_VOLUME = 0x0008
  135. SMB_FILE_ATTRIBUTE_DIRECTORY = 0x0010
  136. SMB_FILE_ATTRIBUTE_ARCHIVE = 0x0020
  137. SMB_SEARCH_ATTRIBUTE_READONLY = 0x0100
  138. SMB_SEARCH_ATTRIBUTE_HIDDEN = 0x0200
  139. SMB_SEARCH_ATTRIBUTE_SYSTEM = 0x0400
  140. SMB_SEARCH_ATTRIBUTE_DIRECTORY = 0x1000
  141. SMB_SEARCH_ATTRIBUTE_ARCHIVE = 0x2000
  142. # Session SetupAndX Action flags
  143. SMB_SETUP_GUEST = 0x01
  144. SMB_SETUP_USE_LANMAN_KEY = 0x02
  145. # QUERY_INFORMATION levels
  146. SMB_INFO_ALLOCATION = 0x0001
  147. SMB_INFO_VOLUME = 0x0002
  148. FILE_FS_SIZE_INFORMATION = 0x0003
  149. SMB_QUERY_FS_VOLUME_INFO = 0x0102
  150. SMB_QUERY_FS_SIZE_INFO = 0x0103
  151. SMB_QUERY_FILE_EA_INFO = 0x0103
  152. SMB_QUERY_FS_DEVICE_INFO = 0x0104
  153. SMB_QUERY_FS_ATTRIBUTE_INFO = 0x0105
  154. SMB_QUERY_FILE_BASIC_INFO = 0x0101
  155. SMB_QUERY_FILE_STANDARD_INFO = 0x0102
  156. SMB_QUERY_FILE_ALL_INFO = 0x0107
  157. FILE_FS_FULL_SIZE_INFORMATION = 0x03EF
  158. # SET_INFORMATION levels
  159. SMB_SET_FILE_DISPOSITION_INFO = 0x0102
  160. SMB_SET_FILE_BASIC_INFO = 0x0101
  161. SMB_SET_FILE_END_OF_FILE_INFO = 0x0104
  162. # File System Attributes
  163. FILE_CASE_SENSITIVE_SEARCH = 0x00000001
  164. FILE_CASE_PRESERVED_NAMES = 0x00000002
  165. FILE_UNICODE_ON_DISK = 0x00000004
  166. FILE_PERSISTENT_ACLS = 0x00000008
  167. FILE_FILE_COMPRESSION = 0x00000010
  168. FILE_VOLUME_IS_COMPRESSED = 0x00008000
  169. # FIND_FIRST2 flags and levels
  170. SMB_FIND_CLOSE_AFTER_REQUEST = 0x0001
  171. SMB_FIND_CLOSE_AT_EOS = 0x0002
  172. SMB_FIND_RETURN_RESUME_KEYS = 0x0004
  173. SMB_FIND_CONTINUE_FROM_LAST = 0x0008
  174. SMB_FIND_WITH_BACKUP_INTENT = 0x0010
  175. FILE_DIRECTORY_FILE = 0x00000001
  176. FILE_DELETE_ON_CLOSE = 0x00001000
  177. FILE_NON_DIRECTORY_FILE = 0x00000040
  178. SMB_FIND_INFO_STANDARD = 0x0001
  179. SMB_FIND_FILE_DIRECTORY_INFO = 0x0101
  180. SMB_FIND_FILE_FULL_DIRECTORY_INFO= 0x0102
  181. SMB_FIND_FILE_NAMES_INFO = 0x0103
  182. SMB_FIND_FILE_BOTH_DIRECTORY_INFO= 0x0104
  183. SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO = 0x105
  184. SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO = 0x106
  185. # DesiredAccess flags
  186. FILE_READ_DATA = 0x00000001
  187. FILE_WRITE_DATA = 0x00000002
  188. FILE_APPEND_DATA = 0x00000004
  189. FILE_EXECUTE = 0x00000020
  190. MAXIMUM_ALLOWED = 0x02000000
  191. GENERIC_ALL = 0x10000000
  192. GENERIC_EXECUTE = 0x20000000
  193. GENERIC_WRITE = 0x40000000
  194. GENERIC_READ = 0x80000000
  195. # ShareAccess flags
  196. FILE_SHARE_NONE = 0x00000000
  197. FILE_SHARE_READ = 0x00000001
  198. FILE_SHARE_WRITE = 0x00000002
  199. FILE_SHARE_DELETE = 0x00000004
  200. # CreateDisposition flags
  201. FILE_SUPERSEDE = 0x00000000
  202. FILE_OPEN = 0x00000001
  203. FILE_CREATE = 0x00000002
  204. FILE_OPEN_IF = 0x00000003
  205. FILE_OVERWRITE = 0x00000004
  206. FILE_OVERWRITE_IF = 0x00000005
  207. def strerror(errclass, errcode):
  208. if errclass == 0x01:
  209. return 'OS error', ERRDOS.get(errcode, 'Unknown error')
  210. elif errclass == 0x02:
  211. return 'Server error', ERRSRV.get(errcode, 'Unknown error')
  212. elif errclass == 0x03:
  213. return 'Hardware error', ERRHRD.get(errcode, 'Unknown error')
  214. # This is not a standard error class for SMB
  215. #elif errclass == 0x80:
  216. # return 'Browse error', ERRBROWSE.get(errcode, 'Unknown error')
  217. elif errclass == 0xff:
  218. return 'Bad command', 'Bad command. Please file bug report'
  219. else:
  220. return 'Unknown error', 'Unknown error'
  221. # Raised when an error has occured during a session
  222. class SessionError(Exception):
  223. # SMB X/Open error codes for the ERRDOS error class
  224. ERRsuccess = 0
  225. ERRbadfunc = 1
  226. ERRbadfile = 2
  227. ERRbadpath = 3
  228. ERRnofids = 4
  229. ERRnoaccess = 5
  230. ERRbadfid = 6
  231. ERRbadmcb = 7
  232. ERRnomem = 8
  233. ERRbadmem = 9
  234. ERRbadenv = 10
  235. ERRbadaccess = 12
  236. ERRbaddata = 13
  237. ERRres = 14
  238. ERRbaddrive = 15
  239. ERRremcd = 16
  240. ERRdiffdevice = 17
  241. ERRnofiles = 18
  242. ERRgeneral = 31
  243. ERRbadshare = 32
  244. ERRlock = 33
  245. ERRunsup = 50
  246. ERRnetnamedel = 64
  247. ERRnosuchshare = 67
  248. ERRfilexists = 80
  249. ERRinvalidparam = 87
  250. ERRcannotopen = 110
  251. ERRinsufficientbuffer = 122
  252. ERRinvalidname = 123
  253. ERRunknownlevel = 124
  254. ERRnotlocked = 158
  255. ERRrename = 183
  256. ERRbadpipe = 230
  257. ERRpipebusy = 231
  258. ERRpipeclosing = 232
  259. ERRnotconnected = 233
  260. ERRmoredata = 234
  261. ERRnomoreitems = 259
  262. ERRbaddirectory = 267
  263. ERReasnotsupported = 282
  264. ERRlogonfailure = 1326
  265. ERRbuftoosmall = 2123
  266. ERRunknownipc = 2142
  267. ERRnosuchprintjob = 2151
  268. ERRinvgroup = 2455
  269. # here's a special one from observing NT
  270. ERRnoipc = 66
  271. # These errors seem to be only returned by the NT printer driver system
  272. ERRdriveralreadyinstalled = 1795
  273. ERRunknownprinterport = 1796
  274. ERRunknownprinterdriver = 1797
  275. ERRunknownprintprocessor = 1798
  276. ERRinvalidseparatorfile = 1799
  277. ERRinvalidjobpriority = 1800
  278. ERRinvalidprintername = 1801
  279. ERRprinteralreadyexists = 1802
  280. ERRinvalidprintercommand = 1803
  281. ERRinvaliddatatype = 1804
  282. ERRinvalidenvironment = 1805
  283. ERRunknownprintmonitor = 3000
  284. ERRprinterdriverinuse = 3001
  285. ERRspoolfilenotfound = 3002
  286. ERRnostartdoc = 3003
  287. ERRnoaddjob = 3004
  288. ERRprintprocessoralreadyinstalled = 3005
  289. ERRprintmonitoralreadyinstalled = 3006
  290. ERRinvalidprintmonitor = 3007
  291. ERRprintmonitorinuse = 3008
  292. ERRprinterhasjobsqueued = 3009
  293. # Error codes for the ERRSRV class
  294. ERRerror = 1
  295. ERRbadpw = 2
  296. ERRbadtype = 3
  297. ERRaccess = 4
  298. ERRinvnid = 5
  299. ERRinvnetname = 6
  300. ERRinvdevice = 7
  301. ERRqfull = 49
  302. ERRqtoobig = 50
  303. ERRinvpfid = 52
  304. ERRsmbcmd = 64
  305. ERRsrverror = 65
  306. ERRfilespecs = 67
  307. ERRbadlink = 68
  308. ERRbadpermits = 69
  309. ERRbadpid = 70
  310. ERRsetattrmode = 71
  311. ERRpaused = 81
  312. ERRmsgoff = 82
  313. ERRnoroom = 83
  314. ERRrmuns = 87
  315. ERRtimeout = 88
  316. ERRnoresource = 89
  317. ERRtoomanyuids = 90
  318. ERRbaduid = 91
  319. ERRuseMPX = 250
  320. ERRuseSTD = 251
  321. ERRcontMPX = 252
  322. ERRbadPW = None
  323. ERRnosupport = 0
  324. ERRunknownsmb = 22
  325. # Error codes for the ERRHRD class
  326. ERRnowrite = 19
  327. ERRbadunit = 20
  328. ERRnotready = 21
  329. ERRbadcmd = 22
  330. ERRdata = 23
  331. ERRbadreq = 24
  332. ERRseek = 25
  333. ERRbadmedia = 26
  334. ERRbadsector = 27
  335. ERRnopaper = 28
  336. ERRwrite = 29
  337. ERRread = 30
  338. ERRwrongdisk = 34
  339. ERRFCBunavail = 35
  340. ERRsharebufexc = 36
  341. ERRdiskfull = 39
  342. hard_msgs = {
  343. 19: ("ERRnowrite", "Attempt to write on write-protected diskette."),
  344. 20: ("ERRbadunit", "Unknown unit."),
  345. 21: ("ERRnotready", "Drive not ready."),
  346. 22: ("ERRbadcmd", "Unknown command."),
  347. 23: ("ERRdata", "Data error (CRC)."),
  348. 24: ("ERRbadreq", "Bad request structure length."),
  349. 25: ("ERRseek", "Seek error."),
  350. 26: ("ERRbadmedia", "Unknown media type."),
  351. 27: ("ERRbadsector", "Sector not found."),
  352. 28: ("ERRnopaper", "Printer out of paper."),
  353. 29: ("ERRwrite", "Write fault."),
  354. 30: ("ERRread", "Read fault."),
  355. 31: ("ERRgeneral", "General failure."),
  356. 32: ("ERRbadshare", "An open conflicts with an existing open."),
  357. 33: ("ERRlock", "A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."),
  358. 34: ("ERRwrongdisk", "The wrong disk was found in a drive."),
  359. 35: ("ERRFCBUnavail", "No FCBs are available to process request."),
  360. 36: ("ERRsharebufexc", "A sharing buffer has been exceeded.")
  361. }
  362. dos_msgs = {
  363. ERRbadfunc: ("ERRbadfunc", "Invalid function."),
  364. ERRbadfile: ("ERRbadfile", "File not found."),
  365. ERRbadpath: ("ERRbadpath", "Directory invalid."),
  366. ERRnofids: ("ERRnofids", "No file descriptors available"),
  367. ERRnoaccess: ("ERRnoaccess", "Access denied."),
  368. ERRbadfid: ("ERRbadfid", "Invalid file handle."),
  369. ERRbadmcb: ("ERRbadmcb", "Memory control blocks destroyed."),
  370. ERRnomem: ("ERRnomem", "Insufficient server memory to perform the requested function."),
  371. ERRbadmem: ("ERRbadmem", "Invalid memory block address."),
  372. ERRbadenv: ("ERRbadenv", "Invalid environment."),
  373. 11: ("ERRbadformat", "Invalid format."),
  374. ERRbadaccess: ("ERRbadaccess", "Invalid open mode."),
  375. ERRbaddata: ("ERRbaddata", "Invalid data."),
  376. ERRres: ("ERRres", "reserved."),
  377. ERRbaddrive: ("ERRbaddrive", "Invalid drive specified."),
  378. ERRremcd: ("ERRremcd", "A Delete Directory request attempted to remove the server's current directory."),
  379. ERRdiffdevice: ("ERRdiffdevice", "Not same device."),
  380. ERRnofiles: ("ERRnofiles", "A File Search command can find no more files matching the specified criteria."),
  381. ERRbadshare: ("ERRbadshare", "The sharing mode specified for an Open conflicts with existing FIDs on the file."),
  382. ERRlock: ("ERRlock", "A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."),
  383. ERRunsup: ("ERRunsup", "The operation is unsupported"),
  384. ERRnosuchshare: ("ERRnosuchshare", "You specified an invalid share name"),
  385. ERRfilexists: ("ERRfilexists", "The file named in a Create Directory, Make New File or Link request already exists."),
  386. ERRinvalidname: ("ERRinvalidname", "Invalid name"),
  387. ERRbadpipe: ("ERRbadpipe", "Pipe invalid."),
  388. ERRpipebusy: ("ERRpipebusy", "All instances of the requested pipe are busy."),
  389. ERRpipeclosing: ("ERRpipeclosing", "Pipe close in progress."),
  390. ERRnotconnected: ("ERRnotconnected", "No process on other end of pipe."),
  391. ERRmoredata: ("ERRmoredata", "There is more data to be returned."),
  392. ERRinvgroup: ("ERRinvgroup", "Invalid workgroup (try the -W option)"),
  393. ERRlogonfailure: ("ERRlogonfailure", "Logon failure"),
  394. ERRdiskfull: ("ERRdiskfull", "Disk full"),
  395. ERRgeneral: ("ERRgeneral", "General failure"),
  396. ERRunknownlevel: ("ERRunknownlevel", "Unknown info level")
  397. }
  398. server_msgs = {
  399. 1: ("ERRerror", "Non-specific error code."),
  400. 2: ("ERRbadpw", "Bad password - name/password pair in a Tree Connect or Session Setup are invalid."),
  401. 3: ("ERRbadtype", "reserved."),
  402. 4: ("ERRaccess", "The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID."),
  403. 5: ("ERRinvnid", "The tree ID (TID) specified in a command was invalid."),
  404. 6: ("ERRinvnetname", "Invalid network name in tree connect."),
  405. 7: ("ERRinvdevice", "Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."),
  406. 49: ("ERRqfull", "Print queue full (files) -- returned by open print file."),
  407. 50: ("ERRqtoobig", "Print queue full -- no space."),
  408. 51: ("ERRqeof", "EOF on print queue dump."),
  409. 52: ("ERRinvpfid", "Invalid print file FID."),
  410. 64: ("ERRsmbcmd", "The server did not recognize the command received."),
  411. 65: ("ERRsrverror","The server encountered an internal error, e.g., system file unavailable."),
  412. 67: ("ERRfilespecs", "The file handle (FID) and pathname parameters contained an invalid combination of values."),
  413. 68: ("ERRreserved", "reserved."),
  414. 69: ("ERRbadpermits", "The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."),
  415. 70: ("ERRreserved", "reserved."),
  416. 71: ("ERRsetattrmode", "The attribute mode in the Set File Attribute request is invalid."),
  417. 81: ("ERRpaused", "Server is paused."),
  418. 82: ("ERRmsgoff", "Not receiving messages."),
  419. 83: ("ERRnoroom", "No room to buffer message."),
  420. 87: ("ERRrmuns", "Too many remote user names."),
  421. 88: ("ERRtimeout", "Operation timed out."),
  422. 89: ("ERRnoresource", "No resources currently available for request."),
  423. 90: ("ERRtoomanyuids", "Too many UIDs active on this session."),
  424. 91: ("ERRbaduid", "The UID is not known as a valid ID on this session."),
  425. 250: ("ERRusempx","Temp unable to support Raw, use MPX mode."),
  426. 251: ("ERRusestd","Temp unable to support Raw, use standard read/write."),
  427. 252: ("ERRcontmpx", "Continue in MPX mode."),
  428. 253: ("ERRreserved", "reserved."),
  429. 254: ("ERRreserved", "reserved."),
  430. 0xFFFF: ("ERRnosupport", "Function not supported.")
  431. }
  432. # Error clases
  433. ERRDOS = 0x1
  434. error_classes = { 0: ("SUCCESS", {}),
  435. ERRDOS: ("ERRDOS", dos_msgs),
  436. 0x02: ("ERRSRV",server_msgs),
  437. 0x03: ("ERRHRD",hard_msgs),
  438. 0x04: ("ERRXOS", {} ),
  439. 0xE1: ("ERRRMX1", {} ),
  440. 0xE2: ("ERRRMX2", {} ),
  441. 0xE3: ("ERRRMX3", {} ),
  442. 0xFF: ("ERRCMD", {} ) }
  443. def __init__( self, error_string, error_class, error_code, nt_status = 0):
  444. Exception.__init__(self, error_string)
  445. self.nt_status = nt_status
  446. self._args = error_string
  447. if nt_status:
  448. self.error_class = 0
  449. self.error_code = (error_code << 16) + error_class
  450. else:
  451. self.error_class = error_class
  452. self.error_code = error_code
  453. def get_error_class( self ):
  454. return self.error_class
  455. def get_error_code( self ):
  456. return self.error_code
  457. def __str__( self ):
  458. error_class = SessionError.error_classes.get( self.error_class, None )
  459. if not error_class:
  460. error_code_str = self.error_code
  461. error_class_str = self.error_class
  462. else:
  463. error_class_str = error_class[0]
  464. error_code = error_class[1].get( self.error_code, None )
  465. if not error_code:
  466. error_code_str = self.error_code
  467. else:
  468. error_code_str = '%s(%s)' % error_code
  469. if self.nt_status:
  470. return 'SMB SessionError: %s(%s)' % nt_errors.ERROR_MESSAGES[self.error_code]
  471. else:
  472. # Fall back to the old format
  473. return 'SMB SessionError: class: %s, code: %s' % (error_class_str, error_code_str)
  474. # Raised when an supported feature is present/required in the protocol but is not
  475. # currently supported by pysmb
  476. class UnsupportedFeature(Exception): pass
  477. # Contains information about a SMB shared device/service
  478. class SharedDevice:
  479. def __init__(self, name, share_type, comment):
  480. self.__name = name
  481. self.__type = share_type
  482. self.__comment = comment
  483. def get_name(self):
  484. return self.__name
  485. def get_type(self):
  486. return self.__type
  487. def get_comment(self):
  488. return self.__comment
  489. def __repr__(self):
  490. return '<SharedDevice instance: name=' + self.__name + ', type=' + str(self.__type) + ', comment="' + self.__comment + '">'
  491. # Contains information about the shared file/directory
  492. class SharedFile:
  493. def __init__(self, ctime, atime, mtime, filesize, allocsize, attribs, shortname, longname):
  494. self.__ctime = ctime
  495. self.__atime = atime
  496. self.__mtime = mtime
  497. self.__filesize = filesize
  498. self.__allocsize = allocsize
  499. self.__attribs = attribs
  500. try:
  501. self.__shortname = shortname[:string.index(shortname, '\0')]
  502. except ValueError:
  503. self.__shortname = shortname
  504. try:
  505. self.__longname = longname[:string.index(longname, '\0')]
  506. except ValueError:
  507. self.__longname = longname
  508. def get_ctime(self):
  509. return self.__ctime
  510. def get_ctime_epoch(self):
  511. return self.__convert_smbtime(self.__ctime)
  512. def get_mtime(self):
  513. return self.__mtime
  514. def get_mtime_epoch(self):
  515. return self.__convert_smbtime(self.__mtime)
  516. def get_atime(self):
  517. return self.__atime
  518. def get_atime_epoch(self):
  519. return self.__convert_smbtime(self.__atime)
  520. def get_filesize(self):
  521. return self.__filesize
  522. def get_allocsize(self):
  523. return self.__allocsize
  524. def get_attributes(self):
  525. return self.__attribs
  526. def is_archive(self):
  527. return self.__attribs & ATTR_ARCHIVE
  528. def is_compressed(self):
  529. return self.__attribs & ATTR_COMPRESSED
  530. def is_normal(self):
  531. return self.__attribs & ATTR_NORMAL
  532. def is_hidden(self):
  533. return self.__attribs & ATTR_HIDDEN
  534. def is_readonly(self):
  535. return self.__attribs & ATTR_READONLY
  536. def is_temporary(self):
  537. return self.__attribs & ATTR_TEMPORARY
  538. def is_directory(self):
  539. return self.__attribs & ATTR_DIRECTORY
  540. def is_system(self):
  541. return self.__attribs & ATTR_SYSTEM
  542. def get_shortname(self):
  543. return self.__shortname
  544. def get_longname(self):
  545. return self.__longname
  546. def __repr__(self):
  547. return '<SharedFile instance: shortname="' + self.__shortname + '", longname="' + self.__longname + '", filesize=' + str(self.__filesize) + '>'
  548. @staticmethod
  549. def __convert_smbtime(t):
  550. x = t >> 32
  551. y = t & 0xffffffffL
  552. geo_cal_offset = 11644473600.0 # = 369.0 * 365.25 * 24 * 60 * 60 - (3.0 * 24 * 60 * 60 + 6.0 * 60 * 60)
  553. return (x * 4.0 * (1 << 30) + (y & 0xfff00000L)) * 1.0e-7 - geo_cal_offset
  554. # Contain information about a SMB machine
  555. class SMBMachine:
  556. def __init__(self, nbname, nbt_type, comment):
  557. self.__nbname = nbname
  558. self.__type = nbt_type
  559. self.__comment = comment
  560. def __repr__(self):
  561. return '<SMBMachine instance: nbname="' + self.__nbname + '", type=' + hex(self.__type) + ', comment="' + self.__comment + '">'
  562. class SMBDomain:
  563. def __init__(self, nbgroup, domain_type, master_browser):
  564. self.__nbgroup = nbgroup
  565. self.__type = domain_type
  566. self.__master_browser = master_browser
  567. def __repr__(self):
  568. return '<SMBDomain instance: nbgroup="' + self.__nbgroup + '", type=' + hex(self.__type) + ', master browser="' + self.__master_browser + '">'
  569. # Represents a SMB Packet
  570. class NewSMBPacket(Structure):
  571. structure = (
  572. ('Signature', '"\xffSMB'),
  573. ('Command','B=0'),
  574. ('ErrorClass','B=0'),
  575. ('_reserved','B=0'),
  576. ('ErrorCode','<H=0'),
  577. ('Flags1','B=0'),
  578. ('Flags2','<H=0'),
  579. ('PIDHigh','<H=0'),
  580. ('SecurityFeatures','8s=""'),
  581. ('Reserved','<H=0'),
  582. ('Tid','<H=0xffff'),
  583. ('Pid','<H=0'),
  584. ('Uid','<H=0'),
  585. ('Mid','<H=0'),
  586. ('Data','*:'),
  587. )
  588. def __init__(self, **kargs):
  589. Structure.__init__(self, **kargs)
  590. if self.fields.has_key('Flags2') is False:
  591. self['Flags2'] = 0
  592. if self.fields.has_key('Flags1') is False:
  593. self['Flags1'] = 0
  594. if not kargs.has_key('data'):
  595. self['Data'] = []
  596. def addCommand(self, command):
  597. if len(self['Data']) == 0:
  598. self['Command'] = command.command
  599. else:
  600. self['Data'][-1]['Parameters']['AndXCommand'] = command.command
  601. self['Data'][-1]['Parameters']['AndXOffset'] = len(self)
  602. self['Data'].append(command)
  603. def isMoreData(self):
  604. return (self['Command'] in [SMB.SMB_COM_TRANSACTION, SMB.SMB_COM_READ_ANDX, SMB.SMB_COM_READ_RAW] and
  605. self['ErrorClass'] == 1 and self['ErrorCode'] == SessionError.ERRmoredata)
  606. def isMoreProcessingRequired(self):
  607. return self['ErrorClass'] == 0x16 and self['ErrorCode'] == 0xc000
  608. def isValidAnswer(self, cmd):
  609. # this was inside a loop reading more from the net (with recv_packet(None))
  610. if self['Command'] == cmd:
  611. if (self['ErrorClass'] == 0x00 and
  612. self['ErrorCode'] == 0x00):
  613. return 1
  614. elif self.isMoreData():
  615. return 1
  616. elif self.isMoreProcessingRequired():
  617. return 1
  618. raise SessionError, ("SMB Library Error", self['ErrorClass'] + (self['_reserved'] << 8), self['ErrorCode'], self['Flags2'] & SMB.FLAGS2_NT_STATUS)
  619. else:
  620. raise UnsupportedFeature, ("Unexpected answer from server: Got %d, Expected %d" % (self['Command'], cmd))
  621. class SMBCommand(Structure):
  622. structure = (
  623. ('WordCount', 'B=len(Parameters)/2'),
  624. ('_ParametersLength','_-Parameters','WordCount*2'),
  625. ('Parameters',':'), # default set by constructor
  626. ('ByteCount','<H-Data'),
  627. ('Data',':'), # default set by constructor
  628. )
  629. def __init__(self, commandOrData = None, data = None, **kargs):
  630. if type(commandOrData) == type(0):
  631. self.command = commandOrData
  632. else:
  633. data = data or commandOrData
  634. Structure.__init__(self, data = data, **kargs)
  635. if data is None:
  636. self['Parameters'] = ''
  637. self['Data'] = ''
  638. class AsciiOrUnicodeStructure(Structure):
  639. UnicodeStructure = ()
  640. AsciiStructure = ()
  641. def __init__(self, flags = 0, **kargs):
  642. if flags & SMB.FLAGS2_UNICODE:
  643. self.structure = self.UnicodeStructure
  644. else:
  645. self.structure = self.AsciiStructure
  646. Structure.__init__(self, **kargs)
  647. class SMBCommand_Parameters(Structure):
  648. pass
  649. class SMBAndXCommand_Parameters(Structure):
  650. commonHdr = (
  651. ('AndXCommand','B=0xff'),
  652. ('_reserved','B=0'),
  653. ('AndXOffset','<H=0'),
  654. )
  655. structure = ( # default structure, overriden by subclasses
  656. ('Data',':=""'),
  657. )
  658. ############# TRANSACTIONS RELATED
  659. # TRANS2_QUERY_FS_INFORMATION
  660. # QUERY_FS Information Levels
  661. # SMB_QUERY_FS_ATTRIBUTE_INFO
  662. class SMBQueryFsAttributeInfo(Structure):
  663. structure = (
  664. ('FileSystemAttributes','<L'),
  665. ('MaxFilenNameLengthInBytes','<L'),
  666. ('LengthOfFileSystemName','<L-FileSystemName'),
  667. ('FileSystemName',':'),
  668. )
  669. class SMBQueryFsInfoVolume(AsciiOrUnicodeStructure):
  670. commonHdr = (
  671. ('ulVolSerialNbr','<L=0xABCDEFAA'),
  672. ('cCharCount','<B-VolumeLabel'),
  673. )
  674. AsciiStructure = (
  675. ('VolumeLabel','z'),
  676. )
  677. UnicodeStructure = (
  678. ('VolumeLabel','u'),
  679. )
  680. # FILE_FS_SIZE_INFORMATION
  681. class FileFsSizeInformation(Structure):
  682. structure = (
  683. ('TotalAllocationUnits','<q=148529400'),
  684. ('AvailableAllocationUnits','<q=14851044'),
  685. ('SectorsPerAllocationUnit','<L=2'),
  686. ('BytesPerSector','<L=512'),
  687. )
  688. # SMB_QUERY_FS_SIZE_INFO
  689. class SMBQueryFsSizeInfo(Structure):
  690. structure = (
  691. ('TotalAllocationUnits','<q=148529400'),
  692. ('TotalFreeAllocationUnits','<q=14851044'),
  693. ('SectorsPerAllocationUnit','<L=2'),
  694. ('BytesPerSector','<L=512'),
  695. )
  696. # FILE_FS_FULL_SIZE_INFORMATION
  697. class SMBFileFsFullSizeInformation(Structure):
  698. structure = (
  699. ('TotalAllocationUnits','<q=148529400'),
  700. ('CallerAvailableAllocationUnits','<q=148529400'),
  701. ('ActualAvailableAllocationUnits','<q=148529400'),
  702. ('SectorsPerAllocationUnit','<L=15'),
  703. ('BytesPerSector','<L=512')
  704. )
  705. # SMB_QUERY_FS_VOLUME_INFO
  706. class SMBQueryFsVolumeInfo(Structure):
  707. structure = (
  708. ('VolumeCreationTime','<q'),
  709. ('SerialNumber','<L=0xABCDEFAA'),
  710. ('VolumeLabelSize','<L=len(VolumeLabel)'),
  711. ('Reserved','<H=0x10'),
  712. ('VolumeLabel',':')
  713. )
  714. # SMB_FIND_FILE_BOTH_DIRECTORY_INFO level
  715. class SMBFindFileBothDirectoryInfo(AsciiOrUnicodeStructure):
  716. commonHdr = (
  717. ('NextEntryOffset','<L=0'),
  718. ('FileIndex','<L=0'),
  719. ('CreationTime','<q'),
  720. ('LastAccessTime','<q'),
  721. ('LastWriteTime','<q'),
  722. ('LastChangeTime','<q'),
  723. ('EndOfFile','<q=0'),
  724. ('AllocationSize','<q=0'),
  725. ('ExtFileAttributes','<L=0'),
  726. )
  727. AsciiStructure = (
  728. ('FileNameLength','<L-FileName','len(FileName)'),
  729. ('EaSize','<L=0'),
  730. ('ShortNameLength','<B=0'),
  731. ('Reserved','<B=0'),
  732. ('ShortName','24s'),
  733. ('FileName',':'),
  734. )
  735. UnicodeStructure = (
  736. ('FileNameLength','<L-FileName','len(FileName)*2'),
  737. ('EaSize','<L=0'),
  738. ('ShortNameLength','<B=0'),
  739. ('Reserved','<B=0'),
  740. ('ShortName','24s'),
  741. ('FileName',':'),
  742. )
  743. # SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO level
  744. class SMBFindFileIdFullDirectoryInfo(AsciiOrUnicodeStructure):
  745. commonHdr = (
  746. ('NextEntryOffset','<L=0'),
  747. ('FileIndex','<L=0'),
  748. ('CreationTime','<q'),
  749. ('LastAccessTime','<q'),
  750. ('LastWriteTime','<q'),
  751. ('LastChangeTime','<q'),
  752. ('EndOfFile','<q=0'),
  753. ('AllocationSize','<q=0'),
  754. ('ExtFileAttributes','<L=0'),
  755. )
  756. AsciiStructure = (
  757. ('FileNameLength','<L-FileName','len(FileName)'),
  758. ('EaSize','<L=0'),
  759. ('FileID','<q=0'),
  760. ('FileName',':'),
  761. )
  762. UnicodeStructure = (
  763. ('FileNameLength','<L-FileName','len(FileName)*2'),
  764. ('EaSize','<L=0'),
  765. ('FileID','<q=0'),
  766. ('FileName',':'),
  767. )
  768. # SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO level
  769. class SMBFindFileIdBothDirectoryInfo(AsciiOrUnicodeStructure):
  770. commonHdr = (
  771. ('NextEntryOffset','<L=0'),
  772. ('FileIndex','<L=0'),
  773. ('CreationTime','<q'),
  774. ('LastAccessTime','<q'),
  775. ('LastWriteTime','<q'),
  776. ('LastChangeTime','<q'),
  777. ('EndOfFile','<q=0'),
  778. ('AllocationSize','<q=0'),
  779. ('ExtFileAttributes','<L=0'),
  780. )
  781. AsciiStructure = (
  782. ('FileNameLength','<L-FileName','len(FileName)'),
  783. ('EaSize','<L=0'),
  784. ('ShortNameLength','<B=0'),
  785. ('Reserved','<B=0'),
  786. ('ShortName','24s'),
  787. ('Reserved','<H=0'),
  788. ('FileID','<q=0'),
  789. ('FileName','z'),
  790. )
  791. UnicodeStructure = (
  792. ('FileNameLength','<L-FileName','len(FileName)*2'),
  793. ('EaSize','<L=0'),
  794. ('ShortNameLength','<B=0'),
  795. ('Reserved','<B=0'),
  796. ('ShortName','24s'),
  797. ('Reserved','<H=0'),
  798. ('FileID','<q=0'),
  799. ('FileName',':'),
  800. )
  801. # SMB_FIND_FILE_DIRECTORY_INFO level
  802. class SMBFindFileDirectoryInfo(AsciiOrUnicodeStructure):
  803. commonHdr = (
  804. ('NextEntryOffset','<L=0'),
  805. ('FileIndex','<L=0'),
  806. ('CreationTime','<q'),
  807. ('LastAccessTime','<q'),
  808. ('LastWriteTime','<q'),
  809. ('LastChangeTime','<q'),
  810. ('EndOfFile','<q=0'),
  811. ('AllocationSize','<q=1'),
  812. ('ExtFileAttributes','<L=0'),
  813. )
  814. AsciiStructure = (
  815. ('FileNameLength','<L-FileName','len(FileName)'),
  816. ('FileName','z'),
  817. )
  818. UnicodeStructure = (
  819. ('FileNameLength','<L-FileName','len(FileName)*2'),
  820. ('FileName',':'),
  821. )
  822. # SMB_FIND_FILE_NAMES_INFO level
  823. class SMBFindFileNamesInfo(AsciiOrUnicodeStructure):
  824. commonHdr = (
  825. ('NextEntryOffset','<L=0'),
  826. ('FileIndex','<L=0'),
  827. )
  828. AsciiStructure = (
  829. ('FileNameLength','<L-FileName','len(FileName)'),
  830. ('FileName','z'),
  831. )
  832. UnicodeStructure = (
  833. ('FileNameLength','<L-FileName','len(FileName)*2'),
  834. ('FileName',':'),
  835. )
  836. # SMB_FIND_FILE_FULL_DIRECTORY_INFO level
  837. class SMBFindFileFullDirectoryInfo(AsciiOrUnicodeStructure):
  838. commonHdr = (
  839. ('NextEntryOffset','<L=0'),
  840. ('FileIndex','<L=0'),
  841. ('CreationTime','<q'),
  842. ('LastAccessTime','<q'),
  843. ('LastWriteTime','<q'),
  844. ('LastChangeTime','<q'),
  845. ('EndOfFile','<q=0'),
  846. ('AllocationSize','<q=1'),
  847. ('ExtFileAttributes','<L=0'),
  848. )
  849. AsciiStructure = (
  850. ('FileNameLength','<L-FileName','len(FileName)'),
  851. ('EaSize','<L'),
  852. ('FileName','z'),
  853. )
  854. UnicodeStructure = (
  855. ('FileNameLength','<L-FileName','len(FileName)*2'),
  856. ('EaSize','<L'),
  857. ('FileName',':'),
  858. )
  859. # SMB_FIND_INFO_STANDARD level
  860. class SMBFindInfoStandard(AsciiOrUnicodeStructure):
  861. commonHdr = (
  862. ('ResumeKey','<L=0xff'),
  863. ('CreationDate','<H=0'),
  864. ('CreationTime','<H=0'),
  865. ('LastAccessDate','<H=0'),
  866. ('LastAccessTime','<H=0'),
  867. ('LastWriteDate','<H=0'),
  868. ('LastWriteTime','<H=0'),
  869. ('EaSize','<L'),
  870. ('AllocationSize','<L=1'),
  871. ('ExtFileAttributes','<H=0'),
  872. )
  873. AsciiStructure = (
  874. ('FileNameLength','<B-FileName','len(FileName)'),
  875. ('FileName','z'),
  876. )
  877. UnicodeStructure = (
  878. ('FileNameLength','<B-FileName','len(FileName)*2'),
  879. ('FileName',':'),
  880. )
  881. # SET_FILE_INFORMATION structures
  882. # SMB_SET_FILE_DISPOSITION_INFO
  883. class SMBSetFileDispositionInfo(Structure):
  884. structure = (
  885. ('DeletePending','<B'),
  886. )
  887. # SMB_SET_FILE_BASIC_INFO
  888. class SMBSetFileBasicInfo(Structure):
  889. structure = (
  890. ('CreationTime','<q'),
  891. ('LastAccessTime','<q'),
  892. ('LastWriteTime','<q'),
  893. ('ChangeTime','<q'),
  894. ('ExtFileAttributes','<H'),
  895. ('Reserved','<L'),
  896. )
  897. # FILE_STREAM_INFORMATION
  898. class SMBFileStreamInformation(Structure):
  899. commonHdr = (
  900. ('NextEntryOffset','<L=0'),
  901. ('StreamNameLength','<L=0'),
  902. ('StreamSize','<q=0'),
  903. ('StreamAllocationSize','<q=0'),
  904. ('StreamName',':=""'),
  905. )
  906. # FILE_NETWORK_OPEN_INFORMATION
  907. class SMBFileNetworkOpenInfo(Structure):
  908. structure = (
  909. ('CreationTime','<q=0'),
  910. ('LastAccessTime','<q=0'),
  911. ('LastWriteTime','<q=0'),
  912. ('ChangeTime','<q=0'),
  913. ('AllocationSize','<q=0'),
  914. ('EndOfFile','<q=0'),
  915. ('FileAttributes','<L=0'),
  916. ('Reserved','<L=0'),
  917. )
  918. # SMB_SET_FILE_END_OF_FILE_INFO
  919. class SMBSetFileEndOfFileInfo(Structure):
  920. structure = (
  921. ('EndOfFile','<q'),
  922. )
  923. # TRANS2_FIND_NEXT2
  924. class SMBFindNext2_Parameters(AsciiOrUnicodeStructure):
  925. commonHdr = (
  926. ('SID','<H'),
  927. ('SearchCount','<H'),
  928. ('InformationLevel','<H'),
  929. ('ResumeKey','<L'),
  930. ('Flags','<H'),
  931. )
  932. AsciiStructure = (
  933. ('FileName','z'),
  934. )
  935. UnicodeStructure = (
  936. ('FileName','u'),
  937. )
  938. class SMBFindNext2Response_Parameters(Structure):
  939. structure = (
  940. ('SearchCount','<H'),
  941. ('EndOfSearch','<H=1'),
  942. ('EaErrorOffset','<H=0'),
  943. ('LastNameOffset','<H=0'),
  944. )
  945. class SMBFindNext2_Data(Structure):
  946. structure = (
  947. ('GetExtendedAttributesListLength','_-GetExtendedAttributesList', 'self["GetExtendedAttributesListLength"]'),
  948. ('GetExtendedAttributesList',':'),
  949. )
  950. # TRANS2_FIND_FIRST2
  951. class SMBFindFirst2Response_Parameters(Structure):
  952. structure = (
  953. ('SID','<H'),
  954. ('SearchCount','<H'),
  955. ('EndOfSearch','<H=1'),
  956. ('EaErrorOffset','<H=0'),
  957. ('LastNameOffset','<H=0'),
  958. )
  959. class SMBFindFirst2_Parameters(AsciiOrUnicodeStructure):
  960. commonHdr = (
  961. ('SearchAttributes','<H'),
  962. ('SearchCount','<H'),
  963. ('Flags','<H'),
  964. ('InformationLevel','<H'),
  965. ('SearchStorageType','<L'),
  966. )
  967. AsciiStructure = (
  968. ('FileName','z'),
  969. )
  970. UnicodeStructure = (
  971. ('FileName','u'),
  972. )
  973. class SMBFindFirst2_Data(Structure):
  974. structure = (
  975. ('GetExtendedAttributesListLength','_-GetExtendedAttributesList', 'self["GetExtendedAttributesListLength"]'),
  976. ('GetExtendedAttributesList',':'),
  977. )
  978. # TRANS2_SET_PATH_INFORMATION
  979. class SMBSetPathInformation_Parameters(AsciiOrUnicodeStructure):
  980. commonHdr = (
  981. ('InformationLevel','<H'),
  982. ('Reserved','<L'),
  983. )
  984. AsciiStructure = (
  985. ('FileName','z'),
  986. )
  987. UnicodeStructure = (
  988. ('FileName','u'),
  989. )
  990. class SMBSetPathInformationResponse_Parameters(Structure):
  991. structure = (
  992. ('EaErrorOffset','<H=0'),
  993. )
  994. # TRANS2_SET_FILE_INFORMATION
  995. class SMBSetFileInformation_Parameters(Structure):
  996. structure = (
  997. ('FID','<H'),
  998. ('InformationLevel','<H'),
  999. ('Reserved','<H'),
  1000. )
  1001. class SMBSetFileInformationResponse_Parameters(Structure):
  1002. structure = (
  1003. ('EaErrorOffset','<H=0'),
  1004. )
  1005. # TRANS2_QUERY_FILE_INFORMATION
  1006. class SMBQueryFileInformation_Parameters(Structure):
  1007. structure = (
  1008. ('FID','<H'),
  1009. ('InformationLevel','<H'),
  1010. )
  1011. class SMBQueryFileInformationResponse_Parameters(Structure):
  1012. structure = (
  1013. ('EaErrorOffset','<H=0'),
  1014. )
  1015. class SMBQueryFileInformation_Data(Structure):
  1016. structure = (
  1017. ('GetExtendedAttributeList',':'),
  1018. )
  1019. # TRANS2_QUERY_PATH_INFORMATION
  1020. class SMBQueryPathInformationResponse_Parameters(Structure):
  1021. structure = (
  1022. ('EaErrorOffset','<H=0'),
  1023. )
  1024. class SMBQueryPathInformation_Parameters(AsciiOrUnicodeStructure):
  1025. commonHdr = (
  1026. ('InformationLevel','<H'),
  1027. ('Reserved','<L=0'),
  1028. )
  1029. AsciiStructure = (
  1030. ('FileName','z'),
  1031. )
  1032. UnicodeStructure = (
  1033. ('FileName','u'),
  1034. )
  1035. class SMBQueryPathInformation_Data(Structure):
  1036. structure = (
  1037. ('GetExtendedAttributeList',':'),
  1038. )
  1039. # SMB_QUERY_FILE_EA_INFO
  1040. class SMBQueryFileEaInfo(Structure):
  1041. structure = (
  1042. ('EaSize','<L=0'),
  1043. )
  1044. # SMB_QUERY_FILE_BASIC_INFO
  1045. class SMBQueryFileBasicInfo(Structure):
  1046. structure = (
  1047. ('CreationTime','<q'),
  1048. ('LastAccessTime','<q'),
  1049. ('LastWriteTime','<q'),
  1050. ('LastChangeTime','<q'),
  1051. ('ExtFileAttributes','<L'),
  1052. #('Reserved','<L=0'),
  1053. )
  1054. # SMB_QUERY_FILE_STANDARD_INFO
  1055. class SMBQueryFileStandardInfo(Structure):
  1056. structure = (
  1057. ('AllocationSize','<q'),
  1058. ('EndOfFile','<q'),
  1059. ('NumberOfLinks','<L=0'),
  1060. ('DeletePending','<B=0'),
  1061. ('Directory','<B'),
  1062. )
  1063. # SMB_QUERY_FILE_ALL_INFO
  1064. class SMBQueryFileAllInfo(Structure):
  1065. structure = (
  1066. ('CreationTime','<q'),
  1067. ('LastAccessTime','<q'),
  1068. ('LastWriteTime','<q'),
  1069. ('LastChangeTime','<q'),
  1070. ('ExtFileAttributes','<L'),
  1071. ('Reserved','<L=0'),
  1072. ('AllocationSize','<q'),
  1073. ('EndOfFile','<q'),
  1074. ('NumberOfLinks','<L=0'),
  1075. ('DeletePending','<B=0'),
  1076. ('Directory','<B'),
  1077. ('Reserved','<H=0'),
  1078. ('EaSize','<L=0'),
  1079. ('FileNameLength','<L-FileName','len(FileName)'),
  1080. ('FileName',':'),
  1081. )
  1082. # \PIPE\LANMAN NetShareEnum
  1083. class SMBNetShareEnum(Structure):
  1084. structure = (
  1085. ('RAPOpcode','<H=0'),
  1086. ('ParamDesc','z'),
  1087. ('DataDesc','z'),
  1088. ('InfoLevel','<H'),
  1089. ('ReceiveBufferSize','<H'),
  1090. )
  1091. class SMBNetShareEnumResponse(Structure):
  1092. structure = (
  1093. ('Status','<H=0'),
  1094. ('Convert','<H=0'),
  1095. ('EntriesReturned','<H'),
  1096. ('EntriesAvailable','<H'),
  1097. )
  1098. class NetShareInfo1(Structure):
  1099. structure = (
  1100. ('NetworkName','13s'),
  1101. ('Pad','<B=0'),
  1102. ('Type','<H=0'),
  1103. ('RemarkOffsetLow','<H=0'),
  1104. ('RemarkOffsetHigh','<H=0'),
  1105. )
  1106. # \PIPE\LANMAN NetServerGetInfo
  1107. class SMBNetServerGetInfoResponse(Structure):
  1108. structure = (
  1109. ('Status','<H=0'),
  1110. ('Convert','<H=0'),
  1111. ('TotalBytesAvailable','<H'),
  1112. )
  1113. class SMBNetServerInfo1(Structure):
  1114. # Level 1 Response
  1115. structure = (
  1116. ('ServerName','16s'),
  1117. ('MajorVersion','B=5'),
  1118. ('MinorVersion','B=0'),
  1119. ('ServerType','<L=3'),
  1120. ('ServerCommentLow','<H=0'),
  1121. ('ServerCommentHigh','<H=0'),
  1122. )
  1123. # \PIPE\LANMAN NetShareGetInfo
  1124. class SMBNetShareGetInfo(Structure):
  1125. structure = (
  1126. ('RAPOpcode','<H=0'),
  1127. ('ParamDesc','z'),
  1128. ('DataDesc','z'),
  1129. ('ShareName','z'),
  1130. ('InfoLevel','<H'),
  1131. ('ReceiveBufferSize','<H'),
  1132. )
  1133. class SMBNetShareGetInfoResponse(Structure):
  1134. structure = (
  1135. ('Status','<H=0'),
  1136. ('Convert','<H=0'),
  1137. ('TotalBytesAvailable','<H'),
  1138. )
  1139. ############# Security Features
  1140. class SecurityFeatures(Structure):
  1141. structure = (
  1142. ('Key','<L=0'),
  1143. ('CID','<H=0'),
  1144. ('SequenceNumber','<H=0'),
  1145. )
  1146. ############# SMB_COM_QUERY_INFORMATION2 (0x23)
  1147. class SMBQueryInformation2_Parameters(Structure):
  1148. structure = (
  1149. ('Fid','<H'),
  1150. )
  1151. class SMBQueryInformation2Response_Parameters(Structure):
  1152. structure = (
  1153. ('CreateDate','<H'),
  1154. ('CreationTime','<H'),
  1155. ('LastAccessDate','<H'),
  1156. ('LastAccessTime','<H'),
  1157. ('LastWriteDate','<H'),
  1158. ('LastWriteTime','<H'),
  1159. ('FileDataSize','<L'),
  1160. ('FileAllocationSize','<L'),
  1161. ('FileAttributes','<L'),
  1162. )
  1163. ############# SMB_COM_SESSION_SETUP_ANDX (0x73)
  1164. class SMBSessionSetupAndX_Parameters(SMBAndXCommand_Parameters):
  1165. structure = (
  1166. ('MaxBuffer','<H'),
  1167. ('MaxMpxCount','<H'),
  1168. ('VCNumber','<H'),
  1169. ('SessionKey','<L'),
  1170. ('AnsiPwdLength','<H'),
  1171. ('UnicodePwdLength','<H'),
  1172. ('_reserved','<L=0'),
  1173. ('Capabilities','<L'),
  1174. )
  1175. class SMBSessionSetupAndX_Extended_Parameters(SMBAndXCommand_Parameters):
  1176. structure = (
  1177. ('MaxBufferSize','<H'),
  1178. ('MaxMpxCount','<H'),
  1179. ('VcNumber','<H'),
  1180. ('SessionKey','<L'),
  1181. ('SecurityBlobLength','<H'),
  1182. ('Reserved','<L=0'),
  1183. ('Capabilities','<L'),
  1184. )
  1185. class SMBSessionSetupAndX_Data(AsciiOrUnicodeStructure):
  1186. AsciiStructure = (
  1187. ('AnsiPwdLength','_-AnsiPwd','self["AnsiPwdLength"]'),
  1188. ('UnicodePwdLength','_-UnicodePwd','self["UnicodePwdLength"]'),
  1189. ('AnsiPwd',':=""'),
  1190. ('UnicodePwd',':=""'),
  1191. ('Account','z=""'),
  1192. ('PrimaryDomain','z=""'),
  1193. ('NativeOS','z=""'),
  1194. ('NativeLanMan','z=""'),
  1195. )
  1196. UnicodeStructure = (
  1197. ('AnsiPwdLength','_-AnsiPwd','self["AnsiPwdLength"]'),
  1198. ('UnicodePwdLength','_-UnicodePwd','self["UnicodePwdLength"]'),
  1199. ('AnsiPwd',':=""'),
  1200. ('UnicodePwd',':=""'),
  1201. ('Account','u=""'),
  1202. ('PrimaryDomain','u=""'),
  1203. ('NativeOS','u=""'),
  1204. ('NativeLanMan','u=""'),
  1205. )
  1206. class SMBSessionSetupAndX_Extended_Data(AsciiOrUnicodeStructure):
  1207. AsciiStructure = (
  1208. ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'),
  1209. ('SecurityBlob',':'),
  1210. ('NativeOS','z=""'),
  1211. ('NativeLanMan','z=""'),
  1212. )
  1213. UnicodeStructure = (
  1214. ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'),
  1215. ('SecurityBlob',':'),
  1216. ('NativeOS','u=""'),
  1217. ('NativeLanMan','u=""'),
  1218. )
  1219. class SMBSessionSetupAndXResponse_Parameters(SMBAndXCommand_Parameters):
  1220. structure = (
  1221. ('Action','<H'),
  1222. )
  1223. class SMBSessionSetupAndX_Extended_Response_Parameters(SMBAndXCommand_Parameters):
  1224. structure = (
  1225. ('Action','<H=0'),
  1226. ('SecurityBlobLength','<H'),
  1227. )
  1228. class SMBSessionSetupAndXResponse_Data(AsciiOrUnicodeStructure):
  1229. AsciiStructure = (
  1230. ('NativeOS','z=""'),
  1231. ('NativeLanMan','z=""'),
  1232. ('PrimaryDomain','z=""'),
  1233. )
  1234. UnicodeStructure = (
  1235. ('NativeOS','u=""'),
  1236. ('NativeLanMan','u=""'),
  1237. ('PrimaryDomain','u=""'),
  1238. )
  1239. class SMBSessionSetupAndX_Extended_Response_Data(AsciiOrUnicodeStructure):
  1240. AsciiStructure = (
  1241. ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'),
  1242. ('SecurityBlob',':'),
  1243. ('NativeOS','z=""'),
  1244. ('NativeLanMan','z=""'),
  1245. )
  1246. UnicodeStructure = (
  1247. ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'),
  1248. ('SecurityBlob',':'),
  1249. ('NativeOS','u=""'),
  1250. ('NativeLanMan','u=""'),
  1251. )
  1252. ############# SMB_COM_TREE_CONNECT (0x70)
  1253. class SMBTreeConnect_Parameters(SMBCommand_Parameters):
  1254. structure = (
  1255. )
  1256. class SMBTreeConnect_Data(SMBCommand_Parameters):
  1257. structure = (
  1258. ('PathFormat','"\x04'),
  1259. ('Path','z'),
  1260. ('PasswordFormat','"\x04'),
  1261. ('Password','z'),
  1262. ('ServiceFormat','"\x04'),
  1263. ('Service','z'),
  1264. )
  1265. ############# SMB_COM_TREE_CONNECT_ANDX (0x75)
  1266. class SMBTreeConnectAndX_Parameters(SMBAndXCommand_Parameters):
  1267. structure = (
  1268. ('Flags','<H=0'),
  1269. ('PasswordLength','<H'),
  1270. )
  1271. class SMBTreeConnectAndXResponse_Parameters(SMBAndXCommand_Parameters):
  1272. structure = (
  1273. ('OptionalSupport','<H=0'),
  1274. )
  1275. class SMBTreeConnectAndXExtendedResponse_Parameters(SMBAndXCommand_Parameters):
  1276. structure = (
  1277. ('OptionalSupport','<H=1'),
  1278. ('MaximalShareAccessRights','<L=0x1fffff'),
  1279. ('GuestMaximalShareAccessRights','<L=0x1fffff'),
  1280. )
  1281. class SMBTreeConnectAndX_Data(AsciiOrUnicodeStructure):
  1282. AsciiStructure = (
  1283. ('_PasswordLength','_-Password','self["_PasswordLength"]'),
  1284. ('Password',':'),
  1285. ('Path','z'),
  1286. ('Service','z'),
  1287. )
  1288. UnicodeStructure = (
  1289. ('_PasswordLength','_-Password','self["_PasswordLength"] if self["_PasswordLength"] > 0 else 1'),
  1290. ('Password',':'),
  1291. ('Path','u'),
  1292. ('Service','z'),
  1293. )
  1294. class SMBTreeConnectAndXResponse_Data(AsciiOrUnicodeStructure):
  1295. AsciiStructure = (
  1296. ('Service','z'),
  1297. ('PadLen','_-Pad','self["PadLen"]'),
  1298. ('Pad',':=""'),
  1299. ('NativeFileSystem','z'),
  1300. )
  1301. UnicodeStructure = (
  1302. ('Service','z'),
  1303. ('PadLen','_-Pad','self["PadLen"]'),
  1304. ('Pad',':=""'),
  1305. ('NativeFileSystem','u'),
  1306. )
  1307. ############# SMB_COM_NT_CREATE_ANDX (0xA2)
  1308. class SMBNtCreateAndX_Parameters(SMBAndXCommand_Parameters):
  1309. structure = (
  1310. ('_reserved', 'B=0'),
  1311. ('FileNameLength','<H'), # NameLength
  1312. ('CreateFlags','<L'), # Flags
  1313. ('RootFid','<L=0'), # RootDirectoryFID
  1314. ('AccessMask','<L'), # DesiredAccess
  1315. ('AllocationSizeLo','<L=0'), # AllocationSize
  1316. ('AllocationSizeHi','<L=0'),
  1317. ('FileAttributes','<L=0'), # ExtFileAttributes
  1318. ('ShareAccess','<L=3'), #
  1319. ('Disposition','<L=1'), # CreateDisposition
  1320. ('CreateOptions','<L'), # CreateOptions
  1321. ('Impersonation','<L=2'),
  1322. ('SecurityFlags','B=3'),
  1323. )
  1324. class SMBNtCreateAndXResponse_Parameters(SMBAndXCommand_Parameters):
  1325. # XXX Is there a memory leak in the response for NTCreate (where the Data section would be) in Win 2000, Win XP, and Win 2003?
  1326. structure = (
  1327. ('OplockLevel', 'B=0'),
  1328. ('Fid','<H'),
  1329. ('CreateAction','<L'),
  1330. ('CreateTime','<q=0'),
  1331. ('LastAccessTime','<q=0'),
  1332. ('LastWriteTime','<q=0'),
  1333. ('LastChangeTime','<q=0'),
  1334. ('FileAttributes','<L=0x80'),
  1335. ('AllocationSize','<q=0'),
  1336. ('EndOfFile','<q=0'),
  1337. ('FileType','<H=0'),
  1338. ('IPCState','<H=0'),
  1339. ('IsDirectory','B'),
  1340. )
  1341. class SMBNtCreateAndXExtendedResponse_Parameters(SMBAndXCommand_Parameters):
  1342. # [MS-SMB] Extended response description
  1343. structure = (
  1344. ('OplockLevel', 'B=0'),
  1345. ('Fid','<H'),
  1346. ('CreateAction','<L'),
  1347. ('CreateTime','<q=0'),
  1348. ('LastAccessTime','<q=0'),
  1349. ('LastWriteTime','<q=0'),
  1350. ('LastChangeTime','<q=0'),
  1351. ('FileAttributes','<L=0x80'),
  1352. ('AllocationSize','<q=0'),
  1353. ('EndOfFile','<q=0'),
  1354. ('FileType','<H=0'),
  1355. ('IPCState','<H=0'),
  1356. ('IsDirectory','B'),
  1357. ('VolumeGUID','16s'),
  1358. ('FileIdLow','<L=0'),
  1359. ('FileIdHigh','<L=0'),
  1360. ('MaximalAccessRights','<L=0x12019b'),
  1361. ('GuestMaximalAccessRights','<L=0x120089'),
  1362. )
  1363. class SMBNtCreateAndX_Data(AsciiOrUnicodeStructure):
  1364. AsciiStructure = (
  1365. ('FileName','z'),
  1366. )
  1367. UnicodeStructure = (
  1368. ('Pad','B'),
  1369. ('FileName','u'),
  1370. )
  1371. ############# SMB_COM_OPEN_ANDX (0xD2)
  1372. class SMBOpenAndX_Parameters(SMBAndXCommand_Parameters):
  1373. structure = (
  1374. ('Flags','<H=0'),
  1375. ('DesiredAccess','<H=0'),
  1376. ('SearchAttributes','<H=0'),
  1377. ('FileAttributes','<H=0'),
  1378. ('CreationTime','<L=0'),
  1379. ('OpenMode','<H=1'), # SMB_O_OPEN = 1
  1380. ('AllocationSize','<L=0'),
  1381. ('Reserved','8s=""'),
  1382. )
  1383. class SMBOpenAndX_Data(SMBNtCreateAndX_Data):
  1384. pass
  1385. class SMBOpenAndXResponse_Parameters(SMBAndXCommand_Parameters):
  1386. structure = (
  1387. ('Fid','<H=0'),
  1388. ('FileAttributes','<H=0'),
  1389. ('LastWriten','<L=0'),
  1390. ('FileSize','<L=0'),
  1391. ('GrantedAccess','<H=0'),
  1392. ('FileType','<H=0'),
  1393. ('IPCState','<H=0'),
  1394. ('Action','<H=0'),
  1395. ('ServerFid','<L=0'),
  1396. ('_reserved','<H=0'),
  1397. )
  1398. ############# SMB_COM_WRITE (0x0B)
  1399. class SMBWrite_Parameters(SMBCommand_Parameters):
  1400. structure = (
  1401. ('Fid','<H'),
  1402. ('Count','<H'),
  1403. ('Offset','<L'),
  1404. ('Remaining','<H'),
  1405. )
  1406. class SMBWriteResponse_Parameters(SMBCommand_Parameters):
  1407. structure = (
  1408. ('Count','<H'),
  1409. )
  1410. class SMBWrite_Data(Structure):
  1411. structure = (
  1412. ('BufferFormat','<B=1'),
  1413. ('DataLength','<H-Data'),
  1414. ('Data',':'),
  1415. )
  1416. ############# SMB_COM_WRITE_ANDX (0x2F)
  1417. class SMBWriteAndX_Parameters(SMBAndXCommand_Parameters):
  1418. structure = (
  1419. ('Fid','<H=0'),
  1420. ('Offset','<L=0'),
  1421. ('_reserved','<L=0xff'),
  1422. ('WriteMode','<H=8'),
  1423. ('Remaining','<H=0'),
  1424. ('DataLength_Hi','<H=0'),
  1425. ('DataLength','<H=0'),
  1426. ('DataOffset','<H=0'),
  1427. ('HighOffset','<L=0'),
  1428. )
  1429. class SMBWriteAndX_Data_Short(Structure):
  1430. structure = (
  1431. ('_PadLen','_-Pad','self["DataOffset"] - 59'),
  1432. ('Pad',':'),
  1433. #('Pad','<B=0'),
  1434. ('DataLength','_-Data','self["DataLength"]'),
  1435. ('Data',':'),
  1436. )
  1437. class SMBWriteAndX_Data(Structure):
  1438. structure = (
  1439. ('_PadLen','_-Pad','self["DataOffset"] - 63'),
  1440. ('Pad',':'),
  1441. #('Pad','<B=0'),
  1442. ('DataLength','_-Data','self["DataLength"]'),
  1443. ('Data',':'),
  1444. )
  1445. class SMBWriteAndX_Parameters_Short(SMBAndXCommand_Parameters):
  1446. structure = (
  1447. ('Fid','<H'),
  1448. ('Offset','<L'),
  1449. ('_reserved','<L=0xff'),
  1450. ('WriteMode','<H=8'),
  1451. ('Remaining','<H'),
  1452. ('DataLength_Hi','<H=0'),
  1453. ('DataLength','<H'),
  1454. ('DataOffset','<H=0'),
  1455. )
  1456. class SMBWriteAndXResponse_Parameters(SMBAndXCommand_Parameters):
  1457. structure = (
  1458. ('Count','<H'),
  1459. ('Available','<H'),
  1460. ('Reserved','<L=0'),
  1461. )
  1462. ############# SMB_COM_WRITE_RAW (0x1D)
  1463. class SMBWriteRaw_Parameters(SMBCommand_Parameters):
  1464. structure = (
  1465. ('Fid','<H'),
  1466. ('Count','<H'),
  1467. ('_reserved','<H=0'),
  1468. ('Offset','<L'),
  1469. ('Timeout','<L=0'),
  1470. ('WriteMode','<H=0'),
  1471. ('_reserved2','<L=0'),
  1472. ('DataLength','<H'),
  1473. ('DataOffset','<H=0'),
  1474. )
  1475. ############# SMB_COM_READ (0x0A)
  1476. class SMBRead_Parameters(SMBCommand_Parameters):
  1477. structure = (
  1478. ('Fid','<H'),
  1479. ('Count','<H'),
  1480. ('Offset','<L'),
  1481. ('Remaining','<H=Count'),
  1482. )
  1483. class SMBReadResponse_Parameters(Structure):
  1484. structure = (
  1485. ('Count','<H=0'),
  1486. ('_reserved','8s=""'),
  1487. )
  1488. class SMBReadResponse_Data(Structure):
  1489. structure = (
  1490. ('BufferFormat','<B=0x1'),
  1491. ('DataLength','<H-Data'),
  1492. ('Data',':'),
  1493. )
  1494. ############# SMB_COM_READ_RAW (0x1A)
  1495. class SMBReadRaw_Parameters(SMBCommand_Parameters):
  1496. structure = (
  1497. ('Fid','<H'),
  1498. ('Offset','<L'),
  1499. ('MaxCount','<H'),
  1500. ('MinCount','<H=MaxCount'),
  1501. ('Timeout','<L=0'),
  1502. ('_reserved','<H=0'),
  1503. )
  1504. ############# SMB_COM_NT_TRANSACT (0xA0)
  1505. class SMBNTTransaction_Parameters(SMBCommand_Parameters):
  1506. structure = (
  1507. ('MaxSetupCount','<B=0'),
  1508. ('Reserved1','<H=0'),
  1509. ('TotalParameterCount','<L'),
  1510. ('TotalDataCount','<L'),
  1511. ('MaxParameterCount','<L=1024'),
  1512. ('MaxDataCount','<L=65504'),
  1513. ('ParameterCount','<L'),
  1514. ('ParameterOffset','<L'),
  1515. ('DataCount','<L'),
  1516. ('DataOffset','<L'),
  1517. ('SetupCount','<B=len(Setup)/2'),
  1518. ('Function','<H=0'),
  1519. ('SetupLength','_-Setup','SetupCount*2'),
  1520. ('Setup',':'),
  1521. )
  1522. class SMBNTTransactionResponse_Parameters(SMBCommand_Parameters):
  1523. structure = (
  1524. ('Reserved1','3s=""'),
  1525. ('TotalParameterCount','<L'),
  1526. ('TotalDataCount','<L'),
  1527. ('ParameterCount','<L'),
  1528. ('ParameterOffset','<L'),
  1529. ('ParameterDisplacement','<L=0'),
  1530. ('DataCount','<L'),
  1531. ('DataOffset','<L'),
  1532. ('DataDisplacement','<L=0'),
  1533. ('SetupCount','<B=0'),
  1534. ('SetupLength','_-Setup','SetupCount*2'),
  1535. ('Setup',':'),
  1536. )
  1537. class SMBNTTransaction_Data(Structure):
  1538. structure = (
  1539. ('Pad1Length','_-Pad1','self["Pad1Length"]'),
  1540. ('Pad1',':'),
  1541. ('NT_Trans_ParametersLength','_-NT_Trans_Parameters','self["NT_Trans_ParametersLength"]'),
  1542. ('NT_Trans_Parameters',':'),
  1543. ('Pad2Length','_-Pad2','self["Pad2Length"]'),
  1544. ('Pad2',':'),
  1545. ('NT_Trans_DataLength','_-NT_Trans_Data','self["NT_Trans_DataLength"]'),
  1546. ('NT_Trans_Data',':'),
  1547. )
  1548. class SMBNTTransactionResponse_Data(Structure):
  1549. structure = (
  1550. ('Pad1Length','_-Pad1','self["Pad1Length"]'),
  1551. ('Pad1',':'),
  1552. ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'),
  1553. ('Trans_Parameters',':'),
  1554. ('Pad2Length','_-Pad2','self["Pad2Length"]'),
  1555. ('Pad2',':'),
  1556. ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'),
  1557. ('Trans_Data',':'),
  1558. )
  1559. ############# SMB_COM_TRANSACTION2_SECONDARY (0x33)
  1560. class SMBTransaction2Secondary_Parameters(SMBCommand_Parameters):
  1561. structure = (
  1562. ('TotalParameterCount','<H'),
  1563. ('TotalDataCount','<H'),
  1564. ('ParameterCount','<H'),
  1565. ('ParameterOffset','<H'),
  1566. ('DataCount','<H'),
  1567. ('DataOffset','<H'),
  1568. ('DataDisplacement','<H=0'),
  1569. ('FID','<H'),
  1570. )
  1571. class SMBTransaction2Secondary_Data(Structure):
  1572. structure = (
  1573. ('Pad1Length','_-Pad1','self["Pad1Length"]'),
  1574. ('Pad1',':'),
  1575. ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'),
  1576. ('Trans_Parameters',':'),
  1577. ('Pad2Length','_-Pad2','self["Pad2Length"]'),
  1578. ('Pad2',':'),
  1579. ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'),
  1580. ('Trans_Data',':'),
  1581. )
  1582. ############# SMB_COM_TRANSACTION2 (0x32)
  1583. class SMBTransaction2_Parameters(SMBCommand_Parameters):
  1584. structure = (
  1585. ('TotalParameterCount','<H'),
  1586. ('TotalDataCount','<H'),
  1587. ('MaxParameterCount','<H=1024'),
  1588. ('MaxDataCount','<H=65504'),
  1589. ('MaxSetupCount','<B=0'),
  1590. ('Reserved1','<B=0'),
  1591. ('Flags','<H=0'),
  1592. ('Timeout','<L=0'),
  1593. ('Reserved2','<H=0'),
  1594. ('ParameterCount','<H'),
  1595. ('ParameterOffset','<H'),
  1596. ('DataCount','<H'),
  1597. ('DataOffset','<H'),
  1598. ('SetupCount','<B=len(Setup)/2'),
  1599. ('Reserved3','<B=0'),
  1600. ('SetupLength','_-Setup','SetupCount*2'),
  1601. ('Setup',':'),
  1602. )
  1603. class SMBTransaction2Response_Parameters(SMBCommand_Parameters):
  1604. structure = (
  1605. ('TotalParameterCount','<H'),
  1606. ('TotalDataCount','<H'),
  1607. ('Reserved1','<H=0'),
  1608. ('ParameterCount','<H'),
  1609. ('ParameterOffset','<H'),
  1610. ('ParameterDisplacement','<H=0'),
  1611. ('DataCount','<H'),
  1612. ('DataOffset','<H'),
  1613. ('DataDisplacement','<H=0'),
  1614. ('SetupCount','<B=0'),
  1615. ('Reserved2','<B=0'),
  1616. ('SetupLength','_-Setup','SetupCount*2'),
  1617. ('Setup',':'),
  1618. )
  1619. class SMBTransaction2_Data(Structure):
  1620. structure = (
  1621. # ('NameLength','_-Name','1'),
  1622. # ('Name',':'),
  1623. ('Pad1Length','_-Pad1','self["Pad1Length"]'),
  1624. ('Pad1',':'),
  1625. ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'),
  1626. ('Trans_Parameters',':'),
  1627. ('Pad2Length','_-Pad2','self["Pad2Length"]'),
  1628. ('Pad2',':'),
  1629. ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'),
  1630. ('Trans_Data',':'),
  1631. )
  1632. class SMBTransaction2Response_Data(Structure):
  1633. structure = (
  1634. ('Pad1Length','_-Pad1','self["Pad1Length"]'),
  1635. ('Pad1',':'),
  1636. ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'),
  1637. ('Trans_Parameters',':'),
  1638. ('Pad2Length','_-Pad2','self["Pad2Length"]'),
  1639. ('Pad2',':'),
  1640. ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'),
  1641. ('Trans_Data',':'),
  1642. )
  1643. ############# SMB_COM_QUERY_INFORMATION (0x08)
  1644. class SMBQueryInformation_Data(AsciiOrUnicodeStructure):
  1645. AsciiStructure = (
  1646. ('BufferFormat','B=4'),
  1647. ('FileName','z'),
  1648. )
  1649. UnicodeStructure = (
  1650. ('BufferFormat','B=4'),
  1651. ('FileName','u'),
  1652. )
  1653. class SMBQueryInformationResponse_Parameters(Structure):
  1654. structure = (
  1655. ('FileAttributes','<H'),
  1656. ('LastWriteTime','<L'),
  1657. ('FileSize','<L'),
  1658. ('Reserved','"0123456789'),
  1659. )
  1660. ############# SMB_COM_TRANSACTION (0x25)
  1661. class SMBTransaction_Parameters(SMBCommand_Parameters):
  1662. structure = (
  1663. ('TotalParameterCount','<H'),
  1664. ('TotalDataCount','<H'),
  1665. ('MaxParameterCount','<H=1024'),
  1666. ('MaxDataCount','<H=65504'),
  1667. ('MaxSetupCount','<B=0'),
  1668. ('Reserved1','<B=0'),
  1669. ('Flags','<H=0'),
  1670. ('Timeout','<L=0'),
  1671. ('Reserved2','<H=0'),
  1672. ('ParameterCount','<H'),
  1673. ('ParameterOffset','<H'),
  1674. ('DataCount','<H'),
  1675. ('DataOffset','<H'),
  1676. ('SetupCount','<B=len(Setup)/2'),
  1677. ('Reserved3','<B=0'),
  1678. ('SetupLength','_-Setup','SetupCount*2'),
  1679. ('Setup',':'),
  1680. )
  1681. class SMBTransactionResponse_Parameters(SMBCommand_Parameters):
  1682. structure = (
  1683. ('TotalParameterCount','<H'),
  1684. ('TotalDataCount','<H'),
  1685. ('Reserved1','<H=0'),
  1686. ('ParameterCount','<H'),
  1687. ('ParameterOffset','<H'),
  1688. ('ParameterDisplacement','<H=0'),
  1689. ('DataCount','<H'),
  1690. ('DataOffset','<H'),
  1691. ('DataDisplacement','<H=0'),
  1692. ('SetupCount','<B'),
  1693. ('Reserved2','<B=0'),
  1694. ('SetupLength','_-Setup','SetupCount*2'),
  1695. ('Setup',':'),
  1696. )
  1697. # TODO: We should merge these both. But this will require fixing
  1698. # the instances where this structure is used on the client side
  1699. class SMBTransaction_SData(AsciiOrUnicodeStructure):
  1700. AsciiStructure = (
  1701. ('Name','z'),
  1702. ('Trans_ParametersLength','_-Trans_Parameters'),
  1703. ('Trans_Parameters',':'),
  1704. ('Trans_DataLength','_-Trans_Data'),
  1705. ('Trans_Data',':'),
  1706. )
  1707. UnicodeStructure = (
  1708. ('Pad','B'),
  1709. ('Name','u'),
  1710. ('Trans_ParametersLength','_-Trans_Parameters'),
  1711. ('Trans_Parameters',':'),
  1712. ('Trans_DataLength','_-Trans_Data'),
  1713. ('Trans_Data',':'),
  1714. )
  1715. class SMBTransaction_Data(Structure):
  1716. structure = (
  1717. ('NameLength','_-Name'),
  1718. ('Name',':'),
  1719. ('Trans_ParametersLength','_-Trans_Parameters'),
  1720. ('Trans_Parameters',':'),
  1721. ('Trans_DataLength','_-Trans_Data'),
  1722. ('Trans_Data',':'),
  1723. )
  1724. class SMBTransactionResponse_Data(Structure):
  1725. structure = (
  1726. ('Trans_ParametersLength','_-Trans_Parameters'),
  1727. ('Trans_Parameters',':'),
  1728. ('Trans_DataLength','_-Trans_Data'),
  1729. ('Trans_Data',':'),
  1730. )
  1731. ############# SMB_COM_READ_ANDX (0x2E)
  1732. class SMBReadAndX_Parameters(SMBAndXCommand_Parameters):
  1733. structure = (
  1734. ('Fid','<H'),
  1735. ('Offset','<L'),
  1736. ('MaxCount','<H'),
  1737. ('MinCount','<H=MaxCount'),
  1738. ('_reserved','<L=0x0'),
  1739. ('Remaining','<H=MaxCount'),
  1740. ('HighOffset','<L=0'),
  1741. )
  1742. class SMBReadAndX_Parameters2(SMBAndXCommand_Parameters):
  1743. structure = (
  1744. ('Fid','<H'),
  1745. ('Offset','<L'),
  1746. ('MaxCount','<H'),
  1747. ('MinCount','<H=MaxCount'),
  1748. ('_reserved','<L=0xffffffff'),
  1749. ('Remaining','<H=MaxCount'),
  1750. )
  1751. class SMBReadAndXResponse_Parameters(SMBAndXCommand_Parameters):
  1752. structure = (
  1753. ('Remaining','<H=0'),
  1754. ('DataMode','<H=0'),
  1755. ('_reserved','<H=0'),
  1756. ('DataCount','<H'),
  1757. ('DataOffset','<H'),
  1758. ('DataCount_Hi','<L'),
  1759. ('_reserved2','6s=""'),
  1760. )
  1761. ############# SMB_COM_ECHO (0x2B)
  1762. class SMBEcho_Data(Structure):
  1763. structure = (
  1764. ('Data',':'),
  1765. )
  1766. class SMBEcho_Parameters(Structure):
  1767. structure = (
  1768. ('EchoCount','<H'),
  1769. )
  1770. class SMBEchoResponse_Data(Structure):
  1771. structure = (
  1772. ('Data',':'),
  1773. )
  1774. class SMBEchoResponse_Parameters(Structure):
  1775. structure = (
  1776. ('SequenceNumber','<H=1'),
  1777. )
  1778. ############# SMB_COM_QUERY_INFORMATION_DISK (0x80)
  1779. class SMBQueryInformationDiskResponse_Parameters(Structure):
  1780. structure = (
  1781. ('TotalUnits','<H'),
  1782. ('BlocksPerUnit','<H'),
  1783. ('BlockSize','<H'),
  1784. ('FreeUnits','<H'),
  1785. ('Reserved','<H=0'),
  1786. )
  1787. ############# SMB_COM_LOGOFF_ANDX (0x74)
  1788. class SMBLogOffAndX(SMBAndXCommand_Parameters):
  1789. strucure = ()
  1790. ############# SMB_COM_CLOSE (0x04)
  1791. class SMBClose_Parameters(SMBCommand_Parameters):
  1792. structure = (
  1793. ('FID','<H'),
  1794. ('Time','<L=0'),
  1795. )
  1796. ############# SMB_COM_FLUSH (0x05)
  1797. class SMBFlush_Parameters(SMBCommand_Parameters):
  1798. structure = (
  1799. ('FID','<H'),
  1800. )
  1801. ############# SMB_COM_CREATE_DIRECTORY (0x00)
  1802. class SMBCreateDirectory_Data(AsciiOrUnicodeStructure):
  1803. AsciiStructure = (
  1804. ('BufferFormat','<B=4'),
  1805. ('DirectoryName','z'),
  1806. )
  1807. UnicodeStructure = (
  1808. ('BufferFormat','<B=4'),
  1809. ('DirectoryName','u'),
  1810. )
  1811. ############# SMB_COM_DELETE (0x06)
  1812. class SMBDelete_Data(AsciiOrUnicodeStructure):
  1813. AsciiStructure = (
  1814. ('BufferFormat','<B=4'),
  1815. ('FileName','z'),
  1816. )
  1817. UnicodeStructure = (
  1818. ('BufferFormat','<B=4'),
  1819. ('FileName','u'),
  1820. )
  1821. class SMBDelete_Parameters(Structure):
  1822. structure = (
  1823. ('SearchAttributes','<H'),
  1824. )
  1825. ############# SMB_COM_DELETE_DIRECTORY (0x01)
  1826. class SMBDeleteDirectory_Data(AsciiOrUnicodeStructure):
  1827. AsciiStructure = (
  1828. ('BufferFormat','<B=4'),
  1829. ('DirectoryName','z'),
  1830. )
  1831. UnicodeStructure = (
  1832. ('BufferFormat','<B=4'),
  1833. ('DirectoryName','u'),
  1834. )
  1835. ############# SMB_COM_CHECK_DIRECTORY (0x10)
  1836. class SMBCheckDirectory_Data(AsciiOrUnicodeStructure):
  1837. AsciiStructure = (
  1838. ('BufferFormat','<B=4'),
  1839. ('DirectoryName','z'),
  1840. )
  1841. UnicodeStructure = (
  1842. ('BufferFormat','<B=4'),
  1843. ('DirectoryName','u'),
  1844. )
  1845. ############# SMB_COM_RENAME (0x07)
  1846. class SMBRename_Parameters(SMBCommand_Parameters):
  1847. structure = (
  1848. ('SearchAttributes','<H'),
  1849. )
  1850. class SMBRename_Data(AsciiOrUnicodeStructure):
  1851. AsciiStructure = (
  1852. ('BufferFormat1','<B=4'),
  1853. ('OldFileName','z'),
  1854. ('BufferFormat2','<B=4'),
  1855. ('NewFileName','z'),
  1856. )
  1857. UnicodeStructure = (
  1858. ('BufferFormat1','<B=4'),
  1859. ('OldFileName','u'),
  1860. ('BufferFormat2','<B=4'),
  1861. ('Pad','B=0'),
  1862. ('NewFileName','u'),
  1863. )
  1864. ############# SMB_COM_OPEN (0x02)
  1865. class SMBOpen_Parameters(SMBCommand_Parameters):
  1866. structure = (
  1867. ('DesiredAccess','<H=0'),
  1868. ('SearchAttributes','<H=0'),
  1869. )
  1870. class SMBOpen_Data(AsciiOrUnicodeStructure):
  1871. AsciiStructure = (
  1872. ('FileNameFormat','"\x04'),
  1873. ('FileName','z'),
  1874. )
  1875. UnicodeStructure = (
  1876. ('FileNameFormat','"\x04'),
  1877. ('FileName','z'),
  1878. )
  1879. class SMBOpenResponse_Parameters(SMBCommand_Parameters):
  1880. structure = (
  1881. ('Fid','<H=0'),
  1882. ('FileAttributes','<H=0'),
  1883. ('LastWriten','<L=0'),
  1884. ('FileSize','<L=0'),
  1885. ('GrantedAccess','<H=0'),
  1886. )
  1887. ############# EXTENDED SECURITY CLASSES
  1888. class SMBExtended_Security_Parameters(Structure):
  1889. structure = (
  1890. ('DialectIndex','<H'),
  1891. ('SecurityMode','<B'),
  1892. ('MaxMpxCount','<H'),
  1893. ('MaxNumberVcs','<H'),
  1894. ('MaxBufferSize','<L'),
  1895. ('MaxRawSize','<L'),
  1896. ('SessionKey','<L'),
  1897. ('Capabilities','<L'),
  1898. ('LowDateTime','<L'),
  1899. ('HighDateTime','<L'),
  1900. ('ServerTimeZone','<H'),
  1901. ('ChallengeLength','<B'),
  1902. )
  1903. class SMBExtended_Security_Data(Structure):
  1904. structure = (
  1905. ('ServerGUID','16s'),
  1906. ('SecurityBlob',':'),
  1907. )
  1908. class SMBNTLMDialect_Parameters(Structure):
  1909. structure = (
  1910. ('DialectIndex','<H'),
  1911. ('SecurityMode','<B'),
  1912. ('MaxMpxCount','<H'),
  1913. ('MaxNumberVcs','<H'),
  1914. ('MaxBufferSize','<L'),
  1915. ('MaxRawSize','<L'),
  1916. ('SessionKey','<L'),
  1917. ('Capabilities','<L'),
  1918. ('LowDateTime','<L'),
  1919. ('HighDateTime','<L'),
  1920. ('ServerTimeZone','<H'),
  1921. ('ChallengeLength','<B'),
  1922. )
  1923. class SMBNTLMDialect_Data(Structure):
  1924. structure = (
  1925. ('ChallengeLength','_-Challenge','self["ChallengeLength"]'),
  1926. ('Challenge',':'),
  1927. ('Payload',':'),
  1928. # For some reason on an old Linux this field is not present, we have to check this out. There must be a flag stating this.
  1929. ('DomainName','_'),
  1930. ('ServerName','_'),
  1931. )
  1932. def __init__(self,data = None, alignment = 0):
  1933. Structure.__init__(self,data,alignment)
  1934. #self['ChallengeLength']=8
  1935. def fromString(self,data):
  1936. Structure.fromString(self,data)
  1937. self['DomainName'] = ''
  1938. self['ServerName'] = ''
  1939. class SMB:
  1940. # SMB Command Codes
  1941. SMB_COM_CREATE_DIRECTORY = 0x00
  1942. SMB_COM_DELETE_DIRECTORY = 0x01
  1943. SMB_COM_OPEN = 0x02
  1944. SMB_COM_CREATE = 0x03
  1945. SMB_COM_CLOSE = 0x04
  1946. SMB_COM_FLUSH = 0x05
  1947. SMB_COM_DELETE = 0x06
  1948. SMB_COM_RENAME = 0x07
  1949. SMB_COM_QUERY_INFORMATION = 0x08
  1950. SMB_COM_SET_INFORMATION = 0x09
  1951. SMB_COM_READ = 0x0A
  1952. SMB_COM_WRITE = 0x0B
  1953. SMB_COM_LOCK_BYTE_RANGE = 0x0C
  1954. SMB_COM_UNLOCK_BYTE_RANGE = 0x0D
  1955. SMB_COM_CREATE_TEMPORARY = 0x0E
  1956. SMB_COM_CREATE_NEW = 0x0F
  1957. SMB_COM_CHECK_DIRECTORY = 0x10
  1958. SMB_COM_PROCESS_EXIT = 0x11
  1959. SMB_COM_SEEK = 0x12
  1960. SMB_COM_LOCK_AND_READ = 0x13
  1961. SMB_COM_WRITE_AND_UNLOCK = 0x14
  1962. SMB_COM_READ_RAW = 0x1A
  1963. SMB_COM_READ_MPX = 0x1B
  1964. SMB_COM_READ_MPX_SECONDARY = 0x1C
  1965. SMB_COM_WRITE_RAW = 0x1D
  1966. SMB_COM_WRITE_MPX = 0x1E
  1967. SMB_COM_WRITE_MPX_SECONDARY = 0x1F
  1968. SMB_COM_WRITE_COMPLETE = 0x20
  1969. SMB_COM_QUERY_SERVER = 0x21
  1970. SMB_COM_SET_INFORMATION2 = 0x22
  1971. SMB_COM_QUERY_INFORMATION2 = 0x23
  1972. SMB_COM_LOCKING_ANDX = 0x24
  1973. SMB_COM_TRANSACTION = 0x25
  1974. SMB_COM_TRANSACTION_SECONDARY = 0x26
  1975. SMB_COM_IOCTL = 0x27
  1976. SMB_COM_IOCTL_SECONDARY = 0x28
  1977. SMB_COM_COPY = 0x29
  1978. SMB_COM_MOVE = 0x2A
  1979. SMB_COM_ECHO = 0x2B
  1980. SMB_COM_WRITE_AND_CLOSE = 0x2C
  1981. SMB_COM_OPEN_ANDX = 0x2D
  1982. SMB_COM_READ_ANDX = 0x2E
  1983. SMB_COM_WRITE_ANDX = 0x2F
  1984. SMB_COM_NEW_FILE_SIZE = 0x30
  1985. SMB_COM_CLOSE_AND_TREE_DISC = 0x31
  1986. SMB_COM_TRANSACTION2 = 0x32
  1987. SMB_COM_TRANSACTION2_SECONDARY = 0x33
  1988. SMB_COM_FIND_CLOSE2 = 0x34
  1989. SMB_COM_FIND_NOTIFY_CLOSE = 0x35
  1990. # Used by Xenix/Unix 0x60 - 0x6E
  1991. SMB_COM_TREE_CONNECT = 0x70
  1992. SMB_COM_TREE_DISCONNECT = 0x71
  1993. SMB_COM_NEGOTIATE = 0x72
  1994. SMB_COM_SESSION_SETUP_ANDX = 0x73
  1995. SMB_COM_LOGOFF_ANDX = 0x74
  1996. SMB_COM_TREE_CONNECT_ANDX = 0x75
  1997. SMB_COM_QUERY_INFORMATION_DISK = 0x80
  1998. SMB_COM_SEARCH = 0x81
  1999. SMB_COM_FIND = 0x82
  2000. SMB_COM_FIND_UNIQUE = 0x83
  2001. SMB_COM_FIND_CLOSE = 0x84
  2002. SMB_COM_NT_TRANSACT = 0xA0
  2003. SMB_COM_NT_TRANSACT_SECONDARY = 0xA1
  2004. SMB_COM_NT_CREATE_ANDX = 0xA2
  2005. SMB_COM_NT_CANCEL = 0xA4
  2006. SMB_COM_NT_RENAME = 0xA5
  2007. SMB_COM_OPEN_PRINT_FILE = 0xC0
  2008. SMB_COM_WRITE_PRINT_FILE = 0xC1
  2009. SMB_COM_CLOSE_PRINT_FILE = 0xC2
  2010. SMB_COM_GET_PRINT_QUEUE = 0xC3
  2011. SMB_COM_READ_BULK = 0xD8
  2012. SMB_COM_WRITE_BULK = 0xD9
  2013. SMB_COM_WRITE_BULK_DATA = 0xDA
  2014. # TRANSACT codes
  2015. TRANS_TRANSACT_NMPIPE = 0x26
  2016. # TRANSACT2 codes
  2017. TRANS2_FIND_FIRST2 = 0x0001
  2018. TRANS2_FIND_NEXT2 = 0x0002
  2019. TRANS2_QUERY_FS_INFORMATION = 0x0003
  2020. TRANS2_QUERY_PATH_INFORMATION = 0x0005
  2021. TRANS2_QUERY_FILE_INFORMATION = 0x0007
  2022. TRANS2_SET_FILE_INFORMATION = 0x0008
  2023. TRANS2_SET_PATH_INFORMATION = 0x0006
  2024. # Security Share Mode (Used internally by SMB class)
  2025. SECURITY_SHARE_MASK = 0x01
  2026. SECURITY_SHARE_SHARE = 0x00
  2027. SECURITY_SHARE_USER = 0x01
  2028. SECURITY_SIGNATURES_ENABLED = 0X04
  2029. SECURITY_SIGNATURES_REQUIRED = 0X08
  2030. # Security Auth Mode (Used internally by SMB class)
  2031. SECURITY_AUTH_MASK = 0x02
  2032. SECURITY_AUTH_ENCRYPTED = 0x02
  2033. SECURITY_AUTH_PLAINTEXT = 0x00
  2034. # Raw Mode Mask (Used internally by SMB class. Good for dialect up to and including LANMAN2.1)
  2035. RAW_READ_MASK = 0x01
  2036. RAW_WRITE_MASK = 0x02
  2037. # Capabilities Mask (Used internally by SMB class. Good for dialect NT LM 0.12)
  2038. CAP_RAW_MODE = 0x00000001
  2039. CAP_MPX_MODE = 0x0002
  2040. CAP_UNICODE = 0x0004
  2041. CAP_LARGE_FILES = 0x0008
  2042. CAP_EXTENDED_SECURITY = 0x80000000
  2043. CAP_USE_NT_ERRORS = 0x40
  2044. CAP_NT_SMBS = 0x10
  2045. CAP_LARGE_READX = 0x00004000
  2046. CAP_LARGE_WRITEX = 0x00008000
  2047. CAP_RPC_REMOTE_APIS = 0x20
  2048. # Flags1 Mask
  2049. FLAGS1_LOCK_AND_READ_OK = 0x01
  2050. FLAGS1_PATHCASELESS = 0x08
  2051. FLAGS1_CANONICALIZED_PATHS = 0x10
  2052. FLAGS1_REPLY = 0x80
  2053. # Flags2 Mask
  2054. FLAGS2_LONG_NAMES = 0x0001
  2055. FLAGS2_EAS = 0x0002
  2056. FLAGS2_SMB_SECURITY_SIGNATURE = 0x0004
  2057. FLAGS2_IS_LONG_NAME = 0x0040
  2058. FLAGS2_DFS = 0x1000
  2059. FLAGS2_PAGING_IO = 0x2000
  2060. FLAGS2_NT_STATUS = 0x4000
  2061. FLAGS2_UNICODE = 0x8000
  2062. FLAGS2_COMPRESSED = 0x0008
  2063. FLAGS2_SMB_SECURITY_SIGNATURE_REQUIRED = 0x0010
  2064. FLAGS2_EXTENDED_SECURITY = 0x0800
  2065. # Dialect's Security Mode flags
  2066. NEGOTIATE_USER_SECURITY = 0x01
  2067. NEGOTIATE_ENCRYPT_PASSWORDS = 0x02
  2068. NEGOTIATE_SECURITY_SIGNATURE_ENABLE = 0x04
  2069. NEGOTIATE_SECURITY_SIGNATURE_REQUIRED = 0x08
  2070. # Tree Connect AndX Response optionalSuppor flags
  2071. SMB_SUPPORT_SEARCH_BITS = 0x01
  2072. SMB_SHARE_IS_IN_DFS = 0x02
  2073. def __init__(self, remote_name, remote_host, my_name = None, host_type = nmb.TYPE_SERVER, sess_port = 445, timeout=None, UDP = 0, session = None, negPacket = None):
  2074. # The uid attribute will be set when the client calls the login() method
  2075. self._uid = 0
  2076. self.__server_name = ''
  2077. self.__server_os = ''
  2078. self.__server_os_major = None
  2079. self.__server_os_minor = None
  2080. self.__server_os_build = None
  2081. self.__server_lanman = ''
  2082. self.__server_domain = ''
  2083. self.__server_dns_domain_name = ''
  2084. self.__remote_name = string.upper(remote_name)
  2085. self.__remote_host = remote_host
  2086. self.__isNTLMv2 = True
  2087. self._dialects_parameters = None
  2088. self._dialects_data = None
  2089. # Credentials
  2090. self.__userName = ''
  2091. self.__password = ''
  2092. self.__domain = ''
  2093. self.__lmhash = ''
  2094. self.__nthash = ''
  2095. self.__aesKey = ''
  2096. self.__kdc = ''
  2097. self.__TGT = None
  2098. self.__TGS = None
  2099. # Negotiate Protocol Result, used everywhere
  2100. # Could be extended or not, flags should be checked before
  2101. self._dialect_data = 0
  2102. self._dialect_parameters = 0
  2103. self._action = 0
  2104. self._sess = None
  2105. self.encrypt_passwords = True
  2106. self.tid = 0
  2107. self.fid = 0
  2108. # Signing stuff
  2109. self._SignSequenceNumber = 0
  2110. self._SigningSessionKey = ''
  2111. self._SigningChallengeResponse = ''
  2112. self._SignatureEnabled = False
  2113. self._SignatureVerificationEnabled = False
  2114. self._SignatureRequired = False
  2115. # Base flags (default flags, can be overriden using set_flags())
  2116. self.__flags1 = SMB.FLAGS1_PATHCASELESS | SMB.FLAGS1_CANONICALIZED_PATHS
  2117. self.__flags2 = SMB.FLAGS2_EXTENDED_SECURITY | SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_LONG_NAMES
  2118. if timeout is None:
  2119. self.__timeout = 60
  2120. else:
  2121. self.__timeout = timeout
  2122. # If port 445 and the name sent is *SMBSERVER we're setting the name to the IP.
  2123. # This is to help some old applications still believing
  2124. # *SMSBSERVER will work against modern OSes. If port is NETBIOS_SESSION_PORT the user better
  2125. # know about *SMBSERVER's limitations
  2126. if sess_port == 445 and remote_name == '*SMBSERVER':
  2127. self.__remote_name = remote_host
  2128. if session is None:
  2129. if not my_name:
  2130. my_name = socket.gethostname()
  2131. i = string.find(my_name, '.')
  2132. if i > -1:
  2133. my_name = my_name[:i]
  2134. if UDP:
  2135. self._sess = nmb.NetBIOSUDPSession(my_name, remote_name, remote_host, host_type, sess_port, self.__timeout)
  2136. else:
  2137. self._sess = nmb.NetBIOSTCPSession(my_name, remote_name, remote_host, host_type, sess_port, self.__timeout)
  2138. # Initialize session values (_dialect_data and _dialect_parameters)
  2139. self.neg_session()
  2140. # Call login() without any authentication information to
  2141. # setup a session if the remote server
  2142. # is in share mode.
  2143. if (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_SHARE:
  2144. self.login('', '')
  2145. else:
  2146. self._sess = session
  2147. self.neg_session(negPacket = negPacket)
  2148. # Call login() without any authentication information to
  2149. # setup a session if the remote server
  2150. # is in share mode.
  2151. if (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_SHARE:
  2152. self.login('', '')
  2153. @staticmethod
  2154. def ntlm_supported():
  2155. return False
  2156. def get_remote_name(self):
  2157. return self.__remote_name
  2158. def get_remote_host(self):
  2159. return self.__remote_host
  2160. def get_flags(self):
  2161. return self.__flags1, self.__flags2
  2162. def set_flags(self, flags1=None, flags2=None):
  2163. if flags1 is not None:
  2164. self.__flags1 = flags1
  2165. if flags2 is not None:
  2166. self.__flags2 = flags2
  2167. def set_timeout(self, timeout):
  2168. prev_timeout = self.__timeout
  2169. self.__timeout = timeout
  2170. return prev_timeout
  2171. def get_timeout(self):
  2172. return self.__timeout
  2173. @contextmanager
  2174. def use_timeout(self, timeout):
  2175. prev_timeout = self.set_timeout(timeout)
  2176. try:
  2177. yield
  2178. finally:
  2179. self.set_timeout(prev_timeout)
  2180. def get_session(self):
  2181. return self._sess
  2182. def get_tid(self):
  2183. return self.tid
  2184. def get_fid(self):
  2185. return self.fid
  2186. def isGuestSession(self):
  2187. return self._action & SMB_SETUP_GUEST
  2188. def doesSupportNTLMv2(self):
  2189. return self.__isNTLMv2
  2190. def __del__(self):
  2191. if self._sess:
  2192. self._sess.close()
  2193. def recvSMB(self):
  2194. r = self._sess.recv_packet(self.__timeout)
  2195. return NewSMBPacket(data = r.get_trailer())
  2196. @staticmethod
  2197. def __decode_trans(params, data):
  2198. totparamcnt, totdatacnt, _, paramcnt, paramoffset, paramds, datacnt, dataoffset, datads, setupcnt = unpack('<HHHHHHHHHB', params[:19])
  2199. if paramcnt + paramds < totparamcnt or datacnt + datads < totdatacnt:
  2200. has_more = 1
  2201. else:
  2202. has_more = 0
  2203. paramoffset = paramoffset - 55 - setupcnt * 2
  2204. dataoffset = dataoffset - 55 - setupcnt * 2
  2205. return has_more, params[20:20 + setupcnt * 2], data[paramoffset:paramoffset + paramcnt], data[dataoffset:dataoffset + datacnt]
  2206. # TODO: Move this to NewSMBPacket, it belongs there
  2207. def signSMB(self, packet, signingSessionKey, signingChallengeResponse):
  2208. # This logic MUST be applied for messages sent in response to any of the higher-layer actions and in
  2209. # compliance with the message sequencing rules.
  2210. # * The client or server that sends the message MUST provide the 32-bit sequence number for this
  2211. # message, as specified in sections 3.2.4.1 and 3.3.4.1.
  2212. # * The SMB_FLAGS2_SMB_SECURITY_SIGNATURE flag in the header MUST be set.
  2213. # * To generate the signature, a 32-bit sequence number is copied into the
  2214. # least significant 32 bits of the SecuritySignature field and the remaining
  2215. # 4 bytes are set to 0x00.
  2216. # * The MD5 algorithm, as specified in [RFC1321], MUST be used to generate a hash of the SMB
  2217. # message from the start of the SMB Header, which is defined as follows.
  2218. # CALL MD5Init( md5context )
  2219. # CALL MD5Update( md5context, Connection.SigningSessionKey )
  2220. # CALL MD5Update( md5context, Connection.SigningChallengeResponse )
  2221. # CALL MD5Update( md5context, SMB message )
  2222. # CALL MD5Final( digest, md5context )
  2223. # SET signature TO the first 8 bytes of the digest
  2224. # The resulting 8-byte signature MUST be copied into the SecuritySignature field of the SMB Header,
  2225. # after which the message can be transmitted.
  2226. #print "seq(%d) signingSessionKey %r, signingChallengeResponse %r" % (self._SignSequenceNumber, signingSessionKey, signingChallengeResponse)
  2227. packet['SecurityFeatures'] = pack('<q',self._SignSequenceNumber)
  2228. # Sign with the sequence
  2229. m = hashlib.md5()
  2230. m.update( signingSessionKey )
  2231. m.update( signingChallengeResponse )
  2232. m.update( str(packet) )
  2233. # Replace sequence with acual hash
  2234. packet['SecurityFeatures'] = m.digest()[:8]
  2235. if self._SignatureVerificationEnabled:
  2236. self._SignSequenceNumber +=1
  2237. else:
  2238. self._SignSequenceNumber +=2
  2239. def checkSignSMB(self, packet, signingSessionKey, signingChallengeResponse):
  2240. # Let's check
  2241. signature = packet['SecurityFeatures']
  2242. #print "Signature received: %r " % signature
  2243. self.signSMB(packet, signingSessionKey, signingChallengeResponse)
  2244. #print "Signature calculated: %r" % packet['SecurityFeatures']
  2245. if self._SignatureVerificationEnabled is not True:
  2246. self._SignSequenceNumber -= 1
  2247. return packet['SecurityFeatures'] == signature
  2248. def sendSMB(self,smb):
  2249. smb['Uid'] = self._uid
  2250. #At least on AIX, PIDs can exceed 16 bits, so we mask them out
  2251. smb['Pid'] = (os.getpid() & 0xFFFF)
  2252. # set flags
  2253. smb['Flags1'] |= self.__flags1
  2254. smb['Flags2'] |= self.__flags2
  2255. if self._SignatureEnabled:
  2256. smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE
  2257. self.signSMB(smb, self._SigningSessionKey, self._SigningChallengeResponse)
  2258. self._sess.send_packet(str(smb))
  2259. @staticmethod
  2260. def isValidAnswer(s, cmd):
  2261. while 1:
  2262. if s.rawData():
  2263. if s.get_command() == cmd:
  2264. if s.get_error_class() == 0x00 and s.get_error_code() == 0x00:
  2265. return 1
  2266. else:
  2267. raise SessionError, ( "SMB Library Error", s.get_error_class()+ (s.get_reserved() << 8), s.get_error_code() , s.get_flags2() & SMB.FLAGS2_NT_STATUS )
  2268. else:
  2269. break
  2270. return 0
  2271. def neg_session(self, extended_security = True, negPacket = None):
  2272. def parsePacket(smb):
  2273. if smb.isValidAnswer(SMB.SMB_COM_NEGOTIATE):
  2274. sessionResponse = SMBCommand(smb['Data'][0])
  2275. self._dialects_parameters = SMBNTLMDialect_Parameters(sessionResponse['Parameters'])
  2276. self._dialects_data = SMBNTLMDialect_Data()
  2277. self._dialects_data['ChallengeLength'] = self._dialects_parameters['ChallengeLength']
  2278. self._dialects_data.fromString(sessionResponse['Data'])
  2279. if self._dialects_parameters['Capabilities'] & SMB.CAP_EXTENDED_SECURITY:
  2280. # Whether we choose it or it is enforced by the server, we go for extended security
  2281. self._dialects_parameters = SMBExtended_Security_Parameters(sessionResponse['Parameters'])
  2282. self._dialects_data = SMBExtended_Security_Data(sessionResponse['Data'])
  2283. # Let's setup some variable for later use
  2284. if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED:
  2285. self._SignatureRequired = True
  2286. # Interestingly, the security Blob might be missing sometimes.
  2287. #spnego = SPNEGO_NegTokenInit(self._dialects_data['SecurityBlob'])
  2288. #for i in spnego['MechTypes']:
  2289. # print "Mech Found: %s" % MechTypes[i]
  2290. return 1
  2291. # If not, let's try the old way
  2292. else:
  2293. if self._dialects_data['ServerName'] is not None:
  2294. self.__server_name = self._dialects_data['ServerName']
  2295. if self._dialects_parameters['DialectIndex'] == 0xffff:
  2296. raise UnsupportedFeature,"Remote server does not know NT LM 0.12"
  2297. return 1
  2298. else:
  2299. return 0
  2300. if negPacket is None:
  2301. smb = NewSMBPacket()
  2302. negSession = SMBCommand(SMB.SMB_COM_NEGOTIATE)
  2303. flags2 = self.get_flags()[1]
  2304. if extended_security is True:
  2305. self.set_flags(flags2=flags2|SMB.FLAGS2_EXTENDED_SECURITY)
  2306. else:
  2307. self.set_flags(flags2=flags2 & (~SMB.FLAGS2_EXTENDED_SECURITY))
  2308. negSession['Data'] = '\x02NT LM 0.12\x00'
  2309. smb.addCommand(negSession)
  2310. self.sendSMB(smb)
  2311. while 1:
  2312. smb = self.recvSMB()
  2313. return parsePacket(smb)
  2314. else:
  2315. return parsePacket( NewSMBPacket( data = negPacket))
  2316. def tree_connect(self, path, password = '', service = SERVICE_ANY):
  2317. LOG.warning("[MS-CIFS] This is an original Core Protocol command.This command has been deprecated.Client Implementations SHOULD use SMB_COM_TREE_CONNECT_ANDX")
  2318. # return 0x800
  2319. if password:
  2320. # Password is only encrypted if the server passed us an "encryption" during protocol dialect
  2321. if self._dialects_parameters['ChallengeLength'] > 0:
  2322. # this code is untested
  2323. password = self.get_ntlmv1_response(ntlm.compute_lmhash(password))
  2324. if not unicode_support:
  2325. if unicode_convert:
  2326. path = str(path)
  2327. else:
  2328. raise Exception('SMB: Can\t conver path from unicode!')
  2329. smb = NewSMBPacket()
  2330. treeConnect = SMBCommand(SMB.SMB_COM_TREE_CONNECT)
  2331. treeConnect['Parameters'] = SMBTreeConnect_Parameters()
  2332. treeConnect['Data'] = SMBTreeConnect_Data()
  2333. treeConnect['Data']['Path'] = path.upper()
  2334. treeConnect['Data']['Password'] = password
  2335. treeConnect['Data']['Service'] = service
  2336. smb.addCommand(treeConnect)
  2337. self.sendSMB(smb)
  2338. while 1:
  2339. smb = self.recvSMB()
  2340. if smb.isValidAnswer(SMB.SMB_COM_TREE_CONNECT):
  2341. # XXX Here we are ignoring the rest of the response
  2342. return smb['Tid']
  2343. return smb['Tid']
  2344. def get_uid(self):
  2345. return self._uid
  2346. def set_uid(self, uid):
  2347. self._uid = uid
  2348. def tree_connect_andx(self, path, password = None, service = SERVICE_ANY, smb_packet=None):
  2349. if password:
  2350. # Password is only encrypted if the server passed us an "encryption" during protocol dialect
  2351. if self._dialects_parameters['ChallengeLength'] > 0:
  2352. # this code is untested
  2353. password = self.get_ntlmv1_response(ntlm.compute_lmhash(password))
  2354. else:
  2355. password = '\x00'
  2356. if not unicode_support:
  2357. if unicode_convert:
  2358. path = str(path)
  2359. else:
  2360. raise Exception('SMB: Can\t convert path from unicode!')
  2361. if smb_packet is None:
  2362. smb = NewSMBPacket()
  2363. else:
  2364. smb = smb_packet
  2365. # Just in case this came with the full path ,let's just leave
  2366. # the sharename, we'll take care of the rest
  2367. share = path.split('\\')[-1]
  2368. try:
  2369. _, _, _, _, sockaddr = socket.getaddrinfo(self.get_remote_host(), 80, 0, 0, socket.IPPROTO_TCP)[0]
  2370. remote_host = sockaddr[0]
  2371. except Exception:
  2372. remote_host = self.get_remote_host()
  2373. path = '\\\\' + remote_host + '\\' +share
  2374. path = path.upper().encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path
  2375. treeConnect = SMBCommand(SMB.SMB_COM_TREE_CONNECT_ANDX)
  2376. treeConnect['Parameters'] = SMBTreeConnectAndX_Parameters()
  2377. treeConnect['Data'] = SMBTreeConnectAndX_Data(flags=self.__flags2)
  2378. treeConnect['Parameters']['PasswordLength'] = len(password)
  2379. treeConnect['Data']['Password'] = password
  2380. treeConnect['Data']['Path'] = path
  2381. treeConnect['Data']['Service'] = service
  2382. if self.__flags2 & SMB.FLAGS2_UNICODE:
  2383. treeConnect['Data']['Pad'] = 0x0
  2384. smb.addCommand(treeConnect)
  2385. # filename = "\PIPE\epmapper"
  2386. # ntCreate = SMBCommand(SMB.SMB_COM_NT_CREATE_ANDX)
  2387. # ntCreate['Parameters'] = SMBNtCreateAndX_Parameters()
  2388. # ntCreate['Data'] = SMBNtCreateAndX_Data()
  2389. # ntCreate['Parameters']['FileNameLength'] = len(filename)
  2390. # ntCreate['Parameters']['CreateFlags'] = 0
  2391. # ntCreate['Parameters']['AccessMask'] = 0x3
  2392. # ntCreate['Parameters']['CreateOptions'] = 0x0
  2393. # ntCreate['Data']['FileName'] = filename
  2394. # smb.addCommand(ntCreate)
  2395. self.sendSMB(smb)
  2396. while 1:
  2397. smb = self.recvSMB()
  2398. if smb.isValidAnswer(SMB.SMB_COM_TREE_CONNECT_ANDX):
  2399. # XXX Here we are ignoring the rest of the response
  2400. self.tid = smb['Tid']
  2401. return self.tid
  2402. self.tid = smb['Tid']
  2403. return self.tid
  2404. # backwars compatibility
  2405. connect_tree = tree_connect_andx
  2406. @staticmethod
  2407. def getDialect():
  2408. return SMB_DIALECT
  2409. def get_server_name(self):
  2410. #return self._dialects_data['ServerName']
  2411. return self.__server_name
  2412. def get_session_key(self):
  2413. return self._SigningSessionKey
  2414. def set_session_key(self, key):
  2415. self._SigningSessionKey = key
  2416. def get_encryption_key(self):
  2417. if self._dialects_data.fields.has_key('Challenge'):
  2418. return self._dialects_data['Challenge']
  2419. else:
  2420. return None
  2421. def get_server_time(self):
  2422. timestamp = self._dialects_parameters['HighDateTime']
  2423. timestamp <<= 32
  2424. timestamp |= self._dialects_parameters['LowDateTime']
  2425. timestamp -= 116444736000000000
  2426. timestamp /= 10000000
  2427. d = datetime.datetime.utcfromtimestamp(timestamp)
  2428. return d.strftime("%a, %d %b %Y %H:%M:%S GMT")
  2429. def disconnect_tree(self, tid):
  2430. smb = NewSMBPacket()
  2431. smb['Tid'] = tid
  2432. smb.addCommand(SMBCommand(SMB.SMB_COM_TREE_DISCONNECT))
  2433. self.sendSMB(smb)
  2434. self.recvSMB()
  2435. def open(self, tid, filename, open_mode, desired_access):
  2436. filename = string.replace(filename,'/', '\\')
  2437. filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename
  2438. smb = NewSMBPacket()
  2439. smb['Tid'] = tid
  2440. openFile = SMBCommand(SMB.SMB_COM_OPEN)
  2441. openFile['Parameters'] = SMBOpen_Parameters()
  2442. openFile['Parameters']['DesiredAccess'] = desired_access
  2443. openFile['Parameters']['OpenMode'] = open_mode
  2444. openFile['Parameters']['SearchAttributes'] = ATTR_READONLY | ATTR_HIDDEN | ATTR_ARCHIVE
  2445. openFile['Data'] = SMBOpen_Data(flags=self.__flags2)
  2446. openFile['Data']['FileName'] = filename
  2447. if self.__flags2 & SMB.FLAGS2_UNICODE:
  2448. openFile['Data']['Pad'] = 0x0
  2449. smb.addCommand(openFile)
  2450. self.sendSMB(smb)
  2451. smb = self.recvSMB()
  2452. if smb.isValidAnswer(SMB.SMB_COM_OPEN):
  2453. # XXX Here we are ignoring the rest of the response
  2454. openFileResponse = SMBCommand(smb['Data'][0])
  2455. openFileParameters = SMBOpenResponse_Parameters(openFileResponse['Parameters'])
  2456. return (
  2457. openFileParameters['Fid'],
  2458. openFileParameters['FileAttributes'],
  2459. openFileParameters['LastWriten'],
  2460. openFileParameters['FileSize'],
  2461. openFileParameters['GrantedAccess'],
  2462. )
  2463. def open_andx(self, tid, filename, open_mode, desired_access):
  2464. filename = string.replace(filename,'/', '\\')
  2465. filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename
  2466. smb = NewSMBPacket()
  2467. smb['Tid'] = tid
  2468. openFile = SMBCommand(SMB.SMB_COM_OPEN_ANDX)
  2469. openFile['Parameters'] = SMBOpenAndX_Parameters()
  2470. openFile['Parameters']['DesiredAccess'] = desired_access
  2471. openFile['Parameters']['OpenMode'] = open_mode
  2472. openFile['Parameters']['SearchAttributes'] = ATTR_READONLY | ATTR_HIDDEN | ATTR_ARCHIVE
  2473. openFile['Data'] = SMBOpenAndX_Data(flags=self.__flags2)
  2474. openFile['Data']['FileName'] = filename
  2475. if self.__flags2 & SMB.FLAGS2_UNICODE:
  2476. openFile['Data']['Pad'] = 0x0
  2477. smb.addCommand(openFile)
  2478. self.sendSMB(smb)
  2479. smb = self.recvSMB()
  2480. if smb.isValidAnswer(SMB.SMB_COM_OPEN_ANDX):
  2481. # XXX Here we are ignoring the rest of the response
  2482. openFileResponse = SMBCommand(smb['Data'][0])
  2483. openFileParameters = SMBOpenAndXResponse_Parameters(openFileResponse['Parameters'])
  2484. return (
  2485. openFileParameters['Fid'],
  2486. openFileParameters['FileAttributes'],
  2487. openFileParameters['LastWriten'],
  2488. openFileParameters['FileSize'],
  2489. openFileParameters['GrantedAccess'],
  2490. openFileParameters['FileType'],
  2491. openFileParameters['IPCState'],
  2492. openFileParameters['Action'],
  2493. openFileParameters['ServerFid'],
  2494. )
  2495. def close(self, tid, fid):
  2496. smb = NewSMBPacket()
  2497. smb['Tid'] = tid
  2498. closeFile = SMBCommand(SMB.SMB_COM_CLOSE)
  2499. closeFile['Parameters'] = SMBClose_Parameters()
  2500. closeFile['Parameters']['FID'] = fid
  2501. smb.addCommand(closeFile)
  2502. self.sendSMB(smb)
  2503. smb = self.recvSMB()
  2504. if smb.isValidAnswer(SMB.SMB_COM_CLOSE):
  2505. return 1
  2506. return 0
  2507. def send_trans(self, tid, setup, name, param, data, noAnswer = 0):
  2508. smb = NewSMBPacket()
  2509. smb['Tid'] = tid
  2510. transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION)
  2511. transCommand['Parameters'] = SMBTransaction_Parameters()
  2512. transCommand['Data'] = SMBTransaction_Data()
  2513. transCommand['Parameters']['Setup'] = setup
  2514. transCommand['Parameters']['TotalParameterCount'] = len(param)
  2515. transCommand['Parameters']['TotalDataCount'] = len(data)
  2516. transCommand['Parameters']['ParameterCount'] = len(param)
  2517. transCommand['Parameters']['ParameterOffset'] = 32+3+28+len(setup)+len(name)
  2518. transCommand['Parameters']['DataCount'] = len(data)
  2519. transCommand['Parameters']['DataOffset'] = transCommand['Parameters']['ParameterOffset'] + len(param)
  2520. transCommand['Data']['Name'] = name
  2521. transCommand['Data']['Trans_Parameters'] = param
  2522. transCommand['Data']['Trans_Data'] = data
  2523. if noAnswer:
  2524. transCommand['Parameters']['Flags'] = TRANS_NO_RESPONSE
  2525. smb.addCommand(transCommand)
  2526. self.sendSMB(smb)
  2527. def send_trans2(self, tid, setup, name, param, data):
  2528. smb = NewSMBPacket()
  2529. smb['Tid'] = tid
  2530. command = pack('<H', setup)
  2531. transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION2)
  2532. transCommand['Parameters'] = SMBTransaction2_Parameters()
  2533. transCommand['Parameters']['MaxDataCount'] = self._dialects_parameters['MaxBufferSize']
  2534. transCommand['Data'] = SMBTransaction2_Data()
  2535. transCommand['Parameters']['Setup'] = command
  2536. transCommand['Parameters']['TotalParameterCount'] = len(param)
  2537. transCommand['Parameters']['TotalDataCount'] = len(data)
  2538. if len(param) > 0:
  2539. padLen = (4 - (32+2+28 + len(command)) % 4 ) % 4
  2540. padBytes = '\xFF' * padLen
  2541. transCommand['Data']['Pad1'] = padBytes
  2542. else:
  2543. transCommand['Data']['Pad1'] = ''
  2544. padLen = 0
  2545. transCommand['Parameters']['ParameterCount'] = len(param)
  2546. transCommand['Parameters']['ParameterOffset'] = 32+2+28+len(command)+len(name) + padLen
  2547. if len(data) > 0:
  2548. pad2Len = (4 - (32+2+28 + len(command) + padLen + len(param)) % 4) % 4
  2549. transCommand['Data']['Pad2'] = '\xFF' * pad2Len
  2550. else:
  2551. transCommand['Data']['Pad2'] = ''
  2552. pad2Len = 0
  2553. transCommand['Parameters']['DataCount'] = len(data)
  2554. transCommand['Parameters']['DataOffset'] = transCommand['Parameters']['ParameterOffset'] + len(param) + pad2Len
  2555. transCommand['Data']['Name'] = name
  2556. transCommand['Data']['Trans_Parameters'] = param
  2557. transCommand['Data']['Trans_Data'] = data
  2558. smb.addCommand(transCommand)
  2559. self.sendSMB(smb)
  2560. def query_file_info(self, tid, fid, fileInfoClass = SMB_QUERY_FILE_STANDARD_INFO):
  2561. self.send_trans2(tid, SMB.TRANS2_QUERY_FILE_INFORMATION, '\x00', pack('<HH', fid, fileInfoClass), '')
  2562. resp = self.recvSMB()
  2563. if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2):
  2564. trans2Response = SMBCommand(resp['Data'][0])
  2565. trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters'])
  2566. # Remove Potential Prefix Padding
  2567. return trans2Response['Data'][-trans2Parameters['TotalDataCount']:]
  2568. def __nonraw_retr_file(self, tid, fid, offset, datasize, callback):
  2569. if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False:
  2570. max_buf_size = 65000
  2571. else:
  2572. max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Read in multiple KB blocks
  2573. read_offset = offset
  2574. while read_offset < datasize:
  2575. data = self.read_andx(tid, fid, read_offset, max_buf_size)
  2576. callback(data)
  2577. read_offset += len(data)
  2578. def __nonraw_stor_file(self, tid, fid, offset, datasize, callback):
  2579. if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_WRITEX) and self._SignatureEnabled is False:
  2580. max_buf_size = 65000
  2581. else:
  2582. max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Write in multiple KB blocks
  2583. write_offset = offset
  2584. while 1:
  2585. data = callback(max_buf_size)
  2586. if not data:
  2587. break
  2588. smb = self.write_andx(tid,fid,data, write_offset)
  2589. writeResponse = SMBCommand(smb['Data'][0])
  2590. writeResponseParameters = SMBWriteAndXResponse_Parameters(writeResponse['Parameters'])
  2591. write_offset += writeResponseParameters['Count']
  2592. def get_server_domain(self):
  2593. return self.__server_domain
  2594. def get_server_dns_domain_name(self):
  2595. return self.__server_dns_domain_name
  2596. def get_server_os(self):
  2597. return self.__server_os
  2598. def get_server_os_major(self):
  2599. return self.__server_os_major
  2600. def get_server_os_minor(self):
  2601. return self.__server_os_minor
  2602. def get_server_os_build(self):
  2603. return self.__server_os_build
  2604. def set_server_os(self, os):
  2605. self.__server_os = os
  2606. def get_server_lanman(self):
  2607. return self.__server_lanman
  2608. def is_login_required(self):
  2609. # Login is required if share mode is user.
  2610. # Otherwise only public services or services in share mode
  2611. # are allowed.
  2612. return (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_USER
  2613. def is_signing_required(self):
  2614. return self._SignatureRequired
  2615. def get_ntlmv1_response(self, key):
  2616. challenge = self._dialects_data['Challenge']
  2617. return ntlm.get_ntlmv1_response(key, challenge)
  2618. def kerberos_login(self, user, password, domain = '', lmhash = '', nthash = '', aesKey = '', kdcHost = '', TGT=None, TGS=None):
  2619. # Importing down here so pyasn1 is not required if kerberos is not used.
  2620. from impacket.krb5.asn1 import AP_REQ, Authenticator, TGS_REP, seq_set
  2621. from impacket.krb5.kerberosv5 import getKerberosTGT, getKerberosTGS
  2622. from impacket.krb5 import constants
  2623. from impacket.krb5.types import Principal, KerberosTime, Ticket
  2624. from pyasn1.codec.der import decoder, encoder
  2625. import datetime
  2626. # login feature does not support unicode
  2627. # disable it if enabled
  2628. flags2 = self.__flags2
  2629. if flags2 & SMB.FLAGS2_UNICODE:
  2630. self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE)
  2631. # If TGT or TGS are specified, they are in the form of:
  2632. # TGS['KDC_REP'] = the response from the server
  2633. # TGS['cipher'] = the cipher used
  2634. # TGS['sessionKey'] = the sessionKey
  2635. # If we have hashes, normalize them
  2636. if lmhash != '' or nthash != '':
  2637. if len(lmhash) % 2: lmhash = '0%s' % lmhash
  2638. if len(nthash) % 2: nthash = '0%s' % nthash
  2639. try: # just in case they were converted already
  2640. lmhash = a2b_hex(lmhash)
  2641. nthash = a2b_hex(nthash)
  2642. except:
  2643. pass
  2644. self.__userName = user
  2645. self.__password = password
  2646. self.__domain = domain
  2647. self.__lmhash = lmhash
  2648. self.__nthash = nthash
  2649. self.__aesKey = aesKey
  2650. self.__kdc = kdcHost
  2651. self.__TGT = TGT
  2652. self.__TGS = TGS
  2653. # First of all, we need to get a TGT for the user
  2654. userName = Principal(user, type=constants.PrincipalNameType.NT_PRINCIPAL.value)
  2655. if TGT is None:
  2656. if TGS is None:
  2657. tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, password, domain, lmhash, nthash, aesKey, kdcHost)
  2658. else:
  2659. tgt = TGT['KDC_REP']
  2660. cipher = TGT['cipher']
  2661. sessionKey = TGT['sessionKey']
  2662. # Now that we have the TGT, we should ask for a TGS for cifs
  2663. if TGS is None:
  2664. serverName = Principal('cifs/%s' % self.__remote_name, type=constants.PrincipalNameType.NT_SRV_INST.value)
  2665. tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(serverName, domain, kdcHost, tgt, cipher, sessionKey)
  2666. else:
  2667. tgs = TGS['KDC_REP']
  2668. cipher = TGS['cipher']
  2669. sessionKey = TGS['sessionKey']
  2670. smb = NewSMBPacket()
  2671. # Are we required to sign SMB? If so we do it, if not we skip it
  2672. if self._SignatureRequired:
  2673. smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE
  2674. sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
  2675. sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters()
  2676. sessionSetup['Data'] = SMBSessionSetupAndX_Extended_Data()
  2677. sessionSetup['Parameters']['MaxBufferSize'] = 61440
  2678. sessionSetup['Parameters']['MaxMpxCount'] = 2
  2679. sessionSetup['Parameters']['VcNumber'] = 1
  2680. sessionSetup['Parameters']['SessionKey'] = 0
  2681. sessionSetup['Parameters']['Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX
  2682. # Let's build a NegTokenInit with the NTLMSSP
  2683. # TODO: In the future we should be able to choose different providers
  2684. blob = SPNEGO_NegTokenInit()
  2685. # Kerberos v5 mech
  2686. blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']]
  2687. # Let's extract the ticket from the TGS
  2688. tgs = decoder.decode(tgs, asn1Spec = TGS_REP())[0]
  2689. ticket = Ticket()
  2690. ticket.from_asn1(tgs['ticket'])
  2691. # Now let's build the AP_REQ
  2692. apReq = AP_REQ()
  2693. apReq['pvno'] = 5
  2694. apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)
  2695. opts = list()
  2696. apReq['ap-options'] = constants.encodeFlags(opts)
  2697. seq_set(apReq,'ticket', ticket.to_asn1)
  2698. authenticator = Authenticator()
  2699. authenticator['authenticator-vno'] = 5
  2700. authenticator['crealm'] = domain
  2701. seq_set(authenticator, 'cname', userName.components_to_asn1)
  2702. now = datetime.datetime.utcnow()
  2703. authenticator['cusec'] = now.microsecond
  2704. authenticator['ctime'] = KerberosTime.to_asn1(now)
  2705. encodedAuthenticator = encoder.encode(authenticator)
  2706. # Key Usage 11
  2707. # AP-REQ Authenticator (includes application authenticator
  2708. # subkey), encrypted with the application session key
  2709. # (Section 5.5.1)
  2710. encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11, encodedAuthenticator, None)
  2711. apReq['authenticator'] = None
  2712. apReq['authenticator']['etype'] = cipher.enctype
  2713. apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator
  2714. blob['MechToken'] = encoder.encode(apReq)
  2715. sessionSetup['Parameters']['SecurityBlobLength'] = len(blob)
  2716. sessionSetup['Parameters'].getData()
  2717. sessionSetup['Data']['SecurityBlob'] = blob.getData()
  2718. # Fake Data here, don't want to get us fingerprinted
  2719. sessionSetup['Data']['NativeOS'] = 'Unix'
  2720. sessionSetup['Data']['NativeLanMan'] = 'Samba'
  2721. smb.addCommand(sessionSetup)
  2722. self.sendSMB(smb)
  2723. smb = self.recvSMB()
  2724. if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX):
  2725. # We will need to use this uid field for all future requests/responses
  2726. self._uid = smb['Uid']
  2727. # Now we have to extract the blob to continue the auth process
  2728. sessionResponse = SMBCommand(smb['Data'][0])
  2729. sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters'])
  2730. sessionData = SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2'])
  2731. sessionData['SecurityBlobLength'] = sessionParameters['SecurityBlobLength']
  2732. sessionData.fromString(sessionResponse['Data'])
  2733. self._action = sessionParameters['Action']
  2734. # If smb sign required, let's enable it for the rest of the connection
  2735. if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED:
  2736. self._SigningSessionKey = sessionKey.contents
  2737. self._SignSequenceNumber = 2
  2738. self._SignatureEnabled = True
  2739. # restore unicode flag if needed
  2740. if flags2 & SMB.FLAGS2_UNICODE:
  2741. self.__flags2 |= SMB.FLAGS2_UNICODE
  2742. return 1
  2743. else:
  2744. raise Exception('Error: Could not login successfully')
  2745. def login_extended(self, user, password, domain = '', lmhash = '', nthash = '', use_ntlmv2 = True ):
  2746. # login feature does not support unicode
  2747. # disable it if enabled
  2748. flags2 = self.__flags2
  2749. if flags2 & SMB.FLAGS2_UNICODE:
  2750. self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE)
  2751. # Once everything's working we should join login methods into a single one
  2752. smb = NewSMBPacket()
  2753. # Are we required to sign SMB? If so we do it, if not we skip it
  2754. if self._SignatureRequired:
  2755. smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE
  2756. sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
  2757. sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters()
  2758. sessionSetup['Data'] = SMBSessionSetupAndX_Extended_Data()
  2759. sessionSetup['Parameters']['MaxBufferSize'] = 61440
  2760. sessionSetup['Parameters']['MaxMpxCount'] = 2
  2761. sessionSetup['Parameters']['VcNumber'] = 1
  2762. sessionSetup['Parameters']['SessionKey'] = 0
  2763. sessionSetup['Parameters']['Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX
  2764. # Let's build a NegTokenInit with the NTLMSSP
  2765. # TODO: In the future we should be able to choose different providers
  2766. blob = SPNEGO_NegTokenInit()
  2767. # NTLMSSP
  2768. blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']]
  2769. auth = ntlm.getNTLMSSPType1('','',self._SignatureRequired, use_ntlmv2 = use_ntlmv2)
  2770. blob['MechToken'] = str(auth)
  2771. sessionSetup['Parameters']['SecurityBlobLength'] = len(blob)
  2772. sessionSetup['Parameters'].getData()
  2773. sessionSetup['Data']['SecurityBlob'] = blob.getData()
  2774. # Fake Data here, don't want to get us fingerprinted
  2775. sessionSetup['Data']['NativeOS'] = 'Unix'
  2776. sessionSetup['Data']['NativeLanMan'] = 'Samba'
  2777. smb.addCommand(sessionSetup)
  2778. self.sendSMB(smb)
  2779. smb = self.recvSMB()
  2780. if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX):
  2781. # We will need to use this uid field for all future requests/responses
  2782. self._uid = smb['Uid']
  2783. # Now we have to extract the blob to continue the auth process
  2784. sessionResponse = SMBCommand(smb['Data'][0])
  2785. sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters'])
  2786. sessionData = SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2'])
  2787. sessionData['SecurityBlobLength'] = sessionParameters['SecurityBlobLength']
  2788. sessionData.fromString(sessionResponse['Data'])
  2789. respToken = SPNEGO_NegTokenResp(sessionData['SecurityBlob'])
  2790. # Let's parse some data and keep it to ourselves in case it is asked
  2791. ntlmChallenge = ntlm.NTLMAuthChallenge(respToken['ResponseToken'])
  2792. if ntlmChallenge['TargetInfoFields_len'] > 0:
  2793. av_pairs = ntlm.AV_PAIRS(ntlmChallenge['TargetInfoFields'][:ntlmChallenge['TargetInfoFields_len']])
  2794. if av_pairs[ntlm.NTLMSSP_AV_HOSTNAME] is not None:
  2795. try:
  2796. self.__server_name = av_pairs[ntlm.NTLMSSP_AV_HOSTNAME][1].decode('utf-16le')
  2797. except:
  2798. # For some reason, we couldn't decode Unicode here.. silently discard the operation
  2799. pass
  2800. if av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME] is not None:
  2801. try:
  2802. if self.__server_name != av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME][1].decode('utf-16le'):
  2803. self.__server_domain = av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME][1].decode('utf-16le')
  2804. except:
  2805. # For some reason, we couldn't decode Unicode here.. silently discard the operation
  2806. pass
  2807. if av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME] is not None:
  2808. try:
  2809. self.__server_dns_domain_name = av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME][1].decode('utf-16le')
  2810. except:
  2811. # For some reason, we couldn't decode Unicode here.. silently discard the operation
  2812. pass
  2813. # Parse Version to know the target Operating system name. Not provided elsewhere anymore
  2814. if ntlmChallenge.fields.has_key('Version'):
  2815. version = ntlmChallenge['Version']
  2816. if len(version) >= 4:
  2817. self.__server_os_major, self.__server_os_minor, self.__server_os_build = unpack('<BBH',version[:4])
  2818. type3, exportedSessionKey = ntlm.getNTLMSSPType3(auth, respToken['ResponseToken'], user, password, domain, lmhash, nthash, use_ntlmv2 = use_ntlmv2)
  2819. if exportedSessionKey is not None:
  2820. self._SigningSessionKey = exportedSessionKey
  2821. smb = NewSMBPacket()
  2822. # Are we required to sign SMB? If so we do it, if not we skip it
  2823. if self._SignatureRequired:
  2824. smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE
  2825. respToken2 = SPNEGO_NegTokenResp()
  2826. respToken2['ResponseToken'] = str(type3)
  2827. # Reusing the previous structure
  2828. sessionSetup['Parameters']['SecurityBlobLength'] = len(respToken2)
  2829. sessionSetup['Data']['SecurityBlob'] = respToken2.getData()
  2830. # Storing some info for later use
  2831. self.__server_os = sessionData['NativeOS']
  2832. self.__server_lanman = sessionData['NativeLanMan']
  2833. smb.addCommand(sessionSetup)
  2834. self.sendSMB(smb)
  2835. smb = self.recvSMB()
  2836. self._uid = 0
  2837. if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX):
  2838. self._uid = smb['Uid']
  2839. sessionResponse = SMBCommand(smb['Data'][0])
  2840. sessionParameters = SMBSessionSetupAndXResponse_Parameters(sessionResponse['Parameters'])
  2841. self._action = sessionParameters['Action']
  2842. # If smb sign required, let's enable it for the rest of the connection
  2843. if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED:
  2844. self._SignSequenceNumber = 2
  2845. self._SignatureEnabled = True
  2846. # restore unicode flag if needed
  2847. if flags2 & SMB.FLAGS2_UNICODE:
  2848. self.__flags2 |= SMB.FLAGS2_UNICODE
  2849. return 1
  2850. else:
  2851. raise Exception('Error: Could not login successfully')
  2852. def getCredentials(self):
  2853. return (
  2854. self.__userName,
  2855. self.__password,
  2856. self.__domain,
  2857. self.__lmhash,
  2858. self.__nthash,
  2859. self.__aesKey,
  2860. self.__TGT,
  2861. self.__TGS)
  2862. def getIOCapabilities(self):
  2863. res = dict()
  2864. if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False:
  2865. max_size = 65000
  2866. else:
  2867. max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks
  2868. res['MaxReadSize'] = max_size
  2869. res['MaxWriteSize'] = max_size
  2870. return res
  2871. def login(self, user, password, domain = '', lmhash = '', nthash = '', ntlm_fallback = True):
  2872. # If we have hashes, normalize them
  2873. if lmhash != '' or nthash != '':
  2874. if len(lmhash) % 2: lmhash = '0%s' % lmhash
  2875. if len(nthash) % 2: nthash = '0%s' % nthash
  2876. try: # just in case they were converted already
  2877. lmhash = a2b_hex(lmhash)
  2878. nthash = a2b_hex(nthash)
  2879. except:
  2880. pass
  2881. self.__userName = user
  2882. self.__password = password
  2883. self.__domain = domain
  2884. self.__lmhash = lmhash
  2885. self.__nthash = nthash
  2886. self.__aesKey = ''
  2887. self.__TGT = None
  2888. self.__TGS = None
  2889. if self._dialects_parameters['Capabilities'] & SMB.CAP_EXTENDED_SECURITY:
  2890. try:
  2891. self.login_extended(user, password, domain, lmhash, nthash, use_ntlmv2 = True)
  2892. except:
  2893. # If the target OS is Windows 5.0 or Samba, let's try using NTLMv1
  2894. if ntlm_fallback and ((self.get_server_lanman().find('Windows 2000') != -1) or (self.get_server_lanman().find('Samba') != -1)):
  2895. self.login_extended(user, password, domain, lmhash, nthash, use_ntlmv2 = False)
  2896. self.__isNTLMv2 = False
  2897. else:
  2898. raise
  2899. elif ntlm_fallback:
  2900. self.login_standard(user, password, domain, lmhash, nthash)
  2901. self.__isNTLMv2 = False
  2902. else:
  2903. raise SessionError('Cannot authenticate against target, enable ntlm_fallback')
  2904. def login_standard(self, user, password, domain = '', lmhash = '', nthash = ''):
  2905. # login feature does not support unicode
  2906. # disable it if enabled
  2907. flags2 = self.__flags2
  2908. if flags2 & SMB.FLAGS2_UNICODE:
  2909. self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE)
  2910. # Only supports NTLMv1
  2911. # Password is only encrypted if the server passed us an "encryption key" during protocol dialect negotiation
  2912. if self._dialects_parameters['ChallengeLength'] > 0:
  2913. if lmhash != '' or nthash != '':
  2914. pwd_ansi = self.get_ntlmv1_response(lmhash)
  2915. pwd_unicode = self.get_ntlmv1_response(nthash)
  2916. elif password:
  2917. lmhash = ntlm.compute_lmhash(password)
  2918. nthash = ntlm.compute_nthash(password)
  2919. pwd_ansi = self.get_ntlmv1_response(lmhash)
  2920. pwd_unicode = self.get_ntlmv1_response(nthash)
  2921. else: # NULL SESSION
  2922. pwd_ansi = ''
  2923. pwd_unicode = ''
  2924. else:
  2925. pwd_ansi = password
  2926. pwd_unicode = ''
  2927. smb = NewSMBPacket()
  2928. sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
  2929. sessionSetup['Parameters'] = SMBSessionSetupAndX_Parameters()
  2930. sessionSetup['Data'] = SMBSessionSetupAndX_Data()
  2931. sessionSetup['Parameters']['MaxBuffer'] = 61440
  2932. sessionSetup['Parameters']['MaxMpxCount'] = 2
  2933. sessionSetup['Parameters']['VCNumber'] = os.getpid()
  2934. sessionSetup['Parameters']['SessionKey'] = self._dialects_parameters['SessionKey']
  2935. sessionSetup['Parameters']['AnsiPwdLength'] = len(pwd_ansi)
  2936. sessionSetup['Parameters']['UnicodePwdLength'] = len(pwd_unicode)
  2937. sessionSetup['Parameters']['Capabilities'] = SMB.CAP_RAW_MODE | SMB.CAP_USE_NT_ERRORS | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX
  2938. sessionSetup['Data']['AnsiPwd'] = pwd_ansi
  2939. sessionSetup['Data']['UnicodePwd'] = pwd_unicode
  2940. sessionSetup['Data']['Account'] = str(user)
  2941. sessionSetup['Data']['PrimaryDomain'] = str(domain)
  2942. sessionSetup['Data']['NativeOS'] = str(os.name)
  2943. sessionSetup['Data']['NativeLanMan'] = 'pysmb'
  2944. smb.addCommand(sessionSetup)
  2945. self.sendSMB(smb)
  2946. smb = self.recvSMB()
  2947. if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX):
  2948. # We will need to use this uid field for all future requests/responses
  2949. self._uid = smb['Uid']
  2950. sessionResponse = SMBCommand(smb['Data'][0])
  2951. sessionParameters = SMBSessionSetupAndXResponse_Parameters(sessionResponse['Parameters'])
  2952. sessionData = SMBSessionSetupAndXResponse_Data(flags = smb['Flags2'], data = sessionResponse['Data'])
  2953. self._action = sessionParameters['Action']
  2954. # Still gotta figure out how to do this with no EXTENDED_SECURITY
  2955. if sessionParameters['Action'] & SMB_SETUP_USE_LANMAN_KEY == 0:
  2956. self._SigningChallengeResponse = sessionSetup['Data']['UnicodePwd']
  2957. self._SigningSessionKey = nthash
  2958. else:
  2959. self._SigningChallengeResponse = sessionSetup['Data']['AnsiPwd']
  2960. self._SigningSessionKey = lmhash
  2961. #self._SignSequenceNumber = 1
  2962. #self.checkSignSMB(smb, self._SigningSessionKey ,self._SigningChallengeResponse)
  2963. #self._SignatureEnabled = True
  2964. self.__server_os = sessionData['NativeOS']
  2965. self.__server_lanman = sessionData['NativeLanMan']
  2966. self.__server_domain = sessionData['PrimaryDomain']
  2967. # restore unicode flag if needed
  2968. if flags2 & SMB.FLAGS2_UNICODE:
  2969. self.__flags2 |= SMB.FLAGS2_UNICODE
  2970. return 1
  2971. else: raise Exception('Error: Could not login successfully')
  2972. def waitNamedPipe(self, tid, pipe, timeout = 5, noAnswer = 0):
  2973. smb = NewSMBPacket()
  2974. smb['Tid'] = tid
  2975. transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION)
  2976. transCommand['Parameters'] = SMBTransaction_Parameters()
  2977. transCommand['Data'] = SMBTransaction_Data()
  2978. setup = '\x53\x00\x00\x00'
  2979. name = '\\PIPE%s\x00' % pipe
  2980. transCommand['Parameters']['Setup'] = setup
  2981. transCommand['Parameters']['TotalParameterCount'] = 0
  2982. transCommand['Parameters']['TotalDataCount'] = 0
  2983. transCommand['Parameters']['MaxParameterCount'] = 0
  2984. transCommand['Parameters']['MaxDataCount'] = 0
  2985. transCommand['Parameters']['Timeout'] = timeout * 1000
  2986. transCommand['Parameters']['ParameterCount'] = 0
  2987. transCommand['Parameters']['ParameterOffset'] = 32+3+28+len(setup)+len(name)
  2988. transCommand['Parameters']['DataCount'] = 0
  2989. transCommand['Parameters']['DataOffset'] = 0
  2990. transCommand['Data']['Name'] = name
  2991. transCommand['Data']['Trans_Parameters'] = ''
  2992. transCommand['Data']['Trans_Data'] = ''
  2993. if noAnswer:
  2994. transCommand['Parameters']['Flags'] = TRANS_NO_RESPONSE
  2995. smb.addCommand(transCommand)
  2996. self.sendSMB(smb)
  2997. smb = self.recvSMB()
  2998. if smb.isValidAnswer(SMB.SMB_COM_TRANSACTION):
  2999. return 1
  3000. return 0
  3001. def read(self, tid, fid, offset=0, max_size = None, wait_answer=1):
  3002. if not max_size:
  3003. max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks
  3004. # max_size is not working, because although it would, the server returns an error (More data avail)
  3005. smb = NewSMBPacket()
  3006. smb['Tid'] = tid
  3007. read = SMBCommand(SMB.SMB_COM_READ)
  3008. read['Parameters'] = SMBRead_Parameters()
  3009. read['Parameters']['Fid'] = fid
  3010. read['Parameters']['Offset'] = offset
  3011. read['Parameters']['Count'] = max_size
  3012. smb.addCommand(read)
  3013. if wait_answer:
  3014. while 1:
  3015. self.sendSMB(smb)
  3016. ans = self.recvSMB()
  3017. if ans.isValidAnswer(SMB.SMB_COM_READ):
  3018. readResponse = SMBCommand(ans['Data'][0])
  3019. readData = SMBReadResponse_Data(readResponse['Data'])
  3020. return readData['Data']
  3021. return None
  3022. def read_andx(self, tid, fid, offset=0, max_size = None, wait_answer=1, smb_packet=None):
  3023. if not max_size:
  3024. if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False:
  3025. max_size = 65000
  3026. else:
  3027. max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks
  3028. # max_size is not working, because although it would, the server returns an error (More data avail)
  3029. if smb_packet is None:
  3030. smb = NewSMBPacket()
  3031. smb['Tid'] = tid
  3032. readAndX = SMBCommand(SMB.SMB_COM_READ_ANDX)
  3033. readAndX['Parameters'] = SMBReadAndX_Parameters()
  3034. readAndX['Parameters']['Fid'] = fid
  3035. readAndX['Parameters']['Offset'] = offset
  3036. readAndX['Parameters']['MaxCount'] = max_size
  3037. smb.addCommand(readAndX)
  3038. else:
  3039. smb = smb_packet
  3040. if wait_answer:
  3041. answer = ''
  3042. while 1:
  3043. self.sendSMB(smb)
  3044. ans = self.recvSMB()
  3045. if ans.isValidAnswer(SMB.SMB_COM_READ_ANDX):
  3046. # XXX Here we are only using a few fields from the response
  3047. readAndXResponse = SMBCommand(ans['Data'][0])
  3048. readAndXParameters = SMBReadAndXResponse_Parameters(readAndXResponse['Parameters'])
  3049. offset = readAndXParameters['DataOffset']
  3050. count = readAndXParameters['DataCount']+0x10000*readAndXParameters['DataCount_Hi']
  3051. answer += str(ans)[offset:offset+count]
  3052. if not ans.isMoreData():
  3053. return answer
  3054. max_size = min(max_size, readAndXParameters['Remaining'])
  3055. readAndX['Parameters']['Offset'] += count # XXX Offset is not important (apparently)
  3056. else:
  3057. self.sendSMB(smb)
  3058. ans = self.recvSMB()
  3059. try:
  3060. if ans.isValidAnswer(SMB.SMB_COM_READ_ANDX):
  3061. return ans
  3062. else:
  3063. return None
  3064. except:
  3065. return ans
  3066. return None
  3067. def read_raw(self, tid, fid, offset=0, max_size = None, wait_answer=1):
  3068. if not max_size:
  3069. max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks
  3070. # max_size is not working, because although it would, the server returns an error (More data avail)
  3071. smb = NewSMBPacket()
  3072. smb['Tid'] = tid
  3073. readRaw = SMBCommand(SMB.SMB_COM_READ_RAW)
  3074. readRaw['Parameters'] = SMBReadRaw_Parameters()
  3075. readRaw['Parameters']['Fid'] = fid
  3076. readRaw['Parameters']['Offset'] = offset
  3077. readRaw['Parameters']['MaxCount'] = max_size
  3078. smb.addCommand(readRaw)
  3079. self.sendSMB(smb)
  3080. if wait_answer:
  3081. data = self._sess.recv_packet(self.__timeout).get_trailer()
  3082. if not data:
  3083. # If there is no data it means there was an error
  3084. data = self.read_andx(tid, fid, offset, max_size)
  3085. return data
  3086. return None
  3087. def write(self,tid,fid,data, offset = 0, wait_answer=1):
  3088. smb = NewSMBPacket()
  3089. smb['Tid'] = tid
  3090. write = SMBCommand(SMB.SMB_COM_WRITE)
  3091. write['Parameters'] = SMBWrite_Parameters()
  3092. write['Data'] = SMBWrite_Data()
  3093. write['Parameters']['Fid'] = fid
  3094. write['Parameters']['Count'] = len(data)
  3095. write['Parameters']['Offset'] = offset
  3096. write['Parameters']['Remaining'] = len(data)
  3097. write['Data']['Data'] = data
  3098. smb.addCommand(write)
  3099. self.sendSMB(smb)
  3100. if wait_answer:
  3101. smb = self.recvSMB()
  3102. if smb.isValidAnswer(SMB.SMB_COM_WRITE):
  3103. return smb
  3104. return None
  3105. def write_andx(self,tid,fid,data, offset = 0, wait_answer=1, write_pipe_mode = False, smb_packet=None):
  3106. if smb_packet is None:
  3107. smb = NewSMBPacket()
  3108. smb['Tid'] = tid
  3109. writeAndX = SMBCommand(SMB.SMB_COM_WRITE_ANDX)
  3110. smb.addCommand(writeAndX)
  3111. writeAndX['Parameters'] = SMBWriteAndX_Parameters()
  3112. writeAndX['Parameters']['Fid'] = fid
  3113. writeAndX['Parameters']['Offset'] = offset
  3114. writeAndX['Parameters']['WriteMode'] = 8
  3115. writeAndX['Parameters']['Remaining'] = len(data)
  3116. writeAndX['Parameters']['DataLength'] = len(data)
  3117. writeAndX['Parameters']['DataOffset'] = len(smb) # this length already includes the parameter
  3118. writeAndX['Data'] = data
  3119. if write_pipe_mode is True:
  3120. # First of all we gotta know what the MaxBuffSize is
  3121. maxBuffSize = self._dialects_parameters['MaxBufferSize']
  3122. if len(data) > maxBuffSize:
  3123. chunks_size = maxBuffSize - 60
  3124. writeAndX['Parameters']['WriteMode'] = 0x0c
  3125. sendData = '\xff\xff' + data
  3126. totalLen = len(sendData)
  3127. writeAndX['Parameters']['DataLength'] = chunks_size
  3128. writeAndX['Parameters']['Remaining'] = totalLen-2
  3129. writeAndX['Data'] = sendData[:chunks_size]
  3130. self.sendSMB(smb)
  3131. if wait_answer:
  3132. smbResp = self.recvSMB()
  3133. smbResp.isValidAnswer(SMB.SMB_COM_WRITE_ANDX)
  3134. alreadySent = chunks_size
  3135. sendData = sendData[chunks_size:]
  3136. while alreadySent < totalLen:
  3137. writeAndX['Parameters']['WriteMode'] = 0x04
  3138. writeAndX['Parameters']['DataLength'] = len(sendData[:chunks_size])
  3139. writeAndX['Data'] = sendData[:chunks_size]
  3140. self.sendSMB(smb)
  3141. if wait_answer:
  3142. smbResp = self.recvSMB()
  3143. smbResp.isValidAnswer(SMB.SMB_COM_WRITE_ANDX)
  3144. alreadySent += writeAndX['Parameters']['DataLength']
  3145. sendData = sendData[chunks_size:]
  3146. return smbResp
  3147. else:
  3148. smb = smb_packet
  3149. self.sendSMB(smb)
  3150. if wait_answer:
  3151. smb = self.recvSMB()
  3152. if smb.isValidAnswer(SMB.SMB_COM_WRITE_ANDX):
  3153. return smb
  3154. return None
  3155. def write_raw(self,tid,fid,data, offset = 0, wait_answer=1):
  3156. LOG.warning("[MS-CIFS] This command was introduced in the CorePlus dialect, but is often listed as part of the LAN Manager 1.0 dialect.This command has been deprecated.Clients SHOULD use SMB_COM_WRITE_ANDX")
  3157. smb = NewSMBPacket()
  3158. smb['Tid'] = tid
  3159. writeRaw = SMBCommand(SMB.SMB_COM_WRITE_RAW)
  3160. writeRaw['Parameters'] = SMBWriteRaw_Parameters()
  3161. writeRaw['Parameters']['Fid'] = fid
  3162. writeRaw['Parameters']['Offset'] = offset
  3163. writeRaw['Parameters']['Count'] = len(data)
  3164. writeRaw['Parameters']['DataLength'] = 0
  3165. writeRaw['Parameters']['DataOffset'] = 0
  3166. smb.addCommand(writeRaw)
  3167. self.sendSMB(smb)
  3168. self._sess.send_packet(data)
  3169. if wait_answer:
  3170. smb = self.recvSMB()
  3171. if smb.isValidAnswer(SMB.SMB_COM_WRITE_RAW):
  3172. return smb
  3173. return None
  3174. def TransactNamedPipe(self, tid, fid, data = '', noAnswer = 0, waitAnswer = 1, offset = 0):
  3175. self.send_trans(tid,pack('<HH', 0x26, fid),'\\PIPE\\\x00','',data, noAnswer = noAnswer)
  3176. if noAnswer or not waitAnswer:
  3177. return
  3178. smb = self.recvSMB()
  3179. if smb.isValidAnswer(SMB.SMB_COM_TRANSACTION):
  3180. transResponse = SMBCommand(smb['Data'][0])
  3181. transParameters = SMBTransactionResponse_Parameters(transResponse['Parameters'])
  3182. return transResponse['Data'][-transParameters['TotalDataCount']:] # Remove Potential Prefix Padding
  3183. return None
  3184. def TransactNamedPipeRecv(self):
  3185. s = self.recvSMB()
  3186. if s.isValidAnswer(SMB.SMB_COM_TRANSACTION):
  3187. transResponse = SMBCommand(s['Data'][0])
  3188. transParameters = SMBTransactionResponse_Parameters(transResponse['Parameters'])
  3189. return transResponse['Data'][-transParameters['TotalDataCount']:] # Remove Potential Prefix Padding
  3190. return None
  3191. def nt_create_andx(self,tid,filename, smb_packet=None, cmd = None, shareAccessMode = FILE_SHARE_READ | FILE_SHARE_WRITE, disposition = FILE_OPEN, accessMask = 0x2019f):
  3192. filename = filename.replace('/', '\\')
  3193. filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename
  3194. if smb_packet is None:
  3195. smb = NewSMBPacket()
  3196. smb['Tid'] = tid
  3197. else:
  3198. smb = smb_packet
  3199. if cmd is None:
  3200. ntCreate = SMBCommand(SMB.SMB_COM_NT_CREATE_ANDX)
  3201. ntCreate['Parameters'] = SMBNtCreateAndX_Parameters()
  3202. ntCreate['Data'] = SMBNtCreateAndX_Data(flags=self.__flags2)
  3203. ntCreate['Parameters']['FileNameLength'] = len(filename)
  3204. ntCreate['Parameters']['CreateFlags'] = 0x16
  3205. ntCreate['Parameters']['AccessMask'] = accessMask
  3206. ntCreate['Parameters']['CreateOptions'] = 0x40
  3207. ntCreate['Parameters']['ShareAccess'] = shareAccessMode
  3208. ntCreate['Parameters']['Disposition'] = disposition
  3209. ntCreate['Data']['FileName'] = filename
  3210. if self.__flags2 & SMB.FLAGS2_UNICODE:
  3211. ntCreate['Data']['Pad'] = 0x0
  3212. else:
  3213. ntCreate = cmd
  3214. smb.addCommand(ntCreate)
  3215. self.sendSMB(smb)
  3216. while 1:
  3217. smb = self.recvSMB()
  3218. if smb.isValidAnswer(SMB.SMB_COM_NT_CREATE_ANDX):
  3219. # XXX Here we are ignoring the rest of the response
  3220. ntCreateResponse = SMBCommand(smb['Data'][0])
  3221. ntCreateParameters = SMBNtCreateAndXResponse_Parameters(ntCreateResponse['Parameters'])
  3222. self.fid = ntCreateParameters['Fid']
  3223. return ntCreateParameters['Fid']
  3224. def logoff(self):
  3225. smb = NewSMBPacket()
  3226. logOff = SMBCommand(SMB.SMB_COM_LOGOFF_ANDX)
  3227. logOff['Parameters'] = SMBLogOffAndX()
  3228. smb.addCommand(logOff)
  3229. self.sendSMB(smb)
  3230. self.recvSMB()
  3231. # Let's clear some fields so you can login again under the same session
  3232. self._uid = 0
  3233. def list_path(self, service, path = '*', password = None):
  3234. path = path.replace('/', '\\')
  3235. path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path
  3236. tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
  3237. try:
  3238. findFirstParameter = SMBFindFirst2_Parameters()
  3239. findFirstParameter['SearchAttributes'] = SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_HIDDEN | \
  3240. SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_READONLY | \
  3241. SMB_FILE_ATTRIBUTE_ARCHIVE
  3242. findFirstParameter['SearchCount'] = 512
  3243. findFirstParameter['Flags'] = SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS
  3244. findFirstParameter['InformationLevel'] = SMB_FIND_FILE_BOTH_DIRECTORY_INFO
  3245. findFirstParameter['SearchStorageType'] = 0
  3246. findFirstParameter['FileName'] = path + ('\x00\x00' if self.__flags2 & SMB.FLAGS2_UNICODE else '\x00')
  3247. self.send_trans2(tid, SMB.TRANS2_FIND_FIRST2, '\x00', findFirstParameter, '')
  3248. files = [ ]
  3249. totalDataCount = 1
  3250. findData = ''
  3251. findFirst2ParameterBlock = ''
  3252. while len(findData) < totalDataCount:
  3253. resp = self.recvSMB()
  3254. if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2):
  3255. trans2Response = SMBCommand(resp['Data'][0])
  3256. trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters'])
  3257. totalDataCount = trans2Parameters['TotalDataCount']
  3258. findFirst2ParameterBlock += trans2Response['Data'][trans2Parameters['ParameterOffset']-55:][:trans2Parameters['ParameterCount']]
  3259. findData += trans2Response['Data'][trans2Parameters['DataOffset']-55:]
  3260. findParameterBlock = SMBFindFirst2Response_Parameters(findFirst2ParameterBlock)
  3261. # Save the SID for resume operations
  3262. sid = findParameterBlock['SID']
  3263. while True:
  3264. record = SMBFindFileBothDirectoryInfo(data = findData)
  3265. shortname = record['ShortName'].decode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else record['ShortName']
  3266. filename = record['FileName'].decode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else record['FileName']
  3267. fileRecord = SharedFile(record['CreationTime'], record['LastAccessTime'], record['LastChangeTime'],
  3268. record['EndOfFile'], record['AllocationSize'], record['ExtFileAttributes'],
  3269. shortname, filename)
  3270. files.append(fileRecord)
  3271. if record['NextEntryOffset'] > 0 and len(findData[record['NextEntryOffset']:]) > 0:
  3272. findData = findData[record['NextEntryOffset']:]
  3273. else:
  3274. # More data to search?
  3275. if findParameterBlock['EndOfSearch'] == 0:
  3276. resume_filename = record['FileName']
  3277. findNextParameter = SMBFindNext2_Parameters()
  3278. findNextParameter['SID'] = sid
  3279. findNextParameter['SearchCount'] = 1024
  3280. findNextParameter['InformationLevel'] = SMB_FIND_FILE_BOTH_DIRECTORY_INFO
  3281. findNextParameter['ResumeKey'] = 0
  3282. findNextParameter['Flags'] = SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS
  3283. findNextParameter['FileName'] = resume_filename + ('\x00\x00' if self.__flags2 & SMB.FLAGS2_UNICODE else '\x00')
  3284. self.send_trans2(tid, SMB.TRANS2_FIND_NEXT2, '\x00', findNextParameter, '')
  3285. findData = ''
  3286. findNext2ParameterBlock = ''
  3287. totalDataCount = 1
  3288. while len(findData) < totalDataCount:
  3289. resp = self.recvSMB()
  3290. if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2):
  3291. trans2Response = SMBCommand(resp['Data'][0])
  3292. trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters'])
  3293. totalDataCount = trans2Parameters['TotalDataCount']
  3294. findNext2ParameterBlock += trans2Response['Data'][trans2Parameters['ParameterOffset']-55:][:trans2Parameters['ParameterCount']]
  3295. findData += trans2Response['Data'][trans2Parameters['DataOffset']-55:]
  3296. findParameterBlock = SMBFindNext2Response_Parameters(findNext2ParameterBlock)
  3297. else:
  3298. break
  3299. finally:
  3300. self.disconnect_tree(tid)
  3301. return files
  3302. def retr_file(self, service, filename, callback, mode = FILE_OPEN, offset = 0, password = None, shareAccessMode = SMB_ACCESS_READ):
  3303. filename = string.replace(filename, '/', '\\')
  3304. fid = -1
  3305. tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
  3306. try:
  3307. fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, accessMask = 0x20089)
  3308. res = self.query_file_info(tid, fid)
  3309. datasize = SMBQueryFileStandardInfo(res)['EndOfFile']
  3310. self.__nonraw_retr_file(tid, fid, offset, datasize, callback)
  3311. finally:
  3312. if fid >= 0:
  3313. self.close(tid, fid)
  3314. self.disconnect_tree(tid)
  3315. def stor_file(self, service, filename, callback, mode = FILE_OVERWRITE_IF, offset = 0, password = None, shareAccessMode = SMB_ACCESS_WRITE):
  3316. filename = string.replace(filename, '/', '\\')
  3317. fid = -1
  3318. tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
  3319. try:
  3320. fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, disposition = mode )
  3321. self.__nonraw_stor_file(tid, fid, offset, 0, callback)
  3322. finally:
  3323. if fid >= 0:
  3324. self.close(tid, fid)
  3325. self.disconnect_tree(tid)
  3326. def stor_file_nonraw(self, service, filename, callback, mode = FILE_OVERWRITE_IF, offset = 0, password = None, shareAccessMode = SMB_ACCESS_WRITE ):
  3327. filename = string.replace(filename, '/', '\\')
  3328. fid = -1
  3329. tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
  3330. try:
  3331. fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, disposition = mode)
  3332. self.__nonraw_stor_file(tid, fid, offset, 0, callback)
  3333. finally:
  3334. if fid >= 0:
  3335. self.close(tid, fid)
  3336. self.disconnect_tree(tid)
  3337. def check_dir(self, service, path, password = None):
  3338. path = string.replace(path,'/', '\\')
  3339. tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
  3340. try:
  3341. smb = NewSMBPacket()
  3342. smb['Tid'] = tid
  3343. smb['Mid'] = 0
  3344. cmd = SMBCommand(SMB.SMB_COM_CHECK_DIRECTORY)
  3345. cmd['Parameters'] = ''
  3346. cmd['Data'] = SMBCheckDirectory_Data(flags = self.__flags2)
  3347. cmd['Data']['DirectoryName'] = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path
  3348. smb.addCommand(cmd)
  3349. self.sendSMB(smb)
  3350. while 1:
  3351. s = self.recvSMB()
  3352. if s.isValidAnswer(SMB.SMB_COM_CHECK_DIRECTORY):
  3353. return
  3354. finally:
  3355. self.disconnect_tree(tid)
  3356. def remove(self, service, path, password = None):
  3357. path = string.replace(path,'/', '\\')
  3358. # Perform a list to ensure the path exists
  3359. self.list_path(service, path, password)
  3360. tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
  3361. try:
  3362. smb = NewSMBPacket()
  3363. smb['Tid'] = tid
  3364. smb['Mid'] = 0
  3365. cmd = SMBCommand(SMB.SMB_COM_DELETE)
  3366. cmd['Parameters'] = SMBDelete_Parameters()
  3367. cmd['Parameters']['SearchAttributes'] = ATTR_HIDDEN | ATTR_SYSTEM | ATTR_ARCHIVE
  3368. cmd['Data'] = SMBDelete_Data(flags = self.__flags2)
  3369. cmd['Data']['FileName'] = (path + '\x00').encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else (path + '\x00')
  3370. smb.addCommand(cmd)
  3371. self.sendSMB(smb)
  3372. while 1:
  3373. s = self.recvSMB()
  3374. if s.isValidAnswer(SMB.SMB_COM_DELETE):
  3375. return
  3376. finally:
  3377. self.disconnect_tree(tid)
  3378. def rmdir(self, service, path, password = None):
  3379. path = string.replace(path,'/', '\\')
  3380. # Check that the directory exists
  3381. self.check_dir(service, path, password)
  3382. tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
  3383. try:
  3384. path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path
  3385. smb = NewSMBPacket()
  3386. smb['Tid'] = tid
  3387. createDir = SMBCommand(SMB.SMB_COM_DELETE_DIRECTORY)
  3388. createDir['Data'] = SMBDeleteDirectory_Data(flags=self.__flags2)
  3389. createDir['Data']['DirectoryName'] = path
  3390. smb.addCommand(createDir)
  3391. self.sendSMB(smb)
  3392. while 1:
  3393. s = self.recvSMB()
  3394. if s.isValidAnswer(SMB.SMB_COM_DELETE_DIRECTORY):
  3395. return
  3396. finally:
  3397. self.disconnect_tree(tid)
  3398. def mkdir(self, service, path, password = None):
  3399. path = string.replace(path,'/', '\\')
  3400. tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
  3401. try:
  3402. path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path
  3403. smb = NewSMBPacket()
  3404. smb['Tid'] = tid
  3405. smb['Mid'] = 0
  3406. createDir = SMBCommand(SMB.SMB_COM_CREATE_DIRECTORY)
  3407. createDir['Data'] = SMBCreateDirectory_Data(flags=self.__flags2)
  3408. createDir['Data']['DirectoryName'] = path
  3409. smb.addCommand(createDir)
  3410. self.sendSMB(smb)
  3411. smb = self.recvSMB()
  3412. if smb.isValidAnswer(SMB.SMB_COM_CREATE_DIRECTORY):
  3413. return 1
  3414. return 0
  3415. finally:
  3416. self.disconnect_tree(tid)
  3417. def rename(self, service, old_path, new_path, password = None):
  3418. old_path = string.replace(old_path,'/', '\\')
  3419. new_path = string.replace(new_path,'/', '\\')
  3420. tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
  3421. try:
  3422. smb = NewSMBPacket()
  3423. smb['Tid'] = tid
  3424. smb['Mid'] = 0
  3425. renameCmd = SMBCommand(SMB.SMB_COM_RENAME)
  3426. renameCmd['Parameters'] = SMBRename_Parameters()
  3427. renameCmd['Parameters']['SearchAttributes'] = ATTR_SYSTEM | ATTR_HIDDEN | ATTR_DIRECTORY
  3428. renameCmd['Data'] = SMBRename_Data(flags = self.__flags2)
  3429. renameCmd['Data']['OldFileName'] = old_path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else old_path
  3430. renameCmd['Data']['NewFileName'] = new_path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else new_path
  3431. smb.addCommand(renameCmd)
  3432. self.sendSMB(smb)
  3433. smb = self.recvSMB()
  3434. if smb.isValidAnswer(SMB.SMB_COM_RENAME):
  3435. return 1
  3436. return 0
  3437. finally:
  3438. self.disconnect_tree(tid)
  3439. def writeFile(self, treeId, fileId, data, offset = 0):
  3440. if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_WRITEX) and self._SignatureEnabled is False:
  3441. max_buf_size = 65000
  3442. else:
  3443. max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Write in multiple KB blocks
  3444. write_offset = offset
  3445. while 1:
  3446. if len(data) == 0:
  3447. break
  3448. writeData = data[:max_buf_size]
  3449. data = data[max_buf_size:]
  3450. smb = self.write_andx(treeId,fileId,writeData, write_offset)
  3451. writeResponse = SMBCommand(smb['Data'][0])
  3452. writeResponseParameters = SMBWriteAndXResponse_Parameters(writeResponse['Parameters'])
  3453. write_offset += writeResponseParameters['Count']
  3454. def get_socket(self):
  3455. return self._sess.get_socket()
  3456. ERRDOS = { 1: 'Invalid function',
  3457. 2: 'File not found',
  3458. 3: 'Invalid directory',
  3459. 4: 'Too many open files',
  3460. 5: 'Access denied',
  3461. 6: 'Invalid file handle. Please file a bug report.',
  3462. 7: 'Memory control blocks destroyed',
  3463. 8: 'Out of memory',
  3464. 9: 'Invalid memory block address',
  3465. 10: 'Invalid environment',
  3466. 11: 'Invalid format',
  3467. 12: 'Invalid open mode',
  3468. 13: 'Invalid data',
  3469. 15: 'Invalid drive',
  3470. 16: 'Attempt to remove server\'s current directory',
  3471. 17: 'Not the same device',
  3472. 18: 'No files found',
  3473. 32: 'Sharing mode conflicts detected',
  3474. 33: 'Lock request conflicts detected',
  3475. 80: 'File already exists'
  3476. }
  3477. ERRSRV = { 1: 'Non-specific error',
  3478. 2: 'Bad password',
  3479. 4: 'Access denied',
  3480. 5: 'Invalid tid. Please file a bug report.',
  3481. 6: 'Invalid network name',
  3482. 7: 'Invalid device',
  3483. 49: 'Print queue full',
  3484. 50: 'Print queue full',
  3485. 51: 'EOF on print queue dump',
  3486. 52: 'Invalid print file handle',
  3487. 64: 'Command not recognized. Please file a bug report.',
  3488. 65: 'Internal server error',
  3489. 67: 'Invalid path',
  3490. 69: 'Invalid access permissions',
  3491. 71: 'Invalid attribute mode',
  3492. 81: 'Server is paused',
  3493. 82: 'Not receiving messages',
  3494. 83: 'No room to buffer messages',
  3495. 87: 'Too many remote user names',
  3496. 88: 'Operation timeout',
  3497. 89: 'Out of resources',
  3498. 91: 'Invalid user handle. Please file a bug report.',
  3499. 250: 'Temporarily unable to support raw mode for transfer',
  3500. 251: 'Temporarily unable to support raw mode for transfer',
  3501. 252: 'Continue in MPX mode',
  3502. 65535: 'Unsupported function'
  3503. }
  3504. ERRHRD = { 19: 'Media is write-protected',
  3505. 20: 'Unknown unit',
  3506. 21: 'Drive not ready',
  3507. 22: 'Unknown command',
  3508. 23: 'CRC error',
  3509. 24: 'Bad request',
  3510. 25: 'Seek error',
  3511. 26: 'Unknown media type',
  3512. 27: 'Sector not found',
  3513. 28: 'Printer out of paper',
  3514. 29: 'Write fault',
  3515. 30: 'Read fault',
  3516. 31: 'General failure',
  3517. 32: 'Open conflicts with an existing open',
  3518. 33: 'Invalid lock request',
  3519. 34: 'Wrong disk in drive',
  3520. 35: 'FCBs not available',
  3521. 36: 'Sharing buffer exceeded'
  3522. }