├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ └── pages.yml
├── .gitignore
├── BappDescription.html
├── BappManifest.bmf
├── Checklist.CSV
├── DOC
├── API-Mapper.md
├── Checklist.md
├── Config.md
├── README.md
├── Vulnerabilites.md
├── _images
│ ├── APIMapper.png
│ ├── Burp-Suite-Extender.png
│ ├── Checklist.png
│ ├── Config.png
│ ├── Load.png
│ ├── Proxy.png
│ ├── Vulnerability.png
│ └── Zip.png
├── _sidebar.md
├── index.html
└── installation.md
├── LICENSE
├── PentestMapper.py
├── README.md
├── images
├── APIMapper.png
├── APIMapper2.png
├── CheckList.png
├── Config.png
├── Sendreq.png
├── Vulnerability-selection.png
├── proxy.png
├── severity.png
└── tt
├── lib
└── swingx-all-1.6.4.jar
└── pentestmapper
├── APIMapper.py
├── __init__.py
├── autolog.py
└── autosave.py
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: Anof-cyber
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/workflows/pages.yml:
--------------------------------------------------------------------------------
1 | # Simple workflow for deploying static content to GitHub Pages
2 | name: Deploy static content to Pages
3 |
4 | on:
5 | # Runs on pushes targeting the default branch
6 | push:
7 | branches: ["main"]
8 |
9 | # Allows you to run this workflow manually from the Actions tab
10 | workflow_dispatch:
11 |
12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
13 | permissions:
14 | contents: read
15 | pages: write
16 | id-token: write
17 |
18 | # Allow one concurrent deployment
19 | concurrency:
20 | group: "pages"
21 | cancel-in-progress: true
22 |
23 | jobs:
24 | # Single deploy job since we're just deploying
25 | deploy:
26 | environment:
27 | name: github-pages
28 | url: ${{ steps.deployment.outputs.page_url }}
29 | runs-on: ubuntu-latest
30 | steps:
31 | - name: Checkout
32 | uses: actions/checkout@v3
33 | - name: Setup Pages
34 | uses: actions/configure-pages@v2
35 | - name: Upload artifact
36 | uses: actions/upload-pages-artifact@v1
37 | with:
38 | # Upload entire repository
39 | path: 'DOC/'
40 | - name: Deploy to GitHub Pages
41 | id: deployment
42 | uses: actions/deploy-pages@v1
43 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | pentestmapper/vuln.py
2 | pentestmapper/vuln$py.class
3 | pentestmapper/autosave$py.class
4 | # Byte-compiled / optimized / DLL files
5 | __pycache__/
6 | *.py[cod]
7 | *$py.class
8 |
9 | # C extensions
10 | *.so
11 |
12 | # Distribution / packaging
13 | .Python
14 | .jython_cache
15 | build/
16 | develop-eggs/
17 | dist/
18 | downloads/
19 | eggs/
20 | .eggs/
21 | lib64/
22 | parts/
23 | sdist/
24 | var/
25 | wheels/
26 | pip-wheel-metadata/
27 | share/python-wheels/
28 | *.egg-info/
29 | .installed.cfg
30 | *.egg
31 | MANIFEST
32 |
33 | # PyInstaller
34 | # Usually these files are written by a python script from a template
35 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
36 | *.manifest
37 | *.spec
38 |
39 | # Installer logs
40 | pip-log.txt
41 | pip-delete-this-directory.txt
42 |
43 | # Unit test / coverage reports
44 | htmlcov/
45 | .tox/
46 | .nox/
47 | .coverage
48 | .coverage.*
49 | .cache
50 | nosetests.xml
51 | coverage.xml
52 | *.cover
53 | *.py,cover
54 | .hypothesis/
55 | .pytest_cache/
56 |
57 | # Translations
58 | *.mo
59 | *.pot
60 |
61 | # Django stuff:
62 | *.log
63 | local_settings.py
64 | db.sqlite3
65 | db.sqlite3-journal
66 |
67 | # Flask stuff:
68 | instance/
69 | .webassets-cache
70 |
71 | # Scrapy stuff:
72 | .scrapy
73 |
74 | # Sphinx documentation
75 | docs/_build/
76 |
77 | # PyBuilder
78 | target/
79 |
80 | # Jupyter Notebook
81 | .ipynb_checkpoints
82 |
83 | # IPython
84 | profile_default/
85 | ipython_config.py
86 |
87 | # pyenv
88 | .python-version
89 |
90 | # pipenv
91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
94 | # install all needed dependencies.
95 | #Pipfile.lock
96 |
97 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
98 | __pypackages__/
99 |
100 | # Celery stuff
101 | celerybeat-schedule
102 | celerybeat.pid
103 |
104 | # SageMath parsed files
105 | *.sage.py
106 |
107 | # Environments
108 | .env
109 | .venv
110 | env/
111 | venv/
112 | ENV/
113 | env.bak/
114 | venv.bak/
115 |
116 | # Spyder project settings
117 | .spyderproject
118 | .spyproject
119 |
120 | # Rope project settings
121 | .ropeproject
122 |
123 | # mkdocs documentation
124 | /site
125 |
126 | # mypy
127 | .mypy_cache/
128 | .dmypy.json
129 | dmypy.json
130 |
131 | # Pyre type checker
132 | .pyre/
133 |
134 |
135 |
136 |
137 |
--------------------------------------------------------------------------------
/BappDescription.html:
--------------------------------------------------------------------------------
1 |
Pentest Mapper is a Burp Suite extension that integrates the Burp Suite request logging with a custom application testing checklist. The extension provides a straightforward flow for application penetration testing. The extension includes functionalities to allow users to map the flow of the application for pentesting to better analyse the application and its vulnerabilities. The API calls from each flow can be connected with the function or flow name. The extension allows users to map or connect each flow or API to vulnerability with the custom checklist.
2 |
3 |
Features Summary
4 |
5 |
Checklist
6 | Allows you to load the custom checklist
7 |
8 |
API Mapper
9 | Allows you to keep track of each API call, Flow and Test Cases for each API calls.
10 |
11 |
Vulnerability
12 | Allows to keep track of vulnerabilities, Map each paramter and API call to vulnerability from the Checklist and severity
13 |
14 |
Config
15 |
16 |
Configure Auto Save timer and directory
17 |
Configure Auto Load Checklist
18 |
Turn ON/OFF Auto Save
19 |
Turn ON/OFF Auto Log Proxy Request for Scope Domain
20 |
21 |
22 |
23 |
24 |
Download the demo checklist file CSV file from here
25 |
--------------------------------------------------------------------------------
/BappManifest.bmf:
--------------------------------------------------------------------------------
1 | Uuid: af490ae7e79546fa81a28d8d0b90874e
2 | ExtensionType: 2
3 | Name: Pentest Mapper
4 | RepoName: pentest-mapper
5 | ScreenVersion: 1.5
6 | SerialVersion: 4
7 | MinPlatformVersion: 0
8 | ProOnly: False
9 | Author: Anof-cyber
10 | ShortDescription: Integrates logging with a custom application testing checklist.
11 | EntryPoint: PentestMapper.py
12 | BuildCommand:
13 | SupportedProducts: Pro, Community
14 |
--------------------------------------------------------------------------------
/Checklist.CSV:
--------------------------------------------------------------------------------
1 | 1,Parameter Tampering
2 | 2,SQL Injection
3 | 3,Reflected Cross Site Scripting
4 | 4,IDOR
5 | 5,Privledge Esclation
6 | 6,Code Tapering
7 | 7,DOM Cross Site Scripting
8 | 8,Stored Cross Site Scripting
9 | 9,Rate Liming
10 | 10,CORS
11 | 11,Verbose Error
12 | 12,Options Method Enabled
13 | 13,Forced Browsing
14 | 14,Missing HSTS Header
15 | 15,Missing X-Frame Header
16 | 16,OTP Bypass with Response Modification
17 | 17,Directory Listing Enabled
18 | 18,Hard-Coded Sensitive Information
19 | 19,SSL not Enabled
20 | 20,SSL not Enforced
21 | 21,Weak Password Policy
22 | 22,Cookie without Secure Flag
23 | 23,Cookie without HTTP Only Flag
24 | 24,Sensitive Information in URL
25 | 25,User Enumeration
26 | 26,Long Password DOS
27 | 27,Insufficient Account Verification
28 | 28,Open Redirect
29 | 29,2FA Bypass
30 | 30,CSRF
31 | 31,Insufficient Session Expiry after Logout
32 | 32,Insufficient Session Expiry after Change or Forget password
33 | 33,Command Injection
34 | 34,Local Storage not Cleaned
35 | 35,Host Header Injection
36 | 36,OTP Valid for more than one time
37 | 37,Password Reset Link is not expired
38 | 38,Password Reset Link Poision
39 | 39,Password Reset Token is predictable
40 | 40,File Path Traversal
41 | 41,LFI
42 | 42,RFI
43 | 43,SSRF
44 | 44,XPath Injection
45 | 45,No SQL Injection
46 | 46,HTTP Request Smuggling
47 | 47,XMLPRC Enabled
48 | 48,DEBUG Method Enabled
49 | 49,View State Not Encrypted
50 | 50,Captcha Bypass
51 | 51,Price Manipulation
52 | 52,Internal IP Disclosed
53 | 53,Login Bypass
54 |
--------------------------------------------------------------------------------
/DOC/API-Mapper.md:
--------------------------------------------------------------------------------
1 | # API Mapper
2 |
3 | The API Mapper allow users to Map the API with HTTP request and response. They can even write test cases or comments for each request.
4 | The idea is to allow the pentester to test each API and URL at a time with test cases which he can write for each API. Also, the pentester can keep track of API like which API is completed, Pending.
5 |
6 | 
7 |
8 | ## Overview
9 |
10 | ### Search
11 |
12 | At the top of the API Mapper tab, we have a search button same as a checklist which allows us to filter the data from the table.
13 |
14 | ### Save Project
15 |
16 | Since the BurpSuite doesn't allow extension to save the extension data within the burp suite project file. We have the option to save the API Mapper output in a CSV file.
17 | You can click on the Save project button and select the directory and it will create a CSV file for you.
18 |
19 | ### Load Project
20 |
21 | Once you save your API Mapper Data you also have the option to load that data again in the extension with the Load Project button.
22 | You can click on the button, select the CSV file and it will load the data in the API Mapper
23 |
24 | ### API Mapper Table
25 |
26 | Now we have a table with multiple columns.
27 | - The 1st column `SR ` will show the row number for the table.
28 | - The 2nd column `URL` will show the full URL of the request.
29 | - The 3rd column `Method` will show the HTTP method used for that request.
30 | - The 4th column `Post Body` will show the Post request Body for that request.
31 | - The 5th column `Functionality Name` is like a text box where the user can specify the name of the Functionality the request belong. Like if this request is for login or profile etc. If you double click it will allow you to edit.
32 | - The 6th column `Status` will allow users to select the Pentest Status for the specific URL or API. Where he can select if the select API is completed for testing or pending etc.
33 |
34 |
35 |
36 | ### Adding Data to API Mapper Table
37 |
38 | Since our table is empty we can add the request from BurpSuite Target, Proxy History, Repeater, Intruder etc. You can right-click on any selected request, and select extension --> Pentest Mapper --> API Mapper. Now you can view the request inside the table.
39 |
40 | 
41 |
42 | ### Test Cases
43 |
44 | Once you click on any row in the table, You can view the request and response below the table. We also have a Test case tab where we can write the test cases for the selected API. Once we are done we can click on the save test cases button to save.
45 |
46 | ### Menu
47 |
48 | You can select any row in the table and right-click. A menu will pop up.
49 | - Add to Vulnerabilities - You can send the selected requests to the Vulnerabilities tab to map the particular request to vulnerability.
50 | - Send to Repeater - You can send the selected request to the repeater tab.
51 | - Delete - Lastly we have the option to delete the selected row.
52 |
53 | You can also select multiple rows to perform the actions.
54 |
--------------------------------------------------------------------------------
/DOC/Checklist.md:
--------------------------------------------------------------------------------
1 | # CheckList
2 |
3 | The extension comes with 4 different tabs inside it. The checklist tab allows users to load a custom vulnerability checklist. The checklist file will later be used while mapping the API to the vulnerabilities.
4 | You can download the demo checklist from [here](https://github.com/Anof-cyber/Pentest-Mapper/blob/main/Checklist.CSV).
5 |
6 | 
7 |
8 | ## Overview
9 |
10 |
11 | ### Search
12 | The first thing in the checklist is the search text box and button which allows you to filter and search the vulnerabilities from the table.
13 |
14 | ### Import Checklist
15 |
16 | You also have an import button which allows you to load your checklist CSV file into the table. This button will be removed in future updates so you can ignore this button.
17 | To load the checklist you can go to the config tab.
18 |
19 | ### Create Checklist
20 |
21 | You have a create button once you click on that button it will show you a text box which allows you to create a new test case or add a new vulnerability in your table.
22 | This creates button is useful if you need to add a new vulnerability to your checklist table.
23 |
24 | **Note:** If you add a new vulnerability using create button, it will only add to your table but your CSV file which you have imported will not be updated.
25 | This is only valid if you load the checklist from the import checklist button. If you load the checklist from the config tab it will update the CSV file if you create a new vulnerability with create button.
26 |
27 | ```
28 |
29 | - It's recommended that you load the checklist from the config tab.
30 |
31 | ```
32 |
33 |
--------------------------------------------------------------------------------
/DOC/Config.md:
--------------------------------------------------------------------------------
1 | # Config
2 |
3 | Lastly we have an Configuration tab where we can set multiple options for our extension.
4 |
5 | 
6 |
7 | ## OverVIew
8 |
9 | ### Auto Save Config
10 |
11 | The extension allows users to store API Mapper and Vulnerabilities output individually. The problem arises here when for some reason burp or system is closed without saving the output.
12 | We have the AutoSave method. The Autosave need to be configured, you have to select the output directory and time. Once done you can click on the Save Config button.
13 |
14 | Every time you load the extension or open the burp suite the saved setting will not be removed since ita stored in your burp configuration.
15 |
16 | The Autosave will run after every 10 minutes ( default time ), and will create two files in the output directory as ```vulnerability.csv``` and ```APIMapper.csv```.
17 | Each time the extension tries to save it will overwrite the files so make sure you import the data first before the auto-save start or change the directory.
18 |
19 | ### Auto Load Checklist
20 |
21 | You can select your checklist file from here. If you load the checklist from here. The file path will be stored and each time extension is loaded the checklist will autoload.
22 | Also once you add a new vulnerability in the checklist tab with create button. the data will also be updated in the CSV file.
23 |
24 | ### One Click Import Export
25 |
26 | You can import or export the API Mapper and vulnerability data with a single button. The extension will try to check if the autosave directory is selected and saved and then it will look for the ```vulnerability.csv``` and ```APIMapper.csv```files in that directory to import.
27 | To export only the autosave directory should be saved.
28 |
29 | ### Auto Logging
30 |
31 | The extension will add each request from the proxy to API Mapper if the Auto Logging is set to ON. it will only add the data in API Mapper if the URL is in scope from the Burp Suite Target tab.
32 | You can also select the excluded files. The default setting is set to OFF.
33 |
34 | ### Auto Save
35 |
36 | By default, the Auto Save is off. You can turn on Auto Save.
37 |
--------------------------------------------------------------------------------
/DOC/README.md:
--------------------------------------------------------------------------------
1 | # Pentest Mapper
2 |
3 | Pentest Mapper is a Burp Suite extension that integrates the Burp Suite request logging with a custom application testing checklist.
4 | The extension provides a straightforward flow for application penetration testing. The extension includes functionalities to allow users to map the flow of the application for pentesting to better analyse the application and its vulnerabilities.
5 | The API calls from each flow can be connected with the function or flow name. The extension allows users to map or connect each flow or API to vulnerability with the custom checklist.
6 |
7 |
8 |
9 | # Documentation
10 | - [Installation](installation.md)
11 | - [Checklist](Checklist.md)
12 | - [API Mapper](API-Mapper.md)
13 | - [Vulnerabilites](Vulnerabilites.md)
14 | - [Config](Config.md)
15 |
16 |
17 | # Features
18 |
19 | - Allow you to load a custom checklist
20 | - Map Each API and HTTP request to keep track of progress
21 | - Connect the Mapped API with flow and functionalities
22 | - Write Pentesting test cases for each HTTP request and APIs
23 | - Map Each Vulnerable API to vulnerabilitst based on severity and parameter
24 | - Set Auto save and checklist and Auto Map
25 |
--------------------------------------------------------------------------------
/DOC/Vulnerabilites.md:
--------------------------------------------------------------------------------
1 | # Vulnerabilites
2 |
3 | The Vulnerabilities tab allows you to keep track of each vulnerability found during the testing of the application. You can add the URL, Parameter, severity and name of the vulnerability.
4 |
5 | 
6 |
7 | ## Overview
8 |
9 | ### Search
10 |
11 | At the top of the Vulnerabilities tab, we have a search button same as a checklist which allows us to filter the data from the table.
12 |
13 |
14 | ### Export Vulnerabilities
15 |
16 | Since the BurpSuite doesn't allow extension to save the extension data within the burp suite project file. We have the option to save the vulnerability output in a CSV file.
17 | You can click on the Export Vulnerabilities button and select the directory and it will create a CSV file for you.
18 |
19 | ### Import Vulnerabilities
20 |
21 | Once you save your Vulnerabilitesr Data you also have the option to load that data again in the extension with the Import Vulnerabilities button.
22 | You can click on the button, select the CSV file and it will load the data in the Vulnerabilities.
23 |
24 | ### Vulnerabilities Table
25 |
26 | Now we have a table with multiple columns.
27 |
28 | - The 1st column `URL ` will show the full URL of the request.
29 | - The 2nd column `Parameter` will allow you to enter the vulnerable parameter name. You can double-click and edit the cell
30 | - The 3rd column `Vulnerability` will show a drop-down list from the checklist tab. You can select the vulnerability to which the particular API is vulnerable.
31 | - The 4th column `severity` will again show a drop-down list where you can select if the vulnerability is Critical, High, Medium, Low or Informational.
32 |
33 |
34 | ### Adding Data to Vulnerabilities Table
35 |
36 | Same as API Mapper you can add the data in the Vulnerabilities table from BurpSuite Target, Proxy History, Repeater, Intruder etc. You can right-click on any selected request,
37 | and select extension --> Pentest Mapper --> API Mapper. Now you can view the request inside the table.
38 |
39 | You can also right-click on any row in API MApper and select send to vulnerability to add the data here.
40 |
--------------------------------------------------------------------------------
/DOC/_images/APIMapper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/DOC/_images/APIMapper.png
--------------------------------------------------------------------------------
/DOC/_images/Burp-Suite-Extender.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/DOC/_images/Burp-Suite-Extender.png
--------------------------------------------------------------------------------
/DOC/_images/Checklist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/DOC/_images/Checklist.png
--------------------------------------------------------------------------------
/DOC/_images/Config.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/DOC/_images/Config.png
--------------------------------------------------------------------------------
/DOC/_images/Load.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/DOC/_images/Load.png
--------------------------------------------------------------------------------
/DOC/_images/Proxy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/DOC/_images/Proxy.png
--------------------------------------------------------------------------------
/DOC/_images/Vulnerability.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/DOC/_images/Vulnerability.png
--------------------------------------------------------------------------------
/DOC/_images/Zip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/DOC/_images/Zip.png
--------------------------------------------------------------------------------
/DOC/_sidebar.md:
--------------------------------------------------------------------------------
1 | - [Installation](installation.md)
2 | - [Checklist](Checklist.md)
3 | - [API Mapper](API-Mapper.md)
4 | - [Vulnerabilites](Vulnerabilites.md)
5 | - [Config](Config.md)
6 |
--------------------------------------------------------------------------------
/DOC/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Pentest Mapper
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/DOC/installation.md:
--------------------------------------------------------------------------------
1 | # Installation
2 |
3 | You need to add the Jython in your burp Suite before your start installing the extension. You can use the BurpSuite guide to complete the process from [Here](https://burpsuite.guide/runtimes/python/).
4 |
5 | ## Burp Suite Extender
6 |
7 | You can download the Pentest Mapper within the BurpSuite extender.
8 |
9 | 
10 | - GO to the Extender tab in the Burp Suite
11 | - Click on BApp Store
12 | - Search `Pentest Mapper` and Click on the install button
13 |
14 | ## Manual
15 | The manual installation process is simple. You need to download the repository and load the `PentestMapper.py` file in the burp Suite.
16 |
17 |
18 |
19 | - You can download the repository as a git clone or you can download the zip file as well.
20 |
21 | ```
22 | git clone https://github.com/Anof-cyber/Pentest-Mapper
23 | ```
24 |
25 | 
26 |
27 | 
28 |
29 | - Open your BurpSuite Click on the Extender Tab.
30 | - Click on Add button and select python from the dropdown list
31 | - Click on the select file button and select the `pentestmapper.py` file
32 |
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/PentestMapper.py:
--------------------------------------------------------------------------------
1 | from burp import (IBurpExtender, ITab, IContextMenuFactory, IContextMenuInvocation,
2 | IHttpService, IParameter, IMessageEditorController, IHttpRequestResponse, IProxyListener,
3 | IMessageEditorTabFactory, IMessageEditorTab, IExtensionStateListener )
4 |
5 | from java.awt import (BorderLayout, FlowLayout , Dimension, Font, Color, Cursor)
6 |
7 | from javax.swing import (JMenuItem, JTable, JButton, JTextField, GroupLayout, JTabbedPane, JTextPane, RowFilter
8 | ,JScrollPane, JSplitPane, JLabel, JPopupMenu, JComboBox, DefaultCellEditor, JToggleButton, JTextArea, DefaultComboBoxModel
9 | ,JPanel, JFileChooser, JSeparator, Box )
10 |
11 | from javax.swing.event import ListSelectionListener
12 |
13 | from javax.swing.table import ( DefaultTableModel, AbstractTableModel, TableRowSorter ,TableCellEditor)
14 | from javax.swing.SwingConstants import VERTICAL
15 | from java.lang import Short
16 | import javax.swing.Box
17 | from javax.swing.filechooser import FileNameExtensionFilter
18 | from urlparse import urlparse
19 | import time, csv, sys, os, base64, zlib
20 | from threading import Lock
21 |
22 |
23 | from pentestmapper.autolog import Autologclas
24 | from pentestmapper.APIMapper import LogEntry, Table, CustomTableModel
25 | from pentestmapper.autosave import Autosaveclas
26 |
27 | sys.path.append("./lib/swingx-all-1.6.4.jar")
28 | from org.jdesktop.swingx.autocomplete import AutoCompleteDecorator
29 |
30 |
31 |
32 | csv.field_size_limit(sys.maxsize)
33 |
34 |
35 |
36 |
37 | # Creating Burp Extend Class
38 | class BurpExtender(IBurpExtender, ITab, IContextMenuFactory, AbstractTableModel, IMessageEditorController, IExtensionStateListener):
39 |
40 |
41 | def registerExtenderCallbacks(self, callbacks):
42 | self.callbacks = callbacks
43 | self.helpers = callbacks.getHelpers()
44 |
45 | # Allowing debugging
46 | sys.stdout = callbacks.getStdout()
47 | sys.stderr = callbacks.getStderr()
48 |
49 | # Informing Burp suite the name of the extension
50 | callbacks.setExtensionName("Pentest Mapper")
51 |
52 | #adding extension state listner if extenion loaded on unloaded
53 | callbacks.registerExtensionStateListener(self)
54 |
55 |
56 | # Creating a output after loading
57 | callbacks.printOutput("Author: Sourav Kalal Aka AnoF")
58 | callbacks.printOutput("Version: 1.7.3")
59 | callbacks.printOutput("https://github.com/Anof-cyber/Pentest-Mapper")
60 |
61 | callbacks.registerContextMenuFactory(self)
62 |
63 | self.tab = JPanel(BorderLayout())
64 | self.tabbedPane = JTabbedPane()
65 | self.tab.add("Center", self.tabbedPane)
66 |
67 | self._log = list()
68 | self._vuln = list()
69 | self._lock = Lock()
70 |
71 | # Creating Another Tab in the extension tab
72 | # Creating the First tab named as CheckList
73 | self.firstTab = JPanel()
74 | self.firstTab.layout = BorderLayout()
75 | self.tabbedPane.addTab("CheckList", self.firstTab)
76 | callbacks.addSuiteTab(self)
77 |
78 | # Creating a Import button in CheckList Tab
79 | self.ChecklistbuttonPanel = JPanel()
80 | self.searchchecklist = JTextField('', 15)
81 | self.ChecklistbuttonPanel.add(self.searchchecklist)
82 | self.ChecklistbuttonPanel.add(JButton("Search", actionPerformed=self.searchinchecklist))
83 |
84 |
85 | # adding the import button with onclick action which refers to the function below
86 | self.ChecklistbuttonPanel.add(JButton(
87 | "Import CheckList", actionPerformed=self.importchecklist))
88 | self.createchecklistbutton = JButton("Create CheckList", actionPerformed=self.createtestcases)
89 | #self.ChecklistbuttonPanel.add(JButton("Create CheckList", actionPerformed=self.createtestcases))
90 | self.ChecklistbuttonPanel.add(self.createchecklistbutton)
91 | self.firstTab.add(self.ChecklistbuttonPanel, BorderLayout.PAGE_START)
92 |
93 |
94 | # Creating a tab in CheckList tab which will show the data from the import checlist
95 | self.tablePanel = JPanel()
96 | self.colNames = ('Sr', 'Test-Cases')
97 | self.dataModel = CustomDefaultTableModelHosts(None, self.colNames)
98 | self.table = JTable(self.dataModel)
99 | self.table.getTableHeader().setReorderingAllowed(False)
100 | self.table.setAutoCreateRowSorter(True)
101 | self.scrollPane = JScrollPane(self.table)
102 | self.sorter = TableRowSorter(self.dataModel);
103 |
104 | self.table.setRowSorter(self.sorter)
105 | X_BASE2 = 200 # send to leff
106 | # 3rd one send to right
107 |
108 | self.scrollPane.getViewport().setView((self.table))
109 | self.firstTab.add(self.scrollPane, BorderLayout.CENTER)
110 |
111 | # Creating Second Tab
112 | self.secondTab = JPanel()
113 | self.secondTab.layout = BorderLayout()
114 | self.tabbedPane.addTab("API Mapper", self.secondTab)
115 |
116 |
117 | # creating UI for button and button in api mapper tab
118 | self.APIMapperButtonPanel = JPanel()
119 | self.searchapimapper = JTextField('', 15)
120 | self.APIMapperButtonPanel.add(self.searchapimapper)
121 | self.APIMapperButtonPanel.add(JButton("Search", actionPerformed=self.searchinapimapper))
122 |
123 | # adding the import button with onclick action which refers to the function below
124 | self.APIMapperButtonPanel.add(JButton(
125 | "Save Project", actionPerformed=self.savelogger))
126 | self.APIMapperButtonPanel.add(JButton(
127 | "Load Project", actionPerformed=self.importlogger))
128 | self.secondTab.add(self.APIMapperButtonPanel, BorderLayout.PAGE_START)
129 |
130 |
131 | # Creating a UI for table in api mapper tab
132 | self.tablePanel2 = JPanel()
133 |
134 |
135 | '''
136 | creating a menu which will be added with the table in api mapper for right click
137 | also assigning a fumction to handle the event when click
138 | '''
139 | popupMenu = JPopupMenu()
140 | sendVulneraility = JMenuItem("Add to Vulnerabilities", actionPerformed=self.sendVulnItem)
141 | sendRepeaterItem = JMenuItem("Send request to Repeater", actionPerformed=self.sendRepeaterItem)
142 | deleterow = JMenuItem("Delete Row", actionPerformed=self.deleterow)
143 | popupMenu.add(sendVulneraility)
144 | popupMenu.add(sendRepeaterItem)
145 | popupMenu.add(deleterow)
146 |
147 | self.comboBox1 = JComboBox()
148 | self.comboBox1.addItem(None)
149 | self.comboBox1.addItem("Pending")
150 | self.comboBox1.addItem("In Progress")
151 | self.comboBox1.addItem("Completed")
152 |
153 |
154 | # creating a message editor from burp to show request
155 | self.requestViewer = callbacks.createMessageEditor(None, True)
156 | self.responseViewer = callbacks.createMessageEditor(None, True)
157 |
158 | # creating a table with custom model for api mapper
159 |
160 |
161 | self.apimappertable = CustomTableModel(self)
162 |
163 | self.logTable = Table(self, self.apimappertable)
164 |
165 |
166 | # allowed colum size for api mapper tab/table
167 | self.logTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF)
168 | self.logTable.getTableHeader().setReorderingAllowed(False)
169 | self.logTable.getColumnModel().getColumn(0).setPreferredWidth(25)
170 | self.logTable.getColumnModel().getColumn(1).setPreferredWidth(400)
171 | self.logTable.getColumnModel().getColumn(2).setPreferredWidth(50)
172 | self.logTable.getColumnModel().getColumn(3).setPreferredWidth(750)
173 | self.logTable.getColumnModel().getColumn(4).setPreferredWidth(142)
174 | self.logTable.setRowSelectionAllowed(True)
175 |
176 | comboColumn1 = self.logTable.getColumnModel().getColumn(5)
177 | comboColumn1.setCellEditor(DefaultCellEditor(self.comboBox1))
178 |
179 | #adding a right click menu in the table in api mapper
180 | self.logTable.setComponentPopupMenu(popupMenu)
181 |
182 |
183 |
184 | # Creating a scroller for table in api mapper and also width hight for table
185 | self.scrollPane2 = JScrollPane(self.logTable)
186 |
187 | self.scrollPane2.getViewport().setView((self.logTable))
188 | self.sorter2 = TableRowSorter(self.apimappertable);
189 | self.logTable.setRowSorter(self.sorter2)
190 |
191 |
192 | # creating a save test case button and UI and a split pane
193 | self.CommentsSplitPane = JSplitPane(JSplitPane.VERTICAL_SPLIT);
194 | self.bottomviewpanel = JPanel()
195 | self.SaveTestCasePanel = JPanel(FlowLayout(FlowLayout.LEADING, 10, 10))
196 | self.SaveTestCasePanel.add(JButton(
197 | "Save TestCases", actionPerformed=self.SaveTestCases))
198 |
199 |
200 | #crearting a text box for test cases
201 | self.testcases = JTextPane()
202 | self.testcases.setContentType("text/plain");
203 | self.testcases.setEditable(True)
204 | penTesterCommentBoxScrollPane = JScrollPane(self.testcases)
205 |
206 | # creating a split in test cases to add button and text box
207 | self.CommentsSplitPane.setTopComponent(self.SaveTestCasePanel)
208 | self.CommentsSplitPane.setBottomComponent(penTesterCommentBoxScrollPane);
209 |
210 |
211 |
212 |
213 |
214 |
215 | #adding the tapped pane to create request and test cases
216 | self.editor_view = JTabbedPane()
217 | self.editor_view.addTab("Request", self.requestViewer.getComponent())
218 | self.editor_view.addTab("Response", self.responseViewer.getComponent())
219 | self.editor_view.addTab('Test Cases', self.CommentsSplitPane)
220 |
221 |
222 |
223 | # creating a split in api mapper with split size
224 | spl = JSplitPane(JSplitPane.VERTICAL_SPLIT)
225 |
226 |
227 | # adding the UI for split pane in api mapper tab
228 |
229 |
230 | spl.setLeftComponent(self.scrollPane2)
231 | spl.setRightComponent(self.editor_view)
232 |
233 | # adding the spilt part to api mapper tab
234 | self.secondTab.add(spl)
235 |
236 | # addinG the burp Defalut UI customization for the api mapper tab
237 | self.callbacks.customizeUiComponent(spl)
238 | self.callbacks.customizeUiComponent(self.logTable)
239 | self.callbacks.customizeUiComponent(self.scrollPane2)
240 | self.callbacks.customizeUiComponent(self.editor_view)
241 |
242 |
243 | # creating a new tab
244 | self.ThirdTab = JPanel()
245 | self.ThirdTab.layout = BorderLayout()
246 | self.tabbedPane.addTab("Vulnerabilities", self.ThirdTab)
247 |
248 |
249 | # creating the button and button location and width in vulnerability tab
250 | self.VulnerabilityButtonPanel = JPanel()
251 |
252 | # Search For Vulnerability UI
253 | self.searchvulnerability = JTextField('', 15)
254 | self.VulnerabilityButtonPanel.add(self.searchvulnerability)
255 | self.VulnerabilityButtonPanel.add(JButton("Search", actionPerformed=self.searchinvulnerability))
256 |
257 | # adding the import button with onclick action which refers to the function below
258 |
259 | self.VulnerabilityButtonPanel.add(JButton(
260 | "Export Vulnerabilities", actionPerformed=self.exportvulnerability))
261 | self.VulnerabilityButtonPanel.add(JButton(
262 | "Import Vulnerabilities", actionPerformed=self.importvulnerability))
263 |
264 | # adding the button in vulnerability tab
265 | self.ThirdTab.add(self.VulnerabilityButtonPanel, BorderLayout.PAGE_START)
266 |
267 |
268 |
269 | # creating the UI pannel for vulnerability tab --> table
270 | self.tablePanel3 = JPanel()
271 |
272 | # Creating a jcombobox that will show the selection option, and adding and none or empty item for selection
273 | self.comboBox = JComboBox()
274 | self.comboBox.addItem(None)
275 | self.comboBox.setEditable(True)
276 | self.combolist = []
277 | #self.comboBox.addActionListener(self.seachincombobox)
278 |
279 | AutoCompleteDecorator.decorate(self.comboBox)
280 |
281 |
282 | # Creating a seelction list for Severity on vulnerability table
283 | self.comboBox2 = JComboBox()
284 | self.comboBox2.addItem(None)
285 | self.comboBox2.addItem('Critical')
286 | self.comboBox2.addItem('High')
287 | self.comboBox2.addItem('Medium')
288 | self.comboBox2.addItem('Low')
289 | self.comboBox2.addItem('Informational')
290 |
291 |
292 |
293 |
294 | # creating the table to vulnerability tab
295 | #self.colNames3 = ['URL', 'Parameters','Vulnerability','Severity','Request','Response']
296 | #self.dataModel2 = CustomDefaultTableModelHosts2(None,self.colNames3)
297 | self.dataModel2 = CustomTableModelVuln(self)
298 |
299 |
300 |
301 | self.table3 = JTable(self.dataModel2)
302 | self.table3.setAutoCreateRowSorter(True)
303 | self.table3.getColumnModel().getColumn(2).setPreferredWidth(0)
304 | self.table3.getColumnModel().getColumn(1).setPreferredWidth(0)
305 | self.table3.getTableHeader().setReorderingAllowed(False)
306 |
307 |
308 |
309 | #comboColumn = self.table3.getColumnModel().getColumn(2)
310 | #comboColumn.setCellEditor(DefaultCellEditor(self.comboBox))
311 |
312 |
313 | self.editor = AutocompleteTableCellEditor(self.combolist,self.table3)
314 | comboColumn = self.table3.getColumnModel().getColumn(2)
315 | comboColumn.setCellEditor(self.editor)
316 |
317 |
318 |
319 |
320 |
321 | comboColumn2 = self.table3.getColumnModel().getColumn(3)
322 | comboColumn2.setCellEditor(DefaultCellEditor(self.comboBox2))
323 |
324 | #self.table3.removeColumn(self.table3.getColumnModel().getColumn(5));
325 | #self.table3.removeColumn(self.table3.getColumnModel().getColumn(4));
326 | self.table3.getColumnModel().getColumn(4).setMinWidth(0);
327 | self.table3.getColumnModel().getColumn(4).setMaxWidth(0);
328 | self.table3.getColumnModel().getColumn(4).setWidth(0);
329 | self.table3.getColumnModel().getColumn(5).setMinWidth(0);
330 | self.table3.getColumnModel().getColumn(5).setMaxWidth(0);
331 | self.table3.getColumnModel().getColumn(5).setWidth(0);
332 |
333 |
334 |
335 |
336 | # Adding a right click menu for Vulnerability
337 | popupMenu2 = JPopupMenu()
338 | deletevulnerability = JMenuItem("Delete Vulnerability", actionPerformed=self.deletevuln)
339 | popupMenu2.add(deletevulnerability)
340 | self.table3.setComponentPopupMenu(popupMenu2)
341 |
342 |
343 |
344 | # adding the table size, width, location and will add the scroller to the table
345 | self.scrollPane3 = JScrollPane(self.table3)
346 | X_BASE3 = 1 # send to leff
347 | # 3rd one send to right
348 | self.scrollPane3.setBounds(X_BASE3 + 10, 20, 1900, 850)
349 | self.scrollPane3.setPreferredSize(Dimension(1500, 700))
350 | self.scrollPane3.getViewport().setView((self.table3))
351 | self.tablePanel3.add(self.scrollPane3)
352 |
353 |
354 | self.requestViewer1 = callbacks.createMessageEditor(None, True)
355 | self.responseViewer1 = callbacks.createMessageEditor(None, True)
356 |
357 | self.editor_view1 = JTabbedPane()
358 | self.editor_view1.addTab("Request", self.requestViewer1.getComponent())
359 | self.editor_view1.addTab("Response", self.responseViewer1.getComponent())
360 | spl1 = JSplitPane(JSplitPane.VERTICAL_SPLIT)
361 |
362 | spl1.setLeftComponent(self.scrollPane3)
363 | spl1.setRightComponent(self.editor_view1)
364 |
365 | #listener = CustomSelectionListener(self.dataModel2, self.requestViewer1, self.responseViewer1)
366 | #self.table3.getSelectionModel().addListSelectionListener(listener)
367 |
368 | listener = CustomSelectionListener(self.table3, self.requestViewer1, self.responseViewer1)
369 | self.table3.getSelectionModel().addListSelectionListener(listener)
370 |
371 |
372 |
373 |
374 |
375 | # adding the table UI to vulnerability tab
376 | self.ThirdTab.add(spl1, BorderLayout.CENTER)
377 | #self.ThirdTab.add(self.scrollPane3, BorderLayout.CENTER)
378 |
379 |
380 | # Config Tab
381 | self.FourthTab = JPanel()
382 | self.FourthTab.layout = BorderLayout()
383 | self.tabbedPane.addTab("Config", self.FourthTab)
384 | self.buttonPanel5 = JPanel()
385 |
386 | layout = GroupLayout(self.buttonPanel5)
387 | self.buttonPanel5.setLayout(layout)
388 |
389 |
390 |
391 |
392 | jButton1 = JButton("Choose Directory", actionPerformed=self.Autosavepath)
393 | jLabel1 = JLabel()
394 | self.autosavepath = JLabel();
395 | self.autosavepath.setForeground(Color(255, 102, 51))
396 | self.timeperid = JLabel();
397 | self.timerbox = JTextField(5);
398 | jLabel4 = JLabel();
399 | button2 = JButton("Choose File", actionPerformed=self.Autosavepath2)
400 | self.Checklistfilepath = JLabel()
401 | self.Checklistfilepath.setForeground(Color(255, 102, 51))
402 | Savechecklistfileconfig = JButton("Save Path", actionPerformed=self.saveautoconfigdata2)
403 | Savechecklistfileconfig.setBackground(Color(255, 102, 51))
404 | Savechecklistfileconfig.setFont(Font("Segoe UI", 1, 12))
405 | Savechecklistfileconfig.setForeground(Color(255, 255, 255))
406 |
407 | self.saveconfigbutton = JButton("Save Config", actionPerformed=self.saveautoconfigdata)
408 | self.saveconfigbutton.setBackground(Color(255, 102, 51));
409 | self.saveconfigbutton.setFont(Font("Segoe UI", 1, 12))
410 | self.saveconfigbutton.setForeground(Color(255, 255, 255))
411 | jLabel1.setText("Select the Auto Save Output Directory :")
412 |
413 | self.timeperid.setText("Set Time for Auto Save :")
414 |
415 | self.timerbox.setText("self.timerbox");
416 |
417 | self.timeerror = JLabel();
418 | self.timeerror.setForeground(Color(204, 0, 0))
419 | importall = JButton("Import All", actionPerformed=self.autoimportall)
420 | jSeparator1 = JSeparator()
421 | jSeparator2 = JSeparator()
422 | jSeparator1.setPreferredSize(Dimension(50, 100))
423 |
424 |
425 | jSeparator2.setPreferredSize(Dimension(50, 100))
426 |
427 | AutoSaveConfigHeading = JLabel()
428 | AutoSaveConfigHeading.setFont(Font("Segoe UI", 1, 14))
429 | AutoSaveConfigHeading.setToolTipText("")
430 | AutoloadChecklistHeading = JLabel();
431 | AutoloadChecklistHeading.setFont(Font("Segoe UI", 1, 14))
432 | AutoloadChecklistHeading.setToolTipText("")
433 | Exportall = JButton("Export All", actionPerformed=self.autoexportall);
434 | AutoSaveConfigHeading.setFont(Font("Segoe UI", 1, 14));
435 | AutoSaveConfigHeading.setText("Auto Save Config");
436 | AutoSaveConfigHeading.setToolTipText("");
437 |
438 | AutoloadChecklistHeading.setFont(Font("Segoe UI", 1, 14))
439 | AutoloadChecklistHeading.setText("Auto Load Checklist");
440 | AutoloadChecklistHeading.setToolTipText("")
441 |
442 |
443 | jLabel4.setText("Select Auto Load Checklist File :")
444 | OneclickImportExportLabel = JLabel()
445 | OneclickImportExportLabel.setText("Import and Export API Mapper and Vulnerabilities from Above Selected Directory")
446 | Singleclickfilename = JLabel()
447 | Singleclickfilename.setForeground(Color(204, 0, 0))
448 | Singleclickfilename.setText("Note: File Name should be APIMapper.csv & Vulnerability.csv")
449 | jSeparator3 = JSeparator()
450 | jSeparator3.setPreferredSize(Dimension(50, 100))
451 | AutologLabel = JLabel()
452 | AutologLabel.setText("Auto Log from Proxy to API Mapper :")
453 | AutologHeading1 = JLabel()
454 | AutologHeading1.setFont(Font("Segoe UI", 1, 14))
455 | AutologHeading1.setText("Auto Logging");
456 | AutologHeading1.setToolTipText("")
457 | self.AutoLoggingtoggle = JToggleButton()
458 | self.AutoLoggingtoggle.addItemListener(self.AutoLogtogglelistener)
459 | self.AutoLoggingtoggle.setBackground(Color(128, 128, 128));
460 | self.AutoLoggingtoggle.setFont(Font("Segoe UI", 1, 14))
461 | self.AutoLoggingtoggle.setText("ON");
462 | self.AutoLoggingtoggle.setCursor(Cursor(Cursor.DEFAULT_CURSOR))
463 | self.ToggleStatus = JLabel()
464 | self.ToggleStatus.setForeground(Color(255, 102, 51))
465 | self.ToggleStatus.setText("Current Status: OFF")
466 | oneclickimportexportHeading = JLabel()
467 | oneclickimportexportHeading.setFont(Font("Segoe UI", 1, 14))
468 | oneclickimportexportHeading.setText("One Click Import Export")
469 | oneclickimportexportHeading.setToolTipText("")
470 | self.SingleclickimportMapper = JLabel()
471 | self.SingleclickimportMapper.setForeground(Color(255, 102, 51));
472 |
473 | self.SingleclickimportVulnerabilities = JLabel()
474 | self.SingleclickimportVulnerabilities.setForeground(Color(255, 102, 51));
475 |
476 | self.SingleclickexportMapper = JLabel()
477 | self.SingleclickexportMapper.setForeground(Color(255, 102, 51))
478 |
479 | self.SingleclickexportVulnerabilities = JLabel()
480 | self.SingleclickexportVulnerabilities.setForeground(Color(255, 102, 51))
481 |
482 | Excludefilelabel = JLabel()
483 | Excludefilelabel.setText("Exclude Files :")
484 | Excludefilebutton = JButton("Save", actionPerformed=self.excludefilebuttonclick)
485 | Excludefilebutton.setBackground(Color(255, 102, 51))
486 | Excludefilebutton.setFont(Font("Segoe UI", 1, 12))
487 | Excludefilebutton.setForeground(Color(255, 255, 255))
488 | AutosaveHeading3 = JLabel()
489 | AutosaveHeading3.setFont(Font("Segoe UI", 1, 14))
490 | AutosaveHeading3.setText("Auto Save")
491 | AutosaveHeading3.setToolTipText("")
492 | self.AutoSavetoggle = JToggleButton()
493 | self.AutoSavetoggle.setBackground(Color(128, 128, 128))
494 | self.AutoSavetoggle.setFont(Font("Segoe UI", 1, 14))
495 | self.AutoSavetoggle.setText("ON")#, itemStateChanged = self.AutoSavetogglelistener)
496 | self.AutoSavetoggle.addItemListener(self.AutoSavetogglelistener)
497 | self.AutoSavetoggle.setCursor(Cursor(Cursor.DEFAULT_CURSOR))
498 | self.Autosavechecker = False
499 | AutoSaveLabel = JLabel()
500 | AutoSaveLabel.setText("Auto Save API Mapper and Vulnerability :")
501 | self.AutoSaveToggleStatus = JLabel()
502 | self.AutoSaveToggleStatus.setForeground(Color(255, 102, 51))
503 | self.AutoSaveToggleStatus.setText("Current Status: OFF")
504 | self.AutoSaveErrorlabel = JLabel()
505 | self.AutoSaveErrorlabel.setBackground(Color(0, 0, 0))
506 | self.AutoSaveErrorlabel.setForeground(Color(204, 0, 0))
507 | #AutoSaveErrorlabel.setText("Auto Save Requires Auto Save Config with Valid Directory Selected")
508 | jScrollPane1 = JScrollPane()
509 | self.Excludefiletextfield = JTextArea()
510 | self.Excludefiletextfield.setColumns(20)
511 | self.Excludefiletextfield.setRows(1)
512 | self.Excludefiletextfield.setTabSize(6)
513 | self.Excludefiletextfield.setText("SCRIPT,JPEG,CSS,PNG,IMAGE,APP")
514 | jScrollPane1.setViewportView(self.Excludefiletextfield)
515 | jSeparator5 = JSeparator()
516 | jSeparator5.setOrientation(VERTICAL)
517 |
518 |
519 |
520 | layout.setHorizontalGroup(
521 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
522 | .addGroup(layout.createSequentialGroup()
523 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
524 | .addGroup(layout.createSequentialGroup()
525 | .addGap(26, 26, 26)
526 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
527 | .addGroup(layout.createSequentialGroup()
528 | .addComponent(AutologHeading1)
529 | .addGap(125, 125, 125)
530 | .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE))
531 | .addComponent(oneclickimportexportHeading)
532 | .addComponent(Singleclickfilename)
533 | .addComponent(OneclickImportExportLabel)
534 | .addGroup(layout.createSequentialGroup()
535 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
536 | .addComponent(jLabel1)
537 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
538 | .addComponent(AutoloadChecklistHeading)
539 | .addComponent(self.timeperid))
540 | .addComponent(jLabel4))
541 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
542 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
543 | .addGroup(layout.createSequentialGroup()
544 | .addComponent(button2)
545 | .addGap(37, 37, 37)
546 | .addComponent(self.Checklistfilepath))
547 | .addGroup(layout.createSequentialGroup()
548 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
549 | .addComponent(jButton1)
550 | .addComponent(self.timerbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
551 | .addComponent(self.saveconfigbutton))
552 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
553 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
554 | .addComponent(self.timeerror)
555 | .addComponent(self.autosavepath)))
556 | .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)
557 | .addComponent(Savechecklistfileconfig)
558 | .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)))
559 | .addGroup(layout.createSequentialGroup()
560 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
561 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, False)
562 | .addGroup(layout.createSequentialGroup()
563 | .addComponent(Exportall)
564 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
565 | .addComponent(self.SingleclickexportMapper))
566 | .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
567 | .addComponent(importall)
568 | .addGap(18, 18, 18)
569 | .addComponent(self.SingleclickimportMapper)))
570 | .addGroup(layout.createSequentialGroup()
571 | .addComponent(AutologLabel)
572 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
573 | .addComponent(self.AutoLoggingtoggle, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE)))
574 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
575 | .addGroup(layout.createSequentialGroup()
576 | .addGap(24, 24, 24)
577 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
578 | .addComponent(self.SingleclickimportVulnerabilities)
579 | .addComponent(self.SingleclickexportVulnerabilities)))
580 | .addGroup(layout.createSequentialGroup()
581 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
582 | .addGroup(layout.createSequentialGroup()
583 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
584 | .addComponent(self.ToggleStatus))
585 | .addGroup(layout.createSequentialGroup()
586 | .addGap(52, 52, 52)
587 | .addComponent(Excludefilebutton)))
588 | .addGap(45, 45, 45)
589 | .addComponent(jSeparator5, javax.swing.GroupLayout.PREFERRED_SIZE, 12, javax.swing.GroupLayout.PREFERRED_SIZE)
590 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
591 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
592 | .addComponent(self.AutoSaveErrorlabel)
593 | .addComponent(AutoSaveLabel)
594 | .addGroup(layout.createSequentialGroup()
595 | .addComponent(self.AutoSavetoggle, javax.swing.GroupLayout.PREFERRED_SIZE, 73, javax.swing.GroupLayout.PREFERRED_SIZE)
596 | .addGap(18, 18, 18)
597 | .addComponent(self.AutoSaveToggleStatus))
598 | .addComponent(AutosaveHeading3)))))
599 | .addGroup(layout.createSequentialGroup()
600 | .addComponent(Excludefilelabel)
601 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
602 | .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
603 | .addGroup(layout.createSequentialGroup()
604 | .addGap(35, 35, 35)
605 | .addComponent(AutoSaveConfigHeading)))
606 | .addContainerGap(133, Short.MAX_VALUE))
607 | );
608 | layout.setVerticalGroup(
609 | layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
610 | .addGroup(layout.createSequentialGroup()
611 | .addContainerGap()
612 | .addComponent(AutoSaveConfigHeading)
613 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
614 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
615 | .addComponent(jLabel1)
616 | .addComponent(jButton1)
617 | .addComponent(self.autosavepath))
618 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
619 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
620 | .addComponent(self.timeperid)
621 | .addComponent(self.timerbox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
622 | .addComponent(self.timeerror))
623 | .addGap(18, 18, 18)
624 | .addComponent(self.saveconfigbutton)
625 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
626 | .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
627 | .addGap(2, 2, 2)
628 | .addComponent(AutoloadChecklistHeading)
629 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
630 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
631 | .addComponent(jLabel4)
632 | .addComponent(button2)
633 | .addComponent(self.Checklistfilepath))
634 | .addGap(18, 18, 18)
635 | .addComponent(Savechecklistfileconfig)
636 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
637 | .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
638 | .addGap(1, 1, 1)
639 | .addComponent(oneclickimportexportHeading)
640 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
641 | .addComponent(OneclickImportExportLabel)
642 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
643 | .addComponent(Singleclickfilename)
644 | .addGap(18, 18, 18)
645 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
646 | .addComponent(importall)
647 | .addComponent(self.SingleclickimportMapper)
648 | .addComponent(self.SingleclickimportVulnerabilities))
649 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
650 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
651 | .addComponent(Exportall)
652 | .addComponent(self.SingleclickexportMapper)
653 | .addComponent(self.SingleclickexportVulnerabilities))
654 | .addGap(18, 18, 18)
655 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
656 | .addGroup(layout.createSequentialGroup()
657 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
658 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
659 | .addComponent(AutologHeading1)
660 | .addComponent(AutosaveHeading3))
661 | .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE))
662 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
663 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
664 | .addComponent(AutologLabel)
665 | .addComponent(self.AutoLoggingtoggle, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE)
666 | .addComponent(self.ToggleStatus))
667 | .addGap(18, 18, 18)
668 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
669 | .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
670 | .addComponent(Excludefilelabel)
671 | .addComponent(Excludefilebutton))
672 | .addGap(0, 0, Short.MAX_VALUE))
673 | .addGroup(layout.createSequentialGroup()
674 | .addGap(22, 22, 22)
675 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
676 | .addGroup(layout.createSequentialGroup()
677 | .addComponent(AutoSaveLabel)
678 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
679 | .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
680 | .addComponent(self.AutoSavetoggle, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE)
681 | .addComponent(self.AutoSaveToggleStatus))
682 | .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
683 | .addComponent(self.AutoSaveErrorlabel))
684 | .addComponent(jSeparator5, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE))
685 | .addContainerGap(187, Short.MAX_VALUE))))
686 | )
687 |
688 |
689 |
690 | self.FourthTab.add(self.buttonPanel5)#,BorderLayout.NORTH)
691 |
692 |
693 | # Loading auto save time,path and auto load checklist and auto log exclude files from burp config
694 | self.path = callbacks.loadExtensionSetting('path')
695 | self.time = callbacks.loadExtensionSetting('time')
696 | self.loadexcludefiles = callbacks.loadExtensionSetting('excludefilestolog')
697 | self.checklistpath = callbacks.loadExtensionSetting('checklistpath')
698 | self.timerbox.setText(self.time)
699 | self.autosavepath.setText(self.path)
700 |
701 |
702 |
703 | self.autoloadchecklist = 0
704 | self.autosavelocation = 0
705 | self.extensionload = True
706 |
707 |
708 | # Validing the content og extension loaded config
709 | if self.loadexcludefiles == None:
710 | self.loadexcludefiles = "SCRIPT,JPEG,CSS,PNG,IMAGE,APP".upper()
711 | else:
712 | self.Excludefiletextfield.setText(self.loadexcludefiles)
713 |
714 | if self.time == None:
715 | self.time = 10
716 | self.timerbox.setText(str(self.time))
717 | else:
718 | pass
719 |
720 | if self.path == None:
721 | self.path = "Please select the Directory"
722 | self.autosavepath.setText(self.path)
723 | else:
724 | pass
725 |
726 | self.callbacks.printOutput("\nAuto Save Time = " + str(self.time))
727 | self.callbacks.printOutput("Auto Save Path = " + self.path +"\n")
728 |
729 |
730 | # Loading the checkling if auto load checklist configured
731 | if self.checklistpath == None:
732 | self.callbacks.printOutput(str(self.checklistpath))
733 | self.Checklistfilepath.setText("Select the Checklist file")
734 | else:
735 | self.comboBox.removeAllItems()
736 | self.comboBox.addItem(None)
737 | self.dataModel.setRowCount(0)
738 | with open(self.checklistpath, 'rb') as f:
739 | reader2 = csv.reader(f, delimiter=',')
740 | for rows in reader2:
741 | SR = rows[0]
742 | title = rows[1]
743 | obj = [SR,title]
744 | self.dataModel.addRow(obj)
745 | #self.comboBox.addItem(str(title))
746 | self.combolist.append(str(title))
747 | combo_model = DefaultComboBoxModel(self.combolist)
748 | self.editor.comboBox.setModel(combo_model)
749 | f.close()
750 | self.Checklistfilepath.setText(self.checklistpath)
751 |
752 |
753 |
754 |
755 |
756 | # Validating if extension is unloaded to stop all running process ( Auto Save and Auto Log)
757 | def extensionUnloaded(self):
758 | self.extensionload = False
759 | self.Autosavechecker = False
760 | self.Autologcheck = False
761 |
762 |
763 | # Listner to validate if auto Log is on or off
764 | def AutoLogtogglelistener(self,e):
765 | self.AutoLoggingtoggle = e.getItem()
766 | if self.AutoLoggingtoggle.isSelected():
767 | self.AutoLoggingtoggle.setText("OFF")
768 | self.AutoLoggingtoggle.setBackground(Color(255, 255, 255))
769 | self.ToggleStatus.setText("Current Status: ON")
770 | self.Autologcheck = True
771 | self.callbacks.registerProxyListener(Autologclas(self))
772 | #Autologclas(self)
773 |
774 |
775 | else:
776 | self.AutoLoggingtoggle.setText("ON")
777 | self.AutoLoggingtoggle.setBackground(Color(128, 128, 128))
778 | self.ToggleStatus.setText("Current Status: OFF")
779 | self.Autologcheck = False
780 | self.callbacks.removeProxyListener(Autologclas(self))
781 |
782 |
783 |
784 | # Listner to validate if auto Save is on or off
785 | def AutoSavetogglelistener(self, e):
786 | self.AutoSavetoggle = e.getItem()
787 | t = Autosaveclas(self)
788 | #p = multiprocessing.Process(target=t.run)
789 |
790 | if self.AutoSavetoggle.isSelected():
791 | if not os.path.isdir(str(self.path)):
792 | self.AutoSavetoggle.setBackground(Color(128, 128, 128))
793 | self.AutoSaveErrorlabel.setText("Auto Save Requires Auto Save Config with Valid Directory Selected")
794 | self.Autosavechecker = False
795 | else:
796 |
797 | self.AutoSavetoggle.setText("OFF")
798 | self.AutoSavetoggle.setBackground(Color(255, 255, 255))
799 | self.AutoSaveToggleStatus.setText("Current Status: ON")
800 | self.AutoSaveErrorlabel.setText("")
801 |
802 | self.Autosavechecker = True
803 | t.start()
804 |
805 | else:
806 | self.AutoSavetoggle.setText("ON")
807 | self.AutoSaveToggleStatus.setText("Current Status: OFF")
808 | self.AutoSavetoggle.setBackground(Color(128, 128, 128))
809 | self.AutoSaveErrorlabel.setText("")
810 | self.Autosavechecker = False
811 | t.stop()
812 |
813 |
814 | # Import All data if Import button clicked from config Tab
815 | def autoimportall(self,e):
816 | if os.path.isdir(str(self.path)):
817 | fname = "APIMapper"+"."+"csv"
818 | fnameWithPath = os.path.join(self.path,fname)
819 | if os.path.exists(fnameWithPath):
820 | with open(fnameWithPath, 'rb') as f:
821 | reader2 = csv.reader(f, delimiter=',')
822 | for rows in reader2:
823 | SR = rows[0]
824 | url = rows[1]
825 | method = rows[2]
826 | body = zlib.decompress(base64.b64decode(rows[3]))
827 | functionname = rows[4]
828 | request = zlib.decompress(base64.b64decode(rows[5]))
829 | testcases = rows[6]
830 | try:
831 | response = zlib.decompress(base64.b64decode(rows[7]))
832 | status = rows[8]
833 | except IndexError:
834 | response = None
835 | status = None
836 | self._log.append(LogEntry(SR,url, method,body,request,functionname,testcases,response,status))
837 |
838 | f.close()
839 | self.fireTableDataChanged()
840 | self.SingleclickimportMapper.setText("API Mapper Import Completed")
841 | fname2 = "Vulnerability"+"."+"csv"
842 | fnameWithPath2 = os.path.join(self.path,fname2)
843 | if os.path.exists(fnameWithPath2):
844 | with open(fnameWithPath2, 'rb') as f:
845 | reader2 = csv.reader(f, delimiter=',')
846 | for rows in reader2:
847 | URL = rows[0]
848 | Parameter = rows[1]
849 | Vulnerability = rows[2]
850 | try:
851 | Severity = rows[3]
852 | Request = zlib.decompress(base64.b64decode(rows[4]))
853 | Response = zlib.decompress(base64.b64decode(rows[5]))
854 | except IndexError:
855 | Severity = None
856 | Request = None
857 | Response = None
858 | obj = [URL,Parameter,Vulnerability,Severity,Request,Response]
859 | self.dataModel2.addRow(obj)
860 | f.close()
861 | self.SingleclickimportVulnerabilities.setText("Vulnerabilities Import Completed")
862 | else:
863 | self.autosavepath.setText("Output Directory doesn't exist")
864 | self.SingleclickimportVulnerabilities.setText("Vulnerabilities Import Failed")
865 | self.SingleclickimportMapper.setText("API Mapper Import Failed")
866 |
867 |
868 |
869 |
870 |
871 | # Export All data if Export button clicked from config Tab
872 | def autoexportall(self,e):
873 | if os.path.isdir(str(self.path)):
874 | if self.logTable.getRowCount() > 0:
875 | fname = "APIMapper"+"."+"csv"
876 | fnameWithPath = os.path.join(self.path,fname)
877 | if os.path.exists(fnameWithPath):
878 | os.remove(fnameWithPath)
879 | self.callbacks.printOutput("Saving the API Mapper output")
880 | with open(fnameWithPath, 'wb') as loggerdata:
881 | writer = csv.writer(loggerdata)
882 | for logEntry in self._log:
883 | writer.writerow([str(logEntry._sr), str(logEntry._url) ,str(logEntry._method) , base64.b64encode(zlib.compress(logEntry._postbody.encode('utf-8'))) ,str(logEntry._FunctionalityName) , base64.b64encode(zlib.compress(logEntry._requestResponse.encode('utf-8'))) ,str(logEntry._TestCases), base64.b64encode(zlib.compress(logEntry._response.encode('utf-8'))) ,str(logEntry._status)])
884 | loggerdata.close()
885 | self.SingleclickexportMapper.setText("API Mapper Export Completed")
886 | else:
887 | self.callbacks.printOutput("Skipping the API Mapper, Table is empty")
888 |
889 | self.SingleclickexportMapper.setText("API Mapper Export Failed. Empty Table")
890 | if self.dataModel2.getRowCount() > 0:
891 |
892 | fname2 = "Vulnerability"+"."+"csv"
893 | fnameWithPath2 = os.path.join(self.path,fname2)
894 | if os.path.exists(fnameWithPath2):
895 | os.remove(fnameWithPath2)
896 | self.callbacks.printOutput("Saving the Vulnerability output")
897 | totalrow = self.dataModel2.getRowCount()
898 | with open(fnameWithPath2, 'wb') as vulnerabilitydata:
899 | writer = csv.writer(vulnerabilitydata)
900 | for row in range (0, totalrow):
901 | url = self.dataModel2.getValueAt(row,0)
902 | paramter = self.dataModel2.getValueAt(int(row),1)
903 | Vulnerability = self.dataModel2.getValueAt(int(row),2)
904 | Severity = self.dataModel2.getValueAt(int(row),3)
905 | Request = self.dataModel2.getValueAt(int(row),4)
906 | Response = self.dataModel2.getValueAt(int(row),5)
907 |
908 |
909 | writer.writerow([str(url), str(paramter) ,str(Vulnerability),str(Severity),base64.b64encode(zlib.compress(Request.encode('utf-8'))),base64.b64encode(zlib.compress(Response.encode('utf-8')))])
910 | vulnerabilitydata.close()
911 | self.SingleclickexportVulnerabilities.setText("Vulnerabilities Export Completed")
912 | else:
913 | self.callbacks.printOutput("Skipping the Vulnerability, Table is empty")
914 | self.SingleclickexportVulnerabilities.setText("Vulnerabilities Export Failed. Empty Table")
915 | else:
916 | self.autosavepath.setText("Output Directory doesn't exist")
917 | self.SingleclickexportVulnerabilities.setText("Vulnerabilities Export Failed")
918 | self.SingleclickexportMapper.setText("API Mapper Export Failed")
919 |
920 |
921 | # Listner if Save button clicked from config tab to modify the auto log excluded files
922 | def excludefilebuttonclick(self,e):
923 | #Excludefiletextfield.getText()
924 | self.callbacks.saveExtensionSetting("excludefilestolog", self.Excludefiletextfield.getText().upper())
925 | self.Excludefiletextfield.setText(self.Excludefiletextfield.getText().upper())
926 |
927 |
928 |
929 | #Allowing users to select the auto save DIRECTORIES
930 | def Autosavepath(self,e):
931 | chooseFile = JFileChooser()
932 | chooseFile.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)
933 | returnedFile = chooseFile.showDialog(self.VulnerabilityButtonPanel, "Output Path")
934 | if returnedFile == JFileChooser.APPROVE_OPTION:
935 | fileLoad1 = chooseFile.getSelectedFile()
936 | self.autosavelocation = fileLoad1.getPath()
937 | return str(self.autosavelocation)
938 |
939 |
940 | # Allowing users to select the checklist CSV file to auto load it everytime extension is reloaded
941 | def Autosavepath2(self,e):
942 | chooseFile = JFileChooser()
943 | filter = FileNameExtensionFilter("csv files", ["csv"])
944 | chooseFile.addChoosableFileFilter(filter)
945 |
946 | ret = chooseFile.showDialog(self.tab, "Choose file")
947 | if ret == JFileChooser.APPROVE_OPTION:
948 | fileLoad = chooseFile.getSelectedFile()
949 | self.autoloadchecklist = fileLoad.getAbsolutePath()
950 | return str(self.autoloadchecklist)
951 |
952 |
953 | # Allowing users to set auto save time
954 | def saveautoconfigdata(self,e):
955 | if self.autoloadchecklist == 0:
956 | self.autoloadchecklist = None
957 | if self.autosavelocation == 0:
958 | if str(self.timerbox.getText()) == "0":
959 | self.timeerror.setText("Invalid time")
960 | else:
961 | self.path = self.callbacks.loadExtensionSetting('path')
962 | if os.path.isdir(str(self.path)):
963 | self.autosavepath.setText(self.path)
964 | self.callbacks.saveExtensionSetting("time", self.timerbox.getText())
965 | self.time = self.callbacks.loadExtensionSetting('time')
966 | else:
967 | self.callbacks.printOutput(str(self.autosavelocation))
968 | self.autosavepath.setText("Please select the valid path!")
969 | else:
970 | if str(self.timerbox.getText()) == "0":
971 |
972 | self.timeerror.setText("Invalid time")
973 |
974 |
975 | else:
976 | self.callbacks.saveExtensionSetting("path", str(self.autosavelocation))
977 | self.callbacks.saveExtensionSetting("time", self.timerbox.getText())
978 | self.autosavepath.setText(str(self.autosavelocation))
979 | self.path = self.callbacks.loadExtensionSetting('path')
980 | self.time = self.callbacks.loadExtensionSetting('time')
981 |
982 |
983 | # Allow users to save the auto load checklist path
984 | def saveautoconfigdata2(self,e):
985 | if self.autoloadchecklist == 0:
986 | self.Checklistfilepath.setText("Select the checklist file")
987 | else:
988 | self.callbacks.saveExtensionSetting("checklistpath", str(self.autoloadchecklist))
989 | self.Checklistfilepath.setText(self.autoloadchecklist)
990 | self.Checklistfilepath.setText(str(self.autoloadchecklist))
991 |
992 |
993 | # this will send the selected row in api mapper to vulnerability tab
994 | def sendVulnItem(self,event):
995 | row = self.logTable.getSelectedRows()
996 | for rows in row:
997 | modelRowIndex = self.logTable.convertRowIndexToModel(rows)
998 | logEntry = self._log[modelRowIndex]
999 | self.url = logEntry._url
1000 | self.requestinst = logEntry._requestResponse
1001 | self.responseinst = logEntry._response
1002 | obj = [str(self.url), None,'','',self.requestinst,self.responseinst]
1003 | self.dataModel2.addRow(obj)
1004 |
1005 | # function will handle to send the selected row to repeater
1006 | def sendRepeaterItem(self,event):
1007 | row = self.logTable.getSelectedRows()
1008 | for rows in row:
1009 | modelRowIndex = self.logTable.convertRowIndexToModel(rows)
1010 | logEntry = self._log[modelRowIndex]
1011 | fullurl = logEntry._url
1012 | url = urlparse(str(fullurl))
1013 | hostname = url.hostname
1014 | #port = url.port
1015 | port = url.port if url.port is not None else 443
1016 | protocol = url.scheme
1017 | request = self.helpers.stringToBytes(logEntry._requestResponse)
1018 | func = logEntry._FunctionalityName
1019 | if protocol == "https":
1020 | self.callbacks.sendToRepeater(hostname,port, True, request, func)
1021 | else:
1022 | self.callbacks.sendToRepeater(hostname,port, False, request, func)
1023 |
1024 |
1025 | # function will handle, delete the row from api mapper
1026 | def deleterow(self,event):
1027 | row = self.logTable.getSelectedRows()
1028 |
1029 |
1030 | for rows in sorted(row, reverse=True):
1031 | modelRowIndex = self.logTable.convertRowIndexToModel(rows)
1032 | self._log.pop(modelRowIndex)
1033 | self.fireTableDataChanged()
1034 |
1035 | # delete row from the vulnerability table
1036 | def deletevuln(self,e):
1037 | totalvulnrows = self.table3.getSelectedRows()
1038 | for rows in sorted(totalvulnrows, reverse=True):
1039 | modelRowIndex = self.table3.convertRowIndexToModel(rows)
1040 | self.dataModel2.removeRow(modelRowIndex)
1041 |
1042 |
1043 | # allow users to search vulnerablity from select vulnerablity list in vulnerability table
1044 | '''
1045 | def seachincombobox(self,event):
1046 | Combo = event.getSource()
1047 | searchedvalue = Combo.getSelectedItem()
1048 | self.comboBox.removeAllItems()
1049 | self.comboBox.addItem(None)
1050 | for items in self.combolist:
1051 | if searchedvalue in items:
1052 | self.comboBox.addItem(items)
1053 |
1054 |
1055 |
1056 | def seachincombobox(self, event):
1057 | Combo = event.getSource()
1058 | searchedValue = Combo.getEditor().getItem()
1059 | model = Combo.getModel()
1060 | model.removeAllElements()
1061 | model.addElement(None)
1062 | for item in self.combolist:
1063 | if not searchedValue or searchedValue.lower() in item.lower():
1064 | model.addElement(item)
1065 | '''
1066 |
1067 |
1068 | #function that will show a option to send request to extension in proxy/repeater etc
1069 | def createMenuItems(self, invocation):
1070 | ctx = invocation.getInvocationContext()
1071 | menu = []
1072 | menu.append(JMenuItem("Send To API Mapper", None,actionPerformed=lambda x, inv=invocation: self.getTabledataa(inv)))
1073 | menu.append(JMenuItem("Send To Vulnerability", None,actionPerformed=lambda x, inv=invocation: self.getVulnerabilitydataa(inv)))
1074 |
1075 | if menu == []:
1076 | return
1077 | else:
1078 | return menu
1079 |
1080 |
1081 | # function will be called when user send any request to vulnerabilites tab, it will give the selected message
1082 | def getVulnerabilitydataa(self,invocation):
1083 | reqRes = invocation.getSelectedMessages()
1084 | for items in reqRes:
1085 | self.url = items.getUrl()
1086 | req = self.helpers.analyzeRequest(items)
1087 | gettingrequest = items.getRequest()
1088 | self.requestinst = self.helpers.bytesToString(gettingrequest)
1089 | self.responseinbytes = items.getResponse()
1090 | self.responseinst = self.helpers.bytesToString(self.responseinbytes)
1091 | obj = [str(self.url), None,'','',self.requestinst,self.responseinst]
1092 |
1093 | self.dataModel2.addRow(obj)
1094 |
1095 |
1096 |
1097 | # function will be called when user send any request to the extension, function will get the required data from the request that is send and will add it to the list
1098 | def getTabledataa(self, invocation):
1099 | reqRes = invocation.getSelectedMessages()
1100 | for items in reqRes:
1101 | req = self.helpers.analyzeRequest(items)
1102 | self.method = req.getMethod()
1103 | paramter = req.getParameters()
1104 | self.url = items.getUrl()
1105 | gettingrequest = items.getRequest()
1106 | self.requestinst = self.helpers.bytesToString(gettingrequest)
1107 | self.responseinbytes = items.getResponse()
1108 | self.responseinst = self.helpers.bytesToString(self.responseinbytes)
1109 | getody = req.getBodyOffset()
1110 | self.body = self.requestinst[getody:len(self.requestinst)]
1111 | rowss = self.logTable.getRowCount()
1112 | self.sr2 = str((rowss + 1))
1113 | self._lock.acquire()
1114 | row = len(self._log)
1115 | column = self.logTable.getColumnCount()
1116 | self._log.append(LogEntry(self.sr2, self.url, self.method, self.body, self.requestinst, '', '', self.responseinst, ''))
1117 | self.logTable.getModel().fireTableRowsInserted(row, row)
1118 | self._lock.release()
1119 |
1120 |
1121 | # Returning the tab name to Burp Suite
1122 | def getTabCaption(self):
1123 | return "Pentest Mapper"
1124 |
1125 |
1126 | # Returning the UI to the extension tab - Returning the new taB insite the extension tab
1127 | def getUiComponent(self):
1128 | return self.tabbedPane
1129 |
1130 | # function will export the table data when clicked on save button in api mapper tab
1131 | def savelogger(self,e):
1132 | currenttime = str(time.strftime('%Y-%m-%d,%H:%M:%S', time.localtime(time.time())))
1133 | chooseFile = JFileChooser()
1134 | chooseFile.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)
1135 | returnedFile = chooseFile.showDialog(self.APIMapperButtonPanel, "Output Path")
1136 | if returnedFile == JFileChooser.APPROVE_OPTION:
1137 | fileLoad = chooseFile.getSelectedFile()
1138 | self.filepath = fileLoad.getPath()
1139 | fname = "APIMapper"+str(time.time())+"."+"csv"
1140 | fnameWithPath = os.path.join(self.filepath,fname)
1141 | with open(fnameWithPath, 'wb') as loggerdata:
1142 | writer = csv.writer(loggerdata)
1143 | for logEntry in self._log:
1144 | writer.writerow([str(logEntry._sr), str(logEntry._url) ,str(logEntry._method) , base64.b64encode(zlib.compress(logEntry._postbody.encode('utf-8'))) ,str(logEntry._FunctionalityName) , base64.b64encode(zlib.compress(logEntry._requestResponse.encode('utf-8'))) ,str(logEntry._TestCases), base64.b64encode(zlib.compress(logEntry._response.encode('utf-8'))) ,str(logEntry._status)])
1145 | loggerdata.close()
1146 |
1147 |
1148 | # function to handle event to import table data in api mapper tab
1149 | def importlogger(self,e):
1150 | chooseFile = JFileChooser()
1151 | filter = FileNameExtensionFilter("csv files", ["csv"])
1152 | chooseFile.addChoosableFileFilter(filter)
1153 | ret = chooseFile.showDialog(self.tab, "Choose file")
1154 | if ret == JFileChooser.APPROVE_OPTION:
1155 | fileLoad = chooseFile.getSelectedFile()
1156 | self.filepath = fileLoad.getAbsolutePath()
1157 | with open(self.filepath, 'rb') as f:
1158 | reader2 = csv.reader(f, delimiter=',')
1159 | for rows in reader2:
1160 | SR = rows[0]
1161 | url = rows[1]
1162 | method = rows[2]
1163 | body = zlib.decompress(base64.b64decode(rows[3]))
1164 | functionname = rows[4]
1165 | request = zlib.decompress(base64.b64decode(rows[5]))
1166 | testcases = rows[6]
1167 | try:
1168 | response = zlib.decompress(base64.b64decode(rows[7]))
1169 | status = rows[8]
1170 | except IndexError:
1171 | response = None
1172 | status = None
1173 | self._log.append(LogEntry(SR,url, method,body,request,functionname,testcases,response,status))
1174 | f.close()
1175 | self.fireTableDataChanged()
1176 |
1177 |
1178 | ## Search text in checklist tab
1179 | def searchinchecklist(self,e):
1180 | checklistsearchstring = self.searchchecklist.getText()
1181 | if checklistsearchstring == "":
1182 | self.sorter.setRowFilter(None)
1183 | else:
1184 | self.sorter.setRowFilter(RowFilter.regexFilter("(?i)" + checklistsearchstring));
1185 |
1186 |
1187 | ## Search text in APIMapper tab
1188 | def searchinapimapper(self,e):
1189 | apimappersearchstring = self.searchapimapper.getText()
1190 | if apimappersearchstring == "":
1191 | self.sorter2.setRowFilter(None)
1192 | else:
1193 | self.sorter2.setRowFilter(RowFilter.regexFilter("(?i)" + apimappersearchstring));
1194 |
1195 | ## Search text in APIMapper tab
1196 | def searchinvulnerability(self,e):
1197 | vulnerabilitysearchstring = self.searchvulnerability.getText()
1198 | if vulnerabilitysearchstring == "":
1199 | self.sorter3.setRowFilter(None)
1200 | else:
1201 | self.sorter3.setRowFilter(RowFilter.regexFilter("(?i)" + vulnerabilitysearchstring));
1202 |
1203 |
1204 | #Function that will be called when user click on import in checklist tab
1205 | def importchecklist(self, e):
1206 | chooseFile = JFileChooser()
1207 | filter = FileNameExtensionFilter("csv files", ["csv"])
1208 | chooseFile.addChoosableFileFilter(filter)
1209 | ret = chooseFile.showDialog(self.tab, "Choose file")
1210 | if ret == JFileChooser.APPROVE_OPTION:
1211 | fileLoad = chooseFile.getSelectedFile()
1212 | self.filepath = fileLoad.getAbsolutePath()
1213 | self.comboBox.removeAllItems()
1214 | self.comboBox.addItem(None)
1215 | self.dataModel.setRowCount(0)
1216 | with open(self.filepath, 'rb') as f:
1217 | reader2 = csv.reader(f, delimiter=',')
1218 | for rows in reader2:
1219 | SR = rows[0]
1220 | title = rows[1]
1221 | obj = [SR,title]
1222 | self.dataModel.addRow(obj)
1223 | self.comboBox.addItem(str(title))
1224 | self.combolist.append(str(title))
1225 | combo_model = DefaultComboBoxModel(self.combolist)
1226 | self.editor.comboBox.setModel(combo_model)
1227 | f.close()
1228 |
1229 |
1230 | # creating a function that will be called when user clicks on the create button this function will show the input field in UI for checklist taB
1231 | def createtestcases(self, e):
1232 | self.createchecklistbutton.setEnabled(False)
1233 | self.textfield1 = JTextField('', 15)
1234 | self.ChecklistbuttonPanel.add(self.textfield1)
1235 | self.ChecklistbuttonPanel.add(JButton(
1236 | "Submit", actionPerformed=self.addrow))
1237 | self.ChecklistbuttonPanel.add(Box.createVerticalGlue())
1238 |
1239 | # this function will be called as soon as user click on suBmit Button of add row UI input
1240 | def addrow(self, e):
1241 | rowsss = self.dataModel.getRowCount()
1242 | sr = (rowsss + 1)
1243 | title = self.value = self.textfield1.getText()
1244 | obj = [sr, title]
1245 | self.comboBox.addItem(str(title))
1246 | self.combolist.append(str(title))
1247 | combo_model = DefaultComboBoxModel(self.combolist)
1248 | self.editor.comboBox.setModel(combo_model)
1249 | self.dataModel.addRow(obj)
1250 | if not self.checklistpath == None:
1251 | # Writing the new entry in file
1252 | with open(self.checklistpath, 'a') as writechecklist:
1253 | writer = csv.writer(writechecklist)
1254 | writer.writerow([str(sr), str(title)])
1255 | writechecklist.close()
1256 | else:
1257 | self.callbacks.printOutput("Auto add to csv file only work if auto checklist load is configured")
1258 |
1259 |
1260 | # function to handel event when save button clicked on test cases
1261 | def SaveTestCases(self,e):
1262 | selectedrow = self.logTable.getSelectedRow()
1263 | modelRowIndex = self.logTable.convertRowIndexToModel(selectedrow)
1264 | if modelRowIndex >= 0:
1265 | logEntry = self._log[modelRowIndex]
1266 | Value = self.testcases.getText()
1267 | logEntry._TestCases = Value
1268 |
1269 |
1270 | # function will handle to event once the export button clicked on vulnerablity tab
1271 | def exportvulnerability(self,e):
1272 | totalrow = self.dataModel2.getRowCount()
1273 | self.callbacks.printOutput(str(totalrow))
1274 | chooseFile = JFileChooser()
1275 | chooseFile.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)
1276 | returnedFile = chooseFile.showDialog(self.VulnerabilityButtonPanel, "Output Path")
1277 | if returnedFile == JFileChooser.APPROVE_OPTION:
1278 | fileLoad1 = chooseFile.getSelectedFile()
1279 | self.filepath2 = fileLoad1.getPath()
1280 | fname2 = "Vulnerability"+str(time.time())+"."+"csv"
1281 | fnameWithPath = os.path.join(self.filepath2,fname2)
1282 |
1283 | #self.filepath2 = fileLoad1.getAbsolutePath()
1284 | with open(fnameWithPath, 'wb') as vulnerabilitydata:
1285 | writer = csv.writer(vulnerabilitydata)
1286 | for row in range (0, totalrow):
1287 | url = self.dataModel2.getValueAt(row,0)
1288 | paramter = self.dataModel2.getValueAt(int(row),1)
1289 | Vulnerability = self.dataModel2.getValueAt(int(row),2)
1290 | Severity = self.dataModel2.getValueAt(int(row),3)
1291 | Request = self.dataModel2.getValueAt(int(row),4)
1292 | Response = self.dataModel2.getValueAt(int(row),5)
1293 | writer.writerow([str(url), str(paramter) ,str(Vulnerability),str(Severity),base64.b64encode(zlib.compress(Request.encode('utf-8'))),base64.b64encode(zlib.compress(Response.encode('utf-8')))])
1294 | vulnerabilitydata.close()
1295 |
1296 |
1297 |
1298 | # function will handle to event once the import button clicked on vulnerablity tab
1299 | def importvulnerability(self,e):
1300 | chooseFile = JFileChooser()
1301 | filter = FileNameExtensionFilter("csv files", ["csv"])
1302 | chooseFile.addChoosableFileFilter(filter)
1303 | ret = chooseFile.showDialog(self.tab, "Choose file")
1304 | if ret == JFileChooser.APPROVE_OPTION:
1305 | fileLoad = chooseFile.getSelectedFile()
1306 | self.filepath = fileLoad.getAbsolutePath()
1307 |
1308 | with open(self.filepath, 'rb') as f:
1309 | reader2 = csv.reader(f, delimiter=',')
1310 | #self.data1 = list(reader)
1311 | for rows in reader2:
1312 | URL = rows[0]
1313 | Parameter = rows[1]
1314 | Vulnerability = rows[2]
1315 | try:
1316 | Severity = rows[3]
1317 | Request = rows[4]
1318 | Response = rows[5]
1319 | except IndexError:
1320 | Severity = None
1321 | Request = None
1322 | Response = None
1323 | obj = [URL,Parameter,Vulnerability,Severity,zlib.decompress(base64.b64decode(Request)),zlib.decompress(base64.b64decode(Response))]
1324 | self.dataModel2.addRow(obj)
1325 | f.close()
1326 |
1327 |
1328 | # extending the default table model to remove the editable column from the checklist taB table
1329 | class CustomDefaultTableModelHosts(DefaultTableModel):
1330 |
1331 | # override isCellEditable method
1332 | def isCellEditable(self, row, column):
1333 | return 0
1334 |
1335 |
1336 |
1337 |
1338 | class CustomSelectionListener(ListSelectionListener):
1339 | def __init__(self, table, request_viewer, response_viewer):
1340 | self.table = table
1341 | self.request_viewer = request_viewer
1342 | self.response_viewer = response_viewer
1343 |
1344 | def valueChanged(self, event):
1345 | if not event.getValueIsAdjusting():
1346 | selected_row = self.table.getSelectedRow()
1347 | if selected_row != -1:
1348 | request_data = self.table.getValueAt(selected_row, 4)
1349 | response_data = self.table.getValueAt(selected_row, 5)
1350 | self.request_viewer.setMessage(request_data, True)
1351 | self.response_viewer.setMessage(response_data, True)
1352 |
1353 |
1354 |
1355 |
1356 |
1357 | # Vulnerability Table vulnerability selection autocompletion
1358 | class AutocompleteTableCellEditor(TableCellEditor):
1359 | def __init__(self, items,table3):
1360 | self.items = items
1361 | self.comboBox = JComboBox(items)
1362 | self.comboBox.setEditable(True)
1363 | AutoCompleteDecorator.decorate(self.comboBox)
1364 | self.listeners = []
1365 | self.table3 = table3
1366 |
1367 |
1368 | def getCellEditorValue(self):
1369 | return self.comboBox.getSelectedItem()
1370 |
1371 | def getTableCellEditorComponent(self, table, value, isSelected, row, column):
1372 | self.comboBox = JComboBox(self.items)
1373 | self.comboBox.setEditable(True)
1374 | AutoCompleteDecorator.decorate(self.comboBox)
1375 | self.comboBox.setSelectedItem(value)
1376 | return self.comboBox
1377 |
1378 | def isCellEditable(self, event):
1379 | return True
1380 |
1381 | def addCellEditorListener(self, listener):
1382 | self.listeners.append(listener)
1383 |
1384 | def removeCellEditorListener(self, listener):
1385 | self.listeners.remove(listener)
1386 |
1387 | def shouldSelectCell(self, event):
1388 | return True
1389 |
1390 | def stopCellEditing(self):
1391 | selected_value = self.comboBox.getSelectedItem()
1392 | selected_row = self.table3.convertRowIndexToModel(self.table3.getEditingRow())
1393 | selected_column = self.table3.convertColumnIndexToModel(self.table3.getEditingColumn())
1394 | self.table3.getModel().setValueAt(selected_value, selected_row, selected_column)
1395 |
1396 | return True
1397 |
1398 | def cancelCellEditing(self):
1399 | return True
1400 |
1401 |
1402 |
1403 | class RowData:
1404 | def __init__(self, url="", parameters="", vulnerability="", severity="", request="", response=""):
1405 | self.url = url
1406 | self.parameters = parameters
1407 | self.vulnerability = vulnerability
1408 | self.severity = severity
1409 | self.request = request
1410 | self.response = response
1411 |
1412 |
1413 |
1414 | class CustomTableModelVuln(AbstractTableModel):
1415 | def __init__(self, extender):
1416 | self.vulndata = extender._vuln
1417 | self.callbacks = extender.callbacks
1418 |
1419 |
1420 | def getRowCount(self):
1421 | try:
1422 | return len(self.vulndata)
1423 | except:
1424 | return 0
1425 |
1426 |
1427 | def getColumnCount(self):
1428 | return 6
1429 |
1430 | def getColumnName(self, columnIndex):
1431 | if columnIndex == 0:
1432 | return "URL"
1433 | if columnIndex == 1:
1434 | return "Parameters"
1435 | if columnIndex == 2:
1436 | return "Vulnerability"
1437 | if columnIndex == 3:
1438 | return "Severity"
1439 | if columnIndex == 4:
1440 | return "Request"
1441 | if columnIndex == 5:
1442 | return "Response"
1443 | return ""
1444 |
1445 |
1446 | def getValueAt(self, rowIndex, columnIndex):
1447 | if rowIndex < self.getRowCount() and columnIndex < self.getColumnCount():
1448 | vulnEntry = self.vulndata[rowIndex]
1449 |
1450 | if columnIndex == 0:
1451 | return vulnEntry.url
1452 | elif columnIndex == 1:
1453 | return vulnEntry.parameters
1454 | elif columnIndex == 2:
1455 | return vulnEntry.vulnerability
1456 | elif columnIndex == 3:
1457 | return vulnEntry.severity
1458 | elif columnIndex == 4:
1459 | return vulnEntry.request
1460 | elif columnIndex == 5:
1461 | return vulnEntry.response
1462 |
1463 |
1464 | def getColumnClass(self, col):
1465 | return str
1466 |
1467 | def isCellEditable(self, row, col):
1468 | return True
1469 |
1470 | def setValueAt(self, value, row, col):
1471 | rowData = self.vulndata[row]
1472 | if col == 0:
1473 | rowData.url = value
1474 | elif col == 1:
1475 | rowData.parameters = value
1476 | elif col == 2:
1477 | rowData.vulnerability = value
1478 | elif col == 3:
1479 | rowData.severity = value
1480 | elif col == 4:
1481 | rowData.request = value
1482 | elif col == 5:
1483 | rowData.response = value
1484 | self.fireTableCellUpdated(row, col)
1485 |
1486 |
1487 |
1488 | def setValueAt(self, value, rowIndex, columnIndex):
1489 |
1490 | if rowIndex < self.getRowCount() and columnIndex == 1:
1491 | vulEntry = self.vulndata[rowIndex]
1492 | vulEntry.parameters = value
1493 |
1494 | if rowIndex < self.getRowCount() and columnIndex == 2:
1495 | vulEntry = self.vulndata[rowIndex]
1496 | vulEntry.vulnerability = value
1497 |
1498 | if rowIndex < self.getRowCount() and columnIndex == 3:
1499 | vulEntry = self.vulndata[rowIndex]
1500 | vulEntry.severity = value
1501 | else:
1502 | self.callbacks.printError("Table is empty")
1503 |
1504 | def addRow(self, obj):
1505 | row_data = RowData(*obj)
1506 | self.vulndata.append(row_data)
1507 | self.fireTableRowsInserted(len(self.vulndata) - 1, len(self.vulndata) - 1)
1508 |
1509 |
1510 |
1511 |
1512 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Pentest Mapper #
2 |
3 | Pentest Mapper is a Burp Suite extension that integrates the Burp Suite request logging with a custom application testing checklist. The extension provides a straightforward flow for application penetration testing. The extension includes functionalities to allow users to map the flow of the application for pentesting to better analyse the application and its vulnerabilities. The API calls from each flow can be connected with the function or flow name. The extension allows users to map or connect each flow or API to vulnerability with the custom checklist.
4 |
5 | # Installation
6 |
7 | - Extension is available on Burp Suite BApp Store
8 |
9 | # Documentation
10 |
11 | https://anof-cyber.github.io/Pentest-Mapper/
12 |
13 | # Features Summary
14 | **1. Checklist**
15 |
16 | Allows to load the custom checklist
17 |
18 | **2. API Mapper**
19 |
20 | Allow to keep track of each API call, Flow and Test Cases for each API calls.
21 |
22 | **3. Vulnerability**
23 |
24 | Allows to keep track of vulnerabilities, Map each paramter and API call to vulnerability from the Checklist and severity
25 |
26 | **4. Config**
27 |
28 | Allow to set Auto save the project or extension data and auto load the checklist. Also import and export all data with one click
29 |
30 |
31 |
32 | # Features
33 |
34 | **1. Checklist**
35 |
36 | The checklist allows users to create or upload the custom checklist to map each API call to the vulnerability from the custom uploaded checklist.
37 |
38 | 
39 |
40 |
41 | **2. API Mapper**
42 |
43 | The API Mapper tab allows logging the HTTP request from the poxy or repeater tab and mapping the request with the flow and sorting the request based on the flow. Also, the tab allows users to write the comment or test cases for each API call logged into the extension. The tab allows mapping each API with the vulnerability from the checklist.
44 |
45 | 
46 |
47 | 
48 |
49 |
50 | **3. Vulnerabilities**
51 |
52 | The tab stores the URL and parameters and allows users to map the selected API to the vulnerabilities.
53 |
54 | 
55 | 
56 |
57 | **4. Config**
58 |
59 | The config tab allow you to set time for auto save after specific time peried and select the output location. You can also set the auto load the checklist file and Import and export data with one click. You can also turn on off the Auto Save and Auto Logging request from proxy for scope domain
60 |
61 | 
62 |
63 | **Sending Request**
64 |
65 | 
66 |
67 | ___
68 |
69 | # TBD
70 |
71 | * ~~Single Click Import and Export~~
72 | * ~~Auto Save the project Data~~
73 | * ~~Auto Logging Scope APIs and requests with Optional mode~~
74 | * ~~Seach option for all 3 tables to manage long table~~
75 | * ~~Solving long checklist selection from vulnerability~~
76 | * ~~Updating checklist file automatically~~
77 | * ~~Map Vulnerabilities with Severity~~
78 | * Custom and Default CVSS score generation
79 | * Multiple row selection for API Mapper
80 | * ~~Turn on off auto save from config~~
81 | * ~~Optimization of code~~
82 | * ~~Allowing individual request to mark as completed~~
83 | * ~~Allowing Request and Response for Vulnerability~~
84 |
85 |
--------------------------------------------------------------------------------
/images/APIMapper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/images/APIMapper.png
--------------------------------------------------------------------------------
/images/APIMapper2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/images/APIMapper2.png
--------------------------------------------------------------------------------
/images/CheckList.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/images/CheckList.png
--------------------------------------------------------------------------------
/images/Config.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/images/Config.png
--------------------------------------------------------------------------------
/images/Sendreq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/images/Sendreq.png
--------------------------------------------------------------------------------
/images/Vulnerability-selection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/images/Vulnerability-selection.png
--------------------------------------------------------------------------------
/images/proxy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/images/proxy.png
--------------------------------------------------------------------------------
/images/severity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/images/severity.png
--------------------------------------------------------------------------------
/images/tt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/lib/swingx-all-1.6.4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/lib/swingx-all-1.6.4.jar
--------------------------------------------------------------------------------
/pentestmapper/APIMapper.py:
--------------------------------------------------------------------------------
1 | from javax.swing import JTable
2 | from java.lang import Integer, String
3 | from javax.swing.table import AbstractTableModel
4 |
5 |
6 | #logger entry <- Class based python list to store the data for API Mapper tab/tabble
7 | class LogEntry:
8 | def __init__(self, sr, url, method, postbody, requestResponse, FunctionalityName, TestCases, response, status):
9 | self._sr = sr
10 | self._url = url
11 | self._method = method
12 | self._postbody = postbody
13 | self._requestResponse = requestResponse
14 | self._FunctionalityName = FunctionalityName
15 | self._TestCases = TestCases
16 | self._response = response
17 | self._status = status
18 |
19 |
20 |
21 | # Extedning the JTable for API Mapper TaB
22 | class Table(JTable):
23 | def __init__(self, extender,tablemodel):
24 | self._extender = extender
25 | self.setModel(tablemodel)
26 | self.setRowSelectionAllowed(True)
27 | self.setAutoCreateRowSorter(True)
28 |
29 | def getColumnClass(self, column):
30 | columnClasses = [Integer, String, String, String, String,String]
31 | return columnClasses[column]
32 |
33 | # Only last colum is allowed for editing
34 | def isCellEditable(self, row, column):
35 | if column == 4 or 5:
36 | return 1
37 | else:
38 | return 0
39 |
40 | # function that will change the request and test case for selected row
41 | def changeSelection(self, row, col, toggle, extend):
42 | self.modelRowIndex = self.convertRowIndexToModel(row)
43 | self._extender._currentlySelectedLogTableRow = self.modelRowIndex
44 | logEntry = self._extender._log[int(self.modelRowIndex)]
45 | self._extender.requestViewer.setMessage(
46 | logEntry._requestResponse, True)
47 | self._extender.responseViewer.setMessage(
48 | logEntry._response, True)
49 | text = logEntry._TestCases
50 | self._extender.testcases.setText(logEntry._TestCases)
51 | self._extender._currentlyDisplayedItem = logEntry._requestResponse
52 | JTable.changeSelection(self, row, col, toggle, extend)
53 |
54 |
55 |
56 |
57 |
58 |
59 | class CustomTableModel(AbstractTableModel):
60 |
61 | def __init__(self, extender):
62 | self._log = extender._log
63 | self.callbacks = extender.callbacks
64 | #self.logTable = extender.logTable
65 |
66 | # part of custom table model to get total number of row in the table, it will check the data in the list amd will return when called
67 | def getRowCount(self):
68 | try:
69 | return len(self._log)
70 | except:
71 | return 0
72 |
73 | # this is required to work with AbstractTableModel, this will show return the total columns in API Mapper
74 | def getColumnCount(self):
75 | return 6
76 |
77 | # this is required to work with AbstractTableModel, this will show the columns Name for API Mapper table
78 | def getColumnName(self, columnIndex):
79 | if columnIndex == 0:
80 | return "SR"
81 | if columnIndex == 1:
82 | return "URL"
83 | if columnIndex == 2:
84 | return "Method"
85 | if columnIndex == 3:
86 | return "Post Body"
87 | if columnIndex == 4:
88 | return "Functionality Name"
89 | if columnIndex == 5:
90 | return "Status"
91 | return ""
92 |
93 | # this is required to work with AbstractTableModel, this will show the data in the columns from the list for API Mapper table
94 | def getValueAt(self, rowIndex, columnIndex):
95 | #self.totalrow = self.logTable.getRowCount()
96 | if rowIndex < self.getRowCount() and columnIndex < self.getColumnCount():
97 | logEntry = self._log[rowIndex]
98 | if columnIndex == 0:
99 | return str(rowIndex + 1)
100 | if columnIndex == 1:
101 | return logEntry._url
102 | if columnIndex == 2:
103 | return logEntry._method
104 | if columnIndex == 3:
105 | return logEntry._postbody
106 | if columnIndex == 4:
107 | return logEntry._FunctionalityName
108 | if columnIndex == 5:
109 | return logEntry._status
110 | return ""
111 | else:
112 | self.callbacks.printError("Table is empty")
113 |
114 | '''
115 | part of custom table for api mapper, it will get the edited value from function column and will save it in the class based list
116 | for the selected row
117 |
118 | '''
119 | def setValueAt(self, value, rowIndex, columnIndex):
120 |
121 | if rowIndex < self.getRowCount() and columnIndex == 4:
122 | logEntry = self._log[rowIndex]
123 | logEntry._FunctionalityName = value
124 |
125 | if rowIndex < self.getRowCount() and columnIndex == 5:
126 | logEntry = self._log[rowIndex]
127 | logEntry._status = value
128 |
129 |
130 | else:
131 | self.callbacks.printError("Table is empty")
132 |
133 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/pentestmapper/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anof-cyber/Pentest-Mapper/e519f144738bdebae4a6e3597324489649ca186c/pentestmapper/__init__.py
--------------------------------------------------------------------------------
/pentestmapper/autolog.py:
--------------------------------------------------------------------------------
1 | from burp import IProxyListener
2 |
3 | from pentestmapper.APIMapper import LogEntry
4 |
5 | # Class to handle auto log requests from proxy
6 | class Autologclas(IProxyListener):
7 | def __init__(self,handlingoutput):
8 | self._handlingoutput = handlingoutput
9 | #self._handlingoutput.callbacks.registerHttpListener(self)
10 |
11 |
12 | def processProxyMessage(self,messageIsRequest, message):
13 |
14 | if self._handlingoutput.Autologcheck == True:
15 | if not messageIsRequest:
16 | if self._handlingoutput.callbacks.isInScope(self._handlingoutput.helpers.analyzeRequest(message.getMessageInfo()).getUrl()):
17 |
18 | req = self._handlingoutput.helpers.analyzeRequest(message.getMessageInfo())
19 | self.url = self._handlingoutput.helpers.analyzeRequest(message.getMessageInfo()).getUrl()
20 | response = message.getMessageInfo().getResponse()
21 | responseInfo = self._handlingoutput.helpers.analyzeResponse(response)
22 |
23 | # Find out if image
24 | self.responsetype = responseInfo.getInferredMimeType()
25 | self.responsetype2 = responseInfo.getStatedMimeType()
26 | self.exludelist = self._handlingoutput.Excludefiletextfield.getText().split(",")
27 |
28 | if (self.responsetype.upper() not in self.exludelist) and (self.responsetype2.upper() not in self.exludelist):
29 | #if self.responsetype.upper() not in self.exludelist:
30 |
31 | self.method = req.getMethod()
32 | self.requestinst = self._handlingoutput.helpers.bytesToString(message.getMessageInfo().getRequest())
33 | getody = req.getBodyOffset()
34 | self.body = self.requestinst[getody:len(self.requestinst)]
35 | self.responseinst = self._handlingoutput.helpers.bytesToString(message.getMessageInfo().getResponse())
36 | rowss = self._handlingoutput.logTable.getRowCount()
37 | self.sr2 = str((rowss + 1))
38 |
39 | self._handlingoutput._lock.acquire()
40 | row = len(self._handlingoutput._log)
41 | self._handlingoutput._log.append(LogEntry(self.sr2, self.url, self.method, self.body, self.requestinst, '', '', self.responseinst,''))
42 | self._handlingoutput.fireTableRowsInserted(row, row)
43 | self._handlingoutput._lock.release()
44 |
45 | else:
46 | self._handlingoutput.callbacks.removeProxyListener(self)
47 |
--------------------------------------------------------------------------------
/pentestmapper/autosave.py:
--------------------------------------------------------------------------------
1 | from threading import Thread, Event
2 | import os
3 | import csv, zlib,time
4 | import base64
5 |
6 |
7 | ##Class to handle auto save
8 | class Autosaveclas(Thread):
9 | def __init__(self,handlingoutput):
10 | self._handlingoutput = handlingoutput
11 |
12 | Thread.__init__(self)
13 | self._stop = Event()
14 |
15 | def run(self):
16 |
17 | #self._handlingoutput = handlingoutput
18 | while not self.stopped():
19 | if self._handlingoutput.Autosavechecker == True:
20 |
21 | if os.path.isdir(str(self._handlingoutput.path)):
22 |
23 | if self._handlingoutput.logTable.getRowCount() > 0:
24 | #self.path = fileLoad.getPath()
25 | fname = "APIMapper"+"."+"csv"
26 | fnameWithPath = os.path.join(self._handlingoutput.path,fname)
27 | if os.path.exists(fnameWithPath):
28 | os.remove(fnameWithPath)
29 | self._handlingoutput.callbacks.printOutput("Saving the API Mapper output")
30 | with open(fnameWithPath, 'wb') as loggerdata:
31 | writer = csv.writer(loggerdata)
32 | for logEntry in self._handlingoutput._log:
33 | writer.writerow([str(logEntry._sr), str(logEntry._url) ,str(logEntry._method) , base64.b64encode(zlib.compress(logEntry._postbody.encode('utf-8'))) ,str(logEntry._FunctionalityName) , base64.b64encode(zlib.compress(logEntry._requestResponse.encode('utf-8'))) ,str(logEntry._TestCases), base64.b64encode(zlib.compress(logEntry._response.encode('utf-8'))) ,str(logEntry._status)])
34 |
35 | loggerdata.close()
36 | else:
37 | self._handlingoutput.callbacks.printOutput("Skipping the API Mapper, Table is empty")
38 | if self._handlingoutput.dataModel2.getRowCount() > 0:
39 | fname2 = "Vulnerability"+"."+"csv"
40 | fnameWithPath2 = os.path.join(self._handlingoutput.path,fname2)
41 | if os.path.exists(fnameWithPath2):
42 | os.remove(fnameWithPath2)
43 | self._handlingoutput.callbacks.printOutput("Saving the Vulnerability output")
44 | totalrow = self._handlingoutput.dataModel2.getRowCount()
45 | with open(fnameWithPath2, 'wb') as vulnerabilitydata:
46 | writer = csv.writer(vulnerabilitydata)
47 | for row in range (0, totalrow):
48 | url = self._handlingoutput.dataModel2.getValueAt(row,0)
49 | paramter = self._handlingoutput.dataModel2.getValueAt(int(row),1)
50 | Vulnerability = self._handlingoutput.dataModel2.getValueAt(int(row),2)
51 | Severity = self._handlingoutput.dataModel2.getValueAt(int(row),3)
52 | Request = self._handlingoutput.dataModel2.getValueAt(int(row),4)
53 | Response = self._handlingoutput.dataModel2.getValueAt(int(row),5)
54 | #self.callbacks.printOutput(str(url))
55 |
56 | #self.callbacks.printOutput(str(logEntry._sr))
57 | writer.writerow([str(url), str(paramter) ,str(Vulnerability),str(Severity),base64.b64encode(zlib.compress(Request.encode('utf-8'))),base64.b64encode(zlib.compress(Response.encode('utf-8')))])
58 | vulnerabilitydata.close()
59 | else:
60 | self._handlingoutput.callbacks.printOutput("Skipping the Vulnerability, Table is empty")
61 | else:
62 | self._handlingoutput.autosavepath.setText("Output Directory doesn't exist")
63 | time.sleep(int(self._handlingoutput.time) * 60)
64 |
65 | def stop(self):
66 | self._stop.set()
67 |
68 | def stopped(self):
69 | return self._stop.isSet()
--------------------------------------------------------------------------------