├── 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 | 
92 |
93 | ### Level 0 (default) output sample
94 |
95 | 
96 |
97 | ### Level 1 verbosity output sample
98 |
99 | 
100 |
101 | ### Level 2 verbosity output sample
102 |
103 | 
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 |
--------------------------------------------------------------------------------