-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathLinEnum-ng.sh
More file actions
1963 lines (1702 loc) · 96 KB
/
Copy pathLinEnum-ng.sh
File metadata and controls
1963 lines (1702 loc) · 96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/bash
# Color codes
CYAN="\033[0;36m"
RED="\033[0;31m"
LRED="\033[1;31m"
GREEN="\033[0;32m"
LBLUE="\033[1;34m"
LMAGENTA="\033[1;35m"
YELLOW="\033[0;33m"
# Banner's
BOLD='\033[1m'
BGREEN='\033[38;5;46m'
NC="\033[0m"
WHITE='\033[38;5;231m'
# Banner
echo -e "${WHITE}"
echo " ▃▄▅█████████▅▄▃"
echo " ▁▂▇███████████████▇▂▁"
echo " ▃▆███████████████████▆▃"
echo " ▄█▆▁▁▁▃▇███████▇▃▁▁▁██▅"
echo " ▅▇▆ ▅▆▄▂███████▃▄▆▆ ▃▇█▅"
echo " ▇█▆ ▄▄▃▁██▃▄███▃▄▆▇ ▆█▆"
echo " ▇█▆ ▂▅▄▂▁▁▄██▆▂▁▁ ▂▆█▆"
echo " ▇██▅▁▁ ▁▃▆▃▃▆█▃▁ ▁▆▇██▆"
echo " ▄█████▅▂ ▃▅▄ ▂▅▇████▇▄"
echo " ▁▂███████▇▆▆▆▆▆▆▆▆▆▆▇████████▂▁"
echo " ▂▅███████▄▂ ▂▃▄███████▆▃"
echo " ▂▅██████▅ ▃▅██████▆▂"
echo " ▁▆██████▅ ▁▅██████▆▂"
echo " ▇██████▄ ▄███████"
echo " ▁███████▃▁ ▁▃███████▁"
echo " ▂▆██████▃▁ ▂▃██████▆▂"
echo " ▃███████▁ ▁███████▃"
echo " ▃██████▇▁ ████████▄"
echo " ▄██████▇ ████████▄"
echo " ▄█████▅▂ ▅▇██████▄"
echo -e " ▄█████▅ ${BGREEN}${BOLD}LinEnum-ng: ${WHITE}1.0.1${NC}${WHITE} ▇██████▄"
echo -e " ▄█████▅ ${BGREEN}${BOLD}Developed by: ${WHITE}Strikoder${NC}${WHITE} ▇██████▄"
echo " ▄█████▅ ▇██████▄"
echo " ▄█████▅ ▇██████▄"
echo " ▄███▅▇▅ ▇█▅▁███▄"
echo " ▁▃▆▆▁▆▅ ▃▇█▅▁▆▆▃▁"
echo " ▂▄▅ ██▅▂"
echo " ▄█ ▁██▄"
echo " ▁▂▇▁ ▃▅▇█▃▁"
echo " ▁▄▅▂▁ ▁▃▆█▃▁"
echo " ▅█▆▄▃ ▃▄▄▁▃▃▁▁▂▄▄▇▇▆▇▄▄▇██▅"
echo " ▂▄▆▆▂▄▇▇▇▇██▇▇▇███▇▅▂▆██▇▄▂"
echo " ▁▅▄▄▅▄ ▁▅█████████▅▂ ▁ ▄▇▇▅█▅▂"
echo " ▄█▄▃▇█▇▄▇█▆▆████████▄▄▅█▃▃▇█████▅▃▃"
echo " ▁▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▃▂▂▂"
echo -e "${NC}"
echo -e "\033[1;31;103mPrivilege Escalation Vector\033[0m"
# ============================================================================
# ARGUMENT PARSING
# ============================================================================
PASSWORD=""
USERNAME=""
HUNT_USERS=0
CLOUD=0
SSH_HUNT=0
# Handle long options before getopts (getopts doesn't support them).
# Recognized long options are consumed here; any remaining args are passed
# through to getopts below via the rebuilt "$@".
_args=()
for arg in "$@"; do
case "$arg" in
--help|-h)
echo -e "${LBLUE}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${LBLUE}║ LinEnum-ng - Usage & Help ║${NC}"
echo -e "${LBLUE}╚═══════════════════════════════════════════════════════════╝${NC}"
echo -e ""
echo -e "${WHITE}Usage:${NC}"
echo -e " ${CYAN}$0 [OPTIONS]${NC}"
echo -e ""
echo -e "${WHITE}Options:${NC}"
echo -e " ${CYAN}-p PASSWORD${NC} Supply a known password to test sudo access with credentials."
echo -e " Without this, only passwordless sudo is checked."
echo -e ""
echo -e " ${CYAN}-u USERNAME${NC} Target a specific username to hunt across the filesystem."
echo -e " Searches for files named after the user and files"
echo -e " containing the username in their content."
echo -e ""
echo -e " ${CYAN}--hunt-users${NC} Cross-reference every login-shell user from /etc/passwd"
echo -e " against config/web/app directories. Powerful, but can be"
echo -e " slow on large boxes, so it is OFF by default and only runs"
echo -e " when this flag is supplied."
echo -e ""
echo -e " ${CYAN}--cloud${NC} Sweep all of /home and /root for cloud credentials"
echo -e " (AWS keys, and so on). Without it, only the usual spots"
echo -e " like ~/.aws are checked."
echo -e ""
echo -e " ${CYAN}--ssh${NC} Sweep all of /home and /root for private keys by content,"
echo -e " catching keys stored under any filename. Without it, only"
echo -e " the standard key locations are checked."
echo -e ""
echo -e " ${CYAN}--full${NC} Turn on every slow check at once: --cloud, --ssh and"
echo -e " --hunt-users. Use when time is not a concern."
echo -e ""
echo -e " ${CYAN}-h, --help${NC} Show this help message and exit."
echo -e ""
echo -e "${WHITE}Examples:${NC}"
echo -e " ${CYAN}$0${NC}"
echo -e " ${YELLOW} Run a full enumeration with no credentials (passwordless only).${NC}"
echo -e ""
echo -e " ${CYAN}$0 -p 'Summer2024!'${NC}"
echo -e " ${YELLOW} Run enumeration and test sudo access using the provided password.${NC}"
echo -e ""
echo -e " ${CYAN}$0 -u john${NC}"
echo -e " ${YELLOW} Run enumeration and hunt all files related to user 'john'.${NC}"
echo -e ""
echo -e " ${CYAN}$0 -p 'Summer2024!' -u john${NC}"
echo -e " ${YELLOW} Full run: test sudo with password AND hunt files for user 'john'.${NC}"
echo -e " ${YELLOW} Useful after finding credentials during an engagement.${NC}"
echo -e ""
echo -e " ${CYAN}$0 -p 'rockyou' -u admin${NC}"
echo -e " ${YELLOW} Check if 'rockyou' grants sudo rights, and search for 'admin' artifacts.${NC}"
echo -e ""
echo -e " ${CYAN}$0 --hunt-users${NC}"
echo -e " ${YELLOW} Full run plus the (slower) login-shell user cross-reference hunt.${NC}"
echo -e ""
echo -e " ${CYAN}$0 --full${NC}"
echo -e " ${YELLOW} Everything, every slow sweep on. Best when you have time to spare.${NC}"
echo -e ""
exit 0
;;
--hunt-users)
HUNT_USERS=1
;;
--cloud)
CLOUD=1
;;
--ssh)
SSH_HUNT=1
;;
--full)
# one switch for every slow check, including ones added later
HUNT_USERS=1
CLOUD=1
SSH_HUNT=1
;;
*)
_args+=("$arg")
;;
esac
done
# Rebuild positional parameters with long options stripped out, so getopts
# only sees the short options it understands.
set -- "${_args[@]}"
while getopts ":p:u:" opt; do
case $opt in
p)
PASSWORD="$OPTARG"
;;
u)
USERNAME="$OPTARG"
;;
\?)
echo -e "${RED}[-] Invalid option: -$OPTARG${NC}" >&2
echo -e "${YELLOW} Run '$0 --help' for usage information.${NC}" >&2
;;
:)
echo -e "${RED}[-] Option -$OPTARG requires an argument.${NC}" >&2
echo -e "${YELLOW} Run '$0 --help' for usage information.${NC}" >&2
;;
esac
done
if [ -n "$PASSWORD" ]; then
echo -e "\n${LMAGENTA}[*] Password provided via -p, will use for sudo -l check${NC}"
else
echo -e "\n${YELLOW}[*] No password provided. Tip: run with -p '<password>' to also check sudo with credentials.${NC}"
fi
if [ -n "$USERNAME" ]; then
echo -e "${LMAGENTA}[*] Username target: ${WHITE}$USERNAME${NC}${LMAGENTA}, will hunt files by name and content${NC}"
fi
if [ "$HUNT_USERS" = "1" ]; then
echo -e "${LMAGENTA}[*] --hunt-users enabled, will cross-reference login-shell users against config/web/app dirs (may be slow)${NC}"
fi
if [ "$CLOUD" = "1" ]; then
echo -e "${LMAGENTA}[*] --cloud enabled, will sweep /home and /root for cloud credentials (may be slow)${NC}"
fi
if [ "$SSH_HUNT" = "1" ]; then
echo -e "${LMAGENTA}[*] --ssh enabled, will sweep /home and /root for private keys by content (may be slow)${NC}"
fi
# ============================================================================
# BASIC SYSTEM INFO
# ============================================================================
echo -e "${LBLUE}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${LBLUE}║ BASIC SYSTEM INFORMATION ║${NC}"
echo -e "${LBLUE}╚═══════════════════════════════════════════════════════════╝${NC}"
echo -e "\n${YELLOW}[+] ${NC}Current user and groups:"
id 2>/dev/null
echo -e "\n${YELLOW}[+] ${NC}Hostname:"
hostname 2>/dev/null
echo -e "\n${YELLOW}[+] ${NC}Kernel version (check manually for exploits):"
uname -r
kernel_version=$(uname -r)
echo -e "\n${YELLOW}[+] ${NC}Full system information:"
uname -a 2>/dev/null
echo -e "\n${YELLOW}[+] ${NC}OS Release:"
cat /etc/os-release 2>/dev/null | grep PRETTY_NAME
echo -e "\n${YELLOW}[+] ${NC}Current shell:"
echo $SHELL
echo -e "\n${YELLOW}[+] ${NC}Uptime:"
uptime 2>/dev/null | sed 's/^ *//'
# ============================================================================
# KERNEL EXPLOIT CHECK
# ============================================================================
echo -e "\n${LBLUE}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${LBLUE}║ KERNEL EXPLOIT VULNERABILITY CHECK ║${NC}"
echo -e "${LBLUE}╚═══════════════════════════════════════════════════════════╝${NC}"
# Extract kernel version components
kernel_base=$(echo $kernel_version | cut -d '-' -f1)
ver1=$(echo $kernel_base | cut -d '.' -f1)
ver2=$(echo $kernel_base | cut -d '.' -f2)
ver3=$(echo $kernel_base | cut -d '.' -f3)
echo -e "\n${YELLOW}[+] ${NC}Parsed kernel version: $ver1.$ver2.$ver3"
# Check for PwnKit (CVE-2021-4034)
echo -e "\n${YELLOW}[+] ${NC}Checking for PwnKit (CVE-2021-4034) [pkexec < 0.120]:"
if [ -f /usr/bin/pkexec ]; then
pkexec_perms=$(ls -l /usr/bin/pkexec 2>/dev/null)
echo -e "pkexec found: ${CYAN}$pkexec_perms${NC}"
if [ -u /usr/bin/pkexec ]; then
echo -e "${CYAN}pkexec has SUID bit set${NC}"
pkexec_version=$(/usr/bin/pkexec --version 2>&1 | grep -o '[0-9][0-9]*\.[0-9][0-9]*' | head -1)
if [ ! -z "$pkexec_version" ]; then
echo -e "pkexec version: ${CYAN}$pkexec_version${NC}"
if awk "BEGIN {exit !($pkexec_version < 0.120)}"; then
echo -e "\033[1;31;103mVulnerable pkexec version $pkexec_version (< 0.120) - CVE-2021-4034\033[0m"
echo -e "${LMAGENTA}Exploit: https://gist.github.com/strikoder/c540a4babb01307960dd6a30f822077c${NC}"
echo -e "${LMAGENTA}Exploit without gcc: https://github.com/joeammond/CVE-2021-4034/blob/main/CVE-2021-4034.py${NC}"
else
echo -e "${GREEN}Not vulnerable (pkexec >= 0.120)${NC}"
fi
else
echo -e "${YELLOW}Could not determine pkexec version, checking manually recommended${NC}"
fi
else
echo -e "${GREEN}pkexec does NOT have SUID bit set${NC}"
fi
else
echo -e "${GREEN}pkexec not found${NC}"
fi
# Check for Dirty Pipe (CVE-2022-0847)
echo -e "\n${YELLOW}[+] ${NC}Checking for Dirty Pipe (CVE-2022-0847) [kernel >= 5.8 & kernel < 5.16.10]:"
if (( ${ver1:-0} < 5 )) || (( ${ver1:-0} > 5 )); then
echo -e "${GREEN}Not vulnerable (kernel < 5.8 or > 5.16.10)${NC}"
elif (( ${ver1:-0} == 5 && ${ver2:-0} < 8 )); then
echo -e "${GREEN}Not vulnerable (kernel < 5.8)${NC}"
elif (( ${ver1:-0} == 5 && ${ver2:-0} == 10 && ${ver3:-0} == 102 )) || \
(( ${ver1:-0} == 5 && ${ver2:-0} == 10 && ${ver3:-0} == 92 )) || \
(( ${ver1:-0} == 5 && ${ver2:-0} == 15 && ${ver3:-0} == 25 )) || \
(( ${ver1:-0} == 5 && ${ver2:-0} >= 16 && ${ver3:-0} >= 11 )) || \
(( ${ver1:-0} == 5 && ${ver2:-0} > 16 )); then
echo -e "${GREEN}Not vulnerable (patched version)${NC}"
else
echo -e "\033[1;31;103mVulnerable to Dirty Pipe - Kernel 5.8 - 5.16.10 (unpatched)\033[0m"
echo -e "${LMAGENTA}Exploit: https://github.com/Arinerron/CVE-2022-0847-DirtyPipe-Exploit${NC}"
fi
# Check for CVE-2017-16995 (eBPF)
echo -e "\n${YELLOW}[+] ${NC}Checking for CVE-2017-16995 (eBPF privilege escalation):"
if [[ "$kernel_version" == "4.4.0-116"* ]]; then
echo -e "\033[1;31;103mVulnerable kernel 4.4.0-116 - CVE-2017-16995\033[0m"
echo -e "${LMAGENTA}Exploit: https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/45010.tar${NC}"
else
echo -e "${GREEN}Not the specific vulnerable version (4.4.0-116)${NC}"
fi
# Check for Dirty COW (CVE-2016-5195)
echo -e "\n${YELLOW}[+] ${NC}Checking for Dirty COW (CVE-2016-5195) [kernel <= 3.19.0-73.8]:"
if (( ${ver1:-0} < 3 )) || (( ${ver1:-0} == 3 && ${ver2:-0} < 19 )); then
echo -e "\033[1;31;103mLikely vulnerable - Kernel < 3.19 - Dirty COW\033[0m"
echo -e "${LMAGENTA}Exploit: https://github.com/dirtycow/dirtycow.github.io/wiki/PoCs${NC}"
echo -e "${LMAGENTA}Must compile on target: gcc -pthread dirty.c -o dirty -lcrypt${NC}"
elif (( ${ver1:-0} == 3 && ${ver2:-0} == 19 && ${ver3:-0} <= 73 )); then
echo -e "\033[1;31;103mVulnerable kernel 3.19.0-73.8 or lower - Dirty COW\033[0m"
echo -e "${LMAGENTA}Exploit: https://github.com/dirtycow/dirtycow.github.io/wiki/PoCs${NC}"
echo -e "${LMAGENTA}Must compile on target: gcc -pthread dirty.c -o dirty -lcrypt${NC}"
elif (( ${ver1:-0} == 4 && ${ver2:-0} < 8 )) || (( ${ver1:-0} == 3 )); then
echo -e "\033[1;31;103mPossibly vulnerable - Check patch level - Dirty COW\033[0m"
echo -e "${LMAGENTA}Kernels before 4.8.3, 4.7.9, 4.4.26 are vulnerable${NC}"
else
echo -e "${GREEN}Not vulnerable (kernel too new)${NC}"
fi
# Check for Baron Samedit (CVE-2021-3156)
echo -e "\n${YELLOW}[+] ${NC}Checking for Baron Samedit (CVE-2021-3156) [sudo < 1.8.21p2 or 1.9.0-1.9.5p1]:"
sudo_version=$(sudo -V | head -1 | cut -d " " -f3)
if [ ! -z "$sudo_version" ]; then
echo -e "Current sudo version: ${CYAN}$sudo_version${NC}"
# Check SUID bit on sudoedit
if [ -u /usr/bin/sudoedit ]; then
echo -e "${CYAN}/usr/bin/sudoedit has SUID bit set${NC}"
ls -l /usr/bin/sudoedit
else
echo -e "${GREEN}/usr/bin/sudoedit does NOT have SUID bit${NC}"
fi
# Quick vulnerability test
echo -e "\n${YELLOW}Testing for vulnerability...${NC}"
sudoedit_test=$(sudoedit -s / 2>&1)
if echo "$sudoedit_test" | grep -q "sudoedit:.*not a regular file"; then
echo -e "\033[1;31;103mVulnerable to Baron Samedit - CVE-2021-3156\033[0m"
echo -e "${LMAGENTA}Exploit: https://github.com/blasty/CVE-2021-3156${NC}"
elif echo "$sudoedit_test" | grep -q "usage:"; then
echo -e "${GREEN}Not vulnerable (patched)${NC}"
else
echo -e "${YELLOW}Uncertain, manual verification needed${NC}"
fi
else
echo -e "${GREEN}sudo not found or not accessible${NC}"
fi
# Check for Copy Fail (CVE-2026-31431)
echo -e "\n${YELLOW}[+] ${NC}Checking for Copy Fail (CVE-2026-31431) [kernel 4.14 - 6.18.21]:"
vuln=0
if (( ver1 == 4 && ver2 >= 14 )); then vuln=1; fi
if (( ver1 == 5 )); then vuln=1; fi
if (( ver1 == 6 && ver2 < 18 )); then vuln=1; fi
if (( ver1 == 6 && ver2 == 18 && ver3 <= 21 )); then vuln=1; fi
if (( vuln == 1 )); then
echo -e "\033[1;31;103mKernel $ver1.$ver2.$ver3 is in vulnerable range - CVE-2026-31431\033[0m"
echo -e "${LMAGENTA}PoC: https://github.com/theori-io/copy-fail-CVE-2026-31431${NC}"
echo -e "${LMAGENTA}Fix: echo 'install algif_aead /bin/false' > /etc/modprobe.d/disable-algif-aead.conf && rmmod algif_aead 2>/dev/null${NC}"
echo -e "${YELLOW} [!] Also verify manually:${NC}"
echo -e "${YELLOW} - AEAD module loaded: grep -c authencesn /proc/crypto${NC}"
echo -e "${YELLOW} - su has SUID bit: find /usr/bin/su -perm -4000${NC}"
echo -e "${YELLOW} - splice available: python3 -c 'import os; os.splice; print(1)'${NC}"
else
echo -e "${GREEN}Not vulnerable (kernel $ver1.$ver2.$ver3 outside range 4.14 - 6.18.21)${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Checking for compilers (kernel exploit compilation):"
for compiler in gcc cc g++ python python3 perl ruby make; do
path=$(which $compiler 2>/dev/null)
[ -n "$path" ] && echo -e "$compiler found at $path"
done
# ============================================================================
# USER/GROUP INFORMATION
# ============================================================================
echo -e "\n${LBLUE}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${LBLUE}║ USER/GROUP INFORMATION ║${NC}"
echo -e "${LBLUE}╚═══════════════════════════════════════════════════════════╝${NC}"
echo -e "\n${YELLOW}[+] ${NC}Users with login shells:"
grep -E "(/bin/bash|/bin/sh|/bin/zsh)" /etc/passwd 2>/dev/null | cut -d: -f1,7 | while read user; do
echo -e "${CYAN}$user${NC}"
done
echo -e "\n${YELLOW}[+] ${NC}All users and their groups:"
for usr in $(cut -d":" -f1 /etc/passwd 2>/dev/null | grep -vE "^(daemon|news|proxy|_apt|lp|uucp|dhcpcd)$"); do
id $usr 2>/dev/null
done
echo -e "\n${YELLOW}[+] ${NC}Users in admin/privileged groups:"
for group in sudo wheel admin docker lxd shadow; do
members=$(grep "^$group:" /etc/group 2>/dev/null | cut -d: -f4)
if [ ! -z "$members" ]; then
echo -e "${LRED}$group: $members${NC}"
fi
done
echo -e "\n${YELLOW}[+] ${NC}Super user accounts (uid 0):"
awk -F: '$3 == 0 {print $1}' /etc/passwd 2>/dev/null | while read superuser; do
echo -e "${LRED}$superuser${NC}"
done
echo -e "\n${YELLOW}[+] ${NC}Users logged in:"
who 2>/dev/null
w 2>/dev/null
echo -e "\n${YELLOW}[+] ${NC}Last logged users:"
lastlog 2>/dev/null | grep -v "Never" | head -10
echo -e "\n${YELLOW}[+] ${NC}/etc/passwd permissions:"
ls -lah /etc/passwd 2>/dev/null
if [ -w /etc/passwd ]; then
echo -e "\033[1;31;103m/etc/passwd is WRITABLE! Can add root user!\033[0m"
echo -e "${LMAGENTA}Exploit: pw=\$(openssl passwd -1 Password123); echo \"r00t:\$pw:0:0:root:/root:/bin/bash\" >> /etc/passwd${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}/etc/shadow permissions:"
ls -lah /etc/shadow 2>/dev/null
if [ -r /etc/shadow ]; then
echo -e "\033[1;31;103m/etc/shadow is READABLE! Password hashes exposed!\033[0m"
echo -e "${YELLOW}[+] ${NC}Shadow file contents (first 5 lines):"
head -5 /etc/shadow 2>/dev/null
fi
if [ -w /etc/shadow ]; then
echo -e "\033[1;31;103m/etc/shadow is WRITABLE!\033[0m"
fi
echo -e "\n${YELLOW}[+] ${NC}Checking for password hashes in /etc/passwd:"
hashesinpasswd=$(grep -v '^[^:]*:[x*]' /etc/passwd 2>/dev/null)
if [ "$hashesinpasswd" ]; then
echo -e "\033[1;31;103mPassword hashes found in /etc/passwd!\033[0m"
echo -e "${CYAN}$hashesinpasswd${NC}"
else
echo -e "${GREEN}No hashes in /etc/passwd${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Sudoers configuration:"
if [ -r /etc/sudoers ]; then
grep -v -e '^$' -e '^#' /etc/sudoers 2>/dev/null
else
echo -e "${GREEN}Cannot read /etc/sudoers${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Sudo version:"
sudo_version=$(sudo -V 2>/dev/null | head -1)
if [ "$sudo_version" ]; then
echo -e "${CYAN}$sudo_version${NC}"
# Extract version number
sudo_ver_num=$(echo "$sudo_version" | grep -oP 'version \K[0-9]+\.[0-9]+\.[0-9]+')
# Check for known vulnerable sudo versions
echo -e "\n${YELLOW}[+] ${NC}Checking for known vulnerable sudo versions:"
if [[ "$sudo_ver_num" == "1.8.23" ]]; then
echo -e "\033[1;31;103mVulnerable Sudo 1.8.23 (PwnKit-related)\033[0m"
fi
if [[ "$sudo_ver_num" < "1.8.26" ]]; then
echo -e "\033[1;31;103mCVE-2019-18634 (pwfeedback buffer overflow)\033[0m"
echo -e "${LMAGENTA}Check if pwfeedback is enabled:${NC}"
echo -e "${CYAN}sudo -l # If you see asterisks (****) when typing, it's vulnerable${NC}"
echo -e "${CYAN}Exploit: https://github.com/saleemrashid/sudo-cve-2019-18634${NC}"
fi
if [[ "$sudo_ver_num" < "1.8.28" ]]; then
echo -e "\033[1;31;103mSudo < 1.8.28 (User ID bypass)\033[0m"
echo -e "${LMAGENTA}Exploitation:${NC}"
echo -e "${CYAN}sudo -u#-1 /bin/bash${NC}"
fi
if [[ "$sudo_ver_num" == "1.8.31" ]]; then
echo -e "\033[1;31;103mCVE-2023-3560 (Policy bypass)\033[0m"
echo -e "${LMAGENTA}Exploit: https://github.com/Whiteh4tWolf/Sudo-1.8.31-Root-Exploit${NC}"
fi
# Check for CVE-2025-32463 (sudo 1.9.14 - 1.9.17)
sudo_major=$(echo "$sudo_ver_num" | cut -d. -f1)
sudo_minor=$(echo "$sudo_ver_num" | cut -d. -f2)
sudo_patch=$(echo "$sudo_ver_num" | cut -d. -f3)
if [[ "$sudo_major" == "1" ]] && [[ "$sudo_minor" == "9" ]]; then
if [[ "$sudo_patch" -ge 14 ]] && [[ "$sudo_patch" -le 17 ]]; then
echo -e "\033[1;31;103mCVE-2025-32463 (Sudo 1.9.14-1.9.17 NSS privilege escalation)\033[0m"
echo -e "${LMAGENTA}Exploit: https://gist.github.com/strikoder/439dab5928787b6dbd5bf990da9cf524${NC}"
fi
fi
else
echo -e "${GREEN}sudo not available${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Can we sudo without password?"
sudo_nopass=$(echo '' | sudo -S -l -k 2>/dev/null)
if [ "$sudo_nopass" ]; then
echo -e "${RED}$sudo_nopass${NC}"
echo -e "\n${YELLOW}[+] ${NC}Checking for exploitable sudo binaries:"
# Extract only the actual command paths
exploitable=$(echo "$sudo_nopass" | grep -E '^\s+\(' | awk '{print $NF}' | xargs -n 1 basename 2>/dev/null | grep -wE '7z|aa-exec|ab|alpine|ansible-playbook|ansible-test|aoss|apache2ctl|apt-get|apt|ar|aria2c|arj|arp|as|ascii-xfr|ascii85|ash|aspell|at|atobm|awk|aws|base32|base58|base64|basenc|basez|bash|batcat|bc|bconsole|bpftrace|bridge|bundle|bundler|busctl|busybox|byebug|bzip2|c89|c99|cabal|capsh|cat|cdist|certbot|check_by_ssh|check_cups|check_log|check_memory|check_raid|check_ssl_cert|check_statusfile|chmod|choom|chown|chroot|clamscan|cmp|cobc|column|comm|composer|cowsay|cowthink|cp|cpan|cpio|cpulimit|crash|crontab|csh|csplit|csvtool|cupsfilter|curl|cut|dash|date|dc|dd|debugfs|dialog|diff|dig|distcc|dmesg|dmidecode|dmsetup|dnf|docker|dosbox|dotnet|dpkg|dstat|dvips|easy_install|eb|ed|efax|elvish|emacs|enscript|env|eqn|espeak|ex|exiftool|expand|expect|facter|file|find|fish|flock|fmt|fold|fping|ftp|gawk|gcc|gcloud|gcore|gdb|gem|genie|genisoimage|ghc|ghci|gimp|ginsh|git|grc|grep|gtester|gzip|hd|head|hexdump|highlight|hping3|iconv|iftop|install|ionice|ip|irb|ispell|jjs|joe|join|journalctl|jq|jrunscript|jtag|julia|knife|ksh|ksshell|ksu|kubectl|latex|latexmk|ld\.so|ldconfig|less|lftp|links|ln|loginctl|logsave|look|ltrace|lua|lualatex|luatex|lwp-download|lwp-request|mail|make|man|mawk|minicom|more|mosquitto|mount|msfconsole|msgattrib|msgcat|msgconv|msgfilter|msgmerge|msguniq|mtr|multitime|mv|mysql|nano|nasm|nawk|nc|ncdu|ncftp|neofetch|nft|nice|nl|nm|nmap|node|nohup|npm|nroff|nsenter|ntpdate|octave|od|openssl|openvpn|openvt|opkg|pandoc|paste|pdb|pdflatex|pdftex|perf|perl|perlbug|pexec|pg|php|pic|pico|pidstat|pip|pkexec|pkg|posh|pr|pry|psftp|psql|ptx|puppet|pwsh|python|rake|rc|readelf|red|redcarpet|restic|rev|rlwrap|rpm|rpmdb|rpmquery|rpmverify|rsync|ruby|run-mailcap|run-parts|runscript|rview|rvim|sash|scanmem|scp|screen|script|scrot|sed|service|setarch|setfacl|setlock|sftp|sg|shuf|slsh|smbclient|snap|socat|soelim|softlimit|sort|split|sqlite3|sqlmap|ss|ssh-agent|ssh-keygen|ssh-keyscan|ssh|sshpass|start-stop-daemon|stdbuf|strace|strings|su|sudo|sysctl|systemctl|systemd-resolve|tac|tail|tar|task|taskset|tasksh|tbl|tclsh|tcpdump|tdbtool|tee|telnet|terraform|tex|tftp|tic|time|timedatectl|timeout|tmate|tmux|top|torify|torsocks|troff|ul|unexpand|uniq|unshare|unsquashfs|unzip|update-alternatives|uudecode|uuencode|vagrant|valgrind|varnishncsa|vi|view|vigr|vim|vimdiff|vipw|virsh|w3m|wall|watch|wc|wget|whiptail|wireshark|wish|xargs|xdg-user-dir|xdotool|xelatex|xetex|xmodmap|xmore|xpad|xxd|xz|yarn|yash|yum|zathura|zip|zsh|zsoelim|zypper' 2>/dev/null)
if [ "$exploitable" ]; then
echo -e "\033[1;31;103mEXPLOITABLE SUDO BINARIES FOUND\033[0m"
while IFS= read -r binary; do
echo -e " ${LMAGENTA}$binary${NC}"
done <<< "$exploitable"
else
echo -e "${GREEN}None found${NC}"
fi
else
echo -e "${GREEN}sudo not available${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Checking sudo privileges with provided password (-p):"
if [ -n "$PASSWORD" ]; then
sudo_withpass=$(echo "$PASSWORD" | sudo -S -l -k 2>/dev/null)
if [ "$sudo_withpass" ]; then
echo -e "\033[1;31;103msudo -l succeeded with provided password!\033[0m"
echo -e "${RED}$sudo_withpass${NC}"
echo -e "\n${YELLOW}[+] ${NC}Checking for exploitable sudo binaries (with password):"
exploitable_p=$(echo "$sudo_withpass" | grep -E '^\s+\(' | awk '{print $NF}' | xargs -n 1 basename 2>/dev/null | grep -wE '7z|aa-exec|ab|alpine|ansible-playbook|ansible-test|aoss|apache2ctl|apt-get|apt|ar|aria2c|arj|arp|as|ascii-xfr|ascii85|ash|aspell|at|atobm|awk|aws|base32|base58|base64|basenc|basez|bash|batcat|bc|bconsole|bpftrace|bridge|bundle|bundler|busctl|busybox|byebug|bzip2|c89|c99|cabal|capsh|cat|cdist|certbot|check_by_ssh|check_cups|check_log|check_memory|check_raid|check_ssl_cert|check_statusfile|chmod|choom|chown|chroot|clamscan|cmp|cobc|column|comm|composer|cowsay|cowthink|cp|cpan|cpio|cpulimit|crash|crontab|csh|csplit|csvtool|cupsfilter|curl|cut|dash|date|dc|dd|debugfs|dialog|diff|dig|distcc|dmesg|dmidecode|dmsetup|dnf|docker|dosbox|dotnet|dpkg|dstat|dvips|easy_install|eb|ed|efax|elvish|emacs|enscript|env|eqn|espeak|ex|exiftool|expand|expect|facter|file|find|fish|flock|fmt|fold|fping|ftp|gawk|gcc|gcloud|gcore|gdb|gem|genie|genisoimage|ghc|ghci|gimp|ginsh|git|grc|grep|gtester|gzip|hd|head|hexdump|highlight|hping3|iconv|iftop|install|ionice|ip|irb|ispell|jjs|joe|join|journalctl|jq|jrunscript|jtag|julia|knife|ksh|ksshell|ksu|kubectl|latex|latexmk|ld\.so|ldconfig|less|lftp|links|ln|loginctl|logsave|look|ltrace|lua|lualatex|luatex|lwp-download|lwp-request|mail|make|man|mawk|minicom|more|mosquitto|mount|msfconsole|msgattrib|msgcat|msgconv|msgfilter|msgmerge|msguniq|mtr|multitime|mv|mysql|nano|nasm|nawk|nc|ncdu|ncftp|neofetch|nft|nice|nl|nm|nmap|node|nohup|npm|nroff|nsenter|ntpdate|octave|od|openssl|openvpn|openvt|opkg|pandoc|paste|pdb|pdflatex|pdftex|perf|perl|perlbug|pexec|pg|php|pic|pico|pidstat|pip|pkexec|pkg|posh|pr|pry|psftp|psql|ptx|puppet|pwsh|python|rake|rc|readelf|red|redcarpet|restic|rev|rlwrap|rpm|rpmdb|rpmquery|rpmverify|rsync|ruby|run-mailcap|run-parts|runscript|rview|rvim|sash|scanmem|scp|screen|script|scrot|sed|service|setarch|setfacl|setlock|sftp|sg|shuf|slsh|smbclient|snap|socat|soelim|softlimit|sort|split|sqlite3|sqlmap|ss|ssh-agent|ssh-keygen|ssh-keyscan|ssh|sshpass|start-stop-daemon|stdbuf|strace|strings|su|sudo|sysctl|systemctl|systemd-resolve|tac|tail|tar|task|taskset|tasksh|tbl|tclsh|tcpdump|tdbtool|tee|telnet|terraform|tex|tftp|tic|time|timedatectl|timeout|tmate|tmux|top|torify|torsocks|troff|ul|unexpand|uniq|unshare|unsquashfs|unzip|update-alternatives|uudecode|uuencode|vagrant|valgrind|varnishncsa|vi|view|vigr|vim|vimdiff|vipw|virsh|w3m|wall|watch|wc|wget|whiptail|wireshark|wish|xargs|xdg-user-dir|xdotool|xelatex|xetex|xmodmap|xmore|xpad|xxd|xz|yarn|yash|yum|zathura|zip|zsh|zsoelim|zypper' 2>/dev/null)
if [ "$exploitable_p" ]; then
echo -e "\033[1;31;103mEXPLOITABLE SUDO BINARIES FOUND (with password)\033[0m"
while IFS= read -r binary; do
echo -e " ${LMAGENTA}$binary${NC}"
done <<< "$exploitable_p"
else
echo -e "${GREEN}None found${NC}"
fi
else
echo -e "${GREEN}sudo -l failed with provided password (wrong password or sudo not configured)${NC}"
fi
else
echo -e "${YELLOW}Skipped, no password provided (-p)${NC}"
fi
# ============================================================================
# ENVIRONMENTAL INFORMATION
# ============================================================================
echo -e "\n${LBLUE}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${LBLUE}║ ENVIRONMENTAL INFORMATION ║${NC}"
echo -e "${LBLUE}╚═══════════════════════════════════════════════════════════╝${NC}"
echo -e "\n${YELLOW}[+] ${NC}Environment variables (filtered for sensitive):"
(env 2>/dev/null || set 2>/dev/null) | grep -i "pass\|pwd\|key\|secret\|token\|api" --color=always
echo -e "\n${YELLOW}[+] ${NC}PATH variable:"
echo -e "${CYAN}$PATH${NC}"
echo -e "\n${YELLOW}[+] ${NC}PATH directory permissions (checking for writable):"
for dir in $(echo $PATH | tr ":" " "); do
if [ -d "$dir" ]; then
perm=$(ls -ld "$dir" 2>/dev/null)
if [ -w "$dir" ]; then
echo -e "${LRED}[WRITABLE!] $perm${NC}"
else
echo -e "${GREEN}$perm${NC}"
fi
fi
done
echo -e "\n${YELLOW}[+] ${NC}Available shells:"
cat /etc/shells 2>/dev/null
echo -e "\n${YELLOW}[+] ${NC}Current umask:"
umask -S 2>/dev/null
umask 2>/dev/null
echo -e "\n${YELLOW}[+] ${NC}Password policy (from /etc/login.defs):"
grep "^PASS_MAX_DAYS\|^PASS_MIN_DAYS\|^PASS_WARN_AGE\|^ENCRYPT_METHOD" /etc/login.defs 2>/dev/null
echo -e "\n${YELLOW}[+] ${NC}SELinux status:"
sestatus 2>/dev/null || echo -e "${GREEN}SELinux not present${NC}"
echo -e "\n${YELLOW}[+] ${NC}Checking for old passwords:"
if [ -r /etc/security/opasswd ]; then
echo -e "\033[1;31;103mOld passwords file is readable\033[0m"
cat /etc/security/opasswd 2>/dev/null
else
echo -e "${GREEN}Cannot read opasswd file${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Home directory permissions:"
ls -lah /home 2>/dev/null
echo -e "\n${YELLOW}[+] ${NC}Can we read root's home?"
if [ -r /root ]; then
echo -e "\033[1;31;103m/root is readable!\033[0m"
ls -lah /root 2>/dev/null
else
echo -e "${GREEN}Cannot access /root${NC}"
fi
# ============================================================================
# SUID/SGID FILES & CAPABILITIES
# ============================================================================
echo -e "\n${LBLUE}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${LBLUE}║ SUID/SGID FILES & CAPABILITIES (HIGH PRIORITY) ║${NC}"
echo -e "${LBLUE}╚═══════════════════════════════════════════════════════════╝${NC}"
echo -e "\n${YELLOW}[+] ${NC}Files with capabilities:"
cap_result=$(/usr/sbin/getcap -r / 2>/dev/null)
if [ ! -z "$cap_result" ]; then
echo -e "$cap_result${NC}"
else
echo -e "${GREEN}No capabilities found${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}SUID files (runs as owner - potential privesc):"
find / -perm -u=s -type f 2>/dev/null | while read file; do
echo -e "$file${NC}"
done
echo -e "\n${YELLOW}[+] ${NC}SGID files (runs as group):"
find / -perm -g=s -type f 2>/dev/null | while read file; do
echo -e "$file${NC}"
done
echo -e "\n${YELLOW}[+] ${NC}World-writable SUID files (CRITICAL):"
wwsuid=$(find / -perm -4002 -type f 2>/dev/null)
if [ "$wwsuid" ]; then
echo -e "\033[1;31;103mWorld-writable SUID files found!\033[0m"
echo -e "${LRED}$wwsuid${NC}"
else
echo -e "${GREEN}None found${NC}"
fi
echo -e "\n${LMAGENTA}[!] For SUID/SGID exploitation automation:${NC}"
echo -e "${LMAGENTA} https://github.com/strikoder/gtfobinSUID${NC}"
# ============================================================================
# SCHEDULED TASKS (CRON & SYSTEMD TIMERS)
# ============================================================================
echo -e "\n${LBLUE}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${LBLUE}║ SCHEDULED TASKS (CRON & SYSTEMD TIMERS) ║${NC}"
echo -e "${LBLUE}╚═══════════════════════════════════════════════════════════╝${NC}"
echo -e "\n${YELLOW}[+] ${NC}System-wide crontab (/etc/crontab):"
if [ -r /etc/crontab ]; then
cat /etc/crontab 2>/dev/null | grep -v "^#"
else
echo -e "${GREEN}Cannot read /etc/crontab${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Current user's crontab:"
crontab -l 2>/dev/null || echo -e "${GREEN}No crontab for current user${NC}"
echo -e "\n${YELLOW}[+] ${NC}Cron job directories:"
ls -lah /etc/cron* 2>/dev/null
echo -e "\n${YELLOW}[+] ${NC}Writable cron directories:"
writable_cron=$(find /etc/cron* -type d -writable 2>/dev/null)
if [ "$writable_cron" ]; then
echo -e "\033[1;31;103mWritable cron directories found!\033[0m"
echo -e "${LRED}$writable_cron${NC}"
else
echo -e "${GREEN}No writable cron directories${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}World-writable cron files:"
ww_cron=$(find /etc/cron* -perm -0002 -type f 2>/dev/null)
if [ "$ww_cron" ]; then
echo -e "\033[1;31;103mWorld-writable cron files found!\033[0m"
echo -e "${LRED}$ww_cron${NC}"
else
echo -e "${GREEN}No world-writable cron files${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Systemd timers:"
systemd_timers=$(systemctl list-timers --all 2>/dev/null)
if [ "$systemd_timers" ]; then
echo -e "$systemd_timers${NC}"
else
echo -e "${GREEN}No systemd timers or systemctl not available${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Systemd timer unit files:"
find /etc/systemd/system /lib/systemd/system -name "*.timer" -exec ls -lah {} \; 2>/dev/null
echo -e "\n${YELLOW}[+] ${NC}Jobs held by all users:"
for user in $(cut -d: -f1 /etc/passwd 2>/dev/null | head -20); do
user_cron=$(crontab -l -u $user 2>/dev/null | grep -v "^#")
if [ ! -z "$user_cron" ]; then
echo -e "${CYAN}Crontab for $user${NC}"
echo -e "${CYAN}$user_cron${NC}"
fi
done
echo -e "\n${YELLOW}[+] ${NC}Recent cron executions from syslog:"
grep "CRON" /var/log/syslog 2>/dev/null | tail -10
# ============================================================================
# SERVICES & PROCESSES
# ============================================================================
echo -e "\n${LBLUE}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${LBLUE}║ SERVICES & PROCESSES ║${NC}"
echo -e "${LBLUE}╚═══════════════════════════════════════════════════════════╝${NC}"
echo -e "\n${YELLOW}[+] ${NC}Running processes:"
ps aux 2>/dev/null | head -20
echo -e "\n${YELLOW}[+] ${NC}Process binary permissions:"
ps aux 2>/dev/null | awk '{print $11}' | sort -u | xargs -r ls -la 2>/dev/null | head -20
echo -e "\n${YELLOW}[+] ${NC}Systemd services:"
systemctl list-units --type=service --state=running 2>/dev/null | head -20 | sed 's/^[[:space:]]*//'
echo -e "\n${YELLOW}[+] ${NC}Init.d services:"
ls -lah /etc/init.d 2>/dev/null
echo -e "\n${YELLOW}[+] ${NC}Init.d files NOT owned by root:"
initd_non_root=$(find /etc/init.d/ \! -uid 0 -type f 2>/dev/null | xargs -r ls -la 2>/dev/null)
if [ "$initd_non_root" ]; then
echo -e "\033[1;31;103mInit.d files NOT owned by root!\033[0m"
echo -e "${LRED}$initd_non_root${NC}"
else
echo -e "${GREEN}All init.d files owned by root${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Systemd service files NOT owned by root:"
systemd_non_root=$(find /lib/systemd/system /etc/systemd/system \! -uid 0 -type f 2>/dev/null | xargs -r ls -la 2>/dev/null)
if [ "$systemd_non_root" ]; then
echo -e "\033[1;31;103mSystemd files NOT owned by root!\033[0m"
echo -e "${LRED}$systemd_non_root${NC}"
else
echo -e "${GREEN}All systemd files owned by root${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Writable systemd service files:"
systemd_writable=$(find /lib/systemd/system /etc/systemd/system -writable -type f 2>/dev/null | xargs -r ls -la 2>/dev/null)
if [ "$systemd_writable" ]; then
echo -e "\033[1;31;103mWritable systemd service files!\033[0m"
echo -e "${LRED}$systemd_writable${NC}"
else
echo -e "${GREEN}No writable systemd service files${NC}"
fi
# ============================================================================
# NETWORK INFORMATION
# ============================================================================
echo -e "\n${LBLUE}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${LBLUE}║ NETWORK INFORMATION ║${NC}"
echo -e "${LBLUE}╚═══════════════════════════════════════════════════════════╝${NC}"
echo -e "\n${YELLOW}[+] ${NC}Network interfaces:"
ip a 2>/dev/null || ifconfig 2>/dev/null
echo -e "\n${YELLOW}[+] ${NC}Network connections and listening ports:"
(netstat -tunlp 2>/dev/null || ss -tunlp 2>/dev/null) | head -30
echo -e "\n${YELLOW}[+] ${NC}Routing table:"
route -n 2>/dev/null || ip route 2>/dev/null
echo -e "\n${YELLOW}[+] ${NC}ARP cache:"
if command -v arp >/dev/null 2>&1; then
arp -a 2>/dev/null
elif command -v ip >/dev/null 2>&1; then
ip n 2>/dev/null
else
echo -e "${GREEN}No arp/ip utility available${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Raw ARP table (/proc/net/arp):"
if [ -r /proc/net/arp ]; then
cat /proc/net/arp 2>/dev/null
else
echo -e "${GREEN}Cannot read /proc/net/arp${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}DNS servers:"
if [ -r /etc/resolv.conf ]; then
grep "nameserver" /etc/resolv.conf 2>/dev/null
echo -e "\n${YELLOW}[+] ${NC}Full resolv.conf contents:"
cat /etc/resolv.conf 2>/dev/null
# Detect unusual/non-default resolver configuration
resolv_extra=$(grep -Ev '^\s*#|^\s*$|^\s*nameserver\s+' /etc/resolv.conf 2>/dev/null)
if [ -n "$resolv_extra" ]; then
echo -e "\033[1;31;103mInteresting /etc/resolv.conf detected - contains additional directives\033[0m"
echo -e "${LMAGENTA}Additional entries:${NC}"
echo "$resolv_extra"
fi
else
echo -e "${GREEN}Cannot read /etc/resolv.conf${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Host resolution entries (getent hosts):"
getent hosts 2>/dev/null || echo -e "${GREEN}No hosts returned${NC}"
echo -e "\n${YELLOW}[+] ${NC}Hosts file:"
cat /etc/hosts 2>/dev/null | grep -v "^#"
echo -e "\n${YELLOW}[+] ${NC}Firewall rules (iptables):"
iptables -L -n 2>/dev/null || echo -e "${GREEN}Cannot read iptables${NC}"
# ============================================================================
# DATABASE ENUMERATION
# ============================================================================
echo -e "\n${LBLUE}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${LBLUE}║ DATABASE ENUMERATION ║${NC}"
echo -e "${LBLUE}╚═══════════════════════════════════════════════════════════╝${NC}"
echo -e "\n${YELLOW}[+] ${NC}MySQL version:"
mysql_ver=$(mysql --version 2>/dev/null)
if [ "$mysql_ver" ]; then
echo -e "$mysql_ver${NC}"
echo -e "\n${YELLOW}[+] ${NC}Testing MySQL root/root:"
mysql_root=$(mysqladmin -uroot -proot version 2>/dev/null)
if [ "$mysql_root" ]; then
echo -e "\033[1;31;103mMySQL accepts root/root!\033[0m"
else
echo -e "${GREEN}root/root failed${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Testing MySQL root (no password):"
mysql_nopass=$(mysqladmin -uroot version 2>/dev/null)
if [ "$mysql_nopass" ]; then
echo -e "\033[1;31;103mMySQL root has no password!\033[0m"
else
echo -e "${GREEN}root no-password failed${NC}"
fi
else
echo -e "${GREEN}MySQL not installed${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}PostgreSQL version:"
psql_ver=$(psql -V 2>/dev/null)
if [ "$psql_ver" ]; then
echo -e "${CYAN}$psql_ver${NC}"
echo -e "\n${YELLOW}[+] ${NC}Testing PostgreSQL postgres user:"
psql_test=$(psql -U postgres -w template0 -c 'select version()' 2>/dev/null | grep version)
if [ "$psql_test" ]; then
echo -e "\033[1;31;103mPostgreSQL 'postgres' no password!\033[0m"
else
echo -e "${GREEN}postgres no-password failed${NC}"
fi
else
echo -e "${GREEN}PostgreSQL not installed${NC}"
fi
# ============================================================================
# WEB SERVER ENUMERATION
# ============================================================================
echo -e "\n${LBLUE}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${LBLUE}║ WEB SERVER ENUMERATION ║${NC}"
echo -e "${LBLUE}╚═══════════════════════════════════════════════════════════╝${NC}"
echo -e "\n${YELLOW}[+] ${NC}Apache version:"
apache_ver=$(apache2 -v 2>/dev/null || httpd -v 2>/dev/null)
if [ "$apache_ver" ]; then
echo -e "$apache_ver${NC}"
echo -e "\n${YELLOW}[+] ${NC}Apache user/group:"
apache_user=$(grep -i 'user\|group' /etc/apache2/envvars 2>/dev/null | awk '{sub(/.*export /,"")}1')
if [ "$apache_user" ]; then
echo -e "${CYAN}$apache_user${NC}"
else
echo -e "${GREEN}Cannot read Apache envvars${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Apache modules:"
apache_mods=$(apache2ctl -M 2>/dev/null || httpd -M 2>/dev/null | head -20)
if [ "$apache_mods" ]; then
echo -e "$apache_mods${NC}"
fi
else
echo -e "${GREEN}Apache not installed${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Nginx version:"
nginx -v 2>&1 | grep -i version || echo -e "${GREEN}Nginx not installed${NC}"
echo -e "\n${YELLOW}[+] ${NC}Web directories:"
for webdir in /var/www /srv/www /usr/local/www /opt/lampp/htdocs; do
if [ -d "$webdir" ]; then
echo -e "$webdir exists${NC}"
ls -lah "$webdir" 2>/dev/null | head -10
fi
done
echo -e "\n${YELLOW}[+] ${NC}/opt directory contents:"
if [ -d /opt ]; then
ls -lah /opt 2>/dev/null
echo -e "\n${YELLOW}[+] ${NC}Interesting files in /opt (configs, scripts, binaries):"
find /opt -type f \( -name "*.conf" -o -name "*.config" -o -name "*.cfg" -o -name "*.ini" \
-o -name "*.env" -o -name "*.sh" -o -name "*.py" -o -name "*.rb" -o -name "*.php" \
-o -name "*.yml" -o -name "*.yaml" -o -name "*.json" \) 2>/dev/null | head -20 | while read f; do
echo -e "${CYAN}$f${NC}"
done
echo -e "\n${YELLOW}[+] ${NC}SUID/SGID files in /opt:"
opt_suid=$(find /opt \( -perm -u=s -o -perm -g=s \) -type f 2>/dev/null)
if [ -n "$opt_suid" ]; then
echo -e "\033[1;31;103mSUID/SGID files found in /opt!\033[0m"
echo "$opt_suid" | while read f; do echo -e "${LRED}$f${NC}"; done
else
echo -e "${GREEN}None found${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}World-writable files in /opt:"
opt_ww=$(find /opt -perm -o+w -type f 2>/dev/null)
if [ -n "$opt_ww" ]; then
echo -e "\033[1;31;103mWorld-writable files in /opt!\033[0m"
echo "$opt_ww" | while read f; do echo -e "${LRED}$f${NC}"; done
else
echo -e "${GREEN}None found${NC}"
fi
else
echo -e "${GREEN}/opt does not exist${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}Apache/Nginx sites-enabled configs:"
for sitesdir in /etc/apache2/sites-enabled /etc/nginx/sites-enabled /etc/nginx/conf.d /etc/httpd/conf.d; do
if [ -d "$sitesdir" ]; then
echo -e "${CYAN}$sitesdir:${NC}"
ls -lah "$sitesdir" 2>/dev/null
for f in "$sitesdir"/*; do
[ -f "$f" ] || continue
echo -e "\n${YELLOW}--- $f ---${NC}"
grep -vE "^\s*(#|$)" "$f" 2>/dev/null | head -30
done
fi
done
# ============================================================================
# SHELL & PROFILE FILES
# ============================================================================
echo -e "\n${LBLUE}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${LBLUE}║ SHELL & PROFILE FILES ║${NC}"
echo -e "${LBLUE}╚═══════════════════════════════════════════════════════════╝${NC}"
echo -e "\n${YELLOW}[+] ${NC}Current user's shell config files:"
for file in ~/.bash_profile ~/.bashrc ~/.bash_logout ~/.profile ~/.zshrc; do
if [ -r "$file" ]; then
echo -e "${CYAN}$file (readable)${NC}"
ls -lah "$file" 2>/dev/null
fi
done
echo -e "\n${YELLOW}[+] ${NC}System-wide shell configs:"
for file in /etc/profile /etc/bashrc /etc/bash.bashrc; do
if [ -r "$file" ]; then
ls -lah "$file" 2>/dev/null
fi
done
echo -e "\n${YELLOW}[+] ${NC}All .bash_history files:"
found_bash_history=0
for homedir in /home/* /root; do
# Skip home dirs we can't traverse (+x) before searching them.
[ -d "$homedir" ] && [ -x "$homedir" ] || continue
for hist_file in $(find "$homedir" -name ".bash_history" -type f 2>/dev/null); do
found_bash_history=1
ls -lah "$hist_file" 2>/dev/null
if [ -r "$hist_file" ]; then
echo -e "${YELLOW} Last 5 commands:${NC}"
tail -5 "$hist_file" 2>/dev/null | while read line; do
echo -e "${RED} $line${NC}"
done
echo ""
fi
done
done
if [ "$found_bash_history" -eq 0 ]; then
echo -e "${GREEN}No .bash_history files found${NC}"
fi
echo -e "\n${YELLOW}[+] ${NC}All shell history files (.*_history):"
for homedir in /home/* /root; do
[ -d "$homedir" ] && [ -x "$homedir" ] || continue
find "$homedir" -type f -name ".*_history" 2>/dev/null
done | head -10 | while read hist; do
echo -e "${CYAN}$hist${NC}"
ls -lah "$hist" 2>/dev/null
done
echo -e "\n${YELLOW}[+] ${NC}Current user's recent command history:"
history 2>/dev/null | tail -20
# ============================================================================
# SSH KEYS & CONFIG
# ============================================================================
echo -e "\n${LBLUE}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${LBLUE}║ SSH KEYS & CONFIGURATION ║${NC}"
echo -e "${LBLUE}╚═══════════════════════════════════════════════════════════╝${NC}"