├── LICENSE ├── README.md ├── cve ├── README.md ├── cve-2019-5736.sh ├── cve-2021-3156.sh ├── cve-2021-3560.sh ├── cve-2021-4034.sh ├── cve-2022-0847.sh ├── cve-2022-25636.sh ├── cve-2023-22809.sh └── skel.sh ├── doc └── setuid_binaries_from_distros.txt ├── lse.sh ├── screenshots ├── lse.gif ├── lse.webm ├── lse_level0.png ├── lse_level1.png └── lse_level2.png └── tools └── package_cvs_into_lse.sh /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | First, a couple of useful oneliners ;) 4 | 5 | ```console 6 | wget "https://github.com/diego-treitos/linux-smart-enumeration/releases/latest/download/lse.sh" -O lse.sh;chmod 700 lse.sh 7 | ``` 8 | 9 | ```console 10 | curl "https://github.com/diego-treitos/linux-smart-enumeration/releases/latest/download/lse.sh" -Lo lse.sh;chmod 700 lse.sh 11 | ``` 12 | 13 | Note that since version `2.10` you can *serve the script* to other hosts with the `-S` flag! 14 | 15 | # linux-smart-enumeration 16 | Linux enumeration tools for pentesting and CTFs 17 | 18 | This project was inspired by https://github.com/rebootuser/LinEnum and uses 19 | many of its tests. 20 | 21 | Unlike LinEnum, `lse` tries to gradualy expose the information depending on its importance from a privesc point of view. 22 | 23 | ## What is it? 24 | 25 | This shell script will show relevant information about the security of the local Linux system, helping to escalate privileges. 26 | 27 | From version **2.0** it is *mostly* **POSIX** compliant and tested with `shellcheck` and `posh`. 28 | 29 | It can also **monitor processes to discover recurrent program executions**. It monitors while it is executing all the other tests so you save some time. By default it monitors during 1 minute but you can choose the watch time with the `-p` parameter. 30 | 31 | It has 3 levels of verbosity so you can control how much information you see. 32 | 33 | In the default level you should see the highly important security flaws in the system. The level `1` (`./lse.sh -l1`) shows 34 | interesting information that should help you to privesc. The level `2` (`./lse.sh -l2`) will just dump all the information it 35 | gathers about the system. 36 | 37 | By default it will ask you some questions: mainly the current user password (if you know it ;) so it can do some additional tests. 38 | 39 | ## How to use it? 40 | 41 | The idea is to get the information gradually. 42 | 43 | First you should execute it just like `./lse.sh`. If you see some green `yes!`, you probably have already some good stuff to work with. 44 | 45 | If not, you should try the `level 1` verbosity with `./lse.sh -l1` and you will see some more information that can be interesting. 46 | 47 | If that does not help, `level 2` will just dump everything you can gather about the service using `./lse.sh -l2`. In this case you might find useful to use `./lse.sh -l2 | less -r`. 48 | 49 | You can also select what tests to execute by passing the `-s` parameter. With it you can select specific tests or sections to be executed. For example `./lse.sh -l2 -s usr010,net,pro` will execute the test `usr010` and all the tests in the sections `net` and `pro`. 50 | 51 | 52 | ```console 53 | Use: ./lse.sh [options] 54 | 55 | OPTIONS 56 | -c Disable color 57 | -i Non interactive mode 58 | -h This help 59 | -l LEVEL Output verbosity level 60 | 0: Show highly important results. (default) 61 | 1: Show interesting results. 62 | 2: Show all gathered information. 63 | -s SELECTION Comma separated list of sections or tests to run. Available 64 | sections: 65 | usr: User related tests. 66 | sud: Sudo related tests. 67 | fst: File system related tests. 68 | sys: System related tests. 69 | sec: Security measures related tests. 70 | ret: Recurren tasks (cron, timers) related tests. 71 | net: Network related tests. 72 | srv: Services related tests. 73 | pro: Processes related tests. 74 | sof: Software related tests. 75 | ctn: Container (docker, lxc) related tests. 76 | cve: CVE related tests. 77 | Specific tests can be used with their IDs (i.e.: usr020,sud) 78 | -e PATHS Comma separated list of paths to exclude. This allows you 79 | to do faster scans at the cost of completeness 80 | -p SECONDS Time that the process monitor will spend watching for 81 | processes. A value of 0 will disable any watch (default: 60) 82 | -S Serve the lse.sh script in this host so it can be retrieved 83 | from a remote host. 84 | ``` 85 | ## Is it pretty? 86 | 87 | ### Usage demo 88 | 89 | Also available in [webm video](https://raw.githubusercontent.com/diego-treitos/linux-smart-enumeration/master/screenshots/lse.webm) 90 | 91 | ![LSE Demo](https://github.com/diego-treitos/linux-smart-enumeration/raw/master/screenshots/lse.gif) 92 | 93 | ### Level 0 (default) output sample 94 | 95 | ![LSE level0](https://raw.githubusercontent.com/diego-treitos/linux-smart-enumeration/master/screenshots/lse_level0.png) 96 | 97 | ### Level 1 verbosity output sample 98 | 99 | ![LSE level1](https://raw.githubusercontent.com/diego-treitos/linux-smart-enumeration/master/screenshots/lse_level1.png) 100 | 101 | ### Level 2 verbosity output sample 102 | 103 | ![LSE level2](https://raw.githubusercontent.com/diego-treitos/linux-smart-enumeration/master/screenshots/lse_level2.png) 104 | 105 | ## Examples 106 | 107 | Direct execution oneliners 108 | 109 | ```console 110 | bash <(wget -q -O - "https://github.com/diego-treitos/linux-smart-enumeration/releases/latest/download/lse.sh") -l2 -i 111 | ``` 112 | 113 | ```console 114 | bash <(curl -s "https://github.com/diego-treitos/linux-smart-enumeration/releases/latest/download/lse.sh") -l1 -i 115 | ``` 116 | 117 | 118 | ## Buy me a beer 119 | Feel free to buy me a beer if this script was useful `:)` 120 | 121 | **₿**: `1DNBZRAzP6WVnTeBPoYvnDtjxnS1S8Gnxk` 122 | -------------------------------------------------------------------------------- /cve/README.md: -------------------------------------------------------------------------------- 1 | # linux-smart-enumeration CVE checks 2 | 3 | LSE can test the host for certain CVEs that might allow privilege escalation. 4 | 5 | Each CVE is tested by a specific script, stored in this folder. 6 | To enable CVE checking for LSE, these scripts need to be bundled with `lse.sh`. 7 | This is accomplished by the tool `tools/package_cvs_into_lse.sh`, which creates `lse_cve.sh`. 8 | For LSE on the GitHub Releases page, this has already been done. 9 | 10 | 11 | ## Adding and improving CVE checks 12 | 13 | To add a new CVE check, just create a copy of the `skel.sh` script in this folder and fill out the metadata. 14 | Then implement the `lse_cve_test()` function for the specific CVE (get inspiration from existing scripts). 15 | Usually this involves checking and comparing the version of the affected software. 16 | If it looks vulnerable, output something to stdout, otherwise do not. 17 | 18 | LSE aims to minimize false positives but for CVE tests, this might require checking backported patches for certain Linux distributions. 19 | This is where improvements are always possible. 20 | If you encounter a false positive, just add the fixed package version for the affected distribution to the script and submit a pull request. 21 | 22 | The general workflow for a `lse_cve_test()` function is: 23 | - get the version of the affected software 24 | - if the version is too old or too new to be affected, output nothing and exit 25 | - for some important distributions, list the package version shipping the backported fix 26 | - if installed package version is recent enough, output nothing and exit 27 | - otherwise, it looks vulnerable: output something like "Vulnerable!" and the software version 28 | 29 | LSE supports this process with a few helper functions and variables, most notably: 30 | - `lse_is_version_bigger` is true if the first argument is larger than the second according to version sort 31 | - `lse_get_pkg_version` obtains the version of an installed software package 32 | - `$lse_distro_codename` contains the distribution name like `ubuntu`, `debian`, `redhat`, ... 33 | 34 | 35 | ### Sources for researching affected versions 36 | 37 | Checking package versions with backported fixes is somewhat optional and nearly impossible to be complete for all existing distributions. 38 | However, it is crucial to eliminate false positives. 39 | The following sources help to determine in which version a distribution patched something. 40 | 41 | - Debian: [Security Bug Tracker](https://security-tracker.debian.org/tracker/) allows to search for CVEs and patched versions 42 | - Ubuntu: [Ubuntu Security CVEs](https://ubuntu.com/security/cves) lists CVEs affecting Ubuntu and patched versions 43 | - Fedora: [Koji buildserver](https://koji.fedoraproject.org/koji/) contains a changelog for each package build 44 | - Red Hat Enterprise Linux: [Red Hat CVE Database](https://access.redhat.com/security/security-updates/#/cve) allows to search for CVEs and patched versions 45 | - Amazon Linux: [Amazon Linux Security Center](https://alas.aws.amazon.com/) lists patched versions in their advisories 46 | -------------------------------------------------------------------------------- /cve/cve-2019-5736.sh: -------------------------------------------------------------------------------- 1 | #!/bin/posh 2 | # shellcheck disable=1003,1091,2006,2016,2034,2039 3 | # vim: set ts=2 sw=2 sts=2 fdm=marker fmr=#(,#) et: 4 | # 5 | # doc: 6 | # 7 | # Copy this file to a new one with the same name of the cve to test, all in 8 | # lowercase (i.e.: cve-2014–6271.sh). 9 | # Then add the code for the functions shown here. **ALL** functions must appear 10 | # in the new created file, however the ones marked as 'optional' can be left 11 | # with the same code than in 'skel.sh'. Inside the function, declare all the 12 | # variables as 'local' (i.e.: local vuln_version="1.2.3") 13 | # 14 | # NOTE: You can use here, functions and variables implemented in 'lse.sh': 15 | # * lse_get_pkg_version: Get package version supplying package name 16 | # * lse_is_version_bigger: Check if version in $1 is bigger than the $2 17 | # * $lse_arch: System architecture 18 | # * $lse_distro_codename: The linux distribution code name (ubuntu, debian, 19 | # opsuse, centos, redhat, fedora) 20 | # * $lse_linux: Kernel version 21 | # * Colors 22 | # XXX: Check the definitions in 'lse.sh' to better understand what they do and 23 | # how they work 24 | # 25 | ################################################################################ 26 | ## RULES: 27 | ## * Do NOT cause any harm with the tests 28 | ## * Try to be as accurate as possible, trying to detect patched versions from 29 | ## distro package versions. Try to minimize false positives. 30 | ## * The script must be POSIX compliant. Test it with 'posh' shell. 31 | ################################################################################ 32 | 33 | 34 | # lse_cve_level: 0 if leads to a privilege escalation; 1 for other CVEs 35 | lse_cve_level=0 36 | 37 | # lse_cve_id: CVE id in lowercase (i.e.: cve-2014–6271) 38 | lse_cve_id="cve-2019-5736" 39 | 40 | # lse_cve_description: Short. Not more than 52 characters long. 41 | #__________________="vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv" 42 | lse_cve_description="Escalate in some types of docker containers" 43 | 44 | # Code retrieved with 'declare -f' by the packaging bash script 45 | lse_cve_test() { #( 46 | local vulnerable=false 47 | local runc_version 48 | local package_version 49 | 50 | runc_version=$(runc --version | grep -i "runc version" | cut -d" " -f3) 51 | package_version=$(lse_get_pkg_version runc) 52 | 53 | if [ -n "$runc_version" ] && lse_is_version_bigger "0.1.1" "$runc_version"; then 54 | vulnerable=true 55 | 56 | case "$lse_distro_codename" in 57 | ubuntu|debian) 58 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_CODENAME=' /etc/os-release | cut -f2 -d=) 59 | case "$distro_release" in 60 | bionic) 61 | package_fixed="1.0.0~rc4+dfsg1-6ubuntu0.18.04.1" 62 | ;; 63 | cosmic) 64 | package_fixed="1.0.0~rc4+dfsg1-6ubuntu0.18.10.1" 65 | ;; 66 | xenial) 67 | package_fixed="1.0.0~rc2+docker1.13.1-0ubuntu1~16.04.1" 68 | ;; 69 | stretch) 70 | package_fixed="0.1.1+dfsg1-2+deb9u1" 71 | ;; 72 | *) # Other releases not vulnerable 73 | package_fixed="0" 74 | ;; 75 | esac 76 | ;; 77 | centos) 78 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_ID=' /etc/os-release | cut -f2 -d=) 79 | case "$distro_release" in 80 | 7*) 81 | package_fixed="1.0.0-60.dev.git2abd837.el7" 82 | ;; 83 | esac 84 | ;; 85 | opsuse) 86 | package_version=$(lse_get_pkg_version docker-runc) 87 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_ID=' /etc/os-release | cut -f2 -d=) 88 | case "$distro_release" in 89 | 15*) 90 | package_fixed="1.0.0rc8+gitr3826_425e105d5a03" 91 | ;; 92 | esac 93 | ;; 94 | esac 95 | if [ -n "$package_fixed" ] && [ -n "$package_version" ] && ! lse_is_version_bigger "$package_fixed" "$package_version"; then 96 | # Not Vulnerable 97 | exit 1 98 | fi 99 | fi 100 | $vulnerable && runc --version 101 | } #) 102 | 103 | # Uncomment this line for testing the lse_cve_test function 104 | #lse_NO_EXEC=true . ../lse.sh ; lse_cve_test 105 | -------------------------------------------------------------------------------- /cve/cve-2021-3156.sh: -------------------------------------------------------------------------------- 1 | #!/bin/posh 2 | # shellcheck disable=1003,1091,2006,2016,2034,2039 3 | # vim: set ts=2 sw=2 sts=2 fdm=marker fmr=#(,#) et: 4 | # 5 | # doc: 6 | # 7 | # Copy this file to a new one with the same name of the cve to test, all in 8 | # lowercase (i.e.: cve-2014–6271.sh). 9 | # Then add the code for the functions shown here. **ALL** functions must appear 10 | # in the new created file, however the ones marked as 'optional' can be left 11 | # with the same code than in 'skel.sh'. Inside the function, declare all the 12 | # variables as 'local' (i.e.: local vuln_version="1.2.3") 13 | # 14 | # NOTE: You can use here, functions and variables implemented in 'lse.sh': 15 | # * lse_get_pkg_version: Get package version supplying package name 16 | # * lse_is_version_bigger: Check if version in $1 is bigger than the $2 17 | # * $lse_arch: System architecture 18 | # * $lse_distro_codename: The linux distribution code name (ubuntu, debian, 19 | # opsuse, centos, redhat, fedora) 20 | # * $lse_linux: Kernel version 21 | # * Colors 22 | # XXX: Check the definitions in 'lse.sh' to better understand what they do and 23 | # how they work 24 | # 25 | ################################################################################ 26 | ## RULES: 27 | ## * Do NOT cause any harm with the tests 28 | ## * Try to be as accurate as possible, trying to detect patched versions from 29 | ## distro package versions. Try to minimize false positives. 30 | ## * The script must be POSIX compliant. Test it with 'posh' shell. 31 | ################################################################################ 32 | 33 | 34 | # lse_cve_level: 0 if leads to a privilege escalation; 1 for other CVEs 35 | lse_cve_level=0 36 | 37 | # lse_cve_id: CVE id in lowercase (i.e.: cve-2014–6271) 38 | lse_cve_id="cve-2021-3156" 39 | 40 | # lse_cve_description: Short. Not more than 52 characters long. 41 | #__________________="vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv" 42 | lse_cve_description="Sudo Baron Samedit vulnerability" 43 | 44 | # Code retrieved with 'declare -f' by the packaging bash script 45 | lse_cve_test() { #( 46 | local vulnerable=false 47 | local sudo 48 | local sudo_version 49 | local v2 50 | local package_version 51 | local package_fixed 52 | local distro_release 53 | sudo="$(command -v sudo)" 54 | if [ -n "$sudo" ]; then 55 | vulnerable=true 56 | sudo_version="$(sudo --version | head -n1 | cut -d ' ' -f 3)" 57 | v2="$(echo "$sudo_version" | cut -d. -f2)" 58 | package_version="$(lse_get_pkg_version sudo)" 59 | # only 1.8.2 to 1.8.31p2 is vulnerable 60 | if lse_is_version_bigger 1.8.2 "$sudo_version"; then 61 | exit 1 62 | fi 63 | if [ "$v2" = 8 ] && lse_is_version_bigger "$sudo_version" 1.8.31p2; then 64 | exit 1 65 | fi 66 | # only 1.9.0 to 1.9.5p1 is vulnerable 67 | if lse_is_version_bigger "$sudo_version" 1.9.5p1; then 68 | exit 1 69 | fi 70 | case "$lse_distro_codename" in 71 | debian|ubuntu) 72 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_CODENAME=' /etc/os-release | cut -f2 -d=) 73 | case "$distro_release" in 74 | stretch) 75 | package_fixed="1.8.19p1-2.1+deb9u3" 76 | ;; 77 | buster) 78 | package_fixed="1.8.27-1+deb10u3" 79 | ;; 80 | precise) 81 | package_fixed="1.8.3p1-1ubuntu3.10" 82 | ;; 83 | trusty) 84 | package_fixed="1.8.9p5-1ubuntu1.5+esm6" 85 | ;; 86 | xenial) 87 | package_fixed="1.8.16-0ubuntu1.10" 88 | ;; 89 | bionic) 90 | package_fixed="1.8.21p2-3ubuntu1.4" 91 | ;; 92 | focal) 93 | package_fixed="1.8.31-1ubuntu1.2" 94 | ;; 95 | groovy) 96 | package_fixed="1.9.1-1ubuntu1.1" 97 | ;; 98 | esac 99 | ;; 100 | redhat) 101 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_ID=' /etc/os-release | cut -f2 -d=) 102 | case "$distro_release" in 103 | 6.*) 104 | package_fixed="1.8.6p3-29.el6_10.4" 105 | ;; 106 | 7.2) 107 | package_fixed="1.8.6p7-17.el7_2.3" 108 | ;; 109 | 7.3) 110 | package_fixed="1.8.6p7-23.el7_3.3" 111 | ;; 112 | 7.4) 113 | package_fixed="1.8.19p2-12.el7_4.2" 114 | ;; 115 | 7.6) 116 | package_fixed="1.8.23-3.el7_6.2" 117 | ;; 118 | 7.7) 119 | package_fixed="1.8.23-4.el7_7.3" 120 | ;; 121 | 7.*) 122 | package_fixed="1.8.23-10.el7_9.1" 123 | ;; 124 | 8.1) 125 | package_fixed="1.8.25p1-8.el8_1.2" 126 | ;; 127 | 8.2) 128 | package_fixed="1.8.29-5.el8_2.1" 129 | ;; 130 | 8.*) 131 | package_fixed="1.8.29-6.el8_3.1" 132 | ;; 133 | *) 134 | lse_is_version_bigger "$distro_release" 8 && exit 1 135 | ;; 136 | esac 137 | ;; 138 | amzn) 139 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_ID=' /etc/os-release | cut -f2 -d= | tr -d '"') 140 | case "$distro_release" in 141 | 1) 142 | package_fixed="1.8.23-9.56.amzn1" 143 | ;; 144 | 2) 145 | package_fixed="1.8.23-4.amzn2.2.1" 146 | ;; 147 | esac 148 | ;; 149 | esac 150 | if [ -n "$package_fixed" ] && [ -n "$package_version" ] && ! lse_is_version_bigger "$package_fixed" "$package_version"; then 151 | exit 1 152 | fi 153 | fi 154 | $vulnerable && echo "Vulnerable! sudo version: ${package_version:-$sudo_version}" 155 | } #) 156 | 157 | # Uncomment this line for testing the lse_cve_test function 158 | #lse_NO_EXEC=true . ../lse.sh ; lse_cve_test 159 | -------------------------------------------------------------------------------- /cve/cve-2021-3560.sh: -------------------------------------------------------------------------------- 1 | #!/bin/posh 2 | # shellcheck disable=1003,1091,2006,2016,2034,2039 3 | # vim: set ts=2 sw=2 sts=2 fdm=marker fmr=#(,#) et: 4 | # 5 | # doc: 6 | # 7 | # Copy this file to a new one with the same name of the cve to test, all in 8 | # lowercase (i.e.: cve-2014–6271.sh). 9 | # Then add the code for the functions shown here. **ALL** functions must appear 10 | # in the new created file, however the ones marked as 'optional' can be left 11 | # with the same code than in 'skel.sh'. Inside the function, declare all the 12 | # variables as 'local' (i.e.: local vuln_version="1.2.3") 13 | # 14 | # NOTE: You can use here, functions and variables implemented in 'lse.sh': 15 | # * lse_get_pkg_version: Get package version supplying package name 16 | # * lse_is_version_bigger: Check if version in $1 is bigger than the $2 17 | # * $lse_arch: System architecture 18 | # * $lse_distro_codename: The linux distribution code name (ubuntu, debian, 19 | # opsuse, centos, redhat, fedora) 20 | # * $lse_linux: Kernel version 21 | # * Colors 22 | # XXX: Check the definitions in 'lse.sh' to better understand what they do and 23 | # how they work 24 | # 25 | ################################################################################ 26 | ## RULES: 27 | ## * Do NOT cause any harm with the tests 28 | ## * Try to be as accurate as possible, trying to detect patched versions from 29 | ## distro package versions. Try to minimize false positives. 30 | ## * The script must be POSIX compliant. Test it with 'posh' shell. 31 | ################################################################################ 32 | 33 | 34 | # lse_cve_level: 0 if leads to a privilege escalation; 1 for other CVEs 35 | lse_cve_level=0 36 | 37 | # lse_cve_id: CVE id in lowercase (i.e.: cve-2014–6271) 38 | lse_cve_id="cve-2021-3560" 39 | 40 | # lse_cve_description: Short. Not more than 52 characters long. 41 | #__________________="vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv" 42 | lse_cve_description="Checking for policykit vulnerability" 43 | 44 | # Code retrieved with 'declare -f' by the packaging bash script 45 | lse_cve_test() { #( 46 | local vulnerable=false 47 | local pkexec 48 | local pkexec_version 49 | local distro_release 50 | local package_version 51 | local package_fixed 52 | pkexec=$(command -v pkexec) 53 | package_version=$(lse_get_pkg_version polkit) 54 | if [ -n "$pkexec" ]; then 55 | vulnerable=true 56 | pkexec_version=$(pkexec --version | grep -Eo '[0-9\.]+') 57 | if lse_is_version_bigger "$pkexec_version" 0.119; then 58 | # Not Vulnerable 59 | exit 1 60 | fi 61 | case "$lse_distro_codename" in 62 | ubuntu|debian) 63 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_CODENAME=' /etc/os-release | cut -f2 -d=) 64 | package_version=$(lse_get_pkg_version policykit-1) 65 | case "$distro_release" in 66 | focal) 67 | package_fixed="0.105-26ubuntu1.1" 68 | ;; 69 | groovy) 70 | package_fixed="0.105-29ubuntu0.1" 71 | ;; 72 | hirsute) 73 | package_fixed="0.105-30ubuntu0.1" 74 | ;; 75 | impish) 76 | package_fixed="0.105-31" 77 | ;; 78 | bullseye) 79 | package_fixed="0.105-31" 80 | ;; 81 | *) # Other releases. This is because debian derivates use a polkit fork from version 0.105. 82 | package_fixed="0" # Never vulnerable 83 | ;; 84 | esac 85 | ;; 86 | redhat) 87 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_ID=' /etc/os-release | cut -f2 -d=) 88 | case "$distro_release" in 89 | 8.1) 90 | package_fixed="0.115-9.el8_1.1" 91 | ;; 92 | 8.2) 93 | package_fixed="0.115-11.el8_2.1" 94 | ;; 95 | 8.*) 96 | package_fixed="0.115-11.el8_4.1" 97 | ;; 98 | *) 99 | lse_is_version_bigger "$distro_release" 8 && exit 1 100 | ;; 101 | esac 102 | ;; 103 | rocky) 104 | if lse_is_version_bigger 0.113 "$pkexec_version"; then 105 | # Not Vulnerable 106 | exit 1 107 | fi 108 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_ID=' /etc/os-release | cut -f2 -d=) 109 | case "$distro_release" in 110 | 8*) 111 | package_fixed="0.115-11" 112 | ;; 113 | esac 114 | ;; 115 | opsuse) 116 | if lse_is_version_bigger 0.113 "$pkexec_version"; then 117 | # Not Vulnerable 118 | exit 1 119 | fi 120 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_ID=' /etc/os-release | cut -f2 -d=) 121 | case "$distro_release" in 122 | 15.2) 123 | package_fixed="0.116-lp152.2.3.1" 124 | ;; 125 | 15.3) 126 | package_fixed="0.116-3.3.1" 127 | ;; 128 | esac 129 | ;; 130 | *) 131 | # The bug was introduced on version 0.113 132 | if lse_is_version_bigger 0.113 "$pkexec_version"; then 133 | # Not Vulnerable 134 | exit 1 135 | fi 136 | ;; 137 | esac 138 | if [ -n "$package_fixed" ] && [ -n "$package_version" ] && ! lse_is_version_bigger "$package_fixed" "$package_version"; then 139 | # Not Vulnerable 140 | exit 1 141 | fi 142 | fi 143 | $vulnerable && echo "Vulnerable! polkit version: ${package_version:-$pkexec_version}" 144 | } #) 145 | 146 | # Uncomment this line for testing the lse_cve_test function 147 | #lse_NO_EXEC=true . ../lse.sh ; lse_cve_test 148 | -------------------------------------------------------------------------------- /cve/cve-2021-4034.sh: -------------------------------------------------------------------------------- 1 | #!/bin/posh 2 | # shellcheck disable=1003,1091,2006,2016,2034,2039 3 | # vim: set ts=2 sw=2 sts=2 fdm=marker fmr=#(,#) et: 4 | # 5 | # doc: 6 | # 7 | # Copy this file to a new one with the same name of the cve to test, all in 8 | # lowercase (i.e.: cve-2014–6271.sh). 9 | # Then add the code for the functions shown here. **ALL** functions must appear 10 | # in the new created file, however the ones marked as 'optional' can be left 11 | # with the same code than in 'skel.sh'. Inside the function, declare all the 12 | # variables as 'local' (i.e.: local vuln_version="1.2.3") 13 | # 14 | # NOTE: You can use here, functions and variables implemented in 'lse.sh': 15 | # * lse_get_pkg_version: Get package version supplying package name 16 | # * lse_is_version_bigger: Check if version in $1 is bigger than the $2 17 | # * $lse_arch: System architecture 18 | # * $lse_distro_codename: The linux distribution code name (ubuntu, debian, 19 | # opsuse, centos, redhat, fedora) 20 | # * $lse_linux: Kernel version 21 | # * Colors 22 | # XXX: Check the definitions in 'lse.sh' to better understand what they do and 23 | # how they work 24 | # 25 | ################################################################################ 26 | ## RULES: 27 | ## * Do NOT cause any harm with the tests 28 | ## * Try to be as accurate as possible, trying to detect patched versions from 29 | ## distro package versions. Try to minimize false positives. 30 | ## * The script must be POSIX compliant. Test it with 'posh' shell. 31 | ################################################################################ 32 | 33 | 34 | # lse_cve_level: 0 if leads to a privilege escalation; 1 for other CVEs 35 | lse_cve_level=0 36 | 37 | # lse_cve_id: CVE id in lowercase (i.e.: cve-2014–6271) 38 | lse_cve_id="cve-2021-4034" 39 | 40 | # lse_cve_description: Short. Not more than 52 characters long. 41 | #__________________="vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv" 42 | lse_cve_description="Checking for PwnKit vulnerability" 43 | 44 | # Code retrieved with 'declare -f' by the packaging bash script 45 | lse_cve_test() { #( 46 | local vulnerable=false 47 | local pkexec 48 | local pkexec_version 49 | local distro_release 50 | local package_version 51 | local package_fixed 52 | pkexec=$(command -v pkexec) 53 | package_version=$(lse_get_pkg_version polkit) 54 | if [ -n "$pkexec" ] && stat -c'%A' "$pkexec" | grep -Eq -- '^-..s.+'; then 55 | vulnerable=true 56 | pkexec_version=$(pkexec --version | grep -Eo '[0-9\.]+') 57 | if lse_is_version_bigger "$pkexec_version" 0.120 ; then 58 | # Not Vulnerable 59 | exit 1 60 | fi 61 | case "$lse_distro_codename" in 62 | ubuntu|debian) 63 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_CODENAME=' /etc/os-release | cut -f2 -d=) 64 | package_version=$(lse_get_pkg_version policykit-1) 65 | case "$distro_release" in 66 | bionic) 67 | package_fixed="0.105-20ubuntu0.18.04.6" 68 | ;; 69 | focal) 70 | package_fixed="0.105-26ubuntu1.2" 71 | ;; 72 | impish) 73 | package_fixed="0.105-31ubuntu0.1" 74 | ;; 75 | trusty) 76 | package_fixed="0.105-4ubuntu3.14.04.6+esm1" 77 | ;; 78 | xenial) 79 | package_fixed="0.105-14.1ubuntu0.5+esm1" 80 | ;; 81 | stretch) 82 | package_fixed="0.105-18+deb9u2" 83 | ;; 84 | buster) 85 | package_fixed="0.105-25+deb10u1" 86 | ;; 87 | bullseye) 88 | package_fixed="0.105-31+deb11u1" 89 | ;; 90 | *) # Future releases (bookworm+ and jammy+). This is because debian derivates use a polkit fork from version 0.105. 91 | package_fixed="0.105-33" 92 | ;; 93 | esac 94 | ;; 95 | redhat) 96 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_ID=' /etc/os-release | cut -f2 -d=) 97 | case "$distro_release" in 98 | 6.*) 99 | package_fixed="0.96-11.el6_10.2" 100 | ;; 101 | 7.3) 102 | package_fixed="0.112-12.el7_3.1" 103 | ;; 104 | 7.4) 105 | package_fixed="0.112-12.el7_4.2" 106 | ;; 107 | 7.6) 108 | package_fixed="0.112-18.el7_6.3" 109 | ;; 110 | 7.7) 111 | package_fixed="0.112-22.el7_7.2" 112 | ;; 113 | 7.*) 114 | package_fixed="0.112-26.el7_9.1" 115 | ;; 116 | 8.1) 117 | package_fixed="0.115-9.el8_1.2" 118 | ;; 119 | 8.2) 120 | package_fixed="0.115-11.el8_2.2" 121 | ;; 122 | 8.4) 123 | package_fixed="0.115-11.el8_4.2" 124 | ;; 125 | 8.*) 126 | package_fixed="0.115-13.el8_5.1" 127 | ;; 128 | *) 129 | lse_is_version_bigger "$distro_release" 8 && exit 1 130 | ;; 131 | esac 132 | ;; 133 | rocky) 134 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_ID=' /etc/os-release | cut -f2 -d=) 135 | case "$distro_release" in 136 | 8.5) 137 | package_fixed="0.115-13.el8_5.1" 138 | ;; 139 | esac 140 | ;; 141 | opsuse) 142 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_ID=' /etc/os-release | cut -f2 -d=) 143 | case "$distro_release" in 144 | 15.3) 145 | package_fixed="0.116-3.6.1" 146 | ;; 147 | esac 148 | ;; 149 | fedora) 150 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_ID=' /etc/os-release | cut -f2 -d=) 151 | case "$distro_release" in 152 | 34) 153 | package_fixed="0.117-3.fc34.2" 154 | ;; 155 | 35) 156 | package_fixed="0.120-1.fc35.1" 157 | ;; 158 | 36) 159 | package_fixed="0.120-3.fc36" 160 | ;; 161 | *) 162 | [ $((distro_release)) -gt 36 ] && exit 1 163 | ;; 164 | esac 165 | ;; 166 | esac 167 | if [ -n "$package_fixed" ] && [ -n "$package_version" ] && ! lse_is_version_bigger "$package_fixed" "$package_version"; then 168 | # Not Vulnerable 169 | exit 1 170 | fi 171 | fi 172 | $vulnerable && echo "Vulnerable! polkit version: ${package_version:-$pkexec_version}" 173 | } #) 174 | 175 | # Uncomment this line for testing the lse_cve_test function 176 | #lse_NO_EXEC=true . ../lse.sh ; lse_cve_test 177 | -------------------------------------------------------------------------------- /cve/cve-2022-0847.sh: -------------------------------------------------------------------------------- 1 | #!/bin/posh 2 | # shellcheck disable=1003,1091,2006,2016,2034,2039 3 | # vim: set ts=2 sw=2 sts=2 fdm=marker fmr=#(,#) et: 4 | # 5 | # doc: 6 | # 7 | # Copy this file to a new one with the same name of the cve to test, all in 8 | # lowercase (i.e.: cve-2014–6271.sh). 9 | # Then add the code for the functions shown here. **ALL** functions must appear 10 | # in the new created file, however the ones marked as 'optional' can be left 11 | # with the same code than in 'skel.sh'. Inside the function, declare all the 12 | # variables as 'local' (i.e.: local vuln_version="1.2.3") 13 | # 14 | # NOTE: You can use here, functions and variables implemented in 'lse.sh': 15 | # * lse_get_pkg_version: Get package version supplying package name 16 | # * lse_is_version_bigger: Check if version in $1 is bigger than the $2 17 | # * $lse_arch: System architecture 18 | # * $lse_distro_codename: The linux distribution code name (ubuntu, debian, 19 | # opsuse, centos, redhat, fedora) 20 | # * $lse_linux: Kernel version 21 | # * Colors 22 | # XXX: Check the definitions in 'lse.sh' to better understand what they do and 23 | # how they work 24 | # 25 | ################################################################################ 26 | ## RULES: 27 | ## * Do NOT cause any harm with the tests 28 | ## * Try to be as accurate as possible, trying to detect patched versions from 29 | ## distro package versions. Try to minimize false positives. 30 | ## * The script must be POSIX compliant. Test it with 'posh' shell. 31 | ################################################################################ 32 | 33 | 34 | # lse_cve_level: 0 if leads to a privilege escalation; 1 for other CVEs 35 | lse_cve_level=0 36 | 37 | # lse_cve_id: CVE id in lowercase (i.e.: cve-2014–6271) 38 | lse_cve_id="cve-2022-0847" 39 | 40 | # lse_cve_description: Short. Not more than 52 characters long. 41 | #__________________="vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv" 42 | lse_cve_description="Dirty Pipe vulnerability" 43 | 44 | lse_cve_test() { #( 45 | local kernel 46 | local kernel_distro 47 | kernel=$(uname -r | cut -d- -f1) 48 | kernel_distro=$(uname -r) 49 | v1=$(echo "$kernel" | cut -d '.' -f1) 50 | v2=$(echo "$kernel" | cut -d '.' -f2) 51 | v3=$(echo "$kernel" | cut -d '.' -f3) 52 | v1=${v1:-0};v2=${v2:-0};v3=${v3:-0}; 53 | 54 | if [ "$v1" != 5 ] || 55 | [ $((v2)) -lt 8 ] || 56 | { [ "$v2" = 10 ] && [ $((v3)) -ge 102 ]; } || 57 | { [ "$v2" = 15 ] && [ $((v3)) -ge 25 ]; } || 58 | { [ "$v2" = 16 ] && [ $((v3)) -ge 11 ]; } || 59 | [ $((v2)) -gt 16 ] 60 | then 61 | # Not vulnerable 62 | exit 1 63 | fi 64 | 65 | case "$lse_distro_codename" in 66 | debian) 67 | # get debian upstream kernel version 68 | kernel=$(uname -v | cut -d' ' -f4 | cut -d- -f1) 69 | lse_is_version_bigger "$kernel" "5.10.92" && exit 1 70 | ;; 71 | ubuntu) 72 | lse_is_version_bigger "$kernel_distro" "5.13.0-35.39" && exit 1 73 | ;; 74 | redhat) 75 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_ID=' /etc/os-release | cut -f2 -d=) 76 | kernel_package=$(lse_get_pkg_version kernel) 77 | case "$distro_release" in 78 | 8.1) 79 | lse_is_version_bigger 4.18.0-147.64.1.el8_1 "$kernel_package" || exit 1 80 | ;; 81 | 8.2) 82 | lse_is_version_bigger 4.18.0-193.79.1.el8_2 "$kernel_package" || exit 1 83 | ;; 84 | 8.4) 85 | lse_is_version_bigger 4.18.0-305.40.2.el8_4 "$kernel_package" || exit 1 86 | ;; 87 | 8.*) 88 | lse_is_version_bigger 4.18.0-348.20.1.el8_5 "$kernel_package" || exit 1 89 | ;; 90 | *) 91 | lse_is_version_bigger "$distro_release" 8 && exit 1 92 | ;; 93 | esac 94 | ;; 95 | esac 96 | 97 | # Vulnerable 98 | echo "Vulnerable! kernel version: $kernel_distro" 99 | } #) 100 | 101 | # Uncomment this line for testing the lse_cve_test function 102 | #lse_NO_EXEC=true . ../lse.sh ; lse_cve_test 103 | -------------------------------------------------------------------------------- /cve/cve-2022-25636.sh: -------------------------------------------------------------------------------- 1 | #!/bin/posh 2 | # shellcheck disable=1003,1091,2006,2016,2034,2039 3 | # vim: set ts=2 sw=2 sts=2 fdm=marker fmr=#(,#) et: 4 | # 5 | # doc: 6 | # 7 | # Copy this file to a new one with the same name of the cve to test, all in 8 | # lowercase (i.e.: cve-2014–6271.sh). 9 | # Then add the code for the functions shown here. **ALL** functions must appear 10 | # in the new created file, however the ones marked as 'optional' can be left 11 | # with the same code than in 'skel.sh'. Inside the function, declare all the 12 | # variables as 'local' (i.e.: local vuln_version="1.2.3") 13 | # 14 | # NOTE: You can use here, functions and variables implemented in 'lse.sh': 15 | # * lse_get_pkg_version: Get package version supplying package name 16 | # * lse_is_version_bigger: Check if version in $1 is bigger than the $2 17 | # * $lse_arch: System architecture 18 | # * $lse_distro_codename: The linux distribution code name (ubuntu, debian, 19 | # opsuse, centos, redhat, fedora) 20 | # * $lse_linux: Kernel version 21 | # * Colors 22 | # XXX: Check the definitions in 'lse.sh' to better understand what they do and 23 | # how they work 24 | # 25 | ################################################################################ 26 | ## RULES: 27 | ## * Do NOT cause any harm with the tests 28 | ## * Try to be as accurate as possible, trying to detect patched versions from 29 | ## distro package versions. Try to minimize false positives. 30 | ## * The script must be POSIX compliant. Test it with 'posh' shell. 31 | ################################################################################ 32 | 33 | 34 | # lse_cve_level: 0 if leads to a privilege escalation; 1 for other CVEs 35 | lse_cve_level=0 36 | 37 | # lse_cve_id: CVE id in lowercase (i.e.: cve-2014–6271) 38 | lse_cve_id="cve-2022-25636" 39 | 40 | # lse_cve_description: Short. Not more than 52 characters long. 41 | #__________________="vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv" 42 | lse_cve_description="Netfilter linux kernel vulnerability" 43 | 44 | lse_cve_test() { #( 45 | local kernel 46 | local kernel_distro 47 | kernel=$(uname -r | cut -d- -f1) 48 | kernel_distro=$(uname -r) 49 | 50 | if lse_is_version_bigger "5.4" "$kernel" || lse_is_version_bigger "$kernel" "5.6.10" 51 | then 52 | # Not vulnerable 53 | exit 1 54 | else 55 | # Possibly vulnerable 56 | local vulnerable=true 57 | fi 58 | 59 | case "$lse_distro_codename" in 60 | debian|ubuntu) 61 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_CODENAME=' /etc/os-release | cut -f2 -d=) 62 | case "$distro_release" in 63 | focal) 64 | package_fixed="5.4.0-104.118" 65 | ;; 66 | impish) 67 | package_fixed="5.13.0-35.40" 68 | ;; 69 | bullseye) 70 | package_fixed="5.10.103-1" 71 | ;; 72 | *) # Other releases not vulnerable 73 | package_fixed="0" 74 | ;; 75 | esac 76 | esac 77 | if [ -n "$package_fixed" ] && ! lse_is_version_bigger "$package_fixed" "$kernel_distro"; then 78 | # Not Vulnerable 79 | exit 1 80 | fi 81 | 82 | if $vulnerable; then 83 | echo "$kernel_distro" 84 | fi 85 | } #) 86 | 87 | # Uncomment this line for testing the lse_cve_test function 88 | #lse_NO_EXEC=true . ../lse.sh ; lse_cve_test 89 | -------------------------------------------------------------------------------- /cve/cve-2023-22809.sh: -------------------------------------------------------------------------------- 1 | #!/bin/posh 2 | # shellcheck disable=1003,1091,2006,2016,2034,2039 3 | # vim: set ts=2 sw=2 sts=2 fdm=marker fmr=#(,#) et: 4 | # 5 | # doc: 6 | # 7 | # Copy this file to a new one with the same name of the cve to test, all in 8 | # lowercase (i.e.: cve-2014–6271.sh). 9 | # Then add the code for the functions shown here. **ALL** functions must appear 10 | # in the new created file, however the ones marked as 'optional' can be left 11 | # with the same code than in 'skel.sh'. Inside the function, declare all the 12 | # variables as 'local' (i.e.: local vuln_version="1.2.3") 13 | # 14 | # NOTE: You can use here, functions and variables implemented in 'lse.sh': 15 | # * lse_get_pkg_version: Get package version supplying package name 16 | # * lse_is_version_bigger: Check if version in $1 is bigger than the $2 17 | # * $lse_arch: System architecture 18 | # * $lse_distro_codename: The linux distribution code name (ubuntu, debian, 19 | # opsuse, centos, redhat, fedora) 20 | # * $lse_linux: Kernel version 21 | # * Colors 22 | # XXX: Check the definitions in 'lse.sh' to better understand what they do and 23 | # how they work 24 | # 25 | ################################################################################ 26 | ## RULES: 27 | ## * Do NOT cause any harm with the tests 28 | ## * Try to be as accurate as possible, trying to detect patched versions from 29 | ## distro package versions. Try to minimize false positives. 30 | ## * The script must be POSIX compliant. Test it with 'posh' shell. 31 | ################################################################################ 32 | 33 | 34 | # lse_cve_level: 0 if leads to a privilege escalation; 1 for other CVEs 35 | lse_cve_level=0 36 | 37 | # lse_cve_id: CVE id in lowercase (i.e.: cve-2014–6271) 38 | lse_cve_id="cve-2023-22809" 39 | 40 | # lse_cve_description: Short. Not more than 52 characters long. 41 | #__________________="vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv" 42 | lse_cve_description="Sudoedit bypass in Sudo <= 1.9.12p1" 43 | 44 | # Code retrieved with 'declare -f' by the packaging bash script 45 | lse_cve_test() { #( 46 | local vulnerable=false 47 | local sudo_version 48 | local package_version 49 | local package_fixed 50 | local distro_release 51 | if [ -n "$(command -v sudo)" ]; then 52 | vulnerable=true 53 | sudo_version="$(sudo --version | head -n1 | cut -d ' ' -f 3)" 54 | package_version="$(lse_get_pkg_version sudo)" 55 | # Versions 1.8.0 through 1.9.12p1 are affected. 56 | if lse_is_version_bigger 1.8.0 "$sudo_version"; then 57 | exit 1 58 | fi 59 | if lse_is_version_bigger "$sudo_version" 1.9.12p1; then 60 | exit 1 61 | fi 62 | case "$lse_distro_codename" in 63 | debian|ubuntu) 64 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_CODENAME=' /etc/os-release | cut -f2 -d=) 65 | case "$distro_release" in 66 | buster) 67 | package_fixed="1.8.27-1+deb10u5" 68 | ;; 69 | bullseye) 70 | package_fixed="1.9.5p2-3+deb11u1" 71 | ;; 72 | trusty) 73 | package_fixed="1.8.9p5-1ubuntu1.5+esm7" 74 | ;; 75 | xenial) 76 | package_fixed="1.8.16-0ubuntu1.10+esm1" 77 | ;; 78 | bionic) 79 | package_fixed="1.8.21p2-3ubuntu1.5" 80 | ;; 81 | focal) 82 | package_fixed="1.8.31-1ubuntu1.4" 83 | ;; 84 | jammy) 85 | package_fixed="1.9.9-1ubuntu2.2" 86 | ;; 87 | kinetic) 88 | package_fixed="1.9.11p3-1ubuntu1.1" 89 | ;; 90 | esac 91 | ;; 92 | redhat) 93 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_ID=' /etc/os-release | cut -f2 -d=) 94 | case "$distro_release" in 95 | 6.*) 96 | package_fixed="1.8.6p3-29.el6_10.7" 97 | ;; 98 | 7.*) 99 | package_fixed="1.8.23-10.el7_9.3" 100 | ;; 101 | 8.1) 102 | package_fixed="1.8.25p1-8.el8_1.3" 103 | ;; 104 | 8.2) 105 | package_fixed="1.8.29-5.el8_2.2" 106 | ;; 107 | 8.4) 108 | package_fixed="1.8.29-7.el8_4.2" 109 | ;; 110 | 8.6) 111 | package_fixed="1.8.29-8.el8_6.1" 112 | ;; 113 | 8.*) 114 | package_fixed="1.8.29-8.el8_7.1" 115 | ;; 116 | 9.0) 117 | package_fixed="1.9.5p2-7.el9_0.2" 118 | ;; 119 | 9.*) 120 | package_fixed="1.9.5p2-7.el9_1.1" 121 | ;; 122 | *) 123 | lse_is_version_bigger "$distro_release" 9 && exit 1 124 | ;; 125 | esac 126 | ;; 127 | amzn) 128 | [ -r "/etc/os-release" ] && distro_release=$(grep -E '^VERSION_ID=' /etc/os-release | cut -f2 -d= | tr -d '"') 129 | case "$distro_release" in 130 | 1) 131 | package_fixed="1.8.23-10.57.amzn1" 132 | ;; 133 | 2) 134 | package_fixed="1.8.23-10.amzn2.3.1" 135 | ;; 136 | 2023) 137 | package_fixed="1.9.12-1.p2.amzn2023.0.2" 138 | ;; 139 | esac 140 | ;; 141 | esac 142 | if [ -n "$package_fixed" ] && [ -n "$package_version" ] && ! lse_is_version_bigger "$package_fixed" "$package_version"; then 143 | exit 1 144 | fi 145 | fi 146 | $vulnerable && echo "Vulnerable! sudo version: ${package_version:-$sudo_version}" 147 | } #) 148 | 149 | # Uncomment this line for testing the lse_cve_test function 150 | #lse_NO_EXEC=true . ../lse.sh ; lse_cve_test 151 | -------------------------------------------------------------------------------- /cve/skel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/posh 2 | # shellcheck disable=1003,1091,2006,2016,2034,2039 3 | # vim: set ts=2 sw=2 sts=2 fdm=marker fmr=#(,#) et: 4 | # 5 | # doc: 6 | # 7 | # Copy this file to a new one with the same name of the cve to test, all in 8 | # lowercase (i.e.: cve-2014–6271.sh). 9 | # Then add the code for the functions shown here. **ALL** functions must appear 10 | # in the new created file, however the ones marked as 'optional' can be left 11 | # with the same code than in 'skel.sh'. Inside the function, declare all the 12 | # variables as 'local' (i.e.: local vuln_version="1.2.3") 13 | # 14 | # NOTE: You can use here, functions and variables implemented in 'lse.sh': 15 | # * lse_get_pkg_version: Get package version supplying package name 16 | # * lse_is_version_bigger: Check if version in $1 is bigger than the $2 17 | # * $lse_arch: System architecture 18 | # * $lse_distro_codename: The linux distribution code name (ubuntu, debian, 19 | # opsuse, centos, redhat, fedora) 20 | # * $lse_linux: Kernel version 21 | # * Colors 22 | # XXX: Check the definitions in 'lse.sh' to better understand what they do and 23 | # how they work 24 | # 25 | ################################################################################ 26 | ## RULES: 27 | ## * Do NOT cause any harm with the tests 28 | ## * Try to be as accurate as possible, trying to detect patched versions from 29 | ## distro package versions. Try to minimize false positives. 30 | ## * The script must be POSIX compliant. Test it with 'posh' shell. 31 | ################################################################################ 32 | 33 | 34 | # lse_cve_level: 0 if leads to a privilege escalation; 1 for other CVEs 35 | lse_cve_level=0 36 | 37 | # lse_cve_id: CVE id in lowercase (i.e.: cve-2014–6271) 38 | lse_cve_id="cve-2014–6271" 39 | 40 | # lse_cve_description: Short. Not more than 52 characters long. 41 | #__________________="vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv" 42 | lse_cve_description="This is a short description about the vulnerability." 43 | 44 | # Code retrieved with 'declare -f' by the packaging bash script 45 | lse_cve_test() { #( 46 | # Checks if the software is installed and the version matches a vulnerable one 47 | # If it is vulnerable it must show something via stdout. 48 | # NOTE: Take care that this function does not output anything to stdout or 49 | # stderr other than information that you want to be visible ONLY WHEN IT 50 | # IS VULNERABLE. If it is not vulnerable there should NOT BE ANY OUTPUT. 51 | echo "Vulnerable!" 52 | } #) 53 | 54 | # Uncomment this line for testing the lse_cve_test function 55 | #lse_NO_EXEC=true . ../lse.sh ; lse_cve_test 56 | -------------------------------------------------------------------------------- /doc/setuid_binaries_from_distros.txt: -------------------------------------------------------------------------------- 1 | 2 | SUID 3 | ==== 4 | 5 | Ubuntu 14.04 LTS 6 | ----------------- 7 | 8 | ub1404:/bin/fusermount 9 | ub1404:/bin/mount 10 | ub1404:/bin/ping 11 | ub1404:/bin/ping6 12 | ub1404:/bin/su 13 | ub1404:/bin/umount 14 | ub1404:/usr/bin/at 15 | ub1404:/usr/bin/chfn 16 | ub1404:/usr/bin/chsh 17 | ub1404:/usr/bin/gpasswd 18 | ub1404:/usr/bin/newgrp 19 | ub1404:/usr/bin/passwd 20 | ub1404:/usr/bin/sudo 21 | ub1404:/usr/bin/sudoedit 22 | ub1404:/usr/bin/traceroute6.iputils 23 | ub1404:/usr/lib/dbus-1.0/dbus-daemon-launch-helper 24 | ub1404:/usr/lib/eject/dmcrypt-get-device 25 | ub1404:/usr/lib/openssh/ssh-keysign 26 | ub1404:/usr/lib/pt_chown 27 | ub1404:/usr/sbin/uuidd 28 | 29 | 30 | Ubuntu 18.04 LTS 31 | ---------------- 32 | 33 | ub1804:/bin/su 34 | ub1804:/bin/umount 35 | ub1804:/bin/fusermount 36 | ub1804:/bin/ntfs-3g 37 | ub1804:/bin/ping 38 | ub1804:/bin/mount 39 | ub1804:/usr/bin/newgrp 40 | ub1804:/usr/bin/passwd 41 | ub1804:/usr/bin/kismet_capture 42 | ub1804:/usr/bin/gpasswd 43 | ub1804:/usr/bin/arping 44 | ub1804:/usr/bin/sudo 45 | ub1804:/usr/bin/chfn 46 | ub1804:/usr/bin/beep 47 | ub1804:/usr/bin/traceroute6.iputils 48 | ub1804:/usr/bin/pkexec 49 | ub1804:/usr/bin/chsh 50 | ub1804:/usr/lib/policykit-1/polkit-agent-helper-1 51 | ub1804:/usr/lib/snapd/snap-confine 52 | ub1804:/usr/lib/dbus-1.0/dbus-daemon-launch-helper 53 | ub1804:/usr/lib/openssh/ssh-keysign 54 | ub1804:/usr/lib/spice-gtk/spice-client-glib-usb-acl-helper 55 | ub1804:/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic 56 | ub1804:/usr/lib/eject/dmcrypt-get-device 57 | ub1804:/usr/lib/chromium-browser/chrome-sandbox 58 | ub1804:/usr/sbin/pppd 59 | ub1804:/sbin/mount.ecryptfs_private 60 | 61 | 62 | Ubuntu 18.10 63 | ------------ 64 | 65 | ub1810:/bin/fusermount 66 | ub1810:/bin/mount 67 | ub1810:/bin/ntfs-3g 68 | ub1810:/bin/ping 69 | ub1810:/bin/su 70 | ub1810:/bin/umount 71 | ub1810:/usr/bin/arping 72 | ub1810:/usr/bin/beep 73 | ub1810:/usr/bin/chfn 74 | ub1810:/usr/bin/chsh 75 | ub1810:/usr/bin/firejail 76 | ub1810:/usr/bin/gpasswd 77 | ub1810:/usr/bin/newgrp 78 | ub1810:/usr/bin/passwd 79 | ub1810:/usr/bin/pkexec 80 | ub1810:/usr/bin/sudo 81 | ub1810:/usr/bin/traceroute6.iputils 82 | ub1810:/usr/bin/weston-launch 83 | ub1810:/usr/lib/chromium-browser/chrome-sandbox 84 | ub1810:/usr/lib/dbus-1.0/dbus-daemon-launch-helper 85 | ub1810:/usr/lib/eject/dmcrypt-get-device 86 | ub1810:/usr/lib/openssh/ssh-keysign 87 | ub1810:/usr/lib/policykit-1/polkit-agent-helper-1 88 | ub1810:/usr/lib/snapd/snap-confine 89 | ub1810:/usr/lib/spice-gtk/spice-client-glib-usb-acl-helper 90 | ub1810:/usr/lib/xorg/Xorg.wrap 91 | ub1810:/usr/sbin/pppd 92 | 93 | 94 | Ubuntu 21.04 95 | ------------ 96 | 97 | ub2104:/usr/lib/openssh/ssh-keysign 98 | ub2104:/usr/lib/xorg/Xorg.wrap 99 | ub2104:/usr/lib/dbus-1.0/dbus-daemon-launch-helper 100 | ub2104:/usr/sbin/pppd 101 | ub2104:/usr/local/share/panasonic/printer/bin/L_H0JDUCZAZ 102 | ub2104:/usr/libexec/spice-client-glib-usb-acl-helper 103 | ub2104:/usr/libexec/polkit-agent-helper-1 104 | ub2104:/usr/bin/mount 105 | ub2104:/usr/bin/pumount 106 | ub2104:/usr/bin/chsh 107 | ub2104:/usr/bin/su 108 | ub2104:/usr/bin/firejail 109 | ub2104:/usr/bin/umount 110 | ub2104:/usr/bin/pkexec 111 | ub2104:/usr/bin/chfn 112 | ub2104:/usr/bin/passwd 113 | ub2104:/usr/bin/fusermount 114 | ub2104:/usr/bin/newgrp 115 | ub2104:/usr/bin/sudo 116 | ub2104:/usr/bin/gpasswd 117 | ub2104:/usr/bin/pmount 118 | 119 | 120 | Debian 121 | ------ 122 | 123 | debian:/bin/mount 124 | debian:/bin/su 125 | debian:/bin/umount 126 | debian:/sbin/mount.nfs 127 | debian:/usr/bin/at 128 | debian:/usr/bin/chfn 129 | debian:/usr/bin/chsh 130 | debian:/usr/bin/gpasswd 131 | debian:/usr/bin/mtr 132 | debian:/usr/bin/newgrp 133 | debian:/usr/bin/passwd 134 | debian:/usr/bin/procmail 135 | debian:/usr/bin/sudo 136 | debian:/usr/sbin/exim4 137 | debian:/usr/lib/dbus-1.0/dbus-daemon-launch-helper 138 | debian:/usr/lib/eject/dmcrypt-get-device 139 | debian:/usr/lib/openssh/ssh-keysign 140 | 141 | 142 | CentOS Linux release 7.6.1810 (Core) 143 | ------------------------------------ 144 | 145 | cent76:/usr/bin/chage 146 | cent76:/usr/bin/chfn 147 | cent76:/usr/bin/chsh 148 | cent76:/usr/bin/crontab 149 | cent76:/usr/bin/gpasswd 150 | cent76:/usr/bin/mount 151 | cent76:/usr/bin/newgrp 152 | cent76:/usr/bin/passwd 153 | cent76:/usr/bin/pkexec 154 | cent76:/usr/bin/su 155 | cent76:/usr/bin/sudo 156 | cent76:/usr/bin/umount 157 | cent76:/usr/lib/polkit-1/polkit-agent-helper-1 158 | cent76:/usr/libexec/dbus-1/dbus-daemon-launch-helper 159 | cent76:/usr/sbin/mount.nfs 160 | cent76:/usr/sbin/pam_timestamp_check 161 | cent76:/usr/sbin/unix_chkpwd 162 | cent76:/usr/sbin/usernetctl 163 | 164 | 165 | CentOS release 6.9 (Final) 166 | -------------------------- 167 | 168 | cent69:/bin/mount 169 | cent69:/bin/ping 170 | cent69:/bin/ping6 171 | cent69:/bin/su 172 | cent69:/bin/umount 173 | cent69:/lib64/dbus-1/dbus-daemon-launch-helper 174 | cent69:/sbin/mount.nfs 175 | cent69:/sbin/pam_timestamp_check 176 | cent69:/sbin/unix_chkpwd 177 | cent69:/usr/bin/Xorg 178 | cent69:/usr/bin/at 179 | cent69:/usr/bin/chage 180 | cent69:/usr/bin/chfn 181 | cent69:/usr/bin/chsh 182 | cent69:/usr/bin/crontab 183 | cent69:/usr/bin/gpasswd 184 | cent69:/usr/bin/newgrp 185 | cent69:/usr/bin/passwd 186 | cent69:/usr/bin/pkexec 187 | cent69:/usr/bin/staprun 188 | cent69:/usr/bin/sudo 189 | cent69:/usr/libexec/abrt-action-install-debuginfo-to-abrt-cache 190 | cent69:/usr/libexec/openssh/ssh-keysign 191 | cent69:/usr/libexec/polkit-1/polkit-agent-helper-1 192 | cent69:/usr/libexec/pt_chown 193 | cent69:/usr/sbin/suexec 194 | cent69:/usr/sbin/userhelper 195 | cent69:/usr/sbin/usernetctl 196 | 197 | 198 | CentOS release 6.6 (Final) 199 | -------------------------- 200 | 201 | cent66:/bin/fusermount 202 | cent66:/bin/mount 203 | cent66:/bin/ping 204 | cent66:/bin/ping6 205 | cent66:/bin/su 206 | cent66:/bin/umount 207 | cent66:/lib64/dbus-1/dbus-daemon-launch-helper 208 | cent66:/sbin/mount.nfs 209 | cent66:/sbin/pam_timestamp_check 210 | cent66:/sbin/unix_chkpwd 211 | cent66:/usr/bin/Xorg 212 | cent66:/usr/bin/chage 213 | cent66:/usr/bin/chfn 214 | cent66:/usr/bin/chsh 215 | cent66:/usr/bin/crontab 216 | cent66:/usr/bin/gpasswd 217 | cent66:/usr/bin/newgrp 218 | cent66:/usr/bin/passwd 219 | cent66:/usr/bin/pkexec 220 | cent66:/usr/bin/sudo 221 | cent66:/usr/libexec/openssh/ssh-keysign 222 | cent66:/usr/libexec/polkit-1/polkit-agent-helper-1 223 | cent66:/usr/libexec/pt_chown 224 | cent66:/usr/sbin/suexec 225 | cent66:/usr/sbin/userhelper 226 | cent66:/usr/sbin/usernetctl 227 | 228 | 229 | CentOS release 7 230 | ---------------- 231 | 232 | cent70:/usr/bin/chfn 233 | cent70:/usr/bin/chsh 234 | cent70:/usr/bin/chage 235 | cent70:/usr/bin/gpasswd 236 | cent70:/usr/bin/newgrp 237 | cent70:/usr/bin/mount 238 | cent70:/usr/bin/su 239 | cent70:/usr/bin/sudo 240 | cent70:/usr/bin/umount 241 | cent70:/usr/bin/pkexec 242 | cent70:/usr/bin/crontab 243 | cent70:/usr/bin/passwd 244 | cent70:/usr/sbin/unix_chkpwd 245 | cent70:/usr/sbin/pam_timestamp_check 246 | cent70:/usr/sbin/usernetctl 247 | cent70:/usr/lib/polkit-1/polkit-agent-helper-1 248 | cent70:/usr/libexec/dbus-1/dbus-daemon-launch-helper 249 | 250 | 251 | openSUSE 15.0 252 | ------------- 253 | 254 | osu150:/sbin/mount.nfs 255 | osu150:/sbin/pccardctl 256 | osu150:/sbin/unix2_chkpwd 257 | osu150:/sbin/unix_chkpwd 258 | osu150:/usr/bin/chfn 259 | osu150:/usr/bin/chsh 260 | osu150:/usr/bin/crontab 261 | osu150:/usr/bin/expiry 262 | osu150:/usr/bin/fusermount 263 | osu150:/usr/bin/gpasswd 264 | osu150:/usr/bin/mount 265 | osu150:/usr/bin/newgidmap 266 | osu150:/usr/bin/newgrp 267 | osu150:/usr/bin/newuidmap 268 | osu150:/usr/bin/passwd 269 | osu150:/usr/bin/pkexec 270 | osu150:/usr/bin/su 271 | osu150:/usr/bin/sudo 272 | osu150:/usr/bin/umount 273 | osu150:/usr/lib/dbus-1/dbus-daemon-launch-helper 274 | osu150:/usr/lib/polkit-1/polkit-agent-helper-1 275 | osu150:/usr/sbin/pppoe-wrapper 276 | 277 | 278 | OpenSUSE Leap 15.3 279 | ------------------ 280 | 281 | osl153:/usr/lib/dbus-1/dbus-daemon-launch-helper 282 | osl153:/usr/lib/polkit-1/polkit-agent-helper-1 283 | osl153:/usr/bin/sudo 284 | osl153:/usr/bin/chfn 285 | osl153:/usr/bin/chsh 286 | osl153:/usr/bin/expiry 287 | osl153:/usr/bin/gpasswd 288 | osl153:/usr/bin/newgidmap 289 | osl153:/usr/bin/newgrp 290 | osl153:/usr/bin/newuidmap 291 | osl153:/usr/bin/passwd 292 | osl153:/usr/bin/mount 293 | osl153:/usr/bin/su 294 | osl153:/usr/bin/umount 295 | osl153:/usr/bin/fusermount 296 | osl153:/usr/bin/pkexec 297 | osl153:/usr/bin/crontab 298 | osl153:/sbin/unix2_chkpwd 299 | osl153:/sbin/unix_chkpwd 300 | osl153:/sbin/mount.nfs 301 | 302 | 303 | Fedora Workstation 29 304 | --------------------- 305 | 306 | fedw29:/usr/bin/at 307 | fedw29:/usr/bin/chage 308 | fedw29:/usr/bin/crontab 309 | fedw29:/usr/bin/fusermount 310 | fedw29:/usr/bin/fusermount-glusterfs 311 | fedw29:/usr/bin/gpasswd 312 | fedw29:/usr/bin/mount 313 | fedw29:/usr/bin/newgidmap 314 | fedw29:/usr/bin/newgrp 315 | fedw29:/usr/bin/newuidmap 316 | fedw29:/usr/bin/passwd 317 | fedw29:/usr/bin/pkexec 318 | fedw29:/usr/bin/su 319 | fedw29:/usr/bin/sudo 320 | fedw29:/usr/bin/umount 321 | fedw29:/usr/lib/polkit-1/polkit-agent-helper-1 322 | fedw29:/usr/libexec/Xorg.wrap 323 | fedw29:/usr/libexec/abrt-action-install-debuginfo-to-abrt-cache 324 | fedw29:/usr/libexec/dbus-1/dbus-daemon-launch-helper 325 | fedw29:/usr/libexec/gstreamer-1.0/gst-ptp-helper 326 | fedw29:/usr/libexec/qemu-bridge-helper 327 | fedw29:/usr/libexec/spice-gtk-x86_64/spice-client-glib-usb-acl-helper 328 | fedw29:/usr/sbin/grub2-set-bootflag 329 | fedw29:/usr/sbin/mount.nfs 330 | fedw29:/usr/sbin/mtr-packet 331 | fedw29:/usr/sbin/pam_timestamp_check 332 | fedw29:/usr/sbin/unix_chkpwd 333 | fedw29:/usr/sbin/userhelper 334 | 335 | 336 | Fedora Server 34 337 | ---------------- 338 | 339 | feds34:/usr/bin/chage 340 | feds34:/usr/bin/gpasswd 341 | feds34:/usr/bin/newgrp 342 | feds34:/usr/bin/mount 343 | feds34:/usr/bin/su 344 | feds34:/usr/bin/umount 345 | feds34:/usr/bin/pkexec 346 | feds34:/usr/bin/crontab 347 | feds34:/usr/bin/sudo 348 | feds34:/usr/bin/passwd 349 | feds34:/usr/bin/chfn 350 | feds34:/usr/bin/chsh 351 | feds34:/usr/bin/at 352 | feds34:/usr/sbin/grub2-set-bootflag 353 | feds34:/usr/sbin/pam_timestamp_check 354 | feds34:/usr/sbin/unix_chkpwd 355 | feds34:/usr/sbin/mount.nfs 356 | feds34:/usr/lib/polkit-1/polkit-agent-helper-1 357 | feds34:/usr/libexec/cockpit-session 358 | -------------------------------------------------------------------------------- /lse.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # shellcheck disable=1003,1091,2006,2016,2034,2039,3043 3 | # vim: set ts=2 sw=2 sts=2 fdm=marker fmr=#(,#) et: 4 | 5 | # Author: Diego Blanco 6 | # GitHub: https://github.com/diego-treitos/linux-smart-enumeration 7 | # 8 | lse_version="4.14nw" 9 | 10 | ##( Colors 11 | # 12 | #( fg 13 | red='\e[31m' 14 | lred='\e[91m' 15 | green='\e[32m' 16 | lgreen='\e[92m' 17 | yellow='\e[33m' 18 | lyellow='\e[93m' 19 | blue='\e[34m' 20 | lblue='\e[94m' 21 | magenta='\e[35m' 22 | lmagenta='\e[95m' 23 | cyan='\e[36m' 24 | lcyan='\e[96m' 25 | grey='\e[90m' 26 | lgrey='\e[37m' 27 | white='\e[97m' 28 | black='\e[30m' 29 | ##) 30 | #( bg 31 | b_red='\e[41m' 32 | b_lred='\e[101m' 33 | b_green='\e[42m' 34 | b_lgreen='\e[102m' 35 | b_yellow='\e[43m' 36 | b_lyellow='\e[103m' 37 | b_blue='\e[44m' 38 | b_lblue='\e[104m' 39 | b_magenta='\e[45m' 40 | b_lmagenta='\e[105m' 41 | b_cyan='\e[46m' 42 | b_lcyan='\e[106m' 43 | b_grey='\e[100m' 44 | b_lgrey='\e[47m' 45 | b_white='\e[107m' 46 | b_black='\e[40m' 47 | ##) 48 | #( special 49 | reset='\e[0;0m' 50 | bold='\e[01m' 51 | italic='\e[03m' 52 | underline='\e[04m' 53 | inverse='\e[07m' 54 | conceil='\e[08m' 55 | crossedout='\e[09m' 56 | bold_off='\e[22m' 57 | italic_off='\e[23m' 58 | underline_off='\e[24m' 59 | inverse_off='\e[27m' 60 | conceil_off='\e[28m' 61 | crossedout_off='\e[29m' 62 | ##) 63 | #) 64 | 65 | ##( Globals 66 | # 67 | # user 68 | lse_user_id="`id -u`" 69 | lse_user="$USER" 70 | [ -z "$lse_user" ] && lse_user="`id -nu`" 71 | lse_pass="" 72 | lse_home="$HOME" 73 | [ -z "$lse_home" ] && lse_home="`(grep -E "^$lse_user:" /etc/passwd | cut -d: -f6)2>/dev/null`" 74 | 75 | # system 76 | lse_arch="`uname -m`" 77 | lse_linux="`uname -r`" 78 | lse_hostname="`hostname`" 79 | lse_distro=`command -v lsb_release >/dev/null 2>&1 && lsb_release -d | sed 's/Description:\s*//' 2>/dev/null` 80 | [ -z "$lse_distro" ] && lse_distro="`(. /etc/os-release && echo "$PRETTY_NAME")2>/dev/null`" 81 | lse_distro_codename="" # retrieved below with lse_get_distro_codename 82 | 83 | # lse 84 | lse_passed_tests="" 85 | lse_executed_tests="" 86 | lse_DEBUG=false 87 | lse_procmon_data=`mktemp` 88 | lse_procmon_lock=`mktemp` 89 | lse_cve_tmp='' 90 | 91 | # printf 92 | printf "$reset" | grep -q '\\' && alias printf="env printf" 93 | 94 | #( internal data 95 | lse_common_setuid=" 96 | /bin/fusermount 97 | /bin/mount 98 | /bin/ntfs-3g 99 | /bin/ping 100 | /bin/ping6 101 | /bin/su 102 | /bin/umount 103 | /lib64/dbus-1/dbus-daemon-launch-helper 104 | /sbin/mount.ecryptfs_private 105 | /sbin/mount.nfs 106 | /sbin/pam_timestamp_check 107 | /sbin/pccardctl 108 | /sbin/unix2_chkpwd 109 | /sbin/unix_chkpwd 110 | /usr/bin/Xorg 111 | /usr/bin/arping 112 | /usr/bin/at 113 | /usr/bin/beep 114 | /usr/bin/chage 115 | /usr/bin/chfn 116 | /usr/bin/chsh 117 | /usr/bin/crontab 118 | /usr/bin/expiry 119 | /usr/bin/firejail 120 | /usr/bin/fusermount 121 | /usr/bin/fusermount-glusterfs 122 | /usr/bin/fusermount3 123 | /usr/bin/gpasswd 124 | /usr/bin/kismet_capture 125 | /usr/bin/mount 126 | /usr/bin/mtr 127 | /usr/bin/newgidmap 128 | /usr/bin/newgrp 129 | /usr/bin/newuidmap 130 | /usr/bin/ntfs-3g 131 | /usr/bin/passwd 132 | /usr/bin/pkexec 133 | /usr/bin/pmount 134 | /usr/bin/procmail 135 | /usr/bin/pumount 136 | /usr/bin/staprun 137 | /usr/bin/su 138 | /usr/bin/sudo 139 | /usr/bin/sudoedit 140 | /usr/bin/traceroute6.iputils 141 | /usr/bin/umount 142 | /usr/bin/weston-launch 143 | /usr/lib/chromium-browser/chrome-sandbox 144 | /usr/lib/dbus-1.0/dbus-daemon-launch-helper 145 | /usr/lib/dbus-1/dbus-daemon-launch-helper 146 | /usr/lib/eject/dmcrypt-get-device 147 | /usr/lib/openssh/ssh-keysign 148 | /usr/lib/policykit-1/polkit-agent-helper-1 149 | /usr/lib/polkit-1/polkit-agent-helper-1 150 | /usr/lib/pt_chown 151 | /usr/lib/snapd/snap-confine 152 | /usr/lib/spice-gtk/spice-client-glib-usb-acl-helper 153 | /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic 154 | /usr/lib/xorg/Xorg.wrap 155 | /usr/libexec/Xorg.wrap 156 | /usr/libexec/abrt-action-install-debuginfo-to-abrt-cache 157 | /usr/libexec/cockpit-session 158 | /usr/libexec/dbus-1/dbus-daemon-launch-helper 159 | /usr/libexec/gstreamer-1.0/gst-ptp-helper 160 | /usr/libexec/openssh/ssh-keysign 161 | /usr/libexec/polkit-1/polkit-agent-helper-1 162 | /usr/libexec/polkit-agent-helper-1 163 | /usr/libexec/pt_chown 164 | /usr/libexec/qemu-bridge-helper 165 | /usr/libexec/spice-client-glib-usb-acl-helper 166 | /usr/libexec/spice-gtk-x86_64/spice-client-glib-usb-acl-helper 167 | /usr/local/share/panasonic/printer/bin/L_H0JDUCZAZ 168 | /usr/sbin/exim4 169 | /usr/sbin/grub2-set-bootflag 170 | /usr/sbin/mount.nfs 171 | /usr/sbin/mtr-packet 172 | /usr/sbin/pam_timestamp_check 173 | /usr/sbin/pppd 174 | /usr/sbin/pppoe-wrapper 175 | /usr/sbin/suexec 176 | /usr/sbin/unix_chkpwd 177 | /usr/sbin/userhelper 178 | /usr/sbin/usernetctl 179 | /usr/sbin/uuidd 180 | " 181 | #) 182 | #( regex rules for common setuid 183 | lse_common_setuid="$lse_common_setuid 184 | /snap/core.* 185 | /var/tmp/mkinitramfs.* 186 | " 187 | #) 188 | #( critical writable files 189 | lse_critical_writable=" 190 | /etc/apache2/apache2.conf 191 | /etc/apache2/httpd.conf 192 | /etc/bash.bashrc 193 | /etc/bash_completion 194 | /etc/bash_completion.d/* 195 | /etc/environment 196 | /etc/environment.d/* 197 | /etc/hosts.allow 198 | /etc/hosts.deny 199 | /etc/httpd/conf/httpd.conf 200 | /etc/httpd/httpd.conf 201 | /etc/incron.conf 202 | /etc/incron.d/* 203 | /etc/logrotate.d/* 204 | /etc/modprobe.d/* 205 | /etc/pam.d/* 206 | /etc/passwd 207 | /etc/php*/fpm/pool.d/* 208 | /etc/php/*/fpm/pool.d/* 209 | /etc/profile 210 | /etc/profile.d/* 211 | /etc/rc*.d/* 212 | /etc/rsyslog.d/* 213 | /etc/shadow 214 | /etc/skel/* 215 | /etc/sudoers 216 | /etc/sudoers.d/* 217 | /etc/supervisor/conf.d/* 218 | /etc/supervisor/supervisord.conf 219 | /etc/sysctl.conf 220 | /etc/sysctl.d/* 221 | /etc/uwsgi/apps-enabled/* 222 | /root/.ssh/authorized_keys 223 | " 224 | #critical writable directories 225 | lse_critical_writable_dirs=" 226 | /etc/bash_completion.d 227 | /etc/cron.d 228 | /etc/cron.daily 229 | /etc/cron.hourly 230 | /etc/cron.weekly 231 | /etc/environment.d 232 | /etc/logrotate.d 233 | /etc/modprobe.d 234 | /etc/pam.d 235 | /etc/profile.d 236 | /etc/rsyslog.d/ 237 | /etc/sudoers.d/ 238 | /etc/sysctl.d 239 | /root 240 | " 241 | #) 242 | #( CVE list (populated by the lse packager) 243 | lse_cve_list=" 244 | " #CVElistMARKER 245 | #) 246 | #) 247 | 248 | ##( Options 249 | lse_color=true 250 | lse_alt_color=false 251 | lse_interactive=true 252 | lse_proc_time=60 253 | lse_level=0 #Valid levels 0:default, 1:interesting, 2:all 254 | lse_selection="" #Selected tests to run. Empty means all. 255 | lse_find_opts='-path /proc -prune -o -path /sys -prune -o -path /dev -prune -o' #paths to exclude from searches 256 | lse_grep_opts='--color=always' 257 | #) 258 | 259 | ##( Lib 260 | cecho() { #( 261 | if $lse_color; then 262 | printf "%b" "$@" 263 | else 264 | # If color is disabled we remove it 265 | printf "%b" "$@" | sed -r 's/(\x1B|\\e)\[[0-9;:]+[A-Za-z]//g' 266 | fi 267 | } #) 268 | lse_recolor() { #( 269 | o_white="$white" 270 | o_lyellow="$lyellow" 271 | o_grey="$grey" 272 | o_lred="$lred" 273 | o_lgreen="$lgreen" 274 | o_lcyan="$lcyan" 275 | 276 | white="$o_grey" 277 | lyellow="$o_lred" 278 | grey="$lgrey" 279 | lred="$red" 280 | lgreen="$b_lgreen$black" 281 | lcyan="$cyan" 282 | } #) 283 | lse_error() { #( 284 | cecho "${red}ERROR: ${reset}$*\n" >&2 285 | } #) 286 | lse_exclude_paths() { #( 287 | local IFS=" 288 | " 289 | for p in `printf "%s" "$1" | tr ',' '\n'`; do 290 | [ "`printf \"%s\" \"$p\" | cut -c1`" = "/" ] || lse_error "'$p' is not an absolute path." 291 | p="${p%%/}" 292 | lse_find_opts="$lse_find_opts -path ${p} -prune -o" 293 | done 294 | } #) 295 | lse_set_level() { #( 296 | case "$1" in 297 | 0|1|2) 298 | lse_level=$(($1)) 299 | ;; 300 | *) 301 | lse_error "Invalid level." 302 | exit 1 303 | ;; 304 | esac 305 | } #) 306 | lse_help() { #( 307 | echo "Use: $0 [options]" 308 | echo 309 | echo " OPTIONS" 310 | echo " -c Disable color" 311 | echo " -C Use alternative color scheme" 312 | echo " -i Non interactive mode" 313 | echo " -h This help" 314 | echo " -l LEVEL Output verbosity level" 315 | echo " 0: Show highly important results. (default)" 316 | echo " 1: Show interesting results." 317 | echo " 2: Show all gathered information." 318 | echo " -s SELECTION Comma separated list of sections or tests to run. Available" 319 | echo " sections:" 320 | echo " usr: User related tests." 321 | echo " sud: Sudo related tests." 322 | echo " fst: File system related tests." 323 | echo " sys: System related tests." 324 | echo " sec: Security measures related tests." 325 | echo " ret: Recurrent tasks (cron, timers) related tests." 326 | echo " net: Network related tests." 327 | echo " srv: Services related tests." 328 | echo " pro: Processes related tests." 329 | echo " sof: Software related tests." 330 | echo " ctn: Container (docker, lxc) related tests." 331 | echo " cve: CVE related tests." 332 | echo " Specific tests can be used with their IDs (i.e.: usr020,sud)" 333 | echo " -e PATHS Comma separated list of paths to exclude. This allows you" 334 | echo " to do faster scans at the cost of completeness" 335 | echo " -p SECONDS Time that the process monitor will spend watching for" 336 | echo " processes. A value of 0 will disable any watch (default: 60)" 337 | echo " -S Serve the lse.sh script in this host so it can be retrieved" 338 | echo " from a remote host." 339 | } #) 340 | lse_ask() { #( 341 | local question="$1" 342 | # We use stderr to print the question 343 | cecho "${white}${question}: ${reset}" >&2 344 | read -r answer 345 | case "$answer" in 346 | y|Y|yes|Yes|ok|Ok|true|True) 347 | return 0 348 | ;; 349 | *) 350 | echo "$answer" 351 | return 1 352 | ;; 353 | esac 354 | } #) 355 | lse_request_information() { #( 356 | if $lse_interactive; then 357 | cecho "${grey}---\n" 358 | [ -z "$lse_user" ] && lse_user=`lse_ask "Could not find current user name. Current user?"` 359 | lse_pass=`lse_ask "If you know the current user password, write it here to check sudo privileges"` 360 | cecho "${grey}---\n" 361 | fi 362 | } #) 363 | lse_test_passed() { #( 364 | # Checks if a test passed by ID 365 | local id="$1" 366 | for i in $lse_passed_tests; do 367 | [ "$i" = "$id" ] && return 0 368 | done 369 | return 1 370 | } #) 371 | lse_test() { #( 372 | # Test id 373 | local id="$1" 374 | # Minimum level required for this test to show its output 375 | local level=$(($2)) 376 | # Name of the current test 377 | local name="$3" 378 | # Output of the test 379 | local cmd="$4" 380 | # Dependencies 381 | local deps="$5" 382 | # Variable name where to store the output 383 | local var="$6" 384 | # Flags affecting the execution of certain tests 385 | local flags="$7" 386 | 387 | # Define colors 388 | local l="${lred}!" 389 | local r="${lgreen}" 390 | [ $level -eq 1 ] && l="${lyellow}*" && r="${cyan}" 391 | [ $level -eq 2 ] && l="${lblue}i" && r="${blue}" 392 | 393 | # Filter selected tests 394 | if [ "$lse_selection" ]; then 395 | local sel_match=false 396 | for s in $lse_selection; do 397 | if [ "$s" = "$id" ] || [ "$s" = "`printf \"%s\" \"$id\" | cut -c1-3`" ]; then 398 | sel_match=true 399 | fi 400 | done 401 | $sel_match || return 0 402 | fi 403 | 404 | # DEBUG messages 405 | $lse_DEBUG && cecho "${lmagenta}DEBUG: ${lgreen}Executing: ${reset}$cmd\n" 406 | 407 | # Print name and line 408 | cecho "${white}[${l}${white}] ${grey}${id}${white} $name${grey}" 409 | for i in $(seq $((${#id}+${#name}+10)) 79); do 410 | printf "." 411 | done 412 | 413 | # Check if test should be skipped when running as root 414 | if [ "$lse_user_id" -eq 0 ] && [ "$flags" = "rootskip" ]; then 415 | cecho " ${grey}skip\n" 416 | return 1 417 | fi 418 | 419 | # Check dependencies 420 | local non_met_deps="" 421 | for d in $deps; do 422 | lse_test_passed "$d" || non_met_deps="$non_met_deps $d" 423 | done 424 | if [ "$non_met_deps" ]; then 425 | cecho " ${grey}skip\n" 426 | # In "selection mode" we print the missed dependencies 427 | if [ "$lse_selection" ]; then 428 | cecho "${red}---\n" 429 | cecho "Dependencies not met:$reset $non_met_deps\n" 430 | cecho "${red}---$reset\n" 431 | fi 432 | return 1 433 | fi 434 | 435 | # If level is 2 and lse_level is less than 2, then we do not execute 436 | # level 2 tests unless their output needs to be assigned to a variable 437 | if [ $level -ge 2 ] && [ $lse_level -lt 2 ] && [ -z "$var" ]; then 438 | cecho " ${grey}skip\n" 439 | return 1 440 | else 441 | if $lse_DEBUG; then 442 | output="`eval "$cmd" 2>&1`" 443 | else 444 | # Execute command if this test's level is in scope 445 | output="`eval "$cmd" 2>/dev/null`" 446 | # Assign variable if available 447 | fi 448 | [ "$var" ] && [ "$output" ] && readonly "${var}=$output" 449 | # Mark test as executed 450 | lse_executed_tests="$lse_executed_tests $id" 451 | fi 452 | 453 | if [ -z "$output" ]; then 454 | cecho " ${grey}nope${reset}\n" 455 | return 1 456 | else 457 | lse_passed_tests="$lse_passed_tests $id" 458 | cecho "${r} yes!${reset}\n" 459 | if [ $lse_level -ge $level ]; then 460 | cecho "${grey}---$reset\n" 461 | echo "$output" 462 | cecho "${grey}---$reset\n" 463 | fi 464 | return 0 465 | fi 466 | } #) 467 | lse_show_info() { #( 468 | echo 469 | cecho "${lcyan} LSE Version:${reset} $lse_version\n" 470 | echo 471 | cecho "${lblue} User:${reset} $lse_user\n" 472 | cecho "${lblue} User ID:${reset} $lse_user_id\n" 473 | cecho "${lblue} Password:${reset} " 474 | if [ -z "$lse_pass" ]; then 475 | cecho "${grey}none${reset}\n" 476 | else 477 | cecho "******\n" 478 | fi 479 | cecho "${lblue} Home:${reset} $lse_home\n" 480 | cecho "${lblue} Path:${reset} $PATH\n" 481 | cecho "${lblue} umask:${reset} `umask 2>/dev/null`\n" 482 | 483 | echo 484 | cecho "${lblue} Hostname:${reset} $lse_hostname\n" 485 | cecho "${lblue} Linux:${reset} $lse_linux\n" 486 | if [ "$lse_distro" ]; then 487 | cecho "${lblue}Distribution:${reset} $lse_distro\n" 488 | fi 489 | cecho "${lblue}Architecture:${reset} $lse_arch\n" 490 | echo 491 | cecho "${green}=====================(${yellow} Current Output Verbosity Level: ${cyan}$lse_level ${green})======================${reset}" 492 | echo 493 | if [ "$lse_user_id" -eq 0 ]; then 494 | cecho "${green}============(${yellow} Already running as ${red}root${yellow}, some tests will be skipped! ${green})============${reset}" 495 | echo 496 | fi 497 | } #) 498 | lse_serve() { #( 499 | # get port 500 | which nc >/dev/null || lse_error "Could not find 'nc' netcat binary." 501 | 502 | local_ips="`ip a | grep -Eo "inet ([0-9]{1,3}\.){3}[0-9]{1,3}" | cut -d' ' -f2`" 503 | 504 | # Get a valid and non used port 505 | port=`od -An -N2 -i /dev/random|grep -Eo '[0-9]+'` 506 | port_valid=true 507 | while true; do 508 | for ip in $local_ips; do 509 | nc -z "$ip" "$port" && port_valid=false 510 | done 511 | if [ $((port)) -lt 1024 ] || [ $((port)) -gt 65500 ]; then 512 | port_valid=false 513 | fi 514 | $port_valid && break 515 | port=`od -An -N2 -i /dev/random|grep -Eo '[0-9]+'` 516 | done 517 | 518 | echo 519 | cecho " Serving ${white}Linux Smart Enumeration${reset} on port ${blue}$port${reset}.\n" 520 | echo 521 | cecho " Depending on your IP and available tools, some of these commands should download it in a remote host:\n" 522 | for ip in $local_ips; do 523 | [ "$ip" = "127.0.0.1" ] && continue 524 | echo 525 | cecho "${reset} [${blue}$ip${reset}]\n" 526 | cecho "${green} * ${white}nc ${reset} $ip $port > lse.sh /dev/tcp/${reset}$ip/$port;printf '\\\\n'>&3;cat<&3>lse.sh;exec 3<&-;chmod 755 lse.sh\n" 530 | done 531 | # try nc with '-N' (openbsd), then ncat and then use '-q0' (traditional) 532 | nc -l -N -p "$port" < "$0" >/dev/null 2>/dev/null || nc -l --send-only -p "$port" < "$0" >/dev/null 2>/dev/null || nc -l -q0 -p "$port" < "$0" >/dev/null 533 | } #) 534 | lse_header() { #( 535 | local id="$1" 536 | shift 537 | local title="$*" 538 | local text="${magenta}" 539 | 540 | # Filter selected tests 541 | if [ "$lse_selection" ]; then 542 | local sel_match=false 543 | for s in $lse_selection; do 544 | if [ "`printf \"%s\" \"$s\"|cut -c1-3`" = "$id" ]; then 545 | sel_match=true 546 | break 547 | fi 548 | done 549 | $sel_match || return 0 550 | fi 551 | 552 | for i in $(seq ${#title} 70); do 553 | text="$text=" 554 | done 555 | text="$text(${green} $title ${magenta})=====" 556 | cecho "$text${reset}\n" 557 | } #) 558 | lse_exit() { #( 559 | local ec=1 560 | local text="\n${magenta}==================================" 561 | [ "$1" ] && ec=$1 562 | text="$text(${green} FINISHED ${magenta})==================================" 563 | cecho "$text${reset}\n" 564 | rm -f "$lse_procmon_data" 565 | rm -f "$lse_procmon_lock" 566 | rm -f "$lse_cve_tmp" 567 | exit "$ec" 568 | } #) 569 | lse_procmon() { #( 570 | # monitor processes 571 | #NOTE: The first number will be the number of occurrences of a process due to 572 | # uniq -c 573 | local ps_args 574 | local ps_busybox 575 | if ps -V 2>&1 | grep -iq busybox; then 576 | ps_args='-o pid,user,args' 577 | ps_busybox=true 578 | else 579 | ps_args="-ewwwo start_time,pid,user:50,args" 580 | ps_busybox=false 581 | fi 582 | while [ -f "$lse_procmon_lock" ]; do 583 | if $ps_busybox; then 584 | ps $ps_args | sed 's/^\([0-9]*\)/? \1 /g' 585 | else 586 | ps $ps_args 587 | fi 588 | sleep 0.001 589 | done | grep -Ev "(pid,user|$lse_user *sed s/)" | sed 's/^ *//g' | tr -s '[:space:]' | grep -Ev "PID *USER *COMMAND" | grep -Ev '[^ ]+ [^ ]+ [^ ]+ \[' | sort -Mr | uniq -c | sed 's/^ *//g' > "$lse_procmon_data" 590 | } #) 591 | lse_proc_print() { #( 592 | # Pretty prints output from lse_procmom received via stdin 593 | if $lse_color; then 594 | printf "${green}%s %8s %8s %s\n" "START" "PID" "USER" "COMMAND" 595 | else 596 | printf "%s %8s %8s %s\n" "START" "PID" "USER" "COMMAND" 597 | fi 598 | while read -r l; do 599 | p_num=`echo "$l" | cut -d" " -f1` 600 | p_time=`echo "$l" | cut -d" " -f2` 601 | p_pid=`echo "$l" | cut -d" " -f3` 602 | p_user=`echo "$l" | cut -d" " -f4` 603 | p_args=`echo "$l" | cut -d" " -f5-` 604 | 605 | if $lse_color; then 606 | if [ $((p_num)) -lt 20 ]; then # few times probably periodic 607 | printf "${red}%s ${reset}%8s ${yellow}%8s ${red}%s\n" "$p_time" "$p_pid" "$p_user" "$p_args" 608 | else 609 | printf "${magenta}%s ${reset}%8s ${yellow}%8s ${reset}%s\n" "$p_time" "$p_pid" "$p_user" "$p_args" 610 | fi 611 | else 612 | printf "%s %8s %8s %s\n" "$p_time" "$p_pid" "$p_user" "$p_args" 613 | fi 614 | done 615 | } #) 616 | lse_get_distro_codename() { #( 617 | # Get the distribution name 618 | # 619 | # ubuntu, debian, centos, redhat, opsuse, fedora, rocky 620 | local distro="${grey}unknown${reset}" 621 | if type lsb_release >/dev/null 2>&1; then 622 | distro=`lsb_release -is` 623 | elif [ -f /etc/os-release ]; then 624 | distro=`grep -E '^ID=' /etc/os-release | cut -f2 -d=` 625 | echo "$distro" | grep -qi opensuse && distro=opsuse 626 | echo "$distro" | grep -qi rhel && distro=redhat 627 | elif [ -f /etc/redhat-release ]; then 628 | grep -qi "centos" /etc/redhat-release && distro=centos 629 | grep -qi "fedora" /etc/redhat-release && distro=fedora 630 | grep -qi "red hat" /etc/redhat-release && distro=redhat 631 | grep -qi "rocky" /etc/redhat-release && distro=rocky 632 | fi 633 | printf '%s' "$distro" | tr '[:upper:]' '[:lower:]' | tr -d \"\' 634 | } #) 635 | lse_is_version_bigger() { #( 636 | # check if version v1 is bigger than v2 637 | local v1="$1"; local v2="$2" ; local vc 638 | [ "$v1" = "$v2" ] && return 1 # equal is not bigger 639 | vc="`printf "%s\n%s\n" "$v1" "$v2" | sort -rV | head -n1`" 640 | [ "$v1" = "$vc" ] && return 0 641 | return 1 642 | } #) 643 | lse_get_pkg_version() { #( 644 | # get package version depending on distro 645 | # returns 2 if distro is unknown 646 | # returns 1 if package is not installed (or doesn't exist) 647 | # returns 0 on success, and prints out the package version 648 | pkg_name="$1" 649 | case "$lse_distro_codename" in 650 | debian|ubuntu) 651 | pkg_version=`dpkg -l "$pkg_name" 2>/dev/null | grep -E '^[ih]i' | tr -s ' ' | cut -d' ' -f3` 652 | ;; 653 | centos|redhat|fedora|opsuse|rocky|amzn) 654 | pkg_version=`rpm -q "$pkg_name" 2>/dev/null` 655 | pkg_version="${pkg_version##"$pkg_name"-}" 656 | pkg_version=`echo "$pkg_version" | sed -E 's/\.(aarch64|armv7hl|i686|noarch|ppc64le|s390x|x86_64)$//'` 657 | ;; 658 | *) 659 | return 2 660 | ;; 661 | esac 662 | [ -z "$pkg_version" ] && return 1 663 | printf "%s" "$pkg_version" 664 | return 0 665 | } #) 666 | #) 667 | #) 668 | 669 | ########################################################################( TESTS 670 | # 671 | # A successful test will receive some output while a failed tests will receive 672 | # an empty string. 673 | # 674 | ########################################################################( users 675 | lse_run_tests_users() { 676 | lse_header "usr" "users" 677 | 678 | #user groups 679 | lse_test "usr000" "2" \ 680 | "Current user groups" \ 681 | 'groups' \ 682 | "" \ 683 | "lse_user_groups" 684 | 685 | #user in an administrative group 686 | lse_test "usr010" "1" \ 687 | "Is current user in an administrative group?" \ 688 | 'grep $lse_grep_opts -E "^(adm|admin|root|sudo|wheel)" /etc/group | grep $lse_grep_opts -E "(:|,)$lse_user"' 689 | 690 | #other users in an administrative group 691 | lse_test "usr020" "1" \ 692 | "Are there other users in administrative groups?" \ 693 | 'grep $lse_grep_opts -E "^(adm|admin|root|sudo|wheel)" /etc/group | grep -Ev ":$|:$lse_user$" | grep $lse_grep_opts -Ei ":[,a-z_-]+\$"' 694 | 695 | #other users with shell 696 | lse_test "usr030" "1" \ 697 | "Other users with shell" \ 698 | 'grep $lse_grep_opts -E ":/[a-z/]+sh\$" /etc/passwd' \ 699 | "" \ 700 | "lse_shell_users" 701 | 702 | #user env information 703 | lse_test "usr040" "2" \ 704 | "Environment information" \ 705 | 'env | grep -v "LS_COLORS"' 706 | 707 | #dump user groups 708 | lse_test "usr050" "2" \ 709 | "Groups for other users" \ 710 | 'cat /etc/group' 711 | 712 | #dump users 713 | lse_test "usr060" "2" \ 714 | "Other users" \ 715 | 'cat /etc/passwd' 716 | 717 | #find defined PATHs 718 | lse_test "usr070" "1" \ 719 | "PATH variables defined inside /etc" \ 720 | 'for p in `grep -ERh "^ *PATH=.*" /etc/ 2> /dev/null | tr -d \"\'"'"' | cut -d= -f2 | tr ":" "\n" | sort -u`; do [ -d "$p" ] && echo "$p";done' \ 721 | "" \ 722 | "lse_exec_paths" 723 | 724 | #check if . is in PATHs 725 | lse_test "usr080" "0" \ 726 | "Is '.' in a PATH variable defined inside /etc?" \ 727 | 'for ep in $lse_exec_paths; do [ "$ep" = "." ] && grep -ER "^ *PATH=.*" /etc/ 2> /dev/null | tr -d \"\'"'"' | grep -E "[=:]\.([:[:space:]]|\$)";done' \ 728 | "usr070" 729 | } 730 | #) 731 | 732 | #########################################################################( sudo 733 | lse_run_tests_sudo() { 734 | lse_header "sud" "sudo" 735 | 736 | #variables for sudo checks 737 | lse_sudo=false 738 | lse_sudo_commands="" 739 | 740 | #can we sudo without supplying a password 741 | lse_test "sud000" "0" \ 742 | "Can we sudo without a password?" \ 743 | 'echo "" | sudo -nS id' && lse_sudo=true 744 | 745 | #can we list sudo commands without supplying a password 746 | $lse_sudo || \ 747 | lse_test "sud010" "0" \ 748 | "Can we list sudo commands without a password?" \ 749 | 'echo "" | sudo -nS -l' \ 750 | "" \ 751 | "lse_sudo_commands" 752 | 753 | if [ "$lse_pass" ]; then 754 | #can we sudo supplying a password 755 | $lse_sudo || \ 756 | lse_test "sud020" "0" \ 757 | "Can we sudo with a password?" \ 758 | 'echo "$lse_pass" | sudo -S id' && lse_sudo=true 759 | 760 | #can we list sudo commands without supplying a password 761 | if ! $lse_sudo && [ -z "$lse_sudo_commands" ]; then 762 | lse_test "sud030" "0" \ 763 | "Can we list sudo commands with a password?" \ 764 | 'echo "$lse_pass" | sudo -S -l' \ 765 | "" \ 766 | "lse_sudo_commands" 767 | fi 768 | fi 769 | 770 | #check if we can read the sudoers file 771 | lse_test "sud040" "1" \ 772 | "Can we read sudoers files?" \ 773 | 'grep -R "" /etc/sudoers*' 774 | 775 | #check users that sudoed in the past 776 | lse_test "sud050" "1" \ 777 | "Do we know if any other users used sudo?" \ 778 | 'for uh in $(cut -d: -f1,6 /etc/passwd); do [ -f "${uh##*:}/.sudo_as_admin_successful" ] && echo "${uh%%:*}"; done' 779 | } 780 | #) 781 | 782 | ##################################################################( file system 783 | lse_run_tests_filesystem() { 784 | lse_header "fst" "file system" 785 | 786 | #writable files outside user's home. NOTE: Does not check if user can write in symlink destination (performance reasons: -L implies -noleaf) 787 | lse_test "fst000" "1" \ 788 | "Writable files outside user's home" \ 789 | 'find / -path "$lse_home" -prune -o $lse_find_opts -not -type l -writable -print; 790 | # Add symlinks owned by the user (so the user can change where they point) 791 | find / -path "$lse_home" -prune -o $lse_find_opts -type l -user $lse_user -print' \ 792 | "" \ 793 | "lse_user_writable" \ 794 | "rootskip" 795 | 796 | #get setuid binaries 797 | lse_test "fst010" "1" \ 798 | "Binaries with setuid bit" \ 799 | 'find / $lse_find_opts -perm -4000 -type f -print' \ 800 | "" \ 801 | "lse_setuid_binaries" 802 | 803 | #uncommon setuid binaries 804 | lse_test "fst020" "0" \ 805 | "Uncommon setuid binaries" \ 806 | 'local setuidbin="$lse_setuid_binaries"; local IFS=" 807 | "; for cs in ${lse_common_setuid}; do setuidbin=`printf "$setuidbin\n" | grep -Ev "^$cs$"`;done ; printf "$setuidbin\n"' \ 808 | "fst010" 809 | 810 | #can we write to any setuid binary 811 | lse_test "fst030" "0" \ 812 | "Can we write to any setuid binary?" \ 813 | 'for b in $lse_setuid_binaries; do [ -x "$b" ] && [ -w "$b" ] && echo "$b" ;done' \ 814 | "fst010" 815 | 816 | #get setgid binaries 817 | lse_test "fst040" "1" \ 818 | "Binaries with setgid bit" \ 819 | 'find / $lse_find_opts -perm -2000 -type f -print' \ 820 | "lse_setgid_binaries" 821 | 822 | #uncommon setgid binaries 823 | lse_test "fst050" "0" \ 824 | "Uncommon setgid binaries" \ 825 | 'printf "$lse_setgid_binaries\n" | grep -Ev "^/(bin|sbin|usr/bin|usr/lib|usr/sbin)"' \ 826 | "fst040" 827 | 828 | #can we write to any setgid binary 829 | lse_test "fst060" "0" \ 830 | "Can we write to any setgid binary?" \ 831 | 'for b in $lse_setgid_binaries; do [ -x "$b" ] && [ -w "$b" ] && echo "$b" ;done' \ 832 | "fst040" 833 | 834 | #can we read /root 835 | lse_test "fst070" "1" \ 836 | "Can we read /root?" \ 837 | 'ls -ahl /root/' 838 | 839 | #check /home permissions 840 | lse_test "fst080" "1" \ 841 | "Can we read subdirectories under /home?" \ 842 | 'for h in /home/*; do [ -d "$h" ] && [ "$h" != "$lse_home" ] && ls -la "$h/"; done' 843 | 844 | #check for SSH files in home directories 845 | lse_test "fst090" "1" \ 846 | "SSH files in home directories" \ 847 | 'for h in $(cut -d: -f6 /etc/passwd | sort -u | grep -Ev "^(/|/dev|/bin|/proc|/run/.*|/var/run/.*)$"); do find "$h" \( -name "*id_dsa*" -o -name "*id_rsa*" -o -name "*id_ecdsa*" -o -name "*id_ed25519*" -o -name "known_hosts" -o -name "authorized_hosts" -o -name "authorized_keys" \) -exec ls -la {} \; ; done' 848 | 849 | #check useful binaries 850 | lse_test "fst100" "1" \ 851 | "Useful binaries" \ 852 | 'which curl; which dig; which gcc; which nc.openbsd; which nc; which netcat; which nmap; which socat; which wget' 853 | 854 | #check for interesting files in home directories 855 | lse_test "fst110" "1" \ 856 | "Other interesting files in home directories" \ 857 | 'for h in $(cut -d: -f6 /etc/passwd); do find "$h" \( -name "*.rhosts" -o -name ".git-credentials" -o -name ".*history" \) -maxdepth 1 -exec ls -la {} \; ;' 858 | 859 | #looking for credentials in /etc/fstab and /etc/mtab 860 | lse_test "fst120" "0" \ 861 | "Are there any credentials in fstab/mtab?" \ 862 | 'grep $lse_grep_opts -Ei "(user|username|login|pass|password|pw|credentials|cred)[=:]" /etc/fstab /etc/mtab' 863 | 864 | #check if current user has mail 865 | lse_test "fst130" "1" \ 866 | "Does '$lse_user' have mail?" \ 867 | 'ls -l "/var/mail/$lse_user"' 868 | 869 | #check if we can access other users mail mail 870 | lse_test "fst140" "0" \ 871 | "Can we access other users mail?" \ 872 | 'for f in /var/mail/*; do [ "$f" != "/var/mail/$lse_user" ] && [ -r "$f" ] && echo "$f"; done' 873 | 874 | #check for code repositories 875 | lse_test "fst150" "1" \ 876 | "Looking for GIT/SVN repositories" \ 877 | 'find / $lse_find_opts \( -name ".git" -o -name ".svn" \) -print' 878 | 879 | #can we write to files that can give us root 880 | lse_test "fst160" "0" \ 881 | "Can we write to critical files?" \ 882 | 'for uw in $lse_user_writable; do [ -f "$uw" ] && IFS=" 883 | "; for cw in ${lse_critical_writable}; do [ "$cw" = "$uw" ] && [ -w "$cw" ] && ls -l $cw; done ; done' \ 884 | "fst000" 885 | 886 | #can we write to directories that can give us root 887 | lse_test "fst170" "0" \ 888 | "Can we write to critical directories?" \ 889 | 'for uw in $lse_user_writable; do [ -d "$uw" ] && IFS=" 890 | "; for cw in ${lse_critical_writable_dirs}; do [ "$cw" = "$uw" ] && [ -w "$cw" ] && ls -ld $cw; done ; done' \ 891 | "fst000" 892 | 893 | #can we write to directories inside PATHS 894 | lse_test "fst180" "0" \ 895 | "Can we write to directories from PATH defined in /etc?" \ 896 | 'for ep in $lse_exec_paths; do [ -d "$ep" ] && [ -w "$ep" ] && ls -ld "$ep"; done' \ 897 | "usr070" 898 | 899 | #can we read backups 900 | lse_test "fst190" "0" \ 901 | "Can we read any backup?" \ 902 | 'find / $lse_find_opts -path /usr/lib -prune -o -path /usr/share -prune -o -regextype egrep -iregex ".*(backup|dump|cop(y|ies)|bak|bkp)[^/]*\.(sql|tgz|tar|zip)?\.?(gz|xz|bzip2|bz2|lz|7z)?" -readable -type f -exec ls -al {} \;' 903 | 904 | #are there possible credentials in any shell history files 905 | lse_test "fst200" "0" \ 906 | "Are there possible credentials in any shell history file?" \ 907 | 'for h in .bash_history .history .histfile .zhistory; do [ -f "$lse_home/$h" ] && grep $lse_grep_opts -Ei "(user|username|login|pass|password|pw|credentials)[=: ][a-z0-9]+" "$lse_home/$h" | grep -v "systemctl"; done' 908 | 909 | #nfs exports with no_root_squash 910 | lse_test "fst210" "0" \ 911 | "Are there NFS exports with 'no_root_squash' option?" \ 912 | 'grep $lse_grep_opts "no_root_squash" /etc/exports' 913 | 914 | #nfs exports with no_all_squash 915 | lse_test "fst220" "1" \ 916 | "Are there NFS exports with 'no_all_squash' option?" \ 917 | 'grep $lse_grep_opts "no_all_squash" /etc/exports' 918 | 919 | #files owned by user 920 | lse_test "fst500" "2" \ 921 | "Files owned by user '$lse_user'" \ 922 | 'find / $lse_find_opts -user $lse_user -type f -exec ls -al {} \;' \ 923 | "" "" "rootskip" 924 | 925 | #check for SSH files anywhere 926 | lse_test "fst510" "2" \ 927 | "SSH files anywhere" \ 928 | 'find / $lse_find_opts \( -name "*id_dsa*" -o -name "*id_rsa*" -o -name "*id_ecdsa*" -o -name "*id_ed25519*" -o -name "known_hosts" -o -name "authorized_hosts" -o -name "authorized_keys" \) -exec ls -la {} \;' 929 | 930 | #dump hosts.equiv file 931 | lse_test "fst520" "2" \ 932 | "Check hosts.equiv file and its contents" \ 933 | 'find /etc -iname hosts.equiv -exec ls -la {} 2>/dev/null \; -exec cat {} \;' 934 | 935 | #list nfs shares 936 | lse_test "fst530" "2" \ 937 | "List NFS server shares" \ 938 | 'ls -la /etc/exports 2>/dev/null && cat /etc/exports' 939 | 940 | #dump fstab 941 | lse_test "fst540" "2" \ 942 | "Dump fstab file" \ 943 | 'cat /etc/fstab' 944 | } 945 | #) 946 | 947 | #######################################################################( system 948 | lse_run_tests_system() { 949 | lse_header "sys" "system" 950 | 951 | #who is logged in 952 | lse_test "sys000" "2" \ 953 | "Who is logged in" \ 954 | 'w' 955 | 956 | #last logged in users 957 | lse_test "sys010" "2" \ 958 | "Last logged in users" \ 959 | 'last' 960 | 961 | #check if /etc/passwd has the hashes (old system) 962 | lse_test "sys020" "0" \ 963 | "Does the /etc/passwd have hashes?" \ 964 | 'grep -v "^[^:]*:[x]" /etc/passwd' 965 | 966 | #check if /etc/group has group password hashes (old system) 967 | lse_test "sys022" "0" \ 968 | "Does the /etc/group have hashes?" \ 969 | 'grep -v "^[^:]*:[x]" /etc/group' 970 | 971 | #check if we can read any shadow file 972 | lse_test "sys030" "0" \ 973 | "Can we read shadow files?" \ 974 | 'for sf in "shadow" "shadow-" "shadow~" "gshadow" "gshadow-" "master.passwd"; do [ -r "/etc/$sf" ] && printf "%s\n---\n" "/etc/$sf" && cat "/etc/$sf" && printf "\n\n";done' 975 | 976 | #check for superuser accounts 977 | lse_test "sys040" "1" \ 978 | "Check for other superuser accounts" \ 979 | 'for u in $(cut -d: -f1 /etc/passwd); do [ $(id -u $u) = 0 ] && echo $u; done | grep -v root' 980 | 981 | #can root log in via SSH 982 | lse_test "sys050" "1" \ 983 | "Can root user log in via SSH?" \ 984 | 'grep -E "^[[:space:]]*PermitRootLogin " /etc/ssh/sshd_config | grep -E "(yes|without-password|prohibit-password)"' 985 | 986 | #list available shells 987 | lse_test "sys060" "2" \ 988 | "List available shells" \ 989 | 'cat /etc/shells' 990 | 991 | #system umask 992 | lse_test "sys070" "2" \ 993 | "System umask in /etc/login.defs" \ 994 | 'grep "^UMASK" /etc/login.defs' 995 | 996 | #system password policies 997 | lse_test "sys080" "2" \ 998 | "System password policies in /etc/login.defs" \ 999 | 'grep "^PASS_MAX_DAYS\|^PASS_MIN_DAYS\|^PASS_WARN_AGE\|^ENCRYPT_METHOD" /etc/login.defs' 1000 | } 1001 | #) 1002 | 1003 | #####################################################################( security 1004 | lse_run_tests_security() { 1005 | lse_header "sec" "security" 1006 | 1007 | #check if selinux is present 1008 | lse_test "sec000" "1" \ 1009 | "Is SELinux present?" \ 1010 | 'sestatus' 1011 | 1012 | #get all binaries with capabilities 1013 | lse_test "sec010" "1" \ 1014 | "List files with capabilities" \ 1015 | 'getcap -r /' \ 1016 | "" \ 1017 | "lse_cap_bin" 1018 | 1019 | #check if we can write an a binary with capabilities 1020 | lse_test "sec020" "0" \ 1021 | "Can we write to a binary with caps?" \ 1022 | 'for b in $(printf "$lse_cap_bin\n" | cut -d" " -f1); do [ -w "$b" ] && echo "$b"; done' 1023 | 1024 | #check if we have all capabilities in any binary 1025 | lse_test "sec030" "0" \ 1026 | "Do we have all caps in any binary?" \ 1027 | 'printf "$lse_cap_bin\n" | grep -v "cap_"' 1028 | 1029 | #search /etc/security/capability.conf for users associated capapilies 1030 | lse_test "sec040" "1" \ 1031 | "Users with associated capabilities" \ 1032 | 'grep -v "^#\|none\|^$" /etc/security/capability.conf' \ 1033 | "" \ 1034 | "lse_user_caps" 1035 | 1036 | #does user have capabilities 1037 | lse_test "sec050" "0" \ 1038 | "Does current user have capabilities?" \ 1039 | 'printf "$lse_user_caps\n" | grep "$lse_user"' \ 1040 | "sec040" 1041 | 1042 | #can user read the auditd log 1043 | lse_test "sec060" "0" \ 1044 | "Can we read the auditd log?" \ 1045 | 'al=/var/log/audit/audit.log; test -r "$al" && echo "tail $al:" && echo && tail "$al"' 1046 | } 1047 | #) 1048 | 1049 | ##############################################################( recurrent tasks 1050 | lse_run_tests_recurrent_tasks() { 1051 | lse_header "ret" "recurrent tasks" 1052 | 1053 | ## CRON 1054 | #user crontab 1055 | lse_test "ret000" "1" \ 1056 | "User crontab" \ 1057 | 'crontab -l | grep -Ev "^#"' 1058 | 1059 | #cron tasks writable by user 1060 | lse_test "ret010" "0" \ 1061 | "Cron tasks writable by user" \ 1062 | 'find -L /etc/cron* /etc/anacron /var/spool/cron -writable' 1063 | 1064 | #list cron jobs 1065 | lse_test "ret020" "1" \ 1066 | "Cron jobs" \ 1067 | 'grep -ERv "^(#|$)" /etc/crontab /etc/cron.d/ /etc/anacrontab' 1068 | 1069 | #can we read other user crontabs? 1070 | lse_test "ret030" "1" \ 1071 | "Can we read user crontabs" \ 1072 | 'ls -la /var/spool/cron/crontabs/*' 1073 | 1074 | #can we list other user cron tasks? (you need privileges for this, so if you can something is fishy) 1075 | lse_test "ret040" "1" \ 1076 | "Can we list other user cron tasks?" \ 1077 | 'for u in $(cut -d: -f 1 /etc/passwd); do [ "$u" != "$lse_user" ] && crontab -l -u "$u"; done' 1078 | 1079 | #can we write to any paths present in cron tasks? 1080 | lse_test "ret050" "1" \ 1081 | "Can we write to any paths present in cron jobs" \ 1082 | 'for p in `grep --color=never -hERoi "/[a-z0-9_/\.\-]+" /etc/cron* | grep -Ev "/dev/(null|zero|random|urandom)" | sort -u`; do [ -w "$p" ] && echo "$p"; done' \ 1083 | "" \ 1084 | "lse_user_writable_cron_paths" 1085 | 1086 | #can we write to executable paths present in cron tasks? 1087 | lse_test "ret060" "0" \ 1088 | "Can we write to executable paths present in cron jobs" \ 1089 | 'for uwcp in $lse_user_writable_cron_paths; do [ -w "$uwcp" ] && [ -x "$uwcp" ] && grep $lse_grep_opts -R "$uwcp" /etc/crontab /etc/cron.d/ /etc/anacrontab ; done' \ 1090 | "ret050" 1091 | 1092 | #list cron files 1093 | lse_test "ret400" "2" \ 1094 | "Cron files" \ 1095 | 'ls -la /etc/cron*' 1096 | 1097 | 1098 | ## Systemd Timers 1099 | #user timers 1100 | lse_test "ret500" "1" \ 1101 | "User systemd timers" \ 1102 | 'systemctl --user list-timers --all | grep -iq "\.timer" && systemctl --user list-timers --all' 1103 | 1104 | #can we write in any system timer? 1105 | lse_test "ret510" "0" \ 1106 | "Can we write in any system timer?" \ 1107 | 'printf "$lse_user_writable\n" | grep -E "\.timer$"' \ 1108 | "fst000" 1109 | 1110 | #system timers 1111 | lse_test "ret900" "2" \ 1112 | "Systemd timers" \ 1113 | 'systemctl list-timers --all' 1114 | } 1115 | #) 1116 | 1117 | ######################################################################( network 1118 | lse_run_tests_network() { 1119 | lse_header "net" "network" 1120 | 1121 | #services listening only on localhost 1122 | lse_test "net000" "1" \ 1123 | "Services listening only on localhost" \ 1124 | '(ss -tunlp || netstat -tunlp)2>/dev/null | grep "127.0.0.1:"' 1125 | 1126 | #can we execute tcpdump 1127 | lse_test "net010" "0" \ 1128 | "Can we sniff traffic with tcpdump?" \ 1129 | '(tcpdump -i lo -n 2>&1 & pid=$!;sleep 0.2;kill $pid)2>/dev/null | grep -i "listening on lo"' 1130 | 1131 | #nic information 1132 | lse_test "net500" "2" \ 1133 | "NIC and IP information" \ 1134 | 'ifconfig -a || ip a' 1135 | 1136 | #routing table 1137 | lse_test "net510" "2" \ 1138 | "Routing table" \ 1139 | 'route -n || ip r' 1140 | 1141 | #arp table 1142 | lse_test "net520" "2" \ 1143 | "ARP table" \ 1144 | 'arp -an || ip n' 1145 | 1146 | #nameservers 1147 | lse_test "net530" "2" \ 1148 | "Nameservers" \ 1149 | 'grep "nameserver" /etc/resolv.conf' 1150 | 1151 | #systemd nameservers 1152 | lse_test "net540" "2" \ 1153 | "Systemd Nameservers" \ 1154 | 'systemd-resolve --status || systemd-resolve --user --status' 1155 | 1156 | #listening TCP 1157 | lse_test "net550" "2" \ 1158 | "Listening TCP" \ 1159 | 'netstat -tnlp || ss -tnlp' 1160 | 1161 | #listening UDP 1162 | lse_test "net560" "2" \ 1163 | "Listening UDP" \ 1164 | 'netstat -unlp || ss -unlp' 1165 | } 1166 | #) 1167 | 1168 | #####################################################################( services 1169 | lse_run_tests_services() { 1170 | lse_header "srv" "services" 1171 | 1172 | ## System-V 1173 | #check write permissions in init.d/* inetd.conf xinetd.conf 1174 | lse_test "srv000" "0" \ 1175 | "Can we write in service files?" \ 1176 | 'printf "$lse_user_writable\n" | grep -E "^/etc/(init/|init\.d/|rc\.d/|rc[0-9S]\.d/|rc\.local|inetd\.conf|xinetd\.conf|xinetd\.d/)"' \ 1177 | "fst000" 1178 | 1179 | #check write permissions for binaries involved in services 1180 | lse_test "srv010" "0" \ 1181 | "Can we write in binaries executed by services?" \ 1182 | 'for b in $(grep -ERvh "^#" /etc/inetd.conf /etc/xinetd.conf /etc/xinetd.d/ /etc/init.d/ /etc/rc* 2>/dev/null | tr -s "[[:space:]]" "\n" | grep -E "^/" | grep -Ev "^/(dev|run|sys|proc|tmp)/" | sort -u); do [ -x "$b" ] && [ -w "$b" ] && echo "$b" done' 1183 | 1184 | #init.d files NOT belonging to root 1185 | lse_test "srv020" "1" \ 1186 | "Files in /etc/init.d/ not belonging to root" \ 1187 | 'find /etc/init.d/ \! -uid 0 -type f | xargs -r ls -la' 1188 | 1189 | #rc.d/init.d files NOT belonging to root! 1190 | lse_test "srv030" "1" \ 1191 | "Files in /etc/rc.d/init.d not belonging to root" \ 1192 | 'find /etc/rc.d/init.d \! -uid 0 -type f | xargs -r ls -la' 1193 | 1194 | # upstart scripts not belonging to root 1195 | lse_test "srv040" "1" \ 1196 | "Upstart files not belonging to root" \ 1197 | 'find /etc/init \! -uid 0 -type f | xargs -r ls -la' 1198 | 1199 | #/usr/local/etc/rc.d files NOT belonging to root! 1200 | lse_test "srv050" "1" \ 1201 | "Files in /usr/local/etc/rc.d not belonging to root" \ 1202 | 'find /usr/local/etc/rc.d \! -uid 0 -type f | xargs -r ls -la' 1203 | 1204 | #contents of inetd.conf 1205 | lse_test "srv400" "2" \ 1206 | "Contents of /etc/inetd.conf" \ 1207 | 'cat /etc/inetd.conf' 1208 | 1209 | #xinetd info 1210 | lse_test "srv410" "2" \ 1211 | "Contents of /etc/xinetd.conf" \ 1212 | 'cat /etc/xinetd.conf' 1213 | 1214 | #check xinetd.d and permissions 1215 | lse_test "srv420" "2" \ 1216 | "List /etc/xinetd.d if used" \ 1217 | 'grep "/etc/xinetd.d" /etc/xinetd.conf ; ls -la /etc/xinetd.d' 1218 | 1219 | #permissions of init.d scripts 1220 | lse_test "srv430" "2" \ 1221 | "List /etc/init.d/ permissions" \ 1222 | 'ls -la /etc/init.d' 1223 | 1224 | #rc.d/init.d permissions 1225 | lse_test "srv440" "2" \ 1226 | "List /etc/rc.d/init.d permissions" \ 1227 | 'ls -la /etc/rc.d/init.d' 1228 | 1229 | #usr/rc.d permissions 1230 | lse_test "srv450" "2" \ 1231 | "List /usr/local/etc/rc.d permissions" \ 1232 | 'ls -la /usr/local/etc/rc.d' 1233 | 1234 | # init permissions 1235 | lse_test "srv460" "2" \ 1236 | "List /etc/init/ permissions" \ 1237 | 'ls -la /etc/init/' 1238 | 1239 | ## Systemd 1240 | #check write permissions in systemd services 1241 | lse_test "srv500" "0" \ 1242 | "Can we write in systemd service files?" \ 1243 | 'printf "$lse_user_writable\n" | grep -E "^/(etc/systemd/|lib/systemd/).+\.service$"' \ 1244 | "fst000" 1245 | 1246 | #check write permissions for binaries involved in systemd services 1247 | lse_test "srv510" "0" \ 1248 | "Can we write in binaries executed by systemd services?" \ 1249 | 'for b in $(grep -ERh "^Exec" /etc/systemd/ /lib/systemd/ 2>/dev/null | tr "=" "\n" | tr -s "[[:space:]]" "\n" | grep -E "^/" | grep -Ev "^/(dev|run|sys|proc|tmp)/" | sort -u); do [ -x "$b" ] && [ -w "$b" ] && echo "$b" done' 1250 | 1251 | # systemd files not belonging to root 1252 | lse_test "srv520" "1" \ 1253 | "Systemd files not belonging to root" \ 1254 | 'find /lib/systemd/ /etc/systemd \! -uid 0 -type f | xargs -r ls -la' 1255 | 1256 | # systemd permissions 1257 | lse_test "srv900" "2" \ 1258 | "Systemd config files permissions" \ 1259 | 'ls -lthR /lib/systemd/ /etc/systemd/' 1260 | } 1261 | #) 1262 | 1263 | #####################################################################( software 1264 | lse_run_tests_software() { 1265 | lse_header "sof" "software" 1266 | 1267 | #checks to see if root/root will get us a connection 1268 | lse_test "sof000" "0" \ 1269 | "Can we connect to MySQL with root/root credentials?" \ 1270 | 'mysqladmin -uroot -proot version' 1271 | 1272 | #checks to see if we can connect as root without password 1273 | lse_test "sof010" "0" \ 1274 | "Can we connect to MySQL as root without password?" \ 1275 | 'mysqladmin -uroot version' 1276 | 1277 | #check if there are credentials stored in .mysql-history 1278 | lse_test "sof015" "0" \ 1279 | "Are there credentials in mysql_history file?" \ 1280 | 'grep -Ei "(pass|identified by|md5\()" "$lse_home/.mysql_history"' 1281 | 1282 | #checks to see if we can connect to postgres templates without password 1283 | lse_test "sof020" "0" \ 1284 | "Can we connect to PostgreSQL template0 as postgres and no pass?" \ 1285 | 'psql -U postgres template0 -c "select version()" | grep version' 1286 | lse_test "sof020" "0" \ 1287 | "Can we connect to PostgreSQL template1 as postgres and no pass?" \ 1288 | 'psql -U postgres template1 -c "select version()" | grep version' 1289 | lse_test "sof020" "0" \ 1290 | "Can we connect to PostgreSQL template0 as psql and no pass?" \ 1291 | 'psql -U pgsql template0 -c "select version()" | grep version' 1292 | lse_test "sof020" "0" \ 1293 | "Can we connect to PostgreSQL template1 as psql and no pass?" \ 1294 | 'psql -U pgsql template1 -c "select version()" | grep version' 1295 | 1296 | #installed apache modules 1297 | lse_test "sof030" "1" \ 1298 | "Installed apache modules" \ 1299 | 'apache2ctl -M; httpd -M' 1300 | 1301 | #find htpassword files 1302 | lse_test "sof040" "0" \ 1303 | "Found any .htpasswd files?" \ 1304 | 'find / $lse_find_opts -name "*.htpasswd" -print -exec cat {} \;' 1305 | 1306 | #check if there are ssh private keys in ssh-agent 1307 | lse_test "sof050" "0" \ 1308 | "Are there private keys in ssh-agent?" \ 1309 | 'ssh-add -l | grep -iv "agent has no identities"' 1310 | 1311 | #check if there are gpg keys in gpg-agent 1312 | lse_test "sof060" "0" \ 1313 | "Are there gpg keys cached in gpg-agent?" \ 1314 | 'gpg-connect-agent "keyinfo --list" /bye | grep "D - - 1"' 1315 | 1316 | #check if there is a writable ssh-agent socket 1317 | lse_test "sof070" "0" \ 1318 | "Can we write to a ssh-agent socket?" \ 1319 | 'for f in $lse_user_writable; do test -S "$f" && printf "$f" | grep -Ea "ssh-[A-Za-z0-9]+/agent\.[0-9]+"; done' \ 1320 | "fst000" 1321 | 1322 | #check if there is a writable gpg-agent socket 1323 | lse_test "sof080" "0" \ 1324 | "Can we write to a gpg-agent socket?" \ 1325 | 'for f in $lse_user_writable; do test -S "$f" && printf "$f" | grep -a "gpg-agent"; done' \ 1326 | "fst000" 1327 | 1328 | #find keepass database files 1329 | lse_test "sof090" "0" \ 1330 | "Found any keepass database files?" \ 1331 | 'find / $lse_find_opts -regextype egrep -iregex ".*\.kdbx?" -readable -type f -print' 1332 | 1333 | #find pass database files 1334 | lse_test "sof100" "0" \ 1335 | "Found any 'pass' store directories?" \ 1336 | 'find / $lse_find_opts -name ".password-store" -readable -type d -print' 1337 | 1338 | #check if any tmux session is active 1339 | lse_test "sof110" "0" \ 1340 | "Are there any tmux sessions available?" \ 1341 | 'tmux list-sessions' 1342 | 1343 | #check for all tmux sessions for other users 1344 | lse_test "sof120" "1" \ 1345 | "Are there any tmux sessions from other users?" \ 1346 | 'find /tmp -type d -regex "/tmp/tmux-[0-9]+" ! -user $lse_user' 1347 | 1348 | #check if we have write access to other users tmux sessions 1349 | lse_test "sof130" "0" \ 1350 | "Can we write to tmux session sockets from other users?" \ 1351 | 'find /tmp -writable -type s -regex "/tmp/tmux-[0-9]+/.+" ! -user $lse_user -exec ls -l {} +' 1352 | 1353 | #check if there is any active screen session 1354 | lse_test "sof140" "0" \ 1355 | "Are any screen sessions available?" \ 1356 | 'screen -ls >/dev/null && screen -ls' 1357 | 1358 | #find other users screen sessions 1359 | lse_test "sof150" "1" \ 1360 | "Are there any screen sessions from other users?" \ 1361 | 'find /run/screen -type d -regex "/run/screen/S-.+" ! -user $lse_user' 1362 | 1363 | #find writable screen session sockets from other users 1364 | lse_test "sof160" "0" \ 1365 | "Can we write to screen session sockets from other users?" \ 1366 | 'find /run/screen -type s -writable -regex "/run/screen/S-.+/.+" ! -user $lse_user -exec ls -l {} +' 1367 | 1368 | #check connection to mongoDB 1369 | lse_test "sof170" "1" \ 1370 | "Can we access MongoDB databases without credentials?" \ 1371 | 'echo "show dbs" | mongo --quiet | grep -E "(admin|config|local)"' 1372 | 1373 | #find kerberos credentials 1374 | lse_test "sof180" "0" \ 1375 | "Can we access any Kerberos credentials?" \ 1376 | 'find / $lse_find_opts -name "*.so" -prune -o \( -name "krb5cc*" -o -name "*.ccache" -o -name "*.kirbi" -o -name "*.keytab" \) -type f -readable -exec ls -lh {} +' 1377 | 1378 | #sudo version - check to see if there are any known vulnerabilities with this 1379 | lse_test "sof500" "2" \ 1380 | "Sudo version" \ 1381 | 'sudo -V | grep "Sudo version"' 1382 | 1383 | #mysql details - if installed 1384 | lse_test "sof510" "2" \ 1385 | "MySQL version" \ 1386 | 'mysql --version' 1387 | 1388 | #postgres details - if installed 1389 | lse_test "sof520" "2" \ 1390 | "Postgres version" \ 1391 | 'psql -V' 1392 | 1393 | #apache details - if installed 1394 | lse_test "sof530" "2" \ 1395 | "Apache version" \ 1396 | 'apache2 -v; httpd -v' 1397 | 1398 | #check tmux version 1399 | lse_test "sof540" "2" \ 1400 | "Tmux version" \ 1401 | 'tmux -V' 1402 | 1403 | #check screen version 1404 | lse_test "sof550" "2" \ 1405 | "Screen version" \ 1406 | 'screen -v' 1407 | 1408 | } 1409 | #) 1410 | 1411 | ###################################################################( containers 1412 | lse_run_tests_containers() { 1413 | lse_header "ctn" "containers" 1414 | 1415 | #check to see if we are in a docker container 1416 | lse_test "ctn000" "1" \ 1417 | "Are we in a docker container?" \ 1418 | 'grep -i docker /proc/self/cgroup; find / $lse_find_opts -name "*dockerenv*" -exec ls -la {} \;' 1419 | 1420 | #check to see if current host is running docker services 1421 | lse_test "ctn010" "1" \ 1422 | "Is docker available?" \ 1423 | 'docker --version; docker ps -a; docker images' 1424 | 1425 | #is user a member of the docker group 1426 | lse_test "ctn020" "0" \ 1427 | "Is the user a member of the 'docker' group?" \ 1428 | 'groups | grep -o docker' 1429 | 1430 | #check to see if we are in an lxc container 1431 | lse_test "ctn200" "1" \ 1432 | "Are we in a lxc container?" \ 1433 | 'grep -a container=lxc /proc/1/environ | tr -d "\0"' 1434 | 1435 | #is user a member of any lxd/lxc group 1436 | lse_test "ctn210" "0" \ 1437 | "Is the user a member of any lxc/lxd group?" \ 1438 | 'groups | grep $lse_grep_opts "lxc\|lxd"' 1439 | } 1440 | #) 1441 | 1442 | ####################################################################( processes 1443 | lse_run_tests_processes() { 1444 | lse_header "pro" "processes" 1445 | 1446 | #wait for the process monitor to finish gathering data 1447 | lse_test "pro000" "2" \ 1448 | "Waiting for the process monitor to finish" \ 1449 | 'while [ ! -s "$lse_procmon_data" ]; do sleep 1; done; cat "$lse_procmon_data"'\ 1450 | "" \ 1451 | "lse_procs" 1452 | 1453 | #look for the paths of the process binaries 1454 | lse_test "pro001" "2" \ 1455 | "Retrieving process binaries" \ 1456 | 'printf "%s" "$lse_procs" | cut -d" " -f5 | sort -u | xargs -r which' \ 1457 | "pro000" \ 1458 | 'lse_proc_bin' 1459 | 1460 | #look for the users running the 1461 | lse_test "pro002" "2" \ 1462 | "Retrieving process users" \ 1463 | 'printf "%s" "$lse_procs" | cut -d" " -f4 | sort -u' \ 1464 | "pro000" \ 1465 | 'lse_proc_users' 1466 | 1467 | #check if we have write permissions in any process binary 1468 | lse_test "pro010" "0" \ 1469 | "Can we write in any process binary?" \ 1470 | 'for b in $lse_proc_bin; do [ -w "$b" ] && echo $b; done'\ 1471 | "pro001" 1472 | 1473 | #list processes running as root 1474 | lse_test "pro020" "1" \ 1475 | "Processes running with root permissions" \ 1476 | 'printf "%s" "$lse_procs" | grep -E "^[^ ]+ [^ ]+ [^ ]+ root" | lse_proc_print' \ 1477 | "pro000" 1478 | 1479 | #list processes running as users with shell 1480 | lse_test "pro030" "1" \ 1481 | "Processes running by non-root users with shell" \ 1482 | 'for user in `printf "%s\n" "$lse_shell_users" | cut -d: -f1 | grep -v root`; do printf "%s" "$lse_proc_users" | grep -qE "(^| )$user( |\$)" && printf "\n\n------ $user ------\n\n\n" && printf "%s" "$lse_procs" | grep -E "^[^ ]+ [^ ]+ [^ ]+ $user" | lse_proc_print; done' \ 1483 | "usr030 pro000 pro002" 1484 | 1485 | #running processes 1486 | lse_test "pro500" "2" \ 1487 | "Running processes" \ 1488 | 'printf "%s\n" "$lse_procs" | lse_proc_print' \ 1489 | "pro000" 1490 | 1491 | #list running process binaries and their permissions 1492 | lse_test "pro510" "2" \ 1493 | "Running process binaries and permissions" \ 1494 | 'printf "%s\n" "$lse_proc_bin" | xargs ls -l' \ 1495 | "pro001" 1496 | } 1497 | #) 1498 | 1499 | #########################################################################( CVEs 1500 | lse_run_tests_cves() { 1501 | lse_header "cve" "CVEs" 1502 | if [ "${#lse_cve_list}" = 1 ]; then 1503 | if [ -z "$lse_selection" ] || printf "%s" "$lse_selection" | grep -iq 'cve'; then 1504 | printf "%s\n%s\n%s" \ 1505 | " In order to test for CVEs, download lse.sh from the GitHub releases page." \ 1506 | " Alternatively, build lse_cve.sh using tools/package_cvs_into_lse.sh from the" \ 1507 | " repository." 1508 | fi 1509 | else 1510 | for lse_cve in $lse_cve_list; do 1511 | eval "$(printf '%s' "$lse_cve" | base64 -d | gunzip -c)" 1512 | 1513 | lse_test "$lse_cve_id" "$lse_cve_level" \ 1514 | "$lse_cve_description" \ 1515 | "lse_cve_test" 1516 | done 1517 | fi 1518 | } 1519 | #) 1520 | # 1521 | ##) 1522 | 1523 | #( Main 1524 | main() { 1525 | while getopts "hcCil:e:p:s:S" option; do 1526 | case "${option}" in 1527 | c) lse_color=false; lse_grep_opts='--color=never';; 1528 | C) lse_alt_color=true;; 1529 | e) lse_exclude_paths "${OPTARG}";; 1530 | i) lse_interactive=false;; 1531 | l) lse_set_level "${OPTARG}";; 1532 | s) lse_selection="`printf \"%s\" \"${OPTARG}\"|sed 's/,/ /g'`";; 1533 | p) lse_proc_time="${OPTARG}";; 1534 | S) lse_serve; exit $?;; 1535 | h) lse_help; exit 0;; 1536 | *) lse_help; exit 1;; 1537 | esac 1538 | done 1539 | 1540 | #trap to exec on SIGINT 1541 | trap "lse_exit 1" 2 1542 | 1543 | # use alternative color scheme 1544 | $lse_alt_color && lse_recolor 1545 | 1546 | lse_request_information 1547 | lse_show_info 1548 | PATH="$PATH:/sbin:/usr/sbin" #fix path just in case 1549 | lse_distro_codename=`lse_get_distro_codename` 1550 | 1551 | lse_procmon & 1552 | (sleep "$lse_proc_time"; rm -f "$lse_procmon_lock") & 1553 | 1554 | ## NO WAR 1555 | lse_header "nowar" "humanity" 1556 | lse_test "nowar0" "0" \ 1557 | 'Should we question autocrats and their "military operations"?' \ 1558 | 'cecho " $black$b_blue NO $reset\n $black$b_yellow WAR $reset"' 1559 | 1560 | lse_run_tests_users 1561 | lse_run_tests_sudo 1562 | lse_run_tests_filesystem 1563 | lse_run_tests_system 1564 | lse_run_tests_security 1565 | lse_run_tests_recurrent_tasks 1566 | lse_run_tests_network 1567 | lse_run_tests_services 1568 | lse_run_tests_software 1569 | lse_run_tests_containers 1570 | lse_run_tests_processes 1571 | lse_run_tests_cves 1572 | 1573 | lse_exit 0 1574 | } 1575 | 1576 | [ ! "$lse_NO_EXEC" ] && main "$@" 1577 | #) 1578 | -------------------------------------------------------------------------------- /screenshots/lse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego-treitos/linux-smart-enumeration/eb80976b1d5e4325894644e264d9f91782f29f50/screenshots/lse.gif -------------------------------------------------------------------------------- /screenshots/lse.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego-treitos/linux-smart-enumeration/eb80976b1d5e4325894644e264d9f91782f29f50/screenshots/lse.webm -------------------------------------------------------------------------------- /screenshots/lse_level0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego-treitos/linux-smart-enumeration/eb80976b1d5e4325894644e264d9f91782f29f50/screenshots/lse_level0.png -------------------------------------------------------------------------------- /screenshots/lse_level1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego-treitos/linux-smart-enumeration/eb80976b1d5e4325894644e264d9f91782f29f50/screenshots/lse_level1.png -------------------------------------------------------------------------------- /screenshots/lse_level2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego-treitos/linux-smart-enumeration/eb80976b1d5e4325894644e264d9f91782f29f50/screenshots/lse_level2.png -------------------------------------------------------------------------------- /tools/package_cvs_into_lse.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # vim: set ts=2 sw=2 sts=2 et: 3 | 4 | #( options 5 | new_lse="lse_cve.sh" 6 | lse_cve_list_marker='#CVElistMARKER' 7 | #) 8 | 9 | #( lib 10 | do_check() { 11 | [ -d "./cve" ] && [ -f "./lse.sh" ] && return 0 12 | echo "Error: Run this script from the main repository directory" 13 | exit 1 14 | } 15 | do_strip_script() { 16 | local script_path="$1" 17 | env "BASH_FUNC_tmp_%%=() { 18 | $(<$script_path) 19 | }" bash --posix -c 'declare -f tmp_' | tail -n+3 | head -n -1 | sed 's/^[[:space:]]\+\(.*\)/\1/g' 20 | } 21 | #) 22 | 23 | #( main 24 | do_check 25 | 26 | [ -f "$new_lse" ] && rm -f "$new_lse" 27 | cp "lse.sh" "$new_lse" 28 | 29 | for f in cve/cve-*.sh; do 30 | cve_code=$(do_strip_script "$f" | gzip -c | base64 -w0) 31 | sed -i "s|.*${lse_cve_list_marker}.*|${cve_code}\n\" ${lse_cve_list_marker}|g" "$new_lse" 32 | done 33 | #) 34 | 35 | --------------------------------------------------------------------------------