1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099 |
- # Copyright (c) 2003-2016 CORE Security Technologies
- #
- # This software is provided under under a slightly modified version
- # of the Apache Software License. See the accompanying LICENSE file
- # for more information.
- #
- # Copyright (C) 2001 Michael Teo <michaelteo@bigfoot.com>
- # smb.py - SMB/CIFS library
- #
- # This software is provided 'as-is', without any express or implied warranty.
- # In no event will the author be held liable for any damages arising from the
- # use of this software.
- #
- # Permission is granted to anyone to use this software for any purpose,
- # including commercial applications, and to alter it and redistribute it
- # freely, subject to the following restrictions:
- #
- # 1. The origin of this software must not be misrepresented; you must not
- # claim that you wrote the original software. If you use this software
- # in a product, an acknowledgment in the product documentation would be
- # appreciated but is not required.
- #
- # 2. Altered source versions must be plainly marked as such, and must not be
- # misrepresented as being the original software.
- #
- # 3. This notice cannot be removed or altered from any source distribution.
- #
- # Altered source done by Alberto Solino (@agsolino)
- # Todo:
- # [ ] Try [SMB]transport fragmentation using Transact requests
- # [ ] Try other methods of doing write (write_raw, transact2, write, write_and_unlock, write_and_close, write_mpx)
- # [-] Try replacements for SMB_COM_NT_CREATE_ANDX (CREATE, T_TRANSACT_CREATE, OPEN_ANDX works
- # [x] Fix forceWriteAndx, which needs to send a RecvRequest, because recv() will not send it
- # [x] Fix Recv() when using RecvAndx and the answer comes splet in several packets
- # [ ] Try [SMB]transport fragmentation with overlaping segments
- # [ ] Try [SMB]transport fragmentation with out of order segments
- # [x] Do chained AndX requests
- # [ ] Transform the rest of the calls to structure
- # [X] Implement TRANS/TRANS2 reassembly for list_path
- import os
- import socket
- import string
- from binascii import a2b_hex
- import datetime
- from struct import pack, unpack
- from contextlib import contextmanager
- from impacket import nmb, ntlm, nt_errors, LOG
- from impacket.structure import Structure
- from impacket.spnego import SPNEGO_NegTokenInit, TypesMech, SPNEGO_NegTokenResp
- # For signing
- import hashlib
- unicode_support = 0
- unicode_convert = 1
- try:
- from cStringIO import StringIO
- except ImportError:
- from StringIO import StringIO
- # Dialect for SMB1
- SMB_DIALECT = 'NT LM 0.12'
- # Shared Device Type
- SHARED_DISK = 0x00
- SHARED_DISK_HIDDEN = 0x80000000
- SHARED_PRINT_QUEUE = 0x01
- SHARED_DEVICE = 0x02
- SHARED_IPC = 0x03
- # Extended attributes mask
- ATTR_ARCHIVE = 0x020
- ATTR_COMPRESSED = 0x800
- ATTR_NORMAL = 0x080
- ATTR_HIDDEN = 0x002
- ATTR_READONLY = 0x001
- ATTR_TEMPORARY = 0x100
- ATTR_DIRECTORY = 0x010
- ATTR_SYSTEM = 0x004
- # Service Type
- SERVICE_DISK = 'A:'
- SERVICE_PRINTER = 'LPT1:'
- SERVICE_IPC = 'IPC'
- SERVICE_COMM = 'COMM'
- SERVICE_ANY = '?????'
- # Server Type (Can be used to mask with SMBMachine.get_type() or SMBDomain.get_type())
- SV_TYPE_WORKSTATION = 0x00000001
- SV_TYPE_SERVER = 0x00000002
- SV_TYPE_SQLSERVER = 0x00000004
- SV_TYPE_DOMAIN_CTRL = 0x00000008
- SV_TYPE_DOMAIN_BAKCTRL = 0x00000010
- SV_TYPE_TIME_SOURCE = 0x00000020
- SV_TYPE_AFP = 0x00000040
- SV_TYPE_NOVELL = 0x00000080
- SV_TYPE_DOMAIN_MEMBER = 0x00000100
- SV_TYPE_PRINTQ_SERVER = 0x00000200
- SV_TYPE_DIALIN_SERVER = 0x00000400
- SV_TYPE_XENIX_SERVER = 0x00000800
- SV_TYPE_NT = 0x00001000
- SV_TYPE_WFW = 0x00002000
- SV_TYPE_SERVER_NT = 0x00004000
- SV_TYPE_POTENTIAL_BROWSER = 0x00010000
- SV_TYPE_BACKUP_BROWSER = 0x00020000
- SV_TYPE_MASTER_BROWSER = 0x00040000
- SV_TYPE_DOMAIN_MASTER = 0x00080000
- SV_TYPE_LOCAL_LIST_ONLY = 0x40000000
- SV_TYPE_DOMAIN_ENUM = 0x80000000
- # Options values for SMB.stor_file and SMB.retr_file
- SMB_O_CREAT = 0x10 # Create the file if file does not exists. Otherwise, operation fails.
- SMB_O_EXCL = 0x00 # When used with SMB_O_CREAT, operation fails if file exists. Cannot be used with SMB_O_OPEN.
- SMB_O_OPEN = 0x01 # Open the file if the file exists
- SMB_O_TRUNC = 0x02 # Truncate the file if the file exists
- # Share Access Mode
- SMB_SHARE_COMPAT = 0x00
- SMB_SHARE_DENY_EXCL = 0x10
- SMB_SHARE_DENY_WRITE = 0x20
- SMB_SHARE_DENY_READEXEC = 0x30
- SMB_SHARE_DENY_NONE = 0x40
- SMB_ACCESS_READ = 0x00
- SMB_ACCESS_WRITE = 0x01
- SMB_ACCESS_READWRITE = 0x02
- SMB_ACCESS_EXEC = 0x03
- TRANS_DISCONNECT_TID = 1
- TRANS_NO_RESPONSE = 2
- STATUS_SUCCESS = 0x00000000
- STATUS_LOGON_FAILURE = 0xC000006D
- STATUS_LOGON_TYPE_NOT_GRANTED = 0xC000015B
- MAX_TFRAG_SIZE = 5840
- EVASION_NONE = 0
- EVASION_LOW = 1
- EVASION_HIGH = 2
- EVASION_MAX = 3
- RPC_X_BAD_STUB_DATA = 0x6F7
- # SMB_FILE_ATTRIBUTES
- SMB_FILE_ATTRIBUTE_NORMAL = 0x0000
- SMB_FILE_ATTRIBUTE_READONLY = 0x0001
- SMB_FILE_ATTRIBUTE_HIDDEN = 0x0002
- SMB_FILE_ATTRIBUTE_SYSTEM = 0x0004
- SMB_FILE_ATTRIBUTE_VOLUME = 0x0008
- SMB_FILE_ATTRIBUTE_DIRECTORY = 0x0010
- SMB_FILE_ATTRIBUTE_ARCHIVE = 0x0020
- SMB_SEARCH_ATTRIBUTE_READONLY = 0x0100
- SMB_SEARCH_ATTRIBUTE_HIDDEN = 0x0200
- SMB_SEARCH_ATTRIBUTE_SYSTEM = 0x0400
- SMB_SEARCH_ATTRIBUTE_DIRECTORY = 0x1000
- SMB_SEARCH_ATTRIBUTE_ARCHIVE = 0x2000
- # Session SetupAndX Action flags
- SMB_SETUP_GUEST = 0x01
- SMB_SETUP_USE_LANMAN_KEY = 0x02
- # QUERY_INFORMATION levels
- SMB_INFO_ALLOCATION = 0x0001
- SMB_INFO_VOLUME = 0x0002
- FILE_FS_SIZE_INFORMATION = 0x0003
- SMB_QUERY_FS_VOLUME_INFO = 0x0102
- SMB_QUERY_FS_SIZE_INFO = 0x0103
- SMB_QUERY_FILE_EA_INFO = 0x0103
- SMB_QUERY_FS_DEVICE_INFO = 0x0104
- SMB_QUERY_FS_ATTRIBUTE_INFO = 0x0105
- SMB_QUERY_FILE_BASIC_INFO = 0x0101
- SMB_QUERY_FILE_STANDARD_INFO = 0x0102
- SMB_QUERY_FILE_ALL_INFO = 0x0107
- FILE_FS_FULL_SIZE_INFORMATION = 0x03EF
- # SET_INFORMATION levels
- SMB_SET_FILE_DISPOSITION_INFO = 0x0102
- SMB_SET_FILE_BASIC_INFO = 0x0101
- SMB_SET_FILE_END_OF_FILE_INFO = 0x0104
- # File System Attributes
- FILE_CASE_SENSITIVE_SEARCH = 0x00000001
- FILE_CASE_PRESERVED_NAMES = 0x00000002
- FILE_UNICODE_ON_DISK = 0x00000004
- FILE_PERSISTENT_ACLS = 0x00000008
- FILE_FILE_COMPRESSION = 0x00000010
- FILE_VOLUME_IS_COMPRESSED = 0x00008000
- # FIND_FIRST2 flags and levels
- SMB_FIND_CLOSE_AFTER_REQUEST = 0x0001
- SMB_FIND_CLOSE_AT_EOS = 0x0002
- SMB_FIND_RETURN_RESUME_KEYS = 0x0004
- SMB_FIND_CONTINUE_FROM_LAST = 0x0008
- SMB_FIND_WITH_BACKUP_INTENT = 0x0010
- FILE_DIRECTORY_FILE = 0x00000001
- FILE_DELETE_ON_CLOSE = 0x00001000
- FILE_NON_DIRECTORY_FILE = 0x00000040
- SMB_FIND_INFO_STANDARD = 0x0001
- SMB_FIND_FILE_DIRECTORY_INFO = 0x0101
- SMB_FIND_FILE_FULL_DIRECTORY_INFO= 0x0102
- SMB_FIND_FILE_NAMES_INFO = 0x0103
- SMB_FIND_FILE_BOTH_DIRECTORY_INFO= 0x0104
- SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO = 0x105
- SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO = 0x106
- # DesiredAccess flags
- FILE_READ_DATA = 0x00000001
- FILE_WRITE_DATA = 0x00000002
- FILE_APPEND_DATA = 0x00000004
- FILE_EXECUTE = 0x00000020
- MAXIMUM_ALLOWED = 0x02000000
- GENERIC_ALL = 0x10000000
- GENERIC_EXECUTE = 0x20000000
- GENERIC_WRITE = 0x40000000
- GENERIC_READ = 0x80000000
- # ShareAccess flags
- FILE_SHARE_NONE = 0x00000000
- FILE_SHARE_READ = 0x00000001
- FILE_SHARE_WRITE = 0x00000002
- FILE_SHARE_DELETE = 0x00000004
- # CreateDisposition flags
- FILE_SUPERSEDE = 0x00000000
- FILE_OPEN = 0x00000001
- FILE_CREATE = 0x00000002
- FILE_OPEN_IF = 0x00000003
- FILE_OVERWRITE = 0x00000004
- FILE_OVERWRITE_IF = 0x00000005
- def strerror(errclass, errcode):
- if errclass == 0x01:
- return 'OS error', ERRDOS.get(errcode, 'Unknown error')
- elif errclass == 0x02:
- return 'Server error', ERRSRV.get(errcode, 'Unknown error')
- elif errclass == 0x03:
- return 'Hardware error', ERRHRD.get(errcode, 'Unknown error')
- # This is not a standard error class for SMB
- #elif errclass == 0x80:
- # return 'Browse error', ERRBROWSE.get(errcode, 'Unknown error')
- elif errclass == 0xff:
- return 'Bad command', 'Bad command. Please file bug report'
- else:
- return 'Unknown error', 'Unknown error'
- # Raised when an error has occured during a session
- class SessionError(Exception):
- # SMB X/Open error codes for the ERRDOS error class
- ERRsuccess = 0
- ERRbadfunc = 1
- ERRbadfile = 2
- ERRbadpath = 3
- ERRnofids = 4
- ERRnoaccess = 5
- ERRbadfid = 6
- ERRbadmcb = 7
- ERRnomem = 8
- ERRbadmem = 9
- ERRbadenv = 10
- ERRbadaccess = 12
- ERRbaddata = 13
- ERRres = 14
- ERRbaddrive = 15
- ERRremcd = 16
- ERRdiffdevice = 17
- ERRnofiles = 18
- ERRgeneral = 31
- ERRbadshare = 32
- ERRlock = 33
- ERRunsup = 50
- ERRnetnamedel = 64
- ERRnosuchshare = 67
- ERRfilexists = 80
- ERRinvalidparam = 87
- ERRcannotopen = 110
- ERRinsufficientbuffer = 122
- ERRinvalidname = 123
- ERRunknownlevel = 124
- ERRnotlocked = 158
- ERRrename = 183
- ERRbadpipe = 230
- ERRpipebusy = 231
- ERRpipeclosing = 232
- ERRnotconnected = 233
- ERRmoredata = 234
- ERRnomoreitems = 259
- ERRbaddirectory = 267
- ERReasnotsupported = 282
- ERRlogonfailure = 1326
- ERRbuftoosmall = 2123
- ERRunknownipc = 2142
- ERRnosuchprintjob = 2151
- ERRinvgroup = 2455
- # here's a special one from observing NT
- ERRnoipc = 66
- # These errors seem to be only returned by the NT printer driver system
- ERRdriveralreadyinstalled = 1795
- ERRunknownprinterport = 1796
- ERRunknownprinterdriver = 1797
- ERRunknownprintprocessor = 1798
- ERRinvalidseparatorfile = 1799
- ERRinvalidjobpriority = 1800
- ERRinvalidprintername = 1801
- ERRprinteralreadyexists = 1802
- ERRinvalidprintercommand = 1803
- ERRinvaliddatatype = 1804
- ERRinvalidenvironment = 1805
- ERRunknownprintmonitor = 3000
- ERRprinterdriverinuse = 3001
- ERRspoolfilenotfound = 3002
- ERRnostartdoc = 3003
- ERRnoaddjob = 3004
- ERRprintprocessoralreadyinstalled = 3005
- ERRprintmonitoralreadyinstalled = 3006
- ERRinvalidprintmonitor = 3007
- ERRprintmonitorinuse = 3008
- ERRprinterhasjobsqueued = 3009
- # Error codes for the ERRSRV class
- ERRerror = 1
- ERRbadpw = 2
- ERRbadtype = 3
- ERRaccess = 4
- ERRinvnid = 5
- ERRinvnetname = 6
- ERRinvdevice = 7
- ERRqfull = 49
- ERRqtoobig = 50
- ERRinvpfid = 52
- ERRsmbcmd = 64
- ERRsrverror = 65
- ERRfilespecs = 67
- ERRbadlink = 68
- ERRbadpermits = 69
- ERRbadpid = 70
- ERRsetattrmode = 71
- ERRpaused = 81
- ERRmsgoff = 82
- ERRnoroom = 83
- ERRrmuns = 87
- ERRtimeout = 88
- ERRnoresource = 89
- ERRtoomanyuids = 90
- ERRbaduid = 91
- ERRuseMPX = 250
- ERRuseSTD = 251
- ERRcontMPX = 252
- ERRbadPW = None
- ERRnosupport = 0
- ERRunknownsmb = 22
- # Error codes for the ERRHRD class
- ERRnowrite = 19
- ERRbadunit = 20
- ERRnotready = 21
- ERRbadcmd = 22
- ERRdata = 23
- ERRbadreq = 24
- ERRseek = 25
- ERRbadmedia = 26
- ERRbadsector = 27
- ERRnopaper = 28
- ERRwrite = 29
- ERRread = 30
- ERRwrongdisk = 34
- ERRFCBunavail = 35
- ERRsharebufexc = 36
- ERRdiskfull = 39
- hard_msgs = {
- 19: ("ERRnowrite", "Attempt to write on write-protected diskette."),
- 20: ("ERRbadunit", "Unknown unit."),
- 21: ("ERRnotready", "Drive not ready."),
- 22: ("ERRbadcmd", "Unknown command."),
- 23: ("ERRdata", "Data error (CRC)."),
- 24: ("ERRbadreq", "Bad request structure length."),
- 25: ("ERRseek", "Seek error."),
- 26: ("ERRbadmedia", "Unknown media type."),
- 27: ("ERRbadsector", "Sector not found."),
- 28: ("ERRnopaper", "Printer out of paper."),
- 29: ("ERRwrite", "Write fault."),
- 30: ("ERRread", "Read fault."),
- 31: ("ERRgeneral", "General failure."),
- 32: ("ERRbadshare", "An open conflicts with an existing open."),
- 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."),
- 34: ("ERRwrongdisk", "The wrong disk was found in a drive."),
- 35: ("ERRFCBUnavail", "No FCBs are available to process request."),
- 36: ("ERRsharebufexc", "A sharing buffer has been exceeded.")
- }
- dos_msgs = {
- ERRbadfunc: ("ERRbadfunc", "Invalid function."),
- ERRbadfile: ("ERRbadfile", "File not found."),
- ERRbadpath: ("ERRbadpath", "Directory invalid."),
- ERRnofids: ("ERRnofids", "No file descriptors available"),
- ERRnoaccess: ("ERRnoaccess", "Access denied."),
- ERRbadfid: ("ERRbadfid", "Invalid file handle."),
- ERRbadmcb: ("ERRbadmcb", "Memory control blocks destroyed."),
- ERRnomem: ("ERRnomem", "Insufficient server memory to perform the requested function."),
- ERRbadmem: ("ERRbadmem", "Invalid memory block address."),
- ERRbadenv: ("ERRbadenv", "Invalid environment."),
- 11: ("ERRbadformat", "Invalid format."),
- ERRbadaccess: ("ERRbadaccess", "Invalid open mode."),
- ERRbaddata: ("ERRbaddata", "Invalid data."),
- ERRres: ("ERRres", "reserved."),
- ERRbaddrive: ("ERRbaddrive", "Invalid drive specified."),
- ERRremcd: ("ERRremcd", "A Delete Directory request attempted to remove the server's current directory."),
- ERRdiffdevice: ("ERRdiffdevice", "Not same device."),
- ERRnofiles: ("ERRnofiles", "A File Search command can find no more files matching the specified criteria."),
- ERRbadshare: ("ERRbadshare", "The sharing mode specified for an Open conflicts with existing FIDs on the file."),
- 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."),
- ERRunsup: ("ERRunsup", "The operation is unsupported"),
- ERRnosuchshare: ("ERRnosuchshare", "You specified an invalid share name"),
- ERRfilexists: ("ERRfilexists", "The file named in a Create Directory, Make New File or Link request already exists."),
- ERRinvalidname: ("ERRinvalidname", "Invalid name"),
- ERRbadpipe: ("ERRbadpipe", "Pipe invalid."),
- ERRpipebusy: ("ERRpipebusy", "All instances of the requested pipe are busy."),
- ERRpipeclosing: ("ERRpipeclosing", "Pipe close in progress."),
- ERRnotconnected: ("ERRnotconnected", "No process on other end of pipe."),
- ERRmoredata: ("ERRmoredata", "There is more data to be returned."),
- ERRinvgroup: ("ERRinvgroup", "Invalid workgroup (try the -W option)"),
- ERRlogonfailure: ("ERRlogonfailure", "Logon failure"),
- ERRdiskfull: ("ERRdiskfull", "Disk full"),
- ERRgeneral: ("ERRgeneral", "General failure"),
- ERRunknownlevel: ("ERRunknownlevel", "Unknown info level")
- }
- server_msgs = {
- 1: ("ERRerror", "Non-specific error code."),
- 2: ("ERRbadpw", "Bad password - name/password pair in a Tree Connect or Session Setup are invalid."),
- 3: ("ERRbadtype", "reserved."),
- 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."),
- 5: ("ERRinvnid", "The tree ID (TID) specified in a command was invalid."),
- 6: ("ERRinvnetname", "Invalid network name in tree connect."),
- 7: ("ERRinvdevice", "Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."),
- 49: ("ERRqfull", "Print queue full (files) -- returned by open print file."),
- 50: ("ERRqtoobig", "Print queue full -- no space."),
- 51: ("ERRqeof", "EOF on print queue dump."),
- 52: ("ERRinvpfid", "Invalid print file FID."),
- 64: ("ERRsmbcmd", "The server did not recognize the command received."),
- 65: ("ERRsrverror","The server encountered an internal error, e.g., system file unavailable."),
- 67: ("ERRfilespecs", "The file handle (FID) and pathname parameters contained an invalid combination of values."),
- 68: ("ERRreserved", "reserved."),
- 69: ("ERRbadpermits", "The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."),
- 70: ("ERRreserved", "reserved."),
- 71: ("ERRsetattrmode", "The attribute mode in the Set File Attribute request is invalid."),
- 81: ("ERRpaused", "Server is paused."),
- 82: ("ERRmsgoff", "Not receiving messages."),
- 83: ("ERRnoroom", "No room to buffer message."),
- 87: ("ERRrmuns", "Too many remote user names."),
- 88: ("ERRtimeout", "Operation timed out."),
- 89: ("ERRnoresource", "No resources currently available for request."),
- 90: ("ERRtoomanyuids", "Too many UIDs active on this session."),
- 91: ("ERRbaduid", "The UID is not known as a valid ID on this session."),
- 250: ("ERRusempx","Temp unable to support Raw, use MPX mode."),
- 251: ("ERRusestd","Temp unable to support Raw, use standard read/write."),
- 252: ("ERRcontmpx", "Continue in MPX mode."),
- 253: ("ERRreserved", "reserved."),
- 254: ("ERRreserved", "reserved."),
- 0xFFFF: ("ERRnosupport", "Function not supported.")
- }
- # Error clases
- ERRDOS = 0x1
- error_classes = { 0: ("SUCCESS", {}),
- ERRDOS: ("ERRDOS", dos_msgs),
- 0x02: ("ERRSRV",server_msgs),
- 0x03: ("ERRHRD",hard_msgs),
- 0x04: ("ERRXOS", {} ),
- 0xE1: ("ERRRMX1", {} ),
- 0xE2: ("ERRRMX2", {} ),
- 0xE3: ("ERRRMX3", {} ),
- 0xFF: ("ERRCMD", {} ) }
- def __init__( self, error_string, error_class, error_code, nt_status = 0):
- Exception.__init__(self, error_string)
- self.nt_status = nt_status
- self._args = error_string
- if nt_status:
- self.error_class = 0
- self.error_code = (error_code << 16) + error_class
- else:
- self.error_class = error_class
- self.error_code = error_code
- def get_error_class( self ):
- return self.error_class
- def get_error_code( self ):
- return self.error_code
- def __str__( self ):
- error_class = SessionError.error_classes.get( self.error_class, None )
- if not error_class:
- error_code_str = self.error_code
- error_class_str = self.error_class
- else:
- error_class_str = error_class[0]
- error_code = error_class[1].get( self.error_code, None )
- if not error_code:
- error_code_str = self.error_code
- else:
- error_code_str = '%s(%s)' % error_code
- if self.nt_status:
- return 'SMB SessionError: %s(%s)' % nt_errors.ERROR_MESSAGES[self.error_code]
- else:
- # Fall back to the old format
- return 'SMB SessionError: class: %s, code: %s' % (error_class_str, error_code_str)
- # Raised when an supported feature is present/required in the protocol but is not
- # currently supported by pysmb
- class UnsupportedFeature(Exception): pass
- # Contains information about a SMB shared device/service
- class SharedDevice:
- def __init__(self, name, share_type, comment):
- self.__name = name
- self.__type = share_type
- self.__comment = comment
- def get_name(self):
- return self.__name
- def get_type(self):
- return self.__type
- def get_comment(self):
- return self.__comment
- def __repr__(self):
- return '<SharedDevice instance: name=' + self.__name + ', type=' + str(self.__type) + ', comment="' + self.__comment + '">'
- # Contains information about the shared file/directory
- class SharedFile:
- def __init__(self, ctime, atime, mtime, filesize, allocsize, attribs, shortname, longname):
- self.__ctime = ctime
- self.__atime = atime
- self.__mtime = mtime
- self.__filesize = filesize
- self.__allocsize = allocsize
- self.__attribs = attribs
- try:
- self.__shortname = shortname[:string.index(shortname, '\0')]
- except ValueError:
- self.__shortname = shortname
- try:
- self.__longname = longname[:string.index(longname, '\0')]
- except ValueError:
- self.__longname = longname
- def get_ctime(self):
- return self.__ctime
- def get_ctime_epoch(self):
- return self.__convert_smbtime(self.__ctime)
- def get_mtime(self):
- return self.__mtime
- def get_mtime_epoch(self):
- return self.__convert_smbtime(self.__mtime)
- def get_atime(self):
- return self.__atime
- def get_atime_epoch(self):
- return self.__convert_smbtime(self.__atime)
- def get_filesize(self):
- return self.__filesize
- def get_allocsize(self):
- return self.__allocsize
- def get_attributes(self):
- return self.__attribs
- def is_archive(self):
- return self.__attribs & ATTR_ARCHIVE
- def is_compressed(self):
- return self.__attribs & ATTR_COMPRESSED
- def is_normal(self):
- return self.__attribs & ATTR_NORMAL
- def is_hidden(self):
- return self.__attribs & ATTR_HIDDEN
- def is_readonly(self):
- return self.__attribs & ATTR_READONLY
- def is_temporary(self):
- return self.__attribs & ATTR_TEMPORARY
- def is_directory(self):
- return self.__attribs & ATTR_DIRECTORY
- def is_system(self):
- return self.__attribs & ATTR_SYSTEM
- def get_shortname(self):
- return self.__shortname
- def get_longname(self):
- return self.__longname
- def __repr__(self):
- return '<SharedFile instance: shortname="' + self.__shortname + '", longname="' + self.__longname + '", filesize=' + str(self.__filesize) + '>'
- @staticmethod
- def __convert_smbtime(t):
- x = t >> 32
- y = t & 0xffffffffL
- geo_cal_offset = 11644473600.0 # = 369.0 * 365.25 * 24 * 60 * 60 - (3.0 * 24 * 60 * 60 + 6.0 * 60 * 60)
- return (x * 4.0 * (1 << 30) + (y & 0xfff00000L)) * 1.0e-7 - geo_cal_offset
- # Contain information about a SMB machine
- class SMBMachine:
- def __init__(self, nbname, nbt_type, comment):
- self.__nbname = nbname
- self.__type = nbt_type
- self.__comment = comment
- def __repr__(self):
- return '<SMBMachine instance: nbname="' + self.__nbname + '", type=' + hex(self.__type) + ', comment="' + self.__comment + '">'
- class SMBDomain:
- def __init__(self, nbgroup, domain_type, master_browser):
- self.__nbgroup = nbgroup
- self.__type = domain_type
- self.__master_browser = master_browser
- def __repr__(self):
- return '<SMBDomain instance: nbgroup="' + self.__nbgroup + '", type=' + hex(self.__type) + ', master browser="' + self.__master_browser + '">'
- # Represents a SMB Packet
- class NewSMBPacket(Structure):
- structure = (
- ('Signature', '"\xffSMB'),
- ('Command','B=0'),
- ('ErrorClass','B=0'),
- ('_reserved','B=0'),
- ('ErrorCode','<H=0'),
- ('Flags1','B=0'),
- ('Flags2','<H=0'),
- ('PIDHigh','<H=0'),
- ('SecurityFeatures','8s=""'),
- ('Reserved','<H=0'),
- ('Tid','<H=0xffff'),
- ('Pid','<H=0'),
- ('Uid','<H=0'),
- ('Mid','<H=0'),
- ('Data','*:'),
- )
- def __init__(self, **kargs):
- Structure.__init__(self, **kargs)
- if self.fields.has_key('Flags2') is False:
- self['Flags2'] = 0
- if self.fields.has_key('Flags1') is False:
- self['Flags1'] = 0
- if not kargs.has_key('data'):
- self['Data'] = []
- def addCommand(self, command):
- if len(self['Data']) == 0:
- self['Command'] = command.command
- else:
- self['Data'][-1]['Parameters']['AndXCommand'] = command.command
- self['Data'][-1]['Parameters']['AndXOffset'] = len(self)
- self['Data'].append(command)
- def isMoreData(self):
- return (self['Command'] in [SMB.SMB_COM_TRANSACTION, SMB.SMB_COM_READ_ANDX, SMB.SMB_COM_READ_RAW] and
- self['ErrorClass'] == 1 and self['ErrorCode'] == SessionError.ERRmoredata)
- def isMoreProcessingRequired(self):
- return self['ErrorClass'] == 0x16 and self['ErrorCode'] == 0xc000
- def isValidAnswer(self, cmd):
- # this was inside a loop reading more from the net (with recv_packet(None))
- if self['Command'] == cmd:
- if (self['ErrorClass'] == 0x00 and
- self['ErrorCode'] == 0x00):
- return 1
- elif self.isMoreData():
- return 1
- elif self.isMoreProcessingRequired():
- return 1
- raise SessionError, ("SMB Library Error", self['ErrorClass'] + (self['_reserved'] << 8), self['ErrorCode'], self['Flags2'] & SMB.FLAGS2_NT_STATUS)
- else:
- raise UnsupportedFeature, ("Unexpected answer from server: Got %d, Expected %d" % (self['Command'], cmd))
- class SMBCommand(Structure):
- structure = (
- ('WordCount', 'B=len(Parameters)/2'),
- ('_ParametersLength','_-Parameters','WordCount*2'),
- ('Parameters',':'), # default set by constructor
- ('ByteCount','<H-Data'),
- ('Data',':'), # default set by constructor
- )
- def __init__(self, commandOrData = None, data = None, **kargs):
- if type(commandOrData) == type(0):
- self.command = commandOrData
- else:
- data = data or commandOrData
- Structure.__init__(self, data = data, **kargs)
- if data is None:
- self['Parameters'] = ''
- self['Data'] = ''
- class AsciiOrUnicodeStructure(Structure):
- UnicodeStructure = ()
- AsciiStructure = ()
- def __init__(self, flags = 0, **kargs):
- if flags & SMB.FLAGS2_UNICODE:
- self.structure = self.UnicodeStructure
- else:
- self.structure = self.AsciiStructure
- Structure.__init__(self, **kargs)
- class SMBCommand_Parameters(Structure):
- pass
- class SMBAndXCommand_Parameters(Structure):
- commonHdr = (
- ('AndXCommand','B=0xff'),
- ('_reserved','B=0'),
- ('AndXOffset','<H=0'),
- )
- structure = ( # default structure, overriden by subclasses
- ('Data',':=""'),
- )
- ############# TRANSACTIONS RELATED
- # TRANS2_QUERY_FS_INFORMATION
- # QUERY_FS Information Levels
- # SMB_QUERY_FS_ATTRIBUTE_INFO
- class SMBQueryFsAttributeInfo(Structure):
- structure = (
- ('FileSystemAttributes','<L'),
- ('MaxFilenNameLengthInBytes','<L'),
- ('LengthOfFileSystemName','<L-FileSystemName'),
- ('FileSystemName',':'),
- )
- class SMBQueryFsInfoVolume(AsciiOrUnicodeStructure):
- commonHdr = (
- ('ulVolSerialNbr','<L=0xABCDEFAA'),
- ('cCharCount','<B-VolumeLabel'),
- )
- AsciiStructure = (
- ('VolumeLabel','z'),
- )
- UnicodeStructure = (
- ('VolumeLabel','u'),
- )
- # FILE_FS_SIZE_INFORMATION
- class FileFsSizeInformation(Structure):
- structure = (
- ('TotalAllocationUnits','<q=148529400'),
- ('AvailableAllocationUnits','<q=14851044'),
- ('SectorsPerAllocationUnit','<L=2'),
- ('BytesPerSector','<L=512'),
- )
- # SMB_QUERY_FS_SIZE_INFO
- class SMBQueryFsSizeInfo(Structure):
- structure = (
- ('TotalAllocationUnits','<q=148529400'),
- ('TotalFreeAllocationUnits','<q=14851044'),
- ('SectorsPerAllocationUnit','<L=2'),
- ('BytesPerSector','<L=512'),
- )
- # FILE_FS_FULL_SIZE_INFORMATION
- class SMBFileFsFullSizeInformation(Structure):
- structure = (
- ('TotalAllocationUnits','<q=148529400'),
- ('CallerAvailableAllocationUnits','<q=148529400'),
- ('ActualAvailableAllocationUnits','<q=148529400'),
- ('SectorsPerAllocationUnit','<L=15'),
- ('BytesPerSector','<L=512')
- )
- # SMB_QUERY_FS_VOLUME_INFO
- class SMBQueryFsVolumeInfo(Structure):
- structure = (
- ('VolumeCreationTime','<q'),
- ('SerialNumber','<L=0xABCDEFAA'),
- ('VolumeLabelSize','<L=len(VolumeLabel)'),
- ('Reserved','<H=0x10'),
- ('VolumeLabel',':')
- )
- # SMB_FIND_FILE_BOTH_DIRECTORY_INFO level
- class SMBFindFileBothDirectoryInfo(AsciiOrUnicodeStructure):
- commonHdr = (
- ('NextEntryOffset','<L=0'),
- ('FileIndex','<L=0'),
- ('CreationTime','<q'),
- ('LastAccessTime','<q'),
- ('LastWriteTime','<q'),
- ('LastChangeTime','<q'),
- ('EndOfFile','<q=0'),
- ('AllocationSize','<q=0'),
- ('ExtFileAttributes','<L=0'),
- )
- AsciiStructure = (
- ('FileNameLength','<L-FileName','len(FileName)'),
- ('EaSize','<L=0'),
- ('ShortNameLength','<B=0'),
- ('Reserved','<B=0'),
- ('ShortName','24s'),
- ('FileName',':'),
- )
- UnicodeStructure = (
- ('FileNameLength','<L-FileName','len(FileName)*2'),
- ('EaSize','<L=0'),
- ('ShortNameLength','<B=0'),
- ('Reserved','<B=0'),
- ('ShortName','24s'),
- ('FileName',':'),
- )
- # SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO level
- class SMBFindFileIdFullDirectoryInfo(AsciiOrUnicodeStructure):
- commonHdr = (
- ('NextEntryOffset','<L=0'),
- ('FileIndex','<L=0'),
- ('CreationTime','<q'),
- ('LastAccessTime','<q'),
- ('LastWriteTime','<q'),
- ('LastChangeTime','<q'),
- ('EndOfFile','<q=0'),
- ('AllocationSize','<q=0'),
- ('ExtFileAttributes','<L=0'),
- )
- AsciiStructure = (
- ('FileNameLength','<L-FileName','len(FileName)'),
- ('EaSize','<L=0'),
- ('FileID','<q=0'),
- ('FileName',':'),
- )
- UnicodeStructure = (
- ('FileNameLength','<L-FileName','len(FileName)*2'),
- ('EaSize','<L=0'),
- ('FileID','<q=0'),
- ('FileName',':'),
- )
- # SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO level
- class SMBFindFileIdBothDirectoryInfo(AsciiOrUnicodeStructure):
- commonHdr = (
- ('NextEntryOffset','<L=0'),
- ('FileIndex','<L=0'),
- ('CreationTime','<q'),
- ('LastAccessTime','<q'),
- ('LastWriteTime','<q'),
- ('LastChangeTime','<q'),
- ('EndOfFile','<q=0'),
- ('AllocationSize','<q=0'),
- ('ExtFileAttributes','<L=0'),
- )
- AsciiStructure = (
- ('FileNameLength','<L-FileName','len(FileName)'),
- ('EaSize','<L=0'),
- ('ShortNameLength','<B=0'),
- ('Reserved','<B=0'),
- ('ShortName','24s'),
- ('Reserved','<H=0'),
- ('FileID','<q=0'),
- ('FileName','z'),
- )
- UnicodeStructure = (
- ('FileNameLength','<L-FileName','len(FileName)*2'),
- ('EaSize','<L=0'),
- ('ShortNameLength','<B=0'),
- ('Reserved','<B=0'),
- ('ShortName','24s'),
- ('Reserved','<H=0'),
- ('FileID','<q=0'),
- ('FileName',':'),
- )
- # SMB_FIND_FILE_DIRECTORY_INFO level
- class SMBFindFileDirectoryInfo(AsciiOrUnicodeStructure):
- commonHdr = (
- ('NextEntryOffset','<L=0'),
- ('FileIndex','<L=0'),
- ('CreationTime','<q'),
- ('LastAccessTime','<q'),
- ('LastWriteTime','<q'),
- ('LastChangeTime','<q'),
- ('EndOfFile','<q=0'),
- ('AllocationSize','<q=1'),
- ('ExtFileAttributes','<L=0'),
- )
- AsciiStructure = (
- ('FileNameLength','<L-FileName','len(FileName)'),
- ('FileName','z'),
- )
- UnicodeStructure = (
- ('FileNameLength','<L-FileName','len(FileName)*2'),
- ('FileName',':'),
- )
- # SMB_FIND_FILE_NAMES_INFO level
- class SMBFindFileNamesInfo(AsciiOrUnicodeStructure):
- commonHdr = (
- ('NextEntryOffset','<L=0'),
- ('FileIndex','<L=0'),
- )
- AsciiStructure = (
- ('FileNameLength','<L-FileName','len(FileName)'),
- ('FileName','z'),
- )
- UnicodeStructure = (
- ('FileNameLength','<L-FileName','len(FileName)*2'),
- ('FileName',':'),
- )
- # SMB_FIND_FILE_FULL_DIRECTORY_INFO level
- class SMBFindFileFullDirectoryInfo(AsciiOrUnicodeStructure):
- commonHdr = (
- ('NextEntryOffset','<L=0'),
- ('FileIndex','<L=0'),
- ('CreationTime','<q'),
- ('LastAccessTime','<q'),
- ('LastWriteTime','<q'),
- ('LastChangeTime','<q'),
- ('EndOfFile','<q=0'),
- ('AllocationSize','<q=1'),
- ('ExtFileAttributes','<L=0'),
- )
- AsciiStructure = (
- ('FileNameLength','<L-FileName','len(FileName)'),
- ('EaSize','<L'),
- ('FileName','z'),
- )
- UnicodeStructure = (
- ('FileNameLength','<L-FileName','len(FileName)*2'),
- ('EaSize','<L'),
- ('FileName',':'),
- )
- # SMB_FIND_INFO_STANDARD level
- class SMBFindInfoStandard(AsciiOrUnicodeStructure):
- commonHdr = (
- ('ResumeKey','<L=0xff'),
- ('CreationDate','<H=0'),
- ('CreationTime','<H=0'),
- ('LastAccessDate','<H=0'),
- ('LastAccessTime','<H=0'),
- ('LastWriteDate','<H=0'),
- ('LastWriteTime','<H=0'),
- ('EaSize','<L'),
- ('AllocationSize','<L=1'),
- ('ExtFileAttributes','<H=0'),
- )
- AsciiStructure = (
- ('FileNameLength','<B-FileName','len(FileName)'),
- ('FileName','z'),
- )
- UnicodeStructure = (
- ('FileNameLength','<B-FileName','len(FileName)*2'),
- ('FileName',':'),
- )
- # SET_FILE_INFORMATION structures
- # SMB_SET_FILE_DISPOSITION_INFO
- class SMBSetFileDispositionInfo(Structure):
- structure = (
- ('DeletePending','<B'),
- )
- # SMB_SET_FILE_BASIC_INFO
- class SMBSetFileBasicInfo(Structure):
- structure = (
- ('CreationTime','<q'),
- ('LastAccessTime','<q'),
- ('LastWriteTime','<q'),
- ('ChangeTime','<q'),
- ('ExtFileAttributes','<H'),
- ('Reserved','<L'),
- )
- # FILE_STREAM_INFORMATION
- class SMBFileStreamInformation(Structure):
- commonHdr = (
- ('NextEntryOffset','<L=0'),
- ('StreamNameLength','<L=0'),
- ('StreamSize','<q=0'),
- ('StreamAllocationSize','<q=0'),
- ('StreamName',':=""'),
- )
- # FILE_NETWORK_OPEN_INFORMATION
- class SMBFileNetworkOpenInfo(Structure):
- structure = (
- ('CreationTime','<q=0'),
- ('LastAccessTime','<q=0'),
- ('LastWriteTime','<q=0'),
- ('ChangeTime','<q=0'),
- ('AllocationSize','<q=0'),
- ('EndOfFile','<q=0'),
- ('FileAttributes','<L=0'),
- ('Reserved','<L=0'),
- )
- # SMB_SET_FILE_END_OF_FILE_INFO
- class SMBSetFileEndOfFileInfo(Structure):
- structure = (
- ('EndOfFile','<q'),
- )
- # TRANS2_FIND_NEXT2
- class SMBFindNext2_Parameters(AsciiOrUnicodeStructure):
- commonHdr = (
- ('SID','<H'),
- ('SearchCount','<H'),
- ('InformationLevel','<H'),
- ('ResumeKey','<L'),
- ('Flags','<H'),
- )
- AsciiStructure = (
- ('FileName','z'),
- )
- UnicodeStructure = (
- ('FileName','u'),
- )
- class SMBFindNext2Response_Parameters(Structure):
- structure = (
- ('SearchCount','<H'),
- ('EndOfSearch','<H=1'),
- ('EaErrorOffset','<H=0'),
- ('LastNameOffset','<H=0'),
- )
- class SMBFindNext2_Data(Structure):
- structure = (
- ('GetExtendedAttributesListLength','_-GetExtendedAttributesList', 'self["GetExtendedAttributesListLength"]'),
- ('GetExtendedAttributesList',':'),
- )
- # TRANS2_FIND_FIRST2
- class SMBFindFirst2Response_Parameters(Structure):
- structure = (
- ('SID','<H'),
- ('SearchCount','<H'),
- ('EndOfSearch','<H=1'),
- ('EaErrorOffset','<H=0'),
- ('LastNameOffset','<H=0'),
- )
- class SMBFindFirst2_Parameters(AsciiOrUnicodeStructure):
- commonHdr = (
- ('SearchAttributes','<H'),
- ('SearchCount','<H'),
- ('Flags','<H'),
- ('InformationLevel','<H'),
- ('SearchStorageType','<L'),
- )
- AsciiStructure = (
- ('FileName','z'),
- )
- UnicodeStructure = (
- ('FileName','u'),
- )
- class SMBFindFirst2_Data(Structure):
- structure = (
- ('GetExtendedAttributesListLength','_-GetExtendedAttributesList', 'self["GetExtendedAttributesListLength"]'),
- ('GetExtendedAttributesList',':'),
- )
- # TRANS2_SET_PATH_INFORMATION
- class SMBSetPathInformation_Parameters(AsciiOrUnicodeStructure):
- commonHdr = (
- ('InformationLevel','<H'),
- ('Reserved','<L'),
- )
- AsciiStructure = (
- ('FileName','z'),
- )
- UnicodeStructure = (
- ('FileName','u'),
- )
- class SMBSetPathInformationResponse_Parameters(Structure):
- structure = (
- ('EaErrorOffset','<H=0'),
- )
- # TRANS2_SET_FILE_INFORMATION
- class SMBSetFileInformation_Parameters(Structure):
- structure = (
- ('FID','<H'),
- ('InformationLevel','<H'),
- ('Reserved','<H'),
- )
- class SMBSetFileInformationResponse_Parameters(Structure):
- structure = (
- ('EaErrorOffset','<H=0'),
- )
- # TRANS2_QUERY_FILE_INFORMATION
- class SMBQueryFileInformation_Parameters(Structure):
- structure = (
- ('FID','<H'),
- ('InformationLevel','<H'),
- )
- class SMBQueryFileInformationResponse_Parameters(Structure):
- structure = (
- ('EaErrorOffset','<H=0'),
- )
- class SMBQueryFileInformation_Data(Structure):
- structure = (
- ('GetExtendedAttributeList',':'),
- )
- # TRANS2_QUERY_PATH_INFORMATION
- class SMBQueryPathInformationResponse_Parameters(Structure):
- structure = (
- ('EaErrorOffset','<H=0'),
- )
- class SMBQueryPathInformation_Parameters(AsciiOrUnicodeStructure):
- commonHdr = (
- ('InformationLevel','<H'),
- ('Reserved','<L=0'),
- )
- AsciiStructure = (
- ('FileName','z'),
- )
- UnicodeStructure = (
- ('FileName','u'),
- )
- class SMBQueryPathInformation_Data(Structure):
- structure = (
- ('GetExtendedAttributeList',':'),
- )
- # SMB_QUERY_FILE_EA_INFO
- class SMBQueryFileEaInfo(Structure):
- structure = (
- ('EaSize','<L=0'),
- )
- # SMB_QUERY_FILE_BASIC_INFO
- class SMBQueryFileBasicInfo(Structure):
- structure = (
- ('CreationTime','<q'),
- ('LastAccessTime','<q'),
- ('LastWriteTime','<q'),
- ('LastChangeTime','<q'),
- ('ExtFileAttributes','<L'),
- #('Reserved','<L=0'),
- )
- # SMB_QUERY_FILE_STANDARD_INFO
- class SMBQueryFileStandardInfo(Structure):
- structure = (
- ('AllocationSize','<q'),
- ('EndOfFile','<q'),
- ('NumberOfLinks','<L=0'),
- ('DeletePending','<B=0'),
- ('Directory','<B'),
- )
- # SMB_QUERY_FILE_ALL_INFO
- class SMBQueryFileAllInfo(Structure):
- structure = (
- ('CreationTime','<q'),
- ('LastAccessTime','<q'),
- ('LastWriteTime','<q'),
- ('LastChangeTime','<q'),
- ('ExtFileAttributes','<L'),
- ('Reserved','<L=0'),
- ('AllocationSize','<q'),
- ('EndOfFile','<q'),
- ('NumberOfLinks','<L=0'),
- ('DeletePending','<B=0'),
- ('Directory','<B'),
- ('Reserved','<H=0'),
- ('EaSize','<L=0'),
- ('FileNameLength','<L-FileName','len(FileName)'),
- ('FileName',':'),
- )
- # \PIPE\LANMAN NetShareEnum
- class SMBNetShareEnum(Structure):
- structure = (
- ('RAPOpcode','<H=0'),
- ('ParamDesc','z'),
- ('DataDesc','z'),
- ('InfoLevel','<H'),
- ('ReceiveBufferSize','<H'),
- )
- class SMBNetShareEnumResponse(Structure):
- structure = (
- ('Status','<H=0'),
- ('Convert','<H=0'),
- ('EntriesReturned','<H'),
- ('EntriesAvailable','<H'),
- )
- class NetShareInfo1(Structure):
- structure = (
- ('NetworkName','13s'),
- ('Pad','<B=0'),
- ('Type','<H=0'),
- ('RemarkOffsetLow','<H=0'),
- ('RemarkOffsetHigh','<H=0'),
- )
- # \PIPE\LANMAN NetServerGetInfo
- class SMBNetServerGetInfoResponse(Structure):
- structure = (
- ('Status','<H=0'),
- ('Convert','<H=0'),
- ('TotalBytesAvailable','<H'),
- )
- class SMBNetServerInfo1(Structure):
- # Level 1 Response
- structure = (
- ('ServerName','16s'),
- ('MajorVersion','B=5'),
- ('MinorVersion','B=0'),
- ('ServerType','<L=3'),
- ('ServerCommentLow','<H=0'),
- ('ServerCommentHigh','<H=0'),
- )
- # \PIPE\LANMAN NetShareGetInfo
- class SMBNetShareGetInfo(Structure):
- structure = (
- ('RAPOpcode','<H=0'),
- ('ParamDesc','z'),
- ('DataDesc','z'),
- ('ShareName','z'),
- ('InfoLevel','<H'),
- ('ReceiveBufferSize','<H'),
- )
- class SMBNetShareGetInfoResponse(Structure):
- structure = (
- ('Status','<H=0'),
- ('Convert','<H=0'),
- ('TotalBytesAvailable','<H'),
- )
- ############# Security Features
- class SecurityFeatures(Structure):
- structure = (
- ('Key','<L=0'),
- ('CID','<H=0'),
- ('SequenceNumber','<H=0'),
- )
- ############# SMB_COM_QUERY_INFORMATION2 (0x23)
- class SMBQueryInformation2_Parameters(Structure):
- structure = (
- ('Fid','<H'),
- )
- class SMBQueryInformation2Response_Parameters(Structure):
- structure = (
- ('CreateDate','<H'),
- ('CreationTime','<H'),
- ('LastAccessDate','<H'),
- ('LastAccessTime','<H'),
- ('LastWriteDate','<H'),
- ('LastWriteTime','<H'),
- ('FileDataSize','<L'),
- ('FileAllocationSize','<L'),
- ('FileAttributes','<L'),
- )
- ############# SMB_COM_SESSION_SETUP_ANDX (0x73)
- class SMBSessionSetupAndX_Parameters(SMBAndXCommand_Parameters):
- structure = (
- ('MaxBuffer','<H'),
- ('MaxMpxCount','<H'),
- ('VCNumber','<H'),
- ('SessionKey','<L'),
- ('AnsiPwdLength','<H'),
- ('UnicodePwdLength','<H'),
- ('_reserved','<L=0'),
- ('Capabilities','<L'),
- )
- class SMBSessionSetupAndX_Extended_Parameters(SMBAndXCommand_Parameters):
- structure = (
- ('MaxBufferSize','<H'),
- ('MaxMpxCount','<H'),
- ('VcNumber','<H'),
- ('SessionKey','<L'),
- ('SecurityBlobLength','<H'),
- ('Reserved','<L=0'),
- ('Capabilities','<L'),
- )
- class SMBSessionSetupAndX_Data(AsciiOrUnicodeStructure):
- AsciiStructure = (
- ('AnsiPwdLength','_-AnsiPwd','self["AnsiPwdLength"]'),
- ('UnicodePwdLength','_-UnicodePwd','self["UnicodePwdLength"]'),
- ('AnsiPwd',':=""'),
- ('UnicodePwd',':=""'),
- ('Account','z=""'),
- ('PrimaryDomain','z=""'),
- ('NativeOS','z=""'),
- ('NativeLanMan','z=""'),
- )
- UnicodeStructure = (
- ('AnsiPwdLength','_-AnsiPwd','self["AnsiPwdLength"]'),
- ('UnicodePwdLength','_-UnicodePwd','self["UnicodePwdLength"]'),
- ('AnsiPwd',':=""'),
- ('UnicodePwd',':=""'),
- ('Account','u=""'),
- ('PrimaryDomain','u=""'),
- ('NativeOS','u=""'),
- ('NativeLanMan','u=""'),
- )
- class SMBSessionSetupAndX_Extended_Data(AsciiOrUnicodeStructure):
- AsciiStructure = (
- ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'),
- ('SecurityBlob',':'),
- ('NativeOS','z=""'),
- ('NativeLanMan','z=""'),
- )
- UnicodeStructure = (
- ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'),
- ('SecurityBlob',':'),
- ('NativeOS','u=""'),
- ('NativeLanMan','u=""'),
- )
- class SMBSessionSetupAndXResponse_Parameters(SMBAndXCommand_Parameters):
- structure = (
- ('Action','<H'),
- )
- class SMBSessionSetupAndX_Extended_Response_Parameters(SMBAndXCommand_Parameters):
- structure = (
- ('Action','<H=0'),
- ('SecurityBlobLength','<H'),
- )
- class SMBSessionSetupAndXResponse_Data(AsciiOrUnicodeStructure):
- AsciiStructure = (
- ('NativeOS','z=""'),
- ('NativeLanMan','z=""'),
- ('PrimaryDomain','z=""'),
- )
- UnicodeStructure = (
- ('NativeOS','u=""'),
- ('NativeLanMan','u=""'),
- ('PrimaryDomain','u=""'),
- )
- class SMBSessionSetupAndX_Extended_Response_Data(AsciiOrUnicodeStructure):
- AsciiStructure = (
- ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'),
- ('SecurityBlob',':'),
- ('NativeOS','z=""'),
- ('NativeLanMan','z=""'),
- )
- UnicodeStructure = (
- ('SecurityBlobLength','_-SecurityBlob','self["SecurityBlobLength"]'),
- ('SecurityBlob',':'),
- ('NativeOS','u=""'),
- ('NativeLanMan','u=""'),
- )
- ############# SMB_COM_TREE_CONNECT (0x70)
- class SMBTreeConnect_Parameters(SMBCommand_Parameters):
- structure = (
- )
- class SMBTreeConnect_Data(SMBCommand_Parameters):
- structure = (
- ('PathFormat','"\x04'),
- ('Path','z'),
- ('PasswordFormat','"\x04'),
- ('Password','z'),
- ('ServiceFormat','"\x04'),
- ('Service','z'),
- )
- ############# SMB_COM_TREE_CONNECT_ANDX (0x75)
- class SMBTreeConnectAndX_Parameters(SMBAndXCommand_Parameters):
- structure = (
- ('Flags','<H=0'),
- ('PasswordLength','<H'),
- )
- class SMBTreeConnectAndXResponse_Parameters(SMBAndXCommand_Parameters):
- structure = (
- ('OptionalSupport','<H=0'),
- )
- class SMBTreeConnectAndXExtendedResponse_Parameters(SMBAndXCommand_Parameters):
- structure = (
- ('OptionalSupport','<H=1'),
- ('MaximalShareAccessRights','<L=0x1fffff'),
- ('GuestMaximalShareAccessRights','<L=0x1fffff'),
- )
- class SMBTreeConnectAndX_Data(AsciiOrUnicodeStructure):
- AsciiStructure = (
- ('_PasswordLength','_-Password','self["_PasswordLength"]'),
- ('Password',':'),
- ('Path','z'),
- ('Service','z'),
- )
- UnicodeStructure = (
- ('_PasswordLength','_-Password','self["_PasswordLength"] if self["_PasswordLength"] > 0 else 1'),
- ('Password',':'),
- ('Path','u'),
- ('Service','z'),
- )
- class SMBTreeConnectAndXResponse_Data(AsciiOrUnicodeStructure):
- AsciiStructure = (
- ('Service','z'),
- ('PadLen','_-Pad','self["PadLen"]'),
- ('Pad',':=""'),
- ('NativeFileSystem','z'),
- )
- UnicodeStructure = (
- ('Service','z'),
- ('PadLen','_-Pad','self["PadLen"]'),
- ('Pad',':=""'),
- ('NativeFileSystem','u'),
- )
- ############# SMB_COM_NT_CREATE_ANDX (0xA2)
- class SMBNtCreateAndX_Parameters(SMBAndXCommand_Parameters):
- structure = (
- ('_reserved', 'B=0'),
- ('FileNameLength','<H'), # NameLength
- ('CreateFlags','<L'), # Flags
- ('RootFid','<L=0'), # RootDirectoryFID
- ('AccessMask','<L'), # DesiredAccess
- ('AllocationSizeLo','<L=0'), # AllocationSize
- ('AllocationSizeHi','<L=0'),
- ('FileAttributes','<L=0'), # ExtFileAttributes
- ('ShareAccess','<L=3'), #
- ('Disposition','<L=1'), # CreateDisposition
- ('CreateOptions','<L'), # CreateOptions
- ('Impersonation','<L=2'),
- ('SecurityFlags','B=3'),
- )
- class SMBNtCreateAndXResponse_Parameters(SMBAndXCommand_Parameters):
- # 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?
- structure = (
- ('OplockLevel', 'B=0'),
- ('Fid','<H'),
- ('CreateAction','<L'),
- ('CreateTime','<q=0'),
- ('LastAccessTime','<q=0'),
- ('LastWriteTime','<q=0'),
- ('LastChangeTime','<q=0'),
- ('FileAttributes','<L=0x80'),
- ('AllocationSize','<q=0'),
- ('EndOfFile','<q=0'),
- ('FileType','<H=0'),
- ('IPCState','<H=0'),
- ('IsDirectory','B'),
- )
- class SMBNtCreateAndXExtendedResponse_Parameters(SMBAndXCommand_Parameters):
- # [MS-SMB] Extended response description
- structure = (
- ('OplockLevel', 'B=0'),
- ('Fid','<H'),
- ('CreateAction','<L'),
- ('CreateTime','<q=0'),
- ('LastAccessTime','<q=0'),
- ('LastWriteTime','<q=0'),
- ('LastChangeTime','<q=0'),
- ('FileAttributes','<L=0x80'),
- ('AllocationSize','<q=0'),
- ('EndOfFile','<q=0'),
- ('FileType','<H=0'),
- ('IPCState','<H=0'),
- ('IsDirectory','B'),
- ('VolumeGUID','16s'),
- ('FileIdLow','<L=0'),
- ('FileIdHigh','<L=0'),
- ('MaximalAccessRights','<L=0x12019b'),
- ('GuestMaximalAccessRights','<L=0x120089'),
- )
- class SMBNtCreateAndX_Data(AsciiOrUnicodeStructure):
- AsciiStructure = (
- ('FileName','z'),
- )
- UnicodeStructure = (
- ('Pad','B'),
- ('FileName','u'),
- )
- ############# SMB_COM_OPEN_ANDX (0xD2)
- class SMBOpenAndX_Parameters(SMBAndXCommand_Parameters):
- structure = (
- ('Flags','<H=0'),
- ('DesiredAccess','<H=0'),
- ('SearchAttributes','<H=0'),
- ('FileAttributes','<H=0'),
- ('CreationTime','<L=0'),
- ('OpenMode','<H=1'), # SMB_O_OPEN = 1
- ('AllocationSize','<L=0'),
- ('Reserved','8s=""'),
- )
- class SMBOpenAndX_Data(SMBNtCreateAndX_Data):
- pass
- class SMBOpenAndXResponse_Parameters(SMBAndXCommand_Parameters):
- structure = (
- ('Fid','<H=0'),
- ('FileAttributes','<H=0'),
- ('LastWriten','<L=0'),
- ('FileSize','<L=0'),
- ('GrantedAccess','<H=0'),
- ('FileType','<H=0'),
- ('IPCState','<H=0'),
- ('Action','<H=0'),
- ('ServerFid','<L=0'),
- ('_reserved','<H=0'),
- )
- ############# SMB_COM_WRITE (0x0B)
- class SMBWrite_Parameters(SMBCommand_Parameters):
- structure = (
- ('Fid','<H'),
- ('Count','<H'),
- ('Offset','<L'),
- ('Remaining','<H'),
- )
- class SMBWriteResponse_Parameters(SMBCommand_Parameters):
- structure = (
- ('Count','<H'),
- )
- class SMBWrite_Data(Structure):
- structure = (
- ('BufferFormat','<B=1'),
- ('DataLength','<H-Data'),
- ('Data',':'),
- )
- ############# SMB_COM_WRITE_ANDX (0x2F)
- class SMBWriteAndX_Parameters(SMBAndXCommand_Parameters):
- structure = (
- ('Fid','<H=0'),
- ('Offset','<L=0'),
- ('_reserved','<L=0xff'),
- ('WriteMode','<H=8'),
- ('Remaining','<H=0'),
- ('DataLength_Hi','<H=0'),
- ('DataLength','<H=0'),
- ('DataOffset','<H=0'),
- ('HighOffset','<L=0'),
- )
- class SMBWriteAndX_Data_Short(Structure):
- structure = (
- ('_PadLen','_-Pad','self["DataOffset"] - 59'),
- ('Pad',':'),
- #('Pad','<B=0'),
- ('DataLength','_-Data','self["DataLength"]'),
- ('Data',':'),
- )
- class SMBWriteAndX_Data(Structure):
- structure = (
- ('_PadLen','_-Pad','self["DataOffset"] - 63'),
- ('Pad',':'),
- #('Pad','<B=0'),
- ('DataLength','_-Data','self["DataLength"]'),
- ('Data',':'),
- )
- class SMBWriteAndX_Parameters_Short(SMBAndXCommand_Parameters):
- structure = (
- ('Fid','<H'),
- ('Offset','<L'),
- ('_reserved','<L=0xff'),
- ('WriteMode','<H=8'),
- ('Remaining','<H'),
- ('DataLength_Hi','<H=0'),
- ('DataLength','<H'),
- ('DataOffset','<H=0'),
- )
- class SMBWriteAndXResponse_Parameters(SMBAndXCommand_Parameters):
- structure = (
- ('Count','<H'),
- ('Available','<H'),
- ('Reserved','<L=0'),
- )
- ############# SMB_COM_WRITE_RAW (0x1D)
- class SMBWriteRaw_Parameters(SMBCommand_Parameters):
- structure = (
- ('Fid','<H'),
- ('Count','<H'),
- ('_reserved','<H=0'),
- ('Offset','<L'),
- ('Timeout','<L=0'),
- ('WriteMode','<H=0'),
- ('_reserved2','<L=0'),
- ('DataLength','<H'),
- ('DataOffset','<H=0'),
- )
- ############# SMB_COM_READ (0x0A)
- class SMBRead_Parameters(SMBCommand_Parameters):
- structure = (
- ('Fid','<H'),
- ('Count','<H'),
- ('Offset','<L'),
- ('Remaining','<H=Count'),
- )
- class SMBReadResponse_Parameters(Structure):
- structure = (
- ('Count','<H=0'),
- ('_reserved','8s=""'),
- )
- class SMBReadResponse_Data(Structure):
- structure = (
- ('BufferFormat','<B=0x1'),
- ('DataLength','<H-Data'),
- ('Data',':'),
- )
- ############# SMB_COM_READ_RAW (0x1A)
- class SMBReadRaw_Parameters(SMBCommand_Parameters):
- structure = (
- ('Fid','<H'),
- ('Offset','<L'),
- ('MaxCount','<H'),
- ('MinCount','<H=MaxCount'),
- ('Timeout','<L=0'),
- ('_reserved','<H=0'),
- )
- ############# SMB_COM_NT_TRANSACT (0xA0)
- class SMBNTTransaction_Parameters(SMBCommand_Parameters):
- structure = (
- ('MaxSetupCount','<B=0'),
- ('Reserved1','<H=0'),
- ('TotalParameterCount','<L'),
- ('TotalDataCount','<L'),
- ('MaxParameterCount','<L=1024'),
- ('MaxDataCount','<L=65504'),
- ('ParameterCount','<L'),
- ('ParameterOffset','<L'),
- ('DataCount','<L'),
- ('DataOffset','<L'),
- ('SetupCount','<B=len(Setup)/2'),
- ('Function','<H=0'),
- ('SetupLength','_-Setup','SetupCount*2'),
- ('Setup',':'),
- )
- class SMBNTTransactionResponse_Parameters(SMBCommand_Parameters):
- structure = (
- ('Reserved1','3s=""'),
- ('TotalParameterCount','<L'),
- ('TotalDataCount','<L'),
- ('ParameterCount','<L'),
- ('ParameterOffset','<L'),
- ('ParameterDisplacement','<L=0'),
- ('DataCount','<L'),
- ('DataOffset','<L'),
- ('DataDisplacement','<L=0'),
- ('SetupCount','<B=0'),
- ('SetupLength','_-Setup','SetupCount*2'),
- ('Setup',':'),
- )
- class SMBNTTransaction_Data(Structure):
- structure = (
- ('Pad1Length','_-Pad1','self["Pad1Length"]'),
- ('Pad1',':'),
- ('NT_Trans_ParametersLength','_-NT_Trans_Parameters','self["NT_Trans_ParametersLength"]'),
- ('NT_Trans_Parameters',':'),
- ('Pad2Length','_-Pad2','self["Pad2Length"]'),
- ('Pad2',':'),
- ('NT_Trans_DataLength','_-NT_Trans_Data','self["NT_Trans_DataLength"]'),
- ('NT_Trans_Data',':'),
- )
- class SMBNTTransactionResponse_Data(Structure):
- structure = (
- ('Pad1Length','_-Pad1','self["Pad1Length"]'),
- ('Pad1',':'),
- ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'),
- ('Trans_Parameters',':'),
- ('Pad2Length','_-Pad2','self["Pad2Length"]'),
- ('Pad2',':'),
- ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'),
- ('Trans_Data',':'),
- )
- ############# SMB_COM_TRANSACTION2_SECONDARY (0x33)
- class SMBTransaction2Secondary_Parameters(SMBCommand_Parameters):
- structure = (
- ('TotalParameterCount','<H'),
- ('TotalDataCount','<H'),
- ('ParameterCount','<H'),
- ('ParameterOffset','<H'),
- ('DataCount','<H'),
- ('DataOffset','<H'),
- ('DataDisplacement','<H=0'),
- ('FID','<H'),
- )
- class SMBTransaction2Secondary_Data(Structure):
- structure = (
- ('Pad1Length','_-Pad1','self["Pad1Length"]'),
- ('Pad1',':'),
- ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'),
- ('Trans_Parameters',':'),
- ('Pad2Length','_-Pad2','self["Pad2Length"]'),
- ('Pad2',':'),
- ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'),
- ('Trans_Data',':'),
- )
- ############# SMB_COM_TRANSACTION2 (0x32)
- class SMBTransaction2_Parameters(SMBCommand_Parameters):
- structure = (
- ('TotalParameterCount','<H'),
- ('TotalDataCount','<H'),
- ('MaxParameterCount','<H=1024'),
- ('MaxDataCount','<H=65504'),
- ('MaxSetupCount','<B=0'),
- ('Reserved1','<B=0'),
- ('Flags','<H=0'),
- ('Timeout','<L=0'),
- ('Reserved2','<H=0'),
- ('ParameterCount','<H'),
- ('ParameterOffset','<H'),
- ('DataCount','<H'),
- ('DataOffset','<H'),
- ('SetupCount','<B=len(Setup)/2'),
- ('Reserved3','<B=0'),
- ('SetupLength','_-Setup','SetupCount*2'),
- ('Setup',':'),
- )
- class SMBTransaction2Response_Parameters(SMBCommand_Parameters):
- structure = (
- ('TotalParameterCount','<H'),
- ('TotalDataCount','<H'),
- ('Reserved1','<H=0'),
- ('ParameterCount','<H'),
- ('ParameterOffset','<H'),
- ('ParameterDisplacement','<H=0'),
- ('DataCount','<H'),
- ('DataOffset','<H'),
- ('DataDisplacement','<H=0'),
- ('SetupCount','<B=0'),
- ('Reserved2','<B=0'),
- ('SetupLength','_-Setup','SetupCount*2'),
- ('Setup',':'),
- )
- class SMBTransaction2_Data(Structure):
- structure = (
- # ('NameLength','_-Name','1'),
- # ('Name',':'),
- ('Pad1Length','_-Pad1','self["Pad1Length"]'),
- ('Pad1',':'),
- ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'),
- ('Trans_Parameters',':'),
- ('Pad2Length','_-Pad2','self["Pad2Length"]'),
- ('Pad2',':'),
- ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'),
- ('Trans_Data',':'),
- )
- class SMBTransaction2Response_Data(Structure):
- structure = (
- ('Pad1Length','_-Pad1','self["Pad1Length"]'),
- ('Pad1',':'),
- ('Trans_ParametersLength','_-Trans_Parameters','self["Trans_ParametersLength"]'),
- ('Trans_Parameters',':'),
- ('Pad2Length','_-Pad2','self["Pad2Length"]'),
- ('Pad2',':'),
- ('Trans_DataLength','_-Trans_Data','self["Trans_DataLength"]'),
- ('Trans_Data',':'),
- )
- ############# SMB_COM_QUERY_INFORMATION (0x08)
- class SMBQueryInformation_Data(AsciiOrUnicodeStructure):
- AsciiStructure = (
- ('BufferFormat','B=4'),
- ('FileName','z'),
- )
- UnicodeStructure = (
- ('BufferFormat','B=4'),
- ('FileName','u'),
- )
- class SMBQueryInformationResponse_Parameters(Structure):
- structure = (
- ('FileAttributes','<H'),
- ('LastWriteTime','<L'),
- ('FileSize','<L'),
- ('Reserved','"0123456789'),
- )
- ############# SMB_COM_TRANSACTION (0x25)
- class SMBTransaction_Parameters(SMBCommand_Parameters):
- structure = (
- ('TotalParameterCount','<H'),
- ('TotalDataCount','<H'),
- ('MaxParameterCount','<H=1024'),
- ('MaxDataCount','<H=65504'),
- ('MaxSetupCount','<B=0'),
- ('Reserved1','<B=0'),
- ('Flags','<H=0'),
- ('Timeout','<L=0'),
- ('Reserved2','<H=0'),
- ('ParameterCount','<H'),
- ('ParameterOffset','<H'),
- ('DataCount','<H'),
- ('DataOffset','<H'),
- ('SetupCount','<B=len(Setup)/2'),
- ('Reserved3','<B=0'),
- ('SetupLength','_-Setup','SetupCount*2'),
- ('Setup',':'),
- )
- class SMBTransactionResponse_Parameters(SMBCommand_Parameters):
- structure = (
- ('TotalParameterCount','<H'),
- ('TotalDataCount','<H'),
- ('Reserved1','<H=0'),
- ('ParameterCount','<H'),
- ('ParameterOffset','<H'),
- ('ParameterDisplacement','<H=0'),
- ('DataCount','<H'),
- ('DataOffset','<H'),
- ('DataDisplacement','<H=0'),
- ('SetupCount','<B'),
- ('Reserved2','<B=0'),
- ('SetupLength','_-Setup','SetupCount*2'),
- ('Setup',':'),
- )
- # TODO: We should merge these both. But this will require fixing
- # the instances where this structure is used on the client side
- class SMBTransaction_SData(AsciiOrUnicodeStructure):
- AsciiStructure = (
- ('Name','z'),
- ('Trans_ParametersLength','_-Trans_Parameters'),
- ('Trans_Parameters',':'),
- ('Trans_DataLength','_-Trans_Data'),
- ('Trans_Data',':'),
- )
- UnicodeStructure = (
- ('Pad','B'),
- ('Name','u'),
- ('Trans_ParametersLength','_-Trans_Parameters'),
- ('Trans_Parameters',':'),
- ('Trans_DataLength','_-Trans_Data'),
- ('Trans_Data',':'),
- )
- class SMBTransaction_Data(Structure):
- structure = (
- ('NameLength','_-Name'),
- ('Name',':'),
- ('Trans_ParametersLength','_-Trans_Parameters'),
- ('Trans_Parameters',':'),
- ('Trans_DataLength','_-Trans_Data'),
- ('Trans_Data',':'),
- )
- class SMBTransactionResponse_Data(Structure):
- structure = (
- ('Trans_ParametersLength','_-Trans_Parameters'),
- ('Trans_Parameters',':'),
- ('Trans_DataLength','_-Trans_Data'),
- ('Trans_Data',':'),
- )
- ############# SMB_COM_READ_ANDX (0x2E)
- class SMBReadAndX_Parameters(SMBAndXCommand_Parameters):
- structure = (
- ('Fid','<H'),
- ('Offset','<L'),
- ('MaxCount','<H'),
- ('MinCount','<H=MaxCount'),
- ('_reserved','<L=0x0'),
- ('Remaining','<H=MaxCount'),
- ('HighOffset','<L=0'),
- )
- class SMBReadAndX_Parameters2(SMBAndXCommand_Parameters):
- structure = (
- ('Fid','<H'),
- ('Offset','<L'),
- ('MaxCount','<H'),
- ('MinCount','<H=MaxCount'),
- ('_reserved','<L=0xffffffff'),
- ('Remaining','<H=MaxCount'),
- )
- class SMBReadAndXResponse_Parameters(SMBAndXCommand_Parameters):
- structure = (
- ('Remaining','<H=0'),
- ('DataMode','<H=0'),
- ('_reserved','<H=0'),
- ('DataCount','<H'),
- ('DataOffset','<H'),
- ('DataCount_Hi','<L'),
- ('_reserved2','6s=""'),
- )
- ############# SMB_COM_ECHO (0x2B)
- class SMBEcho_Data(Structure):
- structure = (
- ('Data',':'),
- )
- class SMBEcho_Parameters(Structure):
- structure = (
- ('EchoCount','<H'),
- )
- class SMBEchoResponse_Data(Structure):
- structure = (
- ('Data',':'),
- )
- class SMBEchoResponse_Parameters(Structure):
- structure = (
- ('SequenceNumber','<H=1'),
- )
- ############# SMB_COM_QUERY_INFORMATION_DISK (0x80)
- class SMBQueryInformationDiskResponse_Parameters(Structure):
- structure = (
- ('TotalUnits','<H'),
- ('BlocksPerUnit','<H'),
- ('BlockSize','<H'),
- ('FreeUnits','<H'),
- ('Reserved','<H=0'),
- )
- ############# SMB_COM_LOGOFF_ANDX (0x74)
- class SMBLogOffAndX(SMBAndXCommand_Parameters):
- strucure = ()
- ############# SMB_COM_CLOSE (0x04)
- class SMBClose_Parameters(SMBCommand_Parameters):
- structure = (
- ('FID','<H'),
- ('Time','<L=0'),
- )
- ############# SMB_COM_FLUSH (0x05)
- class SMBFlush_Parameters(SMBCommand_Parameters):
- structure = (
- ('FID','<H'),
- )
- ############# SMB_COM_CREATE_DIRECTORY (0x00)
- class SMBCreateDirectory_Data(AsciiOrUnicodeStructure):
- AsciiStructure = (
- ('BufferFormat','<B=4'),
- ('DirectoryName','z'),
- )
- UnicodeStructure = (
- ('BufferFormat','<B=4'),
- ('DirectoryName','u'),
- )
- ############# SMB_COM_DELETE (0x06)
- class SMBDelete_Data(AsciiOrUnicodeStructure):
- AsciiStructure = (
- ('BufferFormat','<B=4'),
- ('FileName','z'),
- )
- UnicodeStructure = (
- ('BufferFormat','<B=4'),
- ('FileName','u'),
- )
- class SMBDelete_Parameters(Structure):
- structure = (
- ('SearchAttributes','<H'),
- )
- ############# SMB_COM_DELETE_DIRECTORY (0x01)
- class SMBDeleteDirectory_Data(AsciiOrUnicodeStructure):
- AsciiStructure = (
- ('BufferFormat','<B=4'),
- ('DirectoryName','z'),
- )
- UnicodeStructure = (
- ('BufferFormat','<B=4'),
- ('DirectoryName','u'),
- )
- ############# SMB_COM_CHECK_DIRECTORY (0x10)
- class SMBCheckDirectory_Data(AsciiOrUnicodeStructure):
- AsciiStructure = (
- ('BufferFormat','<B=4'),
- ('DirectoryName','z'),
- )
- UnicodeStructure = (
- ('BufferFormat','<B=4'),
- ('DirectoryName','u'),
- )
- ############# SMB_COM_RENAME (0x07)
- class SMBRename_Parameters(SMBCommand_Parameters):
- structure = (
- ('SearchAttributes','<H'),
- )
- class SMBRename_Data(AsciiOrUnicodeStructure):
- AsciiStructure = (
- ('BufferFormat1','<B=4'),
- ('OldFileName','z'),
- ('BufferFormat2','<B=4'),
- ('NewFileName','z'),
- )
- UnicodeStructure = (
- ('BufferFormat1','<B=4'),
- ('OldFileName','u'),
- ('BufferFormat2','<B=4'),
- ('Pad','B=0'),
- ('NewFileName','u'),
- )
- ############# SMB_COM_OPEN (0x02)
- class SMBOpen_Parameters(SMBCommand_Parameters):
- structure = (
- ('DesiredAccess','<H=0'),
- ('SearchAttributes','<H=0'),
- )
- class SMBOpen_Data(AsciiOrUnicodeStructure):
- AsciiStructure = (
- ('FileNameFormat','"\x04'),
- ('FileName','z'),
- )
- UnicodeStructure = (
- ('FileNameFormat','"\x04'),
- ('FileName','z'),
- )
- class SMBOpenResponse_Parameters(SMBCommand_Parameters):
- structure = (
- ('Fid','<H=0'),
- ('FileAttributes','<H=0'),
- ('LastWriten','<L=0'),
- ('FileSize','<L=0'),
- ('GrantedAccess','<H=0'),
- )
- ############# EXTENDED SECURITY CLASSES
- class SMBExtended_Security_Parameters(Structure):
- structure = (
- ('DialectIndex','<H'),
- ('SecurityMode','<B'),
- ('MaxMpxCount','<H'),
- ('MaxNumberVcs','<H'),
- ('MaxBufferSize','<L'),
- ('MaxRawSize','<L'),
- ('SessionKey','<L'),
- ('Capabilities','<L'),
- ('LowDateTime','<L'),
- ('HighDateTime','<L'),
- ('ServerTimeZone','<H'),
- ('ChallengeLength','<B'),
- )
- class SMBExtended_Security_Data(Structure):
- structure = (
- ('ServerGUID','16s'),
- ('SecurityBlob',':'),
- )
- class SMBNTLMDialect_Parameters(Structure):
- structure = (
- ('DialectIndex','<H'),
- ('SecurityMode','<B'),
- ('MaxMpxCount','<H'),
- ('MaxNumberVcs','<H'),
- ('MaxBufferSize','<L'),
- ('MaxRawSize','<L'),
- ('SessionKey','<L'),
- ('Capabilities','<L'),
- ('LowDateTime','<L'),
- ('HighDateTime','<L'),
- ('ServerTimeZone','<H'),
- ('ChallengeLength','<B'),
- )
- class SMBNTLMDialect_Data(Structure):
- structure = (
- ('ChallengeLength','_-Challenge','self["ChallengeLength"]'),
- ('Challenge',':'),
- ('Payload',':'),
- # 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.
- ('DomainName','_'),
- ('ServerName','_'),
- )
- def __init__(self,data = None, alignment = 0):
- Structure.__init__(self,data,alignment)
- #self['ChallengeLength']=8
- def fromString(self,data):
- Structure.fromString(self,data)
- self['DomainName'] = ''
- self['ServerName'] = ''
- class SMB:
- # SMB Command Codes
- SMB_COM_CREATE_DIRECTORY = 0x00
- SMB_COM_DELETE_DIRECTORY = 0x01
- SMB_COM_OPEN = 0x02
- SMB_COM_CREATE = 0x03
- SMB_COM_CLOSE = 0x04
- SMB_COM_FLUSH = 0x05
- SMB_COM_DELETE = 0x06
- SMB_COM_RENAME = 0x07
- SMB_COM_QUERY_INFORMATION = 0x08
- SMB_COM_SET_INFORMATION = 0x09
- SMB_COM_READ = 0x0A
- SMB_COM_WRITE = 0x0B
- SMB_COM_LOCK_BYTE_RANGE = 0x0C
- SMB_COM_UNLOCK_BYTE_RANGE = 0x0D
- SMB_COM_CREATE_TEMPORARY = 0x0E
- SMB_COM_CREATE_NEW = 0x0F
- SMB_COM_CHECK_DIRECTORY = 0x10
- SMB_COM_PROCESS_EXIT = 0x11
- SMB_COM_SEEK = 0x12
- SMB_COM_LOCK_AND_READ = 0x13
- SMB_COM_WRITE_AND_UNLOCK = 0x14
- SMB_COM_READ_RAW = 0x1A
- SMB_COM_READ_MPX = 0x1B
- SMB_COM_READ_MPX_SECONDARY = 0x1C
- SMB_COM_WRITE_RAW = 0x1D
- SMB_COM_WRITE_MPX = 0x1E
- SMB_COM_WRITE_MPX_SECONDARY = 0x1F
- SMB_COM_WRITE_COMPLETE = 0x20
- SMB_COM_QUERY_SERVER = 0x21
- SMB_COM_SET_INFORMATION2 = 0x22
- SMB_COM_QUERY_INFORMATION2 = 0x23
- SMB_COM_LOCKING_ANDX = 0x24
- SMB_COM_TRANSACTION = 0x25
- SMB_COM_TRANSACTION_SECONDARY = 0x26
- SMB_COM_IOCTL = 0x27
- SMB_COM_IOCTL_SECONDARY = 0x28
- SMB_COM_COPY = 0x29
- SMB_COM_MOVE = 0x2A
- SMB_COM_ECHO = 0x2B
- SMB_COM_WRITE_AND_CLOSE = 0x2C
- SMB_COM_OPEN_ANDX = 0x2D
- SMB_COM_READ_ANDX = 0x2E
- SMB_COM_WRITE_ANDX = 0x2F
- SMB_COM_NEW_FILE_SIZE = 0x30
- SMB_COM_CLOSE_AND_TREE_DISC = 0x31
- SMB_COM_TRANSACTION2 = 0x32
- SMB_COM_TRANSACTION2_SECONDARY = 0x33
- SMB_COM_FIND_CLOSE2 = 0x34
- SMB_COM_FIND_NOTIFY_CLOSE = 0x35
- # Used by Xenix/Unix 0x60 - 0x6E
- SMB_COM_TREE_CONNECT = 0x70
- SMB_COM_TREE_DISCONNECT = 0x71
- SMB_COM_NEGOTIATE = 0x72
- SMB_COM_SESSION_SETUP_ANDX = 0x73
- SMB_COM_LOGOFF_ANDX = 0x74
- SMB_COM_TREE_CONNECT_ANDX = 0x75
- SMB_COM_QUERY_INFORMATION_DISK = 0x80
- SMB_COM_SEARCH = 0x81
- SMB_COM_FIND = 0x82
- SMB_COM_FIND_UNIQUE = 0x83
- SMB_COM_FIND_CLOSE = 0x84
- SMB_COM_NT_TRANSACT = 0xA0
- SMB_COM_NT_TRANSACT_SECONDARY = 0xA1
- SMB_COM_NT_CREATE_ANDX = 0xA2
- SMB_COM_NT_CANCEL = 0xA4
- SMB_COM_NT_RENAME = 0xA5
- SMB_COM_OPEN_PRINT_FILE = 0xC0
- SMB_COM_WRITE_PRINT_FILE = 0xC1
- SMB_COM_CLOSE_PRINT_FILE = 0xC2
- SMB_COM_GET_PRINT_QUEUE = 0xC3
- SMB_COM_READ_BULK = 0xD8
- SMB_COM_WRITE_BULK = 0xD9
- SMB_COM_WRITE_BULK_DATA = 0xDA
- # TRANSACT codes
- TRANS_TRANSACT_NMPIPE = 0x26
- # TRANSACT2 codes
- TRANS2_FIND_FIRST2 = 0x0001
- TRANS2_FIND_NEXT2 = 0x0002
- TRANS2_QUERY_FS_INFORMATION = 0x0003
- TRANS2_QUERY_PATH_INFORMATION = 0x0005
- TRANS2_QUERY_FILE_INFORMATION = 0x0007
- TRANS2_SET_FILE_INFORMATION = 0x0008
- TRANS2_SET_PATH_INFORMATION = 0x0006
- # Security Share Mode (Used internally by SMB class)
- SECURITY_SHARE_MASK = 0x01
- SECURITY_SHARE_SHARE = 0x00
- SECURITY_SHARE_USER = 0x01
- SECURITY_SIGNATURES_ENABLED = 0X04
- SECURITY_SIGNATURES_REQUIRED = 0X08
- # Security Auth Mode (Used internally by SMB class)
- SECURITY_AUTH_MASK = 0x02
- SECURITY_AUTH_ENCRYPTED = 0x02
- SECURITY_AUTH_PLAINTEXT = 0x00
- # Raw Mode Mask (Used internally by SMB class. Good for dialect up to and including LANMAN2.1)
- RAW_READ_MASK = 0x01
- RAW_WRITE_MASK = 0x02
- # Capabilities Mask (Used internally by SMB class. Good for dialect NT LM 0.12)
- CAP_RAW_MODE = 0x00000001
- CAP_MPX_MODE = 0x0002
- CAP_UNICODE = 0x0004
- CAP_LARGE_FILES = 0x0008
- CAP_EXTENDED_SECURITY = 0x80000000
- CAP_USE_NT_ERRORS = 0x40
- CAP_NT_SMBS = 0x10
- CAP_LARGE_READX = 0x00004000
- CAP_LARGE_WRITEX = 0x00008000
- CAP_RPC_REMOTE_APIS = 0x20
- # Flags1 Mask
- FLAGS1_LOCK_AND_READ_OK = 0x01
- FLAGS1_PATHCASELESS = 0x08
- FLAGS1_CANONICALIZED_PATHS = 0x10
- FLAGS1_REPLY = 0x80
- # Flags2 Mask
- FLAGS2_LONG_NAMES = 0x0001
- FLAGS2_EAS = 0x0002
- FLAGS2_SMB_SECURITY_SIGNATURE = 0x0004
- FLAGS2_IS_LONG_NAME = 0x0040
- FLAGS2_DFS = 0x1000
- FLAGS2_PAGING_IO = 0x2000
- FLAGS2_NT_STATUS = 0x4000
- FLAGS2_UNICODE = 0x8000
- FLAGS2_COMPRESSED = 0x0008
- FLAGS2_SMB_SECURITY_SIGNATURE_REQUIRED = 0x0010
- FLAGS2_EXTENDED_SECURITY = 0x0800
- # Dialect's Security Mode flags
- NEGOTIATE_USER_SECURITY = 0x01
- NEGOTIATE_ENCRYPT_PASSWORDS = 0x02
- NEGOTIATE_SECURITY_SIGNATURE_ENABLE = 0x04
- NEGOTIATE_SECURITY_SIGNATURE_REQUIRED = 0x08
- # Tree Connect AndX Response optionalSuppor flags
- SMB_SUPPORT_SEARCH_BITS = 0x01
- SMB_SHARE_IS_IN_DFS = 0x02
- 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):
- # The uid attribute will be set when the client calls the login() method
- self._uid = 0
- self.__server_name = ''
- self.__server_os = ''
- self.__server_os_major = None
- self.__server_os_minor = None
- self.__server_os_build = None
- self.__server_lanman = ''
- self.__server_domain = ''
- self.__server_dns_domain_name = ''
- self.__remote_name = string.upper(remote_name)
- self.__remote_host = remote_host
- self.__isNTLMv2 = True
- self._dialects_parameters = None
- self._dialects_data = None
- # Credentials
- self.__userName = ''
- self.__password = ''
- self.__domain = ''
- self.__lmhash = ''
- self.__nthash = ''
- self.__aesKey = ''
- self.__kdc = ''
- self.__TGT = None
- self.__TGS = None
- # Negotiate Protocol Result, used everywhere
- # Could be extended or not, flags should be checked before
- self._dialect_data = 0
- self._dialect_parameters = 0
- self._action = 0
- self._sess = None
- self.encrypt_passwords = True
- self.tid = 0
- self.fid = 0
- # Signing stuff
- self._SignSequenceNumber = 0
- self._SigningSessionKey = ''
- self._SigningChallengeResponse = ''
- self._SignatureEnabled = False
- self._SignatureVerificationEnabled = False
- self._SignatureRequired = False
- # Base flags (default flags, can be overriden using set_flags())
- self.__flags1 = SMB.FLAGS1_PATHCASELESS | SMB.FLAGS1_CANONICALIZED_PATHS
- self.__flags2 = SMB.FLAGS2_EXTENDED_SECURITY | SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_LONG_NAMES
- if timeout is None:
- self.__timeout = 60
- else:
- self.__timeout = timeout
- # If port 445 and the name sent is *SMBSERVER we're setting the name to the IP.
- # This is to help some old applications still believing
- # *SMSBSERVER will work against modern OSes. If port is NETBIOS_SESSION_PORT the user better
- # know about *SMBSERVER's limitations
- if sess_port == 445 and remote_name == '*SMBSERVER':
- self.__remote_name = remote_host
- if session is None:
- if not my_name:
- my_name = socket.gethostname()
- i = string.find(my_name, '.')
- if i > -1:
- my_name = my_name[:i]
- if UDP:
- self._sess = nmb.NetBIOSUDPSession(my_name, remote_name, remote_host, host_type, sess_port, self.__timeout)
- else:
- self._sess = nmb.NetBIOSTCPSession(my_name, remote_name, remote_host, host_type, sess_port, self.__timeout)
- # Initialize session values (_dialect_data and _dialect_parameters)
- self.neg_session()
- # Call login() without any authentication information to
- # setup a session if the remote server
- # is in share mode.
- if (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_SHARE:
- self.login('', '')
- else:
- self._sess = session
- self.neg_session(negPacket = negPacket)
- # Call login() without any authentication information to
- # setup a session if the remote server
- # is in share mode.
- if (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_SHARE:
- self.login('', '')
- @staticmethod
- def ntlm_supported():
- return False
- def get_remote_name(self):
- return self.__remote_name
- def get_remote_host(self):
- return self.__remote_host
- def get_flags(self):
- return self.__flags1, self.__flags2
- def set_flags(self, flags1=None, flags2=None):
- if flags1 is not None:
- self.__flags1 = flags1
- if flags2 is not None:
- self.__flags2 = flags2
- def set_timeout(self, timeout):
- prev_timeout = self.__timeout
- self.__timeout = timeout
- return prev_timeout
- def get_timeout(self):
- return self.__timeout
- @contextmanager
- def use_timeout(self, timeout):
- prev_timeout = self.set_timeout(timeout)
- try:
- yield
- finally:
- self.set_timeout(prev_timeout)
- def get_session(self):
- return self._sess
- def get_tid(self):
- return self.tid
- def get_fid(self):
- return self.fid
- def isGuestSession(self):
- return self._action & SMB_SETUP_GUEST
- def doesSupportNTLMv2(self):
- return self.__isNTLMv2
- def __del__(self):
- if self._sess:
- self._sess.close()
- def recvSMB(self):
- r = self._sess.recv_packet(self.__timeout)
- return NewSMBPacket(data = r.get_trailer())
- @staticmethod
- def __decode_trans(params, data):
- totparamcnt, totdatacnt, _, paramcnt, paramoffset, paramds, datacnt, dataoffset, datads, setupcnt = unpack('<HHHHHHHHHB', params[:19])
- if paramcnt + paramds < totparamcnt or datacnt + datads < totdatacnt:
- has_more = 1
- else:
- has_more = 0
- paramoffset = paramoffset - 55 - setupcnt * 2
- dataoffset = dataoffset - 55 - setupcnt * 2
- return has_more, params[20:20 + setupcnt * 2], data[paramoffset:paramoffset + paramcnt], data[dataoffset:dataoffset + datacnt]
- # TODO: Move this to NewSMBPacket, it belongs there
- def signSMB(self, packet, signingSessionKey, signingChallengeResponse):
- # This logic MUST be applied for messages sent in response to any of the higher-layer actions and in
- # compliance with the message sequencing rules.
- # * The client or server that sends the message MUST provide the 32-bit sequence number for this
- # message, as specified in sections 3.2.4.1 and 3.3.4.1.
- # * The SMB_FLAGS2_SMB_SECURITY_SIGNATURE flag in the header MUST be set.
- # * To generate the signature, a 32-bit sequence number is copied into the
- # least significant 32 bits of the SecuritySignature field and the remaining
- # 4 bytes are set to 0x00.
- # * The MD5 algorithm, as specified in [RFC1321], MUST be used to generate a hash of the SMB
- # message from the start of the SMB Header, which is defined as follows.
- # CALL MD5Init( md5context )
- # CALL MD5Update( md5context, Connection.SigningSessionKey )
- # CALL MD5Update( md5context, Connection.SigningChallengeResponse )
- # CALL MD5Update( md5context, SMB message )
- # CALL MD5Final( digest, md5context )
- # SET signature TO the first 8 bytes of the digest
- # The resulting 8-byte signature MUST be copied into the SecuritySignature field of the SMB Header,
- # after which the message can be transmitted.
- #print "seq(%d) signingSessionKey %r, signingChallengeResponse %r" % (self._SignSequenceNumber, signingSessionKey, signingChallengeResponse)
- packet['SecurityFeatures'] = pack('<q',self._SignSequenceNumber)
- # Sign with the sequence
- m = hashlib.md5()
- m.update( signingSessionKey )
- m.update( signingChallengeResponse )
- m.update( str(packet) )
- # Replace sequence with acual hash
- packet['SecurityFeatures'] = m.digest()[:8]
- if self._SignatureVerificationEnabled:
- self._SignSequenceNumber +=1
- else:
- self._SignSequenceNumber +=2
- def checkSignSMB(self, packet, signingSessionKey, signingChallengeResponse):
- # Let's check
- signature = packet['SecurityFeatures']
- #print "Signature received: %r " % signature
- self.signSMB(packet, signingSessionKey, signingChallengeResponse)
- #print "Signature calculated: %r" % packet['SecurityFeatures']
- if self._SignatureVerificationEnabled is not True:
- self._SignSequenceNumber -= 1
- return packet['SecurityFeatures'] == signature
- def sendSMB(self,smb):
- smb['Uid'] = self._uid
- #At least on AIX, PIDs can exceed 16 bits, so we mask them out
- smb['Pid'] = (os.getpid() & 0xFFFF)
- # set flags
- smb['Flags1'] |= self.__flags1
- smb['Flags2'] |= self.__flags2
- if self._SignatureEnabled:
- smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE
- self.signSMB(smb, self._SigningSessionKey, self._SigningChallengeResponse)
- self._sess.send_packet(str(smb))
- @staticmethod
- def isValidAnswer(s, cmd):
- while 1:
- if s.rawData():
- if s.get_command() == cmd:
- if s.get_error_class() == 0x00 and s.get_error_code() == 0x00:
- return 1
- else:
- raise SessionError, ( "SMB Library Error", s.get_error_class()+ (s.get_reserved() << 8), s.get_error_code() , s.get_flags2() & SMB.FLAGS2_NT_STATUS )
- else:
- break
- return 0
- def neg_session(self, extended_security = True, negPacket = None):
- def parsePacket(smb):
- if smb.isValidAnswer(SMB.SMB_COM_NEGOTIATE):
- sessionResponse = SMBCommand(smb['Data'][0])
- self._dialects_parameters = SMBNTLMDialect_Parameters(sessionResponse['Parameters'])
- self._dialects_data = SMBNTLMDialect_Data()
- self._dialects_data['ChallengeLength'] = self._dialects_parameters['ChallengeLength']
- self._dialects_data.fromString(sessionResponse['Data'])
- if self._dialects_parameters['Capabilities'] & SMB.CAP_EXTENDED_SECURITY:
- # Whether we choose it or it is enforced by the server, we go for extended security
- self._dialects_parameters = SMBExtended_Security_Parameters(sessionResponse['Parameters'])
- self._dialects_data = SMBExtended_Security_Data(sessionResponse['Data'])
- # Let's setup some variable for later use
- if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED:
- self._SignatureRequired = True
- # Interestingly, the security Blob might be missing sometimes.
- #spnego = SPNEGO_NegTokenInit(self._dialects_data['SecurityBlob'])
- #for i in spnego['MechTypes']:
- # print "Mech Found: %s" % MechTypes[i]
- return 1
- # If not, let's try the old way
- else:
- if self._dialects_data['ServerName'] is not None:
- self.__server_name = self._dialects_data['ServerName']
- if self._dialects_parameters['DialectIndex'] == 0xffff:
- raise UnsupportedFeature,"Remote server does not know NT LM 0.12"
- return 1
- else:
- return 0
- if negPacket is None:
- smb = NewSMBPacket()
- negSession = SMBCommand(SMB.SMB_COM_NEGOTIATE)
- flags2 = self.get_flags()[1]
- if extended_security is True:
- self.set_flags(flags2=flags2|SMB.FLAGS2_EXTENDED_SECURITY)
- else:
- self.set_flags(flags2=flags2 & (~SMB.FLAGS2_EXTENDED_SECURITY))
- negSession['Data'] = '\x02NT LM 0.12\x00'
- smb.addCommand(negSession)
- self.sendSMB(smb)
- while 1:
- smb = self.recvSMB()
- return parsePacket(smb)
- else:
- return parsePacket( NewSMBPacket( data = negPacket))
- def tree_connect(self, path, password = '', service = SERVICE_ANY):
- 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")
- # return 0x800
- if password:
- # Password is only encrypted if the server passed us an "encryption" during protocol dialect
- if self._dialects_parameters['ChallengeLength'] > 0:
- # this code is untested
- password = self.get_ntlmv1_response(ntlm.compute_lmhash(password))
- if not unicode_support:
- if unicode_convert:
- path = str(path)
- else:
- raise Exception('SMB: Can\t conver path from unicode!')
- smb = NewSMBPacket()
- treeConnect = SMBCommand(SMB.SMB_COM_TREE_CONNECT)
- treeConnect['Parameters'] = SMBTreeConnect_Parameters()
- treeConnect['Data'] = SMBTreeConnect_Data()
- treeConnect['Data']['Path'] = path.upper()
- treeConnect['Data']['Password'] = password
- treeConnect['Data']['Service'] = service
- smb.addCommand(treeConnect)
- self.sendSMB(smb)
- while 1:
- smb = self.recvSMB()
- if smb.isValidAnswer(SMB.SMB_COM_TREE_CONNECT):
- # XXX Here we are ignoring the rest of the response
- return smb['Tid']
- return smb['Tid']
- def get_uid(self):
- return self._uid
- def set_uid(self, uid):
- self._uid = uid
- def tree_connect_andx(self, path, password = None, service = SERVICE_ANY, smb_packet=None):
- if password:
- # Password is only encrypted if the server passed us an "encryption" during protocol dialect
- if self._dialects_parameters['ChallengeLength'] > 0:
- # this code is untested
- password = self.get_ntlmv1_response(ntlm.compute_lmhash(password))
- else:
- password = '\x00'
- if not unicode_support:
- if unicode_convert:
- path = str(path)
- else:
- raise Exception('SMB: Can\t convert path from unicode!')
- if smb_packet is None:
- smb = NewSMBPacket()
- else:
- smb = smb_packet
- # Just in case this came with the full path ,let's just leave
- # the sharename, we'll take care of the rest
- share = path.split('\\')[-1]
- try:
- _, _, _, _, sockaddr = socket.getaddrinfo(self.get_remote_host(), 80, 0, 0, socket.IPPROTO_TCP)[0]
- remote_host = sockaddr[0]
- except Exception:
- remote_host = self.get_remote_host()
- path = '\\\\' + remote_host + '\\' +share
- path = path.upper().encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path
- treeConnect = SMBCommand(SMB.SMB_COM_TREE_CONNECT_ANDX)
- treeConnect['Parameters'] = SMBTreeConnectAndX_Parameters()
- treeConnect['Data'] = SMBTreeConnectAndX_Data(flags=self.__flags2)
- treeConnect['Parameters']['PasswordLength'] = len(password)
- treeConnect['Data']['Password'] = password
- treeConnect['Data']['Path'] = path
- treeConnect['Data']['Service'] = service
- if self.__flags2 & SMB.FLAGS2_UNICODE:
- treeConnect['Data']['Pad'] = 0x0
- smb.addCommand(treeConnect)
- # filename = "\PIPE\epmapper"
- # ntCreate = SMBCommand(SMB.SMB_COM_NT_CREATE_ANDX)
- # ntCreate['Parameters'] = SMBNtCreateAndX_Parameters()
- # ntCreate['Data'] = SMBNtCreateAndX_Data()
- # ntCreate['Parameters']['FileNameLength'] = len(filename)
- # ntCreate['Parameters']['CreateFlags'] = 0
- # ntCreate['Parameters']['AccessMask'] = 0x3
- # ntCreate['Parameters']['CreateOptions'] = 0x0
- # ntCreate['Data']['FileName'] = filename
- # smb.addCommand(ntCreate)
- self.sendSMB(smb)
- while 1:
- smb = self.recvSMB()
- if smb.isValidAnswer(SMB.SMB_COM_TREE_CONNECT_ANDX):
- # XXX Here we are ignoring the rest of the response
- self.tid = smb['Tid']
- return self.tid
- self.tid = smb['Tid']
- return self.tid
- # backwars compatibility
- connect_tree = tree_connect_andx
- @staticmethod
- def getDialect():
- return SMB_DIALECT
- def get_server_name(self):
- #return self._dialects_data['ServerName']
- return self.__server_name
- def get_session_key(self):
- return self._SigningSessionKey
- def set_session_key(self, key):
- self._SigningSessionKey = key
- def get_encryption_key(self):
- if self._dialects_data.fields.has_key('Challenge'):
- return self._dialects_data['Challenge']
- else:
- return None
- def get_server_time(self):
- timestamp = self._dialects_parameters['HighDateTime']
- timestamp <<= 32
- timestamp |= self._dialects_parameters['LowDateTime']
- timestamp -= 116444736000000000
- timestamp /= 10000000
- d = datetime.datetime.utcfromtimestamp(timestamp)
- return d.strftime("%a, %d %b %Y %H:%M:%S GMT")
- def disconnect_tree(self, tid):
- smb = NewSMBPacket()
- smb['Tid'] = tid
- smb.addCommand(SMBCommand(SMB.SMB_COM_TREE_DISCONNECT))
- self.sendSMB(smb)
- self.recvSMB()
- def open(self, tid, filename, open_mode, desired_access):
- filename = string.replace(filename,'/', '\\')
- filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename
- smb = NewSMBPacket()
- smb['Tid'] = tid
- openFile = SMBCommand(SMB.SMB_COM_OPEN)
- openFile['Parameters'] = SMBOpen_Parameters()
- openFile['Parameters']['DesiredAccess'] = desired_access
- openFile['Parameters']['OpenMode'] = open_mode
- openFile['Parameters']['SearchAttributes'] = ATTR_READONLY | ATTR_HIDDEN | ATTR_ARCHIVE
- openFile['Data'] = SMBOpen_Data(flags=self.__flags2)
- openFile['Data']['FileName'] = filename
- if self.__flags2 & SMB.FLAGS2_UNICODE:
- openFile['Data']['Pad'] = 0x0
- smb.addCommand(openFile)
- self.sendSMB(smb)
- smb = self.recvSMB()
- if smb.isValidAnswer(SMB.SMB_COM_OPEN):
- # XXX Here we are ignoring the rest of the response
- openFileResponse = SMBCommand(smb['Data'][0])
- openFileParameters = SMBOpenResponse_Parameters(openFileResponse['Parameters'])
- return (
- openFileParameters['Fid'],
- openFileParameters['FileAttributes'],
- openFileParameters['LastWriten'],
- openFileParameters['FileSize'],
- openFileParameters['GrantedAccess'],
- )
- def open_andx(self, tid, filename, open_mode, desired_access):
- filename = string.replace(filename,'/', '\\')
- filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename
- smb = NewSMBPacket()
- smb['Tid'] = tid
- openFile = SMBCommand(SMB.SMB_COM_OPEN_ANDX)
- openFile['Parameters'] = SMBOpenAndX_Parameters()
- openFile['Parameters']['DesiredAccess'] = desired_access
- openFile['Parameters']['OpenMode'] = open_mode
- openFile['Parameters']['SearchAttributes'] = ATTR_READONLY | ATTR_HIDDEN | ATTR_ARCHIVE
- openFile['Data'] = SMBOpenAndX_Data(flags=self.__flags2)
- openFile['Data']['FileName'] = filename
- if self.__flags2 & SMB.FLAGS2_UNICODE:
- openFile['Data']['Pad'] = 0x0
- smb.addCommand(openFile)
- self.sendSMB(smb)
- smb = self.recvSMB()
- if smb.isValidAnswer(SMB.SMB_COM_OPEN_ANDX):
- # XXX Here we are ignoring the rest of the response
- openFileResponse = SMBCommand(smb['Data'][0])
- openFileParameters = SMBOpenAndXResponse_Parameters(openFileResponse['Parameters'])
- return (
- openFileParameters['Fid'],
- openFileParameters['FileAttributes'],
- openFileParameters['LastWriten'],
- openFileParameters['FileSize'],
- openFileParameters['GrantedAccess'],
- openFileParameters['FileType'],
- openFileParameters['IPCState'],
- openFileParameters['Action'],
- openFileParameters['ServerFid'],
- )
- def close(self, tid, fid):
- smb = NewSMBPacket()
- smb['Tid'] = tid
- closeFile = SMBCommand(SMB.SMB_COM_CLOSE)
- closeFile['Parameters'] = SMBClose_Parameters()
- closeFile['Parameters']['FID'] = fid
- smb.addCommand(closeFile)
- self.sendSMB(smb)
- smb = self.recvSMB()
- if smb.isValidAnswer(SMB.SMB_COM_CLOSE):
- return 1
- return 0
- def send_trans(self, tid, setup, name, param, data, noAnswer = 0):
- smb = NewSMBPacket()
- smb['Tid'] = tid
- transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION)
- transCommand['Parameters'] = SMBTransaction_Parameters()
- transCommand['Data'] = SMBTransaction_Data()
- transCommand['Parameters']['Setup'] = setup
- transCommand['Parameters']['TotalParameterCount'] = len(param)
- transCommand['Parameters']['TotalDataCount'] = len(data)
- transCommand['Parameters']['ParameterCount'] = len(param)
- transCommand['Parameters']['ParameterOffset'] = 32+3+28+len(setup)+len(name)
- transCommand['Parameters']['DataCount'] = len(data)
- transCommand['Parameters']['DataOffset'] = transCommand['Parameters']['ParameterOffset'] + len(param)
- transCommand['Data']['Name'] = name
- transCommand['Data']['Trans_Parameters'] = param
- transCommand['Data']['Trans_Data'] = data
- if noAnswer:
- transCommand['Parameters']['Flags'] = TRANS_NO_RESPONSE
- smb.addCommand(transCommand)
- self.sendSMB(smb)
- def send_trans2(self, tid, setup, name, param, data):
- smb = NewSMBPacket()
- smb['Tid'] = tid
- command = pack('<H', setup)
- transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION2)
- transCommand['Parameters'] = SMBTransaction2_Parameters()
- transCommand['Parameters']['MaxDataCount'] = self._dialects_parameters['MaxBufferSize']
- transCommand['Data'] = SMBTransaction2_Data()
- transCommand['Parameters']['Setup'] = command
- transCommand['Parameters']['TotalParameterCount'] = len(param)
- transCommand['Parameters']['TotalDataCount'] = len(data)
- if len(param) > 0:
- padLen = (4 - (32+2+28 + len(command)) % 4 ) % 4
- padBytes = '\xFF' * padLen
- transCommand['Data']['Pad1'] = padBytes
- else:
- transCommand['Data']['Pad1'] = ''
- padLen = 0
- transCommand['Parameters']['ParameterCount'] = len(param)
- transCommand['Parameters']['ParameterOffset'] = 32+2+28+len(command)+len(name) + padLen
- if len(data) > 0:
- pad2Len = (4 - (32+2+28 + len(command) + padLen + len(param)) % 4) % 4
- transCommand['Data']['Pad2'] = '\xFF' * pad2Len
- else:
- transCommand['Data']['Pad2'] = ''
- pad2Len = 0
- transCommand['Parameters']['DataCount'] = len(data)
- transCommand['Parameters']['DataOffset'] = transCommand['Parameters']['ParameterOffset'] + len(param) + pad2Len
- transCommand['Data']['Name'] = name
- transCommand['Data']['Trans_Parameters'] = param
- transCommand['Data']['Trans_Data'] = data
- smb.addCommand(transCommand)
- self.sendSMB(smb)
- def query_file_info(self, tid, fid, fileInfoClass = SMB_QUERY_FILE_STANDARD_INFO):
- self.send_trans2(tid, SMB.TRANS2_QUERY_FILE_INFORMATION, '\x00', pack('<HH', fid, fileInfoClass), '')
- resp = self.recvSMB()
- if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2):
- trans2Response = SMBCommand(resp['Data'][0])
- trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters'])
- # Remove Potential Prefix Padding
- return trans2Response['Data'][-trans2Parameters['TotalDataCount']:]
- def __nonraw_retr_file(self, tid, fid, offset, datasize, callback):
- if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False:
- max_buf_size = 65000
- else:
- max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Read in multiple KB blocks
- read_offset = offset
- while read_offset < datasize:
- data = self.read_andx(tid, fid, read_offset, max_buf_size)
- callback(data)
- read_offset += len(data)
- def __nonraw_stor_file(self, tid, fid, offset, datasize, callback):
- if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_WRITEX) and self._SignatureEnabled is False:
- max_buf_size = 65000
- else:
- max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Write in multiple KB blocks
- write_offset = offset
- while 1:
- data = callback(max_buf_size)
- if not data:
- break
- smb = self.write_andx(tid,fid,data, write_offset)
- writeResponse = SMBCommand(smb['Data'][0])
- writeResponseParameters = SMBWriteAndXResponse_Parameters(writeResponse['Parameters'])
- write_offset += writeResponseParameters['Count']
- def get_server_domain(self):
- return self.__server_domain
- def get_server_dns_domain_name(self):
- return self.__server_dns_domain_name
- def get_server_os(self):
- return self.__server_os
- def get_server_os_major(self):
- return self.__server_os_major
- def get_server_os_minor(self):
- return self.__server_os_minor
- def get_server_os_build(self):
- return self.__server_os_build
- def set_server_os(self, os):
- self.__server_os = os
- def get_server_lanman(self):
- return self.__server_lanman
- def is_login_required(self):
- # Login is required if share mode is user.
- # Otherwise only public services or services in share mode
- # are allowed.
- return (self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SHARE_MASK) == SMB.SECURITY_SHARE_USER
- def is_signing_required(self):
- return self._SignatureRequired
- def get_ntlmv1_response(self, key):
- challenge = self._dialects_data['Challenge']
- return ntlm.get_ntlmv1_response(key, challenge)
- def kerberos_login(self, user, password, domain = '', lmhash = '', nthash = '', aesKey = '', kdcHost = '', TGT=None, TGS=None):
- # Importing down here so pyasn1 is not required if kerberos is not used.
- from impacket.krb5.asn1 import AP_REQ, Authenticator, TGS_REP, seq_set
- from impacket.krb5.kerberosv5 import getKerberosTGT, getKerberosTGS
- from impacket.krb5 import constants
- from impacket.krb5.types import Principal, KerberosTime, Ticket
- from pyasn1.codec.der import decoder, encoder
- import datetime
- # login feature does not support unicode
- # disable it if enabled
- flags2 = self.__flags2
- if flags2 & SMB.FLAGS2_UNICODE:
- self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE)
- # If TGT or TGS are specified, they are in the form of:
- # TGS['KDC_REP'] = the response from the server
- # TGS['cipher'] = the cipher used
- # TGS['sessionKey'] = the sessionKey
- # If we have hashes, normalize them
- if lmhash != '' or nthash != '':
- if len(lmhash) % 2: lmhash = '0%s' % lmhash
- if len(nthash) % 2: nthash = '0%s' % nthash
- try: # just in case they were converted already
- lmhash = a2b_hex(lmhash)
- nthash = a2b_hex(nthash)
- except:
- pass
- self.__userName = user
- self.__password = password
- self.__domain = domain
- self.__lmhash = lmhash
- self.__nthash = nthash
- self.__aesKey = aesKey
- self.__kdc = kdcHost
- self.__TGT = TGT
- self.__TGS = TGS
- # First of all, we need to get a TGT for the user
- userName = Principal(user, type=constants.PrincipalNameType.NT_PRINCIPAL.value)
- if TGT is None:
- if TGS is None:
- tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, password, domain, lmhash, nthash, aesKey, kdcHost)
- else:
- tgt = TGT['KDC_REP']
- cipher = TGT['cipher']
- sessionKey = TGT['sessionKey']
- # Now that we have the TGT, we should ask for a TGS for cifs
- if TGS is None:
- serverName = Principal('cifs/%s' % self.__remote_name, type=constants.PrincipalNameType.NT_SRV_INST.value)
- tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(serverName, domain, kdcHost, tgt, cipher, sessionKey)
- else:
- tgs = TGS['KDC_REP']
- cipher = TGS['cipher']
- sessionKey = TGS['sessionKey']
- smb = NewSMBPacket()
- # Are we required to sign SMB? If so we do it, if not we skip it
- if self._SignatureRequired:
- smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE
- sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
- sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters()
- sessionSetup['Data'] = SMBSessionSetupAndX_Extended_Data()
- sessionSetup['Parameters']['MaxBufferSize'] = 61440
- sessionSetup['Parameters']['MaxMpxCount'] = 2
- sessionSetup['Parameters']['VcNumber'] = 1
- sessionSetup['Parameters']['SessionKey'] = 0
- sessionSetup['Parameters']['Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX
- # Let's build a NegTokenInit with the NTLMSSP
- # TODO: In the future we should be able to choose different providers
- blob = SPNEGO_NegTokenInit()
- # Kerberos v5 mech
- blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']]
- # Let's extract the ticket from the TGS
- tgs = decoder.decode(tgs, asn1Spec = TGS_REP())[0]
- ticket = Ticket()
- ticket.from_asn1(tgs['ticket'])
- # Now let's build the AP_REQ
- apReq = AP_REQ()
- apReq['pvno'] = 5
- apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value)
- opts = list()
- apReq['ap-options'] = constants.encodeFlags(opts)
- seq_set(apReq,'ticket', ticket.to_asn1)
- authenticator = Authenticator()
- authenticator['authenticator-vno'] = 5
- authenticator['crealm'] = domain
- seq_set(authenticator, 'cname', userName.components_to_asn1)
- now = datetime.datetime.utcnow()
- authenticator['cusec'] = now.microsecond
- authenticator['ctime'] = KerberosTime.to_asn1(now)
- encodedAuthenticator = encoder.encode(authenticator)
- # Key Usage 11
- # AP-REQ Authenticator (includes application authenticator
- # subkey), encrypted with the application session key
- # (Section 5.5.1)
- encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11, encodedAuthenticator, None)
- apReq['authenticator'] = None
- apReq['authenticator']['etype'] = cipher.enctype
- apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator
- blob['MechToken'] = encoder.encode(apReq)
- sessionSetup['Parameters']['SecurityBlobLength'] = len(blob)
- sessionSetup['Parameters'].getData()
- sessionSetup['Data']['SecurityBlob'] = blob.getData()
- # Fake Data here, don't want to get us fingerprinted
- sessionSetup['Data']['NativeOS'] = 'Unix'
- sessionSetup['Data']['NativeLanMan'] = 'Samba'
- smb.addCommand(sessionSetup)
- self.sendSMB(smb)
- smb = self.recvSMB()
- if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX):
- # We will need to use this uid field for all future requests/responses
- self._uid = smb['Uid']
- # Now we have to extract the blob to continue the auth process
- sessionResponse = SMBCommand(smb['Data'][0])
- sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters'])
- sessionData = SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2'])
- sessionData['SecurityBlobLength'] = sessionParameters['SecurityBlobLength']
- sessionData.fromString(sessionResponse['Data'])
- self._action = sessionParameters['Action']
- # If smb sign required, let's enable it for the rest of the connection
- if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED:
- self._SigningSessionKey = sessionKey.contents
- self._SignSequenceNumber = 2
- self._SignatureEnabled = True
- # restore unicode flag if needed
- if flags2 & SMB.FLAGS2_UNICODE:
- self.__flags2 |= SMB.FLAGS2_UNICODE
- return 1
- else:
- raise Exception('Error: Could not login successfully')
- def login_extended(self, user, password, domain = '', lmhash = '', nthash = '', use_ntlmv2 = True ):
- # login feature does not support unicode
- # disable it if enabled
- flags2 = self.__flags2
- if flags2 & SMB.FLAGS2_UNICODE:
- self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE)
- # Once everything's working we should join login methods into a single one
- smb = NewSMBPacket()
- # Are we required to sign SMB? If so we do it, if not we skip it
- if self._SignatureRequired:
- smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE
- sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
- sessionSetup['Parameters'] = SMBSessionSetupAndX_Extended_Parameters()
- sessionSetup['Data'] = SMBSessionSetupAndX_Extended_Data()
- sessionSetup['Parameters']['MaxBufferSize'] = 61440
- sessionSetup['Parameters']['MaxMpxCount'] = 2
- sessionSetup['Parameters']['VcNumber'] = 1
- sessionSetup['Parameters']['SessionKey'] = 0
- sessionSetup['Parameters']['Capabilities'] = SMB.CAP_EXTENDED_SECURITY | SMB.CAP_USE_NT_ERRORS | SMB.CAP_UNICODE | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX
- # Let's build a NegTokenInit with the NTLMSSP
- # TODO: In the future we should be able to choose different providers
- blob = SPNEGO_NegTokenInit()
- # NTLMSSP
- blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']]
- auth = ntlm.getNTLMSSPType1('','',self._SignatureRequired, use_ntlmv2 = use_ntlmv2)
- blob['MechToken'] = str(auth)
- sessionSetup['Parameters']['SecurityBlobLength'] = len(blob)
- sessionSetup['Parameters'].getData()
- sessionSetup['Data']['SecurityBlob'] = blob.getData()
- # Fake Data here, don't want to get us fingerprinted
- sessionSetup['Data']['NativeOS'] = 'Unix'
- sessionSetup['Data']['NativeLanMan'] = 'Samba'
- smb.addCommand(sessionSetup)
- self.sendSMB(smb)
- smb = self.recvSMB()
- if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX):
- # We will need to use this uid field for all future requests/responses
- self._uid = smb['Uid']
- # Now we have to extract the blob to continue the auth process
- sessionResponse = SMBCommand(smb['Data'][0])
- sessionParameters = SMBSessionSetupAndX_Extended_Response_Parameters(sessionResponse['Parameters'])
- sessionData = SMBSessionSetupAndX_Extended_Response_Data(flags = smb['Flags2'])
- sessionData['SecurityBlobLength'] = sessionParameters['SecurityBlobLength']
- sessionData.fromString(sessionResponse['Data'])
- respToken = SPNEGO_NegTokenResp(sessionData['SecurityBlob'])
- # Let's parse some data and keep it to ourselves in case it is asked
- ntlmChallenge = ntlm.NTLMAuthChallenge(respToken['ResponseToken'])
- if ntlmChallenge['TargetInfoFields_len'] > 0:
- av_pairs = ntlm.AV_PAIRS(ntlmChallenge['TargetInfoFields'][:ntlmChallenge['TargetInfoFields_len']])
- if av_pairs[ntlm.NTLMSSP_AV_HOSTNAME] is not None:
- try:
- self.__server_name = av_pairs[ntlm.NTLMSSP_AV_HOSTNAME][1].decode('utf-16le')
- except:
- # For some reason, we couldn't decode Unicode here.. silently discard the operation
- pass
- if av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME] is not None:
- try:
- if self.__server_name != av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME][1].decode('utf-16le'):
- self.__server_domain = av_pairs[ntlm.NTLMSSP_AV_DOMAINNAME][1].decode('utf-16le')
- except:
- # For some reason, we couldn't decode Unicode here.. silently discard the operation
- pass
- if av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME] is not None:
- try:
- self.__server_dns_domain_name = av_pairs[ntlm.NTLMSSP_AV_DNS_DOMAINNAME][1].decode('utf-16le')
- except:
- # For some reason, we couldn't decode Unicode here.. silently discard the operation
- pass
- # Parse Version to know the target Operating system name. Not provided elsewhere anymore
- if ntlmChallenge.fields.has_key('Version'):
- version = ntlmChallenge['Version']
- if len(version) >= 4:
- self.__server_os_major, self.__server_os_minor, self.__server_os_build = unpack('<BBH',version[:4])
- type3, exportedSessionKey = ntlm.getNTLMSSPType3(auth, respToken['ResponseToken'], user, password, domain, lmhash, nthash, use_ntlmv2 = use_ntlmv2)
- if exportedSessionKey is not None:
- self._SigningSessionKey = exportedSessionKey
- smb = NewSMBPacket()
- # Are we required to sign SMB? If so we do it, if not we skip it
- if self._SignatureRequired:
- smb['Flags2'] |= SMB.FLAGS2_SMB_SECURITY_SIGNATURE
- respToken2 = SPNEGO_NegTokenResp()
- respToken2['ResponseToken'] = str(type3)
- # Reusing the previous structure
- sessionSetup['Parameters']['SecurityBlobLength'] = len(respToken2)
- sessionSetup['Data']['SecurityBlob'] = respToken2.getData()
- # Storing some info for later use
- self.__server_os = sessionData['NativeOS']
- self.__server_lanman = sessionData['NativeLanMan']
- smb.addCommand(sessionSetup)
- self.sendSMB(smb)
- smb = self.recvSMB()
- self._uid = 0
- if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX):
- self._uid = smb['Uid']
- sessionResponse = SMBCommand(smb['Data'][0])
- sessionParameters = SMBSessionSetupAndXResponse_Parameters(sessionResponse['Parameters'])
- self._action = sessionParameters['Action']
- # If smb sign required, let's enable it for the rest of the connection
- if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_REQUIRED:
- self._SignSequenceNumber = 2
- self._SignatureEnabled = True
- # restore unicode flag if needed
- if flags2 & SMB.FLAGS2_UNICODE:
- self.__flags2 |= SMB.FLAGS2_UNICODE
- return 1
- else:
- raise Exception('Error: Could not login successfully')
- def getCredentials(self):
- return (
- self.__userName,
- self.__password,
- self.__domain,
- self.__lmhash,
- self.__nthash,
- self.__aesKey,
- self.__TGT,
- self.__TGS)
- def getIOCapabilities(self):
- res = dict()
- if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False:
- max_size = 65000
- else:
- max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks
- res['MaxReadSize'] = max_size
- res['MaxWriteSize'] = max_size
- return res
- def login(self, user, password, domain = '', lmhash = '', nthash = '', ntlm_fallback = True):
- # If we have hashes, normalize them
- if lmhash != '' or nthash != '':
- if len(lmhash) % 2: lmhash = '0%s' % lmhash
- if len(nthash) % 2: nthash = '0%s' % nthash
- try: # just in case they were converted already
- lmhash = a2b_hex(lmhash)
- nthash = a2b_hex(nthash)
- except:
- pass
- self.__userName = user
- self.__password = password
- self.__domain = domain
- self.__lmhash = lmhash
- self.__nthash = nthash
- self.__aesKey = ''
- self.__TGT = None
- self.__TGS = None
- if self._dialects_parameters['Capabilities'] & SMB.CAP_EXTENDED_SECURITY:
- try:
- self.login_extended(user, password, domain, lmhash, nthash, use_ntlmv2 = True)
- except:
- # If the target OS is Windows 5.0 or Samba, let's try using NTLMv1
- if ntlm_fallback and ((self.get_server_lanman().find('Windows 2000') != -1) or (self.get_server_lanman().find('Samba') != -1)):
- self.login_extended(user, password, domain, lmhash, nthash, use_ntlmv2 = False)
- self.__isNTLMv2 = False
- else:
- raise
- elif ntlm_fallback:
- self.login_standard(user, password, domain, lmhash, nthash)
- self.__isNTLMv2 = False
- else:
- raise SessionError('Cannot authenticate against target, enable ntlm_fallback')
- def login_standard(self, user, password, domain = '', lmhash = '', nthash = ''):
- # login feature does not support unicode
- # disable it if enabled
- flags2 = self.__flags2
- if flags2 & SMB.FLAGS2_UNICODE:
- self.__flags2 = flags2 & (flags2 ^ SMB.FLAGS2_UNICODE)
- # Only supports NTLMv1
- # Password is only encrypted if the server passed us an "encryption key" during protocol dialect negotiation
- if self._dialects_parameters['ChallengeLength'] > 0:
- if lmhash != '' or nthash != '':
- pwd_ansi = self.get_ntlmv1_response(lmhash)
- pwd_unicode = self.get_ntlmv1_response(nthash)
- elif password:
- lmhash = ntlm.compute_lmhash(password)
- nthash = ntlm.compute_nthash(password)
- pwd_ansi = self.get_ntlmv1_response(lmhash)
- pwd_unicode = self.get_ntlmv1_response(nthash)
- else: # NULL SESSION
- pwd_ansi = ''
- pwd_unicode = ''
- else:
- pwd_ansi = password
- pwd_unicode = ''
- smb = NewSMBPacket()
- sessionSetup = SMBCommand(SMB.SMB_COM_SESSION_SETUP_ANDX)
- sessionSetup['Parameters'] = SMBSessionSetupAndX_Parameters()
- sessionSetup['Data'] = SMBSessionSetupAndX_Data()
- sessionSetup['Parameters']['MaxBuffer'] = 61440
- sessionSetup['Parameters']['MaxMpxCount'] = 2
- sessionSetup['Parameters']['VCNumber'] = os.getpid()
- sessionSetup['Parameters']['SessionKey'] = self._dialects_parameters['SessionKey']
- sessionSetup['Parameters']['AnsiPwdLength'] = len(pwd_ansi)
- sessionSetup['Parameters']['UnicodePwdLength'] = len(pwd_unicode)
- sessionSetup['Parameters']['Capabilities'] = SMB.CAP_RAW_MODE | SMB.CAP_USE_NT_ERRORS | SMB.CAP_LARGE_READX | SMB.CAP_LARGE_WRITEX
- sessionSetup['Data']['AnsiPwd'] = pwd_ansi
- sessionSetup['Data']['UnicodePwd'] = pwd_unicode
- sessionSetup['Data']['Account'] = str(user)
- sessionSetup['Data']['PrimaryDomain'] = str(domain)
- sessionSetup['Data']['NativeOS'] = str(os.name)
- sessionSetup['Data']['NativeLanMan'] = 'pysmb'
- smb.addCommand(sessionSetup)
- self.sendSMB(smb)
- smb = self.recvSMB()
- if smb.isValidAnswer(SMB.SMB_COM_SESSION_SETUP_ANDX):
- # We will need to use this uid field for all future requests/responses
- self._uid = smb['Uid']
- sessionResponse = SMBCommand(smb['Data'][0])
- sessionParameters = SMBSessionSetupAndXResponse_Parameters(sessionResponse['Parameters'])
- sessionData = SMBSessionSetupAndXResponse_Data(flags = smb['Flags2'], data = sessionResponse['Data'])
- self._action = sessionParameters['Action']
- # Still gotta figure out how to do this with no EXTENDED_SECURITY
- if sessionParameters['Action'] & SMB_SETUP_USE_LANMAN_KEY == 0:
- self._SigningChallengeResponse = sessionSetup['Data']['UnicodePwd']
- self._SigningSessionKey = nthash
- else:
- self._SigningChallengeResponse = sessionSetup['Data']['AnsiPwd']
- self._SigningSessionKey = lmhash
- #self._SignSequenceNumber = 1
- #self.checkSignSMB(smb, self._SigningSessionKey ,self._SigningChallengeResponse)
- #self._SignatureEnabled = True
- self.__server_os = sessionData['NativeOS']
- self.__server_lanman = sessionData['NativeLanMan']
- self.__server_domain = sessionData['PrimaryDomain']
- # restore unicode flag if needed
- if flags2 & SMB.FLAGS2_UNICODE:
- self.__flags2 |= SMB.FLAGS2_UNICODE
- return 1
- else: raise Exception('Error: Could not login successfully')
- def waitNamedPipe(self, tid, pipe, timeout = 5, noAnswer = 0):
- smb = NewSMBPacket()
- smb['Tid'] = tid
- transCommand = SMBCommand(SMB.SMB_COM_TRANSACTION)
- transCommand['Parameters'] = SMBTransaction_Parameters()
- transCommand['Data'] = SMBTransaction_Data()
- setup = '\x53\x00\x00\x00'
- name = '\\PIPE%s\x00' % pipe
- transCommand['Parameters']['Setup'] = setup
- transCommand['Parameters']['TotalParameterCount'] = 0
- transCommand['Parameters']['TotalDataCount'] = 0
- transCommand['Parameters']['MaxParameterCount'] = 0
- transCommand['Parameters']['MaxDataCount'] = 0
- transCommand['Parameters']['Timeout'] = timeout * 1000
- transCommand['Parameters']['ParameterCount'] = 0
- transCommand['Parameters']['ParameterOffset'] = 32+3+28+len(setup)+len(name)
- transCommand['Parameters']['DataCount'] = 0
- transCommand['Parameters']['DataOffset'] = 0
- transCommand['Data']['Name'] = name
- transCommand['Data']['Trans_Parameters'] = ''
- transCommand['Data']['Trans_Data'] = ''
- if noAnswer:
- transCommand['Parameters']['Flags'] = TRANS_NO_RESPONSE
- smb.addCommand(transCommand)
- self.sendSMB(smb)
- smb = self.recvSMB()
- if smb.isValidAnswer(SMB.SMB_COM_TRANSACTION):
- return 1
- return 0
- def read(self, tid, fid, offset=0, max_size = None, wait_answer=1):
- if not max_size:
- max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks
- # max_size is not working, because although it would, the server returns an error (More data avail)
- smb = NewSMBPacket()
- smb['Tid'] = tid
- read = SMBCommand(SMB.SMB_COM_READ)
- read['Parameters'] = SMBRead_Parameters()
- read['Parameters']['Fid'] = fid
- read['Parameters']['Offset'] = offset
- read['Parameters']['Count'] = max_size
- smb.addCommand(read)
- if wait_answer:
- while 1:
- self.sendSMB(smb)
- ans = self.recvSMB()
- if ans.isValidAnswer(SMB.SMB_COM_READ):
- readResponse = SMBCommand(ans['Data'][0])
- readData = SMBReadResponse_Data(readResponse['Data'])
- return readData['Data']
- return None
- def read_andx(self, tid, fid, offset=0, max_size = None, wait_answer=1, smb_packet=None):
- if not max_size:
- if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_READX) and self._SignatureEnabled is False:
- max_size = 65000
- else:
- max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks
- # max_size is not working, because although it would, the server returns an error (More data avail)
- if smb_packet is None:
- smb = NewSMBPacket()
- smb['Tid'] = tid
- readAndX = SMBCommand(SMB.SMB_COM_READ_ANDX)
- readAndX['Parameters'] = SMBReadAndX_Parameters()
- readAndX['Parameters']['Fid'] = fid
- readAndX['Parameters']['Offset'] = offset
- readAndX['Parameters']['MaxCount'] = max_size
- smb.addCommand(readAndX)
- else:
- smb = smb_packet
- if wait_answer:
- answer = ''
- while 1:
- self.sendSMB(smb)
- ans = self.recvSMB()
- if ans.isValidAnswer(SMB.SMB_COM_READ_ANDX):
- # XXX Here we are only using a few fields from the response
- readAndXResponse = SMBCommand(ans['Data'][0])
- readAndXParameters = SMBReadAndXResponse_Parameters(readAndXResponse['Parameters'])
- offset = readAndXParameters['DataOffset']
- count = readAndXParameters['DataCount']+0x10000*readAndXParameters['DataCount_Hi']
- answer += str(ans)[offset:offset+count]
- if not ans.isMoreData():
- return answer
- max_size = min(max_size, readAndXParameters['Remaining'])
- readAndX['Parameters']['Offset'] += count # XXX Offset is not important (apparently)
- else:
- self.sendSMB(smb)
- ans = self.recvSMB()
- try:
- if ans.isValidAnswer(SMB.SMB_COM_READ_ANDX):
- return ans
- else:
- return None
- except:
- return ans
- return None
- def read_raw(self, tid, fid, offset=0, max_size = None, wait_answer=1):
- if not max_size:
- max_size = self._dialects_parameters['MaxBufferSize'] # Read in multiple KB blocks
- # max_size is not working, because although it would, the server returns an error (More data avail)
- smb = NewSMBPacket()
- smb['Tid'] = tid
- readRaw = SMBCommand(SMB.SMB_COM_READ_RAW)
- readRaw['Parameters'] = SMBReadRaw_Parameters()
- readRaw['Parameters']['Fid'] = fid
- readRaw['Parameters']['Offset'] = offset
- readRaw['Parameters']['MaxCount'] = max_size
- smb.addCommand(readRaw)
- self.sendSMB(smb)
- if wait_answer:
- data = self._sess.recv_packet(self.__timeout).get_trailer()
- if not data:
- # If there is no data it means there was an error
- data = self.read_andx(tid, fid, offset, max_size)
- return data
- return None
- def write(self,tid,fid,data, offset = 0, wait_answer=1):
- smb = NewSMBPacket()
- smb['Tid'] = tid
- write = SMBCommand(SMB.SMB_COM_WRITE)
- write['Parameters'] = SMBWrite_Parameters()
- write['Data'] = SMBWrite_Data()
- write['Parameters']['Fid'] = fid
- write['Parameters']['Count'] = len(data)
- write['Parameters']['Offset'] = offset
- write['Parameters']['Remaining'] = len(data)
- write['Data']['Data'] = data
- smb.addCommand(write)
- self.sendSMB(smb)
- if wait_answer:
- smb = self.recvSMB()
- if smb.isValidAnswer(SMB.SMB_COM_WRITE):
- return smb
- return None
- def write_andx(self,tid,fid,data, offset = 0, wait_answer=1, write_pipe_mode = False, smb_packet=None):
- if smb_packet is None:
- smb = NewSMBPacket()
- smb['Tid'] = tid
- writeAndX = SMBCommand(SMB.SMB_COM_WRITE_ANDX)
- smb.addCommand(writeAndX)
- writeAndX['Parameters'] = SMBWriteAndX_Parameters()
- writeAndX['Parameters']['Fid'] = fid
- writeAndX['Parameters']['Offset'] = offset
- writeAndX['Parameters']['WriteMode'] = 8
- writeAndX['Parameters']['Remaining'] = len(data)
- writeAndX['Parameters']['DataLength'] = len(data)
- writeAndX['Parameters']['DataOffset'] = len(smb) # this length already includes the parameter
- writeAndX['Data'] = data
- if write_pipe_mode is True:
- # First of all we gotta know what the MaxBuffSize is
- maxBuffSize = self._dialects_parameters['MaxBufferSize']
- if len(data) > maxBuffSize:
- chunks_size = maxBuffSize - 60
- writeAndX['Parameters']['WriteMode'] = 0x0c
- sendData = '\xff\xff' + data
- totalLen = len(sendData)
- writeAndX['Parameters']['DataLength'] = chunks_size
- writeAndX['Parameters']['Remaining'] = totalLen-2
- writeAndX['Data'] = sendData[:chunks_size]
- self.sendSMB(smb)
- if wait_answer:
- smbResp = self.recvSMB()
- smbResp.isValidAnswer(SMB.SMB_COM_WRITE_ANDX)
- alreadySent = chunks_size
- sendData = sendData[chunks_size:]
- while alreadySent < totalLen:
- writeAndX['Parameters']['WriteMode'] = 0x04
- writeAndX['Parameters']['DataLength'] = len(sendData[:chunks_size])
- writeAndX['Data'] = sendData[:chunks_size]
- self.sendSMB(smb)
- if wait_answer:
- smbResp = self.recvSMB()
- smbResp.isValidAnswer(SMB.SMB_COM_WRITE_ANDX)
- alreadySent += writeAndX['Parameters']['DataLength']
- sendData = sendData[chunks_size:]
- return smbResp
- else:
- smb = smb_packet
- self.sendSMB(smb)
- if wait_answer:
- smb = self.recvSMB()
- if smb.isValidAnswer(SMB.SMB_COM_WRITE_ANDX):
- return smb
- return None
- def write_raw(self,tid,fid,data, offset = 0, wait_answer=1):
- 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")
- smb = NewSMBPacket()
- smb['Tid'] = tid
- writeRaw = SMBCommand(SMB.SMB_COM_WRITE_RAW)
- writeRaw['Parameters'] = SMBWriteRaw_Parameters()
- writeRaw['Parameters']['Fid'] = fid
- writeRaw['Parameters']['Offset'] = offset
- writeRaw['Parameters']['Count'] = len(data)
- writeRaw['Parameters']['DataLength'] = 0
- writeRaw['Parameters']['DataOffset'] = 0
- smb.addCommand(writeRaw)
- self.sendSMB(smb)
- self._sess.send_packet(data)
- if wait_answer:
- smb = self.recvSMB()
- if smb.isValidAnswer(SMB.SMB_COM_WRITE_RAW):
- return smb
- return None
- def TransactNamedPipe(self, tid, fid, data = '', noAnswer = 0, waitAnswer = 1, offset = 0):
- self.send_trans(tid,pack('<HH', 0x26, fid),'\\PIPE\\\x00','',data, noAnswer = noAnswer)
- if noAnswer or not waitAnswer:
- return
- smb = self.recvSMB()
- if smb.isValidAnswer(SMB.SMB_COM_TRANSACTION):
- transResponse = SMBCommand(smb['Data'][0])
- transParameters = SMBTransactionResponse_Parameters(transResponse['Parameters'])
- return transResponse['Data'][-transParameters['TotalDataCount']:] # Remove Potential Prefix Padding
- return None
- def TransactNamedPipeRecv(self):
- s = self.recvSMB()
- if s.isValidAnswer(SMB.SMB_COM_TRANSACTION):
- transResponse = SMBCommand(s['Data'][0])
- transParameters = SMBTransactionResponse_Parameters(transResponse['Parameters'])
- return transResponse['Data'][-transParameters['TotalDataCount']:] # Remove Potential Prefix Padding
- return None
- def nt_create_andx(self,tid,filename, smb_packet=None, cmd = None, shareAccessMode = FILE_SHARE_READ | FILE_SHARE_WRITE, disposition = FILE_OPEN, accessMask = 0x2019f):
- filename = filename.replace('/', '\\')
- filename = filename.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else filename
- if smb_packet is None:
- smb = NewSMBPacket()
- smb['Tid'] = tid
- else:
- smb = smb_packet
- if cmd is None:
- ntCreate = SMBCommand(SMB.SMB_COM_NT_CREATE_ANDX)
- ntCreate['Parameters'] = SMBNtCreateAndX_Parameters()
- ntCreate['Data'] = SMBNtCreateAndX_Data(flags=self.__flags2)
- ntCreate['Parameters']['FileNameLength'] = len(filename)
- ntCreate['Parameters']['CreateFlags'] = 0x16
- ntCreate['Parameters']['AccessMask'] = accessMask
- ntCreate['Parameters']['CreateOptions'] = 0x40
- ntCreate['Parameters']['ShareAccess'] = shareAccessMode
- ntCreate['Parameters']['Disposition'] = disposition
- ntCreate['Data']['FileName'] = filename
- if self.__flags2 & SMB.FLAGS2_UNICODE:
- ntCreate['Data']['Pad'] = 0x0
- else:
- ntCreate = cmd
- smb.addCommand(ntCreate)
- self.sendSMB(smb)
- while 1:
- smb = self.recvSMB()
- if smb.isValidAnswer(SMB.SMB_COM_NT_CREATE_ANDX):
- # XXX Here we are ignoring the rest of the response
- ntCreateResponse = SMBCommand(smb['Data'][0])
- ntCreateParameters = SMBNtCreateAndXResponse_Parameters(ntCreateResponse['Parameters'])
- self.fid = ntCreateParameters['Fid']
- return ntCreateParameters['Fid']
- def logoff(self):
- smb = NewSMBPacket()
- logOff = SMBCommand(SMB.SMB_COM_LOGOFF_ANDX)
- logOff['Parameters'] = SMBLogOffAndX()
- smb.addCommand(logOff)
- self.sendSMB(smb)
- self.recvSMB()
- # Let's clear some fields so you can login again under the same session
- self._uid = 0
- def list_path(self, service, path = '*', password = None):
- path = path.replace('/', '\\')
- path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path
- tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
- try:
- findFirstParameter = SMBFindFirst2_Parameters()
- findFirstParameter['SearchAttributes'] = SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_HIDDEN | \
- SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_READONLY | \
- SMB_FILE_ATTRIBUTE_ARCHIVE
- findFirstParameter['SearchCount'] = 512
- findFirstParameter['Flags'] = SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS
- findFirstParameter['InformationLevel'] = SMB_FIND_FILE_BOTH_DIRECTORY_INFO
- findFirstParameter['SearchStorageType'] = 0
- findFirstParameter['FileName'] = path + ('\x00\x00' if self.__flags2 & SMB.FLAGS2_UNICODE else '\x00')
- self.send_trans2(tid, SMB.TRANS2_FIND_FIRST2, '\x00', findFirstParameter, '')
- files = [ ]
- totalDataCount = 1
- findData = ''
- findFirst2ParameterBlock = ''
- while len(findData) < totalDataCount:
- resp = self.recvSMB()
- if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2):
- trans2Response = SMBCommand(resp['Data'][0])
- trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters'])
- totalDataCount = trans2Parameters['TotalDataCount']
- findFirst2ParameterBlock += trans2Response['Data'][trans2Parameters['ParameterOffset']-55:][:trans2Parameters['ParameterCount']]
- findData += trans2Response['Data'][trans2Parameters['DataOffset']-55:]
- findParameterBlock = SMBFindFirst2Response_Parameters(findFirst2ParameterBlock)
- # Save the SID for resume operations
- sid = findParameterBlock['SID']
- while True:
- record = SMBFindFileBothDirectoryInfo(data = findData)
- shortname = record['ShortName'].decode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else record['ShortName']
- filename = record['FileName'].decode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else record['FileName']
- fileRecord = SharedFile(record['CreationTime'], record['LastAccessTime'], record['LastChangeTime'],
- record['EndOfFile'], record['AllocationSize'], record['ExtFileAttributes'],
- shortname, filename)
- files.append(fileRecord)
- if record['NextEntryOffset'] > 0 and len(findData[record['NextEntryOffset']:]) > 0:
- findData = findData[record['NextEntryOffset']:]
- else:
- # More data to search?
- if findParameterBlock['EndOfSearch'] == 0:
- resume_filename = record['FileName']
- findNextParameter = SMBFindNext2_Parameters()
- findNextParameter['SID'] = sid
- findNextParameter['SearchCount'] = 1024
- findNextParameter['InformationLevel'] = SMB_FIND_FILE_BOTH_DIRECTORY_INFO
- findNextParameter['ResumeKey'] = 0
- findNextParameter['Flags'] = SMB_FIND_RETURN_RESUME_KEYS | SMB_FIND_CLOSE_AT_EOS
- findNextParameter['FileName'] = resume_filename + ('\x00\x00' if self.__flags2 & SMB.FLAGS2_UNICODE else '\x00')
- self.send_trans2(tid, SMB.TRANS2_FIND_NEXT2, '\x00', findNextParameter, '')
- findData = ''
- findNext2ParameterBlock = ''
- totalDataCount = 1
- while len(findData) < totalDataCount:
- resp = self.recvSMB()
- if resp.isValidAnswer(SMB.SMB_COM_TRANSACTION2):
- trans2Response = SMBCommand(resp['Data'][0])
- trans2Parameters = SMBTransaction2Response_Parameters(trans2Response['Parameters'])
- totalDataCount = trans2Parameters['TotalDataCount']
- findNext2ParameterBlock += trans2Response['Data'][trans2Parameters['ParameterOffset']-55:][:trans2Parameters['ParameterCount']]
- findData += trans2Response['Data'][trans2Parameters['DataOffset']-55:]
- findParameterBlock = SMBFindNext2Response_Parameters(findNext2ParameterBlock)
- else:
- break
- finally:
- self.disconnect_tree(tid)
- return files
- def retr_file(self, service, filename, callback, mode = FILE_OPEN, offset = 0, password = None, shareAccessMode = SMB_ACCESS_READ):
- filename = string.replace(filename, '/', '\\')
- fid = -1
- tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
- try:
- fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, accessMask = 0x20089)
- res = self.query_file_info(tid, fid)
- datasize = SMBQueryFileStandardInfo(res)['EndOfFile']
- self.__nonraw_retr_file(tid, fid, offset, datasize, callback)
- finally:
- if fid >= 0:
- self.close(tid, fid)
- self.disconnect_tree(tid)
- def stor_file(self, service, filename, callback, mode = FILE_OVERWRITE_IF, offset = 0, password = None, shareAccessMode = SMB_ACCESS_WRITE):
- filename = string.replace(filename, '/', '\\')
- fid = -1
- tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
- try:
- fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, disposition = mode )
- self.__nonraw_stor_file(tid, fid, offset, 0, callback)
- finally:
- if fid >= 0:
- self.close(tid, fid)
- self.disconnect_tree(tid)
- def stor_file_nonraw(self, service, filename, callback, mode = FILE_OVERWRITE_IF, offset = 0, password = None, shareAccessMode = SMB_ACCESS_WRITE ):
- filename = string.replace(filename, '/', '\\')
- fid = -1
- tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
- try:
- fid = self.nt_create_andx(tid, filename, shareAccessMode = shareAccessMode, disposition = mode)
- self.__nonraw_stor_file(tid, fid, offset, 0, callback)
- finally:
- if fid >= 0:
- self.close(tid, fid)
- self.disconnect_tree(tid)
- def check_dir(self, service, path, password = None):
- path = string.replace(path,'/', '\\')
- tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
- try:
- smb = NewSMBPacket()
- smb['Tid'] = tid
- smb['Mid'] = 0
- cmd = SMBCommand(SMB.SMB_COM_CHECK_DIRECTORY)
- cmd['Parameters'] = ''
- cmd['Data'] = SMBCheckDirectory_Data(flags = self.__flags2)
- cmd['Data']['DirectoryName'] = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path
- smb.addCommand(cmd)
- self.sendSMB(smb)
- while 1:
- s = self.recvSMB()
- if s.isValidAnswer(SMB.SMB_COM_CHECK_DIRECTORY):
- return
- finally:
- self.disconnect_tree(tid)
- def remove(self, service, path, password = None):
- path = string.replace(path,'/', '\\')
- # Perform a list to ensure the path exists
- self.list_path(service, path, password)
- tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
- try:
- smb = NewSMBPacket()
- smb['Tid'] = tid
- smb['Mid'] = 0
- cmd = SMBCommand(SMB.SMB_COM_DELETE)
- cmd['Parameters'] = SMBDelete_Parameters()
- cmd['Parameters']['SearchAttributes'] = ATTR_HIDDEN | ATTR_SYSTEM | ATTR_ARCHIVE
- cmd['Data'] = SMBDelete_Data(flags = self.__flags2)
- cmd['Data']['FileName'] = (path + '\x00').encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else (path + '\x00')
- smb.addCommand(cmd)
- self.sendSMB(smb)
- while 1:
- s = self.recvSMB()
- if s.isValidAnswer(SMB.SMB_COM_DELETE):
- return
- finally:
- self.disconnect_tree(tid)
- def rmdir(self, service, path, password = None):
- path = string.replace(path,'/', '\\')
- # Check that the directory exists
- self.check_dir(service, path, password)
- tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
- try:
- path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path
- smb = NewSMBPacket()
- smb['Tid'] = tid
- createDir = SMBCommand(SMB.SMB_COM_DELETE_DIRECTORY)
- createDir['Data'] = SMBDeleteDirectory_Data(flags=self.__flags2)
- createDir['Data']['DirectoryName'] = path
- smb.addCommand(createDir)
- self.sendSMB(smb)
- while 1:
- s = self.recvSMB()
- if s.isValidAnswer(SMB.SMB_COM_DELETE_DIRECTORY):
- return
- finally:
- self.disconnect_tree(tid)
- def mkdir(self, service, path, password = None):
- path = string.replace(path,'/', '\\')
- tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
- try:
- path = path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else path
- smb = NewSMBPacket()
- smb['Tid'] = tid
- smb['Mid'] = 0
- createDir = SMBCommand(SMB.SMB_COM_CREATE_DIRECTORY)
- createDir['Data'] = SMBCreateDirectory_Data(flags=self.__flags2)
- createDir['Data']['DirectoryName'] = path
- smb.addCommand(createDir)
- self.sendSMB(smb)
- smb = self.recvSMB()
- if smb.isValidAnswer(SMB.SMB_COM_CREATE_DIRECTORY):
- return 1
- return 0
- finally:
- self.disconnect_tree(tid)
- def rename(self, service, old_path, new_path, password = None):
- old_path = string.replace(old_path,'/', '\\')
- new_path = string.replace(new_path,'/', '\\')
- tid = self.tree_connect_andx('\\\\' + self.__remote_name + '\\' + service, password)
- try:
- smb = NewSMBPacket()
- smb['Tid'] = tid
- smb['Mid'] = 0
- renameCmd = SMBCommand(SMB.SMB_COM_RENAME)
- renameCmd['Parameters'] = SMBRename_Parameters()
- renameCmd['Parameters']['SearchAttributes'] = ATTR_SYSTEM | ATTR_HIDDEN | ATTR_DIRECTORY
- renameCmd['Data'] = SMBRename_Data(flags = self.__flags2)
- renameCmd['Data']['OldFileName'] = old_path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else old_path
- renameCmd['Data']['NewFileName'] = new_path.encode('utf-16le') if self.__flags2 & SMB.FLAGS2_UNICODE else new_path
- smb.addCommand(renameCmd)
- self.sendSMB(smb)
- smb = self.recvSMB()
- if smb.isValidAnswer(SMB.SMB_COM_RENAME):
- return 1
- return 0
- finally:
- self.disconnect_tree(tid)
- def writeFile(self, treeId, fileId, data, offset = 0):
- if (self._dialects_parameters['Capabilities'] & SMB.CAP_LARGE_WRITEX) and self._SignatureEnabled is False:
- max_buf_size = 65000
- else:
- max_buf_size = self._dialects_parameters['MaxBufferSize'] & ~0x3ff # Write in multiple KB blocks
- write_offset = offset
- while 1:
- if len(data) == 0:
- break
- writeData = data[:max_buf_size]
- data = data[max_buf_size:]
- smb = self.write_andx(treeId,fileId,writeData, write_offset)
- writeResponse = SMBCommand(smb['Data'][0])
- writeResponseParameters = SMBWriteAndXResponse_Parameters(writeResponse['Parameters'])
- write_offset += writeResponseParameters['Count']
- def get_socket(self):
- return self._sess.get_socket()
- ERRDOS = { 1: 'Invalid function',
- 2: 'File not found',
- 3: 'Invalid directory',
- 4: 'Too many open files',
- 5: 'Access denied',
- 6: 'Invalid file handle. Please file a bug report.',
- 7: 'Memory control blocks destroyed',
- 8: 'Out of memory',
- 9: 'Invalid memory block address',
- 10: 'Invalid environment',
- 11: 'Invalid format',
- 12: 'Invalid open mode',
- 13: 'Invalid data',
- 15: 'Invalid drive',
- 16: 'Attempt to remove server\'s current directory',
- 17: 'Not the same device',
- 18: 'No files found',
- 32: 'Sharing mode conflicts detected',
- 33: 'Lock request conflicts detected',
- 80: 'File already exists'
- }
- ERRSRV = { 1: 'Non-specific error',
- 2: 'Bad password',
- 4: 'Access denied',
- 5: 'Invalid tid. Please file a bug report.',
- 6: 'Invalid network name',
- 7: 'Invalid device',
- 49: 'Print queue full',
- 50: 'Print queue full',
- 51: 'EOF on print queue dump',
- 52: 'Invalid print file handle',
- 64: 'Command not recognized. Please file a bug report.',
- 65: 'Internal server error',
- 67: 'Invalid path',
- 69: 'Invalid access permissions',
- 71: 'Invalid attribute mode',
- 81: 'Server is paused',
- 82: 'Not receiving messages',
- 83: 'No room to buffer messages',
- 87: 'Too many remote user names',
- 88: 'Operation timeout',
- 89: 'Out of resources',
- 91: 'Invalid user handle. Please file a bug report.',
- 250: 'Temporarily unable to support raw mode for transfer',
- 251: 'Temporarily unable to support raw mode for transfer',
- 252: 'Continue in MPX mode',
- 65535: 'Unsupported function'
- }
- ERRHRD = { 19: 'Media is write-protected',
- 20: 'Unknown unit',
- 21: 'Drive not ready',
- 22: 'Unknown command',
- 23: 'CRC error',
- 24: 'Bad request',
- 25: 'Seek error',
- 26: 'Unknown media type',
- 27: 'Sector not found',
- 28: 'Printer out of paper',
- 29: 'Write fault',
- 30: 'Read fault',
- 31: 'General failure',
- 32: 'Open conflicts with an existing open',
- 33: 'Invalid lock request',
- 34: 'Wrong disk in drive',
- 35: 'FCBs not available',
- 36: 'Sharing buffer exceeded'
- }
|