Projects STRLCPY vucsa Commits c79948ad
🤬
Showing first 70 files as there are too many
  • ■ ■ ■ ■ ■ ■
    .gitignore
     1 +# Gradle
     2 +.gradle
     3 +gradle**
     4 +# Eclipse, Idea, ...
     5 +.settings
     6 +.idea
     7 +bin
     8 +build
     9 +doc
     10 + 
  • ■ ■ ■ ■ ■ ■
    CHANGELOG.md
     1 +# Changelog
     2 + 
     3 +All notable changes to this project will are documented in this changelog file.
     4 + 
     5 +## [1.0.0] - 2022-01-01
     6 +### Added
     7 +- common functionality
     8 +- server and client implementation
     9 +- 7 basic challenges
     10 + - Buffer Over-read (simulated)
     11 + - Command Execution
     12 + - SQL Injection
     13 + - Enumeration
     14 + - XML
     15 + - Horizontal Access Control
     16 + - Vertical Access Control
  • ■ ■ ■ ■ ■ ■
    LICENSE.md
     1 +### GNU GENERAL PUBLIC LICENSE
     2 + 
     3 +Version 3, 29 June 2007
     4 + 
     5 +Copyright (C) 2007 Free Software Foundation, Inc.
     6 +<https://fsf.org/>
     7 + 
     8 +Everyone is permitted to copy and distribute verbatim copies of this
     9 +license document, but changing it is not allowed.
     10 + 
     11 +### Preamble
     12 + 
     13 +The GNU General Public License is a free, copyleft license for
     14 +software and other kinds of works.
     15 + 
     16 +The licenses for most software and other practical works are designed
     17 +to take away your freedom to share and change the works. By contrast,
     18 +the GNU General Public License is intended to guarantee your freedom
     19 +to share and change all versions of a program--to make sure it remains
     20 +free software for all its users. We, the Free Software Foundation, use
     21 +the GNU General Public License for most of our software; it applies
     22 +also to any other work released this way by its authors. You can apply
     23 +it to your programs, too.
     24 + 
     25 +When we speak of free software, we are referring to freedom, not
     26 +price. Our General Public Licenses are designed to make sure that you
     27 +have the freedom to distribute copies of free software (and charge for
     28 +them if you wish), that you receive source code or can get it if you
     29 +want it, that you can change the software or use pieces of it in new
     30 +free programs, and that you know you can do these things.
     31 + 
     32 +To protect your rights, we need to prevent others from denying you
     33 +these rights or asking you to surrender the rights. Therefore, you
     34 +have certain responsibilities if you distribute copies of the
     35 +software, or if you modify it: responsibilities to respect the freedom
     36 +of others.
     37 + 
     38 +For example, if you distribute copies of such a program, whether
     39 +gratis or for a fee, you must pass on to the recipients the same
     40 +freedoms that you received. You must make sure that they, too, receive
     41 +or can get the source code. And you must show them these terms so they
     42 +know their rights.
     43 + 
     44 +Developers that use the GNU GPL protect your rights with two steps:
     45 +(1) assert copyright on the software, and (2) offer you this License
     46 +giving you legal permission to copy, distribute and/or modify it.
     47 + 
     48 +For the developers' and authors' protection, the GPL clearly explains
     49 +that there is no warranty for this free software. For both users' and
     50 +authors' sake, the GPL requires that modified versions be marked as
     51 +changed, so that their problems will not be attributed erroneously to
     52 +authors of previous versions.
     53 + 
     54 +Some devices are designed to deny users access to install or run
     55 +modified versions of the software inside them, although the
     56 +manufacturer can do so. This is fundamentally incompatible with the
     57 +aim of protecting users' freedom to change the software. The
     58 +systematic pattern of such abuse occurs in the area of products for
     59 +individuals to use, which is precisely where it is most unacceptable.
     60 +Therefore, we have designed this version of the GPL to prohibit the
     61 +practice for those products. If such problems arise substantially in
     62 +other domains, we stand ready to extend this provision to those
     63 +domains in future versions of the GPL, as needed to protect the
     64 +freedom of users.
     65 + 
     66 +Finally, every program is threatened constantly by software patents.
     67 +States should not allow patents to restrict development and use of
     68 +software on general-purpose computers, but in those that do, we wish
     69 +to avoid the special danger that patents applied to a free program
     70 +could make it effectively proprietary. To prevent this, the GPL
     71 +assures that patents cannot be used to render the program non-free.
     72 + 
     73 +The precise terms and conditions for copying, distribution and
     74 +modification follow.
     75 + 
     76 +### TERMS AND CONDITIONS
     77 + 
     78 +#### 0. Definitions.
     79 + 
     80 +"This License" refers to version 3 of the GNU General Public License.
     81 + 
     82 +"Copyright" also means copyright-like laws that apply to other kinds
     83 +of works, such as semiconductor masks.
     84 + 
     85 +"The Program" refers to any copyrightable work licensed under this
     86 +License. Each licensee is addressed as "you". "Licensees" and
     87 +"recipients" may be individuals or organizations.
     88 + 
     89 +To "modify" a work means to copy from or adapt all or part of the work
     90 +in a fashion requiring copyright permission, other than the making of
     91 +an exact copy. The resulting work is called a "modified version" of
     92 +the earlier work or a work "based on" the earlier work.
     93 + 
     94 +A "covered work" means either the unmodified Program or a work based
     95 +on the Program.
     96 + 
     97 +To "propagate" a work means to do anything with it that, without
     98 +permission, would make you directly or secondarily liable for
     99 +infringement under applicable copyright law, except executing it on a
     100 +computer or modifying a private copy. Propagation includes copying,
     101 +distribution (with or without modification), making available to the
     102 +public, and in some countries other activities as well.
     103 + 
     104 +To "convey" a work means any kind of propagation that enables other
     105 +parties to make or receive copies. Mere interaction with a user
     106 +through a computer network, with no transfer of a copy, is not
     107 +conveying.
     108 + 
     109 +An interactive user interface displays "Appropriate Legal Notices" to
     110 +the extent that it includes a convenient and prominently visible
     111 +feature that (1) displays an appropriate copyright notice, and (2)
     112 +tells the user that there is no warranty for the work (except to the
     113 +extent that warranties are provided), that licensees may convey the
     114 +work under this License, and how to view a copy of this License. If
     115 +the interface presents a list of user commands or options, such as a
     116 +menu, a prominent item in the list meets this criterion.
     117 + 
     118 +#### 1. Source Code.
     119 + 
     120 +The "source code" for a work means the preferred form of the work for
     121 +making modifications to it. "Object code" means any non-source form of
     122 +a work.
     123 + 
     124 +A "Standard Interface" means an interface that either is an official
     125 +standard defined by a recognized standards body, or, in the case of
     126 +interfaces specified for a particular programming language, one that
     127 +is widely used among developers working in that language.
     128 + 
     129 +The "System Libraries" of an executable work include anything, other
     130 +than the work as a whole, that (a) is included in the normal form of
     131 +packaging a Major Component, but which is not part of that Major
     132 +Component, and (b) serves only to enable use of the work with that
     133 +Major Component, or to implement a Standard Interface for which an
     134 +implementation is available to the public in source code form. A
     135 +"Major Component", in this context, means a major essential component
     136 +(kernel, window system, and so on) of the specific operating system
     137 +(if any) on which the executable work runs, or a compiler used to
     138 +produce the work, or an object code interpreter used to run it.
     139 + 
     140 +The "Corresponding Source" for a work in object code form means all
     141 +the source code needed to generate, install, and (for an executable
     142 +work) run the object code and to modify the work, including scripts to
     143 +control those activities. However, it does not include the work's
     144 +System Libraries, or general-purpose tools or generally available free
     145 +programs which are used unmodified in performing those activities but
     146 +which are not part of the work. For example, Corresponding Source
     147 +includes interface definition files associated with source files for
     148 +the work, and the source code for shared libraries and dynamically
     149 +linked subprograms that the work is specifically designed to require,
     150 +such as by intimate data communication or control flow between those
     151 +subprograms and other parts of the work.
     152 + 
     153 +The Corresponding Source need not include anything that users can
     154 +regenerate automatically from other parts of the Corresponding Source.
     155 + 
     156 +The Corresponding Source for a work in source code form is that same
     157 +work.
     158 + 
     159 +#### 2. Basic Permissions.
     160 + 
     161 +All rights granted under this License are granted for the term of
     162 +copyright on the Program, and are irrevocable provided the stated
     163 +conditions are met. This License explicitly affirms your unlimited
     164 +permission to run the unmodified Program. The output from running a
     165 +covered work is covered by this License only if the output, given its
     166 +content, constitutes a covered work. This License acknowledges your
     167 +rights of fair use or other equivalent, as provided by copyright law.
     168 + 
     169 +You may make, run and propagate covered works that you do not convey,
     170 +without conditions so long as your license otherwise remains in force.
     171 +You may convey covered works to others for the sole purpose of having
     172 +them make modifications exclusively for you, or provide you with
     173 +facilities for running those works, provided that you comply with the
     174 +terms of this License in conveying all material for which you do not
     175 +control copyright. Those thus making or running the covered works for
     176 +you must do so exclusively on your behalf, under your direction and
     177 +control, on terms that prohibit them from making any copies of your
     178 +copyrighted material outside their relationship with you.
     179 + 
     180 +Conveying under any other circumstances is permitted solely under the
     181 +conditions stated below. Sublicensing is not allowed; section 10 makes
     182 +it unnecessary.
     183 + 
     184 +#### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
     185 + 
     186 +No covered work shall be deemed part of an effective technological
     187 +measure under any applicable law fulfilling obligations under article
     188 +11 of the WIPO copyright treaty adopted on 20 December 1996, or
     189 +similar laws prohibiting or restricting circumvention of such
     190 +measures.
     191 + 
     192 +When you convey a covered work, you waive any legal power to forbid
     193 +circumvention of technological measures to the extent such
     194 +circumvention is effected by exercising rights under this License with
     195 +respect to the covered work, and you disclaim any intention to limit
     196 +operation or modification of the work as a means of enforcing, against
     197 +the work's users, your or third parties' legal rights to forbid
     198 +circumvention of technological measures.
     199 + 
     200 +#### 4. Conveying Verbatim Copies.
     201 + 
     202 +You may convey verbatim copies of the Program's source code as you
     203 +receive it, in any medium, provided that you conspicuously and
     204 +appropriately publish on each copy an appropriate copyright notice;
     205 +keep intact all notices stating that this License and any
     206 +non-permissive terms added in accord with section 7 apply to the code;
     207 +keep intact all notices of the absence of any warranty; and give all
     208 +recipients a copy of this License along with the Program.
     209 + 
     210 +You may charge any price or no price for each copy that you convey,
     211 +and you may offer support or warranty protection for a fee.
     212 + 
     213 +#### 5. Conveying Modified Source Versions.
     214 + 
     215 +You may convey a work based on the Program, or the modifications to
     216 +produce it from the Program, in the form of source code under the
     217 +terms of section 4, provided that you also meet all of these
     218 +conditions:
     219 + 
     220 +- a) The work must carry prominent notices stating that you modified
     221 + it, and giving a relevant date.
     222 +- b) The work must carry prominent notices stating that it is
     223 + released under this License and any conditions added under
     224 + section 7. This requirement modifies the requirement in section 4
     225 + to "keep intact all notices".
     226 +- c) You must license the entire work, as a whole, under this
     227 + License to anyone who comes into possession of a copy. This
     228 + License will therefore apply, along with any applicable section 7
     229 + additional terms, to the whole of the work, and all its parts,
     230 + regardless of how they are packaged. This License gives no
     231 + permission to license the work in any other way, but it does not
     232 + invalidate such permission if you have separately received it.
     233 +- d) If the work has interactive user interfaces, each must display
     234 + Appropriate Legal Notices; however, if the Program has interactive
     235 + interfaces that do not display Appropriate Legal Notices, your
     236 + work need not make them do so.
     237 + 
     238 +A compilation of a covered work with other separate and independent
     239 +works, which are not by their nature extensions of the covered work,
     240 +and which are not combined with it such as to form a larger program,
     241 +in or on a volume of a storage or distribution medium, is called an
     242 +"aggregate" if the compilation and its resulting copyright are not
     243 +used to limit the access or legal rights of the compilation's users
     244 +beyond what the individual works permit. Inclusion of a covered work
     245 +in an aggregate does not cause this License to apply to the other
     246 +parts of the aggregate.
     247 + 
     248 +#### 6. Conveying Non-Source Forms.
     249 + 
     250 +You may convey a covered work in object code form under the terms of
     251 +sections 4 and 5, provided that you also convey the machine-readable
     252 +Corresponding Source under the terms of this License, in one of these
     253 +ways:
     254 + 
     255 +- a) Convey the object code in, or embodied in, a physical product
     256 + (including a physical distribution medium), accompanied by the
     257 + Corresponding Source fixed on a durable physical medium
     258 + customarily used for software interchange.
     259 +- b) Convey the object code in, or embodied in, a physical product
     260 + (including a physical distribution medium), accompanied by a
     261 + written offer, valid for at least three years and valid for as
     262 + long as you offer spare parts or customer support for that product
     263 + model, to give anyone who possesses the object code either (1) a
     264 + copy of the Corresponding Source for all the software in the
     265 + product that is covered by this License, on a durable physical
     266 + medium customarily used for software interchange, for a price no
     267 + more than your reasonable cost of physically performing this
     268 + conveying of source, or (2) access to copy the Corresponding
     269 + Source from a network server at no charge.
     270 +- c) Convey individual copies of the object code with a copy of the
     271 + written offer to provide the Corresponding Source. This
     272 + alternative is allowed only occasionally and noncommercially, and
     273 + only if you received the object code with such an offer, in accord
     274 + with subsection 6b.
     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 +- e) Convey the object code using peer-to-peer transmission,
     288 + provided you inform other peers where the object code and
     289 + Corresponding Source of the work are being offered to the general
     290 + public at no charge under subsection 6d.
     291 + 
     292 +A separable portion of the object code, whose source code is excluded
     293 +from the Corresponding Source as a System Library, need not be
     294 +included in conveying the object code work.
     295 + 
     296 +A "User Product" is either (1) a "consumer product", which means any
     297 +tangible personal property which is normally used for personal,
     298 +family, or household purposes, or (2) anything designed or sold for
     299 +incorporation into a dwelling. In determining whether a product is a
     300 +consumer product, doubtful cases shall be resolved in favor of
     301 +coverage. For a particular product received by a particular user,
     302 +"normally used" refers to a typical or common use of that class of
     303 +product, regardless of the status of the particular user or of the way
     304 +in which the particular user actually uses, or expects or is expected
     305 +to use, the product. A product is a consumer product regardless of
     306 +whether the product has substantial commercial, industrial or
     307 +non-consumer uses, unless such uses represent the only significant
     308 +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
     312 +install and execute modified versions of a covered work in that User
     313 +Product from a modified version of its Corresponding Source. The
     314 +information must suffice to ensure that the continued functioning of
     315 +the modified object code is in no case prevented or interfered with
     316 +solely because 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
     331 +updates for a work that has been modified or installed by the
     332 +recipient, or for the User Product in which it has been modified or
     333 +installed. Access to a network may be denied when the modification
     334 +itself materially and adversely affects the operation of the network
     335 +or violates the rules and protocols for communication across the
     336 +network.
     337 + 
     338 +Corresponding Source conveyed, and Installation Information provided,
     339 +in accord with this section must be in a format that is publicly
     340 +documented (and with an implementation available to the public in
     341 +source code form), and must require no special password or key for
     342 +unpacking, reading or copying.
     343 + 
     344 +#### 7. Additional Terms.
     345 + 
     346 +"Additional permissions" are terms that supplement the terms of this
     347 +License by making exceptions from one or more of its conditions.
     348 +Additional permissions that are applicable to the entire Program shall
     349 +be treated as though they were included in this License, to the extent
     350 +that they are valid under applicable law. If additional permissions
     351 +apply only to part of the Program, that part may be used separately
     352 +under those permissions, but the entire Program remains governed by
     353 +this License without regard to the additional permissions.
     354 + 
     355 +When you convey a copy of a covered work, you may at your option
     356 +remove any additional permissions from that copy, or from any part of
     357 +it. (Additional permissions may be written to require their own
     358 +removal in certain cases when you modify the work.) You may place
     359 +additional permissions on material, added by you to a covered work,
     360 +for which you have or can give appropriate copyright permission.
     361 + 
     362 +Notwithstanding any other provision of this License, for material you
     363 +add to a covered work, you may (if authorized by the copyright holders
     364 +of that material) supplement the terms of this License with terms:
     365 + 
     366 +- a) Disclaiming warranty or limiting liability differently from the
     367 + terms of sections 15 and 16 of this License; or
     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 +- c) Prohibiting misrepresentation of the origin of that material,
     372 + or requiring that modified versions of such material be marked in
     373 + reasonable ways as different from the original version; or
     374 +- d) Limiting the use for publicity purposes of names of licensors
     375 + or authors of the material; or
     376 +- e) Declining to grant rights under trademark law for use of some
     377 + trade names, trademarks, or service marks; or
     378 +- f) Requiring indemnification of licensors and authors of that
     379 + material by anyone who conveys the material (or modified versions
     380 + of it) with contractual assumptions of liability to the recipient,
     381 + for any liability that these contractual assumptions directly
     382 + impose on those licensors and authors.
     383 + 
     384 +All other non-permissive additional terms are considered "further
     385 +restrictions" within the meaning of section 10. If the Program as you
     386 +received it, or any part of it, contains a notice stating that it is
     387 +governed by this License along with a term that is a further
     388 +restriction, you may remove that term. If a license document contains
     389 +a further restriction but permits relicensing or conveying under this
     390 +License, you may add to a covered work material governed by the terms
     391 +of that license document, provided that the further restriction does
     392 +not survive such relicensing or conveying.
     393 + 
     394 +If you add terms to a covered work in accord with this section, you
     395 +must place, in the relevant source files, a statement of the
     396 +additional terms that apply to those files, or a notice indicating
     397 +where to find the applicable terms.
     398 + 
     399 +Additional terms, permissive or non-permissive, may be stated in the
     400 +form of a separately written license, or stated as exceptions; the
     401 +above requirements apply either way.
     402 + 
     403 +#### 8. Termination.
     404 + 
     405 +You may not propagate or modify a covered work except as expressly
     406 +provided under this License. Any attempt otherwise to propagate or
     407 +modify it is void, and will automatically terminate your rights under
     408 +this License (including any patent licenses granted under the third
     409 +paragraph of section 11).
     410 + 
     411 +However, if you cease all violation of this License, then your license
     412 +from a particular copyright holder is reinstated (a) provisionally,
     413 +unless and until the copyright holder explicitly and finally
     414 +terminates your license, and (b) permanently, if the copyright holder
     415 +fails to notify you of the violation by some reasonable means prior to
     416 +60 days after the cessation.
     417 + 
     418 +Moreover, your license from a particular copyright holder is
     419 +reinstated permanently if the copyright holder notifies you of the
     420 +violation by some reasonable means, this is the first time you have
     421 +received notice of violation of this License (for any work) from that
     422 +copyright holder, and you cure the violation prior to 30 days after
     423 +your receipt of the notice.
     424 + 
     425 +Termination of your rights under this section does not terminate the
     426 +licenses of parties who have received copies or rights from you under
     427 +this License. If your rights have been terminated and not permanently
     428 +reinstated, you do not qualify to receive new licenses for the same
     429 +material under section 10.
     430 + 
     431 +#### 9. Acceptance Not Required for Having Copies.
     432 + 
     433 +You are not required to accept this License in order to receive or run
     434 +a copy of the Program. Ancillary propagation of a covered work
     435 +occurring solely as a consequence of using peer-to-peer transmission
     436 +to receive a copy likewise does not require acceptance. However,
     437 +nothing other than this License grants you permission to propagate or
     438 +modify any covered work. These actions infringe copyright if you do
     439 +not accept this License. Therefore, by modifying or propagating a
     440 +covered work, you indicate your acceptance of this License to do so.
     441 + 
     442 +#### 10. Automatic Licensing of Downstream Recipients.
     443 + 
     444 +Each time you convey a covered work, the recipient automatically
     445 +receives a license from the original licensors, to run, modify and
     446 +propagate that work, subject to this License. You are not responsible
     447 +for enforcing compliance by third parties with this License.
     448 + 
     449 +An "entity transaction" is a transaction transferring control of an
     450 +organization, or substantially all assets of one, or subdividing an
     451 +organization, or merging organizations. If propagation of a covered
     452 +work results from an entity transaction, each party to that
     453 +transaction who receives a copy of the work also receives whatever
     454 +licenses to the work the party's predecessor in interest had or could
     455 +give under the previous paragraph, plus a right to possession of the
     456 +Corresponding Source of the work from the predecessor in interest, if
     457 +the predecessor has it or can get it with reasonable efforts.
     458 + 
     459 +You may not impose any further restrictions on the exercise of the
     460 +rights granted or affirmed under this License. For example, you may
     461 +not impose a license fee, royalty, or other charge for exercise of
     462 +rights granted under this License, and you may not initiate litigation
     463 +(including a cross-claim or counterclaim in a lawsuit) alleging that
     464 +any patent claim is infringed by making, using, selling, offering for
     465 +sale, or importing the Program or any portion of it.
     466 + 
     467 +#### 11. Patents.
     468 + 
     469 +A "contributor" is a copyright holder who authorizes use under this
     470 +License of the Program or a work on which the Program is based. The
     471 +work thus licensed is called the contributor's "contributor version".
     472 + 
     473 +A contributor's "essential patent claims" are all patent claims owned
     474 +or controlled by the contributor, whether already acquired or
     475 +hereafter acquired, that would be infringed by some manner, permitted
     476 +by this License, of making, using, or selling its contributor version,
     477 +but do not include claims that would be infringed only as a
     478 +consequence of further modification of the contributor version. For
     479 +purposes of this definition, "control" includes the right to grant
     480 +patent sublicenses in a manner consistent with the requirements of
     481 +this License.
     482 + 
     483 +Each contributor grants you a non-exclusive, worldwide, royalty-free
     484 +patent license under the contributor's essential patent claims, to
     485 +make, use, sell, offer for sale, import and otherwise run, modify and
     486 +propagate the contents of its contributor version.
     487 + 
     488 +In the following three paragraphs, a "patent license" is any express
     489 +agreement or commitment, however denominated, not to enforce a patent
     490 +(such as an express permission to practice a patent or covenant not to
     491 +sue for patent infringement). To "grant" such a patent license to a
     492 +party means to make such an agreement or commitment not to enforce a
     493 +patent against the party.
     494 + 
     495 +If you convey a covered work, knowingly relying on a patent license,
     496 +and the Corresponding Source of the work is not available for anyone
     497 +to copy, free of charge and under the terms of this License, through a
     498 +publicly available network server or other readily accessible means,
     499 +then you must either (1) cause the Corresponding Source to be so
     500 +available, or (2) arrange to deprive yourself of the benefit of the
     501 +patent license for this particular work, or (3) arrange, in a manner
     502 +consistent with the requirements of this License, to extend the patent
     503 +license to downstream recipients. "Knowingly relying" means you have
     504 +actual knowledge that, but for the patent license, your conveying the
     505 +covered work in a country, or your recipient's use of the covered work
     506 +in a country, would infringe one or more identifiable patents in that
     507 +country that you have reason to believe are valid.
     508 + 
     509 +If, pursuant to or in connection with a single transaction or
     510 +arrangement, you convey, or propagate by procuring conveyance of, a
     511 +covered work, and grant a patent license to some of the parties
     512 +receiving the covered work authorizing them to use, propagate, modify
     513 +or convey a specific copy of the covered work, then the patent license
     514 +you grant is automatically extended to all recipients of the covered
     515 +work and works based on it.
     516 + 
     517 +A patent license is "discriminatory" if it does not include within the
     518 +scope of its coverage, prohibits the exercise of, or is conditioned on
     519 +the non-exercise of one or more of the rights that are specifically
     520 +granted under this License. You may not convey a covered work if you
     521 +are a party to an arrangement with a third party that is in the
     522 +business of distributing software, under which you make payment to the
     523 +third party based on the extent of your activity of conveying the
     524 +work, and under which the third party grants, to any of the parties
     525 +who would receive the covered work from you, a discriminatory patent
     526 +license (a) in connection with copies of the covered work conveyed by
     527 +you (or copies made from those copies), or (b) primarily for and in
     528 +connection with specific products or compilations that contain the
     529 +covered work, unless you entered into that arrangement, or that patent
     530 +license was granted, prior to 28 March 2007.
     531 + 
     532 +Nothing in this License shall be construed as excluding or limiting
     533 +any implied license or other defenses to infringement that may
     534 +otherwise be available to you under applicable patent law.
     535 + 
     536 +#### 12. No Surrender of Others' Freedom.
     537 + 
     538 +If conditions are imposed on you (whether by court order, agreement or
     539 +otherwise) that contradict the conditions of this License, they do not
     540 +excuse you from the conditions of this License. If you cannot convey a
     541 +covered work so as to satisfy simultaneously your obligations under
     542 +this License and any other pertinent obligations, then as a
     543 +consequence you may not convey it at all. For example, if you agree to
     544 +terms that obligate you to collect a royalty for further conveying
     545 +from those to whom you convey the Program, the only way you could
     546 +satisfy both those terms and this License would be to refrain entirely
     547 +from conveying the Program.
     548 + 
     549 +#### 13. Use with the GNU Affero General Public License.
     550 + 
     551 +Notwithstanding any other provision of this License, you have
     552 +permission to link or combine any covered work with a work licensed
     553 +under version 3 of the GNU Affero General Public License into a single
     554 +combined work, and to convey the resulting work. The terms of this
     555 +License will continue to apply to the part which is the covered work,
     556 +but the special requirements of the GNU Affero General Public License,
     557 +section 13, concerning interaction through a network will apply to the
     558 +combination as such.
     559 + 
     560 +#### 14. Revised Versions of this License.
     561 + 
     562 +The Free Software Foundation may publish revised and/or new versions
     563 +of the GNU General Public License from time to time. Such new versions
     564 +will be similar in spirit to the present version, but may differ in
     565 +detail to address new problems or concerns.
     566 + 
     567 +Each version is given a distinguishing version number. If the Program
     568 +specifies that a certain numbered version of the GNU General Public
     569 +License "or any later version" applies to it, you have the option of
     570 +following the terms and conditions either of that numbered version or
     571 +of any later version published by the Free Software Foundation. If the
     572 +Program does not specify a version number of the GNU General Public
     573 +License, you may choose any version ever published by the Free
     574 +Software Foundation.
     575 + 
     576 +If the Program specifies that a proxy can decide which future versions
     577 +of the GNU General Public License can be used, that proxy's public
     578 +statement of acceptance of a version permanently authorizes you to
     579 +choose that version for the Program.
     580 + 
     581 +Later license versions may give you additional or different
     582 +permissions. However, no additional obligations are imposed on any
     583 +author or copyright holder as a result of your choosing to follow a
     584 +later version.
     585 + 
     586 +#### 15. Disclaimer of Warranty.
     587 + 
     588 +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
     589 +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
     590 +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
     591 +WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
     592 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     593 +A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
     594 +PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
     595 +DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
     596 +CORRECTION.
     597 + 
     598 +#### 16. Limitation of Liability.
     599 + 
     600 +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
     601 +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
     602 +CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
     603 +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
     604 +ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
     605 +NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
     606 +LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM
     607 +TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
     608 +PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
     609 + 
     610 +#### 17. Interpretation of Sections 15 and 16.
     611 + 
     612 +If the disclaimer of warranty and limitation of liability provided
     613 +above cannot be given local legal effect according to their terms,
     614 +reviewing courts shall apply local law that most closely approximates
     615 +an absolute waiver of all civil liability in connection with the
     616 +Program, unless a warranty or assumption of liability accompanies a
     617 +copy of the Program in return for a fee.
     618 + 
     619 +END OF TERMS AND CONDITIONS
     620 + 
     621 +### How to Apply These Terms to Your New Programs
     622 + 
     623 +If you develop a new program, and you want it to be of the greatest
     624 +possible use to the public, the best way to achieve this is to make it
     625 +free software which everyone can redistribute and change under these
     626 +terms.
     627 + 
     628 +To do so, attach the following notices to the program. It is safest to
     629 +attach them to the start of each source file to most effectively state
     630 +the exclusion of warranty; and each file should have at least the
     631 +"copyright" line and a pointer to where the full notice is found.
     632 + 
     633 + <one line to give the program's name and a brief idea of what it does.>
     634 + Copyright (C) <year> <name of author>
     635 + 
     636 + This program is free software: you can redistribute it and/or modify
     637 + it under the terms of the GNU General Public License as published by
     638 + the Free Software Foundation, either version 3 of the License, or
     639 + (at your option) any later version.
     640 + 
     641 + This program is distributed in the hope that it will be useful,
     642 + but WITHOUT ANY WARRANTY; without even the implied warranty of
     643 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     644 + GNU General Public License for more details.
     645 + 
     646 + You should have received a copy of the GNU General Public License
     647 + along with this program. If not, see <https://www.gnu.org/licenses/>.
     648 + 
     649 +Also add information on how to contact you by electronic and paper
     650 +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 + <program> Copyright (C) <year> <name of author>
     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
     661 +appropriate parts of the General Public License. Of course, your
     662 +program's commands might be different; for a GUI interface, you would
     663 +use an "about box".
     664 + 
     665 +You should also get your employer (if you work as a programmer) or
     666 +school, if any, to sign a "copyright disclaimer" for the program, if
     667 +necessary. For more information on this, and how to apply and follow
     668 +the GNU GPL, see <https://www.gnu.org/licenses/>.
     669 + 
     670 +The GNU General Public License does not permit incorporating your
     671 +program into proprietary programs. If your program is a subroutine
     672 +library, you may consider it more useful to permit linking proprietary
     673 +applications with the library. If this is what you want to do, use the
     674 +GNU Lesser General Public License instead of this License. But first,
     675 +please read <https://www.gnu.org/licenses/why-not-lgpl.html>.
     676 + 
  • ■ ■ ■ ■ ■ ■
    README.md
     1 +# ![Vulnerable Client-Server Application (VuCSA)](http://vucsa.warxim.com/img/logo.png)
     2 +# Vulnerable Client-Server Application (VuCSA)
     3 +Vulnerable client-server application (VuCSA) is made for learning/presenting how to perform penetration tests of non-http thick clients.
     4 +It is written in Java (with JavaFX graphical user interface).
     5 + 
     6 +Currently the vulnerable application contains the following challenges:
     7 +1. Buffer Over-read (simulated)
     8 +2. Command Execution
     9 +3. SQL Injection
     10 +4. Enumeration
     11 +5. XML
     12 +6. Horizontal Access Control
     13 +7. Vertical Access Control
     14 + 
     15 +If you want to know how to solve these challenges, take a look at the [PETEP website](http://petep.warxim.com/methodology/),
     16 +which describes how to use the open-source tool PETEP to exploit them.
     17 + 
     18 +**Tip:** Before you start hacking, do not forget to check the data structure of messages bellow.
     19 + 
     20 +## How to Run
     21 +In order to run the vulnerable server and client, you can use one of releases on GitHub
     22 +or run gradle assemble, which creates distribution packages (for both Windows and Unix).
     23 +These packages contain sh/bat scripts that will run the server and client using JVM.
     24 + 
     25 +## Project Structure
     26 +Project is divided into three modules:
     27 +- **vulnerable-common** - common functionality for both client and server (including protocol processing utilities)
     28 +- **vulnerable-client** - vulnerable client with JavaFX GUI
     29 +- **vulnerable-server** - vulnerable server for terminal use
     30 + 
     31 +## Data Structure
     32 +Messages transmitted between server and client have the following simple format:
     33 + 
     34 + [type][target][length][payload]
     35 + 32b 32b 32b ???
     36 + 
     37 +These four parts have the following meaning:
     38 +- **type** - type of the message (used for serialization/deserialization)
     39 +- **target** - target handler that will receive the message
     40 +- **length** - length of the payload
     41 +- **payload** - data serialized into bytes
     42 + 
  • ■ ■ ■ ■ ■ ■
    build.gradle
     1 +plugins {
     2 + id 'java'
     3 + id 'application'
     4 +}
     5 + 
     6 +group 'com.warxim'
     7 +version '1.0'
     8 + 
     9 +repositories {
     10 + mavenCentral()
     11 +}
     12 + 
     13 +dependencies {
     14 + compile project(":vucsa-common")
     15 + compile project(":vucsa-client")
     16 + compile project(":vucsa-server")
     17 +}
     18 + 
     19 +distributions {
     20 + main {
     21 + distributionBaseName = "vucsa"
     22 + contents {
     23 + from("LICENSE.md") {
     24 + into ""
     25 + }
     26 + 
     27 + from("CHANGELOG.md") {
     28 + into ""
     29 + }
     30 + 
     31 + from("scripts") {
     32 + into ""
     33 + }
     34 + 
     35 + from("vucsa-server/server") {
     36 + into "server"
     37 + }
     38 + 
     39 + startScripts.onlyIf {false}
     40 + }
     41 + }
     42 +}
  • ■ ■ ■ ■ ■ ■
    scripts/client.bat
     1 +@echo off
     2 +set JAVA_EXE=java.exe
     3 +set JAVAW_EXE=javaw.exe
     4 +set DIRNAME=%~dp0
     5 +set APP_HOME=%DIRNAME%
     6 +set CMD_LINE_ARGS=%*
     7 +set DEFAULT_JVM_OPTS=
     8 +set CLASSPATH=%APP_HOME%\lib\*
     9 +set MAIN_CLASS="com.warxim.vucsa.client.Main"
     10 + 
     11 +rem Start Vulnerable Client with GUI (without console).
     12 +start "" /b "%JAVAW_EXE%" %DEFAULT_JVM_OPTS% -classpath "%CLASSPATH%" %MAIN_CLASS% %CMD_LINE_ARGS%
     13 + 
  • ■ ■ ■ ■ ■ ■
    scripts/client.sh
     1 +#!/bin/bash
     2 + 
     3 +JAVA="java"
     4 +APP_HOME="`pwd`"
     5 +DEFAULT_JVM_OPTS=
     6 +CMD_LINE_ARGS=$@
     7 +CLASSPATH=$APP_HOME/lib/*
     8 +MAIN_CLASS="com.warxim.vucsa.client.Main"
     9 +LOG_FILE=client.log
     10 + 
     11 +nohup $JAVA -cp "$CLASSPATH" $MAIN_CLASS $CMD_LINE_ARGS > $LOG_FILE &
     12 + 
  • ■ ■ ■ ■ ■ ■
    scripts/server.bat
     1 +@echo off
     2 +set JAVA_EXE=java.exe
     3 +set JAVAW_EXE=javaw.exe
     4 +set DIRNAME=%~dp0
     5 +set APP_HOME=%DIRNAME%
     6 +set CMD_LINE_ARGS=%*
     7 +set DEFAULT_JVM_OPTS=
     8 +set CLASSPATH=%APP_HOME%\lib\*
     9 +set MAIN_CLASS="com.warxim.vucsa.server.Main"
     10 + 
     11 +rem Start Vulnerable Server without GUI (let console open).
     12 +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% -classpath "%CLASSPATH%" %MAIN_CLASS% %CMD_LINE_ARGS%
     13 + 
  • ■ ■ ■ ■ ■ ■
    scripts/server.sh
     1 +#!/bin/bash
     2 + 
     3 +JAVA="java"
     4 +APP_HOME="`pwd`"
     5 +DEFAULT_JVM_OPTS=
     6 +CMD_LINE_ARGS=$@
     7 +CLASSPATH=$APP_HOME/lib/*
     8 +MAIN_CLASS="com.warxim.vucsa.server.Main"
     9 +LOG_FILE=server.log
     10 + 
     11 +$JAVA -cp "$CLASSPATH" $MAIN_CLASS $CMD_LINE_ARGS
     12 + 
  • ■ ■ ■ ■ ■ ■
    settings.gradle
     1 +rootProject.name = 'VuCSA'
     2 + 
     3 +include 'vucsa-common'
     4 +include 'vucsa-client'
     5 +include 'vucsa-server'
     6 + 
     7 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/build.gradle
     1 +plugins {
     2 + id 'java-library'
     3 + id 'java'
     4 + id 'eclipse'
     5 + id 'application'
     6 + id 'org.openjfx.javafxplugin' version '0.0.13'
     7 +}
     8 + 
     9 +javafx {
     10 + version = "11.0.2"
     11 + modules = ['javafx.controls', 'javafx.fxml', 'javafx.web']
     12 +}
     13 + 
     14 +group 'com.warxim'
     15 +version '1.0'
     16 +mainClassName = 'com.warxim.vucsa.client.Main'
     17 + 
     18 +repositories {
     19 + mavenCentral()
     20 +}
     21 + 
     22 +dependencies {
     23 + implementation project(':vucsa-common')
     24 + 
     25 + compileOnly 'org.projectlombok:lombok:1.18.24'
     26 + annotationProcessor 'org.projectlombok:lombok:1.18.24'
     27 + 
     28 + implementation group: 'org.openjfx', name: 'javafx-base', version: javafx.version, classifier: 'win'
     29 + implementation group: 'org.openjfx', name: 'javafx-base', version: javafx.version, classifier: 'mac'
     30 + implementation group: 'org.openjfx', name: 'javafx-base', version: javafx.version, classifier: 'linux'
     31 + implementation group: 'org.openjfx', name: 'javafx-controls', version: javafx.version, classifier: 'win'
     32 + implementation group: 'org.openjfx', name: 'javafx-controls', version: javafx.version, classifier: 'mac'
     33 + implementation group: 'org.openjfx', name: 'javafx-controls', version: javafx.version, classifier: 'linux'
     34 + implementation group: 'org.openjfx', name: 'javafx-fxml', version: javafx.version, classifier: 'win'
     35 + implementation group: 'org.openjfx', name: 'javafx-fxml', version: javafx.version, classifier: 'mac'
     36 + implementation group: 'org.openjfx', name: 'javafx-fxml', version: javafx.version, classifier: 'linux'
     37 + implementation group: 'org.openjfx', name: 'javafx-graphics', version: javafx.version, classifier: 'win'
     38 + implementation group: 'org.openjfx', name: 'javafx-graphics', version: javafx.version, classifier: 'mac'
     39 + implementation group: 'org.openjfx', name: 'javafx-graphics', version: javafx.version, classifier: 'linux'
     40 + implementation group: 'org.openjfx', name: 'javafx-media', version: javafx.version, classifier: 'win'
     41 + implementation group: 'org.openjfx', name: 'javafx-media', version: javafx.version, classifier: 'mac'
     42 + implementation group: 'org.openjfx', name: 'javafx-media', version: javafx.version, classifier: 'linux'
     43 + implementation group: 'org.openjfx', name: 'javafx-web', version: javafx.version, classifier: 'win'
     44 + implementation group: 'org.openjfx', name: 'javafx-web', version: javafx.version, classifier: 'mac'
     45 + implementation group: 'org.openjfx', name: 'javafx-web', version: javafx.version, classifier: 'linux'
     46 +}
     47 + 
     48 +// Export com.sun.javafx.css (for css editing)
     49 +application {
     50 + applicationDefaultJvmArgs = [
     51 + "--add-opens=javafx.graphics/com.sun.javafx.css=ALL-UNNAMED"
     52 + ]
     53 + executableDir = ''
     54 +}
     55 + 
     56 +// Set run working directory to build/run
     57 +File runningDir = new File('build/run')
     58 +runningDir.mkdirs()
     59 +tasks.run.workingDir = runningDir
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/Bundle.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client;
     18 + 
     19 +import com.warxim.vucsa.client.core.ClientManager;
     20 +import lombok.Getter;
     21 + 
     22 +/**
     23 + * Singleton for client assets.
     24 + */
     25 +@Getter
     26 +public final class Bundle {
     27 + /**
     28 + * Singleton instance.
     29 + */
     30 + private static volatile Bundle instance;
     31 + 
     32 + /**
     33 + * Client manager
     34 + */
     35 + private final ClientManager clientManager;
     36 + 
     37 + private Bundle() {
     38 + clientManager = new ClientManager();
     39 + }
     40 + 
     41 + /**
     42 + * Creates instance of bundle or returns existing instance if it exists.
     43 + * @return Bundle instance
     44 + */
     45 + public static Bundle getInstance() {
     46 + if (instance == null) {
     47 + synchronized(Bundle.class) {
     48 + if (instance == null) {
     49 + instance = new Bundle();
     50 + }
     51 + }
     52 + }
     53 + 
     54 + return instance;
     55 + }
     56 + 
     57 + /**
     58 + * Destroys the bundle.
     59 + */
     60 + public void destroy() {
     61 + // nothing to destroy
     62 + }
     63 +}
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/Main.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client;
     18 + 
     19 +import com.warxim.vucsa.client.gui.GuiApplication;
     20 +import com.warxim.vucsa.client.gui.GuiBundle;
     21 +import com.warxim.vucsa.client.gui.dialog.Dialogs;
     22 +import javafx.application.Application;
     23 + 
     24 +/**
     25 + * Main client application class.
     26 + */
     27 +public final class Main {
     28 + public static void main(String... args) {
     29 + init();
     30 + launch();
     31 + }
     32 + 
     33 + /**
     34 + * Initializes GUI bundle.
     35 + */
     36 + private static void init() {
     37 + var guiBundle = GuiBundle.getInstance();
     38 + Dialogs.setDefaultIcon(guiBundle.getLogo());
     39 + }
     40 + 
     41 + /**
     42 + * Launches GUI application.
     43 + */
     44 + private static void launch() {
     45 + Application.launch(GuiApplication.class);
     46 + }
     47 + 
     48 + private Main() {}
     49 +}
     50 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/ChallengeController.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge;
     18 + 
     19 +import com.warxim.vucsa.client.Bundle;
     20 +import com.warxim.vucsa.common.message.Message;
     21 + 
     22 +/**
     23 + * Base class of challenge controllers.
     24 + */
     25 +public abstract class ChallengeController {
     26 + /**
     27 + * Sends message using client manager.
     28 + * @param message Message to be sent
     29 + * @return {@code true} if the message has been successfully sent
     30 + */
     31 + protected boolean sendMessage(Message message) {
     32 + var clientManager = Bundle.getInstance().getClientManager();
     33 + return clientManager.sendMessage(message);
     34 + }
     35 +}
     36 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/ChallengeWrapper.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge;
     18 + 
     19 +import com.warxim.vucsa.common.connection.listener.ConnectionListener;
     20 +import javafx.scene.Node;
     21 +import lombok.Builder;
     22 +import lombok.Value;
     23 + 
     24 +/**
     25 + * Wrapper for keeping JavaFX node and controller of a challenge.
     26 + */
     27 +@Value
     28 +@Builder
     29 +public class ChallengeWrapper implements ConnectionListener {
     30 + /**
     31 + * Challenge node, which is displayed in the tab.
     32 + */
     33 + Node node;
     34 + 
     35 + /**
     36 + * Controller for controlling the challenge GUI.
     37 + */
     38 + ChallengeController controller;
     39 +}
     40 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/bufferoverread/BufferOverreadController.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge.bufferoverread;
     18 + 
     19 +import com.warxim.vucsa.client.Bundle;
     20 +import com.warxim.vucsa.client.challenge.ChallengeController;
     21 +import com.warxim.vucsa.client.gui.dialog.Dialogs;
     22 +import com.warxim.vucsa.common.ChallengeConstant;
     23 +import com.warxim.vucsa.common.message.bufferoverread.StringListMessage;
     24 +import javafx.application.Platform;
     25 +import javafx.event.ActionEvent;
     26 +import javafx.fxml.FXML;
     27 +import javafx.fxml.Initializable;
     28 +import javafx.scene.control.ContextMenu;
     29 +import javafx.scene.control.ListView;
     30 +import javafx.scene.control.MenuItem;
     31 + 
     32 +import java.net.URL;
     33 +import java.util.List;
     34 +import java.util.ResourceBundle;
     35 + 
     36 +/**
     37 + * Buffer over-read controller handles buffer over-read challenge, which uses simple echo with transformation of input
     38 + * to simulate buffer over-read vulnerability.
     39 + */
     40 +public class BufferOverreadController extends ChallengeController implements Initializable {
     41 + private final BufferOverreadHandler handler = new BufferOverreadHandler(this);
     42 + 
     43 + @FXML
     44 + private ListView<String> requestInput;
     45 + @FXML
     46 + private ListView<String> responseInput;
     47 + 
     48 + @Override
     49 + public void initialize(URL location, ResourceBundle resources) {
     50 + initHandler();
     51 + initDefaultItems();
     52 + initContextMenu();
     53 + }
     54 + 
     55 + /**
     56 + * Sets items to the input component.
     57 + * @param items Items to be set
     58 + */
     59 + public void setItems(List<String> items) {
     60 + Platform.runLater(() -> responseInput.getItems().setAll(items));
     61 + }
     62 + 
     63 + /**
     64 + * Sends items to server.
     65 + */
     66 + @FXML
     67 + private void onSendClick(ActionEvent event) {
     68 + var items = requestInput.getItems();
     69 + var message = StringListMessage.builder()
     70 + .target(ChallengeConstant.BUFFER_OVERREAD_TARGET)
     71 + .items(items)
     72 + .build();
     73 + sendMessage(message);
     74 + }
     75 + 
     76 + /**
     77 + * Adds new item.
     78 + */
     79 + @FXML
     80 + private void onAddItemClick(ActionEvent event) {
     81 + var maybeValue = Dialogs.createTextInputDialog("Add Item", "Value");
     82 + if (maybeValue.isEmpty()) {
     83 + return;
     84 + }
     85 + requestInput.getItems().add(maybeValue.get());
     86 + }
     87 + 
     88 + /**
     89 + * Removes existing item.
     90 + */
     91 + @FXML
     92 + private void onRemoveItemClick(ActionEvent event) {
     93 + var selected = requestInput.getSelectionModel().getSelectedIndex();
     94 + if (selected < 0) {
     95 + return;
     96 + }
     97 + 
     98 + requestInput.getItems().remove(selected);
     99 + }
     100 + 
     101 + /**
     102 + * Initializes buffer over-read message handler.
     103 + */
     104 + private void initHandler() {
     105 + Bundle.getInstance().getClientManager().registerHandler(ChallengeConstant.BUFFER_OVERREAD_TARGET, handler);
     106 + }
     107 + 
     108 + /**
     109 + * Initializes default items in the challenge GUI.
     110 + */
     111 + private void initDefaultItems() {
     112 + requestInput.getItems().add("Item 1");
     113 + requestInput.getItems().add("Item 2");
     114 + requestInput.getItems().add("Item 3");
     115 + }
     116 + 
     117 + /**
     118 + * Initializes context menu of request input.
     119 + */
     120 + private void initContextMenu() {
     121 + var menu = new ContextMenu();
     122 + var addItem = new MenuItem("Add");
     123 + addItem.setOnAction(this::onAddItemClick);
     124 + var removeItem = new MenuItem("Remove");
     125 + removeItem.setOnAction(this::onRemoveItemClick);
     126 + 
     127 + menu.getItems().add(addItem);
     128 + menu.getItems().add(removeItem);
     129 + requestInput.setContextMenu(menu);
     130 + }
     131 +}
     132 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/bufferoverread/BufferOverreadHandler.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge.bufferoverread;
     18 + 
     19 +import com.warxim.vucsa.common.connection.Connection;
     20 +import com.warxim.vucsa.common.message.Message;
     21 +import com.warxim.vucsa.common.message.MessageHandler;
     22 +import com.warxim.vucsa.common.message.bufferoverread.StringListMessage;
     23 +import lombok.RequiredArgsConstructor;
     24 + 
     25 +/**
     26 + * Handler for handling messages for buffer over-read challenge.
     27 + */
     28 +@RequiredArgsConstructor
     29 +public class BufferOverreadHandler implements MessageHandler {
     30 + private final BufferOverreadController controller;
     31 + 
     32 + @Override
     33 + public boolean supports(Message message) {
     34 + return message instanceof StringListMessage;
     35 + }
     36 + 
     37 + @Override
     38 + public boolean handleMessage(Connection connection, Message message) {
     39 + controller.setItems(((StringListMessage) message).getItems());
     40 + return true;
     41 + }
     42 +}
     43 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/commandexecution/CommandExecutionController.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge.commandexecution;
     18 + 
     19 +import com.warxim.vucsa.client.Bundle;
     20 +import com.warxim.vucsa.client.challenge.ChallengeController;
     21 +import com.warxim.vucsa.common.ChallengeConstant;
     22 +import com.warxim.vucsa.common.message.commandexecution.request.PingRequest;
     23 +import javafx.application.Platform;
     24 +import javafx.beans.value.ObservableValue;
     25 +import javafx.event.ActionEvent;
     26 +import javafx.fxml.FXML;
     27 +import javafx.fxml.Initializable;
     28 +import javafx.scene.control.TextArea;
     29 +import javafx.scene.control.TextField;
     30 + 
     31 +import java.net.URL;
     32 +import java.util.ResourceBundle;
     33 + 
     34 +/**
     35 + * Command execution controller handles command execution challenge.
     36 + * <p>Requests server to do PING command and shows output.</p>
     37 + */
     38 +public class CommandExecutionController extends ChallengeController implements Initializable {
     39 + private final CommandExecutionHandler handler = new CommandExecutionHandler(this);
     40 + 
     41 + @FXML
     42 + private TextField hostInput;
     43 + @FXML
     44 + private TextArea resultOutput;
     45 + 
     46 + @Override
     47 + public void initialize(URL location, ResourceBundle resources) {
     48 + initHandler();
     49 + hostInput.textProperty().addListener(this::onHostInputChange);
     50 + }
     51 + /**
     52 + * Sets output to the text area.
     53 + * @param output Output to be set
     54 + */
     55 + public void setOutput(String output) {
     56 + Platform.runLater(() -> resultOutput.setText(output));
     57 + }
     58 + 
     59 + /**
     60 + * Sends ping request to server.
     61 + */
     62 + @FXML
     63 + private void onPingClick(ActionEvent event) {
     64 + var message = PingRequest.builder()
     65 + .target(ChallengeConstant.COMMAND_EXECUTION_TARGET)
     66 + .host(hostInput.getText())
     67 + .build();
     68 + sendMessage(message);
     69 + }
     70 + 
     71 + /**
     72 + * Initializes command execution message handler.
     73 + */
     74 + private void initHandler() {
     75 + Bundle.getInstance().getClientManager().registerHandler(ChallengeConstant.COMMAND_EXECUTION_TARGET, handler);
     76 + }
     77 + 
     78 + /**
     79 + * Removes invalid characters from host input on change.
     80 + */
     81 + private void onHostInputChange(
     82 + ObservableValue<? extends String> observable,
     83 + String oldValue,
     84 + String newValue) {
     85 + if (!newValue.matches("0-9a-zA-Z\\.-")) {
     86 + hostInput.setText(newValue.replaceAll("[^0-9a-zA-Z.-]", ""));
     87 + }
     88 + }
     89 +}
     90 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/commandexecution/CommandExecutionHandler.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge.commandexecution;
     18 + 
     19 +import com.warxim.vucsa.common.connection.Connection;
     20 +import com.warxim.vucsa.common.message.Message;
     21 +import com.warxim.vucsa.common.message.MessageHandler;
     22 +import com.warxim.vucsa.common.message.commandexecution.response.PingResponse;
     23 +import lombok.RequiredArgsConstructor;
     24 + 
     25 +@RequiredArgsConstructor
     26 +public class CommandExecutionHandler implements MessageHandler {
     27 + private final CommandExecutionController controller;
     28 + 
     29 + @Override
     30 + public boolean supports(Message message) {
     31 + return message instanceof PingResponse;
     32 + }
     33 + 
     34 + @Override
     35 + public boolean handleMessage(Connection connection, Message message) {
     36 + controller.setOutput(((PingResponse) message).getOutput());
     37 + return true;
     38 + }
     39 +}
     40 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/enumeration/EnumerationController.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge.enumeration;
     18 + 
     19 +import com.warxim.vucsa.client.Bundle;
     20 +import com.warxim.vucsa.client.challenge.ChallengeController;
     21 +import com.warxim.vucsa.common.ChallengeConstant;
     22 +import com.warxim.vucsa.common.message.enumeration.LoginStatus;
     23 +import com.warxim.vucsa.common.message.enumeration.request.LoginRequest;
     24 +import javafx.application.Platform;
     25 +import javafx.event.ActionEvent;
     26 +import javafx.fxml.FXML;
     27 +import javafx.fxml.Initializable;
     28 +import javafx.scene.control.Label;
     29 +import javafx.scene.control.PasswordField;
     30 +import javafx.scene.control.TextField;
     31 + 
     32 +import java.net.URL;
     33 +import java.util.ResourceBundle;
     34 + 
     35 +/**
     36 + * Enumeration controller handles enumeration challenge.
     37 + * <p>Simulates user login and displays result.</p>
     38 + */
     39 +public class EnumerationController extends ChallengeController implements Initializable {
     40 + private final EnumerationHandler handler = new EnumerationHandler(this);
     41 + 
     42 + @FXML
     43 + private TextField usernameInput;
     44 + @FXML
     45 + private PasswordField passwordInput;
     46 + @FXML
     47 + private Label resultLabel;
     48 + 
     49 + @Override
     50 + public void initialize(URL location, ResourceBundle resources) {
     51 + initHandler();
     52 + }
     53 + 
     54 + /**
     55 + * Sets login result to the GUI.
     56 + * @param status Login status
     57 + * @param userSecret Secret of logged user
     58 + */
     59 + public void setResult(LoginStatus status, String userSecret) {
     60 + Platform.runLater(() -> {
     61 + switch (status) {
     62 + case SUCCESS:
     63 + resultLabel.setText("Successfully logged in! Your secret is: \"" + userSecret + "\"");
     64 + break;
     65 + case WRONG_USERNAME:
     66 + resultLabel.setText("Wrong username!");
     67 + break;
     68 + case WRONG_PASSWORD:
     69 + resultLabel.setText("Wrong password!");
     70 + break;
     71 + }
     72 + });
     73 + }
     74 + 
     75 + /**
     76 + * Sends login request to the server.
     77 + */
     78 + @FXML
     79 + private void onLoginClick(ActionEvent event) {
     80 + var message = LoginRequest.builder()
     81 + .target(ChallengeConstant.ENUMERATION_TARGET)
     82 + .username(usernameInput.getText())
     83 + .password(passwordInput.getText())
     84 + .build();
     85 + sendMessage(message);
     86 + }
     87 + 
     88 + /**
     89 + * Initializes enumeration message handler.
     90 + */
     91 + private void initHandler() {
     92 + Bundle.getInstance().getClientManager().registerHandler(ChallengeConstant.ENUMERATION_TARGET, handler);
     93 + }
     94 +}
     95 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/enumeration/EnumerationHandler.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge.enumeration;
     18 + 
     19 +import com.warxim.vucsa.common.connection.Connection;
     20 +import com.warxim.vucsa.common.message.Message;
     21 +import com.warxim.vucsa.common.message.MessageHandler;
     22 +import com.warxim.vucsa.common.message.enumeration.response.LoginResponse;
     23 +import lombok.RequiredArgsConstructor;
     24 + 
     25 +/**
     26 + * Handler for login response messages for enumeration challenge.
     27 + */
     28 +@RequiredArgsConstructor
     29 +public class EnumerationHandler implements MessageHandler {
     30 + private final EnumerationController controller;
     31 + 
     32 + @Override
     33 + public boolean supports(Message message) {
     34 + return message instanceof LoginResponse;
     35 + }
     36 + 
     37 + @Override
     38 + public boolean handleMessage(Connection connection, Message message) {
     39 + var loginResponse = ((LoginResponse) message);
     40 + controller.setResult(loginResponse.getStatus(), loginResponse.getUserSecret());
     41 + return true;
     42 + }
     43 +}
     44 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/horizontalaccesscontrol/DocumentItem.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge.horizontalaccesscontrol;
     18 + 
     19 +import lombok.Builder;
     20 +import lombok.Value;
     21 + 
     22 +/**
     23 + * Document item for displaying user's documents overview.
     24 + */
     25 +@Builder
     26 +@Value
     27 +public class DocumentItem {
     28 + int id;
     29 + String name;
     30 + 
     31 + @Override
     32 + public String toString() {
     33 + return name;
     34 + }
     35 +}
     36 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/horizontalaccesscontrol/HorizontalAccessControlController.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge.horizontalaccesscontrol;
     18 + 
     19 +import com.warxim.vucsa.client.Bundle;
     20 +import com.warxim.vucsa.client.challenge.ChallengeController;
     21 +import com.warxim.vucsa.common.ChallengeConstant;
     22 +import com.warxim.vucsa.common.message.horizontalaccesscontrol.request.DocumentContentRequest;
     23 +import javafx.application.Platform;
     24 +import javafx.beans.value.ObservableValue;
     25 +import javafx.fxml.Initializable;
     26 +import javafx.fxml.FXML;
     27 +import javafx.scene.control.ListView;
     28 +import javafx.scene.control.TextArea;
     29 + 
     30 +import java.net.URL;
     31 +import java.util.ResourceBundle;
     32 + 
     33 +/**
     34 + * Horizontal access controller handles horizontal access challenge.
     35 + * <p>Simulates document management of logged user and allows him to download document content of his documents.</p>
     36 + */
     37 +public class HorizontalAccessControlController extends ChallengeController implements Initializable {
     38 + private final HorizontalAccessControlHandler handler = new HorizontalAccessControlHandler(this);
     39 + 
     40 + @FXML
     41 + private ListView<DocumentItem> documentInput;
     42 + @FXML
     43 + private TextArea contentOutput;
     44 + 
     45 + @Override
     46 + public void initialize(URL location, ResourceBundle resources) {
     47 + initHandler();
     48 + initDocuments();
     49 + }
     50 + 
     51 + /**
     52 + * Sets document content to GUI.
     53 + * @param content Content of the document
     54 + */
     55 + public void setDocument(String content) {
     56 + Platform.runLater(() -> contentOutput.setText(content));
     57 + }
     58 + 
     59 + /**
     60 + * Initializes horizontal access control message handler.
     61 + */
     62 + private void initHandler() {
     63 + Bundle.getInstance().getClientManager().registerHandler(ChallengeConstant.HORIZONTAL_ACCESS_CONTROL_DOCUMENT_CONTENT_TARGET, handler);
     64 + }
     65 + 
     66 + /**
     67 + * Initializes document overview.
     68 + */
     69 + private void initDocuments() {
     70 + documentInput.getItems().add(DocumentItem.builder()
     71 + .id(8435)
     72 + .name("My first secret document")
     73 + .build());
     74 + documentInput.getItems().add(DocumentItem.builder()
     75 + .id(12002)
     76 + .name("Favorite books")
     77 + .build());
     78 + documentInput.getSelectionModel().selectedItemProperty().addListener(this::onDocumentSelectionChange);
     79 + }
     80 + 
     81 + /**
     82 + * Sends request for document content to the server, when document gets selected.
     83 + */
     84 + private void onDocumentSelectionChange(
     85 + ObservableValue<? extends DocumentItem> observable,
     86 + DocumentItem oldValue,
     87 + DocumentItem newValue
     88 + ) {
     89 + if (newValue == null) {
     90 + return;
     91 + }
     92 + 
     93 + sendMessage(DocumentContentRequest.builder()
     94 + .target(ChallengeConstant.HORIZONTAL_ACCESS_CONTROL_DOCUMENT_CONTENT_TARGET)
     95 + .documentId(newValue.getId())
     96 + .build());
     97 + }
     98 +}
     99 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/horizontalaccesscontrol/HorizontalAccessControlHandler.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge.horizontalaccesscontrol;
     18 + 
     19 +import com.warxim.vucsa.common.connection.Connection;
     20 +import com.warxim.vucsa.common.message.Message;
     21 +import com.warxim.vucsa.common.message.MessageHandler;
     22 +import com.warxim.vucsa.common.message.horizontalaccesscontrol.response.DocumentContentResponse;
     23 +import lombok.RequiredArgsConstructor;
     24 + 
     25 +/**
     26 + * Handler for document content response for horizontal access control challenge.
     27 + */
     28 +@RequiredArgsConstructor
     29 +public class HorizontalAccessControlHandler implements MessageHandler {
     30 + private final HorizontalAccessControlController controller;
     31 + 
     32 + @Override
     33 + public boolean supports(Message message) {
     34 + return message instanceof DocumentContentResponse;
     35 + }
     36 + 
     37 + @Override
     38 + public boolean handleMessage(Connection connection, Message message) {
     39 + var documentContentResponse = ((DocumentContentResponse) message);
     40 + controller.setDocument(documentContentResponse.getContent());
     41 + return true;
     42 + }
     43 +}
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/sqlinjection/SqlInjectionController.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge.sqlinjection;
     18 + 
     19 +import com.warxim.vucsa.client.Bundle;
     20 +import com.warxim.vucsa.client.challenge.ChallengeController;
     21 +import com.warxim.vucsa.common.ChallengeConstant;
     22 +import com.warxim.vucsa.common.message.sqlinjection.request.SearchRequest;
     23 +import com.warxim.vucsa.common.message.sqlinjection.FoodEntity;
     24 +import javafx.application.Platform;
     25 +import javafx.beans.value.ObservableValue;
     26 +import javafx.event.ActionEvent;
     27 +import javafx.fxml.FXML;
     28 +import javafx.fxml.Initializable;
     29 +import javafx.scene.control.TableColumn;
     30 +import javafx.scene.control.TableView;
     31 +import javafx.scene.control.TextField;
     32 +import javafx.scene.control.cell.PropertyValueFactory;
     33 + 
     34 +import java.net.URL;
     35 +import java.util.List;
     36 +import java.util.ResourceBundle;
     37 + 
     38 +/**
     39 + * SQL Injection Controller handles SQL injection challenge.
     40 + * <p>Simulates food menu search and displays found food.</p>
     41 + */
     42 +public class SqlInjectionController extends ChallengeController implements Initializable {
     43 + private final SqlInjectionHandler handler = new SqlInjectionHandler(this);
     44 + 
     45 + @FXML
     46 + private TextField searchInput;
     47 + @FXML
     48 + private TableView<FoodEntity> resultTable;
     49 + @FXML
     50 + private TableColumn<FoodEntity, Integer> idColumn;
     51 + @FXML
     52 + private TableColumn<FoodEntity, String> nameColumn;
     53 + @FXML
     54 + private TableColumn<FoodEntity, String> descriptionColumn;
     55 + @FXML
     56 + private TableColumn<FoodEntity, Double> priceColumn;
     57 + 
     58 + @Override
     59 + public void initialize(URL location, ResourceBundle resources) {
     60 + initHandler();
     61 + initTable();
     62 + searchInput.textProperty().addListener(this::onSearchInputChange);
     63 + }
     64 + 
     65 + /**
     66 + * Sets items to the table.
     67 + * @param items Items to be set
     68 + */
     69 + public void setItems(List<FoodEntity> items) {
     70 + Platform.runLater(() -> resultTable.getItems().setAll(items));
     71 + }
     72 + 
     73 + @FXML
     74 + private void onSearchClick(ActionEvent event) {
     75 + var message = SearchRequest.builder()
     76 + .target(ChallengeConstant.SQL_INJECTION_TARGET)
     77 + .search(searchInput.getText())
     78 + .build();
     79 + sendMessage(message);
     80 + }
     81 + 
     82 + /**
     83 + * Initializes sql injection message handler.
     84 + */
     85 + private void initHandler() {
     86 + Bundle.getInstance().getClientManager().registerHandler(ChallengeConstant.SQL_INJECTION_TARGET, handler);
     87 + }
     88 + 
     89 + /**
     90 + * Initializes table columns.
     91 + */
     92 + private void initTable() {
     93 + idColumn.setCellValueFactory(new PropertyValueFactory<>("id"));
     94 + nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
     95 + descriptionColumn.setCellValueFactory(new PropertyValueFactory<>("description"));
     96 + priceColumn.setCellValueFactory(new PropertyValueFactory<>("price"));
     97 + }
     98 + 
     99 + /**
     100 + * Removes invalid characters from search input on change.
     101 + */
     102 + private void onSearchInputChange(
     103 + ObservableValue<? extends String> observable,
     104 + String oldValue,
     105 + String newValue) {
     106 + if (!newValue.matches("\\s0-9a-zA-Z\\.-")) {
     107 + searchInput.setText(newValue.replaceAll("[^\\s0-9a-zA-Z.-]", ""));
     108 + }
     109 + }
     110 +}
     111 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/sqlinjection/SqlInjectionHandler.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge.sqlinjection;
     18 + 
     19 +import com.warxim.vucsa.common.connection.Connection;
     20 +import com.warxim.vucsa.common.message.Message;
     21 +import com.warxim.vucsa.common.message.MessageHandler;
     22 +import com.warxim.vucsa.common.message.sqlinjection.response.SearchResponse;
     23 +import lombok.RequiredArgsConstructor;
     24 + 
     25 +/**
     26 + * Handler for search responses for SQL injection challenge.
     27 + */
     28 +@RequiredArgsConstructor
     29 +public class SqlInjectionHandler implements MessageHandler {
     30 + private final SqlInjectionController controller;
     31 + 
     32 + @Override
     33 + public boolean supports(Message message) {
     34 + return message instanceof SearchResponse;
     35 + }
     36 + 
     37 + @Override
     38 + public boolean handleMessage(Connection connection, Message message) {
     39 + controller.setItems(((SearchResponse) message).getEntities());
     40 + return true;
     41 + }
     42 +}
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/verticalaccesscontrol/VerticalAccessControlController.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge.verticalaccesscontrol;
     18 + 
     19 +import com.warxim.vucsa.client.Bundle;
     20 +import com.warxim.vucsa.client.challenge.ChallengeController;
     21 +import com.warxim.vucsa.common.ChallengeConstant;
     22 +import com.warxim.vucsa.common.message.verticalaccesscontrol.UserRole;
     23 +import com.warxim.vucsa.common.message.verticalaccesscontrol.request.SecretRequest;
     24 +import com.warxim.vucsa.common.message.verticalaccesscontrol.request.UserInfoRequest;
     25 +import javafx.application.Platform;
     26 +import javafx.event.ActionEvent;
     27 +import javafx.fxml.FXML;
     28 +import javafx.fxml.Initializable;
     29 +import javafx.scene.control.Label;
     30 +import javafx.scene.layout.AnchorPane;
     31 + 
     32 +import java.net.URL;
     33 +import java.util.ResourceBundle;
     34 + 
     35 +/**
     36 + * Vertical access controller handles vertical access challenge.
     37 + * <p>Simulates sending of user info from the server to the client about his session.</p>
     38 + */
     39 +public class VerticalAccessControlController extends ChallengeController implements Initializable {
     40 + private final VerticalAccessControlUserInfoHandler userInfoHandler = new VerticalAccessControlUserInfoHandler(this);
     41 + private final VerticalAccessControlSecretHandler secretHandler = new VerticalAccessControlSecretHandler(this);
     42 + 
     43 + @FXML
     44 + private Label usernameLabel;
     45 + @FXML
     46 + private Label roleLabel;
     47 + 
     48 + @FXML
     49 + private AnchorPane guestPane;
     50 + @FXML
     51 + private AnchorPane userPane;
     52 + @FXML
     53 + private AnchorPane adminPane;
     54 + @FXML
     55 + private Label secretLabel;
     56 + 
     57 + @Override
     58 + public void initialize(URL location, ResourceBundle resources) {
     59 + initHandler();
     60 + initPanes();
     61 + }
     62 + 
     63 + /**
     64 + * Sets user to the GUI.
     65 + * @param username Name of the user
     66 + * @param role Role of the user
     67 + */
     68 + public void setUser(String username, UserRole role) {
     69 + Platform.runLater(() -> {
     70 + usernameLabel.setText(username);
     71 + roleLabel.setText(role.name());
     72 + 
     73 + if (role.equals(UserRole.GUEST)) {
     74 + guestPane.setVisible(true);
     75 + userPane.setVisible(false);
     76 + adminPane.setVisible(false);
     77 + secretLabel.setText("-");
     78 + } else if (role.equals(UserRole.USER)) {
     79 + guestPane.setVisible(false);
     80 + userPane.setVisible(true);
     81 + adminPane.setVisible(false);
     82 + secretLabel.setText("-");
     83 + } else if (role.equals(UserRole.ADMIN)) {
     84 + guestPane.setVisible(false);
     85 + userPane.setVisible(false);
     86 + adminPane.setVisible(true);
     87 + secretLabel.setText("-");
     88 + }
     89 + });
     90 + }
     91 + 
     92 + /**
     93 + * Sets user secret to the GUI.
     94 + * @param secret Secret to be set
     95 + */
     96 + public void setSecret(String secret) {
     97 + Platform.runLater(() -> secretLabel.setText(secret));
     98 + }
     99 + 
     100 + /**
     101 + * Sends request for user info to the server.
     102 + */
     103 + @FXML
     104 + private void onRefreshClick(ActionEvent event) {
     105 + var message = UserInfoRequest.builder()
     106 + .target(ChallengeConstant.VERTICAL_ACCESS_CONTROL_USER_INFO_TARGET)
     107 + .build();
     108 + sendMessage(message);
     109 + }
     110 + 
     111 + /**
     112 + * Sends request for downloading secret to the server.
     113 + */
     114 + @FXML
     115 + private void onDownloadSecretClick(ActionEvent event) {
     116 + var message = SecretRequest.builder()
     117 + .target(ChallengeConstant.VERTICAL_ACCESS_CONTROL_SECRET_TARGET)
     118 + .build();
     119 + sendMessage(message);
     120 + }
     121 + 
     122 + /**
     123 + * Initializes vertical access control message handlers.
     124 + */
     125 + private void initHandler() {
     126 + Bundle.getInstance().getClientManager().registerHandler(ChallengeConstant.VERTICAL_ACCESS_CONTROL_USER_INFO_TARGET, userInfoHandler);
     127 + Bundle.getInstance().getClientManager().registerHandler(ChallengeConstant.VERTICAL_ACCESS_CONTROL_SECRET_TARGET, secretHandler);
     128 + }
     129 + 
     130 + /**
     131 + * Hides all panes.
     132 + */
     133 + private void initPanes() {
     134 + guestPane.setVisible(false);
     135 + userPane.setVisible(false);
     136 + adminPane.setVisible(false);
     137 + }
     138 +}
     139 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/verticalaccesscontrol/VerticalAccessControlSecretHandler.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge.verticalaccesscontrol;
     18 + 
     19 +import com.warxim.vucsa.common.connection.Connection;
     20 +import com.warxim.vucsa.common.message.Message;
     21 +import com.warxim.vucsa.common.message.MessageHandler;
     22 +import com.warxim.vucsa.common.message.verticalaccesscontrol.response.SecretResponse;
     23 +import lombok.RequiredArgsConstructor;
     24 + 
     25 +/**
     26 + * Handler for secret response for vertical access control challenge.
     27 + */
     28 +@RequiredArgsConstructor
     29 +public class VerticalAccessControlSecretHandler implements MessageHandler {
     30 + private final VerticalAccessControlController controller;
     31 + 
     32 + @Override
     33 + public boolean supports(Message message) {
     34 + return message instanceof SecretResponse;
     35 + }
     36 + 
     37 + @Override
     38 + public boolean handleMessage(Connection connection, Message message) {
     39 + var secretResponse = ((SecretResponse) message);
     40 + controller.setSecret(secretResponse.getSecret());
     41 + return true;
     42 + }
     43 +}
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/verticalaccesscontrol/VerticalAccessControlUserInfoHandler.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge.verticalaccesscontrol;
     18 + 
     19 +import com.warxim.vucsa.common.connection.Connection;
     20 +import com.warxim.vucsa.common.message.Message;
     21 +import com.warxim.vucsa.common.message.MessageHandler;
     22 +import com.warxim.vucsa.common.message.verticalaccesscontrol.response.UserInfoResponse;
     23 +import lombok.RequiredArgsConstructor;
     24 + 
     25 +/**
     26 + * Handler for user info response for vertical access control challenge.
     27 + */
     28 +@RequiredArgsConstructor
     29 +public class VerticalAccessControlUserInfoHandler implements MessageHandler {
     30 + private final VerticalAccessControlController controller;
     31 + 
     32 + @Override
     33 + public boolean supports(Message message) {
     34 + return message instanceof UserInfoResponse;
     35 + }
     36 + 
     37 + @Override
     38 + public boolean handleMessage(Connection connection, Message message) {
     39 + var info = ((UserInfoResponse) message);
     40 + controller.setUser(info.getUsername(), info.getRole());
     41 + return true;
     42 + }
     43 +}
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/xml/XmlController.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge.xml;
     18 + 
     19 +import com.warxim.vucsa.client.Bundle;
     20 +import com.warxim.vucsa.client.challenge.ChallengeController;
     21 +import com.warxim.vucsa.client.gui.dialog.Dialogs;
     22 +import com.warxim.vucsa.common.ChallengeConstant;
     23 +import com.warxim.vucsa.common.message.xml.StorageItem;
     24 +import com.warxim.vucsa.common.message.xml.StorageMessage;
     25 +import javafx.application.Platform;
     26 +import javafx.event.ActionEvent;
     27 +import javafx.fxml.FXML;
     28 +import javafx.fxml.Initializable;
     29 +import javafx.scene.control.ContextMenu;
     30 +import javafx.scene.control.MenuItem;
     31 +import javafx.scene.control.TableColumn;
     32 +import javafx.scene.control.TableView;
     33 +import javafx.scene.control.cell.PropertyValueFactory;
     34 + 
     35 +import java.net.URL;
     36 +import java.util.List;
     37 +import java.util.ResourceBundle;
     38 + 
     39 +/**
     40 + * XML controller handles XML challenge.
     41 + * <p>This challenge acts like a simple ECHO functionality (simulates "storage"), but with vulnerable deserialization implementation.</p>
     42 + */
     43 +public class XmlController extends ChallengeController implements Initializable {
     44 + private final XmlHandler handler = new XmlHandler(this);
     45 + 
     46 + @FXML
     47 + private TableView<StorageItem> requestTable;
     48 + @FXML
     49 + private TableColumn<StorageItem, String> requestKeyColumn;
     50 + @FXML
     51 + private TableColumn<StorageItem, String> requestValueColumn;
     52 + @FXML
     53 + private TableView<StorageItem> responseTable;
     54 + @FXML
     55 + private TableColumn<StorageItem, String> responseKeyColumn;
     56 + @FXML
     57 + private TableColumn<StorageItem, String> responseValueColumn;
     58 + 
     59 + @Override
     60 + public void initialize(URL location, ResourceBundle resources) {
     61 + initHandler();
     62 + initDefaultItems();
     63 + initTable();
     64 + initContextMenu();
     65 + }
     66 + 
     67 + /**
     68 + * Sets storage items to the GUI.
     69 + * @param items Items to be set
     70 + */
     71 + public void setItems(List<StorageItem> items) {
     72 + Platform.runLater(() -> responseTable.getItems().setAll(items));
     73 + }
     74 + 
     75 + /**
     76 + * Sends storage items to server to "save" them.
     77 + */
     78 + @FXML
     79 + private void onSendClick(ActionEvent event) {
     80 + var message = StorageMessage.builder()
     81 + .target(ChallengeConstant.XML_TARGET)
     82 + .items(requestTable.getItems())
     83 + .build();
     84 + sendMessage(message);
     85 + }
     86 + 
     87 + /**
     88 + * Adds new item.
     89 + */
     90 + @FXML
     91 + private void onAddItemClick(ActionEvent event) {
     92 + var maybePair = Dialogs.createTextPairDialog("Add Item", "Key", "Value");
     93 + if (maybePair.isEmpty()) {
     94 + return;
     95 + }
     96 + var pair = maybePair.get();
     97 + requestTable.getItems().add(StorageItem.builder()
     98 + .key(pair.getKey())
     99 + .value(pair.getValue())
     100 + .build());
     101 + }
     102 + 
     103 + /**
     104 + * Removes existing item.
     105 + */
     106 + @FXML
     107 + private void onRemoveItemClick(ActionEvent event) {
     108 + var selected = requestTable.getSelectionModel().getSelectedIndex();
     109 + if (selected < 0) {
     110 + return;
     111 + }
     112 + 
     113 + requestTable.getItems().remove(selected);
     114 + }
     115 + 
     116 + /**
     117 + * Initializes buffer over-read message handler.
     118 + */
     119 + private void initHandler() {
     120 + Bundle.getInstance().getClientManager().registerHandler(ChallengeConstant.XML_TARGET, handler);
     121 + }
     122 + 
     123 + /**
     124 + * Initializes default items in the challenge GUI.
     125 + */
     126 + private void initDefaultItems() {
     127 + requestTable.getItems().add(StorageItem.builder().key("Item 1").value("VALUE 1").build());
     128 + requestTable.getItems().add(StorageItem.builder().key("Item 2").value("VALUE 2").build());
     129 + requestTable.getItems().add(StorageItem.builder().key("Item 3").value("VALUE 3").build());
     130 + }
     131 + 
     132 + /**
     133 + * Initializes table columns.
     134 + */
     135 + private void initTable() {
     136 + requestKeyColumn.setCellValueFactory(new PropertyValueFactory<>("key"));
     137 + requestValueColumn.setCellValueFactory(new PropertyValueFactory<>("value"));
     138 + responseKeyColumn.setCellValueFactory(new PropertyValueFactory<>("key"));
     139 + responseValueColumn.setCellValueFactory(new PropertyValueFactory<>("value"));
     140 + }
     141 + 
     142 + /**
     143 + * Initializes context menu of request input.
     144 + */
     145 + private void initContextMenu() {
     146 + var menu = new ContextMenu();
     147 + var addItem = new MenuItem("Add");
     148 + addItem.setOnAction(this::onAddItemClick);
     149 + var removeItem = new MenuItem("Remove");
     150 + removeItem.setOnAction(this::onRemoveItemClick);
     151 + 
     152 + menu.getItems().add(addItem);
     153 + menu.getItems().add(removeItem);
     154 + requestTable.setContextMenu(menu);
     155 + }
     156 +}
     157 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/challenge/xml/XmlHandler.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.challenge.xml;
     18 + 
     19 +import com.warxim.vucsa.common.connection.Connection;
     20 +import com.warxim.vucsa.common.message.Message;
     21 +import com.warxim.vucsa.common.message.MessageHandler;
     22 +import com.warxim.vucsa.common.message.xml.StorageMessage;
     23 +import lombok.RequiredArgsConstructor;
     24 + 
     25 +/**
     26 + * Handler for storage messages from server for XML challenge.
     27 + */
     28 +@RequiredArgsConstructor
     29 +public class XmlHandler implements MessageHandler {
     30 + private final XmlController controller;
     31 + 
     32 + @Override
     33 + public boolean supports(Message message) {
     34 + return message instanceof StorageMessage;
     35 + }
     36 + 
     37 + @Override
     38 + public boolean handleMessage(Connection connection, Message message) {
     39 + controller.setItems(((StorageMessage) message).getItems());
     40 + return true;
     41 + }
     42 +}
     43 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/core/Client.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.core;
     18 + 
     19 +import com.warxim.vucsa.common.connection.Connection;
     20 +import com.warxim.vucsa.common.connection.listener.ConnectionListener;
     21 +import com.warxim.vucsa.common.message.MessageHandler;
     22 + 
     23 +import java.io.IOException;
     24 +import java.net.Socket;
     25 +import java.util.logging.Level;
     26 +import java.util.logging.Logger;
     27 + 
     28 +/**
     29 + * Client, which is used to communicate with the server.
     30 + * <p>The client is created through ClientManager, when user starts it in the Settings tab.</p>
     31 + */
     32 +public class Client extends Connection {
     33 + private final ClientConfig config;
     34 + 
     35 + public Client(
     36 + ClientConfig config,
     37 + ConnectionListener connectionListener,
     38 + MessageHandler messageHandler) {
     39 + super(1, connectionListener, messageHandler);
     40 + this.config = config;
     41 + }
     42 + 
     43 + @Override
     44 + protected boolean handleBeforeStart() {
     45 + if (!super.handleBeforeStart()) {
     46 + return false;
     47 + }
     48 + 
     49 + try {
     50 + socket = new Socket(config.getServerHost(), config.getServerPort());
     51 + } catch (IOException e) {
     52 + Logger.getGlobal().log(Level.SEVERE, "Could not start client socket!", e);
     53 + return false;
     54 + }
     55 + 
     56 + return true;
     57 + }
     58 +}
     59 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/core/ClientConfig.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.core;
     18 + 
     19 +import lombok.Builder;
     20 +import lombok.Value;
     21 + 
     22 +/**
     23 + * Client configuration.
     24 + */
     25 +@Value
     26 +@Builder
     27 +public class ClientConfig {
     28 + /**
     29 + * Server host (127.0.0.1, www.example.org, ...)
     30 + */
     31 + String serverHost;
     32 + 
     33 + /**
     34 + * Server port (8765, ...)
     35 + */
     36 + int serverPort;
     37 +}
     38 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/core/ClientManager.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.core;
     18 + 
     19 +import com.warxim.vucsa.common.connection.Connection;
     20 +import com.warxim.vucsa.common.connection.ConnectionState;
     21 +import com.warxim.vucsa.common.connection.listener.ConnectionListener;
     22 +import com.warxim.vucsa.common.connection.listener.ConnectionListenerManager;
     23 +import com.warxim.vucsa.common.message.Message;
     24 +import com.warxim.vucsa.common.message.MessageHandler;
     25 +import com.warxim.vucsa.common.message.MessageHandlerManager;
     26 + 
     27 +/**
     28 + * Client manager for managing client connection.
     29 + * <p>Wraps all required components and handles client creation, start, stop, ...</p>
     30 + */
     31 +public class ClientManager implements ConnectionListener {
     32 + private final ConnectionListenerManager connectionListenerManager;
     33 + private final MessageHandlerManager messageHandlerManager;
     34 + private Client client;
     35 + 
     36 + public ClientManager() {
     37 + this.connectionListenerManager = new ConnectionListenerManager();
     38 + this.messageHandlerManager = new MessageHandlerManager();
     39 + connectionListenerManager.registerListener(this);
     40 + }
     41 + 
     42 + /**
     43 + * Creates and starts client core.
     44 + * @param config Client configuration
     45 + */
     46 + public synchronized void start(ClientConfig config) {
     47 + if (client != null) {
     48 + return;
     49 + }
     50 + 
     51 + client = new Client(config, connectionListenerManager, messageHandlerManager);
     52 + client.start();
     53 + }
     54 + 
     55 + /**
     56 + * Stops client core.
     57 + */
     58 + public synchronized void stop() {
     59 + if (client == null) {
     60 + return;
     61 + }
     62 + 
     63 + client.stop();
     64 + }
     65 + 
     66 + /**
     67 + * Obtains client core state.
     68 + * @return Connection state
     69 + */
     70 + public synchronized ConnectionState getState() {
     71 + if (client == null) {
     72 + return ConnectionState.STOPPED;
     73 + }
     74 + 
     75 + return client.getState();
     76 + }
     77 + 
     78 + /**
     79 + * Sends message using the client if it is available.
     80 + * <p>If the client is not available, does nothing.</p>
     81 + * @return {@code true} if the message was sent
     82 + */
     83 + public synchronized boolean sendMessage(Message message) {
     84 + if (client != null && getState() == ConnectionState.STARTED) {
     85 + client.sendMessage(message);
     86 + return true;
     87 + }
     88 + return false;
     89 + }
     90 + 
     91 + /**
     92 + * Registers connection listener.
     93 + * @param clientListener Listener to be registered
     94 + */
     95 + public void registerConnectionListener(ConnectionListener clientListener) {
     96 + connectionListenerManager.registerListener(clientListener);
     97 + }
     98 + 
     99 + /**
     100 + * Unregisters connection listener.
     101 + * @param clientListener Listener to be unregistered
     102 + */
     103 + public void unregisterConnectionListener(ConnectionListener clientListener) {
     104 + connectionListenerManager.unregisterListener(clientListener);
     105 + }
     106 + 
     107 + /**
     108 + * Registers message handler.
     109 + * @param target Target identifier of the handler
     110 + * @param messageHandler Handler to be registered
     111 + */
     112 + public void registerHandler(int target, MessageHandler messageHandler) {
     113 + messageHandlerManager.registerHandler(target, messageHandler);
     114 + }
     115 + 
     116 + /**
     117 + * Unregisters message handler.
     118 + * @param target Target identifier of the handler
     119 + */
     120 + public void unregisterHandler(int target) {
     121 + messageHandlerManager.unregisterHandler(target);
     122 + }
     123 + 
     124 + @Override
     125 + public void onConnectionStop(Connection connection) {
     126 + client = null;
     127 + }
     128 +}
     129 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/gui/GuiApplication.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.gui;
     18 + 
     19 +import com.sun.javafx.css.StyleManager;
     20 +import com.warxim.vucsa.client.Bundle;
     21 +import com.warxim.vucsa.common.Constant;
     22 +import com.warxim.vucsa.common.connection.ConnectionState;
     23 +import com.warxim.vucsa.client.gui.controller.ApplicationController;
     24 +import javafx.application.Application;
     25 +import javafx.fxml.FXMLLoader;
     26 +import javafx.scene.Parent;
     27 +import javafx.scene.Scene;
     28 +import javafx.stage.Stage;
     29 + 
     30 +/**
     31 + * Client GUI application.
     32 + * <p>Starts Vulnerable Client GUI.</p>
     33 + */
     34 +public class GuiApplication extends Application {
     35 + @Override
     36 + public void start(Stage stage) throws Exception {
     37 + Application.setUserAgentStylesheet(Application.STYLESHEET_MODENA);
     38 + StyleManager.getInstance().addUserAgentStylesheet(getClass().getResource(GuiConstant.MAIN_CSS_PATH).toString());
     39 + 
     40 + var fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/Application.fxml"));
     41 + fxmlLoader.setController(new ApplicationController());
     42 + 
     43 + Parent root = fxmlLoader.load();
     44 + 
     45 + var scene = new Scene(root);
     46 + stage.setTitle("VuCSA Client v" + Constant.VERSION);
     47 + stage.getIcons().add(GuiBundle.getInstance().getLogo());
     48 + stage.setWidth(1200);
     49 + stage.setHeight(900);
     50 + stage.setScene(scene);
     51 + 
     52 + stage.show();
     53 + }
     54 + 
     55 + @Override
     56 + public void stop() throws Exception {
     57 + super.stop();
     58 + 
     59 + var clientManager = Bundle.getInstance().getClientManager();
     60 + if (clientManager != null && clientManager.getState() != ConnectionState.STOPPED) {
     61 + clientManager.stop();
     62 + }
     63 + 
     64 + Bundle.getInstance().destroy();
     65 + GuiBundle.getInstance().destroy();
     66 + }
     67 +}
     68 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/gui/GuiBundle.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.gui;
     18 + 
     19 +import com.warxim.vucsa.client.gui.controller.ApplicationController;
     20 +import javafx.scene.image.Image;
     21 +import lombok.Getter;
     22 + 
     23 +import java.util.Objects;
     24 + 
     25 +/**
     26 + * Singleton for client GUI assets.
     27 + */
     28 +@Getter
     29 +public final class GuiBundle {
     30 + /**
     31 + * Singleton instance.
     32 + */
     33 + private static volatile GuiBundle instance;
     34 + 
     35 + /**
     36 + * Logo icon
     37 + */
     38 + private final Image logo;
     39 + 
     40 + /**
     41 + * Application controller
     42 + */
     43 + private ApplicationController applicationController;
     44 + 
     45 + private GuiBundle() {
     46 + logo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/img/Logo.png")));
     47 + }
     48 + 
     49 + /**
     50 + * Creates instance of bundle or returns existing instance if it exists.
     51 + * @return Bundle instance
     52 + */
     53 + public static GuiBundle getInstance() {
     54 + if (instance == null) {
     55 + synchronized(GuiBundle.class) {
     56 + if (instance == null) {
     57 + instance = new GuiBundle();
     58 + }
     59 + }
     60 + }
     61 + 
     62 + return instance;
     63 + }
     64 + 
     65 + /**
     66 + * Obtains application controller, which handles main application window UI
     67 + * @return Application controller
     68 + */
     69 + public ApplicationController getApplicationController() {
     70 + return applicationController;
     71 + }
     72 + 
     73 + /**
     74 + * Sets application controller, which handles main application window UI
     75 + * @param controller Application controller
     76 + */
     77 + public void setApplicationController(ApplicationController controller) {
     78 + applicationController = controller;
     79 + }
     80 + 
     81 + /**
     82 + * Destroys the bundle.
     83 + */
     84 + public void destroy() {
     85 + // no action needed
     86 + }
     87 +}
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/gui/GuiConstant.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.gui;
     18 + 
     19 +public final class GuiConstant {
     20 + /**
     21 + * Path to main CSS file of the application
     22 + */
     23 + public static final String MAIN_CSS_PATH = "/css/Main.css";
     24 + 
     25 + public static final int LOG_TAB_ORDER = 1;
     26 + public static final int SETTINGS_TAB_ORDER = 2;
     27 + public static final int CHALLENGES_TAB_ORDER = 10;
     28 + 
     29 + private GuiConstant() {}
     30 +}
     31 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/gui/controller/ApplicationController.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.gui.controller;
     18 + 
     19 +import com.warxim.vucsa.client.Bundle;
     20 +import com.warxim.vucsa.client.challenge.commandexecution.CommandExecutionController;
     21 +import com.warxim.vucsa.client.challenge.enumeration.EnumerationController;
     22 +import com.warxim.vucsa.client.challenge.verticalaccesscontrol.VerticalAccessControlController;
     23 +import com.warxim.vucsa.client.challenge.ChallengeController;
     24 +import com.warxim.vucsa.client.challenge.ChallengeWrapper;
     25 +import com.warxim.vucsa.client.challenge.bufferoverread.BufferOverreadController;
     26 +import com.warxim.vucsa.client.challenge.horizontalaccesscontrol.HorizontalAccessControlController;
     27 +import com.warxim.vucsa.client.challenge.sqlinjection.SqlInjectionController;
     28 +import com.warxim.vucsa.client.challenge.xml.XmlController;
     29 +import com.warxim.vucsa.client.gui.GuiBundle;
     30 +import com.warxim.vucsa.client.gui.GuiConstant;
     31 +import com.warxim.vucsa.client.gui.dialog.AboutDialog;
     32 +import com.warxim.vucsa.client.util.GuiUtils;
     33 +import com.warxim.vucsa.common.connection.Connection;
     34 +import com.warxim.vucsa.common.connection.ConnectionState;
     35 +import com.warxim.vucsa.common.connection.listener.ConnectionListener;
     36 +import javafx.application.Platform;
     37 +import javafx.event.ActionEvent;
     38 +import javafx.fxml.FXML;
     39 +import javafx.fxml.FXMLLoader;
     40 +import javafx.fxml.Initializable;
     41 +import javafx.scene.Node;
     42 +import javafx.scene.control.TabPane;
     43 + 
     44 +import java.io.IOException;
     45 +import java.net.URL;
     46 +import java.util.LinkedList;
     47 +import java.util.List;
     48 +import java.util.ResourceBundle;
     49 +import java.util.logging.Level;
     50 +import java.util.logging.Logger;
     51 + 
     52 +/**
     53 + * Main application controller, which handles the whole application.
     54 + */
     55 +public class ApplicationController implements Initializable, ConnectionListener {
     56 + private final List<ChallengeWrapper> challengeWrappers = new LinkedList<>();
     57 + 
     58 + @FXML
     59 + private TabPane tabs;
     60 + 
     61 + @Override
     62 + public void initialize(URL location, ResourceBundle resources) {
     63 + GuiBundle.getInstance().setApplicationController(this);
     64 + Bundle.getInstance().getClientManager().registerConnectionListener(this);
     65 + 
     66 + initApplicationTabs();
     67 + initChallengeTabs();
     68 + 
     69 + Logger.getGlobal().info("Application initialized!");
     70 + }
     71 + 
     72 + /**
     73 + * Exits application dialog.
     74 + */
     75 + @FXML
     76 + private void onExitMenuClick(ActionEvent event) {
     77 + Platform.exit();
     78 + }
     79 + /**
     80 + * Shows application about dialog.
     81 + */
     82 + 
     83 + @FXML
     84 + private void showAbout(ActionEvent e) {
     85 + AboutDialog.show();
     86 + }
     87 + 
     88 + @Override
     89 + public void onConnectionStart(Connection connection) {
     90 + Platform.runLater(() ->
     91 + challengeWrappers.forEach(challengeWrapper -> challengeWrapper.getNode().setDisable(false))
     92 + );
     93 + }
     94 + 
     95 + @Override
     96 + public void onConnectionStop(Connection connection) {
     97 + Platform.runLater(() ->
     98 + challengeWrappers.forEach(challengeWrapper -> challengeWrapper.getNode().setDisable(true))
     99 + );
     100 + }
     101 + 
     102 + /**
     103 + * Registers new tab to main tabs.
     104 + * @param title Title of the tab
     105 + * @param node Node to be added as a child into the tab
     106 + * @param order Order of the tab (where should the tab be placed)
     107 + */
     108 + private void registerTab(String title, Node node, int order) {
     109 + GuiUtils.addTabToTabPane(tabs, title, node, order);
     110 + }
     111 + 
     112 + /**
     113 + * Initializes application tab.
     114 + */
     115 + private void initApplicationTab(String title, String template, Object controller, int order) {
     116 + try {
     117 + var fxmlLoader = new FXMLLoader(getClass().getResource(template));
     118 + fxmlLoader.setController(controller);
     119 + registerTab(title, fxmlLoader.load(), order);
     120 + } catch (IOException e) {
     121 + Logger.getGlobal().log(Level.SEVERE, "Could not add settings tab", e);
     122 + }
     123 + }
     124 + 
     125 + /**
     126 + * Initializes challenge tab and saves it to {@code challengeWrappers}.
     127 + */
     128 + private void initChallengeTab(String title, String template, ChallengeController controller, int order) {
     129 + try {
     130 + var fxmlLoader = new FXMLLoader(getClass().getResource(template));
     131 + fxmlLoader.setController(controller);
     132 + var node = (Node) fxmlLoader.load();
     133 + var wrapper = ChallengeWrapper.builder()
     134 + .controller(controller)
     135 + .node(node)
     136 + .build();
     137 + challengeWrappers.add(wrapper);
     138 + node.setDisable(Bundle.getInstance().getClientManager().getState() == ConnectionState.STOPPED);
     139 + registerTab(title, node, order);
     140 + } catch (IOException e) {
     141 + Logger.getGlobal().log(Level.SEVERE, "Could not add settings tab", e);
     142 + }
     143 + }
     144 + 
     145 + /**
     146 + * Initializes main application tabs.
     147 + */
     148 + private void initApplicationTabs() {
     149 + initApplicationTab("Log", "/fxml/tab/LogTab.fxml", new LogController(), GuiConstant.LOG_TAB_ORDER);
     150 + initApplicationTab("Settings", "/fxml/tab/SettingsTab.fxml", new SettingsController(), GuiConstant.SETTINGS_TAB_ORDER);
     151 + }
     152 + 
     153 + /**
     154 + * Initializes challenge tabs.
     155 + * <p>Creates challenges and adds them to the tab pane.</p>
     156 + */
     157 + private void initChallengeTabs() {
     158 + var tabOrder = GuiConstant.CHALLENGES_TAB_ORDER;
     159 + initChallengeTab(
     160 + "Buffer Over-read",
     161 + "/fxml/challenge/bufferoverread/BufferOverreadTab.fxml",
     162 + new BufferOverreadController(),
     163 + ++tabOrder);
     164 + initChallengeTab(
     165 + "SQL Injection",
     166 + "/fxml/challenge/sqlinjection/SqlInjectionTab.fxml",
     167 + new SqlInjectionController(),
     168 + ++tabOrder);
     169 + initChallengeTab(
     170 + "Enumeration",
     171 + "/fxml/challenge/enumeration/EnumerationTab.fxml",
     172 + new EnumerationController(),
     173 + ++tabOrder);
     174 + initChallengeTab(
     175 + "Command Execution",
     176 + "/fxml/challenge/commandexecution/CommandExecutionTab.fxml",
     177 + new CommandExecutionController(),
     178 + ++tabOrder);
     179 + initChallengeTab(
     180 + "XML",
     181 + "/fxml/challenge/xml/XmlTab.fxml",
     182 + new XmlController(),
     183 + ++tabOrder);
     184 + initChallengeTab(
     185 + "Horizontal Access Control",
     186 + "/fxml/challenge/horizontalaccesscontrol/HorizontalAccessControlTab.fxml",
     187 + new HorizontalAccessControlController(),
     188 + ++tabOrder);
     189 + initChallengeTab(
     190 + "Vertical Access Control",
     191 + "/fxml/challenge/verticalaccesscontrol/VerticalAccessControlTab.fxml",
     192 + new VerticalAccessControlController(),
     193 + ++tabOrder);
     194 + }
     195 +}
     196 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/gui/controller/LogController.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.gui.controller;
     18 + 
     19 +import javafx.application.Platform;
     20 +import javafx.css.PseudoClass;
     21 +import javafx.fxml.FXML;
     22 +import javafx.fxml.Initializable;
     23 +import javafx.scene.control.ScrollPane;
     24 +import javafx.scene.text.Font;
     25 +import javafx.scene.text.FontWeight;
     26 +import javafx.scene.text.Text;
     27 +import javafx.scene.text.TextFlow;
     28 + 
     29 +import java.io.PrintWriter;
     30 +import java.io.StringWriter;
     31 +import java.net.URL;
     32 +import java.util.ResourceBundle;
     33 +import java.util.logging.Handler;
     34 +import java.util.logging.Level;
     35 +import java.util.logging.LogRecord;
     36 +import java.util.logging.Logger;
     37 + 
     38 +/**
     39 + * Log tab controller.
     40 + * <p>Displays logs from {@link Logger#getGlobal()}.</p>
     41 + */
     42 +public final class LogController extends Handler implements Initializable {
     43 + /**
     44 + * Maximum number of Text elements in text flow.
     45 + */
     46 + private static final int LIMIT_LOG_CHILDREN = 150;
     47 + 
     48 + private static final PseudoClass INFO_PSEUDO_CLASS = PseudoClass.getPseudoClass("info");
     49 + private static final PseudoClass SEVERE_PSEUDO_CLASS = PseudoClass.getPseudoClass("severe");
     50 + private static final PseudoClass WARNING_PSEUDO_CLASS = PseudoClass.getPseudoClass("warning");
     51 + private static final PseudoClass FINE_PSEUDO_CLASS = PseudoClass.getPseudoClass("fine");
     52 + private static final PseudoClass CONFIG_PSEUDO_CLASS = PseudoClass.getPseudoClass("config");
     53 + private static final PseudoClass OTHER_PSEUDO_CLASS = PseudoClass.getPseudoClass("other");
     54 + 
     55 + /**
     56 + * Text flow for logs.
     57 + */
     58 + @FXML
     59 + private TextFlow logFlow;
     60 + /**
     61 + * Scroll pane containing text flow.
     62 + */
     63 + @FXML
     64 + private ScrollPane scrollPane;
     65 + 
     66 + @Override
     67 + public void initialize(URL location, ResourceBundle resources) {
     68 + Logger.getGlobal().addHandler(this);
     69 + }
     70 + 
     71 + @Override
     72 + public void publish(LogRecord logRecord) {
     73 + Platform.runLater(() -> this.addLogRecord(logRecord));
     74 + }
     75 + 
     76 + @Override
     77 + public void flush() {
     78 + // No action needed.
     79 + }
     80 + 
     81 + @Override
     82 + public void close() {
     83 + // No action needed.
     84 + }
     85 + 
     86 + /**
     87 + * Adds log logRecord to the flow.
     88 + */
     89 + private void addLogRecord(LogRecord logRecord) {
     90 + // Level.
     91 + var level = logRecord.getLevel();
     92 + 
     93 + Text levelText;
     94 + if (level == Level.INFO) {
     95 + levelText = new Text("[INFO] ");
     96 + levelText.pseudoClassStateChanged(INFO_PSEUDO_CLASS, true);
     97 + } else if (level == Level.SEVERE) {
     98 + levelText = new Text("[SEVERE] ");
     99 + levelText.pseudoClassStateChanged(SEVERE_PSEUDO_CLASS, true);
     100 + } else if (level == Level.WARNING) {
     101 + levelText = new Text("[WARNING] ");
     102 + levelText.pseudoClassStateChanged(WARNING_PSEUDO_CLASS, true);
     103 + } else if (level == Level.FINE) {
     104 + levelText = new Text("[FINE] ");
     105 + levelText.pseudoClassStateChanged(FINE_PSEUDO_CLASS, true);
     106 + } else if (level == Level.CONFIG) {
     107 + levelText = new Text("[CONFIG] ");
     108 + levelText.pseudoClassStateChanged(CONFIG_PSEUDO_CLASS, true);
     109 + } else {
     110 + levelText = new Text("[OTHER] ");
     111 + levelText.pseudoClassStateChanged(OTHER_PSEUDO_CLASS, true);
     112 + }
     113 + levelText.getStyleClass().add("log-logRecord");
     114 + levelText.setFont(Font.font(null, FontWeight.BOLD, 11));
     115 + 
     116 + // Message.
     117 + var messageText = new Text(logRecord.getMessage());
     118 + 
     119 + logFlow.getChildren().add(levelText);
     120 + logFlow.getChildren().add(messageText);
     121 + 
     122 + // Exception.
     123 + if (logRecord.getThrown() != null) {
     124 + var exception = new StringWriter();
     125 + exception.append(System.lineSeparator());
     126 + exception.append("\tException:");
     127 + exception.append(System.lineSeparator());
     128 + exception.append("\t");
     129 + logRecord.getThrown().printStackTrace(new PrintWriter(exception));
     130 + var exceptionText = new Text(exception.toString());
     131 + logFlow.getChildren().add(exceptionText);
     132 + }
     133 + 
     134 + // Separator.
     135 + var logSeparator = new Text(System.lineSeparator());
     136 + logSeparator.setFont(Font.font(null, FontWeight.NORMAL, 1));
     137 + logSeparator.setLineSpacing(0);
     138 + logFlow.getChildren().add(logSeparator);
     139 + 
     140 + // Limit children.
     141 + var size = logFlow.getChildren().size();
     142 + if (size > LIMIT_LOG_CHILDREN) {
     143 + logFlow.getChildren().remove(0, size - LIMIT_LOG_CHILDREN);
     144 + }
     145 + 
     146 + // Scroll down automatically.
     147 + scrollPane.layout();
     148 + scrollPane.setVvalue(1D);
     149 + }
     150 +}
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/gui/controller/SettingsController.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.gui.controller;
     18 + 
     19 +import com.warxim.vucsa.client.Bundle;
     20 +import com.warxim.vucsa.client.core.ClientConfig;
     21 +import com.warxim.vucsa.client.gui.dialog.Dialogs;
     22 +import com.warxim.vucsa.common.Constant;
     23 +import com.warxim.vucsa.common.connection.Connection;
     24 +import com.warxim.vucsa.common.connection.ConnectionState;
     25 +import com.warxim.vucsa.common.connection.listener.ConnectionListener;
     26 +import javafx.application.Platform;
     27 +import javafx.event.ActionEvent;
     28 +import javafx.fxml.FXML;
     29 +import javafx.fxml.Initializable;
     30 +import javafx.scene.control.Button;
     31 +import javafx.scene.control.Label;
     32 +import javafx.scene.control.TextField;
     33 + 
     34 +import java.net.URL;
     35 +import java.util.Optional;
     36 +import java.util.ResourceBundle;
     37 + 
     38 +/**
     39 + * Controller for settings tab.
     40 + */
     41 +public class SettingsController implements Initializable, ConnectionListener {
     42 + private static final String CONNECT_TEXT = "CONNECT";
     43 + private static final String DISCONNECT_TEXT = "DISCONNECT";
     44 + 
     45 + @FXML
     46 + private TextField serverHostInput;
     47 + @FXML
     48 + private TextField serverPortInput;
     49 + @FXML
     50 + private Label statusLabel;
     51 + @FXML
     52 + private Label serverHostLabel;
     53 + @FXML
     54 + private Label serverPortLabel;
     55 + @FXML
     56 + private Button startStopButton;
     57 + 
     58 + @Override
     59 + public void initialize(URL location, ResourceBundle resources) {
     60 + serverHostInput.setText(Constant.DEFAULT_SERVER_HOST);
     61 + serverPortInput.setText(String.valueOf(Constant.DEFAULT_SERVER_PORT));
     62 + startStopButton.setText(CONNECT_TEXT);
     63 + onConnectionStop(null);
     64 + var clientManager = Bundle.getInstance().getClientManager();
     65 + clientManager.registerConnectionListener(this);
     66 + }
     67 + 
     68 + @Override
     69 + public void onConnectionStart(Connection connection) {
     70 + Platform.runLater(() -> {
     71 + statusLabel.getStyleClass().add("status-connected");
     72 + statusLabel.getStyleClass().removeAll("status-disconnected");
     73 + statusLabel.setText("CONNECTED");
     74 + startStopButton.setText(DISCONNECT_TEXT);
     75 + });
     76 + }
     77 + 
     78 + @Override
     79 + public void onConnectionStop(Connection connection) {
     80 + Platform.runLater(() -> {
     81 + statusLabel.getStyleClass().removeAll("status-connected");
     82 + statusLabel.getStyleClass().add("status-disconnected");
     83 + statusLabel.setText("DISCONNECTED");
     84 + startStopButton.setText(CONNECT_TEXT);
     85 + });
     86 + }
     87 + 
     88 + /**
     89 + * Starts or stops client using client manager.
     90 + */
     91 + @FXML
     92 + private void onStartStopClick(ActionEvent event) {
     93 + var clientManager = Bundle.getInstance().getClientManager();
     94 + var clientState = clientManager.getState();
     95 + if (clientState == ConnectionState.STARTED) {
     96 + clientManager.stop();
     97 + startStopButton.setText(CONNECT_TEXT);
     98 + } else if (clientState == ConnectionState.STOPPED) {
     99 + var settings = validateAndGetSettings();
     100 + if (settings.isEmpty()) {
     101 + return;
     102 + }
     103 + var config = ClientConfig.builder()
     104 + .serverHost(serverHostInput.getText())
     105 + .serverPort(Integer.parseInt(serverPortInput.getText()))
     106 + .build();
     107 + clientManager.start(config);
     108 + serverHostLabel.setText(serverHostInput.getText());
     109 + serverPortLabel.setText(serverPortInput.getText());
     110 + startStopButton.setText(DISCONNECT_TEXT);
     111 + }
     112 + }
     113 + 
     114 + /**
     115 + * Checks if the settings is valid and returns the settings if it is valid.
     116 + */
     117 + private Optional<ClientConfig> validateAndGetSettings() {
     118 + var serverHost = serverHostInput.getText();
     119 + var serverPort = serverPortInput.getText();
     120 + if (serverHost.isBlank()) {
     121 + Dialogs.createErrorDialog(
     122 + "Server host required",
     123 + "You have to specify server host!");
     124 + return Optional.empty();
     125 + }
     126 + 
     127 + if (serverPort.isBlank() || !isInteger(serverPort)) {
     128 + Dialogs.createErrorDialog(
     129 + "Server port required",
     130 + "You have to specify server port!");
     131 + return Optional.empty();
     132 + }
     133 + 
     134 + var settings = ClientConfig.builder()
     135 + .serverHost(serverHost)
     136 + .serverPort(Integer.parseInt(serverPort))
     137 + .build();
     138 + return Optional.of(settings);
     139 + }
     140 + 
     141 + /**
     142 + * Returns true if the value is a valid integer.
     143 + */
     144 + private static boolean isInteger(String value) {
     145 + try {
     146 + Integer.parseInt(value);
     147 + return true;
     148 + } catch(NumberFormatException e){
     149 + return false;
     150 + }
     151 + }
     152 +}
     153 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/gui/dialog/AboutDialog.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.gui.dialog;
     18 + 
     19 +import com.warxim.vucsa.client.gui.GuiBundle;
     20 +import com.warxim.vucsa.common.Constant;
     21 +import javafx.event.ActionEvent;
     22 +import javafx.geometry.Insets;
     23 +import javafx.scene.control.Alert;
     24 +import javafx.scene.control.Hyperlink;
     25 +import javafx.scene.control.Label;
     26 +import javafx.scene.image.ImageView;
     27 +import javafx.scene.layout.GridPane;
     28 +import javafx.stage.Stage;
     29 + 
     30 +import java.awt.*;
     31 +import java.io.IOException;
     32 +import java.net.URI;
     33 +import java.net.URISyntaxException;
     34 +import java.util.logging.Level;
     35 +import java.util.logging.Logger;
     36 + 
     37 +/**
     38 + * About dialog.
     39 + */
     40 +public final class AboutDialog {
     41 + private AboutDialog() {
     42 + }
     43 + 
     44 + /**
     45 + * Shows about dialog.
     46 + */
     47 + public static void show() {
     48 + var alert = new Alert(Alert.AlertType.INFORMATION);
     49 + 
     50 + alert.setTitle("About VuCSA");
     51 + alert.setHeaderText("VuCSA v" + Constant.VERSION);
     52 + 
     53 + var icon = GuiBundle.getInstance().getLogo();
     54 + 
     55 + var image = new ImageView(icon);
     56 + image.setFitWidth(50);
     57 + image.setFitHeight(50);
     58 + alert.setGraphic(image);
     59 + 
     60 + ((Stage) alert.getDialogPane().getScene().getWindow()).getIcons().add(icon);
     61 + 
     62 + // Info
     63 + var infoLabel = new Label("Vulnerable client-server application (VuCSA) is made for learning/presenting how to perform penetration tests of non-http thick clients.");
     64 + 
     65 + // Version
     66 + var versionLabel = new Label("Version:");
     67 + versionLabel.getStyleClass().add("input-label");
     68 + var versionValueLabel = new Label(Constant.VERSION);
     69 + 
     70 + // Link
     71 + var linkLabel = new Label("Website: ");
     72 + linkLabel.getStyleClass().add("input-label");
     73 + var link = new Hyperlink(Constant.WEB);
     74 + link.setOnAction(AboutDialog::onWebClick);
     75 + 
     76 + // Copyright
     77 + var copyrightLabel = new Label("Copyright (C) Michal Valka, 2022, all rights reserved.");
     78 + 
     79 + // Grid
     80 + var grid = new GridPane();
     81 + grid.setMaxWidth(Double.MAX_VALUE);
     82 + grid.setHgap(10);
     83 + grid.setVgap(10);
     84 + grid.setPadding(new Insets(20, 150, 10, 10));
     85 + 
     86 + // Info
     87 + grid.add(infoLabel, 0, 0, 2, 1);
     88 + 
     89 + // Version
     90 + grid.add(versionLabel, 0, 1);
     91 + grid.add(versionValueLabel, 1, 1);
     92 + 
     93 + // Link
     94 + grid.add(linkLabel, 0, 2);
     95 + grid.add(link, 1, 2);
     96 + 
     97 + // Copyright
     98 + grid.add(copyrightLabel, 0, 3, 2, 1);
     99 + 
     100 + alert.getDialogPane().setContent(grid);
     101 + 
     102 + alert.showAndWait();
     103 + }
     104 + 
     105 + /**
     106 + * Opens VuCSA website.
     107 + */
     108 + private static void onWebClick(ActionEvent event) {
     109 + try {
     110 + Desktop.getDesktop().browse(new URI(Constant.WEB));
     111 + } catch (IOException | URISyntaxException e) {
     112 + Logger.getGlobal().log(Level.SEVERE, "Could not open VuCSA link.");
     113 + }
     114 + }
     115 +}
     116 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/gui/dialog/Dialogs.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.gui.dialog;
     18 + 
     19 +import javafx.geometry.Insets;
     20 +import javafx.scene.control.*;
     21 +import javafx.scene.control.Alert.AlertType;
     22 +import javafx.scene.image.Image;
     23 +import javafx.scene.layout.GridPane;
     24 +import javafx.scene.layout.Priority;
     25 +import javafx.stage.Stage;
     26 +import javafx.util.Pair;
     27 + 
     28 +import java.io.PrintWriter;
     29 +import java.io.StringWriter;
     30 +import java.util.List;
     31 +import java.util.Optional;
     32 + 
     33 +/**
     34 + * Dialog helper.
     35 + */
     36 +public final class Dialogs {
     37 + private static Image defaultIcon;
     38 + 
     39 + /**
     40 + * Gets default icon of PETEP.
     41 + * @return JavaFX image object
     42 + */
     43 + public static Image getDefaultIcon() {
     44 + return defaultIcon;
     45 + }
     46 + 
     47 + /**
     48 + * Sets default icon of PETEP.
     49 + * @param icon Icon to be used through the whole PETEP.
     50 + */
     51 + public static void setDefaultIcon(Image icon) {
     52 + defaultIcon = icon;
     53 + }
     54 + 
     55 + /**
     56 + * Creates simple error dialog (with error icon).
     57 + * @param title Dialog title
     58 + * @param message Dialog content message
     59 + */
     60 + public static void createErrorDialog(String title, String message) {
     61 + var alert = new Alert(AlertType.ERROR);
     62 + alert.setTitle(title);
     63 + alert.setHeaderText(title);
     64 + alert.setContentText(message);
     65 + ((Stage) alert.getDialogPane().getScene().getWindow()).getIcons().add(defaultIcon);
     66 + alert.showAndWait();
     67 + }
     68 + 
     69 + /**
     70 + * Creates simple success dialog (with info icon).
     71 + * @param title Dialog title
     72 + * @param message Dialog content message
     73 + */
     74 + public static void createInfoDialog(String title, String message) {
     75 + var alert = new Alert(AlertType.INFORMATION);
     76 + alert.setTitle(title);
     77 + alert.setHeaderText(title);
     78 + alert.setContentText(message);
     79 + ((Stage) alert.getDialogPane().getScene().getWindow()).getIcons().add(defaultIcon);
     80 + alert.showAndWait();
     81 + }
     82 + 
     83 + /**
     84 + * Creates simple exception dialog.
     85 + * @param title Dialog title
     86 + * @param message Dialog content message
     87 + * @param exception Exception to be displayed in textarea.
     88 + */
     89 + public static void createExceptionDialog(String title, String message, Exception exception) {
     90 + var alert = new Alert(AlertType.ERROR);
     91 + alert.setTitle(title);
     92 + alert.setHeaderText(title);
     93 + alert.setContentText(message);
     94 + 
     95 + ((Stage) alert.getDialogPane().getScene().getWindow()).getIcons().add(defaultIcon);
     96 + 
     97 + var stringWriter = new StringWriter();
     98 + var printWriter = new PrintWriter(stringWriter);
     99 + exception.printStackTrace(printWriter);
     100 + var exceptionText = stringWriter.toString();
     101 + 
     102 + var textArea = new TextArea(exceptionText);
     103 + textArea.setEditable(false);
     104 + textArea.setWrapText(true);
     105 + 
     106 + textArea.setMaxWidth(Double.MAX_VALUE);
     107 + textArea.setMaxHeight(Double.MAX_VALUE);
     108 + GridPane.setVgrow(textArea, Priority.ALWAYS);
     109 + GridPane.setHgrow(textArea, Priority.ALWAYS);
     110 + 
     111 + var label = new Label("The exception stacktrace was:");
     112 + 
     113 + var expContent = new GridPane();
     114 + expContent.setMaxWidth(Double.MAX_VALUE);
     115 + expContent.add(label, 0, 0);
     116 + expContent.add(textArea, 0, 1);
     117 + 
     118 + alert.getDialogPane().setExpandableContent(expContent);
     119 + 
     120 + alert.showAndWait();
     121 + }
     122 + 
     123 + /**
     124 + * Creates simple yes / no / cancel dialog.
     125 + * @param title Dialog title
     126 + * @param message Dialog content message
     127 + * @return {@code Optional.of(true)} if yes has been clicked;<br>
     128 + * {@code Optional.of(false)} if no has been clicked;<br>
     129 + * {@code Optional.empty()} otherwise
     130 + */
     131 + public static Optional<Boolean> createYesOrNoOrCancelDialog(String title, String message) {
     132 + var alert = new Alert(AlertType.CONFIRMATION, message, ButtonType.YES, ButtonType.NO, ButtonType.CANCEL);
     133 + alert.setTitle(title);
     134 + alert.setHeaderText(title);
     135 + ((Stage) alert.getDialogPane().getScene().getWindow()).getIcons().add(defaultIcon);
     136 + 
     137 + alert.showAndWait();
     138 + 
     139 + var result = alert.getResult();
     140 + if (result == ButtonType.YES) {
     141 + return Optional.of(Boolean.TRUE);
     142 + } else if (result == ButtonType.NO) {
     143 + return Optional.of(Boolean.FALSE);
     144 + }
     145 + return Optional.empty();
     146 + }
     147 + 
     148 + /**
     149 + * Creates simple yes / no dialog.
     150 + * @param title Dialog title
     151 + * @param message Dialog content message
     152 + * @return {@code true} if yes has been clicked;<br>
     153 + * {@code false} if no has been clicked
     154 + */
     155 + public static boolean createYesOrNoDialog(String title, String message) {
     156 + var alert = new Alert(AlertType.CONFIRMATION, message, ButtonType.YES, ButtonType.NO);
     157 + alert.setTitle(title);
     158 + alert.setHeaderText(title);
     159 + ((Stage) alert.getDialogPane().getScene().getWindow()).getIcons().add(defaultIcon);
     160 + 
     161 + alert.showAndWait();
     162 + 
     163 + return alert.getResult() == ButtonType.YES;
     164 + }
     165 + 
     166 + /**
     167 + * Creates simple text input dialog. (Empty default value.)
     168 + * @param title Dialog title
     169 + * @param message Dialog content message
     170 + * @return Entered value. (Empty optional if the dialog has been closed/canceled.]
     171 + */
     172 + public static Optional<String> createTextInputDialog(String title, String message) {
     173 + return createTextInputDialog(title, message, "");
     174 + }
     175 + 
     176 + /**
     177 + * Creates simple text input dialog.
     178 + * @param title Dialog title
     179 + * @param message Dialog content message
     180 + * @param value Default input value
     181 + * @return Entered value. (Empty optional if the dialog has been closed/canceled.)
     182 + */
     183 + public static Optional<String> createTextInputDialog(String title, String message, String value) {
     184 + var dialog = new TextInputDialog(value);
     185 + dialog.setTitle(title);
     186 + dialog.setHeaderText(title);
     187 + dialog.setContentText(message);
     188 + 
     189 + ((Stage) dialog.getDialogPane().getScene().getWindow()).getIcons().add(defaultIcon);
     190 + 
     191 + return dialog.showAndWait();
     192 + }
     193 + 
     194 + /**
     195 + * Creates simple choice dialog.
     196 + * @param title Dialog title
     197 + * @param message Dialog content message
     198 + * @param choices Choices to display in dialog
     199 + * @param value Default selected choice
     200 + * @return Chosen value. (Empty optional if the dialog has been closed/canceled.)
     201 + */
     202 + public static <T> Optional<T> createChoiceDialog(String title, String message, List<T> choices, T value) {
     203 + var dialog = new ChoiceDialog<>(value, choices);
     204 + dialog.setTitle(title);
     205 + dialog.setHeaderText(title);
     206 + dialog.setContentText(message);
     207 + 
     208 + ((Stage) dialog.getDialogPane().getScene().getWindow()).getIcons().add(defaultIcon);
     209 + 
     210 + return dialog.showAndWait();
     211 + }
     212 + 
     213 + /**
     214 + * Creates simple choice dialog.
     215 + * @param title Dialog title
     216 + * @param message Dialog content message
     217 + * @param choices Choices to display in dialog
     218 + * @return Chosen value. (Empty optional if the dialog has been closed/canceled.)
     219 + */
     220 + public static <T> Optional<T> createChoiceDialog(String title, String message, List<T> choices) {
     221 + return createChoiceDialog(title, message, choices, null);
     222 + }
     223 + 
     224 + /**
     225 + * Creates dialog for text pair input.
     226 + * <p>Lets user enter two string values.</p>
     227 + * @param title Dialog title
     228 + * @param firstLabel Label of first input
     229 + * @param secondLabel Label of second input
     230 + * @return Entered values. (Empty optional if the dialog has been closed/canceled.)
     231 + */
     232 + public static Optional<Pair<String, String>> createTextPairDialog(
     233 + String title,
     234 + String firstLabel,
     235 + String secondLabel) {
     236 + return createTextPairDialog(title, firstLabel, secondLabel, "", "");
     237 + }
     238 + 
     239 + /**
     240 + * Creates dialog for text pair input with default values.
     241 + * <p>Lets user enter two string values.</p>
     242 + * @param title Dialog title
     243 + * @param firstLabel Label of first input
     244 + * @param secondLabel Label of second input
     245 + * @param firstValue Default value for first input
     246 + * @param secondValue Default value for second input
     247 + * @return Entered values. (Empty optional if the dialog has been closed/canceled.)
     248 + */
     249 + public static Optional<Pair<String, String>> createTextPairDialog(
     250 + String title,
     251 + String firstLabel,
     252 + String secondLabel,
     253 + String firstValue,
     254 + String secondValue) {
     255 + var dialog = new Dialog<Pair<String, String>>();
     256 + dialog.setTitle(title);
     257 + dialog.setHeaderText(title);
     258 + 
     259 + ((Stage) dialog.getDialogPane().getScene().getWindow()).getIcons().add(defaultIcon);
     260 + 
     261 + dialog.getDialogPane().getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
     262 + 
     263 + var keyLabel = new Label(firstLabel);
     264 + var keyInput = new TextField(firstValue);
     265 + keyInput.setMaxWidth(Double.MAX_VALUE);
     266 + 
     267 + var valueLabel = new Label(secondLabel);
     268 + var valueInput = new TextField(secondValue);
     269 + valueInput.setMaxWidth(Double.MAX_VALUE);
     270 + 
     271 + var grid = new GridPane();
     272 + grid.setMaxWidth(Double.MAX_VALUE);
     273 + grid.setHgap(10);
     274 + grid.setVgap(10);
     275 + grid.setPadding(new Insets(20, 150, 10, 10));
     276 + 
     277 + grid.add(keyLabel, 0, 0);
     278 + grid.add(keyInput, 1, 0);
     279 + GridPane.setHgrow(keyInput, Priority.ALWAYS);
     280 + 
     281 + grid.add(valueLabel, 0, 1);
     282 + grid.add(valueInput, 1, 1);
     283 + GridPane.setHgrow(valueInput, Priority.ALWAYS);
     284 + 
     285 + dialog.getDialogPane().setContent(grid);
     286 + 
     287 + dialog.setResultConverter(buttonType -> {
     288 + if (buttonType == ButtonType.OK) {
     289 + return new Pair<>(keyInput.getText(), valueInput.getText());
     290 + }
     291 + return null;
     292 + });
     293 + 
     294 + return dialog.showAndWait();
     295 + }
     296 + 
     297 + private Dialogs() {}
     298 +}
     299 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/java/com/warxim/vucsa/client/util/GuiUtils.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.client.util;
     18 + 
     19 +import javafx.scene.Node;
     20 +import javafx.scene.control.ScrollPane;
     21 +import javafx.scene.control.Tab;
     22 +import javafx.scene.control.TabPane;
     23 + 
     24 +/**
     25 + * GUI utils.
     26 + */
     27 +public final class GuiUtils {
     28 + private GuiUtils() {
     29 + }
     30 + 
     31 + /**
     32 + * Adds tab(node) to specified tab pane using the specified order.
     33 + * (Wraps the node to a scroll pane, creates new tab and adds it to the tabPane.)
     34 + * @param tabPane Tab pane to which to add the tab
     35 + * @param title Text of the tab title
     36 + * @param node Content node, which will be a content of the tab
     37 + * @param order Order to use when adding the tab
     38 + * @return Created tab
     39 + */
     40 + public static Tab addTabToTabPane(TabPane tabPane, String title, Node node, Integer order) {
     41 + var scrollPane = new ScrollPane(node);
     42 + 
     43 + scrollPane.setFitToHeight(true);
     44 + scrollPane.setFitToWidth(true);
     45 + var tab = new Tab(title, scrollPane);
     46 + tab.setUserData(order);
     47 + 
     48 + var tabs = tabPane.getTabs();
     49 + var index = 0;
     50 + for (; index < tabs.size(); ++index) {
     51 + var currentOrder = tabs.get(index).getUserData();
     52 + if (currentOrder == null || (Integer) currentOrder > order) {
     53 + break;
     54 + }
     55 + }
     56 + tabPane.getTabs().add(index, tab);
     57 + return tab;
     58 + }
     59 + 
     60 +}
     61 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/resources/css/Main.css
     1 +{
     2 + -fx-font-size: 12px;
     3 + -fx-color-background-light: #fff;
     4 + -fx-color-text-primary: #000;
     5 + -fx-fill: -fx-color-text-primary;
     6 +}
     7 + 
     8 +.h1,
     9 +.h1 .text {
     10 + -fx-font-size: 15px;
     11 + -fx-font-weight: 700;
     12 +}
     13 + 
     14 +.h2,
     15 +.h2 .text {
     16 + -fx-font-size: 14px;
     17 + -fx-font-weight: 700;
     18 +}
     19 + 
     20 +.h3,
     21 +.h3 .text {
     22 + -fx-font-size: 13px;
     23 + -fx-font-weight: 700;
     24 +}
     25 + 
     26 +.input-label {
     27 + -fx-font-weight: 700;
     28 +}
     29 + 
     30 + 
     31 +/*
     32 + LOG FLOW
     33 +*/
     34 + 
     35 +.log-flow {
     36 + -fx-padding: 5px;
     37 + -fx-border-style: solid;
     38 + -fx-border-width: 1;
     39 + -fx-background-color: -fx-color-background-light;
     40 +}
     41 + 
     42 +.log-flow .log-record:info {
     43 + -fx-fill: -fx-color-text-primary;
     44 +}
     45 + 
     46 +.log-flow .log-record:severe {
     47 + -fx-fill: #a93226;
     48 +}
     49 + 
     50 +.log-flow .log-record:warning {
     51 + -fx-fill: #CA6F1E;
     52 +}
     53 + 
     54 +.log-flow .log-record:fine {
     55 + -fx-fill: #229954;
     56 +}
     57 + 
     58 +.log-flow .log-record:other {
     59 + -fx-fill: #344051;
     60 +}
     61 + 
     62 +.log-flow .log-record:config {
     63 + -fx-fill: #2471A3;
     64 +}
     65 + 
     66 + 
     67 +/*
     68 + STATUS LABEL
     69 +*/
     70 + 
     71 +.status-connected,
     72 +.status-connected .text {
     73 + -fx-fill: #048b04;
     74 +}
     75 + 
     76 +.status-disconnected,
     77 +.status-disconnected .text {
     78 + -fx-fill: #970202;
     79 +}
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/resources/fxml/Application.fxml
     1 +<?xml version="1.0" encoding="UTF-8"?>
     2 + 
     3 +<?import javafx.scene.control.*?>
     4 +<?import javafx.scene.layout.*?>
     5 + 
     6 +<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="650" prefWidth="800" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
     7 + <children>
     8 + <MenuBar>
     9 + <menus>
     10 + <Menu mnemonicParsing="false" text="Application">
     11 + <items>
     12 + <MenuItem mnemonicParsing="false" onAction="#onExitMenuClick" text="Exit" />
     13 + </items>
     14 + </Menu>
     15 + <Menu mnemonicParsing="false" text="Help">
     16 + <items>
     17 + <MenuItem mnemonicParsing="false" onAction="#showAbout" text="About" />
     18 + </items>
     19 + </Menu>
     20 + </menus>
     21 + </MenuBar>
     22 + <AnchorPane prefHeight="423.0" prefWidth="698.0" VBox.vgrow="ALWAYS">
     23 + <children>
     24 + <TabPane fx:id="tabs" layoutY="7.0" prefHeight="400.0" prefWidth="600.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
     25 + </children>
     26 + </AnchorPane>
     27 + </children>
     28 +</VBox>
     29 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/resources/fxml/challenge/bufferoverread/BufferOverreadTab.fxml
     1 +<?xml version="1.0" encoding="UTF-8"?>
     2 + 
     3 +<?import javafx.scene.control.Button?>
     4 +<?import javafx.scene.control.Label?>
     5 +<?import javafx.scene.control.ListView?>
     6 +<?import javafx.scene.layout.AnchorPane?>
     7 +<?import javafx.scene.layout.VBox?>
     8 + 
     9 +<AnchorPane prefHeight="468.0" prefWidth="725.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
     10 + <children>
     11 + <Label layoutX="14.0" layoutY="14.0" styleClass="h1" text="Buffer over-read" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="10.0" />
     12 + <Label layoutX="14.0" layoutY="14.0" text="This is a simulation of buffer over-read vulnerability. Find out how to cause buffer over-read by modifying the communication of the following mechanism. (Note: it works in both directions.)" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="35.0" />
     13 + <VBox layoutX="10.0" layoutY="58.0" prefHeight="392.0" prefWidth="686.0" spacing="10.0" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="65.0">
     14 + <children>
     15 + <Label styleClass="input-label" text="Request:" />
     16 + <ListView fx:id="requestInput" prefHeight="410.0" prefWidth="248.0" />
     17 + <Label styleClass="input-label" text="Response:" />
     18 + <ListView fx:id="responseInput" prefHeight="410.0" prefWidth="248.0" />
     19 + </children>
     20 + </VBox>
     21 + <Button layoutX="635.0" layoutY="59.0" mnemonicParsing="false" onAction="#onSendClick" prefHeight="25.0" prefWidth="80.0" text="Send" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="59.0" />
     22 + </children>
     23 +</AnchorPane>
     24 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/resources/fxml/challenge/commandexecution/CommandExecutionTab.fxml
     1 +<?xml version="1.0" encoding="UTF-8"?>
     2 + 
     3 +<?import javafx.scene.control.Button?>
     4 +<?import javafx.scene.control.Label?>
     5 +<?import javafx.scene.control.TextArea?>
     6 +<?import javafx.scene.control.TextField?>
     7 +<?import javafx.scene.layout.AnchorPane?>
     8 + 
     9 +<AnchorPane prefHeight="468.0" prefWidth="725.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
     10 + <children>
     11 + <Label layoutX="14.0" layoutY="14.0" styleClass="h1" text="Command Execution" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="10.0" />
     12 + <Label layoutX="14.0" layoutY="14.0" text="Try to exploit this simple command execution vulnerability!" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="35.0" />
     13 + <Button layoutX="635.0" layoutY="59.0" mnemonicParsing="false" onAction="#onPingClick" prefHeight="25.0" prefWidth="80.0" text="Ping" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="59.0" />
     14 + <TextField fx:id="hostInput" layoutX="67.0" layoutY="59.0" prefHeight="25.0" prefWidth="562.0" AnchorPane.leftAnchor="65.0" AnchorPane.rightAnchor="96.0" />
     15 + <Label layoutX="10.0" layoutY="63.0" styleClass="input-label" text="Ping:" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="63.0" />
     16 + <TextArea fx:id="resultOutput" editable="false" layoutX="14.0" layoutY="90.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="90.0" />
     17 + </children>
     18 +</AnchorPane>
     19 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/resources/fxml/challenge/enumeration/EnumerationTab.fxml
     1 +<?xml version="1.0" encoding="UTF-8"?>
     2 + 
     3 +<?import javafx.scene.control.Button?>
     4 +<?import javafx.scene.control.Label?>
     5 +<?import javafx.scene.control.PasswordField?>
     6 +<?import javafx.scene.control.TextField?>
     7 +<?import javafx.scene.layout.AnchorPane?>
     8 + 
     9 +<AnchorPane prefHeight="468.0" prefWidth="725.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
     10 + <children>
     11 + <Label layoutX="14.0" layoutY="14.0" styleClass="h1" text="Enumeration" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="10.0" />
     12 + <Label layoutX="14.0" layoutY="14.0" text="The login form is vulnerable to user enumeration and password brute-force attacks. Can find all 5 accounts? Can you automate it using external HTTP proxy?" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="35.0" />
     13 + <Button layoutX="200.0" layoutY="176.0" minWidth="80.0" mnemonicParsing="false" onAction="#onLoginClick" prefHeight="25.0" prefWidth="321.0" text="Login" AnchorPane.leftAnchor="200.0" AnchorPane.rightAnchor="200.0" AnchorPane.topAnchor="176.0" />
     14 + <Label alignment="CENTER" layoutX="10.0" layoutY="68.0" styleClass="input-label" text="Username" textAlignment="CENTER" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" />
     15 + <Label alignment="CENTER" layoutX="10.0" layoutY="121.0" styleClass="input-label" text="Password" textAlignment="CENTER" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="121.0" />
     16 + <TextField fx:id="usernameInput" alignment="CENTER" layoutX="200.0" layoutY="91.0" AnchorPane.leftAnchor="200.0" AnchorPane.rightAnchor="200.0" AnchorPane.topAnchor="91.0" />
     17 + <PasswordField fx:id="passwordInput" alignment="CENTER" layoutX="200.0" layoutY="144.0" prefHeight="25.0" prefWidth="325.0" AnchorPane.leftAnchor="200.0" AnchorPane.rightAnchor="200.0" />
     18 + <Label alignment="CENTER" contentDisplay="CENTER" layoutX="49.0" layoutY="246.0" prefHeight="17.0" prefWidth="626.0" styleClass="input-label" text="Result" textAlignment="CENTER" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" />
     19 + <Label fx:id="resultLabel" alignment="CENTER" contentDisplay="CENTER" layoutX="10.0" layoutY="268.0" prefHeight="17.0" prefWidth="626.0" text="-" textAlignment="CENTER" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" />
     20 + </children>
     21 +</AnchorPane>
     22 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/resources/fxml/challenge/horizontalaccesscontrol/HorizontalAccessControlTab.fxml
     1 +<?xml version="1.0" encoding="UTF-8"?>
     2 + 
     3 +<?import javafx.scene.control.Label?>
     4 +<?import javafx.scene.control.ListView?>
     5 +<?import javafx.scene.control.TextArea?>
     6 +<?import javafx.scene.layout.AnchorPane?>
     7 +<?import javafx.scene.layout.VBox?>
     8 + 
     9 +<AnchorPane prefHeight="468.0" prefWidth="725.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
     10 + <children>
     11 + <Label layoutX="14.0" layoutY="14.0" styleClass="h1" text="Horizontal Access Control Vulnerability" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="10.0" />
     12 + <Label layoutX="14.0" layoutY="14.0" text="Imagine that you are logged in as a user and you have the following GUI accessible. Try to find a way to obtain documents of other users." AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="35.0" />
     13 + <VBox layoutX="10.0" layoutY="58.0" prefHeight="392.0" prefWidth="686.0" spacing="10.0" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="65.0">
     14 + <children>
     15 + <Label styleClass="input-label" text="Your documents (select to display text content):" />
     16 + <ListView fx:id="documentInput" prefHeight="410.0" prefWidth="248.0" />
     17 + <Label styleClass="input-label" text="Content:" />
     18 + <TextArea fx:id="contentOutput" prefHeight="410.0" prefWidth="705.0" VBox.vgrow="ALWAYS" />
     19 + </children>
     20 + </VBox>
     21 + </children>
     22 +</AnchorPane>
     23 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/resources/fxml/challenge/sqlinjection/SqlInjectionTab.fxml
     1 +<?xml version="1.0" encoding="UTF-8"?>
     2 + 
     3 +<?import javafx.scene.control.Button?>
     4 +<?import javafx.scene.control.Label?>
     5 +<?import javafx.scene.control.TableColumn?>
     6 +<?import javafx.scene.control.TableView?>
     7 +<?import javafx.scene.control.TextField?>
     8 +<?import javafx.scene.layout.AnchorPane?>
     9 + 
     10 +<AnchorPane prefHeight="468.0" prefWidth="725.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
     11 + <children>
     12 + <Label layoutX="14.0" layoutY="14.0" styleClass="h1" text="SQL Injection" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="10.0" />
     13 + <Label layoutX="14.0" layoutY="14.0" text="The following functionality is vulnerable to SQL injection! Try exploiting it and loading list of users." AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="35.0" />
     14 + <Button layoutX="635.0" layoutY="59.0" mnemonicParsing="false" onAction="#onSearchClick" prefHeight="25.0" prefWidth="80.0" text="Search" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="59.0" />
     15 + <TextField fx:id="searchInput" layoutX="67.0" layoutY="59.0" prefHeight="25.0" prefWidth="562.0" AnchorPane.leftAnchor="65.0" AnchorPane.rightAnchor="96.0" />
     16 + <Label layoutX="10.0" layoutY="63.0" styleClass="input-label" text="Search:" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="63.0" />
     17 + <TableView fx:id="resultTable" layoutX="10.0" layoutY="91.0" prefHeight="370.0" prefWidth="705.0" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="90.0">
     18 + <columns>
     19 + <TableColumn fx:id="idColumn" prefWidth="75.0" text="Number" />
     20 + <TableColumn fx:id="nameColumn" prefWidth="75.0" text="Name" />
     21 + <TableColumn fx:id="descriptionColumn" prefWidth="230.0" text="Description" />
     22 + <TableColumn fx:id="priceColumn" prefWidth="121.0" text="Price" />
     23 + </columns>
     24 + <columnResizePolicy>
     25 + <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
     26 + </columnResizePolicy>
     27 + </TableView>
     28 + </children>
     29 +</AnchorPane>
     30 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/resources/fxml/challenge/verticalaccesscontrol/VerticalAccessControlTab.fxml
     1 +<?xml version="1.0" encoding="UTF-8"?>
     2 + 
     3 +<?import javafx.scene.control.Button?>
     4 +<?import javafx.scene.control.Label?>
     5 +<?import javafx.scene.layout.AnchorPane?>
     6 + 
     7 +<AnchorPane prefHeight="468.0" prefWidth="725.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
     8 + <children>
     9 + <Label layoutX="14.0" layoutY="14.0" styleClass="h1" text="Vertical Access Control Vulnerability" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="10.0" />
     10 + <Label layoutX="14.0" layoutY="14.0" text="Find a way to change your application role by modifying communication and use a secret function, which is only available for admins." AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="35.0" />
     11 + <Button layoutX="377.0" layoutY="59.0" mnemonicParsing="false" onAction="#onRefreshClick" prefHeight="25.0" prefWidth="80.0" text="Refresh" AnchorPane.leftAnchor="377.0" AnchorPane.topAnchor="59.0" />
     12 + <Label layoutX="10.0" layoutY="63.0" styleClass="input-label" text="Username:" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="63.0" />
     13 + <Label fx:id="usernameLabel" layoutX="76.0" layoutY="63.0" text="-" AnchorPane.leftAnchor="85.0" AnchorPane.topAnchor="63.0" />
     14 + <Label layoutX="208.0" layoutY="63.0" styleClass="input-label" text="Role:" AnchorPane.leftAnchor="208.0" AnchorPane.topAnchor="63.0" />
     15 + <Label fx:id="roleLabel" layoutX="246.0" layoutY="63.0" text="-" AnchorPane.leftAnchor="250.0" AnchorPane.topAnchor="63.0" />
     16 + <AnchorPane fx:id="guestPane" layoutX="6.0" layoutY="84.0" prefHeight="200.0" prefWidth="200.0" visible="false" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="90.0">
     17 + <children>
     18 + <Label layoutY="6.0" text="You cannot do anything, because you are a GUEST!" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0" />
     19 + </children>
     20 + </AnchorPane>
     21 + <AnchorPane fx:id="userPane" layoutX="16.0" layoutY="94.0" prefHeight="200.0" prefWidth="200.0" visible="false" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="90.0">
     22 + <children>
     23 + <Label layoutY="6.0" text="Hello user! How was your day? We are working hard on implementing more functionality for you..." AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0" />
     24 + </children>
     25 + </AnchorPane>
     26 + <AnchorPane fx:id="adminPane" layoutX="26.0" layoutY="104.0" prefHeight="200.0" prefWidth="200.0" visible="false" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="90.0">
     27 + <children>
     28 + <Label layoutY="6.0" text="Welcome administrator!" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0" />
     29 + <Label layoutX="-4.0" layoutY="58.0" text="Secret:" AnchorPane.leftAnchor="0.0" />
     30 + <Button layoutX="2.0" layoutY="26.0" mnemonicParsing="false" onAction="#onDownloadSecretClick" text="Download Secret" AnchorPane.leftAnchor="10.0" />
     31 + <Label fx:id="secretLabel" layoutX="46.0" layoutY="58.0" text="-" />
     32 + </children>
     33 + </AnchorPane>
     34 + </children>
     35 +</AnchorPane>
     36 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/resources/fxml/challenge/xml/XmlTab.fxml
     1 +<?xml version="1.0" encoding="UTF-8"?>
     2 + 
     3 +<?import javafx.scene.control.Button?>
     4 +<?import javafx.scene.control.Label?>
     5 +<?import javafx.scene.control.TableColumn?>
     6 +<?import javafx.scene.control.TableView?>
     7 +<?import javafx.scene.layout.AnchorPane?>
     8 +<?import javafx.scene.layout.VBox?>
     9 + 
     10 +<AnchorPane prefHeight="468.0" prefWidth="725.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
     11 + <children>
     12 + <Label layoutX="14.0" layoutY="14.0" styleClass="h1" text="XML Vulnerabilities" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="10.0" />
     13 + <Label layoutX="14.0" layoutY="14.0" text="You can try multiple XML vulnerabilities here. For example, try to load some system file using XML entities or xi:include." AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="35.0" />
     14 + <VBox layoutX="10.0" layoutY="58.0" prefHeight="392.0" prefWidth="686.0" spacing="10.0" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="65.0">
     15 + <children>
     16 + <Label styleClass="input-label" text="Storage request:" />
     17 + <TableView fx:id="requestTable" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
     18 + <columns>
     19 + <TableColumn fx:id="requestKeyColumn" prefWidth="75.0" text="Storage Key" />
     20 + <TableColumn fx:id="requestValueColumn" prefWidth="75.0" text="Storage Value" />
     21 + </columns>
     22 + <columnResizePolicy>
     23 + <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
     24 + </columnResizePolicy>
     25 + </TableView>
     26 + <Label styleClass="input-label" text="Storage response:" />
     27 + <TableView fx:id="responseTable" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
     28 + <columns>
     29 + <TableColumn fx:id="responseKeyColumn" prefWidth="75.0" text="Storage Key" />
     30 + <TableColumn fx:id="responseValueColumn" prefWidth="75.0" text="Storage Value" />
     31 + </columns>
     32 + <columnResizePolicy>
     33 + <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
     34 + </columnResizePolicy>
     35 + </TableView>
     36 + </children>
     37 + </VBox>
     38 + <Button layoutX="635.0" layoutY="59.0" mnemonicParsing="false" onAction="#onSendClick" prefHeight="25.0" prefWidth="80.0" text="Save" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="59.0" />
     39 + </children>
     40 +</AnchorPane>
     41 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/resources/fxml/tab/LogTab.fxml
     1 +<?xml version="1.0" encoding="UTF-8"?>
     2 + 
     3 +<?import javafx.scene.control.ScrollPane?>
     4 +<?import javafx.scene.layout.*?>
     5 +<?import javafx.scene.text.TextFlow?>
     6 + 
     7 +<AnchorPane xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1">
     8 + <children>
     9 + <ScrollPane fx:id="scrollPane" fitToHeight="true" fitToWidth="true" layoutX="10.0" layoutY="10.0" vvalue="1.0" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0">
     10 + <content>
     11 + <TextFlow fx:id="logFlow" styleClass="log-flow" />
     12 + </content>
     13 + </ScrollPane>
     14 + </children>
     15 +</AnchorPane>
     16 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-client/src/main/resources/fxml/tab/SettingsTab.fxml
     1 +<?xml version="1.0" encoding="UTF-8"?>
     2 + 
     3 +<?import javafx.scene.control.Button?>
     4 +<?import javafx.scene.control.Label?>
     5 +<?import javafx.scene.control.TextField?>
     6 +<?import javafx.scene.layout.AnchorPane?>
     7 + 
     8 +<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
     9 + <children>
     10 + <Label layoutX="10.0" layoutY="168.0" styleClass="h2" text="Connection Settings" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="168.0" />
     11 + <Label layoutX="14.0" layoutY="14.0" styleClass="h1" text="Settings" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="10.0" />
     12 + <Label layoutX="10.0" layoutY="218.0" styleClass="input-label" text="Server IP:" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="218.0" />
     13 + <TextField fx:id="serverHostInput" layoutX="100.0" layoutY="214.0" prefHeight="25.0" prefWidth="250.0" AnchorPane.leftAnchor="100.0" AnchorPane.topAnchor="214.0" />
     14 + <Label layoutX="10.0" layoutY="36.0" text="In this tab you can configure the application and the connection to the vulnerable test server." />
     15 + <Label layoutX="10.0" layoutY="190.0" text="Settings of the connection to the vulnerable test server." />
     16 + <Label layoutX="10.0" layoutY="248.0" styleClass="input-label" text="Server port:" AnchorPane.topAnchor="248.0" />
     17 + <TextField fx:id="serverPortInput" layoutX="100.0" layoutY="244.0" prefHeight="25.0" prefWidth="250.0" AnchorPane.leftAnchor="100.0" AnchorPane.topAnchor="244.0" />
     18 + <Label layoutX="10.0" layoutY="63.0" styleClass="h2" text="Status" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="65.0" />
     19 + <Label layoutX="10.0" layoutY="87.0" styleClass="input-label" text="Status:" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="87.0" />
     20 + <Label layoutX="10.0" layoutY="112.0" styleClass="input-label" text="Server Host:" AnchorPane.topAnchor="112.0" />
     21 + <Label layoutX="10.0" layoutY="137.0" styleClass="input-label" text="Server Port:" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="137.0" />
     22 + <Label fx:id="statusLabel" layoutX="100.0" layoutY="87.0" text="-" />
     23 + <Label fx:id="serverHostLabel" layoutX="100.0" layoutY="112.0" text="-" />
     24 + <Label fx:id="serverPortLabel" layoutX="100.0" layoutY="137.0" text="-" />
     25 + <Button fx:id="startStopButton" layoutX="210.0" layoutY="83.0" mnemonicParsing="false" onAction="#onStartStopClick" prefHeight="25.0" prefWidth="107.0" text="CONNECT" />
     26 + </children>
     27 +</AnchorPane>
     28 + 
  • vucsa-client/src/main/resources/img/Logo.png
  • ■ ■ ■ ■ ■ ■
    vucsa-common/build.gradle
     1 +plugins {
     2 + id 'java'
     3 +}
     4 + 
     5 +group 'com.warxim'
     6 +version '1.0'
     7 + 
     8 +repositories {
     9 + mavenCentral()
     10 +}
     11 + 
     12 +dependencies {
     13 + compileOnly 'org.projectlombok:lombok:1.18.24'
     14 + annotationProcessor 'org.projectlombok:lombok:1.18.24'
     15 + implementation 'com.google.code.gson:gson:2.9.0'
     16 + 
     17 + testImplementation 'org.testng:testng:7.6.0'
     18 + testImplementation 'org.assertj:assertj-core:3.23.1'
     19 + testImplementation 'org.mockito:mockito-inline:4.6.1'
     20 +}
     21 + 
     22 +test {
     23 + useTestNG()
     24 +}
     25 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-common/src/main/java/com/warxim/vucsa/common/ChallengeConstant.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.common;
     18 + 
     19 +/**
     20 + * Constants for challenges.
     21 + */
     22 +public final class ChallengeConstant {
     23 + public static final int BUFFER_OVERREAD_TARGET = 1001;
     24 + public static final int SQL_INJECTION_TARGET = 1002;
     25 + public static final int ENUMERATION_TARGET = 1003;
     26 + public static final int COMMAND_EXECUTION_TARGET = 1004;
     27 + public static final int XML_TARGET = 1005;
     28 + public static final int VERTICAL_ACCESS_CONTROL_USER_INFO_TARGET = 1006;
     29 + public static final int VERTICAL_ACCESS_CONTROL_SECRET_TARGET = 1007;
     30 + public static final int HORIZONTAL_ACCESS_CONTROL_DOCUMENT_CONTENT_TARGET = 1008;
     31 + 
     32 + public static final String CHALLENGES_DIRECTORY = "server/challenge/";
     33 + 
     34 + private ChallengeConstant() {}
     35 +}
     36 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-common/src/main/java/com/warxim/vucsa/common/Constant.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.common;
     18 + 
     19 +/**
     20 + * Global constants.
     21 + */
     22 +public final class Constant {
     23 + public static final String VERSION = "1.0.0";
     24 + public static final String WEB = "http://vucsa.warxim.com";
     25 + 
     26 + public static final String DEFAULT_SERVER_HOST = "127.0.0.1";
     27 + public static final int DEFAULT_SERVER_PORT = 8765;
     28 + 
     29 + public static final String SERVER_CONFIG_PATH = "server.json";
     30 + 
     31 + private Constant() {}
     32 +}
     33 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-common/src/main/java/com/warxim/vucsa/common/connection/Connection.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.common.connection;
     18 + 
     19 +import com.warxim.vucsa.common.message.MessageHandler;
     20 +import com.warxim.vucsa.common.connection.listener.ConnectionListener;
     21 +import com.warxim.vucsa.common.message.Message;
     22 +import com.warxim.vucsa.common.message.MessageQueue;
     23 +import com.warxim.vucsa.common.util.MessageUtils;
     24 +import lombok.RequiredArgsConstructor;
     25 + 
     26 +import java.io.DataInputStream;
     27 +import java.io.EOFException;
     28 +import java.io.IOException;
     29 +import java.net.Socket;
     30 +import java.net.SocketException;
     31 +import java.util.concurrent.ExecutorService;
     32 +import java.util.concurrent.Executors;
     33 +import java.util.concurrent.atomic.AtomicBoolean;
     34 +import java.util.logging.Level;
     35 +import java.util.logging.Logger;
     36 + 
     37 +/**
     38 + * Connection representing single connection between client and server.
     39 + * <p>Implementation has to set socket.</p>
     40 + */
     41 +@RequiredArgsConstructor
     42 +public abstract class Connection {
     43 + /**
     44 + * Connection identifier.
     45 + */
     46 + protected final int id;
     47 + 
     48 + /**
     49 + * Connection listener for reporting connection start/stop events.
     50 + */
     51 + protected final ConnectionListener listener;
     52 + 
     53 + /**
     54 + * Message handler for handling messages, which the connection read from the input stream.
     55 + */
     56 + protected final MessageHandler messageHandler;
     57 + 
     58 + /**
     59 + * Executor service for running read and write threads.
     60 + */
     61 + protected final ExecutorService executor = Executors.newFixedThreadPool(2);
     62 + 
     63 + /**
     64 + * Flag determining if the connection is already in closing state or not.
     65 + */
     66 + protected final AtomicBoolean closing = new AtomicBoolean(false);
     67 + 
     68 + /**
     69 + * Queue for message, which the connection will send using the output stream.
     70 + */
     71 + protected final MessageQueue outgoingQueue = new MessageQueue();
     72 + 
     73 + /**
     74 + * Connection socket, which has to be provided by the implementation.
     75 + */
     76 + protected Socket socket;
     77 + 
     78 + /**
     79 + * Connection state.
     80 + */
     81 + protected ConnectionState state;
     82 + 
     83 + /**
     84 + * Starts the connection.
     85 + * <p>If the start fails, it is automatically stopped.</p>
     86 + */
     87 + public void start() {
     88 + Logger.getGlobal().info("Starting connection...");
     89 + state = ConnectionState.STARTING;
     90 + if (!handleBeforeStart()) {
     91 + stop();
     92 + }
     93 + 
     94 + executor.execute(this::doRead);
     95 + executor.execute(this::doWrite);
     96 + executor.execute(this::stop);
     97 + 
     98 + if (!handleAfterStart()) {
     99 + stop();
     100 + }
     101 + state = ConnectionState.STARTED;
     102 + Logger.getGlobal().info("Connection started.");
     103 + 
     104 + listener.onConnectionStart(this);
     105 + }
     106 + 
     107 + /**
     108 + * Stops the connection.
     109 + */
     110 + public void stop() {
     111 + if (!closing.compareAndSet(false, true)) {
     112 + return;
     113 + }
     114 + 
     115 + Logger.getGlobal().info("Stopping connection...");
     116 + state = ConnectionState.STOPPING;
     117 + handleBeforeStop();
     118 + 
     119 + executor.shutdownNow();
     120 + if (socket != null) {
     121 + try {
     122 + socket.close();
     123 + } catch (IOException e) {
     124 + Logger.getGlobal().log(Level.SEVERE, "Could not close connection socket.", e);
     125 + }
     126 + }
     127 + 
     128 + state = ConnectionState.STOPPED;
     129 + handleAfterStop();
     130 + Logger.getGlobal().info("Connection stopped.");
     131 + 
     132 + listener.onConnectionStop(this);
     133 + }
     134 + 
     135 + /**
     136 + * Sends message using the socket.
     137 + * @param message Message to be sent
     138 + */
     139 + public void sendMessage(Message message) {
     140 + this.outgoingQueue.add(message);
     141 + }
     142 + 
     143 + /**
     144 + * Obtains connection state.
     145 + * @return Connection state
     146 + */
     147 + public ConnectionState getState() {
     148 + return state;
     149 + }
     150 + 
     151 + /**
     152 + * Obtains connection identifier.
     153 + * @return Connection identifier
     154 + */
     155 + public int getId() {
     156 + return id;
     157 + }
     158 + 
     159 + /**
     160 + * Runs before the connection starts.
     161 + * @return {@code true} if everything went well; {@code false} if the connection should be stopped
     162 + */
     163 + protected boolean handleBeforeStart() {
     164 + return true;
     165 + }
     166 + 
     167 + /**
     168 + * Runs after the connection starts.
     169 + * @return {@code true} if everything went well; {@code false} if the connection should be stopped
     170 + */
     171 + protected boolean handleAfterStart() {
     172 + return true;
     173 + }
     174 + 
     175 + /**
     176 + * Runs before the connection stops.
     177 + */
     178 + protected void handleBeforeStop() {}
     179 + 
     180 + /**
     181 + * Runs after the connection stops.
     182 + */
     183 + protected void handleAfterStop() {}
     184 + 
     185 + /**
     186 + * Reads messages from input stream and sends them to the handler.
     187 + */
     188 + private void doRead() {
     189 + try (var in = new DataInputStream(socket.getInputStream())) {
     190 + while (!closing.get()) {
     191 + var maybeMessage = MessageUtils.readMessageFromInputStream(in);
     192 + if (maybeMessage.isEmpty()) {
     193 + continue;
     194 + }
     195 + var message = maybeMessage.get();
     196 + if (messageHandler.supports(message)) {
     197 + messageHandler.handleMessage(this, message);
     198 + }
     199 + }
     200 + } catch (SocketException | EOFException e) {
     201 + // Connection closed
     202 + } catch (IOException e) {
     203 + Logger.getGlobal().log(Level.SEVERE, "IO exception occurred durring connection read.", e);
     204 + }
     205 + }
     206 + 
     207 + /**
     208 + * Gets messages from outgoing queue and sends them using output stream.
     209 + */
     210 + private void doWrite() {
     211 + try (var out = socket.getOutputStream()) {
     212 + Message message;
     213 + while (!closing.get() && (message = outgoingQueue.take()) != null) {
     214 + MessageUtils.writeMessageToOutputStream(message, out);
     215 + }
     216 + } catch (SocketException e) {
     217 + // Connection closed
     218 + } catch (IOException e) {
     219 + Logger.getGlobal().log(Level.SEVERE, "IO exception occurred durring connection write.", e);
     220 + } catch (InterruptedException e) {
     221 + // Interrupted
     222 + Thread.currentThread().interrupt();
     223 + }
     224 + }
     225 +}
     226 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-common/src/main/java/com/warxim/vucsa/common/connection/ConnectionState.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.common.connection;
     18 + 
     19 +/**
     20 + * State of connection.
     21 + */
     22 +public enum ConnectionState {
     23 + /**
     24 + * Connection is starting
     25 + */
     26 + STARTING,
     27 + /**
     28 + * Connection is running
     29 + */
     30 + STARTED,
     31 + /**
     32 + * Connection is stopping
     33 + */
     34 + STOPPING,
     35 + /**
     36 + * Connection is offline
     37 + */
     38 + STOPPED
     39 +}
     40 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-common/src/main/java/com/warxim/vucsa/common/connection/listener/ConnectionListener.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.common.connection.listener;
     18 + 
     19 +import com.warxim.vucsa.common.connection.Connection;
     20 + 
     21 +/**
     22 + * ConnectionListener allows code to listen for connection start/stop events.
     23 + * <p>
     24 + * All event handlers should be called from ConnectionManager.
     25 + * </p>
     26 + */
     27 +public interface ConnectionListener {
     28 + /**
     29 + * Event for connection start.
     30 + * @param connection Connection that started
     31 + */
     32 + default void onConnectionStart(Connection connection) {}
     33 + 
     34 + /**
     35 + * Event for connection stop.
     36 + * @param connection Connection that stopped
     37 + */
     38 + default void onConnectionStop(Connection connection) {}
     39 +}
     40 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-common/src/main/java/com/warxim/vucsa/common/connection/listener/ConnectionListenerManager.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.common.connection.listener;
     18 + 
     19 +import com.warxim.vucsa.common.connection.Connection;
     20 +import com.warxim.vucsa.common.listener.ListenerManager;
     21 + 
     22 +/**
     23 + * Listener manager that allows modules to register their own listener (aggregates listeners).
     24 + * <p>Based on {@link ListenerManager}</p>
     25 + */
     26 +public final class ConnectionListenerManager extends ListenerManager<ConnectionListener> implements ConnectionListener {
     27 + @Override
     28 + public void onConnectionStart(Connection connection) {
     29 + parallelCall(listener -> listener.onConnectionStart(connection));
     30 + }
     31 + 
     32 + @Override
     33 + public void onConnectionStop(Connection connection) {
     34 + parallelCall(listener -> listener.onConnectionStop(connection));
     35 + }
     36 +}
  • ■ ■ ■ ■ ■ ■
    vucsa-common/src/main/java/com/warxim/vucsa/common/listener/ListenerManager.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.common.listener;
     18 + 
     19 +import java.lang.ref.WeakReference;
     20 +import java.util.concurrent.CopyOnWriteArrayList;
     21 +import java.util.function.Consumer;
     22 + 
     23 +/**
     24 + * Listener Manager for managing multiple listeners.
     25 + * <p>
     26 + * Uses WeakReference, so that the listener resources are automatically freed,
     27 + * when the reference becomes weakly reachable.
     28 + * (To prevent leaks caused by forgotten unregister call.)
     29 + * </p>
     30 + * <p>
     31 + * Listeners have to be stored as strong reference.
     32 + * </p>
     33 + */
     34 +public class ListenerManager<L> {
     35 + protected final CopyOnWriteArrayList<WeakReference<L>> listeners;
     36 + 
     37 + public ListenerManager() {
     38 + listeners = new CopyOnWriteArrayList<>();
     39 + }
     40 + 
     41 + /**
     42 + * Register listener
     43 + * <p>Stores weak reference to the listener.</p>
     44 + * @param listener Listener to be registered
     45 + */
     46 + public void registerListener(L listener) {
     47 + listeners.add(new WeakReference<>(listener));
     48 + }
     49 + 
     50 + /**
     51 + * Unregister listener
     52 + * <p>Removes listener weak reference from the manager.</p>
     53 + * @param listener Listener to be unregistered
     54 + */
     55 + public void unregisterListener(L listener) {
     56 + listeners.removeIf(reference -> listener.equals(reference.get()));
     57 + }
     58 + 
     59 + /**
     60 + * Call the specified consumer for all listeners
     61 + * <p>
     62 + * Calls {@link Consumer#accept(Object)} for each listener (listener as a parameter).
     63 + * </p>
     64 + * @param consumer Consumer for handling the listener call
     65 + */
     66 + protected void call(Consumer<L> consumer) {
     67 + listeners.forEach(reference -> callListener(reference, consumer));
     68 + }
     69 + 
     70 + /**
     71 + * Call the specified consumer for all listeners in parallel
     72 + * <p>
     73 + * Calls {@link Consumer#accept(Object)} for each listener (listener as a parameter) using parallel stream.
     74 + * </p>
     75 + * @param consumer Consumer for handling the listener call
     76 + */
     77 + protected void parallelCall(Consumer<L> consumer) {
     78 + listeners.parallelStream().forEach(reference -> callListener(reference, consumer));
     79 + }
     80 + 
     81 + /**
     82 + * Removes all listeners.
     83 + */
     84 + public void clear() {
     85 + listeners.clear();
     86 + }
     87 + 
     88 + /**
     89 + * Call the consumer with the listener as parameter (if it is still referenced)
     90 + * <p>Removes the listener reference from listeners, if it does not exist.</p>
     91 + * @param reference Listener reference
     92 + * @param consumer Consumer for handling the listener call
     93 + */
     94 + private void callListener(WeakReference<L> reference, Consumer<L> consumer) {
     95 + var listener = reference.get();
     96 + if (listener == null) {
     97 + listeners.remove(reference);
     98 + return;
     99 + }
     100 + consumer.accept(listener);
     101 + }
     102 +}
     103 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-common/src/main/java/com/warxim/vucsa/common/message/Message.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.common.message;
     18 + 
     19 +import lombok.EqualsAndHashCode;
     20 +import lombok.Getter;
     21 +import lombok.RequiredArgsConstructor;
     22 + 
     23 +/**
     24 + * Message base class.
     25 + * <p>
     26 + * Message is a protocol data unit in vulnerable application.
     27 + * </p>
     28 + */
     29 +@EqualsAndHashCode
     30 +@Getter
     31 +@RequiredArgsConstructor
     32 +public abstract class Message {
     33 + /**
     34 + * Identifier of target handler.
     35 + */
     36 + private final int target;
     37 + 
     38 + /**
     39 + * Obtains type of the message.
     40 + * @return Message type
     41 + */
     42 + public abstract MessageType getType();
     43 +}
     44 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-common/src/main/java/com/warxim/vucsa/common/message/MessageDeserializer.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.common.message;
     18 + 
     19 +import java.util.Optional;
     20 + 
     21 +/**
     22 + * Message deserializer for deserializing bytes into specific message object.
     23 + */
     24 +public interface MessageDeserializer {
     25 + /**
     26 + * Deserializes serialized message into specific message object.
     27 + * @param serializedMessage Serialized message to be deserialized
     28 + * @return Message or empty optional if the deserialization failed
     29 + */
     30 + Optional<Message> deserializeMessage(SerializedMessage serializedMessage);
     31 +}
     32 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-common/src/main/java/com/warxim/vucsa/common/message/MessageHandler.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.common.message;
     18 + 
     19 +import com.warxim.vucsa.common.connection.Connection;
     20 + 
     21 +/**
     22 + * Endpoint for handling messages.
     23 + * <p>Represents "endpoint" for messages.</p>
     24 + */
     25 +public interface MessageHandler {
     26 + /**
     27 + * Checks whether the given message is supported by the handler.
     28 + * @param message Message to be checked
     29 + * @return {@code true} if the message is supported
     30 + */
     31 + boolean supports(Message message);
     32 + 
     33 + /**
     34 + * Handles message in the handler
     35 + * @param connection Connection, which sent the message
     36 + * @param message Message to be handled
     37 + * @return {@code true} if the message has been correctly handled
     38 + */
     39 + boolean handleMessage(Connection connection, Message message);
     40 +}
     41 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-common/src/main/java/com/warxim/vucsa/common/message/MessageHandlerManager.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.common.message;
     18 + 
     19 +import com.warxim.vucsa.common.connection.Connection;
     20 +import lombok.RequiredArgsConstructor;
     21 + 
     22 +import java.util.concurrent.ConcurrentHashMap;
     23 +import java.util.logging.Logger;
     24 + 
     25 +/**
     26 + * Message handler manager aggregates message managers registered for specific target identifiers.
     27 + */
     28 +@RequiredArgsConstructor
     29 +public class MessageHandlerManager implements MessageHandler {
     30 + /**
     31 + * Handlers registered for certain message target.
     32 + */
     33 + private final ConcurrentHashMap<Integer, MessageHandler> handlers = new ConcurrentHashMap<>();
     34 + 
     35 + /**
     36 + * Registers message handler.
     37 + * @param target Target identifier of the handler
     38 + * @param messageHandler Handler to be registered
     39 + */
     40 + public void registerHandler(int target, MessageHandler messageHandler) {
     41 + this.handlers.putIfAbsent(target, messageHandler);
     42 + }
     43 + 
     44 + /**
     45 + * Unregisters message handler.
     46 + * @param target Target identifier of the handler
     47 + */
     48 + public void unregisterHandler(int target) {
     49 + this.handlers.remove(target);
     50 + }
     51 + 
     52 + @Override
     53 + public boolean supports(Message message) {
     54 + return true;
     55 + }
     56 + 
     57 + @Override
     58 + public boolean handleMessage(Connection connection, Message message) {
     59 + var target = message.getTarget();
     60 + var handler = this.handlers.get(target);
     61 + if (handler == null) {
     62 + Logger.getGlobal().severe(() -> String.format("No handler found with id [%d]...", target));
     63 + return false;
     64 + }
     65 + 
     66 + if (!handler.supports(message)) {
     67 + Logger.getGlobal().severe(() -> String.format("Handler [%d] does not support message! Ignoring message...", target));
     68 + return false;
     69 + }
     70 + 
     71 + return handler.handleMessage(connection, message);
     72 + }
     73 +}
     74 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-common/src/main/java/com/warxim/vucsa/common/message/MessageQueue.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.common.message;
     18 + 
     19 +import java.util.Optional;
     20 +import java.util.concurrent.BlockingQueue;
     21 +import java.util.concurrent.LinkedBlockingQueue;
     22 + 
     23 +/**
     24 + * Queue of messages.
     25 + */
     26 +public class MessageQueue {
     27 + private final BlockingQueue<Message> queue;
     28 + 
     29 + public MessageQueue() {
     30 + queue = new LinkedBlockingQueue<>();
     31 + }
     32 + 
     33 + /**
     34 + * Add message to queue.
     35 + * @param message Message to be added to the queue
     36 + */
     37 + public void add(Message message) {
     38 + queue.add(message);
     39 + }
     40 + 
     41 + /**
     42 + * Returns message from queue (blocks until there is message).
     43 + * @return Message from queue
     44 + */
     45 + public Message take() throws InterruptedException {
     46 + return queue.take();
     47 + }
     48 + 
     49 + /**
     50 + * Retrieves and removes the head of the queue.
     51 + * @return Message from queue or empty optional if the queue is empty
     52 + */
     53 + public Optional<Message> poll() {
     54 + return Optional.ofNullable(queue.poll());
     55 + }
     56 + 
     57 + /**
     58 + * Get queue size.
     59 + * @return Size of the queue
     60 + */
     61 + public int size() {
     62 + return queue.size();
     63 + }
     64 + 
     65 + /**
     66 + * Clears queue.
     67 + */
     68 + public void clear() {
     69 + queue.clear();
     70 + }
     71 + 
     72 + /**
     73 + * Checks if the queue is empty.
     74 + * @return {@code true} if the queue is empty
     75 + */
     76 + public boolean isEmpty() {
     77 + return queue.isEmpty();
     78 + }
     79 +}
     80 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-common/src/main/java/com/warxim/vucsa/common/message/MessageSerializer.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.common.message;
     18 + 
     19 +import java.util.Optional;
     20 + 
     21 +/**
     22 + * Message serializer for serializing message into bytes.
     23 + */
     24 +public interface MessageSerializer {
     25 + /**
     26 + * Serializes message into deserialized message.
     27 + * @param message Message to be serialized
     28 + * @return Serialized message or empty optional if the serialization failed
     29 + */
     30 + Optional<SerializedMessage> serializeMessage(Message message);
     31 +}
     32 + 
  • ■ ■ ■ ■ ■ ■
    vucsa-common/src/main/java/com/warxim/vucsa/common/message/MessageType.java
     1 +/*
     2 + * Vulnerable Client-Server Application (VuCSA)
     3 + *
     4 + * Copyright (C) 2021 Michal Válka
     5 + *
     6 + * This program is free software: you can redistribute it and/or modify it under the terms of the
     7 + * GNU General Public License as published by the Free Software Foundation, either version 3 of the
     8 + * License, or (at your option) any later version.
     9 + *
     10 + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
     11 + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     12 + * General Public License for more details.
     13 + *
     14 + * You should have received a copy of the GNU General Public License along with this program. If
     15 + * not, see <https://www.gnu.org/licenses/>.
     16 + */
     17 +package com.warxim.vucsa.common.message;
     18 + 
     19 +import com.warxim.vucsa.common.message.commandexecution.request.PingRequestDeserializer;
     20 +import com.warxim.vucsa.common.message.commandexecution.response.PingResponseDeserializer;
     21 +import com.warxim.vucsa.common.message.commandexecution.response.PingResponseSerializer;
     22 +import com.warxim.vucsa.common.message.horizontalaccesscontrol.request.DocumentContentRequest;
     23 +import com.warxim.vucsa.common.message.horizontalaccesscontrol.response.DocumentContentResponse;
     24 +import com.warxim.vucsa.common.message.sqlinjection.response.SearchResponseDeserializer;
     25 +import com.warxim.vucsa.common.message.verticalaccesscontrol.request.*;
     26 +import com.warxim.vucsa.common.message.verticalaccesscontrol.response.*;
     27 +import com.warxim.vucsa.common.message.bufferoverread.StringListMessageDeserializer;
     28 +import com.warxim.vucsa.common.message.bufferoverread.StringListMessageSerializer;
     29 +import com.warxim.vucsa.common.message.bufferoverread.StringListMessage;
     30 +import com.warxim.vucsa.common.message.commandexecution.request.PingRequest;
     31 +import com.warxim.vucsa.common.message.commandexecution.request.PingRequestSerializer;
     32 +import com.warxim.vucsa.common.message.commandexecution.response.PingResponse;
     33 +import com.warxim.vucsa.common.message.enumeration.request.LoginRequest;
     34 +import com.warxim.vucsa.common.message.enumeration.request.LoginRequestDeserializer;
     35 +import com.warxim.vucsa.common.message.enumeration.request.LoginRequestSerializer;
     36 +import com.warxim.vucsa.common.message.enumeration.response.LoginResponse;
     37 +import com.warxim.vucsa.common.message.enumeration.response.LoginResponseDeserializer;
     38 +import com.warxim.vucsa.common.message.enumeration.response.LoginResponseSerializer;
     39 +import com.warxim.vucsa.common.message.horizontalaccesscontrol.request.DocumentContentRequestDeserializer;
     40 +import com.warxim.vucsa.common.message.horizontalaccesscontrol.request.DocumentContentRequestSerializer;
     41 +import com.warxim.vucsa.common.message.horizontalaccesscontrol.response.DocumentContentResponseDeserializer;
     42 +import com.warxim.vucsa.common.message.horizontalaccesscontrol.response.DocumentContentResponseSerializer;
     43 +import com.warxim.vucsa.common.message.plain.PlainMessage;
     44 +import com.warxim.vucsa.common.message.plain.PlainMessageDeserializer;
     45 +import com.warxim.vucsa.common.message.plain.PlainMessageSerializer;
     46 +import com.warxim.vucsa.common.message.sqlinjection.request.SearchRequest;
     47 +import com.warxim.vucsa.common.message.sqlinjection.request.SearchRequestDeserializer;
     48 +import com.warxim.vucsa.common.message.sqlinjection.request.SearchRequestSerializer;
     49 +import com.warxim.vucsa.common.message.sqlinjection.response.SearchResponse;
     50 +import com.warxim.vucsa.common.message.sqlinjection.response.SearchResponseSerializer;
     51 +import com.warxim.vucsa.common.message.verticalaccesscontrol.request.*;
     52 +import com.warxim.vucsa.common.message.verticalaccesscontrol.response.*;
     53 +import com.warxim.vucsa.common.message.xml.StorageMessage;
     54 +import com.warxim.vucsa.common.message.xml.StorageMessageDeserializer;
     55 +import com.warxim.vucsa.common.message.xml.StorageMessageSerializer;
     56 +import lombok.Getter;
     57 +import lombok.RequiredArgsConstructor;
     58 + 
     59 +import java.util.Arrays;
     60 +import java.util.Optional;
     61 + 
     62 +/**
     63 + * Message type.
     64 + */
     65 +@Getter
     66 +@RequiredArgsConstructor
     67 +public enum MessageType {
     68 + PLAIN(1, PlainMessage.class, new PlainMessageSerializer(), new PlainMessageDeserializer()),
     69 + BUFFER_OVERREAD_STRING_LIST_MESSAGE(2, StringListMessage.class, new StringListMessageSerializer(), new StringListMessageDeserializer()),
     70 + SQL_INJECTION_SEARCH_REQUEST(3, SearchRequest.class, new SearchRequestSerializer(), new SearchRequestDeserializer()),
     71 + SQL_INJECTION_SEARCH_RESPONSE(4, SearchResponse.class, new SearchResponseSerializer(), new SearchResponseDeserializer()),
     72 + ENUMERATION_CHALLENGE_LOGIN_REQUEST(5, LoginRequest.class, new LoginRequestSerializer(), new LoginRequestDeserializer()),
     73 + ENUMERATION_CHALLENGE_LOGIN_RESPONSE(6, LoginResponse.class, new LoginResponseSerializer(), new LoginResponseDeserializer()),
     74 + COMMAND_EXECUTION_PING_REQUEST(7, PingRequest.class, new PingRequestSerializer(), new PingRequestDeserializer()),
     75 + COMMAND_EXECUTION_PING_RESPONSE(8, PingResponse.class, new PingResponseSerializer(), new PingResponseDeserializer()),
     76 + XML_STORAGE_MESSAGE(9, StorageMessage.class, new StorageMessageSerializer(), new StorageMessageDeserializer()),
     77 + VERTICAL_ACCESS_CONTROL_USER_INFO_REQUEST(10, UserInfoRequest.class, new UserInfoRequestSerializer(), new UserInfoRequestDeserializer()),
     78 + VERTICAL_ACCESS_CONTROL_USER_INFO_RESPONSE(11, UserInfoResponse.class, new UserInfoResponseSerializer(), new UserInfoResponseDeserializer()),
     79 + VERTICAL_ACCESS_CONTROL_SECRET_REQUEST(12, SecretRequest.class, new SecretRequestSerializer(), new SecretRequestDeserializer()),
     80 + VERTICAL_ACCESS_CONTROL_SECRET_RESPONSE(13, SecretResponse.class, new SecretResponseSerializer(), new SecretResponseDeserializer()),
     81 + HORIZONTAL_ACCESS_CONTROL_DOCUMENT_CONTENT_REQUEST(14, DocumentContentRequest.class, new DocumentContentRequestSerializer(), new DocumentContentRequestDeserializer()),
     82 + HORIZONTAL_ACCESS_CONTROL_DOCUMENT_CONTENT_RESPONSE(15, DocumentContentResponse.class, new DocumentContentResponseSerializer(), new DocumentContentResponseDeserializer()),
     83 + ;
     84 + 
     85 + /**
     86 + * Serialized value of message type (unique).
     87 + */
     88 + private final int value;
     89 + 
     90 + /**
     91 + * Class representing the message.
     92 + */
     93 + private final Class<? extends Message> clazz;
     94 + 
     95 + /**
     96 + * Serializer for serializing given message type.
     97 + */
     98 + private final MessageSerializer serializer;
     99 + 
     100 + /**
     101 + * Deserializer for deserializing given message type.
     102 + */
     103 + private final MessageDeserializer deserializer;
     104 + 
     105 + /**
     106 + * Converts serialized message type to enum message type.
     107 + * @return Message type or empty optional if message for given type was not found
     108 + */
     109 + public static Optional<MessageType> of(int value) {
     110 + return Arrays.stream(values())
     111 + .filter(type -> type.getValue() == value)
     112 + .findAny();
     113 + }
     114 + 
     115 +}
     116 + 
Please wait...
Page is in error, reload to recover