infobyte / faraday

Open Source Vulnerability Management Platform
https://www.faradaysec.com
GNU General Public License v3.0
5.07k stars 918 forks source link

Jira bidirectional update #264

Closed dkogue closed 6 years ago

dkogue commented 6 years ago

I Have a script that upload scans report to Faraday, and then automatically logs high severity vulnerabilities to Jira.

Now between two scans I want to log only new high severity vulnerabilities that were not found in the previous upload. As earlier vulnerabilities may be in work in progress status in Jira.

Is it possible to identify these type of vulnerabilities at Faraday level, as this will help me know which alerts to log?

I tried with the status flag but, unfortunately its reinitialized when a new report upload is done. Any idea or hint will be much appreciate.

WinnaZ commented 6 years ago

Hey there! First of all, let me start by explaining how the status of vulns works on Faraday. The idea of vulns status is to mark their current state on your target. Therefore a vuln will be automatically opened when just imported into faraday, can be changed to Closed for example if the vuln has been fixed and if a scan imported into faraday shows that same vulnerability again Faraday instead of creating a new vuln will mark the existent one as Re-Open to better keep track of said vuln. You can read more about it on this wiki: https://github.com/infobyte/faraday/wiki/Vulnerability-Life-Cycle

What you did to integrate Faraday with Jira sounds amazing! Thought you should know out of the box integration with JIRA is one of the features that come with commercial versions of Faraday! If you would like a demo just to let us know. Your vision of how to track the history of a vulns sounds very interesting too, and i will talk to the developer team about maybe including it on our roadmap. For now as a workaround, have you considered maybe changing the vuln status when sending it yo JIRA? In any case thank you for the feedback and let us know how it goes!

dkogue commented 6 years ago

@WinnaZ Thanks WinnaZ for your feedback. really appreciated. I have few questions. Is it possible to edit individual vulnerability through cli or API? Is it possible to add a special column different from the default ones at the Status report page? (for example a column that retrieved comments made in jira so they can be viewed directly in Faraday)

dkogue commented 6 years ago

@WinnaZ

Is the "./fplugin -w XXX create_note" creating note for individual vulnerability? If yes can share the options that are needed to execute that? Tanks @WinnaZ ...

dkogue commented 6 years ago

@WinnaZ I managed to create a note but when I click on a note section on the webui it doesnot open. How can I access a note and what it is the use for?

WinnaZ commented 6 years ago

1) Yes it is possible on the new version. Faraday V3 has a brand new REST API made almost from scratch. If you go into the web ui and open de develover tools right before clicking on edit you'll the request that's made. If you copy that request and change the json you can edit any vulns directly from the API. 2) Notes has been deprecated on Faraday V3

WinnaZ commented 6 years ago

FYI: Notes has been deprecated but replaced with a new section called Comments.

dkogue commented 6 years ago

Thansks a lot @WinnaZ ... keep up the good work.

dkogue commented 6 years ago

@WinnaZ Is the comment section available in the community version? Because I cannot see it.

also an example of how to pass a comment through an API will be much appreciated.

llazzaro commented 6 years ago

@dkogue comments is available only in the api rest right know. You can see all api views using manage.py show_urls.

dkogue commented 6 years ago

thanks I will appreciate an example . '/v2/ws//hosts//' (PUT, OPTIONS) -> host_api.HostsView:put>, ########################################################################### {"website": "testasp.vulnweb.com", "status_code": null, "_rev": "", "parent_type": "Service", "owned": false, "owner": "faraday", "query": "", "refs": [], "impact": {"accountability": false, "integrity": false, "confidentiality": false, "availability": false}, "confirmed": false, "severity": "low", "service": {"status": "open", "protocol": "tcp", "name": "http", "summary": "(80/tcp) http", "version": "unknown", "_id": 1, "ports": 80}, "policyviolations": [], "params": "", "type": "VulnerabilityWeb", "method": "", "metadata": {"update_time": "2018-07-26T08:12:37.450883+00:00", "update_user": null, "update_action": 0, "creator": "Burp", "create_time": "2018-07-26T07:50:31.528770+00:00", "update_controller_action": "", "owner": "faraday", "command_id": 1}, "status": "opened", "issuetracker": {}, "description": "Detail\n\nBackground\nThe application allows users to connect to it over unencrypted connections. An attacker suitably positioned to view a legitimate user's network traffic could record and monitor their interactions with the application and obtain any information the user supplies. Furthermore, an attacker able to modify traffic could use the application as a platform for attacks against its users and third-party websites. Unencrypted connections have been exploited by ISPs and governments to track users, and to inject adverts and malicious JavaScript. Due to these concerns, web browser vendors are planning to visually flag unencrypted connections as hazardous.\n\n\nTo exploit this vulnerability, an attacker must be suitably positioned to eavesdrop on the victim's network traffic. This scenario typically occurs when a client communicates with the server over an insecure connection such as public Wi-Fi, or a corporate or home network that is shared with a compromised computer. Common defenses such as switched networks are not sufficient to prevent this. An attacker situated in the user's ISP or the application's hosting infrastructure could also perform this attack. Note that an advanced adversary could potentially target any connection made over the Internet's core infrastructure.\n\n\nPlease note that using a mixture of encrypted and unencrypted communications is an ineffective defense against active attackers, because they can easily remove references to encrypted resources when these references are transmitted over an unencrypted connection.\n", "parent": 1, "tags": [], "easeofresolution": null, "hostnames": [], "pname": "", "date": "2018-07-26T07:50:31.528770+00:00", "path": "/", "data": "", "response": "", "desc": "Detail\n\nBackground\nThe application allows users to connect to it over unencrypted connections. An attacker suitably positioned to view a legitimate user's network traffic could record and monitor their interactions with the application and obtain any information the user supplies. Furthermore, an attacker able to modify traffic could use the application as a platform for attacks against its users and third-party websites. Unencrypted connections have been exploited by ISPs and governments to track users, and to inject adverts and malicious JavaScript. Due to these concerns, web browser vendors are planning to visually flag unencrypted connections as hazardous.\n\n\nTo exploit this vulnerability, an attacker must be suitably positioned to eavesdrop on the victim's network traffic. This scenario typically occurs when a client communicates with the server over an insecure connection such as public Wi-Fi, or a corporate or home network that is shared with a compromised computer. Common defenses such as switched networks are not sufficient to prevent this. An attacker situated in the user's ISP or the application's hosting infrastructure could also perform this attack. Note that an advanced adversary could potentially target any connection made over the Internet's core infrastructure.\n\n\nPlease note that using a mixture of encrypted and unencrypted communications is an ineffective defense against active attackers, because they can easily remove references to encrypted resources when these references are transmitted over an unencrypted connection.\n", "name": "Unencrypted communications", "obj_id": "1", "request": "", "_attachments": {}, "target": "5.175.17.140", "_id": 1, "resolution": "Applications should use transport-level encryption (SSL/TLS) to protect all communications passing between the client and the server. The Strict-Transport-Security HTTP header should be used to ensure that clients refuse to access the server over an insecure connection.\n"} ########################################################### I tried to add comment by sending this api call:

curl -X PUT http://127.0.0.1:5985/_api/v2/ws/dynamscan/comment/1/ -H 'Cookie: session= .eJw90EGLgzAQBeC_suTci6lehB4KpsWFmaBEw-RS2K7FJs0uaIs6pf99pYe9Px7fe09xugzd2Iv8Pjy6jThdv0X-FB9fIhcY6xvIKgHb3rStZrJqJu6DNkGCJ3ax9RAPV23aHjzMwGohH7a6UAlxmJFBalNK8iWjbCbk9oocUvRqC77cOlOlJJsM-BbQ0ETyELX9jFA0DEYtwMTI58SZZs0fAlkXiSmjqFJX7JfVk-ojLCSrnXhtxHkcLqf7b-h-_ic4c2bwTQKmTEHCjEUfVuqEto5wbCNImmHlgleZs3VwHnvc7951j7Eb3neIRLz-AGOJYZU.DjtjbA.9qeZMOBRQ2xFbO4mxx1d3AC60M0' -d '{"title": "https://jira.xxxxxx.eu/browse/SEC-103"}'

but I got below response:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>Object with id &quot;1&quot; not found</p>
montive commented 6 years ago

Hi there.

We realised that you are missing the header 'Content-Type: application/json'. Make sure that you used it in all the requests to the API.

Here is a full example of how to use the comments in the API using curl.

  1. First login to the API. Remember to use 'Content-Type: application/json' NOTE: in the "email" field you have to put your username. And in "password" put your username's password.

    curl -s 'http://127.0.0.1:5985/_api/login' \
        -H 'Origin: http://127.0.0.1:5985' -H 'Accept-Encoding: gzip, deflate, br' \
        -H 'Accept-Language: en-US,en;q=0.9' \
        -H 'Content-Type: application/json' \
        -H 'Accept: application/json, text/javascript, */*; q=0.01' \
        -H 'Referer: http://127.0.0.1:5985/' -H 'X-Requested-With: XMLHttpRequest' \
        -H 'Connection: keep-alive' \
        --data-binary '{"email":"faraday","password": "Password123"}' \
        --compressed -c cookie.txt > /dev/null
  2. To create the comment, you have to use POST and instead of "title", use "text" and remember the 'Content-Type: application/json'. The response will be a json with a new comment id. The json must contain object_type and object_id which correspond to Faraday object. Currently we support to comment host, service, comment. NOTE: In the example we comment a host with id: 1073.

    curl -X POST http://127.0.0.1:5985/_api/v2/ws/openvas/comment/ -d '{"text": "https://jira.xxxxxx.eu/browse/SEC-103", "object_type": "host", "object_id": 1073}' -b cookie.txt -H 'Content-Type: application/json'
  3. Our front-end doesn't show comments yet, but you can consult the API like this:

    curl -X GET http://127.0.0.1:5985/_api/v2/ws/openvas/comment/2/ -b cookie.txt -H 'Content-Type: application/json'

    We realised that you are using PUT method, that is for update the comment. And in this case we need to create it, so we use then POST.

Remember that our commercial version supports JIRA integration and we can send you a demo for free if you want to try it out.

dkogue commented 6 years ago

@llazzaro Thank you very much for these details explanations.

dkogue commented 6 years ago

@llazzaro @WinnaZ

does a comment get deleted between two upload or scan (that is I do a first upload and add a comment. then I scan the same target with same scanner and upload again)

llazzaro commented 6 years ago

It should not get deleted. You can check the comment table by doing:

python manage.py sql_shell

select * from comment;

dkogue commented 6 years ago

Thanks @llazzaro for your swift feedback..

dkogue commented 6 years ago

@llazzaro @WinnaZ

please can we have an example upload_report api call. I think I missing something while doing so: hers is my call

curl -X POST 'http://127.0.0.1:5985/_api/v2/ws/dynamictest/upload_report' -H 'Content-Type: multipart/form-data' -b cookie.txt --data-binary '/home/lab/Desktop/zap.xml' —compressed

llazzaro commented 6 years ago

@dkogue you are sending to the server the path of the file. I can't remember the parameter but I think is -F to send file contents.

dkogue commented 6 years ago

@WinnaZ @montive

HI Team, Thanks for all your supports. I trying to push scan result automatically to faraday but have been unsuccessful. Is there anything wrong with my function. Also I am using a tool chain of scanners know as securecodebox. Do you think their scan result format can be the cause.

I have attached a scan result from a securecodebox with zap_scanner module result.txt

def login_faraday(scan_findings):
        s = requests.Session()

    headers = {
        'Origin': 'http://127.0.0.1:5985',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'en-US,en;q=0.9',
        'Content-Type': 'application/json',
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'Referer': 'http://127.0.0.1:5985/',
        'X-Requested-With': 'XMLHttpRequest',
        'Connection': 'keep-alive',
    }

    data = '{"email":"faraday","password": "0zGGdiWu7eiY"}'
        headers_faraday_connection = {
        'Content-Type': 'multipart/form-data',
    }

    response = s.post('http://127.0.0.1:5985/_api/login', headers=headers, data=data)

        cookies = s.cookies.get_dict()
        #print(type(scan_findings))
    #print(scan_findings)
        push_scanresult_faraday = requests.post('http://127.0.0.1:5985/_api/v2/ws/dynamictest/upload_report', headers=headers_faraday_connection,cookies=cookies, data=scan_findings
montive commented 6 years ago

Hi there.

Here is an example of a function that uploads a report to Faraday.

def login_faraday():
    # File to upload
    files = {'file': open('/PATH/TO/FILE', 'rb')}

    s = requests.Session()
    # /login
    headers = {
        'Origin': 'http://127.0.0.1:5985',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'en-US,en;q=0.9',
        'Content-Type': 'application/json',
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'Referer': 'http://127.0.0.1:5985/',
        'X-Requested-With': 'XMLHttpRequest',
        'Connection': 'keep-alive',
    }   
    data = '{"email":"faraday","password": "changeme"}'
    response = s.post('http://127.0.0.1:5985/_api/login', headers=headers, data=data)
    cookies = s.cookies.get_dict()    

    # /session
    response_session = requests.get('http://127.0.0.1:5985/_api/session', cookies=cookies)
    cookies_session = response_session.cookies.get_dict()
    csrf_token = {'csrf_token': response_session.json()['csrf_token']}

    # Uploading report
    upload = requests.post('http://127.0.0.1:5985/_api/v2/ws/api/upload_report', data=csrf_token, cookies=cookies_session, files=files)

In order to be able to upload a report, you need the CSRF token and session's cookies. Remember that the requests parameters only take key/value pairs. That's why files is a dict.

If you want to upload a report by using cURL, here is an example:

curl  'http://127.0.0.1:5985/_api/v2/ws/api/upload_report' \
       -H 'Content-Type: multipart/form-data' \
       --cookie "session=.eJw90M2KwjAQB_BXWXL2YGu9CB6UlGJhpgSCZeZS2FpNJ2YXqkI24rtv18O-wO__8VTdeRpuTm3u02NYqG48qc1TfXyqjWK9SyyUYVsWmMrUWDei9Etsj4FaDKydw-Qj5KZo9CWSNUu2uzXktQM5XSnxyJVZgTaRrYkk-xEt5ZQfVmT3DmcfKvrhcBQUKMgeIoQysb0knjMh-QIEliyQQzJZ0-IV_kx7DWDZY1WPmNCD9Fv1Wqj-Np27-7cfvv4noNTSVCZjXSaYK2KgiLqMTTtX1H7daMpmPnLFgtpHSk7YbN_c4zZM7ztUoV6_3rRiDA.DkoypQ.q7eGzh1oof8dKnbF4q6xD_n1d6o" \
       --form "file=@PATH/TO/FILE" \
       --form "csrf_token=IjYyYzhkNWQxMzA4MTZmMTQxMTliYTA5OTg2NWYzMWRmYzQ5MWM4Y2Ui.Dko4Zw.sZ-LLdGoxaNFUaySFFQMvyLecxc" --compressed

To get session's cookie, go to the WebUI's tab: Status Report, and take it from Request Headers section of the console. And to get the CSRF token, in the same console, go to the tab Response.

dkogue commented 6 years ago

Thanks @montive. Please did you look at my result format? do you think Faraday will be able to import it. Thank again for always answering my questions. really appreciate it :)

just to confirm in your example you name your workspace api right? I get report uploaded to firaday but firaday does not display anything.

my report is: scanresult.txt

dkogue commented 6 years ago

@WinnaZ @montive

Your feedback would be highly appreciated.

here is the message after upload then no alerts is displayed

Import Reconng: /root/.faraday/uploaded_reports/C35MGSVM40M9scanresult

Thanks in advance.

dkogue commented 6 years ago

@WinnaZ @montive Trying to post a comment using service object type but getting below error. Host object type works fine. Thanks in advance.

curl -X POST http://127.0.0.1:5985/_api/v2/ws/test/comment/ -d '{"text": "https://jira.xxxxxx.eu/browse/SEC-200", "object_type": "service", "object_id": 5}' -H 'Cookie: session=.eJxFkE9rg0AQxb9K2XMOcWMvQi5lrViYXRLGLDMXoWr834ImqBvy3bvk0tMw7w2P95uHyK9TNTciuk33aifythTRQ7x9i0iwagYaITDJxU8KNRYLdb3UruwJs0Cr-gCJ9t5XB_K0J4RN28yB-miN_Wx49JqLF5LZYhAcJ7EESdLfbIxpyIo7k4AzmC2Mccj27Hc9Ep6kxtgR0p67YWQFPpPeydGBR93ohDawFBJeOrCp79EfxXMninm65rffvvr5R8BhMJguhM0Aqmw8hmMspFbnjkdajSpWsNySTVfGOtQqlVwfX3H3uZpe7xCBeP4Ba9lhPA.DlF-QA.aP2OE97YUQcltizAmA-24K9geS8' -H 'Content-Type: application/json' {"message":"Can't comment object of another workspace"}

dkogue commented 6 years ago

Hello Team, we all appreciate your tool and the great work you are doing. But we would appreciate more if you can provide feedback on questions ask. Thank and wish you all a great week.

WinnaZ commented 6 years ago

Hey there, Half of your team is Presenting Faraday v3 at Black Hat this week, sorry if we take longer to reply we have our hands full. Are you absolutely sure that workspace test has a service with id=5 ? Cheers!

llazzaro commented 6 years ago

@dkogue can you check using the sql_shell (python manage.py sql_shell) that the service object with id=5 is on the workspace name test? Try this query:

select service.id, workspace.name from workspace, service where workspace.id = service.workspace_id and service.id=5