|
| 1 | +Tutorial : new parser |
| 2 | +===================== |
| 3 | + |
| 4 | +Create a new file in ``credslayer/parsers/`` named after the protocol you want to analyse. Usually you want to name your file the same as the `Protocol` column in wireshark. |
| 5 | + |
| 6 | +.. image:: wireshark_protocol_column.png |
| 7 | + :width: 800 |
| 8 | + :alt: Wireshark protocol column |
| 9 | + |
| 10 | +But sometimes it won't work, so you might wanna check the name of the protocol by searching it using the following command line : |
| 11 | + |
| 12 | +.. code-block:: none |
| 13 | +
|
| 14 | + $ tshark -G protocols | grep -i SEARCH_HERE | awk '{print $NF}' |
| 15 | +
|
| 16 | +
|
| 17 | +You now have to implement the following function that CredSLayer will automatically call for each incoming packet of your choosen protocol : |
| 18 | + |
| 19 | +.. autofunction:: credslayer.parsers.ftp.analyse |
| 20 | + |
| 21 | +Let's just take the ftp parser as an example, just read the comments :) |
| 22 | + |
| 23 | +.. code-block:: python |
| 24 | +
|
| 25 | + # coding: utf-8 |
| 26 | +
|
| 27 | + from pyshark.packet.layer import Layer |
| 28 | +
|
| 29 | + from credslayer.core import logger |
| 30 | + from credslayer.core.session import Session |
| 31 | +
|
| 32 | +
|
| 33 | + # Remember this function is called for every single packet that belong to the protocol |
| 34 | + def analyse(session: Session, layer: Layer): |
| 35 | +
|
| 36 | + # You can use the pretty_print method to show what's in the packet |
| 37 | + # layer.pretty_print() |
| 38 | +
|
| 39 | + # Just an alias of credentials_being_built |
| 40 | + current_creds = session.credentials_being_built |
| 41 | +
|
| 42 | + # We check (using pyshark's layer object) if the packet contains a "reponse_code" field. |
| 43 | + # This is the name tshark gave to the portion of the packet holding the response code. |
| 44 | + if hasattr(layer, "response_code"): |
| 45 | + code = int(layer.response_code) |
| 46 | +
|
| 47 | + # Code 230 means authentication has been successful |
| 48 | + if code == 230 and current_creds.username: |
| 49 | + # That's how you log credentials you've just found |
| 50 | + logger.found(session, "credentials found: {} -- {}".format(current_creds.username, current_creds.password)) |
| 51 | +
|
| 52 | + # That's how you tell CredsLayer to remove the context and credentials currently being built. |
| 53 | + # You found everything you needed, you're done with everything you saved in the session. |
| 54 | + session.validate_credentials() |
| 55 | +
|
| 56 | + # Code 430 means credentials were wrong |
| 57 | + elif code == 430: |
| 58 | + # That's also how you tell CredsLayer to remove the context and credentials currently being built. |
| 59 | + # You just found out credentials were wrong, you're not interested in what you saved in the session. |
| 60 | + session.invalidate_credentials_and_clear_session() |
| 61 | +
|
| 62 | + # We check (using pyshark's layer object) if the packet contains a "request_command" field, |
| 63 | + # This is the name tshark gave to the portion of the packet holding the FTP command. |
| 64 | + elif hasattr(layer, "request_command"): |
| 65 | + command = layer.request_command |
| 66 | +
|
| 67 | + # The username is sent next to the "USER" command. |
| 68 | + # We store the username in `current_creds`, which is the alias for the credentials being built in the session. |
| 69 | + if command == "USER": |
| 70 | + current_creds.username = layer.request_arg |
| 71 | +
|
| 72 | + # Idem with the password |
| 73 | + elif command == "PASS": |
| 74 | + current_creds.password = layer.request_arg |
| 75 | +
|
| 76 | +I really encourage you to read about :ref:`Sessions` as this is what enables you to build a persistent context across each call to your *analyse* function. |
| 77 | +For example in FTP, the username is first sent in a packet, then the password in another one. Thanks to the :ref:`Sessions` object, you will be able to keep track |
| 78 | +of some valuable data. Then somehow (depending on the protocol you are analysing) you might receive an indicator of success or failure, in FTP codes 230 and 430 fulfill that purpose. |
| 79 | +When you find such an indicator, you must call ``session.invalidate_credentials_and_clear_session`` or ``session.validate_credentials`` to tell CredSLayer you're done with those credentials. |
0 commit comments