Dissecting Cobalt Strike using Python
=====================================
.. image:: https://github.com/fox-it/dissect.cobaltstrike/workflows/Tests/badge.svg
:target: https://github.com/fox-it/dissect.cobaltstrike/actions
:alt: GitHub Actions status
.. image:: https://readthedocs.org/projects/dissect-cobaltstrike/badge/?version=latest
:target: https://dissect-cobaltstrike.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. image:: https://img.shields.io/pypi/v/dissect.cobaltstrike.svg
:target: https://pypi.python.org/pypi/dissect.cobaltstrike
**dissect.cobaltstrike** is a Python library for dissecting and parsing Cobalt Strike related data such as beacon payloads and Malleable C2 Profiles.
Installation
------------
The library is available on `PyPI <https://pypi.org/project/dissect.cobaltstrike/>`_. Use ``pip`` to install it::
$ pip install dissect.cobaltstrike
Or install using the ``full`` extra to automatically install dependencies for C2 and PCAP support::
$ pip install dissect.cobaltstrike[full]
**dissect.cobaltstrike** requires Python 3.9 or later.
Documentation
-------------
The project documentation can be found here: https://dissect-cobaltstrike.readthedocs.io
Basic Usage
-----------
Parse a Cobalt Strike beacon and extract some config settings
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
>>> from dissect.cobaltstrike.beacon import BeaconConfig
>>> bconfig = BeaconConfig.from_path("beacon.bin")
>>> hex(bconfig.watermark)
'0x5109bf6d'
>>> bconfig.protocol
'https'
>>> bconfig.version
<BeaconVersion 'Cobalt Strike 4.2 (Nov 06, 2020)', tuple=(4, 2), date=2020-11-06>
>>> bconfig.settings
mappingproxy({'SETTING_PROTOCOL': 8,
'SETTING_PORT': 443,
'SETTING_SLEEPTIME': 5000,
'SETTING_MAXGET': 1048576,
'SETTING_JITTER': 0, ...
>>> bconfig.settings["SETTING_C2_REQUEST"]
[('_HEADER', b'Connection: close'),
('_HEADER', b'Accept-Language: en-US'),
('BUILD', 'metadata'),
('MASK', True),
('BASE64', True),
('PREPEND', b'wordpress_ed1f617bbd6c004cc09e046f3c1b7148='),
('HEADER', b'Cookie')]
Parse a Malleable C2 Profile and read some configuration settings
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
>>> from dissect.cobaltstrike.c2profile import C2Profile
>>> profile = C2Profile.from_path("amazon.profile")
>>> profile.as_dict()
{'sleeptime': ['5000'],
'jitter': ['0'],
'maxdns': ['255'],
'useragent': ['Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko'],
'http-get.uri': ['/s/ref=nb_sb_noss_1/167-3294888-0262949/field-keywords=books'],
'http-get.client.header': [('Accept', '*/*'), ('Host', 'www.amazon.com')],
...
}
>>> profile.properties["useragent"]
['Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko']
>>> profile.properties["http-get.uri"]
['/s/ref=nb_sb_noss_1/167-3294888-0262949/field-keywords=books']
Connect to Team Server as a Beacon Client
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
See also `A Minimal Beacon Client <https://dissect-cobaltstrike.readthedocs.io/en/latest/tutorials/minimal_beacon_client.html>`_ tutorial in the documentation.
.. image:: https://raw.githubusercontent.com/fox-it/dissect.cobaltstrike/main/docs/images/beacon-client.png
Parse and decrypt a PCAP containing Cobalt Strike traffic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
See also the `Decrypt Cobalt Strike PCAPs <https://dissect-cobaltstrike.readthedocs.io/en/latest/tutorials/decrypt_cobaltstrike_pcaps.html>`_ tutorial in the documentation.
.. code-block:: shell
$ beacon-pcap --extract-beacons 2021-06-15-Hancitor-with-Ficker-Stealer-and-Cobalt-Strike.pcap
[+] Found <BeaconConfig ['<redacted>']> at b'/ZsDK', extracted beacon payload to 'beacon-ZsDK.bin'
[+] Found <BeaconConfig ['<redacted>']> at b'/8mJm', extracted beacon payload to 'beacon-8mJm.bin'
$ beacon-pcap -p key.pem 2021-06-15-Hancitor-with-Ficker-Stealer-and-Cobalt-Strike.pcap --beacon beacon-8mJm.bin
<Beacon/BeaconMetadata packet_ts=2021-06-15 15:08:55.172675 src_ip=net.ipaddress('10.0.0.134') src_port=52886 dst_ip=net.ipaddress('<redacted>') dst_port=443 raw_http=b'GET /activity HTTP/1.1\r\nAccept: */*\r\nCookie: kR/OTFMhCYQpv09cXl2R7qEespVUfQ/8YahAbs1b+rEESbSzcAc44R9Klf4zH4GGYxT4dErzNQWimmMW5wQVQSEGFZ36mWc/beoUTQUGVUxcZWXl0t8WBO12qC6vsmRSV5uQO+qxz0Lbz1P/wOkWwbNM0XF9LhVjRrGYSR0Jlrc=\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727)\r\nHost: <redacted>:443\r\nConnection: Keep-Alive\r\nCache-Control: no-cache\r\n\r\n' magic=48879 size=92 aes_rand=b'\xf9dA\xc8\x8b\x07\xe1:\xfa\np\xbc{`m\xe0' ansi_cp=58372 oem_cp=46337 bid=693615746 pid=6396 port=0 flag=4 ver_major=10 ver_minor=0 ver_build=19042 ptr_x64=0 ptr_gmh=1972243040 ptr_gpa=1972237648 ip=net.ipaddress('<redacted>') info=b'DESKTOP-X9JH6AW\ttabitha.gomez\tsvchost.exe'>
<Beacon/TaskPacket packet_ts=2021-06-15 15:09:56.371968 src_ip=net.ipaddress('<redacted>') src_port=443 dst_ip=net.ipaddress('10.0.0.134') dst_port=52894 raw_http=b'HTTP/1.1 200 OK\r\nDate: Tue, 15 Jun 2021 15:09:55 GMT\r\nContent-Type: application/octet-stream\r\nContent-Length: 48\r\n\r\nP\xc1\xf1\xa0{3 \xa8\x01}\xfe\xbcl\x8e\xa2\x81\xd7A2\xa3;\xe0\x91\xf5\x90\xdd]\xc5\x88`\xa2\x88\x93\x14-\xb4\xbb\x96\xf1\x1c\xd7\r\xa60\xfe\xc5\x9e\xd6' epoch=2021-06-15 15:09:55 total_size=16 command='COMMAND_SLEEP' size=8 data=b'\x00\x00\x00d\x00\x00\x00Z'>
License
-------
**dissect.cobaltstrike** is developed and distributed under the MIT license.
Raw data
{
"_id": null,
"home_page": null,
"name": "dissect.cobaltstrike",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "beacon, cobaltstrike, cstruct, dissect, lark, parser, parsing",
"author": null,
"author_email": "Yun Zheng Hu <hu@fox-it.com>",
"download_url": "https://files.pythonhosted.org/packages/62/ff/41541de82eaeef5dd3308fe22c326cea97dd2efa407b583e61120aeb135c/dissect_cobaltstrike-1.2.0.tar.gz",
"platform": null,
"description": "Dissecting Cobalt Strike using Python\n=====================================\n\n.. image:: https://github.com/fox-it/dissect.cobaltstrike/workflows/Tests/badge.svg\n :target: https://github.com/fox-it/dissect.cobaltstrike/actions\n :alt: GitHub Actions status\n.. image:: https://readthedocs.org/projects/dissect-cobaltstrike/badge/?version=latest\n :target: https://dissect-cobaltstrike.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n.. image:: https://img.shields.io/pypi/v/dissect.cobaltstrike.svg\n :target: https://pypi.python.org/pypi/dissect.cobaltstrike\n\n**dissect.cobaltstrike** is a Python library for dissecting and parsing Cobalt Strike related data such as beacon payloads and Malleable C2 Profiles.\n\nInstallation\n------------\n\nThe library is available on `PyPI <https://pypi.org/project/dissect.cobaltstrike/>`_. Use ``pip`` to install it::\n\n $ pip install dissect.cobaltstrike\n\nOr install using the ``full`` extra to automatically install dependencies for C2 and PCAP support::\n\n $ pip install dissect.cobaltstrike[full]\n\n**dissect.cobaltstrike** requires Python 3.9 or later.\n\nDocumentation\n-------------\n\nThe project documentation can be found here: https://dissect-cobaltstrike.readthedocs.io\n\nBasic Usage\n-----------\n\nParse a Cobalt Strike beacon and extract some config settings\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n >>> from dissect.cobaltstrike.beacon import BeaconConfig\n\n >>> bconfig = BeaconConfig.from_path(\"beacon.bin\")\n\n >>> hex(bconfig.watermark)\n '0x5109bf6d'\n >>> bconfig.protocol\n 'https'\n >>> bconfig.version\n <BeaconVersion 'Cobalt Strike 4.2 (Nov 06, 2020)', tuple=(4, 2), date=2020-11-06>\n\n >>> bconfig.settings\n mappingproxy({'SETTING_PROTOCOL': 8,\n 'SETTING_PORT': 443,\n 'SETTING_SLEEPTIME': 5000,\n 'SETTING_MAXGET': 1048576,\n 'SETTING_JITTER': 0, ...\n\n >>> bconfig.settings[\"SETTING_C2_REQUEST\"]\n [('_HEADER', b'Connection: close'),\n ('_HEADER', b'Accept-Language: en-US'),\n ('BUILD', 'metadata'),\n ('MASK', True),\n ('BASE64', True),\n ('PREPEND', b'wordpress_ed1f617bbd6c004cc09e046f3c1b7148='),\n ('HEADER', b'Cookie')]\n\nParse a Malleable C2 Profile and read some configuration settings\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n >>> from dissect.cobaltstrike.c2profile import C2Profile\n >>> profile = C2Profile.from_path(\"amazon.profile\")\n >>> profile.as_dict()\n {'sleeptime': ['5000'],\n 'jitter': ['0'],\n 'maxdns': ['255'],\n 'useragent': ['Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko'],\n 'http-get.uri': ['/s/ref=nb_sb_noss_1/167-3294888-0262949/field-keywords=books'],\n 'http-get.client.header': [('Accept', '*/*'), ('Host', 'www.amazon.com')],\n ...\n }\n\n >>> profile.properties[\"useragent\"]\n ['Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko']\n\n >>> profile.properties[\"http-get.uri\"]\n ['/s/ref=nb_sb_noss_1/167-3294888-0262949/field-keywords=books']\n\nConnect to Team Server as a Beacon Client\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nSee also `A Minimal Beacon Client <https://dissect-cobaltstrike.readthedocs.io/en/latest/tutorials/minimal_beacon_client.html>`_ tutorial in the documentation.\n\n.. image:: https://raw.githubusercontent.com/fox-it/dissect.cobaltstrike/main/docs/images/beacon-client.png\n\n\nParse and decrypt a PCAP containing Cobalt Strike traffic\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nSee also the `Decrypt Cobalt Strike PCAPs <https://dissect-cobaltstrike.readthedocs.io/en/latest/tutorials/decrypt_cobaltstrike_pcaps.html>`_ tutorial in the documentation.\n\n.. code-block:: shell\n\n $ beacon-pcap --extract-beacons 2021-06-15-Hancitor-with-Ficker-Stealer-and-Cobalt-Strike.pcap\n [+] Found <BeaconConfig ['<redacted>']> at b'/ZsDK', extracted beacon payload to 'beacon-ZsDK.bin'\n [+] Found <BeaconConfig ['<redacted>']> at b'/8mJm', extracted beacon payload to 'beacon-8mJm.bin'\n\n $ beacon-pcap -p key.pem 2021-06-15-Hancitor-with-Ficker-Stealer-and-Cobalt-Strike.pcap --beacon beacon-8mJm.bin\n <Beacon/BeaconMetadata packet_ts=2021-06-15 15:08:55.172675 src_ip=net.ipaddress('10.0.0.134') src_port=52886 dst_ip=net.ipaddress('<redacted>') dst_port=443 raw_http=b'GET /activity HTTP/1.1\\r\\nAccept: */*\\r\\nCookie: kR/OTFMhCYQpv09cXl2R7qEespVUfQ/8YahAbs1b+rEESbSzcAc44R9Klf4zH4GGYxT4dErzNQWimmMW5wQVQSEGFZ36mWc/beoUTQUGVUxcZWXl0t8WBO12qC6vsmRSV5uQO+qxz0Lbz1P/wOkWwbNM0XF9LhVjRrGYSR0Jlrc=\\r\\nUser-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727)\\r\\nHost: <redacted>:443\\r\\nConnection: Keep-Alive\\r\\nCache-Control: no-cache\\r\\n\\r\\n' magic=48879 size=92 aes_rand=b'\\xf9dA\\xc8\\x8b\\x07\\xe1:\\xfa\\np\\xbc{`m\\xe0' ansi_cp=58372 oem_cp=46337 bid=693615746 pid=6396 port=0 flag=4 ver_major=10 ver_minor=0 ver_build=19042 ptr_x64=0 ptr_gmh=1972243040 ptr_gpa=1972237648 ip=net.ipaddress('<redacted>') info=b'DESKTOP-X9JH6AW\\ttabitha.gomez\\tsvchost.exe'>\n <Beacon/TaskPacket packet_ts=2021-06-15 15:09:56.371968 src_ip=net.ipaddress('<redacted>') src_port=443 dst_ip=net.ipaddress('10.0.0.134') dst_port=52894 raw_http=b'HTTP/1.1 200 OK\\r\\nDate: Tue, 15 Jun 2021 15:09:55 GMT\\r\\nContent-Type: application/octet-stream\\r\\nContent-Length: 48\\r\\n\\r\\nP\\xc1\\xf1\\xa0{3 \\xa8\\x01}\\xfe\\xbcl\\x8e\\xa2\\x81\\xd7A2\\xa3;\\xe0\\x91\\xf5\\x90\\xdd]\\xc5\\x88`\\xa2\\x88\\x93\\x14-\\xb4\\xbb\\x96\\xf1\\x1c\\xd7\\r\\xa60\\xfe\\xc5\\x9e\\xd6' epoch=2021-06-15 15:09:55 total_size=16 command='COMMAND_SLEEP' size=8 data=b'\\x00\\x00\\x00d\\x00\\x00\\x00Z'>\n\nLicense\n-------\n\n**dissect.cobaltstrike** is developed and distributed under the MIT license.\n",
"bugtrack_url": null,
"license": "MIT License",
"summary": "a Python library for dissecting Cobalt Strike related data",
"version": "1.2.0",
"project_urls": {
"Documentation": "https://dissect-cobaltstrike.readthedocs.io/",
"Homepage": "https://github.com/fox-it/dissect.cobaltstrike",
"Source": "https://github.com/fox-it/dissect.cobaltstrike"
},
"split_keywords": [
"beacon",
" cobaltstrike",
" cstruct",
" dissect",
" lark",
" parser",
" parsing"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "269b98091077245ceb2a556b57b7cfc666c898edc001035b3fcc9f5b1b23b5db",
"md5": "f477591fef026350a9eb031c5b70316b",
"sha256": "23eac6c9901978fcf85a7a00c6dc1f4dc731013d3382327b1f6c0ea76d4291ba"
},
"downloads": -1,
"filename": "dissect_cobaltstrike-1.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "f477591fef026350a9eb031c5b70316b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 375854,
"upload_time": "2024-10-11T10:28:09",
"upload_time_iso_8601": "2024-10-11T10:28:09.087525Z",
"url": "https://files.pythonhosted.org/packages/26/9b/98091077245ceb2a556b57b7cfc666c898edc001035b3fcc9f5b1b23b5db/dissect_cobaltstrike-1.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "62ff41541de82eaeef5dd3308fe22c326cea97dd2efa407b583e61120aeb135c",
"md5": "8dca959796f25eb3a0fc4b17f863202e",
"sha256": "eb1f43ff314d2c7a9d9c5542db0acdc64dca7c866028bf7499894ba230129351"
},
"downloads": -1,
"filename": "dissect_cobaltstrike-1.2.0.tar.gz",
"has_sig": false,
"md5_digest": "8dca959796f25eb3a0fc4b17f863202e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 363207,
"upload_time": "2024-10-11T10:28:11",
"upload_time_iso_8601": "2024-10-11T10:28:11.134559Z",
"url": "https://files.pythonhosted.org/packages/62/ff/41541de82eaeef5dd3308fe22c326cea97dd2efa407b583e61120aeb135c/dissect_cobaltstrike-1.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-11 10:28:11",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "fox-it",
"github_project": "dissect.cobaltstrike",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "dissect.cobaltstrike"
}